We want the fixes in here as well.
Unified · Split
| @@ -109,6 +109,7 @@ parameter is applicable:: · 108 unmodified lines | ||
| 109 | 109 | IPV6 IPv6 support is enabled. |
| 110 | 110 | ISAPNP ISA PnP code is enabled. |
| 111 | 111 | ISDN Appropriate ISDN support is enabled. |
| 112 | + ISOL CPU Isolation is enabled. | |
| 112 | 113 | JOY Appropriate joystick support is enabled. |
| 113 | 114 | KGDB Kernel debugger support is enabled. |
| 114 | 115 | KVM Kernel Virtual Machine support is enabled. |
| @@ -328,11 +328,15 @@ · 327 unmodified lines | ||
| 328 | 328 | not play well with APC CPU idle - disable it if you have |
| 329 | 329 | APC and your system crashes randomly. |
| 330 | 330 | |
| 331 | − apic= [APIC,X86-32] Advanced Programmable Interrupt Controller | |
| 331 | + apic= [APIC,X86] Advanced Programmable Interrupt Controller | |
| 332 | 332 | Change the output verbosity whilst booting |
| 333 | 333 | Format: { quiet (default) | verbose | debug } |
| 334 | 334 | Change the amount of debugging information output |
| 335 | 335 | when initialising the APIC and IO-APIC components. |
| 336 | + For X86-32, this can also be used to specify an APIC | |
| 337 | + driver name. | |
| 338 | + Format: apic=driver_name | |
| 339 | + Examples: apic=bigsmp | |
| 336 | 340 | |
| 337 | 341 | apic_extnmi= [APIC,X86] External NMI delivery setting |
| 338 | 342 | Format: { bsp (default) | all | none } |
| @@ -1737,7 +1741,7 @@ · 1398 unmodified lines | ||
| 1737 | 1741 | isapnp= [ISAPNP] |
| 1738 | 1742 | Format: <RDP>,<reset>,<pci_scan>,<verbosity> |
| 1739 | 1743 | |
| 1740 | − isolcpus= [KNL,SMP] Isolate a given set of CPUs from disturbance. | |
| 1744 | + isolcpus= [KNL,SMP,ISOL] Isolate a given set of CPUs from disturbance. | |
| 1741 | 1745 | [Deprecated - use cpusets instead] |
| 1742 | 1746 | Format: [flag-list,]<cpu-list> |
| 1743 | 1747 | |
| @@ -2662,7 +2666,7 @@ · 918 unmodified lines | ||
| 2662 | 2666 | Valid arguments: on, off |
| 2663 | 2667 | Default: on |
| 2664 | 2668 | |
| 2665 | − nohz_full= [KNL,BOOT] | |
| 2669 | + nohz_full= [KNL,BOOT,SMP,ISOL] | |
| 2666 | 2670 | The argument is a cpu list, as described above. |
| 2667 | 2671 | In kernels built with CONFIG_NO_HZ_FULL=y, set |
| 2668 | 2672 | the specified list of CPUs whose tick will be stopped |
| @@ -2708,6 +2712,8 @@ · 39 unmodified lines | ||
| 2708 | 2712 | steal time is computed, but won't influence scheduler |
| 2709 | 2713 | behaviour |
| 2710 | 2714 | |
| 2715 | + nopti [X86-64] Disable kernel page table isolation | |
| 2716 | + | |
| 2711 | 2717 | nolapic [X86-32,APIC] Do not enable or use the local APIC. |
| 2712 | 2718 | |
| 2713 | 2719 | nolapic_timer [X86-32,APIC] Do not use the local APIC timer. |
| @@ -3282,6 +3288,12 @@ · 568 unmodified lines | ||
| 3282 | 3288 | pt. [PARIDE] |
| 3283 | 3289 | See Documentation/blockdev/paride.txt. |
| 3284 | 3290 | |
| 3291 | + pti= [X86_64] | |
| 3292 | + Control user/kernel address space isolation: | |
| 3293 | + on - enable | |
| 3294 | + off - disable | |
| 3295 | + auto - default setting | |
| 3296 | + | |
| 3285 | 3297 | pty.legacy_count= |
| 3286 | 3298 | [KNL] Number of legacy pty's. Overwrites compiled-in |
| 3287 | 3299 | default number. |
| @@ -230,7 +230,7 @@ If supported by your machine this will be exposed by the WMI bus with · 229 unmodified lines | ||
| 230 | 230 | a sysfs attribute called "force_power". |
| 231 | 231 | |
| 232 | 232 | For example the intel-wmi-thunderbolt driver exposes this attribute in: |
| 233 | − /sys/devices/platform/PNP0C14:00/wmi_bus/wmi_bus-PNP0C14:00/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power | |
| 233 | + /sys/bus/wmi/devices/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power | |
| 234 | 234 | |
| 235 | 235 | To force the power to on, write 1 to this attribute file. |
| 236 | 236 | To disable force power, write 0 to this attribute file. |
| @@ -75,3 +75,4 @@ stable kernels. · 74 unmodified lines | ||
| 75 | 75 | | Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | |
| 76 | 76 | | Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 | |
| 77 | 77 | | Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 | |
| 78 | +| Qualcomm Tech. | Falkor v{1,2} | E1041 | QCOM_FALKOR_ERRATUM_1041 | | |
| @@ -898,6 +898,13 @@ controller implements weight and absolute bandwidth limit models for · 897 unmodified lines | ||
| 898 | 898 | normal scheduling policy and absolute bandwidth allocation model for |
| 899 | 899 | realtime scheduling policy. |
| 900 | 900 | |
| 901 | +WARNING: cgroup2 doesn't yet support control of realtime processes and | |
| 902 | +the cpu controller can only be enabled when all RT processes are in | |
| 903 | +the root cgroup. Be aware that system management software may already | |
| 904 | +have placed RT processes into nonroot cgroups during the system boot | |
| 905 | +process, and these processes may need to be moved to the root cgroup | |
| 906 | +before the cpu controller can be enabled. | |
| 907 | + | |
| 901 | 908 | |
| 902 | 909 | CPU Interface Files |
| 903 | 910 | ~~~~~~~~~~~~~~~~~~~ |
| @@ -13,7 +13,6 @@ Required properties: · 12 unmodified lines | ||
| 13 | 13 | at25df321a |
| 14 | 14 | at25df641 |
| 15 | 15 | at26df081a |
| 16 | − en25s64 | |
| 17 | 16 | mr25h128 |
| 18 | 17 | mr25h256 |
| 19 | 18 | mr25h10 |
| @@ -33,7 +32,6 @@ Required properties: · 13 unmodified lines | ||
| 33 | 32 | s25fl008k |
| 34 | 33 | s25fl064k |
| 35 | 34 | sst25vf040b |
| 36 | − sst25wf040b | |
| 37 | 35 | m25p40 |
| 38 | 36 | m25p80 |
| 39 | 37 | m25p16 |
| @@ -73,7 +73,7 @@ Example: · 72 unmodified lines | ||
| 73 | 73 | compatible = "dlg,da7218"; |
| 74 | 74 | reg = <0x1a>; |
| 75 | 75 | interrupt-parent = <&gpio6>; |
| 76 | − interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; | |
| 76 | + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | |
| 77 | 77 | wakeup-source; |
| 78 | 78 | |
| 79 | 79 | VDD-supply = <®_audio>; |
| @@ -77,7 +77,7 @@ Example: · 76 unmodified lines | ||
| 77 | 77 | reg = <0x1a>; |
| 78 | 78 | |
| 79 | 79 | interrupt-parent = <&gpio6>; |
| 80 | − interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; | |
| 80 | + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | |
| 81 | 81 | |
| 82 | 82 | VDD-supply = <®_audio>; |
| 83 | 83 | VDDMIC-supply = <®_audio>; |
| @@ -12,24 +12,30 @@ Required properties: · 11 unmodified lines | ||
| 12 | 12 | - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc |
| 13 | 13 | - reg : Offset and length of the register set for the device |
| 14 | 14 | - interrupts : Should contain CSPI/eCSPI interrupt |
| 15 | −- cs-gpios : Specifies the gpio pins to be used for chipselects. | |
| 16 | 15 | - clocks : Clock specifiers for both ipg and per clocks. |
| 17 | 16 | - clock-names : Clock names should include both "ipg" and "per" |
| 18 | 17 | See the clock consumer binding, |
| 19 | 18 | Documentation/devicetree/bindings/clock/clock-bindings.txt |
| 20 | −- dmas: DMA specifiers for tx and rx dma. See the DMA client binding, | |
| 21 | − Documentation/devicetree/bindings/dma/dma.txt | |
| 22 | −- dma-names: DMA request names should include "tx" and "rx" if present. | |
| 23 | 19 | |
| 24 | −Obsolete properties: | |
| 25 | −- fsl,spi-num-chipselects : Contains the number of the chipselect | |
| 20 | +Recommended properties: | |
| 21 | +- cs-gpios : GPIOs to use as chip selects, see spi-bus.txt. While the native chip | |
| 22 | +select lines can be used, they appear to always generate a pulse between each | |
| 23 | +word of a transfer. Most use cases will require GPIO based chip selects to | |
| 24 | +generate a valid transaction. | |
| 26 | 25 | |
| 27 | 26 | Optional properties: |
| 27 | +- num-cs : Number of total chip selects, see spi-bus.txt. | |
| 28 | +- dmas: DMA specifiers for tx and rx dma. See the DMA client binding, | |
| 29 | +Documentation/devicetree/bindings/dma/dma.txt. | |
| 30 | +- dma-names: DMA request names, if present, should include "tx" and "rx". | |
| 28 | 31 | - fsl,spi-rdy-drctl: Integer, representing the value of DRCTL, the register |
| 29 | 32 | controlling the SPI_READY handling. Note that to enable the DRCTL consideration, |
| 30 | 33 | the SPI_READY mode-flag needs to be set too. |
| 31 | 34 | Valid values are: 0 (disabled), 1 (edge-triggered burst) and 2 (level-triggered burst). |
| 32 | 35 | |
| 36 | +Obsolete properties: | |
| 37 | +- fsl,spi-num-chipselects : Contains the number of the chipselect | |
| 38 | + | |
| 33 | 39 | Example: |
| 34 | 40 | |
| 35 | 41 | ecspi@70010000 { |
| @@ -156,6 +156,40 @@ handle it in two different ways: · 155 unmodified lines | ||
| 156 | 156 | root of the overlay. Finally the directory is moved to the new |
| 157 | 157 | location. |
| 158 | 158 | |
| 159 | +There are several ways to tune the "redirect_dir" feature. | |
| 160 | + | |
| 161 | +Kernel config options: | |
| 162 | + | |
| 163 | +- OVERLAY_FS_REDIRECT_DIR: | |
| 164 | + If this is enabled, then redirect_dir is turned on by default. | |
| 165 | +- OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW: | |
| 166 | + If this is enabled, then redirects are always followed by default. Enabling | |
| 167 | + this results in a less secure configuration. Enable this option only when | |
| 168 | + worried about backward compatibility with kernels that have the redirect_dir | |
| 169 | + feature and follow redirects even if turned off. | |
| 170 | + | |
| 171 | +Module options (can also be changed through /sys/module/overlay/parameters/*): | |
| 172 | + | |
| 173 | +- "redirect_dir=BOOL": | |
| 174 | + See OVERLAY_FS_REDIRECT_DIR kernel config option above. | |
| 175 | +- "redirect_always_follow=BOOL": | |
| 176 | + See OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW kernel config option above. | |
| 177 | +- "redirect_max=NUM": | |
| 178 | + The maximum number of bytes in an absolute redirect (default is 256). | |
| 179 | + | |
| 180 | +Mount options: | |
| 181 | + | |
| 182 | +- "redirect_dir=on": | |
| 183 | + Redirects are enabled. | |
| 184 | +- "redirect_dir=follow": | |
| 185 | + Redirects are not created, but followed. | |
| 186 | +- "redirect_dir=off": | |
| 187 | + Redirects are not created and only followed if "redirect_always_follow" | |
| 188 | + feature is enabled in the kernel/module config. | |
| 189 | +- "redirect_dir=nofollow": | |
| 190 | + Redirects are not created and not followed (equivalent to "redirect_dir=off" | |
| 191 | + if "redirect_always_follow" feature is not enabled). | |
| 192 | + | |
| 159 | 193 | Non-directories |
| 160 | 194 | --------------- |
| 161 | 195 | |
| @@ -1,874 +0,0 @@ | ||
| 1 | −Crossrelease | |
| 2 | −============ | |
| 3 | − | |
| 4 | −Started by Byungchul Park <byungchul.park@lge.com> | |
| 5 | − | |
| 6 | −Contents: | |
| 7 | − | |
| 8 | − (*) Background | |
| 9 | − | |
| 10 | − - What causes deadlock | |
| 11 | − - How lockdep works | |
| 12 | − | |
| 13 | − (*) Limitation | |
| 14 | − | |
| 15 | − - Limit lockdep | |
| 16 | − - Pros from the limitation | |
| 17 | − - Cons from the limitation | |
| 18 | − - Relax the limitation | |
| 19 | − | |
| 20 | − (*) Crossrelease | |
| 21 | − | |
| 22 | − - Introduce crossrelease | |
| 23 | − - Introduce commit | |
| 24 | − | |
| 25 | − (*) Implementation | |
| 26 | − | |
| 27 | − - Data structures | |
| 28 | − - How crossrelease works | |
| 29 | − | |
| 30 | − (*) Optimizations | |
| 31 | − | |
| 32 | − - Avoid duplication | |
| 33 | − - Lockless for hot paths | |
| 34 | − | |
| 35 | − (*) APPENDIX A: What lockdep does to work aggresively | |
| 36 | − | |
| 37 | − (*) APPENDIX B: How to avoid adding false dependencies | |
| 38 | − | |
| 39 | − | |
| 40 | −========== | |
| 41 | −Background | |
| 42 | −========== | |
| 43 | − | |
| 44 | −What causes deadlock | |
| 45 | −-------------------- | |
| 46 | − | |
| 47 | −A deadlock occurs when a context is waiting for an event to happen, | |
| 48 | −which is impossible because another (or the) context who can trigger the | |
| 49 | −event is also waiting for another (or the) event to happen, which is | |
| 50 | −also impossible due to the same reason. | |
| 51 | − | |
| 52 | −For example: | |
| 53 | − | |
| 54 | − A context going to trigger event C is waiting for event A to happen. | |
| 55 | − A context going to trigger event A is waiting for event B to happen. | |
| 56 | − A context going to trigger event B is waiting for event C to happen. | |
| 57 | − | |
| 58 | −A deadlock occurs when these three wait operations run at the same time, | |
| 59 | −because event C cannot be triggered if event A does not happen, which in | |
| 60 | −turn cannot be triggered if event B does not happen, which in turn | |
| 61 | −cannot be triggered if event C does not happen. After all, no event can | |
| 62 | −be triggered since any of them never meets its condition to wake up. | |
| 63 | − | |
| 64 | −A dependency might exist between two waiters and a deadlock might happen | |
| 65 | −due to an incorrect releationship between dependencies. Thus, we must | |
| 66 | −define what a dependency is first. A dependency exists between them if: | |
| 67 | − | |
| 68 | − 1. There are two waiters waiting for each event at a given time. | |
| 69 | − 2. The only way to wake up each waiter is to trigger its event. | |
| 70 | − 3. Whether one can be woken up depends on whether the other can. | |
| 71 | − | |
| 72 | −Each wait in the example creates its dependency like: | |
| 73 | − | |
| 74 | − Event C depends on event A. | |
| 75 | − Event A depends on event B. | |
| 76 | − Event B depends on event C. | |
| 77 | − | |
| 78 | − NOTE: Precisely speaking, a dependency is one between whether a | |
| 79 | − waiter for an event can be woken up and whether another waiter for | |
| 80 | − another event can be woken up. However from now on, we will describe | |
| 81 | − a dependency as if it's one between an event and another event for | |
| 82 | − simplicity. | |
| 83 | − | |
| 84 | −And they form circular dependencies like: | |
| 85 | − | |
| 86 | − -> C -> A -> B - | |
| 87 | − / \ | |
| 88 | − \ / | |
| 89 | − ---------------- | |
| 90 | − | |
| 91 | − where 'A -> B' means that event A depends on event B. | |
| 92 | − | |
| 93 | −Such circular dependencies lead to a deadlock since no waiter can meet | |
| 94 | −its condition to wake up as described. | |
| 95 | − | |
| 96 | −CONCLUSION | |
| 97 | − | |
| 98 | −Circular dependencies cause a deadlock. | |
| 99 | − | |
| 100 | − | |
| 101 | −How lockdep works | |
| 102 | −----------------- | |
| 103 | − | |
| 104 | −Lockdep tries to detect a deadlock by checking dependencies created by | |
| 105 | −lock operations, acquire and release. Waiting for a lock corresponds to | |
| 106 | −waiting for an event, and releasing a lock corresponds to triggering an | |
| 107 | −event in the previous section. | |
| 108 | − | |
| 109 | −In short, lockdep does: | |
| 110 | − | |
| 111 | − 1. Detect a new dependency. | |
| 112 | − 2. Add the dependency into a global graph. | |
| 113 | − 3. Check if that makes dependencies circular. | |
| 114 | − 4. Report a deadlock or its possibility if so. | |
| 115 | − | |
| 116 | −For example, consider a graph built by lockdep that looks like: | |
| 117 | − | |
| 118 | − A -> B - | |
| 119 | − \ | |
| 120 | − -> E | |
| 121 | − / | |
| 122 | − C -> D - | |
| 123 | − | |
| 124 | − where A, B,..., E are different lock classes. | |
| 125 | − | |
| 126 | −Lockdep will add a dependency into the graph on detection of a new | |
| 127 | −dependency. For example, it will add a dependency 'E -> C' when a new | |
| 128 | −dependency between lock E and lock C is detected. Then the graph will be: | |
| 129 | − | |
| 130 | − A -> B - | |
| 131 | − \ | |
| 132 | − -> E - | |
| 133 | − / \ | |
| 134 | − -> C -> D - \ | |
| 135 | − / / | |
| 136 | − \ / | |
| 137 | − ------------------ | |
| 138 | − | |
| 139 | − where A, B,..., E are different lock classes. | |
| 140 | − | |
| 141 | −This graph contains a subgraph which demonstrates circular dependencies: | |
| 142 | − | |
| 143 | − -> E - | |
| 144 | − / \ | |
| 145 | − -> C -> D - \ | |
| 146 | − / / | |
| 147 | − \ / | |
| 148 | − ------------------ | |
| 149 | − | |
| 150 | − where C, D and E are different lock classes. | |
| 151 | − | |
| 152 | −This is the condition under which a deadlock might occur. Lockdep | |
| 153 | −reports it on detection after adding a new dependency. This is the way | |
| 154 | −how lockdep works. | |
| 155 | − | |
| 156 | −CONCLUSION | |
| 157 | − | |
| 158 | −Lockdep detects a deadlock or its possibility by checking if circular | |
| 159 | −dependencies were created after adding each new dependency. | |
| 160 | − | |
| 161 | − | |
| 162 | −========== | |
| 163 | −Limitation | |
| 164 | −========== | |
| 165 | − | |
| 166 | −Limit lockdep | |
| 167 | −------------- | |
| 168 | − | |
| 169 | −Limiting lockdep to work on only typical locks e.g. spin locks and | |
| 170 | −mutexes, which are released within the acquire context, the | |
| 171 | −implementation becomes simple but its capacity for detection becomes | |
| 172 | −limited. Let's check pros and cons in next section. | |
| 173 | − | |
| 174 | − | |
| 175 | −Pros from the limitation | |
| 176 | −------------------------ | |
| 177 | − | |
| 178 | −Given the limitation, when acquiring a lock, locks in a held_locks | |
| 179 | −cannot be released if the context cannot acquire it so has to wait to | |
| 180 | −acquire it, which means all waiters for the locks in the held_locks are | |
| 181 | −stuck. It's an exact case to create dependencies between each lock in | |
| 182 | −the held_locks and the lock to acquire. | |
| 183 | − | |
| 184 | −For example: | |
| 185 | − | |
| 186 | − CONTEXT X | |
| 187 | − --------- | |
| 188 | − acquire A | |
| 189 | − acquire B /* Add a dependency 'A -> B' */ | |
| 190 | − release B | |
| 191 | − release A | |
| 192 | − | |
| 193 | − where A and B are different lock classes. | |
| 194 | − | |
| 195 | −When acquiring lock A, the held_locks of CONTEXT X is empty thus no | |
| 196 | −dependency is added. But when acquiring lock B, lockdep detects and adds | |
| 197 | −a new dependency 'A -> B' between lock A in the held_locks and lock B. | |
| 198 | −They can be simply added whenever acquiring each lock. | |
| 199 | − | |
| 200 | −And data required by lockdep exists in a local structure, held_locks | |
| 201 | −embedded in task_struct. Forcing to access the data within the context, | |
| 202 | −lockdep can avoid racy problems without explicit locks while handling | |
| 203 | −the local data. | |
| 204 | − | |
| 205 | −Lastly, lockdep only needs to keep locks currently being held, to build | |
| 206 | −a dependency graph. However, relaxing the limitation, it needs to keep | |
| 207 | −even locks already released, because a decision whether they created | |
| 208 | −dependencies might be long-deferred. | |
| 209 | − | |
| 210 | −To sum up, we can expect several advantages from the limitation: | |
| 211 | − | |
| 212 | − 1. Lockdep can easily identify a dependency when acquiring a lock. | |
| 213 | − 2. Races are avoidable while accessing local locks in a held_locks. | |
| 214 | − 3. Lockdep only needs to keep locks currently being held. | |
| 215 | − | |
| 216 | −CONCLUSION | |
| 217 | − | |
| 218 | −Given the limitation, the implementation becomes simple and efficient. | |
| 219 | − | |
| 220 | − | |
| 221 | −Cons from the limitation | |
| 222 | −------------------------ | |
| 223 | − | |
| 224 | −Given the limitation, lockdep is applicable only to typical locks. For | |
| 225 | −example, page locks for page access or completions for synchronization | |
| 226 | −cannot work with lockdep. | |
| 227 | − | |
| 228 | −Can we detect deadlocks below, under the limitation? | |
| 229 | − | |
| 230 | −Example 1: | |
| 231 | − | |
| 232 | − CONTEXT X CONTEXT Y CONTEXT Z | |
| 233 | − --------- --------- ---------- | |
| 234 | − mutex_lock A | |
| 235 | − lock_page B | |
| 236 | − lock_page B | |
| 237 | − mutex_lock A /* DEADLOCK */ | |
| 238 | − unlock_page B held by X | |
| 239 | − unlock_page B | |
| 240 | − mutex_unlock A | |
| 241 | − mutex_unlock A | |
| 242 | − | |
| 243 | − where A and B are different lock classes. | |
| 244 | − | |
| 245 | −No, we cannot. | |
| 246 | − | |
| 247 | −Example 2: | |
| 248 | − | |
| 249 | − CONTEXT X CONTEXT Y | |
| 250 | − --------- --------- | |
| 251 | − mutex_lock A | |
| 252 | − mutex_lock A | |
| 253 | − wait_for_complete B /* DEADLOCK */ | |
| 254 | − complete B | |
| 255 | − mutex_unlock A | |
| 256 | − mutex_unlock A | |
| 257 | − | |
| 258 | − where A is a lock class and B is a completion variable. | |
| 259 | − | |
| 260 | −No, we cannot. | |
| 261 | − | |
| 262 | −CONCLUSION | |
| 263 | − | |
| 264 | −Given the limitation, lockdep cannot detect a deadlock or its | |
| 265 | −possibility caused by page locks or completions. | |
| 266 | − | |
| 267 | − | |
| 268 | −Relax the limitation | |
| 269 | −-------------------- | |
| 270 | − | |
| 271 | −Under the limitation, things to create dependencies are limited to | |
| 272 | −typical locks. However, synchronization primitives like page locks and | |
| 273 | −completions, which are allowed to be released in any context, also | |
| 274 | −create dependencies and can cause a deadlock. So lockdep should track | |
| 275 | −these locks to do a better job. We have to relax the limitation for | |
| 276 | −these locks to work with lockdep. | |
| 277 | − | |
| 278 | −Detecting dependencies is very important for lockdep to work because | |
| 279 | −adding a dependency means adding an opportunity to check whether it | |
| 280 | −causes a deadlock. The more lockdep adds dependencies, the more it | |
| 281 | −thoroughly works. Thus Lockdep has to do its best to detect and add as | |
| 282 | −many true dependencies into a graph as possible. | |
| 283 | − | |
| 284 | −For example, considering only typical locks, lockdep builds a graph like: | |
| 285 | − | |
| 286 | − A -> B - | |
| 287 | − \ | |
| 288 | − -> E | |
| 289 | − / | |
| 290 | − C -> D - | |
| 291 | − | |
| 292 | − where A, B,..., E are different lock classes. | |
| 293 | − | |
| 294 | −On the other hand, under the relaxation, additional dependencies might | |
| 295 | −be created and added. Assuming additional 'FX -> C' and 'E -> GX' are | |
| 296 | −added thanks to the relaxation, the graph will be: | |
| 297 | − | |
| 298 | − A -> B - | |
| 299 | − \ | |
| 300 | − -> E -> GX | |
| 301 | − / | |
| 302 | − FX -> C -> D - | |
| 303 | − | |
| 304 | − where A, B,..., E, FX and GX are different lock classes, and a suffix | |
| 305 | − 'X' is added on non-typical locks. | |
| 306 | − | |
| 307 | −The latter graph gives us more chances to check circular dependencies | |
| 308 | −than the former. However, it might suffer performance degradation since | |
| 309 | −relaxing the limitation, with which design and implementation of lockdep | |
| 310 | −can be efficient, might introduce inefficiency inevitably. So lockdep | |
| 311 | −should provide two options, strong detection and efficient detection. | |
| 312 | − | |
| 313 | −Choosing efficient detection: | |
| 314 | − | |
| 315 | − Lockdep works with only locks restricted to be released within the | |
| 316 | − acquire context. However, lockdep works efficiently. | |
| 317 | − | |
| 318 | −Choosing strong detection: | |
| 319 | − | |
| 320 | − Lockdep works with all synchronization primitives. However, lockdep | |
| 321 | − suffers performance degradation. | |
| 322 | − | |
| 323 | −CONCLUSION | |
| 324 | − | |
| 325 | −Relaxing the limitation, lockdep can add additional dependencies giving | |
| 326 | −additional opportunities to check circular dependencies. | |
| 327 | − | |
| 328 | − | |
| 329 | −============ | |
| 330 | −Crossrelease | |
| 331 | −============ | |
| 332 | − | |
| 333 | −Introduce crossrelease | |
| 334 | −---------------------- | |
| 335 | − | |
| 336 | −In order to allow lockdep to handle additional dependencies by what | |
| 337 | −might be released in any context, namely 'crosslock', we have to be able | |
| 338 | −to identify those created by crosslocks. The proposed 'crossrelease' | |
| 339 | −feature provoides a way to do that. | |
| 340 | − | |
| 341 | −Crossrelease feature has to do: | |
| 342 | − | |
| 343 | − 1. Identify dependencies created by crosslocks. | |
| 344 | − 2. Add the dependencies into a dependency graph. | |
| 345 | − | |
| 346 | −That's all. Once a meaningful dependency is added into graph, then | |
| 347 | −lockdep would work with the graph as it did. The most important thing | |
| 348 | −crossrelease feature has to do is to correctly identify and add true | |
| 349 | −dependencies into the global graph. | |
| 350 | − | |
| 351 | −A dependency e.g. 'A -> B' can be identified only in the A's release | |
| 352 | −context because a decision required to identify the dependency can be | |
| 353 | −made only in the release context. That is to decide whether A can be | |
| 354 | −released so that a waiter for A can be woken up. It cannot be made in | |
| 355 | −other than the A's release context. | |
| 356 | − | |
| 357 | −It's no matter for typical locks because each acquire context is same as | |
| 358 | −its release context, thus lockdep can decide whether a lock can be | |
| 359 | −released in the acquire context. However for crosslocks, lockdep cannot | |
| 360 | −make the decision in the acquire context but has to wait until the | |
| 361 | −release context is identified. | |
| 362 | − | |
| 363 | −Therefore, deadlocks by crosslocks cannot be detected just when it | |
| 364 | −happens, because those cannot be identified until the crosslocks are | |
| 365 | −released. However, deadlock possibilities can be detected and it's very | |
| 366 | −worth. See 'APPENDIX A' section to check why. | |
| 367 | − | |
| 368 | −CONCLUSION | |
| 369 | − | |
| 370 | −Using crossrelease feature, lockdep can work with what might be released | |
| 371 | −in any context, namely crosslock. | |
| 372 | − | |
| 373 | − | |
| 374 | −Introduce commit | |
| 375 | −---------------- | |
| 376 | − | |
| 377 | −Since crossrelease defers the work adding true dependencies of | |
| 378 | −crosslocks until they are actually released, crossrelease has to queue | |
| 379 | −all acquisitions which might create dependencies with the crosslocks. | |
| 380 | −Then it identifies dependencies using the queued data in batches at a | |
| 381 | −proper time. We call it 'commit'. | |
| 382 | − | |
| 383 | −There are four types of dependencies: | |
| 384 | − | |
| 385 | −1. TT type: 'typical lock A -> typical lock B' | |
| 386 | − | |
| 387 | − Just when acquiring B, lockdep can see it's in the A's release | |
| 388 | − context. So the dependency between A and B can be identified | |
| 389 | − immediately. Commit is unnecessary. | |
| 390 | − | |
| 391 | −2. TC type: 'typical lock A -> crosslock BX' | |
| 392 | − | |
| 393 | − Just when acquiring BX, lockdep can see it's in the A's release | |
| 394 | − context. So the dependency between A and BX can be identified | |
| 395 | − immediately. Commit is unnecessary, too. | |
| 396 | − | |
| 397 | −3. CT type: 'crosslock AX -> typical lock B' | |
| 398 | − | |
| 399 | − When acquiring B, lockdep cannot identify the dependency because | |
| 400 | − there's no way to know if it's in the AX's release context. It has | |
| 401 | − to wait until the decision can be made. Commit is necessary. | |
| 402 | − | |
| 403 | −4. CC type: 'crosslock AX -> crosslock BX' | |
| 404 | − | |
| 405 | − When acquiring BX, lockdep cannot identify the dependency because | |
| 406 | − there's no way to know if it's in the AX's release context. It has | |
| 407 | − to wait until the decision can be made. Commit is necessary. | |
| 408 | − But, handling CC type is not implemented yet. It's a future work. | |
| 409 | − | |
| 410 | −Lockdep can work without commit for typical locks, but commit step is | |
| 411 | −necessary once crosslocks are involved. Introducing commit, lockdep | |
| 412 | −performs three steps. What lockdep does in each step is: | |
| 413 | − | |
| 414 | −1. Acquisition: For typical locks, lockdep does what it originally did | |
| 415 | − and queues the lock so that CT type dependencies can be checked using | |
| 416 | − it at the commit step. For crosslocks, it saves data which will be | |
| 417 | − used at the commit step and increases a reference count for it. | |
| 418 | − | |
| 419 | −2. Commit: No action is reauired for typical locks. For crosslocks, | |
| 420 | − lockdep adds CT type dependencies using the data saved at the | |
| 421 | − acquisition step. | |
| 422 | − | |
| 423 | −3. Release: No changes are required for typical locks. When a crosslock | |
| 424 | − is released, it decreases a reference count for it. | |
| 425 | − | |
| 426 | −CONCLUSION | |
| 427 | − | |
| 428 | −Crossrelease introduces commit step to handle dependencies of crosslocks | |
| 429 | −in batches at a proper time. | |
| 430 | − | |
| 431 | − | |
| 432 | −============== | |
| 433 | −Implementation | |
| 434 | −============== | |
| 435 | − | |
| 436 | −Data structures | |
| 437 | −--------------- | |
| 438 | − | |
| 439 | −Crossrelease introduces two main data structures. | |
| 440 | − | |
| 441 | −1. hist_lock | |
| 442 | − | |
| 443 | − This is an array embedded in task_struct, for keeping lock history so | |
| 444 | − that dependencies can be added using them at the commit step. Since | |
| 445 | − it's local data, it can be accessed locklessly in the owner context. | |
| 446 | − The array is filled at the acquisition step and consumed at the | |
| 447 | − commit step. And it's managed in circular manner. | |
| 448 | − | |
| 449 | −2. cross_lock | |
| 450 | − | |
| 451 | − One per lockdep_map exists. This is for keeping data of crosslocks | |
| 452 | − and used at the commit step. | |
| 453 | − | |
| 454 | − | |
| 455 | −How crossrelease works | |
| 456 | −---------------------- | |
| 457 | − | |
| 458 | −It's the key of how crossrelease works, to defer necessary works to an | |
| 459 | −appropriate point in time and perform in at once at the commit step. | |
| 460 | −Let's take a look with examples step by step, starting from how lockdep | |
| 461 | −works without crossrelease for typical locks. | |
| 462 | − | |
| 463 | − acquire A /* Push A onto held_locks */ | |
| 464 | − acquire B /* Push B onto held_locks and add 'A -> B' */ | |
| 465 | − acquire C /* Push C onto held_locks and add 'B -> C' */ | |
| 466 | − release C /* Pop C from held_locks */ | |
| 467 | − release B /* Pop B from held_locks */ | |
| 468 | − release A /* Pop A from held_locks */ | |
| 469 | − | |
| 470 | − where A, B and C are different lock classes. | |
| 471 | − | |
| 472 | − NOTE: This document assumes that readers already understand how | |
| 473 | − lockdep works without crossrelease thus omits details. But there's | |
| 474 | − one thing to note. Lockdep pretends to pop a lock from held_locks | |
| 475 | − when releasing it. But it's subtly different from the original pop | |
| 476 | − operation because lockdep allows other than the top to be poped. | |
| 477 | − | |
| 478 | −In this case, lockdep adds 'the top of held_locks -> the lock to acquire' | |
| 479 | −dependency every time acquiring a lock. | |
| 480 | − | |
| 481 | −After adding 'A -> B', a dependency graph will be: | |
| 482 | − | |
| 483 | − A -> B | |
| 484 | − | |
| 485 | − where A and B are different lock classes. | |
| 486 | − | |
| 487 | −And after adding 'B -> C', the graph will be: | |
| 488 | − | |
| 489 | − A -> B -> C | |
| 490 | − | |
| 491 | − where A, B and C are different lock classes. | |
| 492 | − | |
| 493 | −Let's performs commit step even for typical locks to add dependencies. | |
| 494 | −Of course, commit step is not necessary for them, however, it would work | |
| 495 | −well because this is a more general way. | |
| 496 | − | |
| 497 | − acquire A | |
| 498 | − /* | |
| 499 | − * Queue A into hist_locks | |
| 500 | − * | |
| 501 | − * In hist_locks: A | |
| 502 | − * In graph: Empty | |
| 503 | − */ | |
| 504 | − | |
| 505 | − acquire B | |
| 506 | − /* | |
| 507 | − * Queue B into hist_locks | |
| 508 | − * | |
| 509 | − * In hist_locks: A, B | |
| 510 | − * In graph: Empty | |
| 511 | − */ | |
| 512 | − | |
| 513 | − acquire C | |
| 514 | − /* | |
| 515 | − * Queue C into hist_locks | |
| 516 | − * | |
| 517 | − * In hist_locks: A, B, C | |
| 518 | − * In graph: Empty | |
| 519 | − */ | |
| 520 | − | |
| 521 | − commit C | |
| 522 | − /* | |
| 523 | − * Add 'C -> ?' | |
| 524 | − * Answer the following to decide '?' | |
| 525 | − * What has been queued since acquire C: Nothing | |
| 526 | − * | |
| 527 | − * In hist_locks: A, B, C | |
| 528 | − * In graph: Empty | |
| 529 | − */ | |
| 530 | − | |
| 531 | − release C | |
| 532 | − | |
| 533 | − commit B | |
| 534 | − /* | |
| 535 | − * Add 'B -> ?' | |
| 536 | − * Answer the following to decide '?' | |
| 537 | − * What has been queued since acquire B: C | |
| 538 | − * | |
| 539 | − * In hist_locks: A, B, C | |
| 540 | − * In graph: 'B -> C' | |
| 541 | − */ | |
| 542 | − | |
| 543 | − release B | |
| 544 | − | |
| 545 | − commit A | |
| 546 | − /* | |
| 547 | − * Add 'A -> ?' | |
| 548 | − * Answer the following to decide '?' | |
| 549 | − * What has been queued since acquire A: B, C | |
| 550 | − * | |
| 551 | − * In hist_locks: A, B, C | |
| 552 | − * In graph: 'B -> C', 'A -> B', 'A -> C' | |
| 553 | − */ | |
| 554 | − | |
| 555 | − release A | |
| 556 | − | |
| 557 | − where A, B and C are different lock classes. | |
| 558 | − | |
| 559 | −In this case, dependencies are added at the commit step as described. | |
| 560 | − | |
| 561 | −After commits for A, B and C, the graph will be: | |
| 562 | − | |
| 563 | − A -> B -> C | |
| 564 | − | |
| 565 | − where A, B and C are different lock classes. | |
| 566 | − | |
| 567 | − NOTE: A dependency 'A -> C' is optimized out. | |
| 568 | − | |
| 569 | −We can see the former graph built without commit step is same as the | |
| 570 | −latter graph built using commit steps. Of course the former way leads to | |
| 571 | −earlier finish for building the graph, which means we can detect a | |
| 572 | −deadlock or its possibility sooner. So the former way would be prefered | |
| 573 | −when possible. But we cannot avoid using the latter way for crosslocks. | |
| 574 | − | |
| 575 | −Let's look at how commit steps work for crosslocks. In this case, the | |
| 576 | −commit step is performed only on crosslock AX as real. And it assumes | |
| 577 | −that the AX release context is different from the AX acquire context. | |
| 578 | − | |
| 579 | − BX RELEASE CONTEXT BX ACQUIRE CONTEXT | |
| 580 | − ------------------ ------------------ | |
| 581 | − acquire A | |
| 582 | − /* | |
| 583 | − * Push A onto held_locks | |
| 584 | − * Queue A into hist_locks | |
| 585 | − * | |
| 586 | − * In held_locks: A | |
| 587 | − * In hist_locks: A | |
| 588 | − * In graph: Empty | |
| 589 | − */ | |
| 590 | − | |
| 591 | − acquire BX | |
| 592 | − /* | |
| 593 | − * Add 'the top of held_locks -> BX' | |
| 594 | − * | |
| 595 | − * In held_locks: A | |
| 596 | − * In hist_locks: A | |
| 597 | − * In graph: 'A -> BX' | |
| 598 | − */ | |
| 599 | − | |
| 600 | − ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 601 | − It must be guaranteed that the following operations are seen after | |
| 602 | − acquiring BX globally. It can be done by things like barrier. | |
| 603 | − ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 604 | − | |
| 605 | − acquire C | |
| 606 | − /* | |
| 607 | − * Push C onto held_locks | |
| 608 | − * Queue C into hist_locks | |
| 609 | − * | |
| 610 | − * In held_locks: C | |
| 611 | − * In hist_locks: C | |
| 612 | − * In graph: 'A -> BX' | |
| 613 | − */ | |
| 614 | − | |
| 615 | − release C | |
| 616 | − /* | |
| 617 | − * Pop C from held_locks | |
| 618 | − * | |
| 619 | − * In held_locks: Empty | |
| 620 | − * In hist_locks: C | |
| 621 | − * In graph: 'A -> BX' | |
| 622 | − */ | |
| 623 | − acquire D | |
| 624 | − /* | |
| 625 | − * Push D onto held_locks | |
| 626 | − * Queue D into hist_locks | |
| 627 | − * Add 'the top of held_locks -> D' | |
| 628 | − * | |
| 629 | − * In held_locks: A, D | |
| 630 | − * In hist_locks: A, D | |
| 631 | − * In graph: 'A -> BX', 'A -> D' | |
| 632 | − */ | |
| 633 | − acquire E | |
| 634 | − /* | |
| 635 | − * Push E onto held_locks | |
| 636 | − * Queue E into hist_locks | |
| 637 | − * | |
| 638 | − * In held_locks: E | |
| 639 | − * In hist_locks: C, E | |
| 640 | − * In graph: 'A -> BX', 'A -> D' | |
| 641 | − */ | |
| 642 | − | |
| 643 | − release E | |
| 644 | − /* | |
| 645 | − * Pop E from held_locks | |
| 646 | − * | |
| 647 | − * In held_locks: Empty | |
| 648 | − * In hist_locks: D, E | |
| 649 | − * In graph: 'A -> BX', 'A -> D' | |
| 650 | − */ | |
| 651 | − release D | |
| 652 | − /* | |
| 653 | − * Pop D from held_locks | |
| 654 | − * | |
| 655 | − * In held_locks: A | |
| 656 | − * In hist_locks: A, D | |
| 657 | − * In graph: 'A -> BX', 'A -> D' | |
| 658 | − */ | |
| 659 | − commit BX | |
| 660 | − /* | |
| 661 | − * Add 'BX -> ?' | |
| 662 | − * What has been queued since acquire BX: C, E | |
| 663 | − * | |
| 664 | − * In held_locks: Empty | |
| 665 | − * In hist_locks: D, E | |
| 666 | − * In graph: 'A -> BX', 'A -> D', | |
| 667 | − * 'BX -> C', 'BX -> E' | |
| 668 | − */ | |
| 669 | − | |
| 670 | − release BX | |
| 671 | − /* | |
| 672 | − * In held_locks: Empty | |
| 673 | − * In hist_locks: D, E | |
| 674 | − * In graph: 'A -> BX', 'A -> D', | |
| 675 | − * 'BX -> C', 'BX -> E' | |
| 676 | − */ | |
| 677 | − release A | |
| 678 | − /* | |
| 679 | − * Pop A from held_locks | |
| 680 | − * | |
| 681 | − * In held_locks: Empty | |
| 682 | − * In hist_locks: A, D | |
| 683 | − * In graph: 'A -> BX', 'A -> D', | |
| 684 | − * 'BX -> C', 'BX -> E' | |
| 685 | − */ | |
| 686 | − | |
| 687 | − where A, BX, C,..., E are different lock classes, and a suffix 'X' is | |
| 688 | − added on crosslocks. | |
| 689 | − | |
| 690 | −Crossrelease considers all acquisitions after acqiuring BX are | |
| 691 | −candidates which might create dependencies with BX. True dependencies | |
| 692 | −will be determined when identifying the release context of BX. Meanwhile, | |
| 693 | −all typical locks are queued so that they can be used at the commit step. | |
| 694 | −And then two dependencies 'BX -> C' and 'BX -> E' are added at the | |
| 695 | −commit step when identifying the release context. | |
| 696 | − | |
| 697 | −The final graph will be, with crossrelease: | |
| 698 | − | |
| 699 | − -> C | |
| 700 | − / | |
| 701 | − -> BX - | |
| 702 | − / \ | |
| 703 | − A - -> E | |
| 704 | − \ | |
| 705 | − -> D | |
| 706 | − | |
| 707 | − where A, BX, C,..., E are different lock classes, and a suffix 'X' is | |
| 708 | − added on crosslocks. | |
| 709 | − | |
| 710 | −However, the final graph will be, without crossrelease: | |
| 711 | − | |
| 712 | − A -> D | |
| 713 | − | |
| 714 | − where A and D are different lock classes. | |
| 715 | − | |
| 716 | −The former graph has three more dependencies, 'A -> BX', 'BX -> C' and | |
| 717 | −'BX -> E' giving additional opportunities to check if they cause | |
| 718 | −deadlocks. This way lockdep can detect a deadlock or its possibility | |
| 719 | −caused by crosslocks. | |
| 720 | − | |
| 721 | −CONCLUSION | |
| 722 | − | |
| 723 | −We checked how crossrelease works with several examples. | |
| 724 | − | |
| 725 | − | |
| 726 | −============= | |
| 727 | −Optimizations | |
| 728 | −============= | |
| 729 | − | |
| 730 | −Avoid duplication | |
| 731 | −----------------- | |
| 732 | − | |
| 733 | −Crossrelease feature uses a cache like what lockdep already uses for | |
| 734 | −dependency chains, but this time it's for caching CT type dependencies. | |
| 735 | −Once that dependency is cached, the same will never be added again. | |
| 736 | − | |
| 737 | − | |
| 738 | −Lockless for hot paths | |
| 739 | −---------------------- | |
| 740 | − | |
| 741 | −To keep all locks for later use at the commit step, crossrelease adopts | |
| 742 | −a local array embedded in task_struct, which makes access to the data | |
| 743 | −lockless by forcing it to happen only within the owner context. It's | |
| 744 | −like how lockdep handles held_locks. Lockless implmentation is important | |
| 745 | −since typical locks are very frequently acquired and released. | |
| 746 | − | |
| 747 | − | |
| 748 | −================================================= | |
| 749 | −APPENDIX A: What lockdep does to work aggresively | |
| 750 | −================================================= | |
| 751 | − | |
| 752 | −A deadlock actually occurs when all wait operations creating circular | |
| 753 | −dependencies run at the same time. Even though they don't, a potential | |
| 754 | −deadlock exists if the problematic dependencies exist. Thus it's | |
| 755 | −meaningful to detect not only an actual deadlock but also its potential | |
| 756 | −possibility. The latter is rather valuable. When a deadlock occurs | |
| 757 | −actually, we can identify what happens in the system by some means or | |
| 758 | −other even without lockdep. However, there's no way to detect possiblity | |
| 759 | −without lockdep unless the whole code is parsed in head. It's terrible. | |
| 760 | −Lockdep does the both, and crossrelease only focuses on the latter. | |
| 761 | − | |
| 762 | −Whether or not a deadlock actually occurs depends on several factors. | |
| 763 | −For example, what order contexts are switched in is a factor. Assuming | |
| 764 | −circular dependencies exist, a deadlock would occur when contexts are | |
| 765 | −switched so that all wait operations creating the dependencies run | |
| 766 | −simultaneously. Thus to detect a deadlock possibility even in the case | |
| 767 | −that it has not occured yet, lockdep should consider all possible | |
| 768 | −combinations of dependencies, trying to: | |
| 769 | − | |
| 770 | −1. Use a global dependency graph. | |
| 771 | − | |
| 772 | − Lockdep combines all dependencies into one global graph and uses them, | |
| 773 | − regardless of which context generates them or what order contexts are | |
| 774 | − switched in. Aggregated dependencies are only considered so they are | |
| 775 | − prone to be circular if a problem exists. | |
| 776 | − | |
| 777 | −2. Check dependencies between classes instead of instances. | |
| 778 | − | |
| 779 | − What actually causes a deadlock are instances of lock. However, | |
| 780 | − lockdep checks dependencies between classes instead of instances. | |
| 781 | − This way lockdep can detect a deadlock which has not happened but | |
| 782 | − might happen in future by others but the same class. | |
| 783 | − | |
| 784 | −3. Assume all acquisitions lead to waiting. | |
| 785 | − | |
| 786 | − Although locks might be acquired without waiting which is essential | |
| 787 | − to create dependencies, lockdep assumes all acquisitions lead to | |
| 788 | − waiting since it might be true some time or another. | |
| 789 | − | |
| 790 | −CONCLUSION | |
| 791 | − | |
| 792 | −Lockdep detects not only an actual deadlock but also its possibility, | |
| 793 | −and the latter is more valuable. | |
| 794 | − | |
| 795 | − | |
| 796 | −================================================== | |
| 797 | −APPENDIX B: How to avoid adding false dependencies | |
| 798 | −================================================== | |
| 799 | − | |
| 800 | −Remind what a dependency is. A dependency exists if: | |
| 801 | − | |
| 802 | − 1. There are two waiters waiting for each event at a given time. | |
| 803 | − 2. The only way to wake up each waiter is to trigger its event. | |
| 804 | − 3. Whether one can be woken up depends on whether the other can. | |
| 805 | − | |
| 806 | −For example: | |
| 807 | − | |
| 808 | − acquire A | |
| 809 | − acquire B /* A dependency 'A -> B' exists */ | |
| 810 | − release B | |
| 811 | − release A | |
| 812 | − | |
| 813 | − where A and B are different lock classes. | |
| 814 | − | |
| 815 | −A depedency 'A -> B' exists since: | |
| 816 | − | |
| 817 | − 1. A waiter for A and a waiter for B might exist when acquiring B. | |
| 818 | − 2. Only way to wake up each is to release what it waits for. | |
| 819 | − 3. Whether the waiter for A can be woken up depends on whether the | |
| 820 | − other can. IOW, TASK X cannot release A if it fails to acquire B. | |
| 821 | − | |
| 822 | −For another example: | |
| 823 | − | |
| 824 | − TASK X TASK Y | |
| 825 | − ------ ------ | |
| 826 | − acquire AX | |
| 827 | − acquire B /* A dependency 'AX -> B' exists */ | |
| 828 | − release B | |
| 829 | − release AX held by Y | |
| 830 | − | |
| 831 | − where AX and B are different lock classes, and a suffix 'X' is added | |
| 832 | − on crosslocks. | |
| 833 | − | |
| 834 | −Even in this case involving crosslocks, the same rule can be applied. A | |
| 835 | −depedency 'AX -> B' exists since: | |
| 836 | − | |
| 837 | − 1. A waiter for AX and a waiter for B might exist when acquiring B. | |
| 838 | − 2. Only way to wake up each is to release what it waits for. | |
| 839 | − 3. Whether the waiter for AX can be woken up depends on whether the | |
| 840 | − other can. IOW, TASK X cannot release AX if it fails to acquire B. | |
| 841 | − | |
| 842 | −Let's take a look at more complicated example: | |
| 843 | − | |
| 844 | − TASK X TASK Y | |
| 845 | − ------ ------ | |
| 846 | − acquire B | |
| 847 | − release B | |
| 848 | − fork Y | |
| 849 | − acquire AX | |
| 850 | − acquire C /* A dependency 'AX -> C' exists */ | |
| 851 | − release C | |
| 852 | − release AX held by Y | |
| 853 | − | |
| 854 | − where AX, B and C are different lock classes, and a suffix 'X' is | |
| 855 | − added on crosslocks. | |
| 856 | − | |
| 857 | −Does a dependency 'AX -> B' exist? Nope. | |
| 858 | − | |
| 859 | −Two waiters are essential to create a dependency. However, waiters for | |
| 860 | −AX and B to create 'AX -> B' cannot exist at the same time in this | |
| 861 | −example. Thus the dependency 'AX -> B' cannot be created. | |
| 862 | − | |
| 863 | −It would be ideal if the full set of true ones can be considered. But | |
| 864 | −we can ensure nothing but what actually happened. Relying on what | |
| 865 | −actually happens at runtime, we can anyway add only true ones, though | |
| 866 | −they might be a subset of true ones. It's similar to how lockdep works | |
| 867 | −for typical locks. There might be more true dependencies than what | |
| 868 | −lockdep has detected in runtime. Lockdep has no choice but to rely on | |
| 869 | −what actually happens. Crossrelease also relies on it. | |
| 870 | − | |
| 871 | −CONCLUSION | |
| 872 | − | |
| 873 | −Relying on what actually happens, lockdep can avoid adding false | |
| 874 | −dependencies. | |
| @@ -98,5 +98,25 @@ request is made for a page in an old zpool, it is uncompressed using its · 97 unmodified lines | ||
| 98 | 98 | original compressor. Once all pages are removed from an old zpool, the zpool |
| 99 | 99 | and its compressor are freed. |
| 100 | 100 | |
| 101 | +Some of the pages in zswap are same-value filled pages (i.e. contents of the | |
| 102 | +page have same value or repetitive pattern). These pages include zero-filled | |
| 103 | +pages and they are handled differently. During store operation, a page is | |
| 104 | +checked if it is a same-value filled page before compressing it. If true, the | |
| 105 | +compressed length of the page is set to zero and the pattern or same-filled | |
| 106 | +value is stored. | |
| 107 | + | |
| 108 | +Same-value filled pages identification feature is enabled by default and can be | |
| 109 | +disabled at boot time by setting the "same_filled_pages_enabled" attribute to 0, | |
| 110 | +e.g. zswap.same_filled_pages_enabled=0. It can also be enabled and disabled at | |
| 111 | +runtime using the sysfs "same_filled_pages_enabled" attribute, e.g. | |
| 112 | + | |
| 113 | +echo 1 > /sys/module/zswap/parameters/same_filled_pages_enabled | |
| 114 | + | |
| 115 | +When zswap same-filled page identification is disabled at runtime, it will stop | |
| 116 | +checking for the same-value filled pages during store operation. However, the | |
| 117 | +existing pages which are marked as same-value filled pages remain stored | |
| 118 | +unchanged in zswap until they are either loaded or invalidated. | |
| 119 | + | |
| 101 | 120 | A debugfs interface is provided for various statistic about pool size, number |
| 102 | −of pages stored, and various counters for the reasons pages are rejected. | |
| 121 | +of pages stored, same-value filled pages and various counters for the reasons | |
| 122 | +pages are rejected. | |
| @@ -1,6 +1,4 @@ | ||
| 1 | 1 | |
| 2 | −<previous description obsolete, deleted> | |
| 3 | − | |
| 4 | 2 | Virtual memory map with 4 level page tables: |
| 5 | 3 | |
| 6 | 4 | 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm |
| @@ -14,13 +12,16 @@ ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB) · 7 unmodified lines | ||
| 14 | 12 | ... unused hole ... |
| 15 | 13 | ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB) |
| 16 | 14 | ... unused hole ... |
| 15 | +fffffe0000000000 - fffffe7fffffffff (=39 bits) LDT remap for PTI | |
| 16 | +fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping | |
| 17 | 17 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks |
| 18 | 18 | ... unused hole ... |
| 19 | 19 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space |
| 20 | 20 | ... unused hole ... |
| 21 | 21 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 |
| 22 | −ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable) | |
| 23 | −ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls | |
| 22 | +ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space (variable) | |
| 23 | +[fixmap start] - ffffffffff5fffff kernel-internal fixmap range | |
| 24 | +ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI | |
| 24 | 25 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole |
| 25 | 26 | |
| 26 | 27 | Virtual memory map with 5 level page tables: |
| @@ -29,26 +30,29 @@ Virtual memory map with 5 level page tables: · 2 unmodified lines | ||
| 29 | 30 | hole caused by [56:63] sign extension |
| 30 | 31 | ff00000000000000 - ff0fffffffffffff (=52 bits) guard hole, reserved for hypervisor |
| 31 | 32 | ff10000000000000 - ff8fffffffffffff (=55 bits) direct mapping of all phys. memory |
| 32 | −ff90000000000000 - ff91ffffffffffff (=49 bits) hole | |
| 33 | −ff92000000000000 - ffd1ffffffffffff (=54 bits) vmalloc/ioremap space | |
| 33 | +ff90000000000000 - ff9fffffffffffff (=52 bits) LDT remap for PTI | |
| 34 | +ffa0000000000000 - ffd1ffffffffffff (=54 bits) vmalloc/ioremap space (12800 TB) | |
| 34 | 35 | ffd2000000000000 - ffd3ffffffffffff (=49 bits) hole |
| 35 | 36 | ffd4000000000000 - ffd5ffffffffffff (=49 bits) virtual memory map (512TB) |
| 36 | 37 | ... unused hole ... |
| 37 | 38 | ffdf000000000000 - fffffc0000000000 (=53 bits) kasan shadow memory (8PB) |
| 38 | 39 | ... unused hole ... |
| 40 | +fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping | |
| 39 | 41 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks |
| 40 | 42 | ... unused hole ... |
| 41 | 43 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space |
| 42 | 44 | ... unused hole ... |
| 43 | 45 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 |
| 44 | −ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space | |
| 45 | −ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls | |
| 46 | +ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space | |
| 47 | +[fixmap start] - ffffffffff5fffff kernel-internal fixmap range | |
| 48 | +ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI | |
| 46 | 49 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole |
| 47 | 50 | |
| 48 | 51 | Architecture defines a 64-bit virtual address. Implementations can support |
| 49 | 52 | less. Currently supported are 48- and 57-bit virtual addresses. Bits 63 |
| 50 | −through to the most-significant implemented bit are set to either all ones | |
| 51 | −or all zero. This causes hole between user space and kernel addresses. | |
| 53 | +through to the most-significant implemented bit are sign extended. | |
| 54 | +This causes hole between user space and kernel addresses if you interpret them | |
| 55 | +as unsigned. | |
| 52 | 56 | |
| 53 | 57 | The direct mapping covers all memory in the system up to the highest |
| 54 | 58 | memory address (this means in some cases it can also include PCI memory |
| @@ -58,9 +62,6 @@ vmalloc space is lazily synchronized into the different PML4/PML5 pages of · 3 unmodified lines | ||
| 58 | 62 | the processes using the page fault handler, with init_top_pgt as |
| 59 | 63 | reference. |
| 60 | 64 | |
| 61 | −Current X86-64 implementations support up to 46 bits of address space (64 TB), | |
| 62 | −which is our current limit. This expands into MBZ space in the page tables. | |
| 63 | − | |
| 64 | 65 | We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual |
| 65 | 66 | memory window (this size is arbitrary, it can be raised later if needed). |
| 66 | 67 | The mappings are not part of any other kernel PGD and are only available |
| @@ -72,5 +73,3 @@ following fixmap section. · 5 unmodified lines | ||
| 72 | 73 | Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all |
| 73 | 74 | physical memory, vmalloc/ioremap space and virtual memory map are randomized. |
| 74 | 75 | Their order is preserved but their base will be offset early at boot time. |
| 75 | − | |
| 76 | −-Andi Kleen, Jul 2004 | |
| @@ -2621,24 +2621,22 @@ F: fs/bfs/ · 2620 unmodified lines | ||
| 2621 | 2621 | F: include/uapi/linux/bfs_fs.h |
| 2622 | 2622 | |
| 2623 | 2623 | BLACKFIN ARCHITECTURE |
| 2624 | −M: Steven Miao <realmz6@gmail.com> | |
| 2625 | 2624 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2626 | 2625 | T: git git://git.code.sf.net/p/adi-linux/code |
| 2627 | 2626 | W: http://blackfin.uclinux.org |
| 2628 | −S: Supported | |
| 2627 | +S: Orphan | |
| 2629 | 2628 | F: arch/blackfin/ |
| 2630 | 2629 | |
| 2631 | 2630 | BLACKFIN EMAC DRIVER |
| 2632 | 2631 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2633 | 2632 | W: http://blackfin.uclinux.org |
| 2634 | −S: Supported | |
| 2633 | +S: Orphan | |
| 2635 | 2634 | F: drivers/net/ethernet/adi/ |
| 2636 | 2635 | |
| 2637 | 2636 | BLACKFIN MEDIA DRIVER |
| 2638 | −M: Scott Jiang <scott.jiang.linux@gmail.com> | |
| 2639 | 2637 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2640 | 2638 | W: http://blackfin.uclinux.org/ |
| 2641 | −S: Supported | |
| 2639 | +S: Orphan | |
| 2642 | 2640 | F: drivers/media/platform/blackfin/ |
| 2643 | 2641 | F: drivers/media/i2c/adv7183* |
| 2644 | 2642 | F: drivers/media/i2c/vs6624* |
| @@ -2646,25 +2644,25 @@ F: drivers/media/i2c/vs6624* · 1 unmodified line | ||
| 2646 | 2644 | BLACKFIN RTC DRIVER |
| 2647 | 2645 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2648 | 2646 | W: http://blackfin.uclinux.org |
| 2649 | −S: Supported | |
| 2647 | +S: Orphan | |
| 2650 | 2648 | F: drivers/rtc/rtc-bfin.c |
| 2651 | 2649 | |
| 2652 | 2650 | BLACKFIN SDH DRIVER |
| 2653 | 2651 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2654 | 2652 | W: http://blackfin.uclinux.org |
| 2655 | −S: Supported | |
| 2653 | +S: Orphan | |
| 2656 | 2654 | F: drivers/mmc/host/bfin_sdh.c |
| 2657 | 2655 | |
| 2658 | 2656 | BLACKFIN SERIAL DRIVER |
| 2659 | 2657 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2660 | 2658 | W: http://blackfin.uclinux.org |
| 2661 | −S: Supported | |
| 2659 | +S: Orphan | |
| 2662 | 2660 | F: drivers/tty/serial/bfin_uart.c |
| 2663 | 2661 | |
| 2664 | 2662 | BLACKFIN WATCHDOG DRIVER |
| 2665 | 2663 | L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) |
| 2666 | 2664 | W: http://blackfin.uclinux.org |
| 2667 | −S: Supported | |
| 2665 | +S: Orphan | |
| 2668 | 2666 | F: drivers/watchdog/bfin_wdt.c |
| 2669 | 2667 | |
| 2670 | 2668 | BLINKM RGB LED DRIVER |
| @@ -5431,7 +5429,7 @@ F: drivers/media/tuners/fc2580* · 2760 unmodified lines | ||
| 5431 | 5429 | |
| 5432 | 5430 | FCOE SUBSYSTEM (libfc, libfcoe, fcoe) |
| 5433 | 5431 | M: Johannes Thumshirn <jth@kernel.org> |
| 5434 | −L: fcoe-devel@open-fcoe.org | |
| 5432 | +L: linux-scsi@vger.kernel.org | |
| 5435 | 5433 | W: www.Open-FCoE.org |
| 5436 | 5434 | S: Supported |
| 5437 | 5435 | F: drivers/scsi/libfc/ |
| @@ -13141,6 +13139,7 @@ F: drivers/dma/dw/ · 7703 unmodified lines | ||
| 13141 | 13139 | |
| 13142 | 13140 | SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER |
| 13143 | 13141 | M: Jie Deng <jiedeng@synopsys.com> |
| 13142 | +M: Jose Abreu <Jose.Abreu@synopsys.com> | |
| 13144 | 13143 | L: netdev@vger.kernel.org |
| 13145 | 13144 | S: Supported |
| 13146 | 13145 | F: drivers/net/ethernet/synopsys/ |
| @@ -13516,6 +13515,7 @@ M: Mika Westerberg <mika.westerberg@linux.intel.com> · 369 unmodified lines | ||
| 13516 | 13515 | M: Yehezkel Bernat <yehezkel.bernat@intel.com> |
| 13517 | 13516 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git |
| 13518 | 13517 | S: Maintained |
| 13518 | +F: Documentation/admin-guide/thunderbolt.rst | |
| 13519 | 13519 | F: drivers/thunderbolt/ |
| 13520 | 13520 | F: include/linux/thunderbolt.h |
| 13521 | 13521 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 4 |
| 3 | 3 | PATCHLEVEL = 15 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Fearless Coyote |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -789,6 +789,9 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign) · 780 unmodified lines | ||
| 789 | 789 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 790 | 790 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) |
| 791 | 791 | |
| 792 | +# Make sure -fstack-check isn't enabled (like gentoo apparently did) | |
| 793 | +KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,) | |
| 794 | + | |
| 792 | 795 | # conserve stack if available |
| 793 | 796 | KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) |
| 794 | 797 | |
| @@ -121,7 +121,7 @@ · 120 unmodified lines | ||
| 121 | 121 | switch0port10: port@10 { |
| 122 | 122 | reg = <10>; |
| 123 | 123 | label = "dsa"; |
| 124 | − phy-mode = "xgmii"; | |
| 124 | + phy-mode = "xaui"; | |
| 125 | 125 | link = <&switch1port10>; |
| 126 | 126 | }; |
| 127 | 127 | }; |
| @@ -208,7 +208,7 @@ · 80 unmodified lines | ||
| 208 | 208 | switch1port10: port@10 { |
| 209 | 209 | reg = <10>; |
| 210 | 210 | label = "dsa"; |
| 211 | − phy-mode = "xgmii"; | |
| 211 | + phy-mode = "xaui"; | |
| 212 | 212 | link = <&switch0port10>; |
| 213 | 213 | }; |
| 214 | 214 | }; |
| @@ -85,7 +85,11 @@ · 84 unmodified lines | ||
| 85 | 85 | .pushsection .text.fixup,"ax" |
| 86 | 86 | .align 4 |
| 87 | 87 | 9001: mov r4, #-EFAULT |
| 88 | +#ifdef CONFIG_CPU_SW_DOMAIN_PAN | |
| 89 | + ldr r5, [sp, #9*4] @ *err_ptr | |
| 90 | +#else | |
| 88 | 91 | ldr r5, [sp, #8*4] @ *err_ptr |
| 92 | +#endif | |
| 89 | 93 | str r4, [r5] |
| 90 | 94 | ldmia sp, {r1, r2} @ retrieve dst, len |
| 91 | 95 | add r2, r2, r1 |
| @@ -557,7 +557,6 @@ config QCOM_QDF2400_ERRATUM_0065 · 556 unmodified lines | ||
| 557 | 557 | |
| 558 | 558 | If unsure, say Y. |
| 559 | 559 | |
| 560 | − | |
| 561 | 560 | config SOCIONEXT_SYNQUACER_PREITS |
| 562 | 561 | bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" |
| 563 | 562 | default y |
| @@ -576,6 +575,17 @@ config HISILICON_ERRATUM_161600802 · 12 unmodified lines | ||
| 576 | 575 | a 128kB offset to be applied to the target address in this commands. |
| 577 | 576 | |
| 578 | 577 | If unsure, say Y. |
| 578 | + | |
| 579 | +config QCOM_FALKOR_ERRATUM_E1041 | |
| 580 | + bool "Falkor E1041: Speculative instruction fetches might cause errant memory access" | |
| 581 | + default y | |
| 582 | + help | |
| 583 | + Falkor CPU may speculatively fetch instructions from an improper | |
| 584 | + memory location when MMU translation is changed from SCTLR_ELn[M]=1 | |
| 585 | + to SCTLR_ELn[M]=0. Prefix an ISB instruction to fix the problem. | |
| 586 | + | |
| 587 | + If unsure, say Y. | |
| 588 | + | |
| 579 | 589 | endmenu |
| 580 | 590 | |
| 581 | 591 | |
| @@ -512,4 +512,14 @@ alternative_else_nop_endif · 511 unmodified lines | ||
| 512 | 512 | #endif |
| 513 | 513 | .endm |
| 514 | 514 | |
| 515 | +/** | |
| 516 | + * Errata workaround prior to disable MMU. Insert an ISB immediately prior | |
| 517 | + * to executing the MSR that will change SCTLR_ELn[M] from a value of 1 to 0. | |
| 518 | + */ | |
| 519 | + .macro pre_disable_mmu_workaround | |
| 520 | +#ifdef CONFIG_QCOM_FALKOR_ERRATUM_E1041 | |
| 521 | + isb | |
| 522 | +#endif | |
| 523 | + .endm | |
| 524 | + | |
| 515 | 525 | #endif /* __ASM_ASSEMBLER_H */ |
| @@ -60,6 +60,9 @@ enum ftr_type { · 59 unmodified lines | ||
| 60 | 60 | #define FTR_VISIBLE true /* Feature visible to the user space */ |
| 61 | 61 | #define FTR_HIDDEN false /* Feature is hidden from the user */ |
| 62 | 62 | |
| 63 | +#define FTR_VISIBLE_IF_IS_ENABLED(config) \ | |
| 64 | + (IS_ENABLED(config) ? FTR_VISIBLE : FTR_HIDDEN) | |
| 65 | + | |
| 63 | 66 | struct arm64_ftr_bits { |
| 64 | 67 | bool sign; /* Value is signed ? */ |
| 65 | 68 | bool visible; |
| @@ -91,6 +91,7 @@ · 90 unmodified lines | ||
| 91 | 91 | #define BRCM_CPU_PART_VULCAN 0x516 |
| 92 | 92 | |
| 93 | 93 | #define QCOM_CPU_PART_FALKOR_V1 0x800 |
| 94 | +#define QCOM_CPU_PART_FALKOR 0xC00 | |
| 94 | 95 | |
| 95 | 96 | #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) |
| 96 | 97 | #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) |
| @@ -99,6 +100,7 @@ · 2 unmodified lines | ||
| 99 | 100 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) |
| 100 | 101 | #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) |
| 101 | 102 | #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) |
| 103 | +#define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) | |
| 102 | 104 | |
| 103 | 105 | #ifndef __ASSEMBLY__ |
| 104 | 106 | |
| @@ -42,6 +42,8 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <asm/cmpxchg.h> |
| 43 | 43 | #include <asm/fixmap.h> |
| 44 | 44 | #include <linux/mmdebug.h> |
| 45 | +#include <linux/mm_types.h> | |
| 46 | +#include <linux/sched.h> | |
| 45 | 47 | |
| 46 | 48 | extern void __pte_error(const char *file, int line, unsigned long val); |
| 47 | 49 | extern void __pmd_error(const char *file, int line, unsigned long val); |
| @@ -149,12 +151,20 @@ static inline pte_t pte_mkwrite(pte_t pte) · 101 unmodified lines | ||
| 149 | 151 | |
| 150 | 152 | static inline pte_t pte_mkclean(pte_t pte) |
| 151 | 153 | { |
| 152 | − return clear_pte_bit(pte, __pgprot(PTE_DIRTY)); | |
| 154 | + pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY)); | |
| 155 | + pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); | |
| 156 | + | |
| 157 | + return pte; | |
| 153 | 158 | } |
| 154 | 159 | |
| 155 | 160 | static inline pte_t pte_mkdirty(pte_t pte) |
| 156 | 161 | { |
| 157 | − return set_pte_bit(pte, __pgprot(PTE_DIRTY)); | |
| 162 | + pte = set_pte_bit(pte, __pgprot(PTE_DIRTY)); | |
| 163 | + | |
| 164 | + if (pte_write(pte)) | |
| 165 | + pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); | |
| 166 | + | |
| 167 | + return pte; | |
| 158 | 168 | } |
| 159 | 169 | |
| 160 | 170 | static inline pte_t pte_mkold(pte_t pte) |
| @@ -207,9 +217,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte) · 46 unmodified lines | ||
| 207 | 217 | } |
| 208 | 218 | } |
| 209 | 219 | |
| 210 | −struct mm_struct; | |
| 211 | −struct vm_area_struct; | |
| 212 | − | |
| 213 | 220 | extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); |
| 214 | 221 | |
| 215 | 222 | /* |
| @@ -238,7 +245,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, · 22 unmodified lines | ||
| 238 | 245 | * hardware updates of the pte (ptep_set_access_flags safely changes |
| 239 | 246 | * valid ptes without going through an invalid entry). |
| 240 | 247 | */ |
| 241 | − if (pte_valid(*ptep) && pte_valid(pte)) { | |
| 248 | + if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(*ptep) && pte_valid(pte) && | |
| 249 | + (mm == current->active_mm || atomic_read(&mm->mm_users) > 1)) { | |
| 242 | 250 | VM_WARN_ONCE(!pte_young(pte), |
| 243 | 251 | "%s: racy access flag clearing: 0x%016llx -> 0x%016llx", |
| 244 | 252 | __func__, pte_val(*ptep), pte_val(pte)); |
| @@ -641,28 +649,23 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, · 396 unmodified lines | ||
| 641 | 649 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| 642 | 650 | |
| 643 | 651 | /* |
| 644 | − * ptep_set_wrprotect - mark read-only while preserving the hardware update of | |
| 645 | − * the Access Flag. | |
| 652 | + * ptep_set_wrprotect - mark read-only while trasferring potential hardware | |
| 653 | + * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit. | |
| 646 | 654 | */ |
| 647 | 655 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT |
| 648 | 656 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep) |
| 649 | 657 | { |
| 650 | 658 | pte_t old_pte, pte; |
| 651 | 659 | |
| 652 | − /* | |
| 653 | − * ptep_set_wrprotect() is only called on CoW mappings which are | |
| 654 | − * private (!VM_SHARED) with the pte either read-only (!PTE_WRITE && | |
| 655 | − * PTE_RDONLY) or writable and software-dirty (PTE_WRITE && | |
| 656 | − * !PTE_RDONLY && PTE_DIRTY); see is_cow_mapping() and | |
| 657 | − * protection_map[]. There is no race with the hardware update of the | |
| 658 | − * dirty state: clearing of PTE_RDONLY when PTE_WRITE (a.k.a. PTE_DBM) | |
| 659 | − * is set. | |
| 660 | − */ | |
| 661 | − VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(*ptep), | |
| 662 | − "%s: potential race with hardware DBM", __func__); | |
| 663 | 660 | pte = READ_ONCE(*ptep); |
| 664 | 661 | do { |
| 665 | 662 | old_pte = pte; |
| 663 | + /* | |
| 664 | + * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY | |
| 665 | + * clear), set the PTE_DIRTY bit. | |
| 666 | + */ | |
| 667 | + if (pte_hw_dirty(pte)) | |
| 668 | + pte = pte_mkdirty(pte); | |
| 666 | 669 | pte = pte_wrprotect(pte); |
| 667 | 670 | pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), |
| 668 | 671 | pte_val(old_pte), pte_val(pte)); |
| @@ -37,6 +37,7 @@ ENTRY(__cpu_soft_restart) · 36 unmodified lines | ||
| 37 | 37 | mrs x12, sctlr_el1 |
| 38 | 38 | ldr x13, =SCTLR_ELx_FLAGS |
| 39 | 39 | bic x12, x12, x13 |
| 40 | + pre_disable_mmu_workaround | |
| 40 | 41 | msr sctlr_el1, x12 |
| 41 | 42 | isb |
| 42 | 43 | |
| @@ -145,7 +145,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { · 144 unmodified lines | ||
| 145 | 145 | }; |
| 146 | 146 | |
| 147 | 147 | static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { |
| 148 | − ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0), | |
| 148 | + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), | |
| 149 | + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0), | |
| 149 | 150 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0), |
| 150 | 151 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI), |
| 151 | 152 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI), |
| @@ -96,6 +96,7 @@ ENTRY(entry) · 95 unmodified lines | ||
| 96 | 96 | mrs x0, sctlr_el2 |
| 97 | 97 | bic x0, x0, #1 << 0 // clear SCTLR.M |
| 98 | 98 | bic x0, x0, #1 << 2 // clear SCTLR.C |
| 99 | + pre_disable_mmu_workaround | |
| 99 | 100 | msr sctlr_el2, x0 |
| 100 | 101 | isb |
| 101 | 102 | b 2f |
| @@ -103,6 +104,7 @@ ENTRY(entry) · 1 unmodified line | ||
| 103 | 104 | mrs x0, sctlr_el1 |
| 104 | 105 | bic x0, x0, #1 << 0 // clear SCTLR.M |
| 105 | 106 | bic x0, x0, #1 << 2 // clear SCTLR.C |
| 107 | + pre_disable_mmu_workaround | |
| 106 | 108 | msr sctlr_el1, x0 |
| 107 | 109 | isb |
| 108 | 110 | 2: |
| @@ -1043,7 +1043,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state) · 1042 unmodified lines | ||
| 1043 | 1043 | |
| 1044 | 1044 | local_bh_disable(); |
| 1045 | 1045 | |
| 1046 | − current->thread.fpsimd_state = *state; | |
| 1046 | + current->thread.fpsimd_state.user_fpsimd = state->user_fpsimd; | |
| 1047 | 1047 | if (system_supports_sve() && test_thread_flag(TIF_SVE)) |
| 1048 | 1048 | fpsimd_to_sve(current); |
| 1049 | 1049 | |
| @@ -750,6 +750,7 @@ __primary_switch: · 749 unmodified lines | ||
| 750 | 750 | * to take into account by discarding the current kernel mapping and |
| 751 | 751 | * creating a new one. |
| 752 | 752 | */ |
| 753 | + pre_disable_mmu_workaround | |
| 753 | 754 | msr sctlr_el1, x20 // disable the MMU |
| 754 | 755 | isb |
| 755 | 756 | bl __create_page_tables // recreate kernel mapping |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/perf_event.h> |
| 29 | 29 | #include <linux/ptrace.h> |
| 30 | 30 | #include <linux/smp.h> |
| 31 | +#include <linux/uaccess.h> | |
| 31 | 32 | |
| 32 | 33 | #include <asm/compat.h> |
| 33 | 34 | #include <asm/current.h> |
| @@ -36,7 +37,6 @@ · 2 unmodified lines | ||
| 36 | 37 | #include <asm/traps.h> |
| 37 | 38 | #include <asm/cputype.h> |
| 38 | 39 | #include <asm/system_misc.h> |
| 39 | −#include <asm/uaccess.h> | |
| 40 | 40 | |
| 41 | 41 | /* Breakpoint currently in use for each BRP. */ |
| 42 | 42 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]); |
| @@ -45,6 +45,7 @@ ENTRY(arm64_relocate_new_kernel) · 44 unmodified lines | ||
| 45 | 45 | mrs x0, sctlr_el2 |
| 46 | 46 | ldr x1, =SCTLR_ELx_FLAGS |
| 47 | 47 | bic x0, x0, x1 |
| 48 | + pre_disable_mmu_workaround | |
| 48 | 49 | msr sctlr_el2, x0 |
| 49 | 50 | isb |
| 50 | 51 | 1: |
| @@ -151,6 +151,7 @@ reset: · 150 unmodified lines | ||
| 151 | 151 | mrs x5, sctlr_el2 |
| 152 | 152 | ldr x6, =SCTLR_ELx_FLAGS |
| 153 | 153 | bic x5, x5, x6 // Clear SCTL_M and etc |
| 154 | + pre_disable_mmu_workaround | |
| 154 | 155 | msr sctlr_el2, x5 |
| 155 | 156 | isb |
| 156 | 157 | |
| @@ -74,6 +74,9 @@ static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1) · 73 unmodified lines | ||
| 74 | 74 | { |
| 75 | 75 | u64 reg; |
| 76 | 76 | |
| 77 | + /* Clear pmscr in case of early return */ | |
| 78 | + *pmscr_el1 = 0; | |
| 79 | + | |
| 77 | 80 | /* SPE present on this CPU? */ |
| 78 | 81 | if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1), |
| 79 | 82 | ID_AA64DFR0_PMSVER_SHIFT)) |
| @@ -389,7 +389,7 @@ void ptdump_check_wx(void) · 388 unmodified lines | ||
| 389 | 389 | .check_wx = true, |
| 390 | 390 | }; |
| 391 | 391 | |
| 392 | − walk_pgd(&st, &init_mm, 0); | |
| 392 | + walk_pgd(&st, &init_mm, VA_START); | |
| 393 | 393 | note_page(&st, 0, 0, 0); |
| 394 | 394 | if (st.wx_pages || st.uxn_pages) |
| 395 | 395 | pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n", |
| @@ -574,7 +574,6 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) · 573 unmodified lines | ||
| 574 | 574 | { |
| 575 | 575 | struct siginfo info; |
| 576 | 576 | const struct fault_info *inf; |
| 577 | − int ret = 0; | |
| 578 | 577 | |
| 579 | 578 | inf = esr_to_fault_info(esr); |
| 580 | 579 | pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n", |
| @@ -589,7 +588,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) · 8 unmodified lines | ||
| 589 | 588 | if (interrupts_enabled(regs)) |
| 590 | 589 | nmi_enter(); |
| 591 | 590 | |
| 592 | − ret = ghes_notify_sea(); | |
| 591 | + ghes_notify_sea(); | |
| 593 | 592 | |
| 594 | 593 | if (interrupts_enabled(regs)) |
| 595 | 594 | nmi_exit(); |
| @@ -604,7 +603,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) · 8 unmodified lines | ||
| 604 | 603 | info.si_addr = (void __user *)addr; |
| 605 | 604 | arm64_notify_die("", regs, &info, esr); |
| 606 | 605 | |
| 607 | − return ret; | |
| 606 | + return 0; | |
| 608 | 607 | } |
| 609 | 608 | |
| 610 | 609 | static const struct fault_info fault_info[] = { |
| @@ -476,6 +476,8 @@ void __init arm64_memblock_init(void) · 475 unmodified lines | ||
| 476 | 476 | |
| 477 | 477 | reserve_elfcorehdr(); |
| 478 | 478 | |
| 479 | + high_memory = __va(memblock_end_of_DRAM() - 1) + 1; | |
| 480 | + | |
| 479 | 481 | dma_contiguous_reserve(arm64_dma_phys_limit); |
| 480 | 482 | |
| 481 | 483 | memblock_allow_resize(); |
| @@ -502,7 +504,6 @@ void __init bootmem_init(void) · 20 unmodified lines | ||
| 502 | 504 | sparse_init(); |
| 503 | 505 | zone_sizes_init(min, max); |
| 504 | 506 | |
| 505 | − high_memory = __va((max << PAGE_SHIFT) - 1) + 1; | |
| 506 | 507 | memblock_dump_all(); |
| 507 | 508 | } |
| 508 | 509 | |
| @@ -123,8 +123,8 @@ int puts(const char *s) · 122 unmodified lines | ||
| 123 | 123 | while ((nuline = strchr(s, '\n')) != NULL) { |
| 124 | 124 | if (nuline != s) |
| 125 | 125 | pdc_iodc_print(s, nuline - s); |
| 126 | − pdc_iodc_print("\r\n", 2); | |
| 127 | − s = nuline + 1; | |
| 126 | + pdc_iodc_print("\r\n", 2); | |
| 127 | + s = nuline + 1; | |
| 128 | 128 | } |
| 129 | 129 | if (*s != '\0') |
| 130 | 130 | pdc_iodc_print(s, strlen(s)); |
| @@ -35,7 +35,12 @@ struct thread_info { · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | /* thread information allocation */ |
| 37 | 37 | |
| 38 | +#ifdef CONFIG_IRQSTACKS | |
| 39 | +#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */ | |
| 40 | +#else | |
| 38 | 41 | #define THREAD_SIZE_ORDER 3 /* PA-RISC requires at least 32k stack */ |
| 42 | +#endif | |
| 43 | + | |
| 39 | 44 | /* Be sure to hunt all references to this down when you change the size of |
| 40 | 45 | * the kernel stack */ |
| 41 | 46 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
| @@ -878,9 +878,6 @@ ENTRY_CFI(syscall_exit_rfi) · 877 unmodified lines | ||
| 878 | 878 | STREG %r19,PT_SR7(%r16) |
| 879 | 879 | |
| 880 | 880 | intr_return: |
| 881 | − /* NOTE: Need to enable interrupts incase we schedule. */ | |
| 882 | − ssm PSW_SM_I, %r0 | |
| 883 | − | |
| 884 | 881 | /* check for reschedule */ |
| 885 | 882 | mfctl %cr30,%r1 |
| 886 | 883 | LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ |
| @@ -907,6 +904,11 @@ intr_check_sig: · 20 unmodified lines | ||
| 907 | 904 | LDREG PT_IASQ1(%r16), %r20 |
| 908 | 905 | cmpib,COND(=),n 0,%r20,intr_restore /* backward */ |
| 909 | 906 | |
| 907 | + /* NOTE: We need to enable interrupts if we have to deliver | |
| 908 | + * signals. We used to do this earlier but it caused kernel | |
| 909 | + * stack overflows. */ | |
| 910 | + ssm PSW_SM_I, %r0 | |
| 911 | + | |
| 910 | 912 | copy %r0, %r25 /* long in_syscall = 0 */ |
| 911 | 913 | #ifdef CONFIG_64BIT |
| 912 | 914 | ldo -16(%r30),%r29 /* Reference param save area */ |
| @@ -958,6 +960,10 @@ intr_do_resched: · 45 unmodified lines | ||
| 958 | 960 | cmpib,COND(=) 0, %r20, intr_do_preempt |
| 959 | 961 | nop |
| 960 | 962 | |
| 963 | + /* NOTE: We need to enable interrupts if we schedule. We used | |
| 964 | + * to do this earlier but it caused kernel stack overflows. */ | |
| 965 | + ssm PSW_SM_I, %r0 | |
| 966 | + | |
| 961 | 967 | #ifdef CONFIG_64BIT |
| 962 | 968 | ldo -16(%r30),%r29 /* Reference param save area */ |
| 963 | 969 | #endif |
| @@ -305,6 +305,7 @@ ENDPROC_CFI(os_hpmc) · 304 unmodified lines | ||
| 305 | 305 | |
| 306 | 306 | |
| 307 | 307 | __INITRODATA |
| 308 | + .align 4 | |
| 308 | 309 | .export os_hpmc_size |
| 309 | 310 | os_hpmc_size: |
| 310 | 311 | .word .os_hpmc_end-.os_hpmc |
| @@ -15,7 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/slab.h> |
| 16 | 16 | #include <linux/kallsyms.h> |
| 17 | 17 | #include <linux/sort.h> |
| 18 | −#include <linux/sched.h> | |
| 19 | 18 | |
| 20 | 19 | #include <linux/uaccess.h> |
| 21 | 20 | #include <asm/assembly.h> |
| @@ -16,9 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/preempt.h> |
| 17 | 17 | #include <linux/init.h> |
| 18 | 18 | |
| 19 | −#include <asm/processor.h> | |
| 20 | 19 | #include <asm/delay.h> |
| 21 | − | |
| 22 | 20 | #include <asm/special_insns.h> /* for mfctl() */ |
| 23 | 21 | #include <asm/processor.h> /* for boot_cpu_data */ |
| 24 | 22 | |
| @@ -160,9 +160,10 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, · 159 unmodified lines | ||
| 160 | 160 | #endif |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | −static inline void arch_dup_mmap(struct mm_struct *oldmm, | |
| 164 | − struct mm_struct *mm) | |
| 163 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, | |
| 164 | + struct mm_struct *mm) | |
| 165 | 165 | { |
| 166 | + return 0; | |
| 166 | 167 | } |
| 167 | 168 | |
| 168 | 169 | #ifndef CONFIG_PPC_BOOK3S_64 |
| @@ -1403,7 +1403,7 @@ void show_regs(struct pt_regs * regs) · 1402 unmodified lines | ||
| 1403 | 1403 | |
| 1404 | 1404 | printk("NIP: "REG" LR: "REG" CTR: "REG"\n", |
| 1405 | 1405 | regs->nip, regs->link, regs->ctr); |
| 1406 | − printk("REGS: %p TRAP: %04lx %s (%s)\n", | |
| 1406 | + printk("REGS: %px TRAP: %04lx %s (%s)\n", | |
| 1407 | 1407 | regs, regs->trap, print_tainted(), init_utsname()->release); |
| 1408 | 1408 | printk("MSR: "REG" ", regs->msr); |
| 1409 | 1409 | print_msr_bits(regs->msr); |
| @@ -725,7 +725,8 @@ u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu) · 724 unmodified lines | ||
| 725 | 725 | |
| 726 | 726 | /* Return the per-cpu state for state saving/migration */ |
| 727 | 727 | return (u64)xc->cppr << KVM_REG_PPC_ICP_CPPR_SHIFT | |
| 728 | − (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT; | |
| 728 | + (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT | | |
| 729 | + (u64)0xff << KVM_REG_PPC_ICP_PPRI_SHIFT; | |
| 729 | 730 | } |
| 730 | 731 | |
| 731 | 732 | int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) |
| @@ -1558,7 +1559,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) · 826 unmodified lines | ||
| 1558 | 1559 | |
| 1559 | 1560 | /* |
| 1560 | 1561 | * Restore P and Q. If the interrupt was pending, we |
| 1561 | − * force both P and Q, which will trigger a resend. | |
| 1562 | + * force Q and !P, which will trigger a resend. | |
| 1562 | 1563 | * |
| 1563 | 1564 | * That means that a guest that had both an interrupt |
| 1564 | 1565 | * pending (queued) and Q set will restore with only |
| @@ -1566,7 +1567,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) · 1 unmodified line | ||
| 1566 | 1567 | * is perfectly fine as coalescing interrupts that haven't |
| 1567 | 1568 | * been presented yet is always allowed. |
| 1568 | 1569 | */ |
| 1569 | − if (val & KVM_XICS_PRESENTED || val & KVM_XICS_PENDING) | |
| 1570 | + if (val & KVM_XICS_PRESENTED && !(val & KVM_XICS_PENDING)) | |
| 1570 | 1571 | state->old_p = true; |
| 1571 | 1572 | if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING) |
| 1572 | 1573 | state->old_q = true; |
| @@ -763,7 +763,8 @@ emit_clear: · 762 unmodified lines | ||
| 763 | 763 | func = (u8 *) __bpf_call_base + imm; |
| 764 | 764 | |
| 765 | 765 | /* Save skb pointer if we need to re-cache skb data */ |
| 766 | − if (bpf_helper_changes_pkt_data(func)) | |
| 766 | + if ((ctx->seen & SEEN_SKB) && | |
| 767 | + bpf_helper_changes_pkt_data(func)) | |
| 767 | 768 | PPC_BPF_STL(3, 1, bpf_jit_stack_local(ctx)); |
| 768 | 769 | |
| 769 | 770 | bpf_jit_emit_func_call(image, ctx, (u64)func); |
| @@ -772,7 +773,8 @@ emit_clear: · 2 unmodified lines | ||
| 772 | 773 | PPC_MR(b2p[BPF_REG_0], 3); |
| 773 | 774 | |
| 774 | 775 | /* refresh skb cache */ |
| 775 | − if (bpf_helper_changes_pkt_data(func)) { | |
| 776 | + if ((ctx->seen & SEEN_SKB) && | |
| 777 | + bpf_helper_changes_pkt_data(func)) { | |
| 776 | 778 | /* reload skb pointer to r3 */ |
| 777 | 779 | PPC_BPF_LL(3, 1, bpf_jit_stack_local(ctx)); |
| 778 | 780 | bpf_jit_emit_skb_loads(image, ctx); |
| @@ -410,8 +410,12 @@ static __u64 power_pmu_bhrb_to(u64 addr) · 409 unmodified lines | ||
| 410 | 410 | int ret; |
| 411 | 411 | __u64 target; |
| 412 | 412 | |
| 413 | − if (is_kernel_addr(addr)) | |
| 414 | − return branch_target((unsigned int *)addr); | |
| 413 | + if (is_kernel_addr(addr)) { | |
| 414 | + if (probe_kernel_read(&instr, (void *)addr, sizeof(instr))) | |
| 415 | + return 0; | |
| 416 | + | |
| 417 | + return branch_target(&instr); | |
| 418 | + } | |
| 415 | 419 | |
| 416 | 420 | /* Userspace: need copy instruction here then translate it */ |
| 417 | 421 | pagefault_disable(); |
| @@ -309,6 +309,19 @@ static int ppc_nest_imc_cpu_offline(unsigned int cpu) · 308 unmodified lines | ||
| 309 | 309 | if (!cpumask_test_and_clear_cpu(cpu, &nest_imc_cpumask)) |
| 310 | 310 | return 0; |
| 311 | 311 | |
| 312 | + /* | |
| 313 | + * Check whether nest_imc is registered. We could end up here if the | |
| 314 | + * cpuhotplug callback registration fails. i.e, callback invokes the | |
| 315 | + * offline path for all successfully registered nodes. At this stage, | |
| 316 | + * nest_imc pmu will not be registered and we should return here. | |
| 317 | + * | |
| 318 | + * We return with a zero since this is not an offline failure. And | |
| 319 | + * cpuhp_setup_state() returns the actual failure reason to the caller, | |
| 320 | + * which in turn will call the cleanup routine. | |
| 321 | + */ | |
| 322 | + if (!nest_pmus) | |
| 323 | + return 0; | |
| 324 | + | |
| 312 | 325 | /* |
| 313 | 326 | * Now that this cpu is one of the designated, |
| 314 | 327 | * find a next cpu a) which is online and b) in same chip. |
| @@ -1171,6 +1184,7 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) · 856 unmodified lines | ||
| 1171 | 1184 | if (nest_pmus == 1) { |
| 1172 | 1185 | cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE); |
| 1173 | 1186 | kfree(nest_imc_refc); |
| 1187 | + kfree(per_nest_pmu_arr); | |
| 1174 | 1188 | } |
| 1175 | 1189 | |
| 1176 | 1190 | if (nest_pmus > 0) |
| @@ -1195,7 +1209,6 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) · 18 unmodified lines | ||
| 1195 | 1209 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); |
| 1196 | 1210 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); |
| 1197 | 1211 | kfree(pmu_ptr); |
| 1198 | − kfree(per_nest_pmu_arr); | |
| 1199 | 1212 | return; |
| 1200 | 1213 | } |
| 1201 | 1214 | |
| @@ -1309,6 +1322,8 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id · 107 unmodified lines | ||
| 1309 | 1322 | ret = nest_pmu_cpumask_init(); |
| 1310 | 1323 | if (ret) { |
| 1311 | 1324 | mutex_unlock(&nest_init_lock); |
| 1325 | + kfree(nest_imc_refc); | |
| 1326 | + kfree(per_nest_pmu_arr); | |
| 1312 | 1327 | goto err_free; |
| 1313 | 1328 | } |
| 1314 | 1329 | } |
| @@ -354,6 +354,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) · 353 unmodified lines | ||
| 354 | 354 | } |
| 355 | 355 | |
| 356 | 356 | static struct lock_class_key fsl_msi_irq_class; |
| 357 | +static struct lock_class_key fsl_msi_irq_request_class; | |
| 357 | 358 | |
| 358 | 359 | static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, |
| 359 | 360 | int offset, int irq_index) |
| @@ -373,7 +374,8 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, · 13 unmodified lines | ||
| 373 | 374 | dev_err(&dev->dev, "No memory for MSI cascade data\n"); |
| 374 | 375 | return -ENOMEM; |
| 375 | 376 | } |
| 376 | − irq_set_lockdep_class(virt_msir, &fsl_msi_irq_class); | |
| 377 | + irq_set_lockdep_class(virt_msir, &fsl_msi_irq_class, | |
| 378 | + &fsl_msi_irq_request_class); | |
| 377 | 379 | cascade_data->index = offset; |
| 378 | 380 | cascade_data->msi_data = msi; |
| 379 | 381 | cascade_data->virq = virt_msir; |
| @@ -38,6 +38,25 @@ · 37 unmodified lines | ||
| 38 | 38 | #define smp_rmb() RISCV_FENCE(r,r) |
| 39 | 39 | #define smp_wmb() RISCV_FENCE(w,w) |
| 40 | 40 | |
| 41 | +/* | |
| 42 | + * This is a very specific barrier: it's currently only used in two places in | |
| 43 | + * the kernel, both in the scheduler. See include/linux/spinlock.h for the two | |
| 44 | + * orderings it guarantees, but the "critical section is RCsc" guarantee | |
| 45 | + * mandates a barrier on RISC-V. The sequence looks like: | |
| 46 | + * | |
| 47 | + * lr.aq lock | |
| 48 | + * sc lock <= LOCKED | |
| 49 | + * smp_mb__after_spinlock() | |
| 50 | + * // critical section | |
| 51 | + * lr lock | |
| 52 | + * sc.rl lock <= UNLOCKED | |
| 53 | + * | |
| 54 | + * The AQ/RL pair provides a RCpc critical section, but there's not really any | |
| 55 | + * way we can take advantage of that here because the ordering is only enforced | |
| 56 | + * on that one lock. Thus, we're just doing a full fence. | |
| 57 | + */ | |
| 58 | +#define smp_mb__after_spinlock() RISCV_FENCE(rw,rw) | |
| 59 | + | |
| 41 | 60 | #include <asm-generic/barrier.h> |
| 42 | 61 | |
| 43 | 62 | #endif /* __ASSEMBLY__ */ |
| @@ -38,10 +38,6 @@ · 37 unmodified lines | ||
| 38 | 38 | #include <asm/tlbflush.h> |
| 39 | 39 | #include <asm/thread_info.h> |
| 40 | 40 | |
| 41 | −#ifdef CONFIG_HVC_RISCV_SBI | |
| 42 | −#include <asm/hvc_riscv_sbi.h> | |
| 43 | −#endif | |
| 44 | − | |
| 45 | 41 | #ifdef CONFIG_DUMMY_CONSOLE |
| 46 | 42 | struct screen_info screen_info = { |
| 47 | 43 | .orig_video_lines = 30, |
| @@ -212,13 +208,6 @@ static void __init setup_bootmem(void) · 164 unmodified lines | ||
| 212 | 208 | |
| 213 | 209 | void __init setup_arch(char **cmdline_p) |
| 214 | 210 | { |
| 215 | −#if defined(CONFIG_HVC_RISCV_SBI) | |
| 216 | − if (likely(early_console == NULL)) { | |
| 217 | − early_console = &riscv_sbi_early_console_dev; | |
| 218 | − register_console(early_console); | |
| 219 | − } | |
| 220 | −#endif | |
| 221 | − | |
| 222 | 211 | #ifdef CONFIG_CMDLINE_BOOL |
| 223 | 212 | #ifdef CONFIG_CMDLINE_OVERRIDE |
| 224 | 213 | strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
| @@ -70,7 +70,7 @@ SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end, · 69 unmodified lines | ||
| 70 | 70 | bool local = (flags & SYS_RISCV_FLUSH_ICACHE_LOCAL) != 0; |
| 71 | 71 | |
| 72 | 72 | /* Check the reserved flags. */ |
| 73 | − if (unlikely(flags & !SYS_RISCV_FLUSH_ICACHE_ALL)) | |
| 73 | + if (unlikely(flags & ~SYS_RISCV_FLUSH_ICACHE_ALL)) | |
| 74 | 74 | return -EINVAL; |
| 75 | 75 | |
| 76 | 76 | flush_icache_mm(mm, local); |
| @@ -1264,12 +1264,6 @@ static inline pud_t pud_mkwrite(pud_t pud) · 1263 unmodified lines | ||
| 1264 | 1264 | return pud; |
| 1265 | 1265 | } |
| 1266 | 1266 | |
| 1267 | −#define pud_write pud_write | |
| 1268 | −static inline int pud_write(pud_t pud) | |
| 1269 | −{ | |
| 1270 | − return (pud_val(pud) & _REGION3_ENTRY_WRITE) != 0; | |
| 1271 | −} | |
| 1272 | − | |
| 1273 | 1267 | static inline pud_t pud_mkclean(pud_t pud) |
| 1274 | 1268 | { |
| 1275 | 1269 | if (pud_large(pud)) { |
| @@ -263,6 +263,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplis · 262 unmodified lines | ||
| 263 | 263 | return retval; |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | + groups_sort(group_info); | |
| 266 | 267 | retval = set_current_groups(group_info); |
| 267 | 268 | put_group_info(group_info); |
| 268 | 269 | |
| @@ -55,8 +55,7 @@ struct bpf_jit { · 54 unmodified lines | ||
| 55 | 55 | #define SEEN_LITERAL 8 /* code uses literals */ |
| 56 | 56 | #define SEEN_FUNC 16 /* calls C functions */ |
| 57 | 57 | #define SEEN_TAIL_CALL 32 /* code uses tail calls */ |
| 58 | −#define SEEN_SKB_CHANGE 64 /* code changes skb data */ | |
| 59 | −#define SEEN_REG_AX 128 /* code uses constant blinding */ | |
| 58 | +#define SEEN_REG_AX 64 /* code uses constant blinding */ | |
| 60 | 59 | #define SEEN_STACK (SEEN_FUNC | SEEN_MEM | SEEN_SKB) |
| 61 | 60 | |
| 62 | 61 | /* |
| @@ -448,12 +447,12 @@ static void bpf_jit_prologue(struct bpf_jit *jit, u32 stack_depth) · 385 unmodified lines | ||
| 448 | 447 | EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, |
| 449 | 448 | REG_15, 152); |
| 450 | 449 | } |
| 451 | − if (jit->seen & SEEN_SKB) | |
| 450 | + if (jit->seen & SEEN_SKB) { | |
| 452 | 451 | emit_load_skb_data_hlen(jit); |
| 453 | − if (jit->seen & SEEN_SKB_CHANGE) | |
| 454 | 452 | /* stg %b1,ST_OFF_SKBP(%r0,%r15) */ |
| 455 | 453 | EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15, |
| 456 | 454 | STK_OFF_SKBP); |
| 455 | + } | |
| 457 | 456 | } |
| 458 | 457 | |
| 459 | 458 | /* |
| @@ -983,8 +982,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i · 523 unmodified lines | ||
| 983 | 982 | EMIT2(0x0d00, REG_14, REG_W1); |
| 984 | 983 | /* lgr %b0,%r2: load return value into %b0 */ |
| 985 | 984 | EMIT4(0xb9040000, BPF_REG_0, REG_2); |
| 986 | − if (bpf_helper_changes_pkt_data((void *)func)) { | |
| 987 | − jit->seen |= SEEN_SKB_CHANGE; | |
| 985 | + if ((jit->seen & SEEN_SKB) && | |
| 986 | + bpf_helper_changes_pkt_data((void *)func)) { | |
| 988 | 987 | /* lg %b1,ST_OFF_SKBP(%r15) */ |
| 989 | 988 | EMIT6_DISP_LH(0xe3000000, 0x0004, BPF_REG_1, REG_0, |
| 990 | 989 | REG_15, STK_OFF_SKBP); |
| @@ -44,8 +44,8 @@ EXPORT_SYMBOL(__arch_hweight32) · 43 unmodified lines | ||
| 44 | 44 | .previous |
| 45 | 45 | |
| 46 | 46 | ENTRY(__arch_hweight64) |
| 47 | − sethi %hi(__sw_hweight16), %g1 | |
| 48 | − jmpl %g1 + %lo(__sw_hweight16), %g0 | |
| 47 | + sethi %hi(__sw_hweight64), %g1 | |
| 48 | + jmpl %g1 + %lo(__sw_hweight64), %g0 | |
| 49 | 49 | nop |
| 50 | 50 | ENDPROC(__arch_hweight64) |
| 51 | 51 | EXPORT_SYMBOL(__arch_hweight64) |
| @@ -113,7 +113,7 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, · 112 unmodified lines | ||
| 113 | 113 | if (!printk_ratelimit()) |
| 114 | 114 | return; |
| 115 | 115 | |
| 116 | − printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", | |
| 116 | + printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x", | |
| 117 | 117 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
| 118 | 118 | tsk->comm, task_pid_nr(tsk), address, |
| 119 | 119 | (void *)regs->pc, (void *)regs->u_regs[UREG_I7], |
| @@ -154,7 +154,7 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, · 153 unmodified lines | ||
| 154 | 154 | if (!printk_ratelimit()) |
| 155 | 155 | return; |
| 156 | 156 | |
| 157 | − printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", | |
| 157 | + printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x", | |
| 158 | 158 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
| 159 | 159 | tsk->comm, task_pid_nr(tsk), address, |
| 160 | 160 | (void *)regs->tpc, (void *)regs->u_regs[UREG_I7], |
| @@ -75,7 +75,7 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, · 74 unmodified lines | ||
| 75 | 75 | if (!(pmd_val(pmd) & _PAGE_VALID)) |
| 76 | 76 | return 0; |
| 77 | 77 | |
| 78 | − if (!pmd_access_permitted(pmd, write)) | |
| 78 | + if (write && !pmd_write(pmd)) | |
| 79 | 79 | return 0; |
| 80 | 80 | |
| 81 | 81 | refs = 0; |
| @@ -114,7 +114,7 @@ static int gup_huge_pud(pud_t *pudp, pud_t pud, unsigned long addr, · 32 unmodified lines | ||
| 114 | 114 | if (!(pud_val(pud) & _PAGE_VALID)) |
| 115 | 115 | return 0; |
| 116 | 116 | |
| 117 | − if (!pud_access_permitted(pud, write)) | |
| 117 | + if (write && !pud_write(pud)) | |
| 118 | 118 | return 0; |
| 119 | 119 | |
| 120 | 120 | refs = 0; |
| @@ -1245,14 +1245,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) · 1244 unmodified lines | ||
| 1245 | 1245 | u8 *func = ((u8 *)__bpf_call_base) + imm; |
| 1246 | 1246 | |
| 1247 | 1247 | ctx->saw_call = true; |
| 1248 | + if (ctx->saw_ld_abs_ind && bpf_helper_changes_pkt_data(func)) | |
| 1249 | + emit_reg_move(bpf2sparc[BPF_REG_1], L7, ctx); | |
| 1248 | 1250 | |
| 1249 | 1251 | emit_call((u32 *)func, ctx); |
| 1250 | 1252 | emit_nop(ctx); |
| 1251 | 1253 | |
| 1252 | 1254 | emit_reg_move(O0, bpf2sparc[BPF_REG_0], ctx); |
| 1253 | 1255 | |
| 1254 | − if (bpf_helper_changes_pkt_data(func) && ctx->saw_ld_abs_ind) | |
| 1255 | − load_skb_regs(ctx, bpf2sparc[BPF_REG_6]); | |
| 1256 | + if (ctx->saw_ld_abs_ind && bpf_helper_changes_pkt_data(func)) | |
| 1257 | + load_skb_regs(ctx, L7); | |
| 1256 | 1258 | break; |
| 1257 | 1259 | } |
| 1258 | 1260 | |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | generic-y += barrier.h |
| 2 | +generic-y += bpf_perf_event.h | |
| 2 | 3 | generic-y += bug.h |
| 3 | 4 | generic-y += clkdev.h |
| 4 | 5 | generic-y += current.h |
| @@ -15,9 +15,10 @@ extern void uml_setup_stubs(struct mm_struct *mm); · 14 unmodified lines | ||
| 15 | 15 | /* |
| 16 | 16 | * Needed since we do not use the asm-generic/mm_hooks.h: |
| 17 | 17 | */ |
| 18 | −static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) | |
| 18 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) | |
| 19 | 19 | { |
| 20 | 20 | uml_setup_stubs(mm); |
| 21 | + return 0; | |
| 21 | 22 | } |
| 22 | 23 | extern void arch_exit_mmap(struct mm_struct *mm); |
| 23 | 24 | static inline void arch_unmap(struct mm_struct *mm, |
| @@ -150,7 +150,7 @@ static void show_segv_info(struct uml_pt_regs *regs) · 149 unmodified lines | ||
| 150 | 150 | if (!printk_ratelimit()) |
| 151 | 151 | return; |
| 152 | 152 | |
| 153 | − printk("%s%s[%d]: segfault at %lx ip %p sp %p error %x", | |
| 153 | + printk("%s%s[%d]: segfault at %lx ip %px sp %px error %x", | |
| 154 | 154 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
| 155 | 155 | tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi), |
| 156 | 156 | (void *)UPT_IP(regs), (void *)UPT_SP(regs), |
| @@ -81,9 +81,10 @@ do { \ · 80 unmodified lines | ||
| 81 | 81 | } \ |
| 82 | 82 | } while (0) |
| 83 | 83 | |
| 84 | −static inline void arch_dup_mmap(struct mm_struct *oldmm, | |
| 85 | − struct mm_struct *mm) | |
| 84 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, | |
| 85 | + struct mm_struct *mm) | |
| 86 | 86 | { |
| 87 | + return 0; | |
| 87 | 88 | } |
| 88 | 89 | |
| 89 | 90 | static inline void arch_unmap(struct mm_struct *mm, |
| @@ -926,7 +926,8 @@ config MAXSMP · 925 unmodified lines | ||
| 926 | 926 | config NR_CPUS |
| 927 | 927 | int "Maximum number of CPUs" if SMP && !MAXSMP |
| 928 | 928 | range 2 8 if SMP && X86_32 && !X86_BIGSMP |
| 929 | − range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK | |
| 929 | + range 2 64 if SMP && X86_32 && X86_BIGSMP | |
| 930 | + range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK && X86_64 | |
| 930 | 931 | range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 |
| 931 | 932 | default "1" if !SMP |
| 932 | 933 | default "8192" if MAXSMP |
| @@ -400,6 +400,7 @@ config UNWINDER_FRAME_POINTER · 399 unmodified lines | ||
| 400 | 400 | config UNWINDER_GUESS |
| 401 | 401 | bool "Guess unwinder" |
| 402 | 402 | depends on EXPERT |
| 403 | + depends on !STACKDEPOT | |
| 403 | 404 | ---help--- |
| 404 | 405 | This option enables the "guess" unwinder for unwinding kernel stack |
| 405 | 406 | traces. It scans the stack and reports every kernel text address it |
| @@ -80,6 +80,7 @@ vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o · 79 unmodified lines | ||
| 80 | 80 | ifdef CONFIG_X86_64 |
| 81 | 81 | vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/pagetable.o |
| 82 | 82 | vmlinux-objs-y += $(obj)/mem_encrypt.o |
| 83 | + vmlinux-objs-y += $(obj)/pgtable_64.o | |
| 83 | 84 | endif |
| 84 | 85 | |
| 85 | 86 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone |
| @@ -305,10 +305,18 @@ ENTRY(startup_64) · 304 unmodified lines | ||
| 305 | 305 | leaq boot_stack_end(%rbx), %rsp |
| 306 | 306 | |
| 307 | 307 | #ifdef CONFIG_X86_5LEVEL |
| 308 | − /* Check if 5-level paging has already enabled */ | |
| 309 | − movq %cr4, %rax | |
| 310 | − testl $X86_CR4_LA57, %eax | |
| 311 | − jnz lvl5 | |
| 308 | + /* | |
| 309 | + * Check if we need to enable 5-level paging. | |
| 310 | + * RSI holds real mode data and need to be preserved across | |
| 311 | + * a function call. | |
| 312 | + */ | |
| 313 | + pushq %rsi | |
| 314 | + call l5_paging_required | |
| 315 | + popq %rsi | |
| 316 | + | |
| 317 | + /* If l5_paging_required() returned zero, we're done here. */ | |
| 318 | + cmpq $0, %rax | |
| 319 | + je lvl5 | |
| 312 | 320 | |
| 313 | 321 | /* |
| 314 | 322 | * At this point we are in long mode with 4-level paging enabled, |
| @@ -169,6 +169,16 @@ void __puthex(unsigned long value) · 168 unmodified lines | ||
| 169 | 169 | } |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | +static bool l5_supported(void) | |
| 173 | +{ | |
| 174 | + /* Check if leaf 7 is supported. */ | |
| 175 | + if (native_cpuid_eax(0) < 7) | |
| 176 | + return 0; | |
| 177 | + | |
| 178 | + /* Check if la57 is supported. */ | |
| 179 | + return native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)); | |
| 180 | +} | |
| 181 | + | |
| 172 | 182 | #if CONFIG_X86_NEED_RELOCS |
| 173 | 183 | static void handle_relocations(void *output, unsigned long output_len, |
| 174 | 184 | unsigned long virt_addr) |
| @@ -362,6 +372,12 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, · 187 unmodified lines | ||
| 362 | 372 | console_init(); |
| 363 | 373 | debug_putstr("early console in extract_kernel\n"); |
| 364 | 374 | |
| 375 | + if (IS_ENABLED(CONFIG_X86_5LEVEL) && !l5_supported()) { | |
| 376 | + error("This linux kernel as configured requires 5-level paging\n" | |
| 377 | + "This CPU does not support the required 'cr4.la57' feature\n" | |
| 378 | + "Unable to boot - please use a kernel appropriate for your CPU\n"); | |
| 379 | + } | |
| 380 | + | |
| 365 | 381 | free_mem_ptr = heap; /* Heap */ |
| 366 | 382 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; |
| 367 | 383 | |
| @@ -23,6 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | */ |
| 24 | 24 | #undef CONFIG_AMD_MEM_ENCRYPT |
| 25 | 25 | |
| 26 | +/* No PAGE_TABLE_ISOLATION support needed either: */ | |
| 27 | +#undef CONFIG_PAGE_TABLE_ISOLATION | |
| 28 | + | |
| 26 | 29 | #include "misc.h" |
| 27 | 30 | |
| 28 | 31 | /* These actually do the work of building the kernel identity maps. */ |
| @@ -0,0 +1,28 @@ | ||
| 1 | +#include <asm/processor.h> | |
| 2 | + | |
| 3 | +/* | |
| 4 | + * __force_order is used by special_insns.h asm code to force instruction | |
| 5 | + * serialization. | |
| 6 | + * | |
| 7 | + * It is not referenced from the code, but GCC < 5 with -fPIE would fail | |
| 8 | + * due to an undefined symbol. Define it to make these ancient GCCs work. | |
| 9 | + */ | |
| 10 | +unsigned long __force_order; | |
| 11 | + | |
| 12 | +int l5_paging_required(void) | |
| 13 | +{ | |
| 14 | + /* Check if leaf 7 is supported. */ | |
| 15 | + | |
| 16 | + if (native_cpuid_eax(0) < 7) | |
| 17 | + return 0; | |
| 18 | + | |
| 19 | + /* Check if la57 is supported. */ | |
| 20 | + if (!(native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) | |
| 21 | + return 0; | |
| 22 | + | |
| 23 | + /* Check if 5-level paging has already been enabled. */ | |
| 24 | + if (native_read_cr4() & X86_CR4_LA57) | |
| 25 | + return 0; | |
| 26 | + | |
| 27 | + return 1; | |
| 28 | +} | |
| @@ -44,9 +44,9 @@ FDINITRD=$6 · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | # Make sure the files actually exist |
| 46 | 46 | verify "$FBZIMAGE" |
| 47 | −verify "$MTOOLSRC" | |
| 48 | 47 | |
| 49 | 48 | genbzdisk() { |
| 49 | + verify "$MTOOLSRC" | |
| 50 | 50 | mformat a: |
| 51 | 51 | syslinux $FIMAGE |
| 52 | 52 | echo "$KCMDLINE" | mcopy - a:syslinux.cfg |
| @@ -57,6 +57,7 @@ genbzdisk() { · 4 unmodified lines | ||
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | genfdimage144() { |
| 60 | + verify "$MTOOLSRC" | |
| 60 | 61 | dd if=/dev/zero of=$FIMAGE bs=1024 count=1440 2> /dev/null |
| 61 | 62 | mformat v: |
| 62 | 63 | syslinux $FIMAGE |
| @@ -68,6 +69,7 @@ genfdimage144() { · 5 unmodified lines | ||
| 68 | 69 | } |
| 69 | 70 | |
| 70 | 71 | genfdimage288() { |
| 72 | + verify "$MTOOLSRC" | |
| 71 | 73 | dd if=/dev/zero of=$FIMAGE bs=1024 count=2880 2> /dev/null |
| 72 | 74 | mformat w: |
| 73 | 75 | syslinux $FIMAGE |
| @@ -78,39 +80,43 @@ genfdimage288() { · 4 unmodified lines | ||
| 78 | 80 | mcopy $FBZIMAGE w:linux |
| 79 | 81 | } |
| 80 | 82 | |
| 81 | −genisoimage() { | |
| 83 | +geniso() { | |
| 82 | 84 | tmp_dir=`dirname $FIMAGE`/isoimage |
| 83 | 85 | rm -rf $tmp_dir |
| 84 | 86 | mkdir $tmp_dir |
| 85 | − for i in lib lib64 share end ; do | |
| 87 | + for i in lib lib64 share ; do | |
| 86 | 88 | for j in syslinux ISOLINUX ; do |
| 87 | 89 | if [ -f /usr/$i/$j/isolinux.bin ] ; then |
| 88 | 90 | isolinux=/usr/$i/$j/isolinux.bin |
| 89 | − cp $isolinux $tmp_dir | |
| 90 | 91 | fi |
| 91 | 92 | done |
| 92 | 93 | for j in syslinux syslinux/modules/bios ; do |
| 93 | 94 | if [ -f /usr/$i/$j/ldlinux.c32 ]; then |
| 94 | 95 | ldlinux=/usr/$i/$j/ldlinux.c32 |
| 95 | − cp $ldlinux $tmp_dir | |
| 96 | 96 | fi |
| 97 | 97 | done |
| 98 | 98 | if [ -n "$isolinux" -a -n "$ldlinux" ] ; then |
| 99 | 99 | break |
| 100 | 100 | fi |
| 101 | − if [ $i = end -a -z "$isolinux" ] ; then | |
| 102 | − echo 'Need an isolinux.bin file, please install syslinux/isolinux.' | |
| 103 | − exit 1 | |
| 104 | − fi | |
| 105 | 101 | done |
| 102 | + if [ -z "$isolinux" ] ; then | |
| 103 | + echo 'Need an isolinux.bin file, please install syslinux/isolinux.' | |
| 104 | + exit 1 | |
| 105 | + fi | |
| 106 | + if [ -z "$ldlinux" ] ; then | |
| 107 | + echo 'Need an ldlinux.c32 file, please install syslinux/isolinux.' | |
| 108 | + exit 1 | |
| 109 | + fi | |
| 110 | + cp $isolinux $tmp_dir | |
| 111 | + cp $ldlinux $tmp_dir | |
| 106 | 112 | cp $FBZIMAGE $tmp_dir/linux |
| 107 | 113 | echo "$KCMDLINE" > $tmp_dir/isolinux.cfg |
| 108 | 114 | if [ -f "$FDINITRD" ] ; then |
| 109 | 115 | cp "$FDINITRD" $tmp_dir/initrd.img |
| 110 | 116 | fi |
| 111 | − mkisofs -J -r -input-charset=utf-8 -quiet -o $FIMAGE -b isolinux.bin \ | |
| 112 | − -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table \ | |
| 113 | − $tmp_dir | |
| 117 | + genisoimage -J -r -input-charset=utf-8 -quiet -o $FIMAGE \ | |
| 118 | + -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 \ | |
| 119 | + -boot-info-table $tmp_dir | |
| 114 | 120 | isohybrid $FIMAGE 2>/dev/null || true |
| 115 | 121 | rm -rf $tmp_dir |
| 116 | 122 | } |
| @@ -119,6 +125,6 @@ case $1 in · 2 unmodified lines | ||
| 119 | 125 | bzdisk) genbzdisk;; |
| 120 | 126 | fdimage144) genfdimage144;; |
| 121 | 127 | fdimage288) genfdimage288;; |
| 122 | − isoimage) genisoimage;; | |
| 128 | + isoimage) geniso;; | |
| 123 | 129 | *) echo 'Unknown image format'; exit 1; |
| 124 | 130 | esac |
| @@ -59,13 +59,6 @@ static int encrypt(struct blkcipher_desc *desc, · 58 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | salsa20_ivsetup(ctx, walk.iv); |
| 61 | 61 | |
| 62 | − if (likely(walk.nbytes == nbytes)) | |
| 63 | − { | |
| 64 | − salsa20_encrypt_bytes(ctx, walk.src.virt.addr, | |
| 65 | − walk.dst.virt.addr, nbytes); | |
| 66 | − return blkcipher_walk_done(desc, &walk, 0); | |
| 67 | − } | |
| 68 | − | |
| 69 | 62 | while (walk.nbytes >= 64) { |
| 70 | 63 | salsa20_encrypt_bytes(ctx, walk.src.virt.addr, |
| 71 | 64 | walk.dst.virt.addr, |
| @@ -1,6 +1,11 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | #include <linux/jump_label.h> |
| 3 | 3 | #include <asm/unwind_hints.h> |
| 4 | +#include <asm/cpufeatures.h> | |
| 5 | +#include <asm/page_types.h> | |
| 6 | +#include <asm/percpu.h> | |
| 7 | +#include <asm/asm-offsets.h> | |
| 8 | +#include <asm/processor-flags.h> | |
| 4 | 9 | |
| 5 | 10 | /* |
| 6 | 11 | |
| @@ -187,6 +192,146 @@ For 32-bit we have the following conventions - kernel is built with · 180 unmodified lines | ||
| 187 | 192 | #endif |
| 188 | 193 | .endm |
| 189 | 194 | |
| 195 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 196 | + | |
| 197 | +/* | |
| 198 | + * PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two | |
| 199 | + * halves: | |
| 200 | + */ | |
| 201 | +#define PTI_SWITCH_PGTABLES_MASK (1<<PAGE_SHIFT) | |
| 202 | +#define PTI_SWITCH_MASK (PTI_SWITCH_PGTABLES_MASK|(1<<X86_CR3_PTI_SWITCH_BIT)) | |
| 203 | + | |
| 204 | +.macro SET_NOFLUSH_BIT reg:req | |
| 205 | + bts $X86_CR3_PCID_NOFLUSH_BIT, \reg | |
| 206 | +.endm | |
| 207 | + | |
| 208 | +.macro ADJUST_KERNEL_CR3 reg:req | |
| 209 | + ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID | |
| 210 | + /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */ | |
| 211 | + andq $(~PTI_SWITCH_MASK), \reg | |
| 212 | +.endm | |
| 213 | + | |
| 214 | +.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req | |
| 215 | + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI | |
| 216 | + mov %cr3, \scratch_reg | |
| 217 | + ADJUST_KERNEL_CR3 \scratch_reg | |
| 218 | + mov \scratch_reg, %cr3 | |
| 219 | +.Lend_\@: | |
| 220 | +.endm | |
| 221 | + | |
| 222 | +#define THIS_CPU_user_pcid_flush_mask \ | |
| 223 | + PER_CPU_VAR(cpu_tlbstate) + TLB_STATE_user_pcid_flush_mask | |
| 224 | + | |
| 225 | +.macro SWITCH_TO_USER_CR3_NOSTACK scratch_reg:req scratch_reg2:req | |
| 226 | + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI | |
| 227 | + mov %cr3, \scratch_reg | |
| 228 | + | |
| 229 | + ALTERNATIVE "jmp .Lwrcr3_\@", "", X86_FEATURE_PCID | |
| 230 | + | |
| 231 | + /* | |
| 232 | + * Test if the ASID needs a flush. | |
| 233 | + */ | |
| 234 | + movq \scratch_reg, \scratch_reg2 | |
| 235 | + andq $(0x7FF), \scratch_reg /* mask ASID */ | |
| 236 | + bt \scratch_reg, THIS_CPU_user_pcid_flush_mask | |
| 237 | + jnc .Lnoflush_\@ | |
| 238 | + | |
| 239 | + /* Flush needed, clear the bit */ | |
| 240 | + btr \scratch_reg, THIS_CPU_user_pcid_flush_mask | |
| 241 | + movq \scratch_reg2, \scratch_reg | |
| 242 | + jmp .Lwrcr3_\@ | |
| 243 | + | |
| 244 | +.Lnoflush_\@: | |
| 245 | + movq \scratch_reg2, \scratch_reg | |
| 246 | + SET_NOFLUSH_BIT \scratch_reg | |
| 247 | + | |
| 248 | +.Lwrcr3_\@: | |
| 249 | + /* Flip the PGD and ASID to the user version */ | |
| 250 | + orq $(PTI_SWITCH_MASK), \scratch_reg | |
| 251 | + mov \scratch_reg, %cr3 | |
| 252 | +.Lend_\@: | |
| 253 | +.endm | |
| 254 | + | |
| 255 | +.macro SWITCH_TO_USER_CR3_STACK scratch_reg:req | |
| 256 | + pushq %rax | |
| 257 | + SWITCH_TO_USER_CR3_NOSTACK scratch_reg=\scratch_reg scratch_reg2=%rax | |
| 258 | + popq %rax | |
| 259 | +.endm | |
| 260 | + | |
| 261 | +.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req | |
| 262 | + ALTERNATIVE "jmp .Ldone_\@", "", X86_FEATURE_PTI | |
| 263 | + movq %cr3, \scratch_reg | |
| 264 | + movq \scratch_reg, \save_reg | |
| 265 | + /* | |
| 266 | + * Is the "switch mask" all zero? That means that both of | |
| 267 | + * these are zero: | |
| 268 | + * | |
| 269 | + * 1. The user/kernel PCID bit, and | |
| 270 | + * 2. The user/kernel "bit" that points CR3 to the | |
| 271 | + * bottom half of the 8k PGD | |
| 272 | + * | |
| 273 | + * That indicates a kernel CR3 value, not a user CR3. | |
| 274 | + */ | |
| 275 | + testq $(PTI_SWITCH_MASK), \scratch_reg | |
| 276 | + jz .Ldone_\@ | |
| 277 | + | |
| 278 | + ADJUST_KERNEL_CR3 \scratch_reg | |
| 279 | + movq \scratch_reg, %cr3 | |
| 280 | + | |
| 281 | +.Ldone_\@: | |
| 282 | +.endm | |
| 283 | + | |
| 284 | +.macro RESTORE_CR3 scratch_reg:req save_reg:req | |
| 285 | + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI | |
| 286 | + | |
| 287 | + ALTERNATIVE "jmp .Lwrcr3_\@", "", X86_FEATURE_PCID | |
| 288 | + | |
| 289 | + /* | |
| 290 | + * KERNEL pages can always resume with NOFLUSH as we do | |
| 291 | + * explicit flushes. | |
| 292 | + */ | |
| 293 | + bt $X86_CR3_PTI_SWITCH_BIT, \save_reg | |
| 294 | + jnc .Lnoflush_\@ | |
| 295 | + | |
| 296 | + /* | |
| 297 | + * Check if there's a pending flush for the user ASID we're | |
| 298 | + * about to set. | |
| 299 | + */ | |
| 300 | + movq \save_reg, \scratch_reg | |
| 301 | + andq $(0x7FF), \scratch_reg | |
| 302 | + bt \scratch_reg, THIS_CPU_user_pcid_flush_mask | |
| 303 | + jnc .Lnoflush_\@ | |
| 304 | + | |
| 305 | + btr \scratch_reg, THIS_CPU_user_pcid_flush_mask | |
| 306 | + jmp .Lwrcr3_\@ | |
| 307 | + | |
| 308 | +.Lnoflush_\@: | |
| 309 | + SET_NOFLUSH_BIT \save_reg | |
| 310 | + | |
| 311 | +.Lwrcr3_\@: | |
| 312 | + /* | |
| 313 | + * The CR3 write could be avoided when not changing its value, | |
| 314 | + * but would require a CR3 read *and* a scratch register. | |
| 315 | + */ | |
| 316 | + movq \save_reg, %cr3 | |
| 317 | +.Lend_\@: | |
| 318 | +.endm | |
| 319 | + | |
| 320 | +#else /* CONFIG_PAGE_TABLE_ISOLATION=n: */ | |
| 321 | + | |
| 322 | +.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req | |
| 323 | +.endm | |
| 324 | +.macro SWITCH_TO_USER_CR3_NOSTACK scratch_reg:req scratch_reg2:req | |
| 325 | +.endm | |
| 326 | +.macro SWITCH_TO_USER_CR3_STACK scratch_reg:req | |
| 327 | +.endm | |
| 328 | +.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req | |
| 329 | +.endm | |
| 330 | +.macro RESTORE_CR3 scratch_reg:req save_reg:req | |
| 331 | +.endm | |
| 332 | + | |
| 333 | +#endif | |
| 334 | + | |
| 190 | 335 | #endif /* CONFIG_X86_64 */ |
| 191 | 336 | |
| 192 | 337 | /* |
| @@ -941,9 +941,10 @@ ENTRY(debug) · 940 unmodified lines | ||
| 941 | 941 | movl %esp, %eax # pt_regs pointer |
| 942 | 942 | |
| 943 | 943 | /* Are we currently on the SYSENTER stack? */ |
| 944 | − PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx) | |
| 945 | − subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ | |
| 946 | − cmpl $SIZEOF_SYSENTER_stack, %ecx | |
| 944 | + movl PER_CPU_VAR(cpu_entry_area), %ecx | |
| 945 | + addl $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx | |
| 946 | + subl %eax, %ecx /* ecx = (end of entry_stack) - esp */ | |
| 947 | + cmpl $SIZEOF_entry_stack, %ecx | |
| 947 | 948 | jb .Ldebug_from_sysenter_stack |
| 948 | 949 | |
| 949 | 950 | TRACE_IRQS_OFF |
| @@ -984,9 +985,10 @@ ENTRY(nmi) · 34 unmodified lines | ||
| 984 | 985 | movl %esp, %eax # pt_regs pointer |
| 985 | 986 | |
| 986 | 987 | /* Are we currently on the SYSENTER stack? */ |
| 987 | − PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx) | |
| 988 | − subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ | |
| 989 | − cmpl $SIZEOF_SYSENTER_stack, %ecx | |
| 988 | + movl PER_CPU_VAR(cpu_entry_area), %ecx | |
| 989 | + addl $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx | |
| 990 | + subl %eax, %ecx /* ecx = (end of entry_stack) - esp */ | |
| 991 | + cmpl $SIZEOF_entry_stack, %ecx | |
| 990 | 992 | jb .Lnmi_from_sysenter_stack |
| 991 | 993 | |
| 992 | 994 | /* Not on SYSENTER stack. */ |
| @@ -23,7 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <asm/segment.h> |
| 24 | 24 | #include <asm/cache.h> |
| 25 | 25 | #include <asm/errno.h> |
| 26 | −#include "calling.h" | |
| 27 | 26 | #include <asm/asm-offsets.h> |
| 28 | 27 | #include <asm/msr.h> |
| 29 | 28 | #include <asm/unistd.h> |
| @@ -40,6 +39,8 @@ · 10 unmodified lines | ||
| 40 | 39 | #include <asm/frame.h> |
| 41 | 40 | #include <linux/err.h> |
| 42 | 41 | |
| 42 | +#include "calling.h" | |
| 43 | + | |
| 43 | 44 | .code64 |
| 44 | 45 | .section .entry.text, "ax" |
| 45 | 46 | |
| @@ -140,6 +141,67 @@ END(native_usergs_sysret64) · 94 unmodified lines | ||
| 140 | 141 | * with them due to bugs in both AMD and Intel CPUs. |
| 141 | 142 | */ |
| 142 | 143 | |
| 144 | + .pushsection .entry_trampoline, "ax" | |
| 145 | + | |
| 146 | +/* | |
| 147 | + * The code in here gets remapped into cpu_entry_area's trampoline. This means | |
| 148 | + * that the assembler and linker have the wrong idea as to where this code | |
| 149 | + * lives (and, in fact, it's mapped more than once, so it's not even at a | |
| 150 | + * fixed address). So we can't reference any symbols outside the entry | |
| 151 | + * trampoline and expect it to work. | |
| 152 | + * | |
| 153 | + * Instead, we carefully abuse %rip-relative addressing. | |
| 154 | + * _entry_trampoline(%rip) refers to the start of the remapped) entry | |
| 155 | + * trampoline. We can thus find cpu_entry_area with this macro: | |
| 156 | + */ | |
| 157 | + | |
| 158 | +#define CPU_ENTRY_AREA \ | |
| 159 | + _entry_trampoline - CPU_ENTRY_AREA_entry_trampoline(%rip) | |
| 160 | + | |
| 161 | +/* The top word of the SYSENTER stack is hot and is usable as scratch space. */ | |
| 162 | +#define RSP_SCRATCH CPU_ENTRY_AREA_entry_stack + \ | |
| 163 | + SIZEOF_entry_stack - 8 + CPU_ENTRY_AREA | |
| 164 | + | |
| 165 | +ENTRY(entry_SYSCALL_64_trampoline) | |
| 166 | + UNWIND_HINT_EMPTY | |
| 167 | + swapgs | |
| 168 | + | |
| 169 | + /* Stash the user RSP. */ | |
| 170 | + movq %rsp, RSP_SCRATCH | |
| 171 | + | |
| 172 | + /* Note: using %rsp as a scratch reg. */ | |
| 173 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp | |
| 174 | + | |
| 175 | + /* Load the top of the task stack into RSP */ | |
| 176 | + movq CPU_ENTRY_AREA_tss + TSS_sp1 + CPU_ENTRY_AREA, %rsp | |
| 177 | + | |
| 178 | + /* Start building the simulated IRET frame. */ | |
| 179 | + pushq $__USER_DS /* pt_regs->ss */ | |
| 180 | + pushq RSP_SCRATCH /* pt_regs->sp */ | |
| 181 | + pushq %r11 /* pt_regs->flags */ | |
| 182 | + pushq $__USER_CS /* pt_regs->cs */ | |
| 183 | + pushq %rcx /* pt_regs->ip */ | |
| 184 | + | |
| 185 | + /* | |
| 186 | + * x86 lacks a near absolute jump, and we can't jump to the real | |
| 187 | + * entry text with a relative jump. We could push the target | |
| 188 | + * address and then use retq, but this destroys the pipeline on | |
| 189 | + * many CPUs (wasting over 20 cycles on Sandy Bridge). Instead, | |
| 190 | + * spill RDI and restore it in a second-stage trampoline. | |
| 191 | + */ | |
| 192 | + pushq %rdi | |
| 193 | + movq $entry_SYSCALL_64_stage2, %rdi | |
| 194 | + jmp *%rdi | |
| 195 | +END(entry_SYSCALL_64_trampoline) | |
| 196 | + | |
| 197 | + .popsection | |
| 198 | + | |
| 199 | +ENTRY(entry_SYSCALL_64_stage2) | |
| 200 | + UNWIND_HINT_EMPTY | |
| 201 | + popq %rdi | |
| 202 | + jmp entry_SYSCALL_64_after_hwframe | |
| 203 | +END(entry_SYSCALL_64_stage2) | |
| 204 | + | |
| 143 | 205 | ENTRY(entry_SYSCALL_64) |
| 144 | 206 | UNWIND_HINT_EMPTY |
| 145 | 207 | /* |
| @@ -149,6 +211,10 @@ ENTRY(entry_SYSCALL_64) · 3 unmodified lines | ||
| 149 | 211 | */ |
| 150 | 212 | |
| 151 | 213 | swapgs |
| 214 | + /* | |
| 215 | + * This path is not taken when PAGE_TABLE_ISOLATION is disabled so it | |
| 216 | + * is not required to switch CR3. | |
| 217 | + */ | |
| 152 | 218 | movq %rsp, PER_CPU_VAR(rsp_scratch) |
| 153 | 219 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| 154 | 220 | |
| @@ -330,8 +396,25 @@ syscall_return_via_sysret: · 175 unmodified lines | ||
| 330 | 396 | popq %rsi /* skip rcx */ |
| 331 | 397 | popq %rdx |
| 332 | 398 | popq %rsi |
| 399 | + | |
| 400 | + /* | |
| 401 | + * Now all regs are restored except RSP and RDI. | |
| 402 | + * Save old stack pointer and switch to trampoline stack. | |
| 403 | + */ | |
| 404 | + movq %rsp, %rdi | |
| 405 | + movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp | |
| 406 | + | |
| 407 | + pushq RSP-RDI(%rdi) /* RSP */ | |
| 408 | + pushq (%rdi) /* RDI */ | |
| 409 | + | |
| 410 | + /* | |
| 411 | + * We are on the trampoline stack. All regs except RDI are live. | |
| 412 | + * We can do future final exit work right here. | |
| 413 | + */ | |
| 414 | + SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi | |
| 415 | + | |
| 333 | 416 | popq %rdi |
| 334 | − movq RSP-ORIG_RAX(%rsp), %rsp | |
| 417 | + popq %rsp | |
| 335 | 418 | USERGS_SYSRET64 |
| 336 | 419 | END(entry_SYSCALL_64) |
| 337 | 420 | |
| @@ -466,12 +549,13 @@ END(irq_entries_start) · 128 unmodified lines | ||
| 466 | 549 | |
| 467 | 550 | .macro DEBUG_ENTRY_ASSERT_IRQS_OFF |
| 468 | 551 | #ifdef CONFIG_DEBUG_ENTRY |
| 469 | − pushfq | |
| 470 | − testl $X86_EFLAGS_IF, (%rsp) | |
| 552 | + pushq %rax | |
| 553 | + SAVE_FLAGS(CLBR_RAX) | |
| 554 | + testl $X86_EFLAGS_IF, %eax | |
| 471 | 555 | jz .Lokay_\@ |
| 472 | 556 | ud2 |
| 473 | 557 | .Lokay_\@: |
| 474 | − addq $8, %rsp | |
| 558 | + popq %rax | |
| 475 | 559 | #endif |
| 476 | 560 | .endm |
| 477 | 561 | |
| @@ -563,6 +647,13 @@ END(irq_entries_start) · 85 unmodified lines | ||
| 563 | 647 | /* 0(%rsp): ~(interrupt number) */ |
| 564 | 648 | .macro interrupt func |
| 565 | 649 | cld |
| 650 | + | |
| 651 | + testb $3, CS-ORIG_RAX(%rsp) | |
| 652 | + jz 1f | |
| 653 | + SWAPGS | |
| 654 | + call switch_to_thread_stack | |
| 655 | +1: | |
| 656 | + | |
| 566 | 657 | ALLOC_PT_GPREGS_ON_STACK |
| 567 | 658 | SAVE_C_REGS |
| 568 | 659 | SAVE_EXTRA_REGS |
| @@ -572,12 +663,8 @@ END(irq_entries_start) · 3 unmodified lines | ||
| 572 | 663 | jz 1f |
| 573 | 664 | |
| 574 | 665 | /* |
| 575 | − * IRQ from user mode. Switch to kernel gsbase and inform context | |
| 576 | − * tracking that we're in kernel mode. | |
| 577 | − */ | |
| 578 | − SWAPGS | |
| 579 | − | |
| 580 | − /* | |
| 666 | + * IRQ from user mode. | |
| 667 | + * | |
| 581 | 668 | * We need to tell lockdep that IRQs are off. We can't do this until |
| 582 | 669 | * we fix gsbase, and we should do it before enter_from_user_mode |
| 583 | 670 | * (which can take locks). Since TRACE_IRQS_OFF idempotent, |
| @@ -630,10 +717,43 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode) · 46 unmodified lines | ||
| 630 | 717 | ud2 |
| 631 | 718 | 1: |
| 632 | 719 | #endif |
| 633 | − SWAPGS | |
| 634 | 720 | POP_EXTRA_REGS |
| 635 | − POP_C_REGS | |
| 636 | − addq $8, %rsp /* skip regs->orig_ax */ | |
| 721 | + popq %r11 | |
| 722 | + popq %r10 | |
| 723 | + popq %r9 | |
| 724 | + popq %r8 | |
| 725 | + popq %rax | |
| 726 | + popq %rcx | |
| 727 | + popq %rdx | |
| 728 | + popq %rsi | |
| 729 | + | |
| 730 | + /* | |
| 731 | + * The stack is now user RDI, orig_ax, RIP, CS, EFLAGS, RSP, SS. | |
| 732 | + * Save old stack pointer and switch to trampoline stack. | |
| 733 | + */ | |
| 734 | + movq %rsp, %rdi | |
| 735 | + movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp | |
| 736 | + | |
| 737 | + /* Copy the IRET frame to the trampoline stack. */ | |
| 738 | + pushq 6*8(%rdi) /* SS */ | |
| 739 | + pushq 5*8(%rdi) /* RSP */ | |
| 740 | + pushq 4*8(%rdi) /* EFLAGS */ | |
| 741 | + pushq 3*8(%rdi) /* CS */ | |
| 742 | + pushq 2*8(%rdi) /* RIP */ | |
| 743 | + | |
| 744 | + /* Push user RDI on the trampoline stack. */ | |
| 745 | + pushq (%rdi) | |
| 746 | + | |
| 747 | + /* | |
| 748 | + * We are on the trampoline stack. All regs except RDI are live. | |
| 749 | + * We can do future final exit work right here. | |
| 750 | + */ | |
| 751 | + | |
| 752 | + SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi | |
| 753 | + | |
| 754 | + /* Restore RDI. */ | |
| 755 | + popq %rdi | |
| 756 | + SWAPGS | |
| 637 | 757 | INTERRUPT_RETURN |
| 638 | 758 | |
| 639 | 759 | |
| @@ -713,7 +833,9 @@ native_irq_return_ldt: · 73 unmodified lines | ||
| 713 | 833 | */ |
| 714 | 834 | |
| 715 | 835 | pushq %rdi /* Stash user RDI */ |
| 716 | − SWAPGS | |
| 836 | + SWAPGS /* to kernel GS */ | |
| 837 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi /* to kernel CR3 */ | |
| 838 | + | |
| 717 | 839 | movq PER_CPU_VAR(espfix_waddr), %rdi |
| 718 | 840 | movq %rax, (0*8)(%rdi) /* user RAX */ |
| 719 | 841 | movq (1*8)(%rsp), %rax /* user RIP */ |
| @@ -729,7 +851,6 @@ native_irq_return_ldt: · 9 unmodified lines | ||
| 729 | 851 | /* Now RAX == RSP. */ |
| 730 | 852 | |
| 731 | 853 | andl $0xffff0000, %eax /* RAX = (RSP & 0xffff0000) */ |
| 732 | − popq %rdi /* Restore user RDI */ | |
| 733 | 854 | |
| 734 | 855 | /* |
| 735 | 856 | * espfix_stack[31:16] == 0. The page tables are set up such that |
| @@ -740,7 +861,11 @@ native_irq_return_ldt: · 4 unmodified lines | ||
| 740 | 861 | * still points to an RO alias of the ESPFIX stack. |
| 741 | 862 | */ |
| 742 | 863 | orq PER_CPU_VAR(espfix_stack), %rax |
| 743 | − SWAPGS | |
| 864 | + | |
| 865 | + SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi | |
| 866 | + SWAPGS /* to user GS */ | |
| 867 | + popq %rdi /* Restore user RDI */ | |
| 868 | + | |
| 744 | 869 | movq %rax, %rsp |
| 745 | 870 | UNWIND_HINT_IRET_REGS offset=8 |
| 746 | 871 | |
| @@ -829,7 +954,35 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt · 82 unmodified lines | ||
| 829 | 954 | /* |
| 830 | 955 | * Exception entry points. |
| 831 | 956 | */ |
| 832 | −#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) | |
| 957 | +#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8) | |
| 958 | + | |
| 959 | +/* | |
| 960 | + * Switch to the thread stack. This is called with the IRET frame and | |
| 961 | + * orig_ax on the stack. (That is, RDI..R12 are not on the stack and | |
| 962 | + * space has not been allocated for them.) | |
| 963 | + */ | |
| 964 | +ENTRY(switch_to_thread_stack) | |
| 965 | + UNWIND_HINT_FUNC | |
| 966 | + | |
| 967 | + pushq %rdi | |
| 968 | + /* Need to switch before accessing the thread stack. */ | |
| 969 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi | |
| 970 | + movq %rsp, %rdi | |
| 971 | + movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp | |
| 972 | + UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI | |
| 973 | + | |
| 974 | + pushq 7*8(%rdi) /* regs->ss */ | |
| 975 | + pushq 6*8(%rdi) /* regs->rsp */ | |
| 976 | + pushq 5*8(%rdi) /* regs->eflags */ | |
| 977 | + pushq 4*8(%rdi) /* regs->cs */ | |
| 978 | + pushq 3*8(%rdi) /* regs->ip */ | |
| 979 | + pushq 2*8(%rdi) /* regs->orig_ax */ | |
| 980 | + pushq 8(%rdi) /* return address */ | |
| 981 | + UNWIND_HINT_FUNC | |
| 982 | + | |
| 983 | + movq (%rdi), %rdi | |
| 984 | + ret | |
| 985 | +END(switch_to_thread_stack) | |
| 833 | 986 | |
| 834 | 987 | .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 |
| 835 | 988 | ENTRY(\sym) |
| @@ -848,11 +1001,12 @@ ENTRY(\sym) · 12 unmodified lines | ||
| 848 | 1001 | |
| 849 | 1002 | ALLOC_PT_GPREGS_ON_STACK |
| 850 | 1003 | |
| 851 | − .if \paranoid | |
| 852 | − .if \paranoid == 1 | |
| 1004 | + .if \paranoid < 2 | |
| 853 | 1005 | testb $3, CS(%rsp) /* If coming from userspace, switch stacks */ |
| 854 | − jnz 1f | |
| 1006 | + jnz .Lfrom_usermode_switch_stack_\@ | |
| 855 | 1007 | .endif |
| 1008 | + | |
| 1009 | + .if \paranoid | |
| 856 | 1010 | call paranoid_entry |
| 857 | 1011 | .else |
| 858 | 1012 | call error_entry |
| @@ -894,20 +1048,15 @@ ENTRY(\sym) · 35 unmodified lines | ||
| 894 | 1048 | jmp error_exit |
| 895 | 1049 | .endif |
| 896 | 1050 | |
| 897 | − .if \paranoid == 1 | |
| 1051 | + .if \paranoid < 2 | |
| 898 | 1052 | /* |
| 899 | − * Paranoid entry from userspace. Switch stacks and treat it | |
| 1053 | + * Entry from userspace. Switch stacks and treat it | |
| 900 | 1054 | * as a normal entry. This means that paranoid handlers |
| 901 | 1055 | * run in real process context if user_mode(regs). |
| 902 | 1056 | */ |
| 903 | −1: | |
| 1057 | +.Lfrom_usermode_switch_stack_\@: | |
| 904 | 1058 | call error_entry |
| 905 | 1059 | |
| 906 | − | |
| 907 | − movq %rsp, %rdi /* pt_regs pointer */ | |
| 908 | − call sync_regs | |
| 909 | − movq %rax, %rsp /* switch stack */ | |
| 910 | − | |
| 911 | 1060 | movq %rsp, %rdi /* pt_regs pointer */ |
| 912 | 1061 | |
| 913 | 1062 | .if \has_error_code |
| @@ -1119,7 +1268,11 @@ ENTRY(paranoid_entry) · 205 unmodified lines | ||
| 1119 | 1268 | js 1f /* negative -> in kernel */ |
| 1120 | 1269 | SWAPGS |
| 1121 | 1270 | xorl %ebx, %ebx |
| 1122 | −1: ret | |
| 1271 | + | |
| 1272 | +1: | |
| 1273 | + SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14 | |
| 1274 | + | |
| 1275 | + ret | |
| 1123 | 1276 | END(paranoid_entry) |
| 1124 | 1277 | |
| 1125 | 1278 | /* |
| @@ -1141,6 +1294,7 @@ ENTRY(paranoid_exit) · 15 unmodified lines | ||
| 1141 | 1294 | testl %ebx, %ebx /* swapgs needed? */ |
| 1142 | 1295 | jnz .Lparanoid_exit_no_swapgs |
| 1143 | 1296 | TRACE_IRQS_IRETQ |
| 1297 | + RESTORE_CR3 scratch_reg=%rbx save_reg=%r14 | |
| 1144 | 1298 | SWAPGS_UNSAFE_STACK |
| 1145 | 1299 | jmp .Lparanoid_exit_restore |
| 1146 | 1300 | .Lparanoid_exit_no_swapgs: |
| @@ -1168,8 +1322,18 @@ ENTRY(error_entry) · 21 unmodified lines | ||
| 1168 | 1322 | * from user mode due to an IRET fault. |
| 1169 | 1323 | */ |
| 1170 | 1324 | SWAPGS |
| 1325 | + /* We have user CR3. Change to kernel CR3. */ | |
| 1326 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rax | |
| 1171 | 1327 | |
| 1172 | 1328 | .Lerror_entry_from_usermode_after_swapgs: |
| 1329 | + /* Put us onto the real thread stack. */ | |
| 1330 | + popq %r12 /* save return addr in %12 */ | |
| 1331 | + movq %rsp, %rdi /* arg0 = pt_regs pointer */ | |
| 1332 | + call sync_regs | |
| 1333 | + movq %rax, %rsp /* switch stack */ | |
| 1334 | + ENCODE_FRAME_POINTER | |
| 1335 | + pushq %r12 | |
| 1336 | + | |
| 1173 | 1337 | /* |
| 1174 | 1338 | * We need to tell lockdep that IRQs are off. We can't do this until |
| 1175 | 1339 | * we fix gsbase, and we should do it before enter_from_user_mode |
| @@ -1206,6 +1370,7 @@ ENTRY(error_entry) · 30 unmodified lines | ||
| 1206 | 1370 | * .Lgs_change's error handler with kernel gsbase. |
| 1207 | 1371 | */ |
| 1208 | 1372 | SWAPGS |
| 1373 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rax | |
| 1209 | 1374 | jmp .Lerror_entry_done |
| 1210 | 1375 | |
| 1211 | 1376 | .Lbstep_iret: |
| @@ -1215,10 +1380,11 @@ ENTRY(error_entry) · 3 unmodified lines | ||
| 1215 | 1380 | |
| 1216 | 1381 | .Lerror_bad_iret: |
| 1217 | 1382 | /* |
| 1218 | − * We came from an IRET to user mode, so we have user gsbase. | |
| 1219 | − * Switch to kernel gsbase: | |
| 1383 | + * We came from an IRET to user mode, so we have user | |
| 1384 | + * gsbase and CR3. Switch to kernel gsbase and CR3: | |
| 1220 | 1385 | */ |
| 1221 | 1386 | SWAPGS |
| 1387 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rax | |
| 1222 | 1388 | |
| 1223 | 1389 | /* |
| 1224 | 1390 | * Pretend that the exception came from user mode: set up pt_regs |
| @@ -1250,6 +1416,10 @@ END(error_exit) · 25 unmodified lines | ||
| 1250 | 1416 | /* |
| 1251 | 1417 | * Runs on exception stack. Xen PV does not go through this path at all, |
| 1252 | 1418 | * so we can use real assembly here. |
| 1419 | + * | |
| 1420 | + * Registers: | |
| 1421 | + * %r14: Used to save/restore the CR3 of the interrupted context | |
| 1422 | + * when PAGE_TABLE_ISOLATION is in use. Do not clobber. | |
| 1253 | 1423 | */ |
| 1254 | 1424 | ENTRY(nmi) |
| 1255 | 1425 | UNWIND_HINT_IRET_REGS |
| @@ -1313,6 +1483,7 @@ ENTRY(nmi) · 57 unmodified lines | ||
| 1313 | 1483 | |
| 1314 | 1484 | swapgs |
| 1315 | 1485 | cld |
| 1486 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx | |
| 1316 | 1487 | movq %rsp, %rdx |
| 1317 | 1488 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| 1318 | 1489 | UNWIND_HINT_IRET_REGS base=%rdx offset=8 |
| @@ -1565,6 +1736,8 @@ end_repeat_nmi: · 246 unmodified lines | ||
| 1565 | 1736 | movq $-1, %rsi |
| 1566 | 1737 | call do_nmi |
| 1567 | 1738 | |
| 1739 | + RESTORE_CR3 scratch_reg=%r15 save_reg=%r14 | |
| 1740 | + | |
| 1568 | 1741 | testl %ebx, %ebx /* swapgs needed? */ |
| 1569 | 1742 | jnz nmi_restore |
| 1570 | 1743 | nmi_swapgs: |
| @@ -48,7 +48,11 @@ · 47 unmodified lines | ||
| 48 | 48 | */ |
| 49 | 49 | ENTRY(entry_SYSENTER_compat) |
| 50 | 50 | /* Interrupts are off on entry. */ |
| 51 | − SWAPGS_UNSAFE_STACK | |
| 51 | + SWAPGS | |
| 52 | + | |
| 53 | + /* We are about to clobber %rsp anyway, clobbering here is OK */ | |
| 54 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp | |
| 55 | + | |
| 52 | 56 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| 53 | 57 | |
| 54 | 58 | /* |
| @@ -215,6 +219,12 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) · 160 unmodified lines | ||
| 215 | 219 | pushq $0 /* pt_regs->r14 = 0 */ |
| 216 | 220 | pushq $0 /* pt_regs->r15 = 0 */ |
| 217 | 221 | |
| 222 | + /* | |
| 223 | + * We just saved %rdi so it is safe to clobber. It is not | |
| 224 | + * preserved during the C calls inside TRACE_IRQS_OFF anyway. | |
| 225 | + */ | |
| 226 | + SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi | |
| 227 | + | |
| 218 | 228 | /* |
| 219 | 229 | * User mode is traced as though IRQs are on, and SYSENTER |
| 220 | 230 | * turned them off. |
| @@ -256,10 +266,22 @@ sysret32_from_system_call: · 35 unmodified lines | ||
| 256 | 266 | * when the system call started, which is already known to user |
| 257 | 267 | * code. We zero R8-R10 to avoid info leaks. |
| 258 | 268 | */ |
| 269 | + movq RSP-ORIG_RAX(%rsp), %rsp | |
| 270 | + | |
| 271 | + /* | |
| 272 | + * The original userspace %rsp (RSP-ORIG_RAX(%rsp)) is stored | |
| 273 | + * on the process stack which is not mapped to userspace and | |
| 274 | + * not readable after we SWITCH_TO_USER_CR3. Delay the CR3 | |
| 275 | + * switch until after after the last reference to the process | |
| 276 | + * stack. | |
| 277 | + * | |
| 278 | + * %r8/%r9 are zeroed before the sysret, thus safe to clobber. | |
| 279 | + */ | |
| 280 | + SWITCH_TO_USER_CR3_NOSTACK scratch_reg=%r8 scratch_reg2=%r9 | |
| 281 | + | |
| 259 | 282 | xorq %r8, %r8 |
| 260 | 283 | xorq %r9, %r9 |
| 261 | 284 | xorq %r10, %r10 |
| 262 | − movq RSP-ORIG_RAX(%rsp), %rsp | |
| 263 | 285 | swapgs |
| 264 | 286 | sysretl |
| 265 | 287 | END(entry_SYSCALL_compat) |
| @@ -306,8 +328,11 @@ ENTRY(entry_INT80_compat) · 40 unmodified lines | ||
| 306 | 328 | */ |
| 307 | 329 | movl %eax, %eax |
| 308 | 330 | |
| 309 | − /* Construct struct pt_regs on stack (iret frame is already on stack) */ | |
| 310 | 331 | pushq %rax /* pt_regs->orig_ax */ |
| 332 | + | |
| 333 | + /* switch to thread stack expects orig_ax to be pushed */ | |
| 334 | + call switch_to_thread_stack | |
| 335 | + | |
| 311 | 336 | pushq %rdi /* pt_regs->di */ |
| 312 | 337 | pushq %rsi /* pt_regs->si */ |
| 313 | 338 | pushq %rdx /* pt_regs->dx */ |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <asm/unistd.h> |
| 38 | 38 | #include <asm/fixmap.h> |
| 39 | 39 | #include <asm/traps.h> |
| 40 | +#include <asm/paravirt.h> | |
| 40 | 41 | |
| 41 | 42 | #define CREATE_TRACE_POINTS |
| 42 | 43 | #include "vsyscall_trace.h" |
| @@ -138,6 +139,10 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) · 95 unmodified lines | ||
| 138 | 139 | |
| 139 | 140 | WARN_ON_ONCE(address != regs->ip); |
| 140 | 141 | |
| 142 | + /* This should be unreachable in NATIVE mode. */ | |
| 143 | + if (WARN_ON(vsyscall_mode == NATIVE)) | |
| 144 | + return false; | |
| 145 | + | |
| 141 | 146 | if (vsyscall_mode == NONE) { |
| 142 | 147 | warn_bad_vsyscall(KERN_INFO, regs, |
| 143 | 148 | "vsyscall attempted with vsyscall=none"); |
| @@ -329,16 +334,47 @@ int in_gate_area_no_mm(unsigned long addr) · 185 unmodified lines | ||
| 329 | 334 | return vsyscall_mode != NONE && (addr & PAGE_MASK) == VSYSCALL_ADDR; |
| 330 | 335 | } |
| 331 | 336 | |
| 337 | +/* | |
| 338 | + * The VSYSCALL page is the only user-accessible page in the kernel address | |
| 339 | + * range. Normally, the kernel page tables can have _PAGE_USER clear, but | |
| 340 | + * the tables covering VSYSCALL_ADDR need _PAGE_USER set if vsyscalls | |
| 341 | + * are enabled. | |
| 342 | + * | |
| 343 | + * Some day we may create a "minimal" vsyscall mode in which we emulate | |
| 344 | + * vsyscalls but leave the page not present. If so, we skip calling | |
| 345 | + * this. | |
| 346 | + */ | |
| 347 | +void __init set_vsyscall_pgtable_user_bits(pgd_t *root) | |
| 348 | +{ | |
| 349 | + pgd_t *pgd; | |
| 350 | + p4d_t *p4d; | |
| 351 | + pud_t *pud; | |
| 352 | + pmd_t *pmd; | |
| 353 | + | |
| 354 | + pgd = pgd_offset_pgd(root, VSYSCALL_ADDR); | |
| 355 | + set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER)); | |
| 356 | + p4d = p4d_offset(pgd, VSYSCALL_ADDR); | |
| 357 | +#if CONFIG_PGTABLE_LEVELS >= 5 | |
| 358 | + p4d->p4d |= _PAGE_USER; | |
| 359 | +#endif | |
| 360 | + pud = pud_offset(p4d, VSYSCALL_ADDR); | |
| 361 | + set_pud(pud, __pud(pud_val(*pud) | _PAGE_USER)); | |
| 362 | + pmd = pmd_offset(pud, VSYSCALL_ADDR); | |
| 363 | + set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_USER)); | |
| 364 | +} | |
| 365 | + | |
| 332 | 366 | void __init map_vsyscall(void) |
| 333 | 367 | { |
| 334 | 368 | extern char __vsyscall_page; |
| 335 | 369 | unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); |
| 336 | 370 | |
| 337 | − if (vsyscall_mode != NONE) | |
| 371 | + if (vsyscall_mode != NONE) { | |
| 338 | 372 | __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, |
| 339 | 373 | vsyscall_mode == NATIVE |
| 340 | 374 | ? PAGE_KERNEL_VSYSCALL |
| 341 | 375 | : PAGE_KERNEL_VVAR); |
| 376 | + set_vsyscall_pgtable_user_bits(swapper_pg_dir); | |
| 377 | + } | |
| 342 | 378 | |
| 343 | 379 | BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) != |
| 344 | 380 | (unsigned long)VSYSCALL_ADDR); |
| @@ -3847,6 +3847,8 @@ static struct attribute *intel_pmu_attrs[] = { · 3846 unmodified lines | ||
| 3847 | 3847 | |
| 3848 | 3848 | __init int intel_pmu_init(void) |
| 3849 | 3849 | { |
| 3850 | + struct attribute **extra_attr = NULL; | |
| 3851 | + struct attribute **to_free = NULL; | |
| 3850 | 3852 | union cpuid10_edx edx; |
| 3851 | 3853 | union cpuid10_eax eax; |
| 3852 | 3854 | union cpuid10_ebx ebx; |
| @@ -3854,7 +3856,6 @@ __init int intel_pmu_init(void) · 1 unmodified line | ||
| 3854 | 3856 | unsigned int unused; |
| 3855 | 3857 | struct extra_reg *er; |
| 3856 | 3858 | int version, i; |
| 3857 | − struct attribute **extra_attr = NULL; | |
| 3858 | 3859 | char *name; |
| 3859 | 3860 | |
| 3860 | 3861 | if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { |
| @@ -4294,6 +4295,7 @@ __init int intel_pmu_init(void) · 433 unmodified lines | ||
| 4294 | 4295 | extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? |
| 4295 | 4296 | hsw_format_attr : nhm_format_attr; |
| 4296 | 4297 | extra_attr = merge_attr(extra_attr, skl_format_attr); |
| 4298 | + to_free = extra_attr; | |
| 4297 | 4299 | x86_pmu.cpu_events = get_hsw_events_attrs(); |
| 4298 | 4300 | intel_pmu_pebs_data_source_skl( |
| 4299 | 4301 | boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); |
| @@ -4401,6 +4403,7 @@ __init int intel_pmu_init(void) · 101 unmodified lines | ||
| 4401 | 4403 | pr_cont("full-width counters, "); |
| 4402 | 4404 | } |
| 4403 | 4405 | |
| 4406 | + kfree(to_free); | |
| 4404 | 4407 | return 0; |
| 4405 | 4408 | } |
| 4406 | 4409 | |
| @@ -3,16 +3,18 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/types.h> |
| 4 | 4 | #include <linux/slab.h> |
| 5 | 5 | |
| 6 | +#include <asm/cpu_entry_area.h> | |
| 6 | 7 | #include <asm/perf_event.h> |
| 7 | 8 | #include <asm/insn.h> |
| 8 | 9 | |
| 9 | 10 | #include "../perf_event.h" |
| 10 | 11 | |
| 12 | +/* Waste a full page so it can be mapped into the cpu_entry_area */ | |
| 13 | +DEFINE_PER_CPU_PAGE_ALIGNED(struct debug_store, cpu_debug_store); | |
| 14 | + | |
| 11 | 15 | /* The size of a BTS record in bytes: */ |
| 12 | 16 | #define BTS_RECORD_SIZE 24 |
| 13 | 17 | |
| 14 | −#define BTS_BUFFER_SIZE (PAGE_SIZE << 4) | |
| 15 | −#define PEBS_BUFFER_SIZE (PAGE_SIZE << 4) | |
| 16 | 18 | #define PEBS_FIXUP_SIZE PAGE_SIZE |
| 17 | 19 | |
| 18 | 20 | /* |
| @@ -279,17 +281,52 @@ void fini_debug_store_on_cpu(int cpu) · 260 unmodified lines | ||
| 279 | 281 | |
| 280 | 282 | static DEFINE_PER_CPU(void *, insn_buffer); |
| 281 | 283 | |
| 282 | −static int alloc_pebs_buffer(int cpu) | |
| 284 | +static void ds_update_cea(void *cea, void *addr, size_t size, pgprot_t prot) | |
| 283 | 285 | { |
| 284 | − struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; | |
| 286 | + phys_addr_t pa; | |
| 287 | + size_t msz = 0; | |
| 288 | + | |
| 289 | + pa = virt_to_phys(addr); | |
| 290 | + for (; msz < size; msz += PAGE_SIZE, pa += PAGE_SIZE, cea += PAGE_SIZE) | |
| 291 | + cea_set_pte(cea, pa, prot); | |
| 292 | +} | |
| 293 | + | |
| 294 | +static void ds_clear_cea(void *cea, size_t size) | |
| 295 | +{ | |
| 296 | + size_t msz = 0; | |
| 297 | + | |
| 298 | + for (; msz < size; msz += PAGE_SIZE, cea += PAGE_SIZE) | |
| 299 | + cea_set_pte(cea, 0, PAGE_NONE); | |
| 300 | +} | |
| 301 | + | |
| 302 | +static void *dsalloc_pages(size_t size, gfp_t flags, int cpu) | |
| 303 | +{ | |
| 304 | + unsigned int order = get_order(size); | |
| 285 | 305 | int node = cpu_to_node(cpu); |
| 286 | − int max; | |
| 287 | − void *buffer, *ibuffer; | |
| 306 | + struct page *page; | |
| 307 | + | |
| 308 | + page = __alloc_pages_node(node, flags | __GFP_ZERO, order); | |
| 309 | + return page ? page_address(page) : NULL; | |
| 310 | +} | |
| 311 | + | |
| 312 | +static void dsfree_pages(const void *buffer, size_t size) | |
| 313 | +{ | |
| 314 | + if (buffer) | |
| 315 | + free_pages((unsigned long)buffer, get_order(size)); | |
| 316 | +} | |
| 317 | + | |
| 318 | +static int alloc_pebs_buffer(int cpu) | |
| 319 | +{ | |
| 320 | + struct cpu_hw_events *hwev = per_cpu_ptr(&cpu_hw_events, cpu); | |
| 321 | + struct debug_store *ds = hwev->ds; | |
| 322 | + size_t bsiz = x86_pmu.pebs_buffer_size; | |
| 323 | + int max, node = cpu_to_node(cpu); | |
| 324 | + void *buffer, *ibuffer, *cea; | |
| 288 | 325 | |
| 289 | 326 | if (!x86_pmu.pebs) |
| 290 | 327 | return 0; |
| 291 | 328 | |
| 292 | − buffer = kzalloc_node(x86_pmu.pebs_buffer_size, GFP_KERNEL, node); | |
| 329 | + buffer = dsalloc_pages(bsiz, GFP_KERNEL, cpu); | |
| 293 | 330 | if (unlikely(!buffer)) |
| 294 | 331 | return -ENOMEM; |
| 295 | 332 | |
| @@ -300,25 +337,27 @@ static int alloc_pebs_buffer(int cpu) · 4 unmodified lines | ||
| 300 | 337 | if (x86_pmu.intel_cap.pebs_format < 2) { |
| 301 | 338 | ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node); |
| 302 | 339 | if (!ibuffer) { |
| 303 | − kfree(buffer); | |
| 340 | + dsfree_pages(buffer, bsiz); | |
| 304 | 341 | return -ENOMEM; |
| 305 | 342 | } |
| 306 | 343 | per_cpu(insn_buffer, cpu) = ibuffer; |
| 307 | 344 | } |
| 308 | − | |
| 309 | − max = x86_pmu.pebs_buffer_size / x86_pmu.pebs_record_size; | |
| 310 | − | |
| 311 | − ds->pebs_buffer_base = (u64)(unsigned long)buffer; | |
| 345 | + hwev->ds_pebs_vaddr = buffer; | |
| 346 | + /* Update the cpu entry area mapping */ | |
| 347 | + cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.pebs_buffer; | |
| 348 | + ds->pebs_buffer_base = (unsigned long) cea; | |
| 349 | + ds_update_cea(cea, buffer, bsiz, PAGE_KERNEL); | |
| 312 | 350 | ds->pebs_index = ds->pebs_buffer_base; |
| 313 | − ds->pebs_absolute_maximum = ds->pebs_buffer_base + | |
| 314 | − max * x86_pmu.pebs_record_size; | |
| 315 | − | |
| 351 | + max = x86_pmu.pebs_record_size * (bsiz / x86_pmu.pebs_record_size); | |
| 352 | + ds->pebs_absolute_maximum = ds->pebs_buffer_base + max; | |
| 316 | 353 | return 0; |
| 317 | 354 | } |
| 318 | 355 | |
| 319 | 356 | static void release_pebs_buffer(int cpu) |
| 320 | 357 | { |
| 321 | − struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; | |
| 358 | + struct cpu_hw_events *hwev = per_cpu_ptr(&cpu_hw_events, cpu); | |
| 359 | + struct debug_store *ds = hwev->ds; | |
| 360 | + void *cea; | |
| 322 | 361 | |
| 323 | 362 | if (!ds || !x86_pmu.pebs) |
| 324 | 363 | return; |
| @@ -326,73 +365,70 @@ static void release_pebs_buffer(int cpu) · 1 unmodified line | ||
| 326 | 365 | kfree(per_cpu(insn_buffer, cpu)); |
| 327 | 366 | per_cpu(insn_buffer, cpu) = NULL; |
| 328 | 367 | |
| 329 | − kfree((void *)(unsigned long)ds->pebs_buffer_base); | |
| 368 | + /* Clear the fixmap */ | |
| 369 | + cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.pebs_buffer; | |
| 370 | + ds_clear_cea(cea, x86_pmu.pebs_buffer_size); | |
| 330 | 371 | ds->pebs_buffer_base = 0; |
| 372 | + dsfree_pages(hwev->ds_pebs_vaddr, x86_pmu.pebs_buffer_size); | |
| 373 | + hwev->ds_pebs_vaddr = NULL; | |
| 331 | 374 | } |
| 332 | 375 | |
| 333 | 376 | static int alloc_bts_buffer(int cpu) |
| 334 | 377 | { |
| 335 | − struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; | |
| 336 | − int node = cpu_to_node(cpu); | |
| 337 | − int max, thresh; | |
| 338 | − void *buffer; | |
| 378 | + struct cpu_hw_events *hwev = per_cpu_ptr(&cpu_hw_events, cpu); | |
| 379 | + struct debug_store *ds = hwev->ds; | |
| 380 | + void *buffer, *cea; | |
| 381 | + int max; | |
| 339 | 382 | |
| 340 | 383 | if (!x86_pmu.bts) |
| 341 | 384 | return 0; |
| 342 | 385 | |
| 343 | − buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node); | |
| 386 | + buffer = dsalloc_pages(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, cpu); | |
| 344 | 387 | if (unlikely(!buffer)) { |
| 345 | 388 | WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__); |
| 346 | 389 | return -ENOMEM; |
| 347 | 390 | } |
| 348 | − | |
| 349 | − max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE; | |
| 350 | − thresh = max / 16; | |
| 351 | − | |
| 352 | − ds->bts_buffer_base = (u64)(unsigned long)buffer; | |
| 391 | + hwev->ds_bts_vaddr = buffer; | |
| 392 | + /* Update the fixmap */ | |
| 393 | + cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.bts_buffer; | |
| 394 | + ds->bts_buffer_base = (unsigned long) cea; | |
| 395 | + ds_update_cea(cea, buffer, BTS_BUFFER_SIZE, PAGE_KERNEL); | |
| 353 | 396 | ds->bts_index = ds->bts_buffer_base; |
| 354 | − ds->bts_absolute_maximum = ds->bts_buffer_base + | |
| 355 | − max * BTS_RECORD_SIZE; | |
| 356 | − ds->bts_interrupt_threshold = ds->bts_absolute_maximum - | |
| 357 | − thresh * BTS_RECORD_SIZE; | |
| 358 | − | |
| 397 | + max = BTS_RECORD_SIZE * (BTS_BUFFER_SIZE / BTS_RECORD_SIZE); | |
| 398 | + ds->bts_absolute_maximum = ds->bts_buffer_base + max; | |
| 399 | + ds->bts_interrupt_threshold = ds->bts_absolute_maximum - (max / 16); | |
| 359 | 400 | return 0; |
| 360 | 401 | } |
| 361 | 402 | |
| 362 | 403 | static void release_bts_buffer(int cpu) |
| 363 | 404 | { |
| 364 | − struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; | |
| 405 | + struct cpu_hw_events *hwev = per_cpu_ptr(&cpu_hw_events, cpu); | |
| 406 | + struct debug_store *ds = hwev->ds; | |
| 407 | + void *cea; | |
| 365 | 408 | |
| 366 | 409 | if (!ds || !x86_pmu.bts) |
| 367 | 410 | return; |
| 368 | 411 | |
| 369 | − kfree((void *)(unsigned long)ds->bts_buffer_base); | |
| 412 | + /* Clear the fixmap */ | |
| 413 | + cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.bts_buffer; | |
| 414 | + ds_clear_cea(cea, BTS_BUFFER_SIZE); | |
| 370 | 415 | ds->bts_buffer_base = 0; |
| 416 | + dsfree_pages(hwev->ds_bts_vaddr, BTS_BUFFER_SIZE); | |
| 417 | + hwev->ds_bts_vaddr = NULL; | |
| 371 | 418 | } |
| 372 | 419 | |
| 373 | 420 | static int alloc_ds_buffer(int cpu) |
| 374 | 421 | { |
| 375 | − int node = cpu_to_node(cpu); | |
| 376 | − struct debug_store *ds; | |
| 377 | − | |
| 378 | − ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node); | |
| 379 | − if (unlikely(!ds)) | |
| 380 | − return -ENOMEM; | |
| 422 | + struct debug_store *ds = &get_cpu_entry_area(cpu)->cpu_debug_store; | |
| 381 | 423 | |
| 424 | + memset(ds, 0, sizeof(*ds)); | |
| 382 | 425 | per_cpu(cpu_hw_events, cpu).ds = ds; |
| 383 | − | |
| 384 | 426 | return 0; |
| 385 | 427 | } |
| 386 | 428 | |
| 387 | 429 | static void release_ds_buffer(int cpu) |
| 388 | 430 | { |
| 389 | − struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; | |
| 390 | − | |
| 391 | − if (!ds) | |
| 392 | − return; | |
| 393 | − | |
| 394 | 431 | per_cpu(cpu_hw_events, cpu).ds = NULL; |
| 395 | − kfree(ds); | |
| 396 | 432 | } |
| 397 | 433 | |
| 398 | 434 | void release_ds_buffers(void) |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include <linux/perf_event.h> |
| 16 | 16 | |
| 17 | +#include <asm/intel_ds.h> | |
| 18 | + | |
| 17 | 19 | /* To enable MSR tracing please use the generic trace points. */ |
| 18 | 20 | |
| 19 | 21 | /* |
| @@ -77,8 +79,6 @@ struct amd_nb { · 57 unmodified lines | ||
| 77 | 79 | struct event_constraint event_constraints[X86_PMC_IDX_MAX]; |
| 78 | 80 | }; |
| 79 | 81 | |
| 80 | −/* The maximal number of PEBS events: */ | |
| 81 | −#define MAX_PEBS_EVENTS 8 | |
| 82 | 82 | #define PEBS_COUNTER_MASK ((1ULL << MAX_PEBS_EVENTS) - 1) |
| 83 | 83 | |
| 84 | 84 | /* |
| @@ -95,23 +95,6 @@ struct amd_nb { · 10 unmodified lines | ||
| 95 | 95 | PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR | \ |
| 96 | 96 | PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER) |
| 97 | 97 | |
| 98 | −/* | |
| 99 | − * A debug store configuration. | |
| 100 | − * | |
| 101 | − * We only support architectures that use 64bit fields. | |
| 102 | − */ | |
| 103 | −struct debug_store { | |
| 104 | − u64 bts_buffer_base; | |
| 105 | − u64 bts_index; | |
| 106 | − u64 bts_absolute_maximum; | |
| 107 | − u64 bts_interrupt_threshold; | |
| 108 | − u64 pebs_buffer_base; | |
| 109 | − u64 pebs_index; | |
| 110 | − u64 pebs_absolute_maximum; | |
| 111 | − u64 pebs_interrupt_threshold; | |
| 112 | − u64 pebs_event_reset[MAX_PEBS_EVENTS]; | |
| 113 | −}; | |
| 114 | − | |
| 115 | 98 | #define PEBS_REGS \ |
| 116 | 99 | (PERF_REG_X86_AX | \ |
| 117 | 100 | PERF_REG_X86_BX | \ |
| @@ -216,6 +199,8 @@ struct cpu_hw_events { · 98 unmodified lines | ||
| 216 | 199 | * Intel DebugStore bits |
| 217 | 200 | */ |
| 218 | 201 | struct debug_store *ds; |
| 202 | + void *ds_pebs_vaddr; | |
| 203 | + void *ds_bts_vaddr; | |
| 219 | 204 | u64 pebs_enabled; |
| 220 | 205 | int n_pebs; |
| 221 | 206 | int n_large_pebs; |
| @@ -136,6 +136,7 @@ · 135 unmodified lines | ||
| 136 | 136 | #endif |
| 137 | 137 | |
| 138 | 138 | #ifndef __ASSEMBLY__ |
| 139 | +#ifndef __BPF__ | |
| 139 | 140 | /* |
| 140 | 141 | * This output constraint should be used for any inline asm which has a "call" |
| 141 | 142 | * instruction. Otherwise the asm may be inserted before the frame pointer |
| @@ -145,5 +146,6 @@ · 3 unmodified lines | ||
| 145 | 146 | register unsigned long current_stack_pointer asm(_ASM_SP); |
| 146 | 147 | #define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) |
| 147 | 148 | #endif |
| 149 | +#endif | |
| 148 | 150 | |
| 149 | 151 | #endif /* _ASM_X86_ASM_H */ |
| @@ -0,0 +1,81 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +#ifndef _ASM_X86_CPU_ENTRY_AREA_H | |
| 4 | +#define _ASM_X86_CPU_ENTRY_AREA_H | |
| 5 | + | |
| 6 | +#include <linux/percpu-defs.h> | |
| 7 | +#include <asm/processor.h> | |
| 8 | +#include <asm/intel_ds.h> | |
| 9 | + | |
| 10 | +/* | |
| 11 | + * cpu_entry_area is a percpu region that contains things needed by the CPU | |
| 12 | + * and early entry/exit code. Real types aren't used for all fields here | |
| 13 | + * to avoid circular header dependencies. | |
| 14 | + * | |
| 15 | + * Every field is a virtual alias of some other allocated backing store. | |
| 16 | + * There is no direct allocation of a struct cpu_entry_area. | |
| 17 | + */ | |
| 18 | +struct cpu_entry_area { | |
| 19 | + char gdt[PAGE_SIZE]; | |
| 20 | + | |
| 21 | + /* | |
| 22 | + * The GDT is just below entry_stack and thus serves (on x86_64) as | |
| 23 | + * a a read-only guard page. | |
| 24 | + */ | |
| 25 | + struct entry_stack_page entry_stack_page; | |
| 26 | + | |
| 27 | + /* | |
| 28 | + * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because | |
| 29 | + * we need task switches to work, and task switches write to the TSS. | |
| 30 | + */ | |
| 31 | + struct tss_struct tss; | |
| 32 | + | |
| 33 | + char entry_trampoline[PAGE_SIZE]; | |
| 34 | + | |
| 35 | +#ifdef CONFIG_X86_64 | |
| 36 | + /* | |
| 37 | + * Exception stacks used for IST entries. | |
| 38 | + * | |
| 39 | + * In the future, this should have a separate slot for each stack | |
| 40 | + * with guard pages between them. | |
| 41 | + */ | |
| 42 | + char exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]; | |
| 43 | +#endif | |
| 44 | +#ifdef CONFIG_CPU_SUP_INTEL | |
| 45 | + /* | |
| 46 | + * Per CPU debug store for Intel performance monitoring. Wastes a | |
| 47 | + * full page at the moment. | |
| 48 | + */ | |
| 49 | + struct debug_store cpu_debug_store; | |
| 50 | + /* | |
| 51 | + * The actual PEBS/BTS buffers must be mapped to user space | |
| 52 | + * Reserve enough fixmap PTEs. | |
| 53 | + */ | |
| 54 | + struct debug_store_buffers cpu_debug_buffers; | |
| 55 | +#endif | |
| 56 | +}; | |
| 57 | + | |
| 58 | +#define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area)) | |
| 59 | +#define CPU_ENTRY_AREA_TOT_SIZE (CPU_ENTRY_AREA_SIZE * NR_CPUS) | |
| 60 | + | |
| 61 | +DECLARE_PER_CPU(struct cpu_entry_area *, cpu_entry_area); | |
| 62 | + | |
| 63 | +extern void setup_cpu_entry_areas(void); | |
| 64 | +extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags); | |
| 65 | + | |
| 66 | +#define CPU_ENTRY_AREA_RO_IDT CPU_ENTRY_AREA_BASE | |
| 67 | +#define CPU_ENTRY_AREA_PER_CPU (CPU_ENTRY_AREA_RO_IDT + PAGE_SIZE) | |
| 68 | + | |
| 69 | +#define CPU_ENTRY_AREA_RO_IDT_VADDR ((void *)CPU_ENTRY_AREA_RO_IDT) | |
| 70 | + | |
| 71 | +#define CPU_ENTRY_AREA_MAP_SIZE \ | |
| 72 | + (CPU_ENTRY_AREA_PER_CPU + CPU_ENTRY_AREA_TOT_SIZE - CPU_ENTRY_AREA_BASE) | |
| 73 | + | |
| 74 | +extern struct cpu_entry_area *get_cpu_entry_area(int cpu); | |
| 75 | + | |
| 76 | +static inline struct entry_stack *cpu_entry_stack(int cpu) | |
| 77 | +{ | |
| 78 | + return &get_cpu_entry_area(cpu)->entry_stack_page.stack; | |
| 79 | +} | |
| 80 | + | |
| 81 | +#endif | |
| @@ -135,6 +135,8 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); · 134 unmodified lines | ||
| 135 | 135 | set_bit(bit, (unsigned long *)cpu_caps_set); \ |
| 136 | 136 | } while (0) |
| 137 | 137 | |
| 138 | +#define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) | |
| 139 | + | |
| 138 | 140 | #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_X86_FAST_FEATURE_TESTS) |
| 139 | 141 | /* |
| 140 | 142 | * Static testing of CPU features. Used the same as boot_cpu_has(). |
| @@ -197,11 +197,12 @@ · 196 unmodified lines | ||
| 197 | 197 | #define X86_FEATURE_CAT_L3 ( 7*32+ 4) /* Cache Allocation Technology L3 */ |
| 198 | 198 | #define X86_FEATURE_CAT_L2 ( 7*32+ 5) /* Cache Allocation Technology L2 */ |
| 199 | 199 | #define X86_FEATURE_CDP_L3 ( 7*32+ 6) /* Code and Data Prioritization L3 */ |
| 200 | +#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */ | |
| 200 | 201 | |
| 201 | 202 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ |
| 202 | 203 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ |
| 203 | 204 | #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ |
| 204 | − | |
| 205 | +#define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ | |
| 205 | 206 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ |
| 206 | 207 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ |
| 207 | 208 | #define X86_FEATURE_AVX512_4VNNIW ( 7*32+16) /* AVX-512 Neural Network Instructions */ |
| @@ -340,5 +341,6 @@ · 132 unmodified lines | ||
| 340 | 341 | #define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */ |
| 341 | 342 | #define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */ |
| 342 | 343 | #define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */ |
| 344 | +#define X86_BUG_CPU_INSECURE X86_BUG(14) /* CPU is insecure and needs kernel page table isolation */ | |
| 343 | 345 | |
| 344 | 346 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/mmu.h> |
| 8 | 8 | #include <asm/fixmap.h> |
| 9 | 9 | #include <asm/irq_vectors.h> |
| 10 | +#include <asm/cpu_entry_area.h> | |
| 10 | 11 | |
| 11 | 12 | #include <linux/smp.h> |
| 12 | 13 | #include <linux/percpu.h> |
| @@ -20,6 +21,8 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in · 7 unmodified lines | ||
| 20 | 21 | |
| 21 | 22 | desc->type = (info->read_exec_only ^ 1) << 1; |
| 22 | 23 | desc->type |= info->contents << 2; |
| 24 | + /* Set the ACCESS bit so it can be mapped RO */ | |
| 25 | + desc->type |= 1; | |
| 23 | 26 | |
| 24 | 27 | desc->s = 1; |
| 25 | 28 | desc->dpl = 0x3; |
| @@ -60,17 +63,10 @@ static inline struct desc_struct *get_current_gdt_rw(void) · 34 unmodified lines | ||
| 60 | 63 | return this_cpu_ptr(&gdt_page)->gdt; |
| 61 | 64 | } |
| 62 | 65 | |
| 63 | −/* Get the fixmap index for a specific processor */ | |
| 64 | −static inline unsigned int get_cpu_gdt_ro_index(int cpu) | |
| 65 | −{ | |
| 66 | − return FIX_GDT_REMAP_BEGIN + cpu; | |
| 67 | −} | |
| 68 | − | |
| 69 | 66 | /* Provide the fixmap address of the remapped GDT */ |
| 70 | 67 | static inline struct desc_struct *get_cpu_gdt_ro(int cpu) |
| 71 | 68 | { |
| 72 | − unsigned int idx = get_cpu_gdt_ro_index(cpu); | |
| 73 | − return (struct desc_struct *)__fix_to_virt(idx); | |
| 69 | + return (struct desc_struct *)&get_cpu_entry_area(cpu)->gdt; | |
| 74 | 70 | } |
| 75 | 71 | |
| 76 | 72 | /* Provide the current read-only GDT */ |
| @@ -185,7 +181,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, · 108 unmodified lines | ||
| 185 | 181 | #endif |
| 186 | 182 | } |
| 187 | 183 | |
| 188 | −static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr) | |
| 184 | +static inline void __set_tss_desc(unsigned cpu, unsigned int entry, struct x86_hw_tss *addr) | |
| 189 | 185 | { |
| 190 | 186 | struct desc_struct *d = get_cpu_gdt_rw(cpu); |
| 191 | 187 | tss_desc tss; |
| @@ -50,6 +50,12 @@ · 49 unmodified lines | ||
| 50 | 50 | # define DISABLE_LA57 (1<<(X86_FEATURE_LA57 & 31)) |
| 51 | 51 | #endif |
| 52 | 52 | |
| 53 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 54 | +# define DISABLE_PTI 0 | |
| 55 | +#else | |
| 56 | +# define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31)) | |
| 57 | +#endif | |
| 58 | + | |
| 53 | 59 | /* |
| 54 | 60 | * Make sure to add features to the correct mask |
| 55 | 61 | */ |
| @@ -60,7 +66,7 @@ · 4 unmodified lines | ||
| 60 | 66 | #define DISABLED_MASK4 (DISABLE_PCID) |
| 61 | 67 | #define DISABLED_MASK5 0 |
| 62 | 68 | #define DISABLED_MASK6 0 |
| 63 | −#define DISABLED_MASK7 0 | |
| 69 | +#define DISABLED_MASK7 (DISABLE_PTI) | |
| 64 | 70 | #define DISABLED_MASK8 0 |
| 65 | 71 | #define DISABLED_MASK9 (DISABLE_MPX) |
| 66 | 72 | #define DISABLED_MASK10 0 |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ASM_X86_ESPFIX_H |
| 3 | 3 | #define _ASM_X86_ESPFIX_H |
| 4 | 4 | |
| 5 | −#ifdef CONFIG_X86_64 | |
| 5 | +#ifdef CONFIG_X86_ESPFIX64 | |
| 6 | 6 | |
| 7 | 7 | #include <asm/percpu.h> |
| 8 | 8 | |
| @@ -11,7 +11,8 @@ DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr); · 2 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | extern void init_espfix_bsp(void); |
| 13 | 13 | extern void init_espfix_ap(int cpu); |
| 14 | − | |
| 15 | −#endif /* CONFIG_X86_64 */ | |
| 14 | +#else | |
| 15 | +static inline void init_espfix_ap(int cpu) { } | |
| 16 | +#endif | |
| 16 | 17 | |
| 17 | 18 | #endif /* _ASM_X86_ESPFIX_H */ |
| @@ -44,7 +44,6 @@ extern unsigned long __FIXADDR_TOP; · 43 unmodified lines | ||
| 44 | 44 | PAGE_SIZE) |
| 45 | 45 | #endif |
| 46 | 46 | |
| 47 | − | |
| 48 | 47 | /* |
| 49 | 48 | * Here we define all the compile-time 'special' virtual |
| 50 | 49 | * addresses. The point is to have a constant address at |
| @@ -84,7 +83,6 @@ enum fixed_addresses { · 33 unmodified lines | ||
| 84 | 83 | FIX_IO_APIC_BASE_0, |
| 85 | 84 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, |
| 86 | 85 | #endif |
| 87 | − FIX_RO_IDT, /* Virtual mapping for read-only IDT */ | |
| 88 | 86 | #ifdef CONFIG_X86_32 |
| 89 | 87 | FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ |
| 90 | 88 | FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, |
| @@ -100,9 +98,6 @@ enum fixed_addresses { · 9 unmodified lines | ||
| 100 | 98 | #ifdef CONFIG_X86_INTEL_MID |
| 101 | 99 | FIX_LNW_VRTC, |
| 102 | 100 | #endif |
| 103 | − /* Fixmap entries to remap the GDTs, one per processor. */ | |
| 104 | − FIX_GDT_REMAP_BEGIN, | |
| 105 | − FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1, | |
| 106 | 101 | |
| 107 | 102 | #ifdef CONFIG_ACPI_APEI_GHES |
| 108 | 103 | /* Used for GHES mapping from assorted contexts */ |
| @@ -143,7 +138,7 @@ enum fixed_addresses { · 34 unmodified lines | ||
| 143 | 138 | extern void reserve_top_address(unsigned long reserve); |
| 144 | 139 | |
| 145 | 140 | #define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) |
| 146 | −#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | |
| 141 | +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | |
| 147 | 142 | |
| 148 | 143 | extern int fixmaps_set; |
| 149 | 144 | |
| @@ -20,16 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #ifndef _ASM_X86_HYPERVISOR_H |
| 21 | 21 | #define _ASM_X86_HYPERVISOR_H |
| 22 | 22 | |
| 23 | −#ifdef CONFIG_HYPERVISOR_GUEST | |
| 24 | − | |
| 25 | −#include <asm/kvm_para.h> | |
| 26 | −#include <asm/x86_init.h> | |
| 27 | −#include <asm/xen/hypervisor.h> | |
| 28 | − | |
| 29 | −/* | |
| 30 | − * x86 hypervisor information | |
| 31 | − */ | |
| 32 | − | |
| 23 | +/* x86 hypervisor types */ | |
| 33 | 24 | enum x86_hypervisor_type { |
| 34 | 25 | X86_HYPER_NATIVE = 0, |
| 35 | 26 | X86_HYPER_VMWARE, |
| @@ -39,6 +30,12 @@ enum x86_hypervisor_type { · 3 unmodified lines | ||
| 39 | 30 | X86_HYPER_KVM, |
| 40 | 31 | }; |
| 41 | 32 | |
| 33 | +#ifdef CONFIG_HYPERVISOR_GUEST | |
| 34 | + | |
| 35 | +#include <asm/kvm_para.h> | |
| 36 | +#include <asm/x86_init.h> | |
| 37 | +#include <asm/xen/hypervisor.h> | |
| 38 | + | |
| 42 | 39 | struct hypervisor_x86 { |
| 43 | 40 | /* Hypervisor name */ |
| 44 | 41 | const char *name; |
| @@ -58,7 +55,15 @@ struct hypervisor_x86 { · 13 unmodified lines | ||
| 58 | 55 | |
| 59 | 56 | extern enum x86_hypervisor_type x86_hyper_type; |
| 60 | 57 | extern void init_hypervisor_platform(void); |
| 58 | +static inline bool hypervisor_is_type(enum x86_hypervisor_type type) | |
| 59 | +{ | |
| 60 | + return x86_hyper_type == type; | |
| 61 | +} | |
| 61 | 62 | #else |
| 62 | 63 | static inline void init_hypervisor_platform(void) { } |
| 64 | +static inline bool hypervisor_is_type(enum x86_hypervisor_type type) | |
| 65 | +{ | |
| 66 | + return type == X86_HYPER_NATIVE; | |
| 67 | +} | |
| 63 | 68 | #endif /* CONFIG_HYPERVISOR_GUEST */ |
| 64 | 69 | #endif /* _ASM_X86_HYPERVISOR_H */ |
| @@ -0,0 +1,36 @@ | ||
| 1 | +#ifndef _ASM_INTEL_DS_H | |
| 2 | +#define _ASM_INTEL_DS_H | |
| 3 | + | |
| 4 | +#include <linux/percpu-defs.h> | |
| 5 | + | |
| 6 | +#define BTS_BUFFER_SIZE (PAGE_SIZE << 4) | |
| 7 | +#define PEBS_BUFFER_SIZE (PAGE_SIZE << 4) | |
| 8 | + | |
| 9 | +/* The maximal number of PEBS events: */ | |
| 10 | +#define MAX_PEBS_EVENTS 8 | |
| 11 | + | |
| 12 | +/* | |
| 13 | + * A debug store configuration. | |
| 14 | + * | |
| 15 | + * We only support architectures that use 64bit fields. | |
| 16 | + */ | |
| 17 | +struct debug_store { | |
| 18 | + u64 bts_buffer_base; | |
| 19 | + u64 bts_index; | |
| 20 | + u64 bts_absolute_maximum; | |
| 21 | + u64 bts_interrupt_threshold; | |
| 22 | + u64 pebs_buffer_base; | |
| 23 | + u64 pebs_index; | |
| 24 | + u64 pebs_absolute_maximum; | |
| 25 | + u64 pebs_interrupt_threshold; | |
| 26 | + u64 pebs_event_reset[MAX_PEBS_EVENTS]; | |
| 27 | +} __aligned(PAGE_SIZE); | |
| 28 | + | |
| 29 | +DECLARE_PER_CPU_PAGE_ALIGNED(struct debug_store, cpu_debug_store); | |
| 30 | + | |
| 31 | +struct debug_store_buffers { | |
| 32 | + char bts_buffer[BTS_BUFFER_SIZE]; | |
| 33 | + char pebs_buffer[PEBS_BUFFER_SIZE]; | |
| 34 | +}; | |
| 35 | + | |
| 36 | +#endif | |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef _ASM_X86_INVPCID | |
| 3 | +#define _ASM_X86_INVPCID | |
| 4 | + | |
| 5 | +static inline void __invpcid(unsigned long pcid, unsigned long addr, | |
| 6 | + unsigned long type) | |
| 7 | +{ | |
| 8 | + struct { u64 d[2]; } desc = { { pcid, addr } }; | |
| 9 | + | |
| 10 | + /* | |
| 11 | + * The memory clobber is because the whole point is to invalidate | |
| 12 | + * stale TLB entries and, especially if we're flushing global | |
| 13 | + * mappings, we don't want the compiler to reorder any subsequent | |
| 14 | + * memory accesses before the TLB flush. | |
| 15 | + * | |
| 16 | + * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and | |
| 17 | + * invpcid (%rcx), %rax in long mode. | |
| 18 | + */ | |
| 19 | + asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" | |
| 20 | + : : "m" (desc), "a" (type), "c" (&desc) : "memory"); | |
| 21 | +} | |
| 22 | + | |
| 23 | +#define INVPCID_TYPE_INDIV_ADDR 0 | |
| 24 | +#define INVPCID_TYPE_SINGLE_CTXT 1 | |
| 25 | +#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 | |
| 26 | +#define INVPCID_TYPE_ALL_NON_GLOBAL 3 | |
| 27 | + | |
| 28 | +/* Flush all mappings for a given pcid and addr, not including globals. */ | |
| 29 | +static inline void invpcid_flush_one(unsigned long pcid, | |
| 30 | + unsigned long addr) | |
| 31 | +{ | |
| 32 | + __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); | |
| 33 | +} | |
| 34 | + | |
| 35 | +/* Flush all mappings for a given PCID, not including globals. */ | |
| 36 | +static inline void invpcid_flush_single_context(unsigned long pcid) | |
| 37 | +{ | |
| 38 | + __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); | |
| 39 | +} | |
| 40 | + | |
| 41 | +/* Flush all mappings, including globals, for all PCIDs. */ | |
| 42 | +static inline void invpcid_flush_all(void) | |
| 43 | +{ | |
| 44 | + __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); | |
| 45 | +} | |
| 46 | + | |
| 47 | +/* Flush all mappings for all PCIDs except globals. */ | |
| 48 | +static inline void invpcid_flush_all_nonglobals(void) | |
| 49 | +{ | |
| 50 | + __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); | |
| 51 | +} | |
| 52 | + | |
| 53 | +#endif /* _ASM_X86_INVPCID */ | |
| @@ -44,7 +44,7 @@ extern int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, · 43 unmodified lines | ||
| 44 | 44 | extern void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, |
| 45 | 45 | unsigned int nr_irqs); |
| 46 | 46 | extern int mp_irqdomain_activate(struct irq_domain *domain, |
| 47 | − struct irq_data *irq_data, bool early); | |
| 47 | + struct irq_data *irq_data, bool reserve); | |
| 48 | 48 | extern void mp_irqdomain_deactivate(struct irq_domain *domain, |
| 49 | 49 | struct irq_data *irq_data); |
| 50 | 50 | extern int mp_irqdomain_ioapic_idx(struct irq_domain *domain); |
| @@ -142,6 +142,9 @@ static inline notrace unsigned long arch_local_irq_save(void) · 141 unmodified lines | ||
| 142 | 142 | swapgs; \ |
| 143 | 143 | sysretl |
| 144 | 144 | |
| 145 | +#ifdef CONFIG_DEBUG_ENTRY | |
| 146 | +#define SAVE_FLAGS(x) pushfq; popq %rax | |
| 147 | +#endif | |
| 145 | 148 | #else |
| 146 | 149 | #define INTERRUPT_RETURN iret |
| 147 | 150 | #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit |
| @@ -26,6 +26,7 @@ extern void die(const char *, struct pt_regs *,long); · 25 unmodified lines | ||
| 26 | 26 | extern int __must_check __die(const char *, struct pt_regs *, long); |
| 27 | 27 | extern void show_stack_regs(struct pt_regs *regs); |
| 28 | 28 | extern void __show_regs(struct pt_regs *regs, int all); |
| 29 | +extern void show_iret_regs(struct pt_regs *regs); | |
| 29 | 30 | extern unsigned long oops_begin(void); |
| 30 | 31 | extern void oops_end(unsigned long, struct pt_regs *, int signr); |
| 31 | 32 | |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define _ASM_X86_MMU_H |
| 4 | 4 | |
| 5 | 5 | #include <linux/spinlock.h> |
| 6 | +#include <linux/rwsem.h> | |
| 6 | 7 | #include <linux/mutex.h> |
| 7 | 8 | #include <linux/atomic.h> |
| 8 | 9 | |
| @@ -27,7 +28,8 @@ typedef struct { · 18 unmodified lines | ||
| 27 | 28 | atomic64_t tlb_gen; |
| 28 | 29 | |
| 29 | 30 | #ifdef CONFIG_MODIFY_LDT_SYSCALL |
| 30 | − struct ldt_struct *ldt; | |
| 31 | + struct rw_semaphore ldt_usr_sem; | |
| 32 | + struct ldt_struct *ldt; | |
| 31 | 33 | #endif |
| 32 | 34 | |
| 33 | 35 | #ifdef CONFIG_X86_64 |
| @@ -50,22 +50,53 @@ struct ldt_struct { · 49 unmodified lines | ||
| 50 | 50 | * call gates. On native, we could merge the ldt_struct and LDT |
| 51 | 51 | * allocations, but it's not worth trying to optimize. |
| 52 | 52 | */ |
| 53 | − struct desc_struct *entries; | |
| 54 | − unsigned int nr_entries; | |
| 53 | + struct desc_struct *entries; | |
| 54 | + unsigned int nr_entries; | |
| 55 | + | |
| 56 | + /* | |
| 57 | + * If PTI is in use, then the entries array is not mapped while we're | |
| 58 | + * in user mode. The whole array will be aliased at the addressed | |
| 59 | + * given by ldt_slot_va(slot). We use two slots so that we can allocate | |
| 60 | + * and map, and enable a new LDT without invalidating the mapping | |
| 61 | + * of an older, still-in-use LDT. | |
| 62 | + * | |
| 63 | + * slot will be -1 if this LDT doesn't have an alias mapping. | |
| 64 | + */ | |
| 65 | + int slot; | |
| 55 | 66 | }; |
| 56 | 67 | |
| 68 | +/* This is a multiple of PAGE_SIZE. */ | |
| 69 | +#define LDT_SLOT_STRIDE (LDT_ENTRIES * LDT_ENTRY_SIZE) | |
| 70 | + | |
| 71 | +static inline void *ldt_slot_va(int slot) | |
| 72 | +{ | |
| 73 | +#ifdef CONFIG_X86_64 | |
| 74 | + return (void *)(LDT_BASE_ADDR + LDT_SLOT_STRIDE * slot); | |
| 75 | +#else | |
| 76 | + BUG(); | |
| 77 | +#endif | |
| 78 | +} | |
| 79 | + | |
| 57 | 80 | /* |
| 58 | 81 | * Used for LDT copy/destruction. |
| 59 | 82 | */ |
| 60 | −int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm); | |
| 83 | +static inline void init_new_context_ldt(struct mm_struct *mm) | |
| 84 | +{ | |
| 85 | + mm->context.ldt = NULL; | |
| 86 | + init_rwsem(&mm->context.ldt_usr_sem); | |
| 87 | +} | |
| 88 | +int ldt_dup_context(struct mm_struct *oldmm, struct mm_struct *mm); | |
| 61 | 89 | void destroy_context_ldt(struct mm_struct *mm); |
| 90 | +void ldt_arch_exit_mmap(struct mm_struct *mm); | |
| 62 | 91 | #else /* CONFIG_MODIFY_LDT_SYSCALL */ |
| 63 | −static inline int init_new_context_ldt(struct task_struct *tsk, | |
| 64 | − struct mm_struct *mm) | |
| 92 | +static inline void init_new_context_ldt(struct mm_struct *mm) { } | |
| 93 | +static inline int ldt_dup_context(struct mm_struct *oldmm, | |
| 94 | + struct mm_struct *mm) | |
| 65 | 95 | { |
| 66 | 96 | return 0; |
| 67 | 97 | } |
| 68 | −static inline void destroy_context_ldt(struct mm_struct *mm) {} | |
| 98 | +static inline void destroy_context_ldt(struct mm_struct *mm) { } | |
| 99 | +static inline void ldt_arch_exit_mmap(struct mm_struct *mm) { } | |
| 69 | 100 | #endif |
| 70 | 101 | |
| 71 | 102 | static inline void load_mm_ldt(struct mm_struct *mm) |
| @@ -90,10 +121,31 @@ static inline void load_mm_ldt(struct mm_struct *mm) · 18 unmodified lines | ||
| 90 | 121 | * that we can see. |
| 91 | 122 | */ |
| 92 | 123 | |
| 93 | − if (unlikely(ldt)) | |
| 94 | − set_ldt(ldt->entries, ldt->nr_entries); | |
| 95 | − else | |
| 124 | + if (unlikely(ldt)) { | |
| 125 | + if (static_cpu_has(X86_FEATURE_PTI)) { | |
| 126 | + if (WARN_ON_ONCE((unsigned long)ldt->slot > 1)) { | |
| 127 | + /* | |
| 128 | + * Whoops -- either the new LDT isn't mapped | |
| 129 | + * (if slot == -1) or is mapped into a bogus | |
| 130 | + * slot (if slot > 1). | |
| 131 | + */ | |
| 132 | + clear_LDT(); | |
| 133 | + return; | |
| 134 | + } | |
| 135 | + | |
| 136 | + /* | |
| 137 | + * If page table isolation is enabled, ldt->entries | |
| 138 | + * will not be mapped in the userspace pagetables. | |
| 139 | + * Tell the CPU to access the LDT through the alias | |
| 140 | + * at ldt_slot_va(ldt->slot). | |
| 141 | + */ | |
| 142 | + set_ldt(ldt_slot_va(ldt->slot), ldt->nr_entries); | |
| 143 | + } else { | |
| 144 | + set_ldt(ldt->entries, ldt->nr_entries); | |
| 145 | + } | |
| 146 | + } else { | |
| 96 | 147 | clear_LDT(); |
| 148 | + } | |
| 97 | 149 | #else |
| 98 | 150 | clear_LDT(); |
| 99 | 151 | #endif |
| @@ -132,18 +184,21 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk); · 32 unmodified lines | ||
| 132 | 184 | static inline int init_new_context(struct task_struct *tsk, |
| 133 | 185 | struct mm_struct *mm) |
| 134 | 186 | { |
| 187 | + mutex_init(&mm->context.lock); | |
| 188 | + | |
| 135 | 189 | mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); |
| 136 | 190 | atomic64_set(&mm->context.tlb_gen, 0); |
| 137 | 191 | |
| 138 | − #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS | |
| 192 | +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS | |
| 139 | 193 | if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { |
| 140 | 194 | /* pkey 0 is the default and always allocated */ |
| 141 | 195 | mm->context.pkey_allocation_map = 0x1; |
| 142 | 196 | /* -1 means unallocated or invalid */ |
| 143 | 197 | mm->context.execute_only_pkey = -1; |
| 144 | 198 | } |
| 145 | − #endif | |
| 146 | − return init_new_context_ldt(tsk, mm); | |
| 199 | +#endif | |
| 200 | + init_new_context_ldt(mm); | |
| 201 | + return 0; | |
| 147 | 202 | } |
| 148 | 203 | static inline void destroy_context(struct mm_struct *mm) |
| 149 | 204 | { |
| @@ -176,15 +231,16 @@ do { \ · 26 unmodified lines | ||
| 176 | 231 | } while (0) |
| 177 | 232 | #endif |
| 178 | 233 | |
| 179 | −static inline void arch_dup_mmap(struct mm_struct *oldmm, | |
| 180 | − struct mm_struct *mm) | |
| 234 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) | |
| 181 | 235 | { |
| 182 | 236 | paravirt_arch_dup_mmap(oldmm, mm); |
| 237 | + return ldt_dup_context(oldmm, mm); | |
| 183 | 238 | } |
| 184 | 239 | |
| 185 | 240 | static inline void arch_exit_mmap(struct mm_struct *mm) |
| 186 | 241 | { |
| 187 | 242 | paravirt_arch_exit_mmap(mm); |
| 243 | + ldt_arch_exit_mmap(mm); | |
| 188 | 244 | } |
| 189 | 245 | |
| 190 | 246 | #ifdef CONFIG_X86_64 |
| @@ -281,33 +337,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, · 90 unmodified lines | ||
| 281 | 337 | return __pkru_allows_pkey(vma_pkey(vma), write); |
| 282 | 338 | } |
| 283 | 339 | |
| 284 | −/* | |
| 285 | − * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID | |
| 286 | − * bits. This serves two purposes. It prevents a nasty situation in | |
| 287 | − * which PCID-unaware code saves CR3, loads some other value (with PCID | |
| 288 | − * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if | |
| 289 | − * the saved ASID was nonzero. It also means that any bugs involving | |
| 290 | − * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger | |
| 291 | − * deterministically. | |
| 292 | − */ | |
| 293 | − | |
| 294 | −static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid) | |
| 295 | −{ | |
| 296 | − if (static_cpu_has(X86_FEATURE_PCID)) { | |
| 297 | − VM_WARN_ON_ONCE(asid > 4094); | |
| 298 | − return __sme_pa(mm->pgd) | (asid + 1); | |
| 299 | − } else { | |
| 300 | − VM_WARN_ON_ONCE(asid != 0); | |
| 301 | − return __sme_pa(mm->pgd); | |
| 302 | − } | |
| 303 | −} | |
| 304 | − | |
| 305 | −static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) | |
| 306 | −{ | |
| 307 | − VM_WARN_ON_ONCE(asid > 4094); | |
| 308 | − return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH; | |
| 309 | −} | |
| 310 | − | |
| 311 | 340 | /* |
| 312 | 341 | * This can be used from process context to figure out what the value of |
| 313 | 342 | * CR3 is without needing to do a (slow) __read_cr3(). |
| @@ -317,7 +346,7 @@ static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) · 3 unmodified lines | ||
| 317 | 346 | */ |
| 318 | 347 | static inline unsigned long __get_current_cr3_fast(void) |
| 319 | 348 | { |
| 320 | − unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm), | |
| 349 | + unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd, | |
| 321 | 350 | this_cpu_read(cpu_tlbstate.loaded_mm_asid)); |
| 322 | 351 | |
| 323 | 352 | /* For now, be very restrictive about when this can be called. */ |
| @@ -927,6 +927,15 @@ extern void default_banner(void); · 926 unmodified lines | ||
| 927 | 927 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ |
| 928 | 928 | CLBR_NONE, \ |
| 929 | 929 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64)) |
| 930 | + | |
| 931 | +#ifdef CONFIG_DEBUG_ENTRY | |
| 932 | +#define SAVE_FLAGS(clobbers) \ | |
| 933 | + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_save_fl), clobbers, \ | |
| 934 | + PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | |
| 935 | + call PARA_INDIRECT(pv_irq_ops+PV_IRQ_save_fl); \ | |
| 936 | + PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | |
| 937 | +#endif | |
| 938 | + | |
| 930 | 939 | #endif /* CONFIG_X86_32 */ |
| 931 | 940 | |
| 932 | 941 | #endif /* __ASSEMBLY__ */ |
| @@ -30,6 +30,17 @@ static inline void paravirt_release_p4d(unsigned long pfn) {} · 29 unmodified lines | ||
| 30 | 30 | */ |
| 31 | 31 | extern gfp_t __userpte_alloc_gfp; |
| 32 | 32 | |
| 33 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 34 | +/* | |
| 35 | + * Instead of one PGD, we acquire two PGDs. Being order-1, it is | |
| 36 | + * both 8k in size and 8k-aligned. That lets us just flip bit 12 | |
| 37 | + * in a pointer to swap between the two 4k halves. | |
| 38 | + */ | |
| 39 | +#define PGD_ALLOCATION_ORDER 1 | |
| 40 | +#else | |
| 41 | +#define PGD_ALLOCATION_ORDER 0 | |
| 42 | +#endif | |
| 43 | + | |
| 33 | 44 | /* |
| 34 | 45 | * Allocate and free page tables. |
| 35 | 46 | */ |
| @@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]; · 27 unmodified lines | ||
| 28 | 28 | int __init __early_make_pgtable(unsigned long address, pmdval_t pmd); |
| 29 | 29 | |
| 30 | 30 | void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd); |
| 31 | +void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user); | |
| 31 | 32 | void ptdump_walk_pgd_level_checkwx(void); |
| 32 | 33 | |
| 33 | 34 | #ifdef CONFIG_DEBUG_WX |
| @@ -841,7 +842,12 @@ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) · 807 unmodified lines | ||
| 841 | 842 | |
| 842 | 843 | static inline int p4d_bad(p4d_t p4d) |
| 843 | 844 | { |
| 844 | − return (p4d_flags(p4d) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0; | |
| 845 | + unsigned long ignore_flags = _KERNPG_TABLE | _PAGE_USER; | |
| 846 | + | |
| 847 | + if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) | |
| 848 | + ignore_flags |= _PAGE_NX; | |
| 849 | + | |
| 850 | + return (p4d_flags(p4d) & ~ignore_flags) != 0; | |
| 845 | 851 | } |
| 846 | 852 | #endif /* CONFIG_PGTABLE_LEVELS > 3 */ |
| 847 | 853 | |
| @@ -875,7 +881,12 @@ static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) · 27 unmodified lines | ||
| 875 | 881 | |
| 876 | 882 | static inline int pgd_bad(pgd_t pgd) |
| 877 | 883 | { |
| 878 | − return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE; | |
| 884 | + unsigned long ignore_flags = _PAGE_USER; | |
| 885 | + | |
| 886 | + if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) | |
| 887 | + ignore_flags |= _PAGE_NX; | |
| 888 | + | |
| 889 | + return (pgd_flags(pgd) & ~ignore_flags) != _KERNPG_TABLE; | |
| 879 | 890 | } |
| 880 | 891 | |
| 881 | 892 | static inline int pgd_none(pgd_t pgd) |
| @@ -904,7 +915,11 @@ static inline int pgd_none(pgd_t pgd) · 22 unmodified lines | ||
| 904 | 915 | * pgd_offset() returns a (pgd_t *) |
| 905 | 916 | * pgd_index() is used get the offset into the pgd page's array of pgd_t's; |
| 906 | 917 | */ |
| 907 | −#define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address))) | |
| 918 | +#define pgd_offset_pgd(pgd, address) (pgd + pgd_index((address))) | |
| 919 | +/* | |
| 920 | + * a shortcut to get a pgd_t in a given mm | |
| 921 | + */ | |
| 922 | +#define pgd_offset(mm, address) pgd_offset_pgd((mm)->pgd, (address)) | |
| 908 | 923 | /* |
| 909 | 924 | * a shortcut which implies the use of the kernel's pgd, instead |
| 910 | 925 | * of a process's |
| @@ -1106,7 +1121,14 @@ static inline int pud_write(pud_t pud) · 195 unmodified lines | ||
| 1106 | 1121 | */ |
| 1107 | 1122 | static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) |
| 1108 | 1123 | { |
| 1109 | − memcpy(dst, src, count * sizeof(pgd_t)); | |
| 1124 | + memcpy(dst, src, count * sizeof(pgd_t)); | |
| 1125 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 1126 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 1127 | + return; | |
| 1128 | + /* Clone the user space pgd as well */ | |
| 1129 | + memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src), | |
| 1130 | + count * sizeof(pgd_t)); | |
| 1131 | +#endif | |
| 1110 | 1132 | } |
| 1111 | 1133 | |
| 1112 | 1134 | #define PTE_SHIFT ilog2(PTRS_PER_PTE) |
| @@ -38,13 +38,22 @@ extern bool __vmalloc_start_set; /* set once high_memory is set */ · 37 unmodified lines | ||
| 38 | 38 | #define LAST_PKMAP 1024 |
| 39 | 39 | #endif |
| 40 | 40 | |
| 41 | −#define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE * (LAST_PKMAP + 1)) \ | |
| 42 | − & PMD_MASK) | |
| 41 | +/* | |
| 42 | + * Define this here and validate with BUILD_BUG_ON() in pgtable_32.c | |
| 43 | + * to avoid include recursion hell | |
| 44 | + */ | |
| 45 | +#define CPU_ENTRY_AREA_PAGES (NR_CPUS * 40) | |
| 46 | + | |
| 47 | +#define CPU_ENTRY_AREA_BASE \ | |
| 48 | + ((FIXADDR_START - PAGE_SIZE * (CPU_ENTRY_AREA_PAGES + 1)) & PMD_MASK) | |
| 49 | + | |
| 50 | +#define PKMAP_BASE \ | |
| 51 | + ((CPU_ENTRY_AREA_BASE - PAGE_SIZE) & PMD_MASK) | |
| 43 | 52 | |
| 44 | 53 | #ifdef CONFIG_HIGHMEM |
| 45 | 54 | # define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE) |
| 46 | 55 | #else |
| 47 | −# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) | |
| 56 | +# define VMALLOC_END (CPU_ENTRY_AREA_BASE - 2 * PAGE_SIZE) | |
| 48 | 57 | #endif |
| 49 | 58 | |
| 50 | 59 | #define MODULES_VADDR VMALLOC_START |
| @@ -131,9 +131,97 @@ static inline pud_t native_pudp_get_and_clear(pud_t *xp) · 130 unmodified lines | ||
| 131 | 131 | #endif |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 135 | +/* | |
| 136 | + * All top-level PAGE_TABLE_ISOLATION page tables are order-1 pages | |
| 137 | + * (8k-aligned and 8k in size). The kernel one is at the beginning 4k and | |
| 138 | + * the user one is in the last 4k. To switch between them, you | |
| 139 | + * just need to flip the 12th bit in their addresses. | |
| 140 | + */ | |
| 141 | +#define PTI_PGTABLE_SWITCH_BIT PAGE_SHIFT | |
| 142 | + | |
| 143 | +/* | |
| 144 | + * This generates better code than the inline assembly in | |
| 145 | + * __set_bit(). | |
| 146 | + */ | |
| 147 | +static inline void *ptr_set_bit(void *ptr, int bit) | |
| 148 | +{ | |
| 149 | + unsigned long __ptr = (unsigned long)ptr; | |
| 150 | + | |
| 151 | + __ptr |= BIT(bit); | |
| 152 | + return (void *)__ptr; | |
| 153 | +} | |
| 154 | +static inline void *ptr_clear_bit(void *ptr, int bit) | |
| 155 | +{ | |
| 156 | + unsigned long __ptr = (unsigned long)ptr; | |
| 157 | + | |
| 158 | + __ptr &= ~BIT(bit); | |
| 159 | + return (void *)__ptr; | |
| 160 | +} | |
| 161 | + | |
| 162 | +static inline pgd_t *kernel_to_user_pgdp(pgd_t *pgdp) | |
| 163 | +{ | |
| 164 | + return ptr_set_bit(pgdp, PTI_PGTABLE_SWITCH_BIT); | |
| 165 | +} | |
| 166 | + | |
| 167 | +static inline pgd_t *user_to_kernel_pgdp(pgd_t *pgdp) | |
| 168 | +{ | |
| 169 | + return ptr_clear_bit(pgdp, PTI_PGTABLE_SWITCH_BIT); | |
| 170 | +} | |
| 171 | + | |
| 172 | +static inline p4d_t *kernel_to_user_p4dp(p4d_t *p4dp) | |
| 173 | +{ | |
| 174 | + return ptr_set_bit(p4dp, PTI_PGTABLE_SWITCH_BIT); | |
| 175 | +} | |
| 176 | + | |
| 177 | +static inline p4d_t *user_to_kernel_p4dp(p4d_t *p4dp) | |
| 178 | +{ | |
| 179 | + return ptr_clear_bit(p4dp, PTI_PGTABLE_SWITCH_BIT); | |
| 180 | +} | |
| 181 | +#endif /* CONFIG_PAGE_TABLE_ISOLATION */ | |
| 182 | + | |
| 183 | +/* | |
| 184 | + * Page table pages are page-aligned. The lower half of the top | |
| 185 | + * level is used for userspace and the top half for the kernel. | |
| 186 | + * | |
| 187 | + * Returns true for parts of the PGD that map userspace and | |
| 188 | + * false for the parts that map the kernel. | |
| 189 | + */ | |
| 190 | +static inline bool pgdp_maps_userspace(void *__ptr) | |
| 191 | +{ | |
| 192 | + unsigned long ptr = (unsigned long)__ptr; | |
| 193 | + | |
| 194 | + return (ptr & ~PAGE_MASK) < (PAGE_SIZE / 2); | |
| 195 | +} | |
| 196 | + | |
| 197 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 198 | +pgd_t __pti_set_user_pgd(pgd_t *pgdp, pgd_t pgd); | |
| 199 | + | |
| 200 | +/* | |
| 201 | + * Take a PGD location (pgdp) and a pgd value that needs to be set there. | |
| 202 | + * Populates the user and returns the resulting PGD that must be set in | |
| 203 | + * the kernel copy of the page tables. | |
| 204 | + */ | |
| 205 | +static inline pgd_t pti_set_user_pgd(pgd_t *pgdp, pgd_t pgd) | |
| 206 | +{ | |
| 207 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 208 | + return pgd; | |
| 209 | + return __pti_set_user_pgd(pgdp, pgd); | |
| 210 | +} | |
| 211 | +#else | |
| 212 | +static inline pgd_t pti_set_user_pgd(pgd_t *pgdp, pgd_t pgd) | |
| 213 | +{ | |
| 214 | + return pgd; | |
| 215 | +} | |
| 216 | +#endif | |
| 217 | + | |
| 134 | 218 | static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) |
| 135 | 219 | { |
| 220 | +#if defined(CONFIG_PAGE_TABLE_ISOLATION) && !defined(CONFIG_X86_5LEVEL) | |
| 221 | + p4dp->pgd = pti_set_user_pgd(&p4dp->pgd, p4d.pgd); | |
| 222 | +#else | |
| 136 | 223 | *p4dp = p4d; |
| 224 | +#endif | |
| 137 | 225 | } |
| 138 | 226 | |
| 139 | 227 | static inline void native_p4d_clear(p4d_t *p4d) |
| @@ -147,7 +235,11 @@ static inline void native_p4d_clear(p4d_t *p4d) · 7 unmodified lines | ||
| 147 | 235 | |
| 148 | 236 | static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd) |
| 149 | 237 | { |
| 238 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 239 | + *pgdp = pti_set_user_pgd(pgdp, pgd); | |
| 240 | +#else | |
| 150 | 241 | *pgdp = pgd; |
| 242 | +#endif | |
| 151 | 243 | } |
| 152 | 244 | |
| 153 | 245 | static inline void native_pgd_clear(pgd_t *pgd) |
| @@ -76,32 +76,45 @@ typedef struct { pteval_t pte; } pte_t; · 75 unmodified lines | ||
| 76 | 76 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) |
| 77 | 77 | |
| 78 | 78 | /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ |
| 79 | −#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) | |
| 79 | +#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) | |
| 80 | + | |
| 80 | 81 | #ifdef CONFIG_X86_5LEVEL |
| 81 | −#define VMALLOC_SIZE_TB _AC(16384, UL) | |
| 82 | −#define __VMALLOC_BASE _AC(0xff92000000000000, UL) | |
| 83 | −#define __VMEMMAP_BASE _AC(0xffd4000000000000, UL) | |
| 82 | +# define VMALLOC_SIZE_TB _AC(12800, UL) | |
| 83 | +# define __VMALLOC_BASE _AC(0xffa0000000000000, UL) | |
| 84 | +# define __VMEMMAP_BASE _AC(0xffd4000000000000, UL) | |
| 85 | +# define LDT_PGD_ENTRY _AC(-112, UL) | |
| 86 | +# define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT) | |
| 84 | 87 | #else |
| 85 | −#define VMALLOC_SIZE_TB _AC(32, UL) | |
| 86 | −#define __VMALLOC_BASE _AC(0xffffc90000000000, UL) | |
| 87 | −#define __VMEMMAP_BASE _AC(0xffffea0000000000, UL) | |
| 88 | +# define VMALLOC_SIZE_TB _AC(32, UL) | |
| 89 | +# define __VMALLOC_BASE _AC(0xffffc90000000000, UL) | |
| 90 | +# define __VMEMMAP_BASE _AC(0xffffea0000000000, UL) | |
| 91 | +# define LDT_PGD_ENTRY _AC(-4, UL) | |
| 92 | +# define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT) | |
| 88 | 93 | #endif |
| 94 | + | |
| 89 | 95 | #ifdef CONFIG_RANDOMIZE_MEMORY |
| 90 | −#define VMALLOC_START vmalloc_base | |
| 91 | −#define VMEMMAP_START vmemmap_base | |
| 96 | +# define VMALLOC_START vmalloc_base | |
| 97 | +# define VMEMMAP_START vmemmap_base | |
| 92 | 98 | #else |
| 93 | −#define VMALLOC_START __VMALLOC_BASE | |
| 94 | −#define VMEMMAP_START __VMEMMAP_BASE | |
| 99 | +# define VMALLOC_START __VMALLOC_BASE | |
| 100 | +# define VMEMMAP_START __VMEMMAP_BASE | |
| 95 | 101 | #endif /* CONFIG_RANDOMIZE_MEMORY */ |
| 96 | −#define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL)) | |
| 97 | −#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) | |
| 102 | + | |
| 103 | +#define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL)) | |
| 104 | + | |
| 105 | +#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) | |
| 98 | 106 | /* The module sections ends with the start of the fixmap */ |
| 99 | −#define MODULES_END __fix_to_virt(__end_of_fixed_addresses + 1) | |
| 100 | −#define MODULES_LEN (MODULES_END - MODULES_VADDR) | |
| 101 | −#define ESPFIX_PGD_ENTRY _AC(-2, UL) | |
| 102 | −#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) | |
| 103 | −#define EFI_VA_START ( -4 * (_AC(1, UL) << 30)) | |
| 104 | −#define EFI_VA_END (-68 * (_AC(1, UL) << 30)) | |
| 107 | +#define MODULES_END __fix_to_virt(__end_of_fixed_addresses + 1) | |
| 108 | +#define MODULES_LEN (MODULES_END - MODULES_VADDR) | |
| 109 | + | |
| 110 | +#define ESPFIX_PGD_ENTRY _AC(-2, UL) | |
| 111 | +#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) | |
| 112 | + | |
| 113 | +#define CPU_ENTRY_AREA_PGD _AC(-3, UL) | |
| 114 | +#define CPU_ENTRY_AREA_BASE (CPU_ENTRY_AREA_PGD << P4D_SHIFT) | |
| 115 | + | |
| 116 | +#define EFI_VA_START ( -4 * (_AC(1, UL) << 30)) | |
| 117 | +#define EFI_VA_END (-68 * (_AC(1, UL) << 30)) | |
| 105 | 118 | |
| 106 | 119 | #define EARLY_DYNAMIC_PAGE_TABLES 64 |
| 107 | 120 | |
| @@ -38,6 +38,11 @@ · 37 unmodified lines | ||
| 38 | 38 | #define CR3_ADDR_MASK __sme_clr(0x7FFFFFFFFFFFF000ull) |
| 39 | 39 | #define CR3_PCID_MASK 0xFFFull |
| 40 | 40 | #define CR3_NOFLUSH BIT_ULL(63) |
| 41 | + | |
| 42 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 43 | +# define X86_CR3_PTI_SWITCH_BIT 11 | |
| 44 | +#endif | |
| 45 | + | |
| 41 | 46 | #else |
| 42 | 47 | /* |
| 43 | 48 | * CR3_ADDR_MASK needs at least bits 31:5 set on PAE systems, and we save |
| @@ -163,9 +163,9 @@ enum cpuid_regs_idx { · 162 unmodified lines | ||
| 163 | 163 | extern struct cpuinfo_x86 boot_cpu_data; |
| 164 | 164 | extern struct cpuinfo_x86 new_cpu_data; |
| 165 | 165 | |
| 166 | −extern struct tss_struct doublefault_tss; | |
| 167 | −extern __u32 cpu_caps_cleared[NCAPINTS]; | |
| 168 | −extern __u32 cpu_caps_set[NCAPINTS]; | |
| 166 | +extern struct x86_hw_tss doublefault_tss; | |
| 167 | +extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS]; | |
| 168 | +extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS]; | |
| 169 | 169 | |
| 170 | 170 | #ifdef CONFIG_SMP |
| 171 | 171 | DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); |
| @@ -253,6 +253,11 @@ static inline void load_cr3(pgd_t *pgdir) · 81 unmodified lines | ||
| 253 | 253 | write_cr3(__sme_pa(pgdir)); |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | +/* | |
| 257 | + * Note that while the legacy 'TSS' name comes from 'Task State Segment', | |
| 258 | + * on modern x86 CPUs the TSS also holds information important to 64-bit mode, | |
| 259 | + * unrelated to the task-switch mechanism: | |
| 260 | + */ | |
| 256 | 261 | #ifdef CONFIG_X86_32 |
| 257 | 262 | /* This is the TSS defined by the hardware. */ |
| 258 | 263 | struct x86_hw_tss { |
| @@ -305,7 +310,13 @@ struct x86_hw_tss { · 46 unmodified lines | ||
| 305 | 310 | struct x86_hw_tss { |
| 306 | 311 | u32 reserved1; |
| 307 | 312 | u64 sp0; |
| 313 | + | |
| 314 | + /* | |
| 315 | + * We store cpu_current_top_of_stack in sp1 so it's always accessible. | |
| 316 | + * Linux does not use ring 1, so sp1 is not otherwise needed. | |
| 317 | + */ | |
| 308 | 318 | u64 sp1; |
| 319 | + | |
| 309 | 320 | u64 sp2; |
| 310 | 321 | u64 reserved2; |
| 311 | 322 | u64 ist[7]; |
| @@ -323,12 +334,22 @@ struct x86_hw_tss { · 11 unmodified lines | ||
| 323 | 334 | #define IO_BITMAP_BITS 65536 |
| 324 | 335 | #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) |
| 325 | 336 | #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) |
| 326 | −#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap) | |
| 337 | +#define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss)) | |
| 327 | 338 | #define INVALID_IO_BITMAP_OFFSET 0x8000 |
| 328 | 339 | |
| 340 | +struct entry_stack { | |
| 341 | + unsigned long words[64]; | |
| 342 | +}; | |
| 343 | + | |
| 344 | +struct entry_stack_page { | |
| 345 | + struct entry_stack stack; | |
| 346 | +} __aligned(PAGE_SIZE); | |
| 347 | + | |
| 329 | 348 | struct tss_struct { |
| 330 | 349 | /* |
| 331 | − * The hardware state: | |
| 350 | + * The fixed hardware portion. This must not cross a page boundary | |
| 351 | + * at risk of violating the SDM's advice and potentially triggering | |
| 352 | + * errata. | |
| 332 | 353 | */ |
| 333 | 354 | struct x86_hw_tss x86_tss; |
| 334 | 355 | |
| @@ -339,18 +360,9 @@ struct tss_struct { · 4 unmodified lines | ||
| 339 | 360 | * be within the limit. |
| 340 | 361 | */ |
| 341 | 362 | unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; |
| 363 | +} __aligned(PAGE_SIZE); | |
| 342 | 364 | |
| 343 | −#ifdef CONFIG_X86_32 | |
| 344 | − /* | |
| 345 | − * Space for the temporary SYSENTER stack. | |
| 346 | − */ | |
| 347 | − unsigned long SYSENTER_stack_canary; | |
| 348 | − unsigned long SYSENTER_stack[64]; | |
| 349 | −#endif | |
| 350 | − | |
| 351 | −} ____cacheline_aligned; | |
| 352 | − | |
| 353 | −DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss); | |
| 365 | +DECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw); | |
| 354 | 366 | |
| 355 | 367 | /* |
| 356 | 368 | * sizeof(unsigned long) coming from an extra "long" at the end |
| @@ -364,6 +376,9 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss); · 7 unmodified lines | ||
| 364 | 376 | |
| 365 | 377 | #ifdef CONFIG_X86_32 |
| 366 | 378 | DECLARE_PER_CPU(unsigned long, cpu_current_top_of_stack); |
| 379 | +#else | |
| 380 | +/* The RO copy can't be accessed with this_cpu_xyz(), so use the RW copy. */ | |
| 381 | +#define cpu_current_top_of_stack cpu_tss_rw.x86_tss.sp1 | |
| 367 | 382 | #endif |
| 368 | 383 | |
| 369 | 384 | /* |
| @@ -523,7 +538,7 @@ static inline void native_set_iopl_mask(unsigned mask) · 153 unmodified lines | ||
| 523 | 538 | static inline void |
| 524 | 539 | native_load_sp0(unsigned long sp0) |
| 525 | 540 | { |
| 526 | − this_cpu_write(cpu_tss.x86_tss.sp0, sp0); | |
| 541 | + this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0); | |
| 527 | 542 | } |
| 528 | 543 | |
| 529 | 544 | static inline void native_swapgs(void) |
| @@ -535,12 +550,12 @@ static inline void native_swapgs(void) · 5 unmodified lines | ||
| 535 | 550 | |
| 536 | 551 | static inline unsigned long current_top_of_stack(void) |
| 537 | 552 | { |
| 538 | −#ifdef CONFIG_X86_64 | |
| 539 | − return this_cpu_read_stable(cpu_tss.x86_tss.sp0); | |
| 540 | −#else | |
| 541 | − /* sp0 on x86_32 is special in and around vm86 mode. */ | |
| 553 | + /* | |
| 554 | + * We can't read directly from tss.sp0: sp0 on x86_32 is special in | |
| 555 | + * and around vm86 mode and sp0 on x86_64 is special because of the | |
| 556 | + * entry trampoline. | |
| 557 | + */ | |
| 542 | 558 | return this_cpu_read_stable(cpu_current_top_of_stack); |
| 543 | −#endif | |
| 544 | 559 | } |
| 545 | 560 | |
| 546 | 561 | static inline bool on_thread_stack(void) |
| @@ -837,13 +852,22 @@ static inline void spin_lock_prefetch(const void *x) · 290 unmodified lines | ||
| 837 | 852 | |
| 838 | 853 | #else |
| 839 | 854 | /* |
| 840 | − * User space process size. 47bits minus one guard page. The guard | |
| 841 | − * page is necessary on Intel CPUs: if a SYSCALL instruction is at | |
| 842 | − * the highest possible canonical userspace address, then that | |
| 843 | − * syscall will enter the kernel with a non-canonical return | |
| 844 | − * address, and SYSRET will explode dangerously. We avoid this | |
| 845 | − * particular problem by preventing anything from being mapped | |
| 846 | − * at the maximum canonical address. | |
| 855 | + * User space process size. This is the first address outside the user range. | |
| 856 | + * There are a few constraints that determine this: | |
| 857 | + * | |
| 858 | + * On Intel CPUs, if a SYSCALL instruction is at the highest canonical | |
| 859 | + * address, then that syscall will enter the kernel with a | |
| 860 | + * non-canonical return address, and SYSRET will explode dangerously. | |
| 861 | + * We avoid this particular problem by preventing anything executable | |
| 862 | + * from being mapped at the maximum canonical address. | |
| 863 | + * | |
| 864 | + * On AMD CPUs in the Ryzen family, there's a nasty bug in which the | |
| 865 | + * CPUs malfunction if they execute code from the highest canonical page. | |
| 866 | + * They'll speculate right off the end of the canonical space, and | |
| 867 | + * bad things happen. This is worked around in the same way as the | |
| 868 | + * Intel problem. | |
| 869 | + * | |
| 870 | + * With page table isolation enabled, we map the LDT in ... [stay tuned] | |
| 847 | 871 | */ |
| 848 | 872 | #define TASK_SIZE_MAX ((1UL << __VIRTUAL_MASK_SHIFT) - PAGE_SIZE) |
| 849 | 873 | |
| @@ -0,0 +1,14 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +#ifndef _ASM_X86_PTI_H | |
| 3 | +#define _ASM_X86_PTI_H | |
| 4 | +#ifndef __ASSEMBLY__ | |
| 5 | + | |
| 6 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 7 | +extern void pti_init(void); | |
| 8 | +extern void pti_check_boottime_disable(void); | |
| 9 | +#else | |
| 10 | +static inline void pti_check_boottime_disable(void) { } | |
| 11 | +#endif | |
| 12 | + | |
| 13 | +#endif /* __ASSEMBLY__ */ | |
| 14 | +#endif /* _ASM_X86_PTI_H */ | |
| @@ -16,6 +16,7 @@ enum stack_type { · 15 unmodified lines | ||
| 16 | 16 | STACK_TYPE_TASK, |
| 17 | 17 | STACK_TYPE_IRQ, |
| 18 | 18 | STACK_TYPE_SOFTIRQ, |
| 19 | + STACK_TYPE_ENTRY, | |
| 19 | 20 | STACK_TYPE_EXCEPTION, |
| 20 | 21 | STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1, |
| 21 | 22 | }; |
| @@ -28,6 +29,8 @@ struct stack_info { · 6 unmodified lines | ||
| 28 | 29 | bool in_task_stack(unsigned long *stack, struct task_struct *task, |
| 29 | 30 | struct stack_info *info); |
| 30 | 31 | |
| 32 | +bool in_entry_stack(unsigned long *stack, struct stack_info *info); | |
| 33 | + | |
| 31 | 34 | int get_stack_info(unsigned long *stack, struct task_struct *task, |
| 32 | 35 | struct stack_info *info, unsigned long *visit_mask); |
| 33 | 36 | |
| @@ -12,7 +12,13 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | /* image of the saved processor state */ |
| 14 | 14 | struct saved_context { |
| 15 | − u16 es, fs, gs, ss; | |
| 15 | + /* | |
| 16 | + * On x86_32, all segment registers, with the possible exception of | |
| 17 | + * gs, are saved at kernel entry in pt_regs. | |
| 18 | + */ | |
| 19 | +#ifdef CONFIG_X86_32_LAZY_GS | |
| 20 | + u16 gs; | |
| 21 | +#endif | |
| 16 | 22 | unsigned long cr0, cr2, cr3, cr4; |
| 17 | 23 | u64 misc_enable; |
| 18 | 24 | bool misc_enable_saved; |
| @@ -20,8 +20,20 @@ · 19 unmodified lines | ||
| 20 | 20 | */ |
| 21 | 21 | struct saved_context { |
| 22 | 22 | struct pt_regs regs; |
| 23 | − u16 ds, es, fs, gs, ss; | |
| 24 | − unsigned long gs_base, gs_kernel_base, fs_base; | |
| 23 | + | |
| 24 | + /* | |
| 25 | + * User CS and SS are saved in current_pt_regs(). The rest of the | |
| 26 | + * segment selectors need to be saved and restored here. | |
| 27 | + */ | |
| 28 | + u16 ds, es, fs, gs; | |
| 29 | + | |
| 30 | + /* | |
| 31 | + * Usermode FSBASE and GSBASE may not match the fs and gs selectors, | |
| 32 | + * so we save them separately. We save the kernelmode GSBASE to | |
| 33 | + * restore percpu access after resume. | |
| 34 | + */ | |
| 35 | + unsigned long kernelmode_gs_base, usermode_gs_base, fs_base; | |
| 36 | + | |
| 25 | 37 | unsigned long cr0, cr2, cr3, cr4, cr8; |
| 26 | 38 | u64 misc_enable; |
| 27 | 39 | bool misc_enable_saved; |
| @@ -30,8 +42,7 @@ struct saved_context { · 2 unmodified lines | ||
| 30 | 42 | u16 gdt_pad; /* Unused */ |
| 31 | 43 | struct desc_ptr gdt_desc; |
| 32 | 44 | u16 idt_pad; |
| 33 | − u16 idt_limit; | |
| 34 | − unsigned long idt_base; | |
| 45 | + struct desc_ptr idt; | |
| 35 | 46 | u16 ldt; |
| 36 | 47 | u16 tss; |
| 37 | 48 | unsigned long tr; |
| @@ -16,8 +16,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, · 15 unmodified lines | ||
| 16 | 16 | struct tss_struct *tss); |
| 17 | 17 | |
| 18 | 18 | /* This runs runs on the previous thread's stack. */ |
| 19 | −static inline void prepare_switch_to(struct task_struct *prev, | |
| 20 | − struct task_struct *next) | |
| 19 | +static inline void prepare_switch_to(struct task_struct *next) | |
| 21 | 20 | { |
| 22 | 21 | #ifdef CONFIG_VMAP_STACK |
| 23 | 22 | /* |
| @@ -70,7 +69,7 @@ struct fork_frame { · 46 unmodified lines | ||
| 70 | 69 | |
| 71 | 70 | #define switch_to(prev, next, last) \ |
| 72 | 71 | do { \ |
| 73 | − prepare_switch_to(prev, next); \ | |
| 72 | + prepare_switch_to(next); \ | |
| 74 | 73 | \ |
| 75 | 74 | ((last) = __switch_to_asm((prev), (next))); \ |
| 76 | 75 | } while (0) |
| @@ -79,10 +78,10 @@ do { \ · 2 unmodified lines | ||
| 79 | 78 | static inline void refresh_sysenter_cs(struct thread_struct *thread) |
| 80 | 79 | { |
| 81 | 80 | /* Only happens when SEP is enabled, no need to test "SEP"arately: */ |
| 82 | − if (unlikely(this_cpu_read(cpu_tss.x86_tss.ss1) == thread->sysenter_cs)) | |
| 81 | + if (unlikely(this_cpu_read(cpu_tss_rw.x86_tss.ss1) == thread->sysenter_cs)) | |
| 83 | 82 | return; |
| 84 | 83 | |
| 85 | − this_cpu_write(cpu_tss.x86_tss.ss1, thread->sysenter_cs); | |
| 84 | + this_cpu_write(cpu_tss_rw.x86_tss.ss1, thread->sysenter_cs); | |
| 86 | 85 | wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); |
| 87 | 86 | } |
| 88 | 87 | #endif |
| @@ -90,10 +89,12 @@ static inline void refresh_sysenter_cs(struct thread_struct *thread) · 1 unmodified line | ||
| 90 | 89 | /* This is used when switching tasks or entering/exiting vm86 mode. */ |
| 91 | 90 | static inline void update_sp0(struct task_struct *task) |
| 92 | 91 | { |
| 92 | + /* On x86_64, sp0 always points to the entry trampoline stack, which is constant: */ | |
| 93 | 93 | #ifdef CONFIG_X86_32 |
| 94 | 94 | load_sp0(task->thread.sp0); |
| 95 | 95 | #else |
| 96 | − load_sp0(task_top_of_stack(task)); | |
| 96 | + if (static_cpu_has(X86_FEATURE_XENPV)) | |
| 97 | + load_sp0(task_top_of_stack(task)); | |
| 97 | 98 | #endif |
| 98 | 99 | } |
| 99 | 100 | |
| @@ -207,7 +207,7 @@ static inline int arch_within_stack_frames(const void * const stack, · 206 unmodified lines | ||
| 207 | 207 | #else /* !__ASSEMBLY__ */ |
| 208 | 208 | |
| 209 | 209 | #ifdef CONFIG_X86_64 |
| 210 | −# define cpu_current_top_of_stack (cpu_tss + TSS_sp0) | |
| 210 | +# define cpu_current_top_of_stack (cpu_tss_rw + TSS_sp1) | |
| 211 | 211 | #endif |
| 212 | 212 | |
| 213 | 213 | #endif |
| @@ -9,70 +9,130 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <asm/cpufeature.h> |
| 10 | 10 | #include <asm/special_insns.h> |
| 11 | 11 | #include <asm/smp.h> |
| 12 | +#include <asm/invpcid.h> | |
| 13 | +#include <asm/pti.h> | |
| 14 | +#include <asm/processor-flags.h> | |
| 12 | 15 | |
| 13 | −static inline void __invpcid(unsigned long pcid, unsigned long addr, | |
| 14 | − unsigned long type) | |
| 15 | −{ | |
| 16 | − struct { u64 d[2]; } desc = { { pcid, addr } }; | |
| 16 | +/* | |
| 17 | + * The x86 feature is called PCID (Process Context IDentifier). It is similar | |
| 18 | + * to what is traditionally called ASID on the RISC processors. | |
| 19 | + * | |
| 20 | + * We don't use the traditional ASID implementation, where each process/mm gets | |
| 21 | + * its own ASID and flush/restart when we run out of ASID space. | |
| 22 | + * | |
| 23 | + * Instead we have a small per-cpu array of ASIDs and cache the last few mm's | |
| 24 | + * that came by on this CPU, allowing cheaper switch_mm between processes on | |
| 25 | + * this CPU. | |
| 26 | + * | |
| 27 | + * We end up with different spaces for different things. To avoid confusion we | |
| 28 | + * use different names for each of them: | |
| 29 | + * | |
| 30 | + * ASID - [0, TLB_NR_DYN_ASIDS-1] | |
| 31 | + * the canonical identifier for an mm | |
| 32 | + * | |
| 33 | + * kPCID - [1, TLB_NR_DYN_ASIDS] | |
| 34 | + * the value we write into the PCID part of CR3; corresponds to the | |
| 35 | + * ASID+1, because PCID 0 is special. | |
| 36 | + * | |
| 37 | + * uPCID - [2048 + 1, 2048 + TLB_NR_DYN_ASIDS] | |
| 38 | + * for KPTI each mm has two address spaces and thus needs two | |
| 39 | + * PCID values, but we can still do with a single ASID denomination | |
| 40 | + * for each mm. Corresponds to kPCID + 2048. | |
| 41 | + * | |
| 42 | + */ | |
| 17 | 43 | |
| 18 | − /* | |
| 19 | − * The memory clobber is because the whole point is to invalidate | |
| 20 | − * stale TLB entries and, especially if we're flushing global | |
| 21 | − * mappings, we don't want the compiler to reorder any subsequent | |
| 22 | − * memory accesses before the TLB flush. | |
| 23 | − * | |
| 24 | − * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and | |
| 25 | − * invpcid (%rcx), %rax in long mode. | |
| 26 | − */ | |
| 27 | − asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" | |
| 28 | − : : "m" (desc), "a" (type), "c" (&desc) : "memory"); | |
| 29 | −} | |
| 44 | +/* There are 12 bits of space for ASIDS in CR3 */ | |
| 45 | +#define CR3_HW_ASID_BITS 12 | |
| 30 | 46 | |
| 31 | −#define INVPCID_TYPE_INDIV_ADDR 0 | |
| 32 | −#define INVPCID_TYPE_SINGLE_CTXT 1 | |
| 33 | −#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 | |
| 34 | −#define INVPCID_TYPE_ALL_NON_GLOBAL 3 | |
| 47 | +/* | |
| 48 | + * When enabled, PAGE_TABLE_ISOLATION consumes a single bit for | |
| 49 | + * user/kernel switches | |
| 50 | + */ | |
| 51 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 52 | +# define PTI_CONSUMED_PCID_BITS 1 | |
| 53 | +#else | |
| 54 | +# define PTI_CONSUMED_PCID_BITS 0 | |
| 55 | +#endif | |
| 35 | 56 | |
| 36 | −/* Flush all mappings for a given pcid and addr, not including globals. */ | |
| 37 | −static inline void invpcid_flush_one(unsigned long pcid, | |
| 38 | − unsigned long addr) | |
| 39 | −{ | |
| 40 | − __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); | |
| 41 | −} | |
| 57 | +#define CR3_AVAIL_PCID_BITS (X86_CR3_PCID_BITS - PTI_CONSUMED_PCID_BITS) | |
| 58 | + | |
| 59 | +/* | |
| 60 | + * ASIDs are zero-based: 0->MAX_AVAIL_ASID are valid. -1 below to account | |
| 61 | + * for them being zero-based. Another -1 is because PCID 0 is reserved for | |
| 62 | + * use by non-PCID-aware users. | |
| 63 | + */ | |
| 64 | +#define MAX_ASID_AVAILABLE ((1 << CR3_AVAIL_PCID_BITS) - 2) | |
| 65 | + | |
| 66 | +/* | |
| 67 | + * 6 because 6 should be plenty and struct tlb_state will fit in two cache | |
| 68 | + * lines. | |
| 69 | + */ | |
| 70 | +#define TLB_NR_DYN_ASIDS 6 | |
| 42 | 71 | |
| 43 | −/* Flush all mappings for a given PCID, not including globals. */ | |
| 44 | −static inline void invpcid_flush_single_context(unsigned long pcid) | |
| 72 | +/* | |
| 73 | + * Given @asid, compute kPCID | |
| 74 | + */ | |
| 75 | +static inline u16 kern_pcid(u16 asid) | |
| 45 | 76 | { |
| 46 | − __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); | |
| 77 | + VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); | |
| 78 | + | |
| 79 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 80 | + /* | |
| 81 | + * Make sure that the dynamic ASID space does not confict with the | |
| 82 | + * bit we are using to switch between user and kernel ASIDs. | |
| 83 | + */ | |
| 84 | + BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_SWITCH_BIT)); | |
| 85 | + | |
| 86 | + /* | |
| 87 | + * The ASID being passed in here should have respected the | |
| 88 | + * MAX_ASID_AVAILABLE and thus never have the switch bit set. | |
| 89 | + */ | |
| 90 | + VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_SWITCH_BIT)); | |
| 91 | +#endif | |
| 92 | + /* | |
| 93 | + * The dynamically-assigned ASIDs that get passed in are small | |
| 94 | + * (<TLB_NR_DYN_ASIDS). They never have the high switch bit set, | |
| 95 | + * so do not bother to clear it. | |
| 96 | + * | |
| 97 | + * If PCID is on, ASID-aware code paths put the ASID+1 into the | |
| 98 | + * PCID bits. This serves two purposes. It prevents a nasty | |
| 99 | + * situation in which PCID-unaware code saves CR3, loads some other | |
| 100 | + * value (with PCID == 0), and then restores CR3, thus corrupting | |
| 101 | + * the TLB for ASID 0 if the saved ASID was nonzero. It also means | |
| 102 | + * that any bugs involving loading a PCID-enabled CR3 with | |
| 103 | + * CR4.PCIDE off will trigger deterministically. | |
| 104 | + */ | |
| 105 | + return asid + 1; | |
| 47 | 106 | } |
| 48 | 107 | |
| 49 | −/* Flush all mappings, including globals, for all PCIDs. */ | |
| 50 | −static inline void invpcid_flush_all(void) | |
| 108 | +/* | |
| 109 | + * Given @asid, compute uPCID | |
| 110 | + */ | |
| 111 | +static inline u16 user_pcid(u16 asid) | |
| 51 | 112 | { |
| 52 | − __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); | |
| 113 | + u16 ret = kern_pcid(asid); | |
| 114 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 115 | + ret |= 1 << X86_CR3_PTI_SWITCH_BIT; | |
| 116 | +#endif | |
| 117 | + return ret; | |
| 53 | 118 | } |
| 54 | 119 | |
| 55 | −/* Flush all mappings for all PCIDs except globals. */ | |
| 56 | −static inline void invpcid_flush_all_nonglobals(void) | |
| 120 | +struct pgd_t; | |
| 121 | +static inline unsigned long build_cr3(pgd_t *pgd, u16 asid) | |
| 57 | 122 | { |
| 58 | − __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); | |
| 123 | + if (static_cpu_has(X86_FEATURE_PCID)) { | |
| 124 | + return __sme_pa(pgd) | kern_pcid(asid); | |
| 125 | + } else { | |
| 126 | + VM_WARN_ON_ONCE(asid != 0); | |
| 127 | + return __sme_pa(pgd); | |
| 128 | + } | |
| 59 | 129 | } |
| 60 | 130 | |
| 61 | −static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
| 131 | +static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid) | |
| 62 | 132 | { |
| 63 | − u64 new_tlb_gen; | |
| 64 | − | |
| 65 | − /* | |
| 66 | − * Bump the generation count. This also serves as a full barrier | |
| 67 | − * that synchronizes with switch_mm(): callers are required to order | |
| 68 | − * their read of mm_cpumask after their writes to the paging | |
| 69 | − * structures. | |
| 70 | − */ | |
| 71 | − smp_mb__before_atomic(); | |
| 72 | − new_tlb_gen = atomic64_inc_return(&mm->context.tlb_gen); | |
| 73 | − smp_mb__after_atomic(); | |
| 74 | − | |
| 75 | − return new_tlb_gen; | |
| 133 | + VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); | |
| 134 | + VM_WARN_ON_ONCE(!this_cpu_has(X86_FEATURE_PCID)); | |
| 135 | + return __sme_pa(pgd) | kern_pcid(asid) | CR3_NOFLUSH; | |
| 76 | 136 | } |
| 77 | 137 | |
| 78 | 138 | #ifdef CONFIG_PARAVIRT |
| @@ -99,12 +159,6 @@ static inline bool tlb_defer_switch_to_init_mm(void) · 20 unmodified lines | ||
| 99 | 159 | return !static_cpu_has(X86_FEATURE_PCID); |
| 100 | 160 | } |
| 101 | 161 | |
| 102 | −/* | |
| 103 | − * 6 because 6 should be plenty and struct tlb_state will fit in | |
| 104 | − * two cache lines. | |
| 105 | − */ | |
| 106 | −#define TLB_NR_DYN_ASIDS 6 | |
| 107 | − | |
| 108 | 162 | struct tlb_context { |
| 109 | 163 | u64 ctx_id; |
| 110 | 164 | u64 tlb_gen; |
| @@ -138,6 +192,24 @@ struct tlb_state { · 27 unmodified lines | ||
| 138 | 192 | */ |
| 139 | 193 | bool is_lazy; |
| 140 | 194 | |
| 195 | + /* | |
| 196 | + * If set we changed the page tables in such a way that we | |
| 197 | + * needed an invalidation of all contexts (aka. PCIDs / ASIDs). | |
| 198 | + * This tells us to go invalidate all the non-loaded ctxs[] | |
| 199 | + * on the next context switch. | |
| 200 | + * | |
| 201 | + * The current ctx was kept up-to-date as it ran and does not | |
| 202 | + * need to be invalidated. | |
| 203 | + */ | |
| 204 | + bool invalidate_other; | |
| 205 | + | |
| 206 | + /* | |
| 207 | + * Mask that contains TLB_NR_DYN_ASIDS+1 bits to indicate | |
| 208 | + * the corresponding user PCID needs a flush next time we | |
| 209 | + * switch to it; see SWITCH_TO_USER_CR3. | |
| 210 | + */ | |
| 211 | + unsigned short user_pcid_flush_mask; | |
| 212 | + | |
| 141 | 213 | /* |
| 142 | 214 | * Access to this CR4 shadow and to H/W CR4 is protected by |
| 143 | 215 | * disabling interrupts when modifying either one. |
| @@ -218,6 +290,14 @@ static inline unsigned long cr4_read_shadow(void) · 74 unmodified lines | ||
| 218 | 290 | return this_cpu_read(cpu_tlbstate.cr4); |
| 219 | 291 | } |
| 220 | 292 | |
| 293 | +/* | |
| 294 | + * Mark all other ASIDs as invalid, preserves the current. | |
| 295 | + */ | |
| 296 | +static inline void invalidate_other_asid(void) | |
| 297 | +{ | |
| 298 | + this_cpu_write(cpu_tlbstate.invalidate_other, true); | |
| 299 | +} | |
| 300 | + | |
| 221 | 301 | /* |
| 222 | 302 | * Save some of cr4 feature set we're using (e.g. Pentium 4MB |
| 223 | 303 | * enable and PPro Global page enable), so that any CPU's that boot |
| @@ -237,37 +317,63 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask) · 13 unmodified lines | ||
| 237 | 317 | |
| 238 | 318 | extern void initialize_tlbstate_and_flush(void); |
| 239 | 319 | |
| 240 | −static inline void __native_flush_tlb(void) | |
| 320 | +/* | |
| 321 | + * Given an ASID, flush the corresponding user ASID. We can delay this | |
| 322 | + * until the next time we switch to it. | |
| 323 | + * | |
| 324 | + * See SWITCH_TO_USER_CR3. | |
| 325 | + */ | |
| 326 | +static inline void invalidate_user_asid(u16 asid) | |
| 241 | 327 | { |
| 328 | + /* There is no user ASID if address space separation is off */ | |
| 329 | + if (!IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) | |
| 330 | + return; | |
| 331 | + | |
| 242 | 332 | /* |
| 243 | − * If current->mm == NULL then we borrow a mm which may change during a | |
| 244 | − * task switch and therefore we must not be preempted while we write CR3 | |
| 245 | − * back: | |
| 333 | + * We only have a single ASID if PCID is off and the CR3 | |
| 334 | + * write will have flushed it. | |
| 246 | 335 | */ |
| 247 | − preempt_disable(); | |
| 248 | − native_write_cr3(__native_read_cr3()); | |
| 249 | − preempt_enable(); | |
| 336 | + if (!cpu_feature_enabled(X86_FEATURE_PCID)) | |
| 337 | + return; | |
| 338 | + | |
| 339 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 340 | + return; | |
| 341 | + | |
| 342 | + __set_bit(kern_pcid(asid), | |
| 343 | + (unsigned long *)this_cpu_ptr(&cpu_tlbstate.user_pcid_flush_mask)); | |
| 250 | 344 | } |
| 251 | 345 | |
| 252 | −static inline void __native_flush_tlb_global_irq_disabled(void) | |
| 346 | +/* | |
| 347 | + * flush the entire current user mapping | |
| 348 | + */ | |
| 349 | +static inline void __native_flush_tlb(void) | |
| 253 | 350 | { |
| 254 | − unsigned long cr4; | |
| 351 | + /* | |
| 352 | + * Preemption or interrupts must be disabled to protect the access | |
| 353 | + * to the per CPU variable and to prevent being preempted between | |
| 354 | + * read_cr3() and write_cr3(). | |
| 355 | + */ | |
| 356 | + WARN_ON_ONCE(preemptible()); | |
| 255 | 357 | |
| 256 | − cr4 = this_cpu_read(cpu_tlbstate.cr4); | |
| 257 | − /* clear PGE */ | |
| 258 | − native_write_cr4(cr4 & ~X86_CR4_PGE); | |
| 259 | − /* write old PGE again and flush TLBs */ | |
| 260 | − native_write_cr4(cr4); | |
| 358 | + invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid)); | |
| 359 | + | |
| 360 | + /* If current->mm == NULL then the read_cr3() "borrows" an mm */ | |
| 361 | + native_write_cr3(__native_read_cr3()); | |
| 261 | 362 | } |
| 262 | 363 | |
| 364 | +/* | |
| 365 | + * flush everything | |
| 366 | + */ | |
| 263 | 367 | static inline void __native_flush_tlb_global(void) |
| 264 | 368 | { |
| 265 | − unsigned long flags; | |
| 369 | + unsigned long cr4, flags; | |
| 266 | 370 | |
| 267 | 371 | if (static_cpu_has(X86_FEATURE_INVPCID)) { |
| 268 | 372 | /* |
| 269 | 373 | * Using INVPCID is considerably faster than a pair of writes |
| 270 | 374 | * to CR4 sandwiched inside an IRQ flag save/restore. |
| 375 | + * | |
| 376 | + * Note, this works with CR4.PCIDE=0 or 1. | |
| 271 | 377 | */ |
| 272 | 378 | invpcid_flush_all(); |
| 273 | 379 | return; |
| @@ -280,36 +386,69 @@ static inline void __native_flush_tlb_global(void) · 6 unmodified lines | ||
| 280 | 386 | */ |
| 281 | 387 | raw_local_irq_save(flags); |
| 282 | 388 | |
| 283 | − __native_flush_tlb_global_irq_disabled(); | |
| 389 | + cr4 = this_cpu_read(cpu_tlbstate.cr4); | |
| 390 | + /* toggle PGE */ | |
| 391 | + native_write_cr4(cr4 ^ X86_CR4_PGE); | |
| 392 | + /* write old PGE again and flush TLBs */ | |
| 393 | + native_write_cr4(cr4); | |
| 284 | 394 | |
| 285 | 395 | raw_local_irq_restore(flags); |
| 286 | 396 | } |
| 287 | 397 | |
| 398 | +/* | |
| 399 | + * flush one page in the user mapping | |
| 400 | + */ | |
| 288 | 401 | static inline void __native_flush_tlb_single(unsigned long addr) |
| 289 | 402 | { |
| 403 | + u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid); | |
| 404 | + | |
| 290 | 405 | asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); |
| 406 | + | |
| 407 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 408 | + return; | |
| 409 | + | |
| 410 | + /* | |
| 411 | + * Some platforms #GP if we call invpcid(type=1/2) before CR4.PCIDE=1. | |
| 412 | + * Just use invalidate_user_asid() in case we are called early. | |
| 413 | + */ | |
| 414 | + if (!this_cpu_has(X86_FEATURE_INVPCID_SINGLE)) | |
| 415 | + invalidate_user_asid(loaded_mm_asid); | |
| 416 | + else | |
| 417 | + invpcid_flush_one(user_pcid(loaded_mm_asid), addr); | |
| 291 | 418 | } |
| 292 | 419 | |
| 420 | +/* | |
| 421 | + * flush everything | |
| 422 | + */ | |
| 293 | 423 | static inline void __flush_tlb_all(void) |
| 294 | 424 | { |
| 295 | − if (boot_cpu_has(X86_FEATURE_PGE)) | |
| 425 | + if (boot_cpu_has(X86_FEATURE_PGE)) { | |
| 296 | 426 | __flush_tlb_global(); |
| 297 | − else | |
| 427 | + } else { | |
| 428 | + /* | |
| 429 | + * !PGE -> !PCID (setup_pcid()), thus every flush is total. | |
| 430 | + */ | |
| 298 | 431 | __flush_tlb(); |
| 299 | − | |
| 300 | − /* | |
| 301 | − * Note: if we somehow had PCID but not PGE, then this wouldn't work -- | |
| 302 | − * we'd end up flushing kernel translations for the current ASID but | |
| 303 | − * we might fail to flush kernel translations for other cached ASIDs. | |
| 304 | − * | |
| 305 | − * To avoid this issue, we force PCID off if PGE is off. | |
| 306 | − */ | |
| 432 | + } | |
| 307 | 433 | } |
| 308 | 434 | |
| 435 | +/* | |
| 436 | + * flush one page in the kernel mapping | |
| 437 | + */ | |
| 309 | 438 | static inline void __flush_tlb_one(unsigned long addr) |
| 310 | 439 | { |
| 311 | 440 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); |
| 312 | 441 | __flush_tlb_single(addr); |
| 442 | + | |
| 443 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 444 | + return; | |
| 445 | + | |
| 446 | + /* | |
| 447 | + * __flush_tlb_single() will have cleared the TLB entry for this ASID, | |
| 448 | + * but since kernel space is replicated across all, we must also | |
| 449 | + * invalidate all others. | |
| 450 | + */ | |
| 451 | + invalidate_other_asid(); | |
| 313 | 452 | } |
| 314 | 453 | |
| 315 | 454 | #define TLB_FLUSH_ALL -1UL |
| @@ -370,6 +509,17 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a) · 54 unmodified lines | ||
| 370 | 509 | void native_flush_tlb_others(const struct cpumask *cpumask, |
| 371 | 510 | const struct flush_tlb_info *info); |
| 372 | 511 | |
| 512 | +static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
| 513 | +{ | |
| 514 | + /* | |
| 515 | + * Bump the generation count. This also serves as a full barrier | |
| 516 | + * that synchronizes with switch_mm(): callers are required to order | |
| 517 | + * their read of mm_cpumask after their writes to the paging | |
| 518 | + * structures. | |
| 519 | + */ | |
| 520 | + return atomic64_inc_return(&mm->context.tlb_gen); | |
| 521 | +} | |
| 522 | + | |
| 373 | 523 | static inline void arch_tlbbatch_add_mm(struct arch_tlbflush_unmap_batch *batch, |
| 374 | 524 | struct mm_struct *mm) |
| 375 | 525 | { |
| @@ -283,34 +283,34 @@ TRACE_EVENT(vector_alloc_managed, · 282 unmodified lines | ||
| 283 | 283 | DECLARE_EVENT_CLASS(vector_activate, |
| 284 | 284 | |
| 285 | 285 | TP_PROTO(unsigned int irq, bool is_managed, bool can_reserve, |
| 286 | − bool early), | |
| 286 | + bool reserve), | |
| 287 | 287 | |
| 288 | − TP_ARGS(irq, is_managed, can_reserve, early), | |
| 288 | + TP_ARGS(irq, is_managed, can_reserve, reserve), | |
| 289 | 289 | |
| 290 | 290 | TP_STRUCT__entry( |
| 291 | 291 | __field( unsigned int, irq ) |
| 292 | 292 | __field( bool, is_managed ) |
| 293 | 293 | __field( bool, can_reserve ) |
| 294 | − __field( bool, early ) | |
| 294 | + __field( bool, reserve ) | |
| 295 | 295 | ), |
| 296 | 296 | |
| 297 | 297 | TP_fast_assign( |
| 298 | 298 | __entry->irq = irq; |
| 299 | 299 | __entry->is_managed = is_managed; |
| 300 | 300 | __entry->can_reserve = can_reserve; |
| 301 | − __entry->early = early; | |
| 301 | + __entry->reserve = reserve; | |
| 302 | 302 | ), |
| 303 | 303 | |
| 304 | − TP_printk("irq=%u is_managed=%d can_reserve=%d early=%d", | |
| 304 | + TP_printk("irq=%u is_managed=%d can_reserve=%d reserve=%d", | |
| 305 | 305 | __entry->irq, __entry->is_managed, __entry->can_reserve, |
| 306 | − __entry->early) | |
| 306 | + __entry->reserve) | |
| 307 | 307 | ); |
| 308 | 308 | |
| 309 | 309 | #define DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(name) \ |
| 310 | 310 | DEFINE_EVENT_FN(vector_activate, name, \ |
| 311 | 311 | TP_PROTO(unsigned int irq, bool is_managed, \ |
| 312 | − bool can_reserve, bool early), \ | |
| 313 | − TP_ARGS(irq, is_managed, can_reserve, early), NULL, NULL); \ | |
| 312 | + bool can_reserve, bool reserve), \ | |
| 313 | + TP_ARGS(irq, is_managed, can_reserve, reserve), NULL, NULL); \ | |
| 314 | 314 | |
| 315 | 315 | DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_activate); |
| 316 | 316 | DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_deactivate); |
| @@ -75,7 +75,6 @@ dotraplinkage void do_segment_not_present(struct pt_regs *, long); · 74 unmodified lines | ||
| 75 | 75 | dotraplinkage void do_stack_segment(struct pt_regs *, long); |
| 76 | 76 | #ifdef CONFIG_X86_64 |
| 77 | 77 | dotraplinkage void do_double_fault(struct pt_regs *, long); |
| 78 | −asmlinkage struct pt_regs *sync_regs(struct pt_regs *); | |
| 79 | 78 | #endif |
| 80 | 79 | dotraplinkage void do_general_protection(struct pt_regs *, long); |
| 81 | 80 | dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); |
| @@ -7,6 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/ptrace.h> |
| 8 | 8 | #include <asm/stacktrace.h> |
| 9 | 9 | |
| 10 | +#define IRET_FRAME_OFFSET (offsetof(struct pt_regs, ip)) | |
| 11 | +#define IRET_FRAME_SIZE (sizeof(struct pt_regs) - IRET_FRAME_OFFSET) | |
| 12 | + | |
| 10 | 13 | struct unwind_state { |
| 11 | 14 | struct stack_info stack_info; |
| 12 | 15 | unsigned long stack_mask; |
| @@ -52,6 +55,10 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, · 39 unmodified lines | ||
| 52 | 55 | } |
| 53 | 56 | |
| 54 | 57 | #if defined(CONFIG_UNWINDER_ORC) || defined(CONFIG_UNWINDER_FRAME_POINTER) |
| 58 | +/* | |
| 59 | + * WARNING: The entire pt_regs may not be safe to dereference. In some cases, | |
| 60 | + * only the iret frame registers are accessible. Use with caution! | |
| 61 | + */ | |
| 55 | 62 | static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) |
| 56 | 63 | { |
| 57 | 64 | if (unwind_done(state)) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #ifdef CONFIG_X86_VSYSCALL_EMULATION |
| 9 | 9 | extern void map_vsyscall(void); |
| 10 | +extern void set_vsyscall_pgtable_user_bits(pgd_t *root); | |
| 10 | 11 | |
| 11 | 12 | /* |
| 12 | 13 | * Called on instruction fetch fault in vsyscall page. |
| @@ -78,7 +78,12 @@ · 77 unmodified lines | ||
| 78 | 78 | #define X86_CR3_PWT _BITUL(X86_CR3_PWT_BIT) |
| 79 | 79 | #define X86_CR3_PCD_BIT 4 /* Page Cache Disable */ |
| 80 | 80 | #define X86_CR3_PCD _BITUL(X86_CR3_PCD_BIT) |
| 81 | −#define X86_CR3_PCID_MASK _AC(0x00000fff,UL) /* PCID Mask */ | |
| 81 | + | |
| 82 | +#define X86_CR3_PCID_BITS 12 | |
| 83 | +#define X86_CR3_PCID_MASK (_AC((1UL << X86_CR3_PCID_BITS) - 1, UL)) | |
| 84 | + | |
| 85 | +#define X86_CR3_PCID_NOFLUSH_BIT 63 /* Preserve old PCID */ | |
| 86 | +#define X86_CR3_PCID_NOFLUSH _BITULL(X86_CR3_PCID_NOFLUSH_BIT) | |
| 82 | 87 | |
| 83 | 88 | /* |
| 84 | 89 | * Intel CPU features in CR4 |
| @@ -2626,11 +2626,13 @@ static int __init apic_set_verbosity(char *arg) · 2625 unmodified lines | ||
| 2626 | 2626 | apic_verbosity = APIC_DEBUG; |
| 2627 | 2627 | else if (strcmp("verbose", arg) == 0) |
| 2628 | 2628 | apic_verbosity = APIC_VERBOSE; |
| 2629 | +#ifdef CONFIG_X86_64 | |
| 2629 | 2630 | else { |
| 2630 | 2631 | pr_warning("APIC Verbosity level %s not recognised" |
| 2631 | 2632 | " use apic=verbose or apic=debug\n", arg); |
| 2632 | 2633 | return -EINVAL; |
| 2633 | 2634 | } |
| 2635 | +#endif | |
| 2634 | 2636 | |
| 2635 | 2637 | return 0; |
| 2636 | 2638 | } |
| @@ -151,7 +151,7 @@ static struct apic apic_flat __ro_after_init = { · 150 unmodified lines | ||
| 151 | 151 | .apic_id_valid = default_apic_id_valid, |
| 152 | 152 | .apic_id_registered = flat_apic_id_registered, |
| 153 | 153 | |
| 154 | − .irq_delivery_mode = dest_LowestPrio, | |
| 154 | + .irq_delivery_mode = dest_Fixed, | |
| 155 | 155 | .irq_dest_mode = 1, /* logical */ |
| 156 | 156 | |
| 157 | 157 | .disable_esr = 0, |
| @@ -110,7 +110,7 @@ struct apic apic_noop __ro_after_init = { · 109 unmodified lines | ||
| 110 | 110 | .apic_id_valid = default_apic_id_valid, |
| 111 | 111 | .apic_id_registered = noop_apic_id_registered, |
| 112 | 112 | |
| 113 | − .irq_delivery_mode = dest_LowestPrio, | |
| 113 | + .irq_delivery_mode = dest_Fixed, | |
| 114 | 114 | /* logical delivery broadcast to all CPUs: */ |
| 115 | 115 | .irq_dest_mode = 1, |
| 116 | 116 | |
| @@ -2988,7 +2988,7 @@ void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, · 2987 unmodified lines | ||
| 2988 | 2988 | } |
| 2989 | 2989 | |
| 2990 | 2990 | int mp_irqdomain_activate(struct irq_domain *domain, |
| 2991 | − struct irq_data *irq_data, bool early) | |
| 2991 | + struct irq_data *irq_data, bool reserve) | |
| 2992 | 2992 | { |
| 2993 | 2993 | unsigned long flags; |
| 2994 | 2994 | |
| @@ -39,17 +39,13 @@ static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) · 38 unmodified lines | ||
| 39 | 39 | ((apic->irq_dest_mode == 0) ? |
| 40 | 40 | MSI_ADDR_DEST_MODE_PHYSICAL : |
| 41 | 41 | MSI_ADDR_DEST_MODE_LOGICAL) | |
| 42 | − ((apic->irq_delivery_mode != dest_LowestPrio) ? | |
| 43 | − MSI_ADDR_REDIRECTION_CPU : | |
| 44 | − MSI_ADDR_REDIRECTION_LOWPRI) | | |
| 42 | + MSI_ADDR_REDIRECTION_CPU | | |
| 45 | 43 | MSI_ADDR_DEST_ID(cfg->dest_apicid); |
| 46 | 44 | |
| 47 | 45 | msg->data = |
| 48 | 46 | MSI_DATA_TRIGGER_EDGE | |
| 49 | 47 | MSI_DATA_LEVEL_ASSERT | |
| 50 | − ((apic->irq_delivery_mode != dest_LowestPrio) ? | |
| 51 | − MSI_DATA_DELIVERY_FIXED : | |
| 52 | − MSI_DATA_DELIVERY_LOWPRI) | | |
| 48 | + MSI_DATA_DELIVERY_FIXED | | |
| 53 | 49 | MSI_DATA_VECTOR(cfg->vector); |
| 54 | 50 | } |
| 55 | 51 | |
| @@ -105,7 +105,7 @@ static struct apic apic_default __ro_after_init = { · 104 unmodified lines | ||
| 105 | 105 | .apic_id_valid = default_apic_id_valid, |
| 106 | 106 | .apic_id_registered = default_apic_id_registered, |
| 107 | 107 | |
| 108 | − .irq_delivery_mode = dest_LowestPrio, | |
| 108 | + .irq_delivery_mode = dest_Fixed, | |
| 109 | 109 | /* logical delivery broadcast to all CPUs: */ |
| 110 | 110 | .irq_dest_mode = 1, |
| 111 | 111 | |
| @@ -184,6 +184,7 @@ static void reserve_irq_vector_locked(struct irq_data *irqd) · 183 unmodified lines | ||
| 184 | 184 | irq_matrix_reserve(vector_matrix); |
| 185 | 185 | apicd->can_reserve = true; |
| 186 | 186 | apicd->has_reserved = true; |
| 187 | + irqd_set_can_reserve(irqd); | |
| 187 | 188 | trace_vector_reserve(irqd->irq, 0); |
| 188 | 189 | vector_assign_managed_shutdown(irqd); |
| 189 | 190 | } |
| @@ -368,8 +369,18 @@ static int activate_reserved(struct irq_data *irqd) · 178 unmodified lines | ||
| 368 | 369 | int ret; |
| 369 | 370 | |
| 370 | 371 | ret = assign_irq_vector_any_locked(irqd); |
| 371 | − if (!ret) | |
| 372 | + if (!ret) { | |
| 372 | 373 | apicd->has_reserved = false; |
| 374 | + /* | |
| 375 | + * Core might have disabled reservation mode after | |
| 376 | + * allocating the irq descriptor. Ideally this should | |
| 377 | + * happen before allocation time, but that would require | |
| 378 | + * completely convoluted ways of transporting that | |
| 379 | + * information. | |
| 380 | + */ | |
| 381 | + if (!irqd_can_reserve(irqd)) | |
| 382 | + apicd->can_reserve = false; | |
| 383 | + } | |
| 373 | 384 | return ret; |
| 374 | 385 | } |
| 375 | 386 | |
| @@ -398,21 +409,21 @@ static int activate_managed(struct irq_data *irqd) · 22 unmodified lines | ||
| 398 | 409 | } |
| 399 | 410 | |
| 400 | 411 | static int x86_vector_activate(struct irq_domain *dom, struct irq_data *irqd, |
| 401 | − bool early) | |
| 412 | + bool reserve) | |
| 402 | 413 | { |
| 403 | 414 | struct apic_chip_data *apicd = apic_chip_data(irqd); |
| 404 | 415 | unsigned long flags; |
| 405 | 416 | int ret = 0; |
| 406 | 417 | |
| 407 | 418 | trace_vector_activate(irqd->irq, apicd->is_managed, |
| 408 | − apicd->can_reserve, early); | |
| 419 | + apicd->can_reserve, reserve); | |
| 409 | 420 | |
| 410 | 421 | /* Nothing to do for fixed assigned vectors */ |
| 411 | 422 | if (!apicd->can_reserve && !apicd->is_managed) |
| 412 | 423 | return 0; |
| 413 | 424 | |
| 414 | 425 | raw_spin_lock_irqsave(&vector_lock, flags); |
| 415 | − if (early || irqd_is_managed_and_shutdown(irqd)) | |
| 426 | + if (reserve || irqd_is_managed_and_shutdown(irqd)) | |
| 416 | 427 | vector_assign_managed_shutdown(irqd); |
| 417 | 428 | else if (apicd->is_managed) |
| 418 | 429 | ret = activate_managed(irqd); |
| @@ -478,6 +489,7 @@ static bool vector_configure_legacy(unsigned int virq, struct irq_data *irqd, · 59 unmodified lines | ||
| 478 | 489 | } else { |
| 479 | 490 | /* Release the vector */ |
| 480 | 491 | apicd->can_reserve = true; |
| 492 | + irqd_set_can_reserve(irqd); | |
| 481 | 493 | clear_irq_vector(irqd); |
| 482 | 494 | realloc = true; |
| 483 | 495 | } |
| @@ -184,7 +184,7 @@ static struct apic apic_x2apic_cluster __ro_after_init = { · 183 unmodified lines | ||
| 184 | 184 | .apic_id_valid = x2apic_apic_id_valid, |
| 185 | 185 | .apic_id_registered = x2apic_apic_id_registered, |
| 186 | 186 | |
| 187 | − .irq_delivery_mode = dest_LowestPrio, | |
| 187 | + .irq_delivery_mode = dest_Fixed, | |
| 188 | 188 | .irq_dest_mode = 1, /* logical */ |
| 189 | 189 | |
| 190 | 190 | .disable_esr = 0, |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <asm/sigframe.h> |
| 18 | 18 | #include <asm/bootparam.h> |
| 19 | 19 | #include <asm/suspend.h> |
| 20 | +#include <asm/tlbflush.h> | |
| 20 | 21 | |
| 21 | 22 | #ifdef CONFIG_XEN |
| 22 | 23 | #include <xen/interface/xen.h> |
| @@ -93,4 +94,13 @@ void common(void) { · 70 unmodified lines | ||
| 93 | 94 | |
| 94 | 95 | BLANK(); |
| 95 | 96 | DEFINE(PTREGS_SIZE, sizeof(struct pt_regs)); |
| 97 | + | |
| 98 | + /* TLB state for the entry code */ | |
| 99 | + OFFSET(TLB_STATE_user_pcid_flush_mask, tlb_state, user_pcid_flush_mask); | |
| 100 | + | |
| 101 | + /* Layout info for cpu_entry_area */ | |
| 102 | + OFFSET(CPU_ENTRY_AREA_tss, cpu_entry_area, tss); | |
| 103 | + OFFSET(CPU_ENTRY_AREA_entry_trampoline, cpu_entry_area, entry_trampoline); | |
| 104 | + OFFSET(CPU_ENTRY_AREA_entry_stack, cpu_entry_area, entry_stack_page); | |
| 105 | + DEFINE(SIZEOF_entry_stack, sizeof(struct entry_stack)); | |
| 96 | 106 | } |
| @@ -47,13 +47,8 @@ void foo(void) · 46 unmodified lines | ||
| 47 | 47 | BLANK(); |
| 48 | 48 | |
| 49 | 49 | /* Offset from the sysenter stack to tss.sp0 */ |
| 50 | − DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) - | |
| 51 | − offsetofend(struct tss_struct, SYSENTER_stack)); | |
| 52 | − | |
| 53 | − /* Offset from cpu_tss to SYSENTER_stack */ | |
| 54 | − OFFSET(CPU_TSS_SYSENTER_stack, tss_struct, SYSENTER_stack); | |
| 55 | − /* Size of SYSENTER_stack */ | |
| 56 | − DEFINE(SIZEOF_SYSENTER_stack, sizeof(((struct tss_struct *)0)->SYSENTER_stack)); | |
| 50 | + DEFINE(TSS_sysenter_sp0, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) - | |
| 51 | + offsetofend(struct cpu_entry_area, entry_stack_page.stack)); | |
| 57 | 52 | |
| 58 | 53 | #ifdef CONFIG_CC_STACKPROTECTOR |
| 59 | 54 | BLANK(); |
| @@ -23,6 +23,9 @@ int main(void) · 22 unmodified lines | ||
| 23 | 23 | #ifdef CONFIG_PARAVIRT |
| 24 | 24 | OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); |
| 25 | 25 | OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); |
| 26 | +#ifdef CONFIG_DEBUG_ENTRY | |
| 27 | + OFFSET(PV_IRQ_save_fl, pv_irq_ops, save_fl); | |
| 28 | +#endif | |
| 26 | 29 | BLANK(); |
| 27 | 30 | #endif |
| 28 | 31 | |
| @@ -63,6 +66,7 @@ int main(void) · 34 unmodified lines | ||
| 63 | 66 | |
| 64 | 67 | OFFSET(TSS_ist, tss_struct, x86_tss.ist); |
| 65 | 68 | OFFSET(TSS_sp0, tss_struct, x86_tss.sp0); |
| 69 | + OFFSET(TSS_sp1, tss_struct, x86_tss.sp1); | |
| 66 | 70 | BLANK(); |
| 67 | 71 | |
| 68 | 72 | #ifdef CONFIG_CC_STACKPROTECTOR |
| @@ -476,8 +476,8 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c) · 475 unmodified lines | ||
| 476 | 476 | return NULL; /* Not found */ |
| 477 | 477 | } |
| 478 | 478 | |
| 479 | −__u32 cpu_caps_cleared[NCAPINTS]; | |
| 480 | −__u32 cpu_caps_set[NCAPINTS]; | |
| 479 | +__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS]; | |
| 480 | +__u32 cpu_caps_set[NCAPINTS + NBUGINTS]; | |
| 481 | 481 | |
| 482 | 482 | void load_percpu_segment(int cpu) |
| 483 | 483 | { |
| @@ -490,28 +490,23 @@ void load_percpu_segment(int cpu) · 6 unmodified lines | ||
| 490 | 490 | load_stack_canary_segment(); |
| 491 | 491 | } |
| 492 | 492 | |
| 493 | −/* Setup the fixmap mapping only once per-processor */ | |
| 494 | −static inline void setup_fixmap_gdt(int cpu) | |
| 495 | −{ | |
| 496 | −#ifdef CONFIG_X86_64 | |
| 497 | − /* On 64-bit systems, we use a read-only fixmap GDT. */ | |
| 498 | − pgprot_t prot = PAGE_KERNEL_RO; | |
| 499 | −#else | |
| 500 | − /* | |
| 501 | − * On native 32-bit systems, the GDT cannot be read-only because | |
| 502 | − * our double fault handler uses a task gate, and entering through | |
| 503 | − * a task gate needs to change an available TSS to busy. If the GDT | |
| 504 | − * is read-only, that will triple fault. | |
| 505 | − * | |
| 506 | − * On Xen PV, the GDT must be read-only because the hypervisor requires | |
| 507 | − * it. | |
| 508 | − */ | |
| 509 | − pgprot_t prot = boot_cpu_has(X86_FEATURE_XENPV) ? | |
| 510 | − PAGE_KERNEL_RO : PAGE_KERNEL; | |
| 493 | +#ifdef CONFIG_X86_32 | |
| 494 | +/* The 32-bit entry code needs to find cpu_entry_area. */ | |
| 495 | +DEFINE_PER_CPU(struct cpu_entry_area *, cpu_entry_area); | |
| 511 | 496 | #endif |
| 512 | 497 | |
| 513 | − __set_fixmap(get_cpu_gdt_ro_index(cpu), get_cpu_gdt_paddr(cpu), prot); | |
| 514 | −} | |
| 498 | +#ifdef CONFIG_X86_64 | |
| 499 | +/* | |
| 500 | + * Special IST stacks which the CPU switches to when it calls | |
| 501 | + * an IST-marked descriptor entry. Up to 7 stacks (hardware | |
| 502 | + * limit), all of them are 4K, except the debug stack which | |
| 503 | + * is 8K. | |
| 504 | + */ | |
| 505 | +static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { | |
| 506 | + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, | |
| 507 | + [DEBUG_STACK - 1] = DEBUG_STKSZ | |
| 508 | +}; | |
| 509 | +#endif | |
| 515 | 510 | |
| 516 | 511 | /* Load the original GDT from the per-cpu structure */ |
| 517 | 512 | void load_direct_gdt(int cpu) |
| @@ -747,7 +742,7 @@ static void apply_forced_caps(struct cpuinfo_x86 *c) · 229 unmodified lines | ||
| 747 | 742 | { |
| 748 | 743 | int i; |
| 749 | 744 | |
| 750 | − for (i = 0; i < NCAPINTS; i++) { | |
| 745 | + for (i = 0; i < NCAPINTS + NBUGINTS; i++) { | |
| 751 | 746 | c->x86_capability[i] &= ~cpu_caps_cleared[i]; |
| 752 | 747 | c->x86_capability[i] |= cpu_caps_set[i]; |
| 753 | 748 | } |
| @@ -927,6 +922,10 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) · 173 unmodified lines | ||
| 927 | 922 | } |
| 928 | 923 | |
| 929 | 924 | setup_force_cpu_cap(X86_FEATURE_ALWAYS); |
| 925 | + | |
| 926 | + /* Assume for now that ALL x86 CPUs are insecure */ | |
| 927 | + setup_force_cpu_bug(X86_BUG_CPU_INSECURE); | |
| 928 | + | |
| 930 | 929 | fpu__init_system(c); |
| 931 | 930 | |
| 932 | 931 | #ifdef CONFIG_X86_32 |
| @@ -1250,7 +1249,7 @@ void enable_sep_cpu(void) · 317 unmodified lines | ||
| 1250 | 1249 | return; |
| 1251 | 1250 | |
| 1252 | 1251 | cpu = get_cpu(); |
| 1253 | − tss = &per_cpu(cpu_tss, cpu); | |
| 1252 | + tss = &per_cpu(cpu_tss_rw, cpu); | |
| 1254 | 1253 | |
| 1255 | 1254 | /* |
| 1256 | 1255 | * We cache MSR_IA32_SYSENTER_CS's value in the TSS's ss1 field -- |
| @@ -1259,11 +1258,7 @@ void enable_sep_cpu(void) · 2 unmodified lines | ||
| 1259 | 1258 | |
| 1260 | 1259 | tss->x86_tss.ss1 = __KERNEL_CS; |
| 1261 | 1260 | wrmsr(MSR_IA32_SYSENTER_CS, tss->x86_tss.ss1, 0); |
| 1262 | − | |
| 1263 | − wrmsr(MSR_IA32_SYSENTER_ESP, | |
| 1264 | − (unsigned long)tss + offsetofend(struct tss_struct, SYSENTER_stack), | |
| 1265 | − 0); | |
| 1266 | − | |
| 1261 | + wrmsr(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1), 0); | |
| 1267 | 1262 | wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)entry_SYSENTER_32, 0); |
| 1268 | 1263 | |
| 1269 | 1264 | put_cpu(); |
| @@ -1357,25 +1352,22 @@ DEFINE_PER_CPU(unsigned int, irq_count) __visible = -1; · 87 unmodified lines | ||
| 1357 | 1352 | DEFINE_PER_CPU(int, __preempt_count) = INIT_PREEMPT_COUNT; |
| 1358 | 1353 | EXPORT_PER_CPU_SYMBOL(__preempt_count); |
| 1359 | 1354 | |
| 1360 | −/* | |
| 1361 | − * Special IST stacks which the CPU switches to when it calls | |
| 1362 | − * an IST-marked descriptor entry. Up to 7 stacks (hardware | |
| 1363 | − * limit), all of them are 4K, except the debug stack which | |
| 1364 | − * is 8K. | |
| 1365 | − */ | |
| 1366 | −static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { | |
| 1367 | − [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, | |
| 1368 | − [DEBUG_STACK - 1] = DEBUG_STKSZ | |
| 1369 | −}; | |
| 1370 | − | |
| 1371 | −static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | |
| 1372 | − [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); | |
| 1373 | − | |
| 1374 | 1355 | /* May not be marked __init: used by software suspend */ |
| 1375 | 1356 | void syscall_init(void) |
| 1376 | 1357 | { |
| 1358 | + extern char _entry_trampoline[]; | |
| 1359 | + extern char entry_SYSCALL_64_trampoline[]; | |
| 1360 | + | |
| 1361 | + int cpu = smp_processor_id(); | |
| 1362 | + unsigned long SYSCALL64_entry_trampoline = | |
| 1363 | + (unsigned long)get_cpu_entry_area(cpu)->entry_trampoline + | |
| 1364 | + (entry_SYSCALL_64_trampoline - _entry_trampoline); | |
| 1365 | + | |
| 1377 | 1366 | wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS); |
| 1378 | − wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64); | |
| 1367 | + if (static_cpu_has(X86_FEATURE_PTI)) | |
| 1368 | + wrmsrl(MSR_LSTAR, SYSCALL64_entry_trampoline); | |
| 1369 | + else | |
| 1370 | + wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64); | |
| 1379 | 1371 | |
| 1380 | 1372 | #ifdef CONFIG_IA32_EMULATION |
| 1381 | 1373 | wrmsrl(MSR_CSTAR, (unsigned long)entry_SYSCALL_compat); |
| @@ -1386,7 +1378,7 @@ void syscall_init(void) · 4 unmodified lines | ||
| 1386 | 1378 | * AMD doesn't allow SYSENTER in long mode (either 32- or 64-bit). |
| 1387 | 1379 | */ |
| 1388 | 1380 | wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); |
| 1389 | − wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); | |
| 1381 | + wrmsrl_safe(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1)); | |
| 1390 | 1382 | wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat); |
| 1391 | 1383 | #else |
| 1392 | 1384 | wrmsrl(MSR_CSTAR, (unsigned long)ignore_sysret); |
| @@ -1530,7 +1522,7 @@ void cpu_init(void) · 137 unmodified lines | ||
| 1530 | 1522 | if (cpu) |
| 1531 | 1523 | load_ucode_ap(); |
| 1532 | 1524 | |
| 1533 | − t = &per_cpu(cpu_tss, cpu); | |
| 1525 | + t = &per_cpu(cpu_tss_rw, cpu); | |
| 1534 | 1526 | oist = &per_cpu(orig_ist, cpu); |
| 1535 | 1527 | |
| 1536 | 1528 | #ifdef CONFIG_NUMA |
| @@ -1569,7 +1561,7 @@ void cpu_init(void) · 32 unmodified lines | ||
| 1569 | 1561 | * set up and load the per-CPU TSS |
| 1570 | 1562 | */ |
| 1571 | 1563 | if (!oist->ist[0]) { |
| 1572 | − char *estacks = per_cpu(exception_stacks, cpu); | |
| 1564 | + char *estacks = get_cpu_entry_area(cpu)->exception_stacks; | |
| 1573 | 1565 | |
| 1574 | 1566 | for (v = 0; v < N_EXCEPTION_STACKS; v++) { |
| 1575 | 1567 | estacks += exception_stack_sizes[v]; |
| @@ -1580,7 +1572,7 @@ void cpu_init(void) · 4 unmodified lines | ||
| 1580 | 1572 | } |
| 1581 | 1573 | } |
| 1582 | 1574 | |
| 1583 | − t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); | |
| 1575 | + t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; | |
| 1584 | 1576 | |
| 1585 | 1577 | /* |
| 1586 | 1578 | * <= is required because the CPU will access up to |
| @@ -1596,11 +1588,12 @@ void cpu_init(void) · 9 unmodified lines | ||
| 1596 | 1588 | enter_lazy_tlb(&init_mm, me); |
| 1597 | 1589 | |
| 1598 | 1590 | /* |
| 1599 | − * Initialize the TSS. Don't bother initializing sp0, as the initial | |
| 1600 | − * task never enters user mode. | |
| 1591 | + * Initialize the TSS. sp0 points to the entry trampoline stack | |
| 1592 | + * regardless of what task is running. | |
| 1601 | 1593 | */ |
| 1602 | − set_tss_desc(cpu, t); | |
| 1594 | + set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); | |
| 1603 | 1595 | load_TR_desc(); |
| 1596 | + load_sp0((unsigned long)(cpu_entry_stack(cpu) + 1)); | |
| 1604 | 1597 | |
| 1605 | 1598 | load_mm_ldt(&init_mm); |
| 1606 | 1599 | |
| @@ -1612,7 +1605,6 @@ void cpu_init(void) · 5 unmodified lines | ||
| 1612 | 1605 | if (is_uv_system()) |
| 1613 | 1606 | uv_cpu_init(); |
| 1614 | 1607 | |
| 1615 | − setup_fixmap_gdt(cpu); | |
| 1616 | 1608 | load_fixmap_gdt(cpu); |
| 1617 | 1609 | } |
| 1618 | 1610 | |
| @@ -1622,7 +1614,7 @@ void cpu_init(void) · 3 unmodified lines | ||
| 1622 | 1614 | { |
| 1623 | 1615 | int cpu = smp_processor_id(); |
| 1624 | 1616 | struct task_struct *curr = current; |
| 1625 | − struct tss_struct *t = &per_cpu(cpu_tss, cpu); | |
| 1617 | + struct tss_struct *t = &per_cpu(cpu_tss_rw, cpu); | |
| 1626 | 1618 | |
| 1627 | 1619 | wait_for_master_cpu(cpu); |
| 1628 | 1620 | |
| @@ -1657,12 +1649,12 @@ void cpu_init(void) · 28 unmodified lines | ||
| 1657 | 1649 | * Initialize the TSS. Don't bother initializing sp0, as the initial |
| 1658 | 1650 | * task never enters user mode. |
| 1659 | 1651 | */ |
| 1660 | − set_tss_desc(cpu, t); | |
| 1652 | + set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); | |
| 1661 | 1653 | load_TR_desc(); |
| 1662 | 1654 | |
| 1663 | 1655 | load_mm_ldt(&init_mm); |
| 1664 | 1656 | |
| 1665 | − t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); | |
| 1657 | + t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; | |
| 1666 | 1658 | |
| 1667 | 1659 | #ifdef CONFIG_DOUBLEFAULT |
| 1668 | 1660 | /* Set up doublefault TSS pointer in the GDT */ |
| @@ -1674,7 +1666,6 @@ void cpu_init(void) · 5 unmodified lines | ||
| 1674 | 1666 | |
| 1675 | 1667 | fpu__init_cpu(); |
| 1676 | 1668 | |
| 1677 | − setup_fixmap_gdt(cpu); | |
| 1678 | 1669 | load_fixmap_gdt(cpu); |
| 1679 | 1670 | } |
| 1680 | 1671 | #endif |
| @@ -565,15 +565,6 @@ static void print_ucode(struct ucode_cpu_info *uci) · 564 unmodified lines | ||
| 565 | 565 | } |
| 566 | 566 | #else |
| 567 | 567 | |
| 568 | −/* | |
| 569 | − * Flush global tlb. We only do this in x86_64 where paging has been enabled | |
| 570 | − * already and PGE should be enabled as well. | |
| 571 | − */ | |
| 572 | −static inline void flush_tlb_early(void) | |
| 573 | −{ | |
| 574 | − __native_flush_tlb_global_irq_disabled(); | |
| 575 | −} | |
| 576 | − | |
| 577 | 568 | static inline void print_ucode(struct ucode_cpu_info *uci) |
| 578 | 569 | { |
| 579 | 570 | struct microcode_intel *mc; |
| @@ -602,10 +593,6 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) · 22 unmodified lines | ||
| 602 | 593 | if (rev != mc->hdr.rev) |
| 603 | 594 | return -1; |
| 604 | 595 | |
| 605 | −#ifdef CONFIG_X86_64 | |
| 606 | − /* Flush global tlb. This is precaution. */ | |
| 607 | − flush_tlb_early(); | |
| 608 | −#endif | |
| 609 | 596 | uci->cpu_sig.rev = rev; |
| 610 | 597 | |
| 611 | 598 | if (early) |
| @@ -50,25 +50,23 @@ static void doublefault_fn(void) · 49 unmodified lines | ||
| 50 | 50 | cpu_relax(); |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | −struct tss_struct doublefault_tss __cacheline_aligned = { | |
| 54 | − .x86_tss = { | |
| 55 | − .sp0 = STACK_START, | |
| 56 | − .ss0 = __KERNEL_DS, | |
| 57 | − .ldt = 0, | |
| 58 | − .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, | |
| 59 | − | |
| 60 | − .ip = (unsigned long) doublefault_fn, | |
| 61 | − /* 0x2 bit is always set */ | |
| 62 | − .flags = X86_EFLAGS_SF | 0x2, | |
| 63 | − .sp = STACK_START, | |
| 64 | − .es = __USER_DS, | |
| 65 | − .cs = __KERNEL_CS, | |
| 66 | − .ss = __KERNEL_DS, | |
| 67 | − .ds = __USER_DS, | |
| 68 | − .fs = __KERNEL_PERCPU, | |
| 69 | − | |
| 70 | − .__cr3 = __pa_nodebug(swapper_pg_dir), | |
| 71 | − } | |
| 53 | +struct x86_hw_tss doublefault_tss __cacheline_aligned = { | |
| 54 | + .sp0 = STACK_START, | |
| 55 | + .ss0 = __KERNEL_DS, | |
| 56 | + .ldt = 0, | |
| 57 | + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, | |
| 58 | + | |
| 59 | + .ip = (unsigned long) doublefault_fn, | |
| 60 | + /* 0x2 bit is always set */ | |
| 61 | + .flags = X86_EFLAGS_SF | 0x2, | |
| 62 | + .sp = STACK_START, | |
| 63 | + .es = __USER_DS, | |
| 64 | + .cs = __KERNEL_CS, | |
| 65 | + .ss = __KERNEL_DS, | |
| 66 | + .ds = __USER_DS, | |
| 67 | + .fs = __KERNEL_PERCPU, | |
| 68 | + | |
| 69 | + .__cr3 = __pa_nodebug(swapper_pg_dir), | |
| 72 | 70 | }; |
| 73 | 71 | |
| 74 | 72 | /* dummy for do_double_fault() call */ |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/nmi.h> |
| 19 | 19 | #include <linux/sysfs.h> |
| 20 | 20 | |
| 21 | +#include <asm/cpu_entry_area.h> | |
| 21 | 22 | #include <asm/stacktrace.h> |
| 22 | 23 | #include <asm/unwind.h> |
| 23 | 24 | |
| @@ -43,6 +44,24 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task, · 19 unmodified lines | ||
| 43 | 44 | return true; |
| 44 | 45 | } |
| 45 | 46 | |
| 47 | +bool in_entry_stack(unsigned long *stack, struct stack_info *info) | |
| 48 | +{ | |
| 49 | + struct entry_stack *ss = cpu_entry_stack(smp_processor_id()); | |
| 50 | + | |
| 51 | + void *begin = ss; | |
| 52 | + void *end = ss + 1; | |
| 53 | + | |
| 54 | + if ((void *)stack < begin || (void *)stack >= end) | |
| 55 | + return false; | |
| 56 | + | |
| 57 | + info->type = STACK_TYPE_ENTRY; | |
| 58 | + info->begin = begin; | |
| 59 | + info->end = end; | |
| 60 | + info->next_sp = NULL; | |
| 61 | + | |
| 62 | + return true; | |
| 63 | +} | |
| 64 | + | |
| 46 | 65 | static void printk_stack_address(unsigned long address, int reliable, |
| 47 | 66 | char *log_lvl) |
| 48 | 67 | { |
| @@ -50,6 +69,28 @@ static void printk_stack_address(unsigned long address, int reliable, · 1 unmodified line | ||
| 50 | 69 | printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); |
| 51 | 70 | } |
| 52 | 71 | |
| 72 | +void show_iret_regs(struct pt_regs *regs) | |
| 73 | +{ | |
| 74 | + printk(KERN_DEFAULT "RIP: %04x:%pS\n", (int)regs->cs, (void *)regs->ip); | |
| 75 | + printk(KERN_DEFAULT "RSP: %04x:%016lx EFLAGS: %08lx", (int)regs->ss, | |
| 76 | + regs->sp, regs->flags); | |
| 77 | +} | |
| 78 | + | |
| 79 | +static void show_regs_safe(struct stack_info *info, struct pt_regs *regs) | |
| 80 | +{ | |
| 81 | + if (on_stack(info, regs, sizeof(*regs))) | |
| 82 | + __show_regs(regs, 0); | |
| 83 | + else if (on_stack(info, (void *)regs + IRET_FRAME_OFFSET, | |
| 84 | + IRET_FRAME_SIZE)) { | |
| 85 | + /* | |
| 86 | + * When an interrupt or exception occurs in entry code, the | |
| 87 | + * full pt_regs might not have been saved yet. In that case | |
| 88 | + * just print the iret frame. | |
| 89 | + */ | |
| 90 | + show_iret_regs(regs); | |
| 91 | + } | |
| 92 | +} | |
| 93 | + | |
| 53 | 94 | void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
| 54 | 95 | unsigned long *stack, char *log_lvl) |
| 55 | 96 | { |
| @@ -71,31 +112,35 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, · 15 unmodified lines | ||
| 71 | 112 | * - task stack |
| 72 | 113 | * - interrupt stack |
| 73 | 114 | * - HW exception stacks (double fault, nmi, debug, mce) |
| 115 | + * - entry stack | |
| 74 | 116 | * |
| 75 | − * x86-32 can have up to three stacks: | |
| 117 | + * x86-32 can have up to four stacks: | |
| 76 | 118 | * - task stack |
| 77 | 119 | * - softirq stack |
| 78 | 120 | * - hardirq stack |
| 121 | + * - entry stack | |
| 79 | 122 | */ |
| 80 | 123 | for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { |
| 81 | 124 | const char *stack_name; |
| 82 | 125 | |
| 83 | − /* | |
| 84 | − * If we overflowed the task stack into a guard page, jump back | |
| 85 | − * to the bottom of the usable stack. | |
| 86 | − */ | |
| 87 | − if (task_stack_page(task) - (void *)stack < PAGE_SIZE) | |
| 88 | − stack = task_stack_page(task); | |
| 89 | − | |
| 90 | − if (get_stack_info(stack, task, &stack_info, &visit_mask)) | |
| 91 | − break; | |
| 126 | + if (get_stack_info(stack, task, &stack_info, &visit_mask)) { | |
| 127 | + /* | |
| 128 | + * We weren't on a valid stack. It's possible that | |
| 129 | + * we overflowed a valid stack into a guard page. | |
| 130 | + * See if the next page up is valid so that we can | |
| 131 | + * generate some kind of backtrace if this happens. | |
| 132 | + */ | |
| 133 | + stack = (unsigned long *)PAGE_ALIGN((unsigned long)stack); | |
| 134 | + if (get_stack_info(stack, task, &stack_info, &visit_mask)) | |
| 135 | + break; | |
| 136 | + } | |
| 92 | 137 | |
| 93 | 138 | stack_name = stack_type_name(stack_info.type); |
| 94 | 139 | if (stack_name) |
| 95 | 140 | printk("%s <%s>\n", log_lvl, stack_name); |
| 96 | 141 | |
| 97 | − if (regs && on_stack(&stack_info, regs, sizeof(*regs))) | |
| 98 | − __show_regs(regs, 0); | |
| 142 | + if (regs) | |
| 143 | + show_regs_safe(&stack_info, regs); | |
| 99 | 144 | |
| 100 | 145 | /* |
| 101 | 146 | * Scan the stack, printing any text addresses we find. At the |
| @@ -119,7 +164,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, · 17 unmodified lines | ||
| 119 | 164 | |
| 120 | 165 | /* |
| 121 | 166 | * Don't print regs->ip again if it was already printed |
| 122 | − * by __show_regs() below. | |
| 167 | + * by show_regs_safe() below. | |
| 123 | 168 | */ |
| 124 | 169 | if (regs && stack == ®s->ip) |
| 125 | 170 | goto next; |
| @@ -155,8 +200,8 @@ next: · 29 unmodified lines | ||
| 155 | 200 | |
| 156 | 201 | /* if the frame has entry regs, print them */ |
| 157 | 202 | regs = unwind_get_entry_regs(&state); |
| 158 | − if (regs && on_stack(&stack_info, regs, sizeof(*regs))) | |
| 159 | − __show_regs(regs, 0); | |
| 203 | + if (regs) | |
| 204 | + show_regs_safe(&stack_info, regs); | |
| 160 | 205 | } |
| 161 | 206 | |
| 162 | 207 | if (stack_name) |
| @@ -252,11 +297,13 @@ int __die(const char *str, struct pt_regs *regs, long err) · 89 unmodified lines | ||
| 252 | 297 | unsigned long sp; |
| 253 | 298 | #endif |
| 254 | 299 | printk(KERN_DEFAULT |
| 255 | − "%s: %04lx [#%d]%s%s%s%s\n", str, err & 0xffff, ++die_counter, | |
| 300 | + "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter, | |
| 256 | 301 | IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", |
| 257 | 302 | IS_ENABLED(CONFIG_SMP) ? " SMP" : "", |
| 258 | 303 | debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "", |
| 259 | − IS_ENABLED(CONFIG_KASAN) ? " KASAN" : ""); | |
| 304 | + IS_ENABLED(CONFIG_KASAN) ? " KASAN" : "", | |
| 305 | + IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ? | |
| 306 | + (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : ""); | |
| 260 | 307 | |
| 261 | 308 | if (notify_die(DIE_OOPS, str, regs, err, |
| 262 | 309 | current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) |
| @@ -26,6 +26,9 @@ const char *stack_type_name(enum stack_type type) · 25 unmodified lines | ||
| 26 | 26 | if (type == STACK_TYPE_SOFTIRQ) |
| 27 | 27 | return "SOFTIRQ"; |
| 28 | 28 | |
| 29 | + if (type == STACK_TYPE_ENTRY) | |
| 30 | + return "ENTRY_TRAMPOLINE"; | |
| 31 | + | |
| 29 | 32 | return NULL; |
| 30 | 33 | } |
| 31 | 34 | |
| @@ -93,6 +96,9 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, · 61 unmodified lines | ||
| 93 | 96 | if (task != current) |
| 94 | 97 | goto unknown; |
| 95 | 98 | |
| 99 | + if (in_entry_stack(stack, info)) | |
| 100 | + goto recursion_check; | |
| 101 | + | |
| 96 | 102 | if (in_hardirq_stack(stack, info)) |
| 97 | 103 | goto recursion_check; |
| 98 | 104 | |
| @@ -37,6 +37,15 @@ const char *stack_type_name(enum stack_type type) · 36 unmodified lines | ||
| 37 | 37 | if (type == STACK_TYPE_IRQ) |
| 38 | 38 | return "IRQ"; |
| 39 | 39 | |
| 40 | + if (type == STACK_TYPE_ENTRY) { | |
| 41 | + /* | |
| 42 | + * On 64-bit, we have a generic entry stack that we | |
| 43 | + * use for all the kernel entry points, including | |
| 44 | + * SYSENTER. | |
| 45 | + */ | |
| 46 | + return "ENTRY_TRAMPOLINE"; | |
| 47 | + } | |
| 48 | + | |
| 40 | 49 | if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) |
| 41 | 50 | return exception_stack_names[type - STACK_TYPE_EXCEPTION]; |
| 42 | 51 | |
| @@ -115,6 +124,9 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, · 72 unmodified lines | ||
| 115 | 124 | if (in_irq_stack(stack, info)) |
| 116 | 125 | goto recursion_check; |
| 117 | 126 | |
| 127 | + if (in_entry_stack(stack, info)) | |
| 128 | + goto recursion_check; | |
| 129 | + | |
| 118 | 130 | goto unknown; |
| 119 | 131 | |
| 120 | 132 | recursion_check: |
| @@ -341,6 +341,27 @@ GLOBAL(early_recursion_flag) · 340 unmodified lines | ||
| 341 | 341 | .balign PAGE_SIZE; \ |
| 342 | 342 | GLOBAL(name) |
| 343 | 343 | |
| 344 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 345 | +/* | |
| 346 | + * Each PGD needs to be 8k long and 8k aligned. We do not | |
| 347 | + * ever go out to userspace with these, so we do not | |
| 348 | + * strictly *need* the second page, but this allows us to | |
| 349 | + * have a single set_pgd() implementation that does not | |
| 350 | + * need to worry about whether it has 4k or 8k to work | |
| 351 | + * with. | |
| 352 | + * | |
| 353 | + * This ensures PGDs are 8k long: | |
| 354 | + */ | |
| 355 | +#define PTI_USER_PGD_FILL 512 | |
| 356 | +/* This ensures they are 8k-aligned: */ | |
| 357 | +#define NEXT_PGD_PAGE(name) \ | |
| 358 | + .balign 2 * PAGE_SIZE; \ | |
| 359 | +GLOBAL(name) | |
| 360 | +#else | |
| 361 | +#define NEXT_PGD_PAGE(name) NEXT_PAGE(name) | |
| 362 | +#define PTI_USER_PGD_FILL 0 | |
| 363 | +#endif | |
| 364 | + | |
| 344 | 365 | /* Automate the creation of 1 to 1 mapping pmd entries */ |
| 345 | 366 | #define PMDS(START, PERM, COUNT) \ |
| 346 | 367 | i = 0 ; \ |
| @@ -350,13 +371,14 @@ GLOBAL(name) · 3 unmodified lines | ||
| 350 | 371 | .endr |
| 351 | 372 | |
| 352 | 373 | __INITDATA |
| 353 | −NEXT_PAGE(early_top_pgt) | |
| 374 | +NEXT_PGD_PAGE(early_top_pgt) | |
| 354 | 375 | .fill 511,8,0 |
| 355 | 376 | #ifdef CONFIG_X86_5LEVEL |
| 356 | 377 | .quad level4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC |
| 357 | 378 | #else |
| 358 | 379 | .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC |
| 359 | 380 | #endif |
| 381 | + .fill PTI_USER_PGD_FILL,8,0 | |
| 360 | 382 | |
| 361 | 383 | NEXT_PAGE(early_dynamic_pgts) |
| 362 | 384 | .fill 512*EARLY_DYNAMIC_PAGE_TABLES,8,0 |
| @@ -364,13 +386,14 @@ NEXT_PAGE(early_dynamic_pgts) · 1 unmodified line | ||
| 364 | 386 | .data |
| 365 | 387 | |
| 366 | 388 | #if defined(CONFIG_XEN_PV) || defined(CONFIG_XEN_PVH) |
| 367 | −NEXT_PAGE(init_top_pgt) | |
| 389 | +NEXT_PGD_PAGE(init_top_pgt) | |
| 368 | 390 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC |
| 369 | 391 | .org init_top_pgt + PGD_PAGE_OFFSET*8, 0 |
| 370 | 392 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC |
| 371 | 393 | .org init_top_pgt + PGD_START_KERNEL*8, 0 |
| 372 | 394 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
| 373 | 395 | .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC |
| 396 | + .fill PTI_USER_PGD_FILL,8,0 | |
| 374 | 397 | |
| 375 | 398 | NEXT_PAGE(level3_ident_pgt) |
| 376 | 399 | .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC |
| @@ -381,8 +404,9 @@ NEXT_PAGE(level2_ident_pgt) · 4 unmodified lines | ||
| 381 | 404 | */ |
| 382 | 405 | PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD) |
| 383 | 406 | #else |
| 384 | −NEXT_PAGE(init_top_pgt) | |
| 407 | +NEXT_PGD_PAGE(init_top_pgt) | |
| 385 | 408 | .fill 512,8,0 |
| 409 | + .fill PTI_USER_PGD_FILL,8,0 | |
| 386 | 410 | #endif |
| 387 | 411 | |
| 388 | 412 | #ifdef CONFIG_X86_5LEVEL |
| @@ -67,7 +67,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) · 66 unmodified lines | ||
| 67 | 67 | * because the ->io_bitmap_max value must match the bitmap |
| 68 | 68 | * contents: |
| 69 | 69 | */ |
| 70 | − tss = &per_cpu(cpu_tss, get_cpu()); | |
| 70 | + tss = &per_cpu(cpu_tss_rw, get_cpu()); | |
| 71 | 71 | |
| 72 | 72 | if (turn_on) |
| 73 | 73 | bitmap_clear(t->io_bitmap_ptr, from, num); |
| @@ -219,18 +219,6 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) · 218 unmodified lines | ||
| 219 | 219 | /* high bit used in ret_from_ code */ |
| 220 | 220 | unsigned vector = ~regs->orig_ax; |
| 221 | 221 | |
| 222 | − /* | |
| 223 | − * NB: Unlike exception entries, IRQ entries do not reliably | |
| 224 | − * handle context tracking in the low-level entry code. This is | |
| 225 | − * because syscall entries execute briefly with IRQs on before | |
| 226 | − * updating context tracking state, so we can take an IRQ from | |
| 227 | − * kernel mode with CONTEXT_USER. The low-level entry code only | |
| 228 | − * updates the context if we came from user mode, so we won't | |
| 229 | − * switch to CONTEXT_KERNEL. We'll fix that once the syscall | |
| 230 | − * code is cleaned up enough that we can cleanly defer enabling | |
| 231 | − * IRQs. | |
| 232 | − */ | |
| 233 | − | |
| 234 | 222 | entering_irq(); |
| 235 | 223 | |
| 236 | 224 | /* entering_irq() tells RCU that we're not quiescent. Check it. */ |
| @@ -57,10 +57,10 @@ static inline void stack_overflow_check(struct pt_regs *regs) · 56 unmodified lines | ||
| 57 | 57 | if (regs->sp >= estack_top && regs->sp <= estack_bottom) |
| 58 | 58 | return; |
| 59 | 59 | |
| 60 | − WARN_ONCE(1, "do_IRQ(): %s has overflown the kernel stack (cur:%Lx,sp:%lx,irq stk top-bottom:%Lx-%Lx,exception stk top-bottom:%Lx-%Lx)\n", | |
| 60 | + WARN_ONCE(1, "do_IRQ(): %s has overflown the kernel stack (cur:%Lx,sp:%lx,irq stk top-bottom:%Lx-%Lx,exception stk top-bottom:%Lx-%Lx,ip:%pF)\n", | |
| 61 | 61 | current->comm, curbase, regs->sp, |
| 62 | 62 | irq_stack_top, irq_stack_bottom, |
| 63 | − estack_top, estack_bottom); | |
| 63 | + estack_top, estack_bottom, (void *)regs->ip); | |
| 64 | 64 | |
| 65 | 65 | if (sysctl_panic_on_stackoverflow) |
| 66 | 66 | panic("low stack detected by irq handler - check messages\n"); |
| @@ -5,6 +5,11 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright (C) 2002 Andi Kleen |
| 6 | 6 | * |
| 7 | 7 | * This handles calls from both 32bit and 64bit mode. |
| 8 | + * | |
| 9 | + * Lock order: | |
| 10 | + * contex.ldt_usr_sem | |
| 11 | + * mmap_sem | |
| 12 | + * context.lock | |
| 8 | 13 | */ |
| 9 | 14 | |
| 10 | 15 | #include <linux/errno.h> |
| @@ -19,6 +24,7 @@ · 8 unmodified lines | ||
| 19 | 24 | #include <linux/uaccess.h> |
| 20 | 25 | |
| 21 | 26 | #include <asm/ldt.h> |
| 27 | +#include <asm/tlb.h> | |
| 22 | 28 | #include <asm/desc.h> |
| 23 | 29 | #include <asm/mmu_context.h> |
| 24 | 30 | #include <asm/syscalls.h> |
| @@ -42,17 +48,15 @@ static void refresh_ldt_segments(void) · 17 unmodified lines | ||
| 42 | 48 | #endif |
| 43 | 49 | } |
| 44 | 50 | |
| 45 | −/* context.lock is held for us, so we don't need any locking. */ | |
| 51 | +/* context.lock is held by the task which issued the smp function call */ | |
| 46 | 52 | static void flush_ldt(void *__mm) |
| 47 | 53 | { |
| 48 | 54 | struct mm_struct *mm = __mm; |
| 49 | − mm_context_t *pc; | |
| 50 | 55 | |
| 51 | 56 | if (this_cpu_read(cpu_tlbstate.loaded_mm) != mm) |
| 52 | 57 | return; |
| 53 | 58 | |
| 54 | − pc = &mm->context; | |
| 55 | − set_ldt(pc->ldt->entries, pc->ldt->nr_entries); | |
| 59 | + load_mm_ldt(mm); | |
| 56 | 60 | |
| 57 | 61 | refresh_ldt_segments(); |
| 58 | 62 | } |
| @@ -89,25 +93,143 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries) · 30 unmodified lines | ||
| 89 | 93 | return NULL; |
| 90 | 94 | } |
| 91 | 95 | |
| 96 | + /* The new LDT isn't aliased for PTI yet. */ | |
| 97 | + new_ldt->slot = -1; | |
| 98 | + | |
| 92 | 99 | new_ldt->nr_entries = num_entries; |
| 93 | 100 | return new_ldt; |
| 94 | 101 | } |
| 95 | 102 | |
| 103 | +/* | |
| 104 | + * If PTI is enabled, this maps the LDT into the kernelmode and | |
| 105 | + * usermode tables for the given mm. | |
| 106 | + * | |
| 107 | + * There is no corresponding unmap function. Even if the LDT is freed, we | |
| 108 | + * leave the PTEs around until the slot is reused or the mm is destroyed. | |
| 109 | + * This is harmless: the LDT is always in ordinary memory, and no one will | |
| 110 | + * access the freed slot. | |
| 111 | + * | |
| 112 | + * If we wanted to unmap freed LDTs, we'd also need to do a flush to make | |
| 113 | + * it useful, and the flush would slow down modify_ldt(). | |
| 114 | + */ | |
| 115 | +static int | |
| 116 | +map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) | |
| 117 | +{ | |
| 118 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 119 | + bool is_vmalloc, had_top_level_entry; | |
| 120 | + unsigned long va; | |
| 121 | + spinlock_t *ptl; | |
| 122 | + pgd_t *pgd; | |
| 123 | + int i; | |
| 124 | + | |
| 125 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 126 | + return 0; | |
| 127 | + | |
| 128 | + /* | |
| 129 | + * Any given ldt_struct should have map_ldt_struct() called at most | |
| 130 | + * once. | |
| 131 | + */ | |
| 132 | + WARN_ON(ldt->slot != -1); | |
| 133 | + | |
| 134 | + /* | |
| 135 | + * Did we already have the top level entry allocated? We can't | |
| 136 | + * use pgd_none() for this because it doens't do anything on | |
| 137 | + * 4-level page table kernels. | |
| 138 | + */ | |
| 139 | + pgd = pgd_offset(mm, LDT_BASE_ADDR); | |
| 140 | + had_top_level_entry = (pgd->pgd != 0); | |
| 141 | + | |
| 142 | + is_vmalloc = is_vmalloc_addr(ldt->entries); | |
| 143 | + | |
| 144 | + for (i = 0; i * PAGE_SIZE < ldt->nr_entries * LDT_ENTRY_SIZE; i++) { | |
| 145 | + unsigned long offset = i << PAGE_SHIFT; | |
| 146 | + const void *src = (char *)ldt->entries + offset; | |
| 147 | + unsigned long pfn; | |
| 148 | + pte_t pte, *ptep; | |
| 149 | + | |
| 150 | + va = (unsigned long)ldt_slot_va(slot) + offset; | |
| 151 | + pfn = is_vmalloc ? vmalloc_to_pfn(src) : | |
| 152 | + page_to_pfn(virt_to_page(src)); | |
| 153 | + /* | |
| 154 | + * Treat the PTI LDT range as a *userspace* range. | |
| 155 | + * get_locked_pte() will allocate all needed pagetables | |
| 156 | + * and account for them in this mm. | |
| 157 | + */ | |
| 158 | + ptep = get_locked_pte(mm, va, &ptl); | |
| 159 | + if (!ptep) | |
| 160 | + return -ENOMEM; | |
| 161 | + /* | |
| 162 | + * Map it RO so the easy to find address is not a primary | |
| 163 | + * target via some kernel interface which misses a | |
| 164 | + * permission check. | |
| 165 | + */ | |
| 166 | + pte = pfn_pte(pfn, __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL)); | |
| 167 | + set_pte_at(mm, va, ptep, pte); | |
| 168 | + pte_unmap_unlock(ptep, ptl); | |
| 169 | + } | |
| 170 | + | |
| 171 | + if (mm->context.ldt) { | |
| 172 | + /* | |
| 173 | + * We already had an LDT. The top-level entry should already | |
| 174 | + * have been allocated and synchronized with the usermode | |
| 175 | + * tables. | |
| 176 | + */ | |
| 177 | + WARN_ON(!had_top_level_entry); | |
| 178 | + if (static_cpu_has(X86_FEATURE_PTI)) | |
| 179 | + WARN_ON(!kernel_to_user_pgdp(pgd)->pgd); | |
| 180 | + } else { | |
| 181 | + /* | |
| 182 | + * This is the first time we're mapping an LDT for this process. | |
| 183 | + * Sync the pgd to the usermode tables. | |
| 184 | + */ | |
| 185 | + WARN_ON(had_top_level_entry); | |
| 186 | + if (static_cpu_has(X86_FEATURE_PTI)) { | |
| 187 | + WARN_ON(kernel_to_user_pgdp(pgd)->pgd); | |
| 188 | + set_pgd(kernel_to_user_pgdp(pgd), *pgd); | |
| 189 | + } | |
| 190 | + } | |
| 191 | + | |
| 192 | + va = (unsigned long)ldt_slot_va(slot); | |
| 193 | + flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, 0); | |
| 194 | + | |
| 195 | + ldt->slot = slot; | |
| 196 | +#endif | |
| 197 | + return 0; | |
| 198 | +} | |
| 199 | + | |
| 200 | +static void free_ldt_pgtables(struct mm_struct *mm) | |
| 201 | +{ | |
| 202 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 203 | + struct mmu_gather tlb; | |
| 204 | + unsigned long start = LDT_BASE_ADDR; | |
| 205 | + unsigned long end = start + (1UL << PGDIR_SHIFT); | |
| 206 | + | |
| 207 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 208 | + return; | |
| 209 | + | |
| 210 | + tlb_gather_mmu(&tlb, mm, start, end); | |
| 211 | + free_pgd_range(&tlb, start, end, start, end); | |
| 212 | + tlb_finish_mmu(&tlb, start, end); | |
| 213 | +#endif | |
| 214 | +} | |
| 215 | + | |
| 96 | 216 | /* After calling this, the LDT is immutable. */ |
| 97 | 217 | static void finalize_ldt_struct(struct ldt_struct *ldt) |
| 98 | 218 | { |
| 99 | 219 | paravirt_alloc_ldt(ldt->entries, ldt->nr_entries); |
| 100 | 220 | } |
| 101 | 221 | |
| 102 | −/* context.lock is held */ | |
| 103 | −static void install_ldt(struct mm_struct *current_mm, | |
| 104 | − struct ldt_struct *ldt) | |
| 222 | +static void install_ldt(struct mm_struct *mm, struct ldt_struct *ldt) | |
| 105 | 223 | { |
| 224 | + mutex_lock(&mm->context.lock); | |
| 225 | + | |
| 106 | 226 | /* Synchronizes with READ_ONCE in load_mm_ldt. */ |
| 107 | − smp_store_release(¤t_mm->context.ldt, ldt); | |
| 227 | + smp_store_release(&mm->context.ldt, ldt); | |
| 108 | 228 | |
| 109 | − /* Activate the LDT for all CPUs using current_mm. */ | |
| 110 | − on_each_cpu_mask(mm_cpumask(current_mm), flush_ldt, current_mm, true); | |
| 229 | + /* Activate the LDT for all CPUs using currents mm. */ | |
| 230 | + on_each_cpu_mask(mm_cpumask(mm), flush_ldt, mm, true); | |
| 231 | + | |
| 232 | + mutex_unlock(&mm->context.lock); | |
| 111 | 233 | } |
| 112 | 234 | |
| 113 | 235 | static void free_ldt_struct(struct ldt_struct *ldt) |
| @@ -124,27 +246,20 @@ static void free_ldt_struct(struct ldt_struct *ldt) · 10 unmodified lines | ||
| 124 | 246 | } |
| 125 | 247 | |
| 126 | 248 | /* |
| 127 | − * we do not have to muck with descriptors here, that is | |
| 128 | − * done in switch_mm() as needed. | |
| 249 | + * Called on fork from arch_dup_mmap(). Just copy the current LDT state, | |
| 250 | + * the new task is not running, so nothing can be installed. | |
| 129 | 251 | */ |
| 130 | −int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm) | |
| 252 | +int ldt_dup_context(struct mm_struct *old_mm, struct mm_struct *mm) | |
| 131 | 253 | { |
| 132 | 254 | struct ldt_struct *new_ldt; |
| 133 | − struct mm_struct *old_mm; | |
| 134 | 255 | int retval = 0; |
| 135 | 256 | |
| 136 | − mutex_init(&mm->context.lock); | |
| 137 | − old_mm = current->mm; | |
| 138 | − if (!old_mm) { | |
| 139 | − mm->context.ldt = NULL; | |
| 257 | + if (!old_mm) | |
| 140 | 258 | return 0; |
| 141 | − } | |
| 142 | 259 | |
| 143 | 260 | mutex_lock(&old_mm->context.lock); |
| 144 | − if (!old_mm->context.ldt) { | |
| 145 | − mm->context.ldt = NULL; | |
| 261 | + if (!old_mm->context.ldt) | |
| 146 | 262 | goto out_unlock; |
| 147 | − } | |
| 148 | 263 | |
| 149 | 264 | new_ldt = alloc_ldt_struct(old_mm->context.ldt->nr_entries); |
| 150 | 265 | if (!new_ldt) { |
| @@ -156,6 +271,12 @@ int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm) · 5 unmodified lines | ||
| 156 | 271 | new_ldt->nr_entries * LDT_ENTRY_SIZE); |
| 157 | 272 | finalize_ldt_struct(new_ldt); |
| 158 | 273 | |
| 274 | + retval = map_ldt_struct(mm, new_ldt, 0); | |
| 275 | + if (retval) { | |
| 276 | + free_ldt_pgtables(mm); | |
| 277 | + free_ldt_struct(new_ldt); | |
| 278 | + goto out_unlock; | |
| 279 | + } | |
| 159 | 280 | mm->context.ldt = new_ldt; |
| 160 | 281 | |
| 161 | 282 | out_unlock: |
| @@ -174,13 +295,18 @@ void destroy_context_ldt(struct mm_struct *mm) · 12 unmodified lines | ||
| 174 | 295 | mm->context.ldt = NULL; |
| 175 | 296 | } |
| 176 | 297 | |
| 298 | +void ldt_arch_exit_mmap(struct mm_struct *mm) | |
| 299 | +{ | |
| 300 | + free_ldt_pgtables(mm); | |
| 301 | +} | |
| 302 | + | |
| 177 | 303 | static int read_ldt(void __user *ptr, unsigned long bytecount) |
| 178 | 304 | { |
| 179 | 305 | struct mm_struct *mm = current->mm; |
| 180 | 306 | unsigned long entries_size; |
| 181 | 307 | int retval; |
| 182 | 308 | |
| 183 | − mutex_lock(&mm->context.lock); | |
| 309 | + down_read(&mm->context.ldt_usr_sem); | |
| 184 | 310 | |
| 185 | 311 | if (!mm->context.ldt) { |
| 186 | 312 | retval = 0; |
| @@ -209,7 +335,7 @@ static int read_ldt(void __user *ptr, unsigned long bytecount) · 22 unmodified lines | ||
| 209 | 335 | retval = bytecount; |
| 210 | 336 | |
| 211 | 337 | out_unlock: |
| 212 | − mutex_unlock(&mm->context.lock); | |
| 338 | + up_read(&mm->context.ldt_usr_sem); | |
| 213 | 339 | return retval; |
| 214 | 340 | } |
| 215 | 341 | |
| @@ -269,7 +395,8 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) · 53 unmodified lines | ||
| 269 | 395 | ldt.avl = 0; |
| 270 | 396 | } |
| 271 | 397 | |
| 272 | − mutex_lock(&mm->context.lock); | |
| 398 | + if (down_write_killable(&mm->context.ldt_usr_sem)) | |
| 399 | + return -EINTR; | |
| 273 | 400 | |
| 274 | 401 | old_ldt = mm->context.ldt; |
| 275 | 402 | old_nr_entries = old_ldt ? old_ldt->nr_entries : 0; |
| @@ -286,12 +413,31 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) · 10 unmodified lines | ||
| 286 | 413 | new_ldt->entries[ldt_info.entry_number] = ldt; |
| 287 | 414 | finalize_ldt_struct(new_ldt); |
| 288 | 415 | |
| 416 | + /* | |
| 417 | + * If we are using PTI, map the new LDT into the userspace pagetables. | |
| 418 | + * If there is already an LDT, use the other slot so that other CPUs | |
| 419 | + * will continue to use the old LDT until install_ldt() switches | |
| 420 | + * them over to the new LDT. | |
| 421 | + */ | |
| 422 | + error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0); | |
| 423 | + if (error) { | |
| 424 | + /* | |
| 425 | + * This only can fail for the first LDT setup. If an LDT is | |
| 426 | + * already installed then the PTE page is already | |
| 427 | + * populated. Mop up a half populated page table. | |
| 428 | + */ | |
| 429 | + if (!WARN_ON_ONCE(old_ldt)) | |
| 430 | + free_ldt_pgtables(mm); | |
| 431 | + free_ldt_struct(new_ldt); | |
| 432 | + goto out_unlock; | |
| 433 | + } | |
| 434 | + | |
| 289 | 435 | install_ldt(mm, new_ldt); |
| 290 | 436 | free_ldt_struct(old_ldt); |
| 291 | 437 | error = 0; |
| 292 | 438 | |
| 293 | 439 | out_unlock: |
| 294 | − mutex_unlock(&mm->context.lock); | |
| 440 | + up_write(&mm->context.ldt_usr_sem); | |
| 295 | 441 | out: |
| 296 | 442 | return error; |
| 297 | 443 | } |
| @@ -48,8 +48,6 @@ static void load_segments(void) · 47 unmodified lines | ||
| 48 | 48 | "\tmovl $"STR(__KERNEL_DS)",%%eax\n" |
| 49 | 49 | "\tmovl %%eax,%%ds\n" |
| 50 | 50 | "\tmovl %%eax,%%es\n" |
| 51 | − "\tmovl %%eax,%%fs\n" | |
| 52 | − "\tmovl %%eax,%%gs\n" | |
| 53 | 51 | "\tmovl %%eax,%%ss\n" |
| 54 | 52 | : : : "eax", "memory"); |
| 55 | 53 | #undef STR |
| @@ -232,8 +230,8 @@ void machine_kexec(struct kimage *image) · 176 unmodified lines | ||
| 232 | 230 | * The gdt & idt are now invalid. |
| 233 | 231 | * If you want to load them you must set up your own idt & gdt. |
| 234 | 232 | */ |
| 235 | − set_gdt(phys_to_virt(0), 0); | |
| 236 | 233 | idt_invalidate(phys_to_virt(0)); |
| 234 | + set_gdt(phys_to_virt(0), 0); | |
| 237 | 235 | |
| 238 | 236 | /* now call it */ |
| 239 | 237 | image->start = relocate_kernel_ptr((unsigned long)image->head, |
| @@ -10,7 +10,6 @@ DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax"); · 9 unmodified lines | ||
| 10 | 10 | DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax"); |
| 11 | 11 | DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax"); |
| 12 | 12 | DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3"); |
| 13 | −DEF_NATIVE(pv_mmu_ops, flush_tlb_single, "invlpg (%rdi)"); | |
| 14 | 13 | DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd"); |
| 15 | 14 | |
| 16 | 15 | DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq"); |
| @@ -60,7 +59,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf, · 43 unmodified lines | ||
| 60 | 59 | PATCH_SITE(pv_mmu_ops, read_cr2); |
| 61 | 60 | PATCH_SITE(pv_mmu_ops, read_cr3); |
| 62 | 61 | PATCH_SITE(pv_mmu_ops, write_cr3); |
| 63 | − PATCH_SITE(pv_mmu_ops, flush_tlb_single); | |
| 64 | 62 | PATCH_SITE(pv_cpu_ops, wbinvd); |
| 65 | 63 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) |
| 66 | 64 | case PARAVIRT_PATCH(pv_lock_ops.queued_spin_unlock): |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | * section. Since TSS's are completely CPU-local, we want them |
| 48 | 48 | * on exact cacheline boundaries, to eliminate cacheline ping-pong. |
| 49 | 49 | */ |
| 50 | −__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { | |
| 50 | +__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss_rw) = { | |
| 51 | 51 | .x86_tss = { |
| 52 | 52 | /* |
| 53 | 53 | * .sp0 is only used when entering ring 0 from a lower |
| @@ -56,6 +56,16 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { · 2 unmodified lines | ||
| 56 | 56 | * Poison it. |
| 57 | 57 | */ |
| 58 | 58 | .sp0 = (1UL << (BITS_PER_LONG-1)) + 1, |
| 59 | + | |
| 60 | +#ifdef CONFIG_X86_64 | |
| 61 | + /* | |
| 62 | + * .sp1 is cpu_current_top_of_stack. The init task never | |
| 63 | + * runs user code, but cpu_current_top_of_stack should still | |
| 64 | + * be well defined before the first context switch. | |
| 65 | + */ | |
| 66 | + .sp1 = TOP_OF_INIT_STACK, | |
| 67 | +#endif | |
| 68 | + | |
| 59 | 69 | #ifdef CONFIG_X86_32 |
| 60 | 70 | .ss0 = __KERNEL_DS, |
| 61 | 71 | .ss1 = __KERNEL_CS, |
| @@ -71,11 +81,8 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { · 9 unmodified lines | ||
| 71 | 81 | */ |
| 72 | 82 | .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, |
| 73 | 83 | #endif |
| 74 | −#ifdef CONFIG_X86_32 | |
| 75 | − .SYSENTER_stack_canary = STACK_END_MAGIC, | |
| 76 | −#endif | |
| 77 | 84 | }; |
| 78 | −EXPORT_PER_CPU_SYMBOL(cpu_tss); | |
| 85 | +EXPORT_PER_CPU_SYMBOL(cpu_tss_rw); | |
| 79 | 86 | |
| 80 | 87 | DEFINE_PER_CPU(bool, __tss_limit_invalid); |
| 81 | 88 | EXPORT_PER_CPU_SYMBOL_GPL(__tss_limit_invalid); |
| @@ -104,7 +111,7 @@ void exit_thread(struct task_struct *tsk) · 22 unmodified lines | ||
| 104 | 111 | struct fpu *fpu = &t->fpu; |
| 105 | 112 | |
| 106 | 113 | if (bp) { |
| 107 | − struct tss_struct *tss = &per_cpu(cpu_tss, get_cpu()); | |
| 114 | + struct tss_struct *tss = &per_cpu(cpu_tss_rw, get_cpu()); | |
| 108 | 115 | |
| 109 | 116 | t->io_bitmap_ptr = NULL; |
| 110 | 117 | clear_thread_flag(TIF_IO_BITMAP); |
| @@ -234,7 +234,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 233 unmodified lines | ||
| 234 | 234 | struct fpu *prev_fpu = &prev->fpu; |
| 235 | 235 | struct fpu *next_fpu = &next->fpu; |
| 236 | 236 | int cpu = smp_processor_id(); |
| 237 | − struct tss_struct *tss = &per_cpu(cpu_tss, cpu); | |
| 237 | + struct tss_struct *tss = &per_cpu(cpu_tss_rw, cpu); | |
| 238 | 238 | |
| 239 | 239 | /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ |
| 240 | 240 | |
| @@ -69,9 +69,8 @@ void __show_regs(struct pt_regs *regs, int all) · 68 unmodified lines | ||
| 69 | 69 | unsigned int fsindex, gsindex; |
| 70 | 70 | unsigned int ds, cs, es; |
| 71 | 71 | |
| 72 | − printk(KERN_DEFAULT "RIP: %04lx:%pS\n", regs->cs, (void *)regs->ip); | |
| 73 | − printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx", regs->ss, | |
| 74 | − regs->sp, regs->flags); | |
| 72 | + show_iret_regs(regs); | |
| 73 | + | |
| 75 | 74 | if (regs->orig_ax != -1) |
| 76 | 75 | pr_cont(" ORIG_RAX: %016lx\n", regs->orig_ax); |
| 77 | 76 | else |
| @@ -88,6 +87,9 @@ void __show_regs(struct pt_regs *regs, int all) · 10 unmodified lines | ||
| 88 | 87 | printk(KERN_DEFAULT "R13: %016lx R14: %016lx R15: %016lx\n", |
| 89 | 88 | regs->r13, regs->r14, regs->r15); |
| 90 | 89 | |
| 90 | + if (!all) | |
| 91 | + return; | |
| 92 | + | |
| 91 | 93 | asm("movl %%ds,%0" : "=r" (ds)); |
| 92 | 94 | asm("movl %%cs,%0" : "=r" (cs)); |
| 93 | 95 | asm("movl %%es,%0" : "=r" (es)); |
| @@ -98,9 +100,6 @@ void __show_regs(struct pt_regs *regs, int all) · 4 unmodified lines | ||
| 98 | 100 | rdmsrl(MSR_GS_BASE, gs); |
| 99 | 101 | rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); |
| 100 | 102 | |
| 101 | − if (!all) | |
| 102 | − return; | |
| 103 | − | |
| 104 | 103 | cr0 = read_cr0(); |
| 105 | 104 | cr2 = read_cr2(); |
| 106 | 105 | cr3 = __read_cr3(); |
| @@ -400,7 +399,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 293 unmodified lines | ||
| 400 | 399 | struct fpu *prev_fpu = &prev->fpu; |
| 401 | 400 | struct fpu *next_fpu = &next->fpu; |
| 402 | 401 | int cpu = smp_processor_id(); |
| 403 | − struct tss_struct *tss = &per_cpu(cpu_tss, cpu); | |
| 402 | + struct tss_struct *tss = &per_cpu(cpu_tss_rw, cpu); | |
| 404 | 403 | |
| 405 | 404 | WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) && |
| 406 | 405 | this_cpu_read(irq_count) != -1); |
| @@ -462,6 +461,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) · 55 unmodified lines | ||
| 462 | 461 | * Switch the PDA and FPU contexts. |
| 463 | 462 | */ |
| 464 | 463 | this_cpu_write(current_task, next_p); |
| 464 | + this_cpu_write(cpu_current_top_of_stack, task_top_of_stack(next_p)); | |
| 465 | 465 | |
| 466 | 466 | /* Reload sp0. */ |
| 467 | 467 | update_sp0(next_p); |
| @@ -106,7 +106,7 @@ EXPORT_SYMBOL(__max_logical_packages); · 105 unmodified lines | ||
| 106 | 106 | static unsigned int logical_packages __read_mostly; |
| 107 | 107 | |
| 108 | 108 | /* Maximum number of SMT threads on any online core */ |
| 109 | −int __max_smt_threads __read_mostly; | |
| 109 | +int __read_mostly __max_smt_threads = 1; | |
| 110 | 110 | |
| 111 | 111 | /* Flag to indicate if a complete sched domain rebuild is required */ |
| 112 | 112 | bool x86_topology_update; |
| @@ -126,25 +126,16 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) · 13 unmodified lines | ||
| 126 | 126 | spin_lock_irqsave(&rtc_lock, flags); |
| 127 | 127 | CMOS_WRITE(0xa, 0xf); |
| 128 | 128 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 129 | − local_flush_tlb(); | |
| 130 | − pr_debug("1.\n"); | |
| 131 | 129 | *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = |
| 132 | 130 | start_eip >> 4; |
| 133 | − pr_debug("2.\n"); | |
| 134 | 131 | *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = |
| 135 | 132 | start_eip & 0xf; |
| 136 | − pr_debug("3.\n"); | |
| 137 | 133 | } |
| 138 | 134 | |
| 139 | 135 | static inline void smpboot_restore_warm_reset_vector(void) |
| 140 | 136 | { |
| 141 | 137 | unsigned long flags; |
| 142 | 138 | |
| 143 | − /* | |
| 144 | − * Install writable page 0 entry to set BIOS data area. | |
| 145 | − */ | |
| 146 | − local_flush_tlb(); | |
| 147 | − | |
| 148 | 139 | /* |
| 149 | 140 | * Paranoid: Set warm reset code and vector here back |
| 150 | 141 | * to default values. |
| @@ -932,12 +923,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, · 781 unmodified lines | ||
| 932 | 923 | initial_code = (unsigned long)start_secondary; |
| 933 | 924 | initial_stack = idle->thread.sp; |
| 934 | 925 | |
| 935 | − /* | |
| 936 | − * Enable the espfix hack for this CPU | |
| 937 | − */ | |
| 938 | −#ifdef CONFIG_X86_ESPFIX64 | |
| 926 | + /* Enable the espfix hack for this CPU */ | |
| 939 | 927 | init_espfix_ap(cpu); |
| 940 | −#endif | |
| 941 | 928 | |
| 942 | 929 | /* So we see what's up */ |
| 943 | 930 | announce_cpu(cpu, apicid); |
| @@ -1304,7 +1291,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus) · 360 unmodified lines | ||
| 1304 | 1291 | * Today neither Intel nor AMD support heterogenous systems so |
| 1305 | 1292 | * extrapolate the boot cpu's data to all packages. |
| 1306 | 1293 | */ |
| 1307 | − ncpus = cpu_data(0).booted_cores * smp_num_siblings; | |
| 1294 | + ncpus = cpu_data(0).booted_cores * topology_max_smt_threads(); | |
| 1308 | 1295 | __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus); |
| 1309 | 1296 | pr_info("Max logical packages: %u\n", __max_logical_packages); |
| 1310 | 1297 | |
| @@ -164,8 +164,12 @@ int save_stack_trace_tsk_reliable(struct task_struct *tsk, · 163 unmodified lines | ||
| 164 | 164 | { |
| 165 | 165 | int ret; |
| 166 | 166 | |
| 167 | + /* | |
| 168 | + * If the task doesn't have a stack (e.g., a zombie), the stack is | |
| 169 | + * "reliably" empty. | |
| 170 | + */ | |
| 167 | 171 | if (!try_get_task_stack(tsk)) |
| 168 | − return -EINVAL; | |
| 172 | + return 0; | |
| 169 | 173 | |
| 170 | 174 | ret = __save_stack_trace_reliable(trace, tsk); |
| 171 | 175 | |
| @@ -93,17 +93,10 @@ static void set_tls_desc(struct task_struct *p, int idx, · 92 unmodified lines | ||
| 93 | 93 | cpu = get_cpu(); |
| 94 | 94 | |
| 95 | 95 | while (n-- > 0) { |
| 96 | − if (LDT_empty(info) || LDT_zero(info)) { | |
| 96 | + if (LDT_empty(info) || LDT_zero(info)) | |
| 97 | 97 | memset(desc, 0, sizeof(*desc)); |
| 98 | − } else { | |
| 98 | + else | |
| 99 | 99 | fill_ldt(desc, info); |
| 100 | − | |
| 101 | − /* | |
| 102 | − * Always set the accessed bit so that the CPU | |
| 103 | − * doesn't try to write to the (read-only) GDT. | |
| 104 | − */ | |
| 105 | − desc->type |= 1; | |
| 106 | − } | |
| 107 | 100 | ++info; |
| 108 | 101 | ++desc; |
| 109 | 102 | } |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | #include <asm/traps.h> |
| 52 | 52 | #include <asm/desc.h> |
| 53 | 53 | #include <asm/fpu/internal.h> |
| 54 | +#include <asm/cpu_entry_area.h> | |
| 54 | 55 | #include <asm/mce.h> |
| 55 | 56 | #include <asm/fixmap.h> |
| 56 | 57 | #include <asm/mach_traps.h> |
| @@ -348,23 +349,42 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) · 291 unmodified lines | ||
| 348 | 349 | |
| 349 | 350 | /* |
| 350 | 351 | * If IRET takes a non-IST fault on the espfix64 stack, then we |
| 351 | − * end up promoting it to a doublefault. In that case, modify | |
| 352 | − * the stack to make it look like we just entered the #GP | |
| 353 | − * handler from user space, similar to bad_iret. | |
| 352 | + * end up promoting it to a doublefault. In that case, take | |
| 353 | + * advantage of the fact that we're not using the normal (TSS.sp0) | |
| 354 | + * stack right now. We can write a fake #GP(0) frame at TSS.sp0 | |
| 355 | + * and then modify our own IRET frame so that, when we return, | |
| 356 | + * we land directly at the #GP(0) vector with the stack already | |
| 357 | + * set up according to its expectations. | |
| 358 | + * | |
| 359 | + * The net result is that our #GP handler will think that we | |
| 360 | + * entered from usermode with the bad user context. | |
| 354 | 361 | * |
| 355 | 362 | * No need for ist_enter here because we don't use RCU. |
| 356 | 363 | */ |
| 357 | − if (((long)regs->sp >> PGDIR_SHIFT) == ESPFIX_PGD_ENTRY && | |
| 364 | + if (((long)regs->sp >> P4D_SHIFT) == ESPFIX_PGD_ENTRY && | |
| 358 | 365 | regs->cs == __KERNEL_CS && |
| 359 | 366 | regs->ip == (unsigned long)native_irq_return_iret) |
| 360 | 367 | { |
| 361 | − struct pt_regs *normal_regs = task_pt_regs(current); | |
| 368 | + struct pt_regs *gpregs = (struct pt_regs *)this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1; | |
| 362 | 369 | |
| 363 | − /* Fake a #GP(0) from userspace. */ | |
| 364 | − memmove(&normal_regs->ip, (void *)regs->sp, 5*8); | |
| 365 | − normal_regs->orig_ax = 0; /* Missing (lost) #GP error code */ | |
| 370 | + /* | |
| 371 | + * regs->sp points to the failing IRET frame on the | |
| 372 | + * ESPFIX64 stack. Copy it to the entry stack. This fills | |
| 373 | + * in gpregs->ss through gpregs->ip. | |
| 374 | + * | |
| 375 | + */ | |
| 376 | + memmove(&gpregs->ip, (void *)regs->sp, 5*8); | |
| 377 | + gpregs->orig_ax = 0; /* Missing (lost) #GP error code */ | |
| 378 | + | |
| 379 | + /* | |
| 380 | + * Adjust our frame so that we return straight to the #GP | |
| 381 | + * vector with the expected RSP value. This is safe because | |
| 382 | + * we won't enable interupts or schedule before we invoke | |
| 383 | + * general_protection, so nothing will clobber the stack | |
| 384 | + * frame we just set up. | |
| 385 | + */ | |
| 366 | 386 | regs->ip = (unsigned long)general_protection; |
| 367 | − regs->sp = (unsigned long)&normal_regs->orig_ax; | |
| 387 | + regs->sp = (unsigned long)&gpregs->orig_ax; | |
| 368 | 388 | |
| 369 | 389 | return; |
| 370 | 390 | } |
| @@ -389,7 +409,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) · 18 unmodified lines | ||
| 389 | 409 | * |
| 390 | 410 | * Processors update CR2 whenever a page fault is detected. If a |
| 391 | 411 | * second page fault occurs while an earlier page fault is being |
| 392 | − * deliv- ered, the faulting linear address of the second fault will | |
| 412 | + * delivered, the faulting linear address of the second fault will | |
| 393 | 413 | * overwrite the contents of CR2 (replacing the previous |
| 394 | 414 | * address). These updates to CR2 occur even if the page fault |
| 395 | 415 | * results in a double fault or occurs during the delivery of a |
| @@ -605,14 +625,15 @@ NOKPROBE_SYMBOL(do_int3); · 209 unmodified lines | ||
| 605 | 625 | |
| 606 | 626 | #ifdef CONFIG_X86_64 |
| 607 | 627 | /* |
| 608 | − * Help handler running on IST stack to switch off the IST stack if the | |
| 609 | − * interrupted code was in user mode. The actual stack switch is done in | |
| 610 | − * entry_64.S | |
| 628 | + * Help handler running on a per-cpu (IST or entry trampoline) stack | |
| 629 | + * to switch to the normal thread stack if the interrupted code was in | |
| 630 | + * user mode. The actual stack switch is done in entry_64.S | |
| 611 | 631 | */ |
| 612 | 632 | asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs) |
| 613 | 633 | { |
| 614 | − struct pt_regs *regs = task_pt_regs(current); | |
| 615 | − *regs = *eregs; | |
| 634 | + struct pt_regs *regs = (struct pt_regs *)this_cpu_read(cpu_current_top_of_stack) - 1; | |
| 635 | + if (regs != eregs) | |
| 636 | + *regs = *eregs; | |
| 616 | 637 | return regs; |
| 617 | 638 | } |
| 618 | 639 | NOKPROBE_SYMBOL(sync_regs); |
| @@ -628,13 +649,13 @@ struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s) · 9 unmodified lines | ||
| 628 | 649 | /* |
| 629 | 650 | * This is called from entry_64.S early in handling a fault |
| 630 | 651 | * caused by a bad iret to user mode. To handle the fault |
| 631 | − * correctly, we want move our stack frame to task_pt_regs | |
| 632 | − * and we want to pretend that the exception came from the | |
| 633 | − * iret target. | |
| 652 | + * correctly, we want to move our stack frame to where it would | |
| 653 | + * be had we entered directly on the entry stack (rather than | |
| 654 | + * just below the IRET frame) and we want to pretend that the | |
| 655 | + * exception came from the IRET target. | |
| 634 | 656 | */ |
| 635 | 657 | struct bad_iret_stack *new_stack = |
| 636 | − container_of(task_pt_regs(current), | |
| 637 | − struct bad_iret_stack, regs); | |
| 658 | + (struct bad_iret_stack *)this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1; | |
| 638 | 659 | |
| 639 | 660 | /* Copy the IRET target to the new stack. */ |
| 640 | 661 | memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8); |
| @@ -795,14 +816,6 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) · 154 unmodified lines | ||
| 795 | 816 | debug_stack_usage_dec(); |
| 796 | 817 | |
| 797 | 818 | exit: |
| 798 | −#if defined(CONFIG_X86_32) | |
| 799 | − /* | |
| 800 | − * This is the most likely code path that involves non-trivial use | |
| 801 | − * of the SYSENTER stack. Check that we haven't overrun it. | |
| 802 | − */ | |
| 803 | − WARN(this_cpu_read(cpu_tss.SYSENTER_stack_canary) != STACK_END_MAGIC, | |
| 804 | − "Overran or corrupted SYSENTER stack\n"); | |
| 805 | −#endif | |
| 806 | 819 | ist_exit(regs); |
| 807 | 820 | } |
| 808 | 821 | NOKPROBE_SYMBOL(do_debug); |
| @@ -929,6 +942,9 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) · 120 unmodified lines | ||
| 929 | 942 | |
| 930 | 943 | void __init trap_init(void) |
| 931 | 944 | { |
| 945 | + /* Init cpu_entry_area before IST entries are set up */ | |
| 946 | + setup_cpu_entry_areas(); | |
| 947 | + | |
| 932 | 948 | idt_setup_traps(); |
| 933 | 949 | |
| 934 | 950 | /* |
| @@ -936,8 +952,9 @@ void __init trap_init(void) · 1 unmodified line | ||
| 936 | 952 | * "sidt" instruction will not leak the location of the kernel, and |
| 937 | 953 | * to defend the IDT against arbitrary memory write vulnerabilities. |
| 938 | 954 | * It will be reloaded in cpu_init() */ |
| 939 | − __set_fixmap(FIX_RO_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO); | |
| 940 | − idt_descr.address = fix_to_virt(FIX_RO_IDT); | |
| 955 | + cea_set_pte(CPU_ENTRY_AREA_RO_IDT_VADDR, __pa_symbol(idt_table), | |
| 956 | + PAGE_KERNEL_RO); | |
| 957 | + idt_descr.address = CPU_ENTRY_AREA_RO_IDT; | |
| 941 | 958 | |
| 942 | 959 | /* |
| 943 | 960 | * Should be a barrier for any external CPU state: |
| @@ -253,22 +253,15 @@ unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) · 252 unmodified lines | ||
| 253 | 253 | return NULL; |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | −static bool stack_access_ok(struct unwind_state *state, unsigned long addr, | |
| 256 | +static bool stack_access_ok(struct unwind_state *state, unsigned long _addr, | |
| 257 | 257 | size_t len) |
| 258 | 258 | { |
| 259 | 259 | struct stack_info *info = &state->stack_info; |
| 260 | + void *addr = (void *)_addr; | |
| 260 | 261 | |
| 261 | − /* | |
| 262 | − * If the address isn't on the current stack, switch to the next one. | |
| 263 | − * | |
| 264 | − * We may have to traverse multiple stacks to deal with the possibility | |
| 265 | − * that info->next_sp could point to an empty stack and the address | |
| 266 | − * could be on a subsequent stack. | |
| 267 | − */ | |
| 268 | − while (!on_stack(info, (void *)addr, len)) | |
| 269 | − if (get_stack_info(info->next_sp, state->task, info, | |
| 270 | − &state->stack_mask)) | |
| 271 | − return false; | |
| 262 | + if (!on_stack(info, addr, len) && | |
| 263 | + (get_stack_info(addr, state->task, info, &state->stack_mask))) | |
| 264 | + return false; | |
| 272 | 265 | |
| 273 | 266 | return true; |
| 274 | 267 | } |
| @@ -283,42 +276,32 @@ static bool deref_stack_reg(struct unwind_state *state, unsigned long addr, · 8 unmodified lines | ||
| 283 | 276 | return true; |
| 284 | 277 | } |
| 285 | 278 | |
| 286 | −#define REGS_SIZE (sizeof(struct pt_regs)) | |
| 287 | −#define SP_OFFSET (offsetof(struct pt_regs, sp)) | |
| 288 | −#define IRET_REGS_SIZE (REGS_SIZE - offsetof(struct pt_regs, ip)) | |
| 289 | −#define IRET_SP_OFFSET (SP_OFFSET - offsetof(struct pt_regs, ip)) | |
| 290 | − | |
| 291 | 279 | static bool deref_stack_regs(struct unwind_state *state, unsigned long addr, |
| 292 | − unsigned long *ip, unsigned long *sp, bool full) | |
| 280 | + unsigned long *ip, unsigned long *sp) | |
| 293 | 281 | { |
| 294 | − size_t regs_size = full ? REGS_SIZE : IRET_REGS_SIZE; | |
| 295 | − size_t sp_offset = full ? SP_OFFSET : IRET_SP_OFFSET; | |
| 296 | − struct pt_regs *regs = (struct pt_regs *)(addr + regs_size - REGS_SIZE); | |
| 297 | − | |
| 298 | − if (IS_ENABLED(CONFIG_X86_64)) { | |
| 299 | − if (!stack_access_ok(state, addr, regs_size)) | |
| 300 | − return false; | |
| 282 | + struct pt_regs *regs = (struct pt_regs *)addr; | |
| 301 | 283 | |
| 302 | − *ip = regs->ip; | |
| 303 | − *sp = regs->sp; | |
| 284 | + /* x86-32 support will be more complicated due to the ®s->sp hack */ | |
| 285 | + BUILD_BUG_ON(IS_ENABLED(CONFIG_X86_32)); | |
| 304 | 286 | |
| 305 | − return true; | |
| 306 | − } | |
| 307 | − | |
| 308 | − if (!stack_access_ok(state, addr, sp_offset)) | |
| 287 | + if (!stack_access_ok(state, addr, sizeof(struct pt_regs))) | |
| 309 | 288 | return false; |
| 310 | 289 | |
| 311 | 290 | *ip = regs->ip; |
| 291 | + *sp = regs->sp; | |
| 292 | + return true; | |
| 293 | +} | |
| 312 | 294 | |
| 313 | − if (user_mode(regs)) { | |
| 314 | − if (!stack_access_ok(state, addr + sp_offset, | |
| 315 | − REGS_SIZE - SP_OFFSET)) | |
| 316 | − return false; | |
| 295 | +static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr, | |
| 296 | + unsigned long *ip, unsigned long *sp) | |
| 297 | +{ | |
| 298 | + struct pt_regs *regs = (void *)addr - IRET_FRAME_OFFSET; | |
| 317 | 299 | |
| 318 | − *sp = regs->sp; | |
| 319 | − } else | |
| 320 | − *sp = (unsigned long)®s->sp; | |
| 300 | + if (!stack_access_ok(state, addr, IRET_FRAME_SIZE)) | |
| 301 | + return false; | |
| 321 | 302 | |
| 303 | + *ip = regs->ip; | |
| 304 | + *sp = regs->sp; | |
| 322 | 305 | return true; |
| 323 | 306 | } |
| 324 | 307 | |
| @@ -327,7 +310,6 @@ bool unwind_next_frame(struct unwind_state *state) · 2 unmodified lines | ||
| 327 | 310 | unsigned long ip_p, sp, orig_ip, prev_sp = state->sp; |
| 328 | 311 | enum stack_type prev_type = state->stack_info.type; |
| 329 | 312 | struct orc_entry *orc; |
| 330 | − struct pt_regs *ptregs; | |
| 331 | 313 | bool indirect = false; |
| 332 | 314 | |
| 333 | 315 | if (unwind_done(state)) |
| @@ -435,7 +417,7 @@ bool unwind_next_frame(struct unwind_state *state) · 101 unmodified lines | ||
| 435 | 417 | break; |
| 436 | 418 | |
| 437 | 419 | case ORC_TYPE_REGS: |
| 438 | − if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) { | |
| 420 | + if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) { | |
| 439 | 421 | orc_warn("can't dereference registers at %p for ip %pB\n", |
| 440 | 422 | (void *)sp, (void *)orig_ip); |
| 441 | 423 | goto done; |
| @@ -447,20 +429,14 @@ bool unwind_next_frame(struct unwind_state *state) · 5 unmodified lines | ||
| 447 | 429 | break; |
| 448 | 430 | |
| 449 | 431 | case ORC_TYPE_REGS_IRET: |
| 450 | − if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) { | |
| 432 | + if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) { | |
| 451 | 433 | orc_warn("can't dereference iret registers at %p for ip %pB\n", |
| 452 | 434 | (void *)sp, (void *)orig_ip); |
| 453 | 435 | goto done; |
| 454 | 436 | } |
| 455 | 437 | |
| 456 | − ptregs = container_of((void *)sp, struct pt_regs, ip); | |
| 457 | − if ((unsigned long)ptregs >= prev_sp && | |
| 458 | − on_stack(&state->stack_info, ptregs, REGS_SIZE)) { | |
| 459 | − state->regs = ptregs; | |
| 460 | − state->full_regs = false; | |
| 461 | − } else | |
| 462 | − state->regs = NULL; | |
| 463 | − | |
| 438 | + state->regs = (void *)sp - IRET_FRAME_OFFSET; | |
| 439 | + state->full_regs = false; | |
| 464 | 440 | state->signal = true; |
| 465 | 441 | break; |
| 466 | 442 | |
| @@ -553,8 +529,18 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 86 unmodified lines | ||
| 553 | 529 | } |
| 554 | 530 | |
| 555 | 531 | if (get_stack_info((unsigned long *)state->sp, state->task, |
| 556 | − &state->stack_info, &state->stack_mask)) | |
| 557 | − return; | |
| 532 | + &state->stack_info, &state->stack_mask)) { | |
| 533 | + /* | |
| 534 | + * We weren't on a valid stack. It's possible that | |
| 535 | + * we overflowed a valid stack into a guard page. | |
| 536 | + * See if the next page up is valid so that we can | |
| 537 | + * generate some kind of backtrace if this happens. | |
| 538 | + */ | |
| 539 | + void *next_page = (void *)PAGE_ALIGN((unsigned long)state->sp); | |
| 540 | + if (get_stack_info(next_page, state->task, &state->stack_info, | |
| 541 | + &state->stack_mask)) | |
| 542 | + return; | |
| 543 | + } | |
| 558 | 544 | |
| 559 | 545 | /* |
| 560 | 546 | * The caller can provide the address of the first frame directly |
| @@ -61,11 +61,17 @@ jiffies_64 = jiffies; · 60 unmodified lines | ||
| 61 | 61 | . = ALIGN(HPAGE_SIZE); \ |
| 62 | 62 | __end_rodata_hpage_align = .; |
| 63 | 63 | |
| 64 | +#define ALIGN_ENTRY_TEXT_BEGIN . = ALIGN(PMD_SIZE); | |
| 65 | +#define ALIGN_ENTRY_TEXT_END . = ALIGN(PMD_SIZE); | |
| 66 | + | |
| 64 | 67 | #else |
| 65 | 68 | |
| 66 | 69 | #define X64_ALIGN_RODATA_BEGIN |
| 67 | 70 | #define X64_ALIGN_RODATA_END |
| 68 | 71 | |
| 72 | +#define ALIGN_ENTRY_TEXT_BEGIN | |
| 73 | +#define ALIGN_ENTRY_TEXT_END | |
| 74 | + | |
| 69 | 75 | #endif |
| 70 | 76 | |
| 71 | 77 | PHDRS { |
| @@ -102,11 +108,22 @@ SECTIONS · 30 unmodified lines | ||
| 102 | 108 | CPUIDLE_TEXT |
| 103 | 109 | LOCK_TEXT |
| 104 | 110 | KPROBES_TEXT |
| 111 | + ALIGN_ENTRY_TEXT_BEGIN | |
| 105 | 112 | ENTRY_TEXT |
| 106 | 113 | IRQENTRY_TEXT |
| 114 | + ALIGN_ENTRY_TEXT_END | |
| 107 | 115 | SOFTIRQENTRY_TEXT |
| 108 | 116 | *(.fixup) |
| 109 | 117 | *(.gnu.warning) |
| 118 | + | |
| 119 | +#ifdef CONFIG_X86_64 | |
| 120 | + . = ALIGN(PAGE_SIZE); | |
| 121 | + _entry_trampoline = .; | |
| 122 | + *(.entry_trampoline) | |
| 123 | + . = ALIGN(PAGE_SIZE); | |
| 124 | + ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big"); | |
| 125 | +#endif | |
| 126 | + | |
| 110 | 127 | /* End of text section */ |
| 111 | 128 | _etext = .; |
| 112 | 129 | } :text = 0x9090 |
| @@ -2390,9 +2390,21 @@ static int rsm_load_seg_64(struct x86_emulate_ctxt *ctxt, u64 smbase, int n) · 2389 unmodified lines | ||
| 2390 | 2390 | } |
| 2391 | 2391 | |
| 2392 | 2392 | static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt, |
| 2393 | − u64 cr0, u64 cr4) | |
| 2393 | + u64 cr0, u64 cr3, u64 cr4) | |
| 2394 | 2394 | { |
| 2395 | 2395 | int bad; |
| 2396 | + u64 pcid; | |
| 2397 | + | |
| 2398 | + /* In order to later set CR4.PCIDE, CR3[11:0] must be zero. */ | |
| 2399 | + pcid = 0; | |
| 2400 | + if (cr4 & X86_CR4_PCIDE) { | |
| 2401 | + pcid = cr3 & 0xfff; | |
| 2402 | + cr3 &= ~0xfff; | |
| 2403 | + } | |
| 2404 | + | |
| 2405 | + bad = ctxt->ops->set_cr(ctxt, 3, cr3); | |
| 2406 | + if (bad) | |
| 2407 | + return X86EMUL_UNHANDLEABLE; | |
| 2396 | 2408 | |
| 2397 | 2409 | /* |
| 2398 | 2410 | * First enable PAE, long mode needs it before CR0.PG = 1 is set. |
| @@ -2411,6 +2423,12 @@ static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt, · 12 unmodified lines | ||
| 2411 | 2423 | bad = ctxt->ops->set_cr(ctxt, 4, cr4); |
| 2412 | 2424 | if (bad) |
| 2413 | 2425 | return X86EMUL_UNHANDLEABLE; |
| 2426 | + if (pcid) { | |
| 2427 | + bad = ctxt->ops->set_cr(ctxt, 3, cr3 | pcid); | |
| 2428 | + if (bad) | |
| 2429 | + return X86EMUL_UNHANDLEABLE; | |
| 2430 | + } | |
| 2431 | + | |
| 2414 | 2432 | } |
| 2415 | 2433 | |
| 2416 | 2434 | return X86EMUL_CONTINUE; |
| @@ -2421,11 +2439,11 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase) · 4 unmodified lines | ||
| 2421 | 2439 | struct desc_struct desc; |
| 2422 | 2440 | struct desc_ptr dt; |
| 2423 | 2441 | u16 selector; |
| 2424 | − u32 val, cr0, cr4; | |
| 2442 | + u32 val, cr0, cr3, cr4; | |
| 2425 | 2443 | int i; |
| 2426 | 2444 | |
| 2427 | 2445 | cr0 = GET_SMSTATE(u32, smbase, 0x7ffc); |
| 2428 | − ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u32, smbase, 0x7ff8)); | |
| 2446 | + cr3 = GET_SMSTATE(u32, smbase, 0x7ff8); | |
| 2429 | 2447 | ctxt->eflags = GET_SMSTATE(u32, smbase, 0x7ff4) | X86_EFLAGS_FIXED; |
| 2430 | 2448 | ctxt->_eip = GET_SMSTATE(u32, smbase, 0x7ff0); |
| 2431 | 2449 | |
| @@ -2467,14 +2485,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase) · 35 unmodified lines | ||
| 2467 | 2485 | |
| 2468 | 2486 | ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7ef8)); |
| 2469 | 2487 | |
| 2470 | − return rsm_enter_protected_mode(ctxt, cr0, cr4); | |
| 2488 | + return rsm_enter_protected_mode(ctxt, cr0, cr3, cr4); | |
| 2471 | 2489 | } |
| 2472 | 2490 | |
| 2473 | 2491 | static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase) |
| 2474 | 2492 | { |
| 2475 | 2493 | struct desc_struct desc; |
| 2476 | 2494 | struct desc_ptr dt; |
| 2477 | − u64 val, cr0, cr4; | |
| 2495 | + u64 val, cr0, cr3, cr4; | |
| 2478 | 2496 | u32 base3; |
| 2479 | 2497 | u16 selector; |
| 2480 | 2498 | int i, r; |
| @@ -2491,7 +2509,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase) · 10 unmodified lines | ||
| 2491 | 2509 | ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1); |
| 2492 | 2510 | |
| 2493 | 2511 | cr0 = GET_SMSTATE(u64, smbase, 0x7f58); |
| 2494 | − ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u64, smbase, 0x7f50)); | |
| 2512 | + cr3 = GET_SMSTATE(u64, smbase, 0x7f50); | |
| 2495 | 2513 | cr4 = GET_SMSTATE(u64, smbase, 0x7f48); |
| 2496 | 2514 | ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7f00)); |
| 2497 | 2515 | val = GET_SMSTATE(u64, smbase, 0x7ed0); |
| @@ -2519,7 +2537,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase) · 21 unmodified lines | ||
| 2519 | 2537 | dt.address = GET_SMSTATE(u64, smbase, 0x7e68); |
| 2520 | 2538 | ctxt->ops->set_gdt(ctxt, &dt); |
| 2521 | 2539 | |
| 2522 | − r = rsm_enter_protected_mode(ctxt, cr0, cr4); | |
| 2540 | + r = rsm_enter_protected_mode(ctxt, cr0, cr3, cr4); | |
| 2523 | 2541 | if (r != X86EMUL_CONTINUE) |
| 2524 | 2542 | return r; |
| 2525 | 2543 | |
| @@ -3395,7 +3395,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) · 3394 unmodified lines | ||
| 3395 | 3395 | spin_lock(&vcpu->kvm->mmu_lock); |
| 3396 | 3396 | if(make_mmu_pages_available(vcpu) < 0) { |
| 3397 | 3397 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 3398 | − return 1; | |
| 3398 | + return -ENOSPC; | |
| 3399 | 3399 | } |
| 3400 | 3400 | sp = kvm_mmu_get_page(vcpu, 0, 0, |
| 3401 | 3401 | vcpu->arch.mmu.shadow_root_level, 1, ACC_ALL); |
| @@ -3410,7 +3410,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) · 8 unmodified lines | ||
| 3410 | 3410 | spin_lock(&vcpu->kvm->mmu_lock); |
| 3411 | 3411 | if (make_mmu_pages_available(vcpu) < 0) { |
| 3412 | 3412 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 3413 | − return 1; | |
| 3413 | + return -ENOSPC; | |
| 3414 | 3414 | } |
| 3415 | 3415 | sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT), |
| 3416 | 3416 | i << 30, PT32_ROOT_LEVEL, 1, ACC_ALL); |
| @@ -3450,7 +3450,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) · 33 unmodified lines | ||
| 3450 | 3450 | spin_lock(&vcpu->kvm->mmu_lock); |
| 3451 | 3451 | if (make_mmu_pages_available(vcpu) < 0) { |
| 3452 | 3452 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 3453 | − return 1; | |
| 3453 | + return -ENOSPC; | |
| 3454 | 3454 | } |
| 3455 | 3455 | sp = kvm_mmu_get_page(vcpu, root_gfn, 0, |
| 3456 | 3456 | vcpu->arch.mmu.shadow_root_level, 0, ACC_ALL); |
| @@ -3487,7 +3487,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) · 30 unmodified lines | ||
| 3487 | 3487 | spin_lock(&vcpu->kvm->mmu_lock); |
| 3488 | 3488 | if (make_mmu_pages_available(vcpu) < 0) { |
| 3489 | 3489 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 3490 | − return 1; | |
| 3490 | + return -ENOSPC; | |
| 3491 | 3491 | } |
| 3492 | 3492 | sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, |
| 3493 | 3493 | 0, ACC_ALL); |
| @@ -2302,7 +2302,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 2301 unmodified lines | ||
| 2302 | 2302 | * processors. See 22.2.4. |
| 2303 | 2303 | */ |
| 2304 | 2304 | vmcs_writel(HOST_TR_BASE, |
| 2305 | − (unsigned long)this_cpu_ptr(&cpu_tss)); | |
| 2305 | + (unsigned long)&get_cpu_entry_area(cpu)->tss.x86_tss); | |
| 2306 | 2306 | vmcs_writel(HOST_GDTR_BASE, (unsigned long)gdt); /* 22.2.4 */ |
| 2307 | 2307 | |
| 2308 | 2308 | /* |
| @@ -4384,7 +4384,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) · 4383 unmodified lines | ||
| 4384 | 4384 | addr, n, v)) |
| 4385 | 4385 | && kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, n, v)) |
| 4386 | 4386 | break; |
| 4387 | − trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v); | |
| 4387 | + trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, v); | |
| 4388 | 4388 | handled += n; |
| 4389 | 4389 | addr += n; |
| 4390 | 4390 | len -= n; |
| @@ -4643,7 +4643,7 @@ static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes) · 252 unmodified lines | ||
| 4643 | 4643 | { |
| 4644 | 4644 | if (vcpu->mmio_read_completed) { |
| 4645 | 4645 | trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, |
| 4646 | − vcpu->mmio_fragments[0].gpa, *(u64 *)val); | |
| 4646 | + vcpu->mmio_fragments[0].gpa, val); | |
| 4647 | 4647 | vcpu->mmio_read_completed = 0; |
| 4648 | 4648 | return 1; |
| 4649 | 4649 | } |
| @@ -4665,14 +4665,14 @@ static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa, · 15 unmodified lines | ||
| 4665 | 4665 | |
| 4666 | 4666 | static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val) |
| 4667 | 4667 | { |
| 4668 | − trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val); | |
| 4668 | + trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, val); | |
| 4669 | 4669 | return vcpu_mmio_write(vcpu, gpa, bytes, val); |
| 4670 | 4670 | } |
| 4671 | 4671 | |
| 4672 | 4672 | static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, |
| 4673 | 4673 | void *val, int bytes) |
| 4674 | 4674 | { |
| 4675 | − trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0); | |
| 4675 | + trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, NULL); | |
| 4676 | 4676 | return X86EMUL_IO_NEEDED; |
| 4677 | 4677 | } |
| 4678 | 4678 | |
| @@ -7264,13 +7264,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) · 2585 unmodified lines | ||
| 7264 | 7264 | |
| 7265 | 7265 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
| 7266 | 7266 | { |
| 7267 | − struct fpu *fpu = ¤t->thread.fpu; | |
| 7268 | 7267 | int r; |
| 7269 | 7268 | |
| 7270 | − fpu__initialize(fpu); | |
| 7271 | − | |
| 7272 | 7269 | kvm_sigset_activate(vcpu); |
| 7273 | 7270 | |
| 7271 | + kvm_load_guest_fpu(vcpu); | |
| 7272 | + | |
| 7274 | 7273 | if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { |
| 7275 | 7274 | if (kvm_run->immediate_exit) { |
| 7276 | 7275 | r = -EINTR; |
| @@ -7296,14 +7295,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · 19 unmodified lines | ||
| 7296 | 7295 | } |
| 7297 | 7296 | } |
| 7298 | 7297 | |
| 7299 | − kvm_load_guest_fpu(vcpu); | |
| 7300 | − | |
| 7301 | 7298 | if (unlikely(vcpu->arch.complete_userspace_io)) { |
| 7302 | 7299 | int (*cui)(struct kvm_vcpu *) = vcpu->arch.complete_userspace_io; |
| 7303 | 7300 | vcpu->arch.complete_userspace_io = NULL; |
| 7304 | 7301 | r = cui(vcpu); |
| 7305 | 7302 | if (r <= 0) |
| 7306 | − goto out_fpu; | |
| 7303 | + goto out; | |
| 7307 | 7304 | } else |
| 7308 | 7305 | WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); |
| 7309 | 7306 | |
| @@ -7312,9 +7309,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · 2 unmodified lines | ||
| 7312 | 7309 | else |
| 7313 | 7310 | r = vcpu_run(vcpu); |
| 7314 | 7311 | |
| 7315 | −out_fpu: | |
| 7316 | − kvm_put_guest_fpu(vcpu); | |
| 7317 | 7312 | out: |
| 7313 | + kvm_put_guest_fpu(vcpu); | |
| 7318 | 7314 | post_kvm_run_save(vcpu); |
| 7319 | 7315 | kvm_sigset_deactivate(vcpu); |
| 7320 | 7316 | |
| @@ -7384,7 +7380,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) · 63 unmodified lines | ||
| 7384 | 7380 | #endif |
| 7385 | 7381 | |
| 7386 | 7382 | kvm_rip_write(vcpu, regs->rip); |
| 7387 | − kvm_set_rflags(vcpu, regs->rflags); | |
| 7383 | + kvm_set_rflags(vcpu, regs->rflags | X86_EFLAGS_FIXED); | |
| 7388 | 7384 | |
| 7389 | 7385 | vcpu->arch.exception.pending = false; |
| 7390 | 7386 | |
| @@ -7498,6 +7494,29 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, · 107 unmodified lines | ||
| 7498 | 7494 | } |
| 7499 | 7495 | EXPORT_SYMBOL_GPL(kvm_task_switch); |
| 7500 | 7496 | |
| 7497 | +int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) | |
| 7498 | +{ | |
| 7499 | + if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG_BIT)) { | |
| 7500 | + /* | |
| 7501 | + * When EFER.LME and CR0.PG are set, the processor is in | |
| 7502 | + * 64-bit mode (though maybe in a 32-bit code segment). | |
| 7503 | + * CR4.PAE and EFER.LMA must be set. | |
| 7504 | + */ | |
| 7505 | + if (!(sregs->cr4 & X86_CR4_PAE_BIT) | |
| 7506 | + || !(sregs->efer & EFER_LMA)) | |
| 7507 | + return -EINVAL; | |
| 7508 | + } else { | |
| 7509 | + /* | |
| 7510 | + * Not in 64-bit mode: EFER.LMA is clear and the code | |
| 7511 | + * segment cannot be 64-bit. | |
| 7512 | + */ | |
| 7513 | + if (sregs->efer & EFER_LMA || sregs->cs.l) | |
| 7514 | + return -EINVAL; | |
| 7515 | + } | |
| 7516 | + | |
| 7517 | + return 0; | |
| 7518 | +} | |
| 7519 | + | |
| 7501 | 7520 | int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, |
| 7502 | 7521 | struct kvm_sregs *sregs) |
| 7503 | 7522 | { |
| @@ -7510,6 +7529,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, · 6 unmodified lines | ||
| 7510 | 7529 | (sregs->cr4 & X86_CR4_OSXSAVE)) |
| 7511 | 7530 | return -EINVAL; |
| 7512 | 7531 | |
| 7532 | + if (kvm_valid_sregs(vcpu, sregs)) | |
| 7533 | + return -EINVAL; | |
| 7534 | + | |
| 7513 | 7535 | apic_base_msr.data = sregs->apic_base; |
| 7514 | 7536 | apic_base_msr.host_initiated = true; |
| 7515 | 7537 | if (kvm_set_apic_base(vcpu, &apic_base_msr)) |
| @@ -107,10 +107,10 @@ static void delay_mwaitx(unsigned long __loops) · 106 unmodified lines | ||
| 107 | 107 | delay = min_t(u64, MWAITX_MAX_LOOPS, loops); |
| 108 | 108 | |
| 109 | 109 | /* |
| 110 | − * Use cpu_tss as a cacheline-aligned, seldomly | |
| 110 | + * Use cpu_tss_rw as a cacheline-aligned, seldomly | |
| 111 | 111 | * accessed per-cpu variable as the monitor target. |
| 112 | 112 | */ |
| 113 | − __monitorx(raw_cpu_ptr(&cpu_tss), 0, 0); | |
| 113 | + __monitorx(raw_cpu_ptr(&cpu_tss_rw), 0, 0); | |
| 114 | 114 | |
| 115 | 115 | /* |
| 116 | 116 | * AMD, like Intel, supports the EAX hint and EAX=0xf |
| @@ -607,7 +607,7 @@ fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) · 606 unmodified lines | ||
| 607 | 607 | fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) |
| 608 | 608 | fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) |
| 609 | 609 | fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) |
| 610 | −ff: | |
| 610 | +ff: UD0 | |
| 611 | 611 | EndTable |
| 612 | 612 | |
| 613 | 613 | Table: 3-byte opcode 1 (0x0f 0x38) |
| @@ -717,7 +717,7 @@ AVXcode: 2 · 103 unmodified lines | ||
| 717 | 717 | 7e: vpermt2d/q Vx,Hx,Wx (66),(ev) |
| 718 | 718 | 7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) |
| 719 | 719 | 80: INVEPT Gy,Mdq (66) |
| 720 | −81: INVPID Gy,Mdq (66) | |
| 720 | +81: INVVPID Gy,Mdq (66) | |
| 721 | 721 | 82: INVPCID Gy,Mdq (66) |
| 722 | 722 | 83: vpmultishiftqb Vx,Hx,Wx (66),(ev) |
| 723 | 723 | 88: vexpandps/d Vpd,Wpd (66),(ev) |
| @@ -970,6 +970,15 @@ GrpTable: Grp9 · 246 unmodified lines | ||
| 970 | 970 | EndTable |
| 971 | 971 | |
| 972 | 972 | GrpTable: Grp10 |
| 973 | +# all are UD1 | |
| 974 | +0: UD1 | |
| 975 | +1: UD1 | |
| 976 | +2: UD1 | |
| 977 | +3: UD1 | |
| 978 | +4: UD1 | |
| 979 | +5: UD1 | |
| 980 | +6: UD1 | |
| 981 | +7: UD1 | |
| 973 | 982 | EndTable |
| 974 | 983 | |
| 975 | 984 | # Grp11A and Grp11B are expressed as Grp11 in Intel SDM |
| @@ -10,7 +10,7 @@ CFLAGS_REMOVE_mem_encrypt.o = -pg · 9 unmodified lines | ||
| 10 | 10 | endif |
| 11 | 11 | |
| 12 | 12 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ |
| 13 | − pat.o pgtable.o physaddr.o setup_nx.o tlb.o | |
| 13 | + pat.o pgtable.o physaddr.o setup_nx.o tlb.o cpu_entry_area.o | |
| 14 | 14 | |
| 15 | 15 | # Make sure __phys_addr has no stackprotector |
| 16 | 16 | nostackp := $(call cc-option, -fno-stack-protector) |
| @@ -41,9 +41,10 @@ obj-$(CONFIG_AMD_NUMA) += amdtopology.o · 24 unmodified lines | ||
| 41 | 41 | obj-$(CONFIG_ACPI_NUMA) += srat.o |
| 42 | 42 | obj-$(CONFIG_NUMA_EMU) += numa_emulation.o |
| 43 | 43 | |
| 44 | −obj-$(CONFIG_X86_INTEL_MPX) += mpx.o | |
| 45 | −obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o | |
| 46 | −obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o | |
| 44 | +obj-$(CONFIG_X86_INTEL_MPX) += mpx.o | |
| 45 | +obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o | |
| 46 | +obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o | |
| 47 | +obj-$(CONFIG_PAGE_TABLE_ISOLATION) += pti.o | |
| 47 | 48 | |
| 48 | 49 | obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt.o |
| 49 | 50 | obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_boot.o |
| @@ -0,0 +1,166 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +#include <linux/spinlock.h> | |
| 4 | +#include <linux/percpu.h> | |
| 5 | + | |
| 6 | +#include <asm/cpu_entry_area.h> | |
| 7 | +#include <asm/pgtable.h> | |
| 8 | +#include <asm/fixmap.h> | |
| 9 | +#include <asm/desc.h> | |
| 10 | + | |
| 11 | +static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage); | |
| 12 | + | |
| 13 | +#ifdef CONFIG_X86_64 | |
| 14 | +static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | |
| 15 | + [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); | |
| 16 | +#endif | |
| 17 | + | |
| 18 | +struct cpu_entry_area *get_cpu_entry_area(int cpu) | |
| 19 | +{ | |
| 20 | + unsigned long va = CPU_ENTRY_AREA_PER_CPU + cpu * CPU_ENTRY_AREA_SIZE; | |
| 21 | + BUILD_BUG_ON(sizeof(struct cpu_entry_area) % PAGE_SIZE != 0); | |
| 22 | + | |
| 23 | + return (struct cpu_entry_area *) va; | |
| 24 | +} | |
| 25 | +EXPORT_SYMBOL(get_cpu_entry_area); | |
| 26 | + | |
| 27 | +void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags) | |
| 28 | +{ | |
| 29 | + unsigned long va = (unsigned long) cea_vaddr; | |
| 30 | + | |
| 31 | + set_pte_vaddr(va, pfn_pte(pa >> PAGE_SHIFT, flags)); | |
| 32 | +} | |
| 33 | + | |
| 34 | +static void __init | |
| 35 | +cea_map_percpu_pages(void *cea_vaddr, void *ptr, int pages, pgprot_t prot) | |
| 36 | +{ | |
| 37 | + for ( ; pages; pages--, cea_vaddr+= PAGE_SIZE, ptr += PAGE_SIZE) | |
| 38 | + cea_set_pte(cea_vaddr, per_cpu_ptr_to_phys(ptr), prot); | |
| 39 | +} | |
| 40 | + | |
| 41 | +static void percpu_setup_debug_store(int cpu) | |
| 42 | +{ | |
| 43 | +#ifdef CONFIG_CPU_SUP_INTEL | |
| 44 | + int npages; | |
| 45 | + void *cea; | |
| 46 | + | |
| 47 | + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | |
| 48 | + return; | |
| 49 | + | |
| 50 | + cea = &get_cpu_entry_area(cpu)->cpu_debug_store; | |
| 51 | + npages = sizeof(struct debug_store) / PAGE_SIZE; | |
| 52 | + BUILD_BUG_ON(sizeof(struct debug_store) % PAGE_SIZE != 0); | |
| 53 | + cea_map_percpu_pages(cea, &per_cpu(cpu_debug_store, cpu), npages, | |
| 54 | + PAGE_KERNEL); | |
| 55 | + | |
| 56 | + cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers; | |
| 57 | + /* | |
| 58 | + * Force the population of PMDs for not yet allocated per cpu | |
| 59 | + * memory like debug store buffers. | |
| 60 | + */ | |
| 61 | + npages = sizeof(struct debug_store_buffers) / PAGE_SIZE; | |
| 62 | + for (; npages; npages--, cea += PAGE_SIZE) | |
| 63 | + cea_set_pte(cea, 0, PAGE_NONE); | |
| 64 | +#endif | |
| 65 | +} | |
| 66 | + | |
| 67 | +/* Setup the fixmap mappings only once per-processor */ | |
| 68 | +static void __init setup_cpu_entry_area(int cpu) | |
| 69 | +{ | |
| 70 | +#ifdef CONFIG_X86_64 | |
| 71 | + extern char _entry_trampoline[]; | |
| 72 | + | |
| 73 | + /* On 64-bit systems, we use a read-only fixmap GDT and TSS. */ | |
| 74 | + pgprot_t gdt_prot = PAGE_KERNEL_RO; | |
| 75 | + pgprot_t tss_prot = PAGE_KERNEL_RO; | |
| 76 | +#else | |
| 77 | + /* | |
| 78 | + * On native 32-bit systems, the GDT cannot be read-only because | |
| 79 | + * our double fault handler uses a task gate, and entering through | |
| 80 | + * a task gate needs to change an available TSS to busy. If the | |
| 81 | + * GDT is read-only, that will triple fault. The TSS cannot be | |
| 82 | + * read-only because the CPU writes to it on task switches. | |
| 83 | + * | |
| 84 | + * On Xen PV, the GDT must be read-only because the hypervisor | |
| 85 | + * requires it. | |
| 86 | + */ | |
| 87 | + pgprot_t gdt_prot = boot_cpu_has(X86_FEATURE_XENPV) ? | |
| 88 | + PAGE_KERNEL_RO : PAGE_KERNEL; | |
| 89 | + pgprot_t tss_prot = PAGE_KERNEL; | |
| 90 | +#endif | |
| 91 | + | |
| 92 | + cea_set_pte(&get_cpu_entry_area(cpu)->gdt, get_cpu_gdt_paddr(cpu), | |
| 93 | + gdt_prot); | |
| 94 | + | |
| 95 | + cea_map_percpu_pages(&get_cpu_entry_area(cpu)->entry_stack_page, | |
| 96 | + per_cpu_ptr(&entry_stack_storage, cpu), 1, | |
| 97 | + PAGE_KERNEL); | |
| 98 | + | |
| 99 | + /* | |
| 100 | + * The Intel SDM says (Volume 3, 7.2.1): | |
| 101 | + * | |
| 102 | + * Avoid placing a page boundary in the part of the TSS that the | |
| 103 | + * processor reads during a task switch (the first 104 bytes). The | |
| 104 | + * processor may not correctly perform address translations if a | |
| 105 | + * boundary occurs in this area. During a task switch, the processor | |
| 106 | + * reads and writes into the first 104 bytes of each TSS (using | |
| 107 | + * contiguous physical addresses beginning with the physical address | |
| 108 | + * of the first byte of the TSS). So, after TSS access begins, if | |
| 109 | + * part of the 104 bytes is not physically contiguous, the processor | |
| 110 | + * will access incorrect information without generating a page-fault | |
| 111 | + * exception. | |
| 112 | + * | |
| 113 | + * There are also a lot of errata involving the TSS spanning a page | |
| 114 | + * boundary. Assert that we're not doing that. | |
| 115 | + */ | |
| 116 | + BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^ | |
| 117 | + offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK); | |
| 118 | + BUILD_BUG_ON(sizeof(struct tss_struct) % PAGE_SIZE != 0); | |
| 119 | + cea_map_percpu_pages(&get_cpu_entry_area(cpu)->tss, | |
| 120 | + &per_cpu(cpu_tss_rw, cpu), | |
| 121 | + sizeof(struct tss_struct) / PAGE_SIZE, tss_prot); | |
| 122 | + | |
| 123 | +#ifdef CONFIG_X86_32 | |
| 124 | + per_cpu(cpu_entry_area, cpu) = get_cpu_entry_area(cpu); | |
| 125 | +#endif | |
| 126 | + | |
| 127 | +#ifdef CONFIG_X86_64 | |
| 128 | + BUILD_BUG_ON(sizeof(exception_stacks) % PAGE_SIZE != 0); | |
| 129 | + BUILD_BUG_ON(sizeof(exception_stacks) != | |
| 130 | + sizeof(((struct cpu_entry_area *)0)->exception_stacks)); | |
| 131 | + cea_map_percpu_pages(&get_cpu_entry_area(cpu)->exception_stacks, | |
| 132 | + &per_cpu(exception_stacks, cpu), | |
| 133 | + sizeof(exception_stacks) / PAGE_SIZE, PAGE_KERNEL); | |
| 134 | + | |
| 135 | + cea_set_pte(&get_cpu_entry_area(cpu)->entry_trampoline, | |
| 136 | + __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX); | |
| 137 | +#endif | |
| 138 | + percpu_setup_debug_store(cpu); | |
| 139 | +} | |
| 140 | + | |
| 141 | +static __init void setup_cpu_entry_area_ptes(void) | |
| 142 | +{ | |
| 143 | +#ifdef CONFIG_X86_32 | |
| 144 | + unsigned long start, end; | |
| 145 | + | |
| 146 | + BUILD_BUG_ON(CPU_ENTRY_AREA_PAGES * PAGE_SIZE < CPU_ENTRY_AREA_MAP_SIZE); | |
| 147 | + BUG_ON(CPU_ENTRY_AREA_BASE & ~PMD_MASK); | |
| 148 | + | |
| 149 | + start = CPU_ENTRY_AREA_BASE; | |
| 150 | + end = start + CPU_ENTRY_AREA_MAP_SIZE; | |
| 151 | + | |
| 152 | + /* Careful here: start + PMD_SIZE might wrap around */ | |
| 153 | + for (; start < end && start >= CPU_ENTRY_AREA_BASE; start += PMD_SIZE) | |
| 154 | + populate_extra_pte(start); | |
| 155 | +#endif | |
| 156 | +} | |
| 157 | + | |
| 158 | +void __init setup_cpu_entry_areas(void) | |
| 159 | +{ | |
| 160 | + unsigned int cpu; | |
| 161 | + | |
| 162 | + setup_cpu_entry_area_ptes(); | |
| 163 | + | |
| 164 | + for_each_possible_cpu(cpu) | |
| 165 | + setup_cpu_entry_area(cpu); | |
| 166 | +} | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | static int ptdump_show(struct seq_file *m, void *v) |
| 7 | 7 | { |
| 8 | − ptdump_walk_pgd_level(m, NULL); | |
| 8 | + ptdump_walk_pgd_level_debugfs(m, NULL, false); | |
| 9 | 9 | return 0; |
| 10 | 10 | } |
| 11 | 11 | |
| @@ -22,21 +22,89 @@ static const struct file_operations ptdump_fops = { · 10 unmodified lines | ||
| 22 | 22 | .release = single_release, |
| 23 | 23 | }; |
| 24 | 24 | |
| 25 | −static struct dentry *pe; | |
| 25 | +static int ptdump_show_curknl(struct seq_file *m, void *v) | |
| 26 | +{ | |
| 27 | + if (current->mm->pgd) { | |
| 28 | + down_read(¤t->mm->mmap_sem); | |
| 29 | + ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false); | |
| 30 | + up_read(¤t->mm->mmap_sem); | |
| 31 | + } | |
| 32 | + return 0; | |
| 33 | +} | |
| 34 | + | |
| 35 | +static int ptdump_open_curknl(struct inode *inode, struct file *filp) | |
| 36 | +{ | |
| 37 | + return single_open(filp, ptdump_show_curknl, NULL); | |
| 38 | +} | |
| 39 | + | |
| 40 | +static const struct file_operations ptdump_curknl_fops = { | |
| 41 | + .owner = THIS_MODULE, | |
| 42 | + .open = ptdump_open_curknl, | |
| 43 | + .read = seq_read, | |
| 44 | + .llseek = seq_lseek, | |
| 45 | + .release = single_release, | |
| 46 | +}; | |
| 47 | + | |
| 48 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 49 | +static struct dentry *pe_curusr; | |
| 50 | + | |
| 51 | +static int ptdump_show_curusr(struct seq_file *m, void *v) | |
| 52 | +{ | |
| 53 | + if (current->mm->pgd) { | |
| 54 | + down_read(¤t->mm->mmap_sem); | |
| 55 | + ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true); | |
| 56 | + up_read(¤t->mm->mmap_sem); | |
| 57 | + } | |
| 58 | + return 0; | |
| 59 | +} | |
| 60 | + | |
| 61 | +static int ptdump_open_curusr(struct inode *inode, struct file *filp) | |
| 62 | +{ | |
| 63 | + return single_open(filp, ptdump_show_curusr, NULL); | |
| 64 | +} | |
| 65 | + | |
| 66 | +static const struct file_operations ptdump_curusr_fops = { | |
| 67 | + .owner = THIS_MODULE, | |
| 68 | + .open = ptdump_open_curusr, | |
| 69 | + .read = seq_read, | |
| 70 | + .llseek = seq_lseek, | |
| 71 | + .release = single_release, | |
| 72 | +}; | |
| 73 | +#endif | |
| 74 | + | |
| 75 | +static struct dentry *dir, *pe_knl, *pe_curknl; | |
| 26 | 76 | |
| 27 | 77 | static int __init pt_dump_debug_init(void) |
| 28 | 78 | { |
| 29 | − pe = debugfs_create_file("kernel_page_tables", S_IRUSR, NULL, NULL, | |
| 30 | − &ptdump_fops); | |
| 31 | − if (!pe) | |
| 79 | + dir = debugfs_create_dir("page_tables", NULL); | |
| 80 | + if (!dir) | |
| 32 | 81 | return -ENOMEM; |
| 33 | 82 | |
| 83 | + pe_knl = debugfs_create_file("kernel", 0400, dir, NULL, | |
| 84 | + &ptdump_fops); | |
| 85 | + if (!pe_knl) | |
| 86 | + goto err; | |
| 87 | + | |
| 88 | + pe_curknl = debugfs_create_file("current_kernel", 0400, | |
| 89 | + dir, NULL, &ptdump_curknl_fops); | |
| 90 | + if (!pe_curknl) | |
| 91 | + goto err; | |
| 92 | + | |
| 93 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 94 | + pe_curusr = debugfs_create_file("current_user", 0400, | |
| 95 | + dir, NULL, &ptdump_curusr_fops); | |
| 96 | + if (!pe_curusr) | |
| 97 | + goto err; | |
| 98 | +#endif | |
| 34 | 99 | return 0; |
| 100 | +err: | |
| 101 | + debugfs_remove_recursive(dir); | |
| 102 | + return -ENOMEM; | |
| 35 | 103 | } |
| 36 | 104 | |
| 37 | 105 | static void __exit pt_dump_debug_exit(void) |
| 38 | 106 | { |
| 39 | − debugfs_remove_recursive(pe); | |
| 107 | + debugfs_remove_recursive(dir); | |
| 40 | 108 | } |
| 41 | 109 | |
| 42 | 110 | module_init(pt_dump_debug_init); |
| @@ -44,68 +44,97 @@ struct addr_marker { · 43 unmodified lines | ||
| 44 | 44 | unsigned long max_lines; |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | −/* indices for address_markers; keep sync'd w/ address_markers below */ | |
| 47 | +/* Address space markers hints */ | |
| 48 | + | |
| 49 | +#ifdef CONFIG_X86_64 | |
| 50 | + | |
| 48 | 51 | enum address_markers_idx { |
| 49 | 52 | USER_SPACE_NR = 0, |
| 50 | −#ifdef CONFIG_X86_64 | |
| 51 | 53 | KERNEL_SPACE_NR, |
| 52 | 54 | LOW_KERNEL_NR, |
| 55 | +#if defined(CONFIG_MODIFY_LDT_SYSCALL) && defined(CONFIG_X86_5LEVEL) | |
| 56 | + LDT_NR, | |
| 57 | +#endif | |
| 53 | 58 | VMALLOC_START_NR, |
| 54 | 59 | VMEMMAP_START_NR, |
| 55 | 60 | #ifdef CONFIG_KASAN |
| 56 | 61 | KASAN_SHADOW_START_NR, |
| 57 | 62 | KASAN_SHADOW_END_NR, |
| 58 | 63 | #endif |
| 59 | −# ifdef CONFIG_X86_ESPFIX64 | |
| 64 | +#if defined(CONFIG_MODIFY_LDT_SYSCALL) && !defined(CONFIG_X86_5LEVEL) | |
| 65 | + LDT_NR, | |
| 66 | +#endif | |
| 67 | + CPU_ENTRY_AREA_NR, | |
| 68 | +#ifdef CONFIG_X86_ESPFIX64 | |
| 60 | 69 | ESPFIX_START_NR, |
| 61 | −# endif | |
| 70 | +#endif | |
| 71 | +#ifdef CONFIG_EFI | |
| 72 | + EFI_END_NR, | |
| 73 | +#endif | |
| 62 | 74 | HIGH_KERNEL_NR, |
| 63 | 75 | MODULES_VADDR_NR, |
| 64 | 76 | MODULES_END_NR, |
| 65 | −#else | |
| 77 | + FIXADDR_START_NR, | |
| 78 | + END_OF_SPACE_NR, | |
| 79 | +}; | |
| 80 | + | |
| 81 | +static struct addr_marker address_markers[] = { | |
| 82 | + [USER_SPACE_NR] = { 0, "User Space" }, | |
| 83 | + [KERNEL_SPACE_NR] = { (1UL << 63), "Kernel Space" }, | |
| 84 | + [LOW_KERNEL_NR] = { 0UL, "Low Kernel Mapping" }, | |
| 85 | + [VMALLOC_START_NR] = { 0UL, "vmalloc() Area" }, | |
| 86 | + [VMEMMAP_START_NR] = { 0UL, "Vmemmap" }, | |
| 87 | +#ifdef CONFIG_KASAN | |
| 88 | + [KASAN_SHADOW_START_NR] = { KASAN_SHADOW_START, "KASAN shadow" }, | |
| 89 | + [KASAN_SHADOW_END_NR] = { KASAN_SHADOW_END, "KASAN shadow end" }, | |
| 90 | +#endif | |
| 91 | +#ifdef CONFIG_MODIFY_LDT_SYSCALL | |
| 92 | + [LDT_NR] = { LDT_BASE_ADDR, "LDT remap" }, | |
| 93 | +#endif | |
| 94 | + [CPU_ENTRY_AREA_NR] = { CPU_ENTRY_AREA_BASE,"CPU entry Area" }, | |
| 95 | +#ifdef CONFIG_X86_ESPFIX64 | |
| 96 | + [ESPFIX_START_NR] = { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, | |
| 97 | +#endif | |
| 98 | +#ifdef CONFIG_EFI | |
| 99 | + [EFI_END_NR] = { EFI_VA_END, "EFI Runtime Services" }, | |
| 100 | +#endif | |
| 101 | + [HIGH_KERNEL_NR] = { __START_KERNEL_map, "High Kernel Mapping" }, | |
| 102 | + [MODULES_VADDR_NR] = { MODULES_VADDR, "Modules" }, | |
| 103 | + [MODULES_END_NR] = { MODULES_END, "End Modules" }, | |
| 104 | + [FIXADDR_START_NR] = { FIXADDR_START, "Fixmap Area" }, | |
| 105 | + [END_OF_SPACE_NR] = { -1, NULL } | |
| 106 | +}; | |
| 107 | + | |
| 108 | +#else /* CONFIG_X86_64 */ | |
| 109 | + | |
| 110 | +enum address_markers_idx { | |
| 111 | + USER_SPACE_NR = 0, | |
| 66 | 112 | KERNEL_SPACE_NR, |
| 67 | 113 | VMALLOC_START_NR, |
| 68 | 114 | VMALLOC_END_NR, |
| 69 | −# ifdef CONFIG_HIGHMEM | |
| 115 | +#ifdef CONFIG_HIGHMEM | |
| 70 | 116 | PKMAP_BASE_NR, |
| 71 | −# endif | |
| 72 | − FIXADDR_START_NR, | |
| 73 | 117 | #endif |
| 118 | + CPU_ENTRY_AREA_NR, | |
| 119 | + FIXADDR_START_NR, | |
| 120 | + END_OF_SPACE_NR, | |
| 74 | 121 | }; |
| 75 | 122 | |
| 76 | −/* Address space markers hints */ | |
| 77 | 123 | static struct addr_marker address_markers[] = { |
| 78 | − { 0, "User Space" }, | |
| 79 | −#ifdef CONFIG_X86_64 | |
| 80 | − { 0x8000000000000000UL, "Kernel Space" }, | |
| 81 | − { 0/* PAGE_OFFSET */, "Low Kernel Mapping" }, | |
| 82 | − { 0/* VMALLOC_START */, "vmalloc() Area" }, | |
| 83 | − { 0/* VMEMMAP_START */, "Vmemmap" }, | |
| 84 | −#ifdef CONFIG_KASAN | |
| 85 | − { KASAN_SHADOW_START, "KASAN shadow" }, | |
| 86 | − { KASAN_SHADOW_END, "KASAN shadow end" }, | |
| 124 | + [USER_SPACE_NR] = { 0, "User Space" }, | |
| 125 | + [KERNEL_SPACE_NR] = { PAGE_OFFSET, "Kernel Mapping" }, | |
| 126 | + [VMALLOC_START_NR] = { 0UL, "vmalloc() Area" }, | |
| 127 | + [VMALLOC_END_NR] = { 0UL, "vmalloc() End" }, | |
| 128 | +#ifdef CONFIG_HIGHMEM | |
| 129 | + [PKMAP_BASE_NR] = { 0UL, "Persistent kmap() Area" }, | |
| 87 | 130 | #endif |
| 88 | −# ifdef CONFIG_X86_ESPFIX64 | |
| 89 | − { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, | |
| 90 | −# endif | |
| 91 | −# ifdef CONFIG_EFI | |
| 92 | − { EFI_VA_END, "EFI Runtime Services" }, | |
| 93 | −# endif | |
| 94 | − { __START_KERNEL_map, "High Kernel Mapping" }, | |
| 95 | − { MODULES_VADDR, "Modules" }, | |
| 96 | − { MODULES_END, "End Modules" }, | |
| 97 | −#else | |
| 98 | − { PAGE_OFFSET, "Kernel Mapping" }, | |
| 99 | − { 0/* VMALLOC_START */, "vmalloc() Area" }, | |
| 100 | − { 0/*VMALLOC_END*/, "vmalloc() End" }, | |
| 101 | −# ifdef CONFIG_HIGHMEM | |
| 102 | − { 0/*PKMAP_BASE*/, "Persistent kmap() Area" }, | |
| 103 | −# endif | |
| 104 | − { 0/*FIXADDR_START*/, "Fixmap Area" }, | |
| 105 | −#endif | |
| 106 | − { -1, NULL } /* End of list */ | |
| 131 | + [CPU_ENTRY_AREA_NR] = { 0UL, "CPU entry area" }, | |
| 132 | + [FIXADDR_START_NR] = { 0UL, "Fixmap area" }, | |
| 133 | + [END_OF_SPACE_NR] = { -1, NULL } | |
| 107 | 134 | }; |
| 108 | 135 | |
| 136 | +#endif /* !CONFIG_X86_64 */ | |
| 137 | + | |
| 109 | 138 | /* Multipliers for offsets within the PTEs */ |
| 110 | 139 | #define PTE_LEVEL_MULT (PAGE_SIZE) |
| 111 | 140 | #define PMD_LEVEL_MULT (PTRS_PER_PTE * PTE_LEVEL_MULT) |
| @@ -140,7 +169,7 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg) · 28 unmodified lines | ||
| 140 | 169 | static const char * const level_name[] = |
| 141 | 170 | { "cr3", "pgd", "p4d", "pud", "pmd", "pte" }; |
| 142 | 171 | |
| 143 | − if (!pgprot_val(prot)) { | |
| 172 | + if (!(pr & _PAGE_PRESENT)) { | |
| 144 | 173 | /* Not present */ |
| 145 | 174 | pt_dump_cont_printf(m, dmsg, " "); |
| 146 | 175 | } else { |
| @@ -447,7 +476,7 @@ static inline bool is_hypervisor_range(int idx) · 300 unmodified lines | ||
| 447 | 476 | } |
| 448 | 477 | |
| 449 | 478 | static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, |
| 450 | − bool checkwx) | |
| 479 | + bool checkwx, bool dmesg) | |
| 451 | 480 | { |
| 452 | 481 | #ifdef CONFIG_X86_64 |
| 453 | 482 | pgd_t *start = (pgd_t *) &init_top_pgt; |
| @@ -460,7 +489,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, · 6 unmodified lines | ||
| 460 | 489 | |
| 461 | 490 | if (pgd) { |
| 462 | 491 | start = pgd; |
| 463 | − st.to_dmesg = true; | |
| 492 | + st.to_dmesg = dmesg; | |
| 464 | 493 | } |
| 465 | 494 | |
| 466 | 495 | st.check_wx = checkwx; |
| @@ -498,13 +527,37 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, · 31 unmodified lines | ||
| 498 | 527 | |
| 499 | 528 | void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd) |
| 500 | 529 | { |
| 501 | − ptdump_walk_pgd_level_core(m, pgd, false); | |
| 530 | + ptdump_walk_pgd_level_core(m, pgd, false, true); | |
| 531 | +} | |
| 532 | + | |
| 533 | +void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user) | |
| 534 | +{ | |
| 535 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 536 | + if (user && static_cpu_has(X86_FEATURE_PTI)) | |
| 537 | + pgd = kernel_to_user_pgdp(pgd); | |
| 538 | +#endif | |
| 539 | + ptdump_walk_pgd_level_core(m, pgd, false, false); | |
| 540 | +} | |
| 541 | +EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs); | |
| 542 | + | |
| 543 | +static void ptdump_walk_user_pgd_level_checkwx(void) | |
| 544 | +{ | |
| 545 | +#ifdef CONFIG_PAGE_TABLE_ISOLATION | |
| 546 | + pgd_t *pgd = (pgd_t *) &init_top_pgt; | |
| 547 | + | |
| 548 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 549 | + return; | |
| 550 | + | |
| 551 | + pr_info("x86/mm: Checking user space page tables\n"); | |
| 552 | + pgd = kernel_to_user_pgdp(pgd); | |
| 553 | + ptdump_walk_pgd_level_core(NULL, pgd, true, false); | |
| 554 | +#endif | |
| 502 | 555 | } |
| 503 | −EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level); | |
| 504 | 556 | |
| 505 | 557 | void ptdump_walk_pgd_level_checkwx(void) |
| 506 | 558 | { |
| 507 | − ptdump_walk_pgd_level_core(NULL, NULL, true); | |
| 559 | + ptdump_walk_pgd_level_core(NULL, NULL, true, false); | |
| 560 | + ptdump_walk_user_pgd_level_checkwx(); | |
| 508 | 561 | } |
| 509 | 562 | |
| 510 | 563 | static int __init pt_dump_init(void) |
| @@ -525,8 +578,8 @@ static int __init pt_dump_init(void) · 14 unmodified lines | ||
| 525 | 578 | address_markers[PKMAP_BASE_NR].start_address = PKMAP_BASE; |
| 526 | 579 | # endif |
| 527 | 580 | address_markers[FIXADDR_START_NR].start_address = FIXADDR_START; |
| 581 | + address_markers[CPU_ENTRY_AREA_NR].start_address = CPU_ENTRY_AREA_BASE; | |
| 528 | 582 | #endif |
| 529 | − | |
| 530 | 583 | return 0; |
| 531 | 584 | } |
| 532 | 585 | __initcall(pt_dump_init); |
| @@ -860,7 +860,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, · 859 unmodified lines | ||
| 860 | 860 | if (!printk_ratelimit()) |
| 861 | 861 | return; |
| 862 | 862 | |
| 863 | − printk("%s%s[%d]: segfault at %lx ip %p sp %p error %lx", | |
| 863 | + printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx", | |
| 864 | 864 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
| 865 | 865 | tsk->comm, task_pid_nr(tsk), address, |
| 866 | 866 | (void *)regs->ip, (void *)regs->sp, error_code); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <asm/kaslr.h> |
| 21 | 21 | #include <asm/hypervisor.h> |
| 22 | 22 | #include <asm/cpufeature.h> |
| 23 | +#include <asm/pti.h> | |
| 23 | 24 | |
| 24 | 25 | /* |
| 25 | 26 | * We need to define the tracepoints somewhere, and tlb.c |
| @@ -160,6 +161,12 @@ struct map_range { · 134 unmodified lines | ||
| 160 | 161 | |
| 161 | 162 | static int page_size_mask; |
| 162 | 163 | |
| 164 | +static void enable_global_pages(void) | |
| 165 | +{ | |
| 166 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 167 | + __supported_pte_mask |= _PAGE_GLOBAL; | |
| 168 | +} | |
| 169 | + | |
| 163 | 170 | static void __init probe_page_size_mask(void) |
| 164 | 171 | { |
| 165 | 172 | /* |
| @@ -177,11 +184,11 @@ static void __init probe_page_size_mask(void) · 11 unmodified lines | ||
| 177 | 184 | cr4_set_bits_and_update_boot(X86_CR4_PSE); |
| 178 | 185 | |
| 179 | 186 | /* Enable PGE if available */ |
| 187 | + __supported_pte_mask &= ~_PAGE_GLOBAL; | |
| 180 | 188 | if (boot_cpu_has(X86_FEATURE_PGE)) { |
| 181 | 189 | cr4_set_bits_and_update_boot(X86_CR4_PGE); |
| 182 | − __supported_pte_mask |= _PAGE_GLOBAL; | |
| 183 | − } else | |
| 184 | − __supported_pte_mask &= ~_PAGE_GLOBAL; | |
| 190 | + enable_global_pages(); | |
| 191 | + } | |
| 185 | 192 | |
| 186 | 193 | /* Enable 1 GB linear kernel mappings if available: */ |
| 187 | 194 | if (direct_gbpages && boot_cpu_has(X86_FEATURE_GBPAGES)) { |
| @@ -194,34 +201,44 @@ static void __init probe_page_size_mask(void) · 6 unmodified lines | ||
| 194 | 201 | |
| 195 | 202 | static void setup_pcid(void) |
| 196 | 203 | { |
| 197 | −#ifdef CONFIG_X86_64 | |
| 198 | − if (boot_cpu_has(X86_FEATURE_PCID)) { | |
| 199 | − if (boot_cpu_has(X86_FEATURE_PGE)) { | |
| 200 | − /* | |
| 201 | − * This can't be cr4_set_bits_and_update_boot() -- | |
| 202 | − * the trampoline code can't handle CR4.PCIDE and | |
| 203 | − * it wouldn't do any good anyway. Despite the name, | |
| 204 | − * cr4_set_bits_and_update_boot() doesn't actually | |
| 205 | − * cause the bits in question to remain set all the | |
| 206 | − * way through the secondary boot asm. | |
| 207 | − * | |
| 208 | − * Instead, we brute-force it and set CR4.PCIDE | |
| 209 | − * manually in start_secondary(). | |
| 210 | − */ | |
| 211 | − cr4_set_bits(X86_CR4_PCIDE); | |
| 212 | − } else { | |
| 213 | − /* | |
| 214 | − * flush_tlb_all(), as currently implemented, won't | |
| 215 | − * work if PCID is on but PGE is not. Since that | |
| 216 | − * combination doesn't exist on real hardware, there's | |
| 217 | − * no reason to try to fully support it, but it's | |
| 218 | − * polite to avoid corrupting data if we're on | |
| 219 | − * an improperly configured VM. | |
| 220 | − */ | |
| 221 | − setup_clear_cpu_cap(X86_FEATURE_PCID); | |
| 222 | − } | |
| 204 | + if (!IS_ENABLED(CONFIG_X86_64)) | |
| 205 | + return; | |
| 206 | + | |
| 207 | + if (!boot_cpu_has(X86_FEATURE_PCID)) | |
| 208 | + return; | |
| 209 | + | |
| 210 | + if (boot_cpu_has(X86_FEATURE_PGE)) { | |
| 211 | + /* | |
| 212 | + * This can't be cr4_set_bits_and_update_boot() -- the | |
| 213 | + * trampoline code can't handle CR4.PCIDE and it wouldn't | |
| 214 | + * do any good anyway. Despite the name, | |
| 215 | + * cr4_set_bits_and_update_boot() doesn't actually cause | |
| 216 | + * the bits in question to remain set all the way through | |
| 217 | + * the secondary boot asm. | |
| 218 | + * | |
| 219 | + * Instead, we brute-force it and set CR4.PCIDE manually in | |
| 220 | + * start_secondary(). | |
| 221 | + */ | |
| 222 | + cr4_set_bits(X86_CR4_PCIDE); | |
| 223 | + | |
| 224 | + /* | |
| 225 | + * INVPCID's single-context modes (2/3) only work if we set | |
| 226 | + * X86_CR4_PCIDE, *and* we INVPCID support. It's unusable | |
| 227 | + * on systems that have X86_CR4_PCIDE clear, or that have | |
| 228 | + * no INVPCID support at all. | |
| 229 | + */ | |
| 230 | + if (boot_cpu_has(X86_FEATURE_INVPCID)) | |
| 231 | + setup_force_cpu_cap(X86_FEATURE_INVPCID_SINGLE); | |
| 232 | + } else { | |
| 233 | + /* | |
| 234 | + * flush_tlb_all(), as currently implemented, won't work if | |
| 235 | + * PCID is on but PGE is not. Since that combination | |
| 236 | + * doesn't exist on real hardware, there's no reason to try | |
| 237 | + * to fully support it, but it's polite to avoid corrupting | |
| 238 | + * data if we're on an improperly configured VM. | |
| 239 | + */ | |
| 240 | + setup_clear_cpu_cap(X86_FEATURE_PCID); | |
| 223 | 241 | } |
| 224 | −#endif | |
| 225 | 242 | } |
| 226 | 243 | |
| 227 | 244 | #ifdef CONFIG_X86_32 |
| @@ -622,6 +639,7 @@ void __init init_mem_mapping(void) · 394 unmodified lines | ||
| 622 | 639 | { |
| 623 | 640 | unsigned long end; |
| 624 | 641 | |
| 642 | + pti_check_boottime_disable(); | |
| 625 | 643 | probe_page_size_mask(); |
| 626 | 644 | setup_pcid(); |
| 627 | 645 | |
| @@ -845,7 +863,7 @@ void __init zone_sizes_init(void) · 217 unmodified lines | ||
| 845 | 863 | free_area_init_nodes(max_zone_pfns); |
| 846 | 864 | } |
| 847 | 865 | |
| 848 | −DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { | |
| 866 | +__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { | |
| 849 | 867 | .loaded_mm = &init_mm, |
| 850 | 868 | .next_asid = 1, |
| 851 | 869 | .cr4 = ~0UL, /* fail hard if we screw up cr4 shadow initialization */ |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #include <asm/setup.h> |
| 51 | 51 | #include <asm/set_memory.h> |
| 52 | 52 | #include <asm/page_types.h> |
| 53 | +#include <asm/cpu_entry_area.h> | |
| 53 | 54 | #include <asm/init.h> |
| 54 | 55 | |
| 55 | 56 | #include "mm_internal.h" |
| @@ -766,6 +767,7 @@ void __init mem_init(void) · 710 unmodified lines | ||
| 766 | 767 | mem_init_print_info(NULL); |
| 767 | 768 | printk(KERN_INFO "virtual kernel memory layout:\n" |
| 768 | 769 | " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" |
| 770 | + " cpu_entry : 0x%08lx - 0x%08lx (%4ld kB)\n" | |
| 769 | 771 | #ifdef CONFIG_HIGHMEM |
| 770 | 772 | " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" |
| 771 | 773 | #endif |
| @@ -777,6 +779,10 @@ void __init mem_init(void) · 5 unmodified lines | ||
| 777 | 779 | FIXADDR_START, FIXADDR_TOP, |
| 778 | 780 | (FIXADDR_TOP - FIXADDR_START) >> 10, |
| 779 | 781 | |
| 782 | + CPU_ENTRY_AREA_BASE, | |
| 783 | + CPU_ENTRY_AREA_BASE + CPU_ENTRY_AREA_MAP_SIZE, | |
| 784 | + CPU_ENTRY_AREA_MAP_SIZE >> 10, | |
| 785 | + | |
| 780 | 786 | #ifdef CONFIG_HIGHMEM |
| 781 | 787 | PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, |
| 782 | 788 | (LAST_PKMAP*PAGE_SIZE) >> 10, |
| @@ -404,11 +404,11 @@ void iounmap(volatile void __iomem *addr) · 403 unmodified lines | ||
| 404 | 404 | return; |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | + mmiotrace_iounmap(addr); | |
| 408 | + | |
| 407 | 409 | addr = (volatile void __iomem *) |
| 408 | 410 | (PAGE_MASK & (unsigned long __force)addr); |
| 409 | 411 | |
| 410 | − mmiotrace_iounmap(addr); | |
| 411 | − | |
| 412 | 412 | /* Use the vm area unlocked, assuming the caller |
| 413 | 413 | ensures there isn't another iounmap for the same address |
| 414 | 414 | in parallel. Reuse of the virtual address is prevented by |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/tlbflush.h> |
| 16 | 16 | #include <asm/sections.h> |
| 17 | 17 | #include <asm/pgtable.h> |
| 18 | +#include <asm/cpu_entry_area.h> | |
| 18 | 19 | |
| 19 | 20 | extern struct range pfn_mapped[E820_MAX_ENTRIES]; |
| 20 | 21 | |
| @@ -277,6 +278,7 @@ void __init kasan_early_init(void) · 256 unmodified lines | ||
| 277 | 278 | void __init kasan_init(void) |
| 278 | 279 | { |
| 279 | 280 | int i; |
| 281 | + void *shadow_cpu_entry_begin, *shadow_cpu_entry_end; | |
| 280 | 282 | |
| 281 | 283 | #ifdef CONFIG_KASAN_INLINE |
| 282 | 284 | register_die_notifier(&kasan_die_notifier); |
| @@ -321,16 +323,33 @@ void __init kasan_init(void) · 38 unmodified lines | ||
| 321 | 323 | map_range(&pfn_mapped[i]); |
| 322 | 324 | } |
| 323 | 325 | |
| 326 | + shadow_cpu_entry_begin = (void *)CPU_ENTRY_AREA_BASE; | |
| 327 | + shadow_cpu_entry_begin = kasan_mem_to_shadow(shadow_cpu_entry_begin); | |
| 328 | + shadow_cpu_entry_begin = (void *)round_down((unsigned long)shadow_cpu_entry_begin, | |
| 329 | + PAGE_SIZE); | |
| 330 | + | |
| 331 | + shadow_cpu_entry_end = (void *)(CPU_ENTRY_AREA_BASE + | |
| 332 | + CPU_ENTRY_AREA_MAP_SIZE); | |
| 333 | + shadow_cpu_entry_end = kasan_mem_to_shadow(shadow_cpu_entry_end); | |
| 334 | + shadow_cpu_entry_end = (void *)round_up((unsigned long)shadow_cpu_entry_end, | |
| 335 | + PAGE_SIZE); | |
| 336 | + | |
| 324 | 337 | kasan_populate_zero_shadow( |
| 325 | 338 | kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM), |
| 326 | − kasan_mem_to_shadow((void *)__START_KERNEL_map)); | |
| 339 | + shadow_cpu_entry_begin); | |
| 340 | + | |
| 341 | + kasan_populate_shadow((unsigned long)shadow_cpu_entry_begin, | |
| 342 | + (unsigned long)shadow_cpu_entry_end, 0); | |
| 343 | + | |
| 344 | + kasan_populate_zero_shadow(shadow_cpu_entry_end, | |
| 345 | + kasan_mem_to_shadow((void *)__START_KERNEL_map)); | |
| 327 | 346 | |
| 328 | 347 | kasan_populate_shadow((unsigned long)kasan_mem_to_shadow(_stext), |
| 329 | 348 | (unsigned long)kasan_mem_to_shadow(_end), |
| 330 | 349 | early_pfn_to_nid(__pa(_stext))); |
| 331 | 350 | |
| 332 | 351 | kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END), |
| 333 | − (void *)KASAN_SHADOW_END); | |
| 352 | + (void *)KASAN_SHADOW_END); | |
| 334 | 353 | |
| 335 | 354 | load_cr3(init_top_pgt); |
| 336 | 355 | __flush_tlb_all(); |
| @@ -435,17 +435,18 @@ int register_kmmio_probe(struct kmmio_probe *p) · 434 unmodified lines | ||
| 435 | 435 | unsigned long flags; |
| 436 | 436 | int ret = 0; |
| 437 | 437 | unsigned long size = 0; |
| 438 | + unsigned long addr = p->addr & PAGE_MASK; | |
| 438 | 439 | const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); |
| 439 | 440 | unsigned int l; |
| 440 | 441 | pte_t *pte; |
| 441 | 442 | |
| 442 | 443 | spin_lock_irqsave(&kmmio_lock, flags); |
| 443 | − if (get_kmmio_probe(p->addr)) { | |
| 444 | + if (get_kmmio_probe(addr)) { | |
| 444 | 445 | ret = -EEXIST; |
| 445 | 446 | goto out; |
| 446 | 447 | } |
| 447 | 448 | |
| 448 | − pte = lookup_address(p->addr, &l); | |
| 449 | + pte = lookup_address(addr, &l); | |
| 449 | 450 | if (!pte) { |
| 450 | 451 | ret = -EINVAL; |
| 451 | 452 | goto out; |
| @@ -454,7 +455,7 @@ int register_kmmio_probe(struct kmmio_probe *p) · 2 unmodified lines | ||
| 454 | 455 | kmmio_count++; |
| 455 | 456 | list_add_rcu(&p->list, &kmmio_probes); |
| 456 | 457 | while (size < size_lim) { |
| 457 | − if (add_kmmio_fault_page(p->addr + size)) | |
| 458 | + if (add_kmmio_fault_page(addr + size)) | |
| 458 | 459 | pr_err("Unable to set page fault.\n"); |
| 459 | 460 | size += page_level_size(l); |
| 460 | 461 | } |
| @@ -528,19 +529,20 @@ void unregister_kmmio_probe(struct kmmio_probe *p) · 67 unmodified lines | ||
| 528 | 529 | { |
| 529 | 530 | unsigned long flags; |
| 530 | 531 | unsigned long size = 0; |
| 532 | + unsigned long addr = p->addr & PAGE_MASK; | |
| 531 | 533 | const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); |
| 532 | 534 | struct kmmio_fault_page *release_list = NULL; |
| 533 | 535 | struct kmmio_delayed_release *drelease; |
| 534 | 536 | unsigned int l; |
| 535 | 537 | pte_t *pte; |
| 536 | 538 | |
| 537 | − pte = lookup_address(p->addr, &l); | |
| 539 | + pte = lookup_address(addr, &l); | |
| 538 | 540 | if (!pte) |
| 539 | 541 | return; |
| 540 | 542 | |
| 541 | 543 | spin_lock_irqsave(&kmmio_lock, flags); |
| 542 | 544 | while (size < size_lim) { |
| 543 | − release_kmmio_fault_page(p->addr + size, &release_list); | |
| 545 | + release_kmmio_fault_page(addr + size, &release_list); | |
| 544 | 546 | size += page_level_size(l); |
| 545 | 547 | } |
| 546 | 548 | list_del_rcu(&p->list); |
| @@ -405,13 +405,13 @@ bool sme_active(void) · 404 unmodified lines | ||
| 405 | 405 | { |
| 406 | 406 | return sme_me_mask && !sev_enabled; |
| 407 | 407 | } |
| 408 | −EXPORT_SYMBOL_GPL(sme_active); | |
| 408 | +EXPORT_SYMBOL(sme_active); | |
| 409 | 409 | |
| 410 | 410 | bool sev_active(void) |
| 411 | 411 | { |
| 412 | 412 | return sme_me_mask && sev_enabled; |
| 413 | 413 | } |
| 414 | −EXPORT_SYMBOL_GPL(sev_active); | |
| 414 | +EXPORT_SYMBOL(sev_active); | |
| 415 | 415 | |
| 416 | 416 | static const struct dma_map_ops sev_dma_ops = { |
| 417 | 417 | .alloc = sev_alloc, |
| @@ -355,14 +355,15 @@ static inline void _pgd_free(pgd_t *pgd) · 354 unmodified lines | ||
| 355 | 355 | kmem_cache_free(pgd_cache, pgd); |
| 356 | 356 | } |
| 357 | 357 | #else |
| 358 | + | |
| 358 | 359 | static inline pgd_t *_pgd_alloc(void) |
| 359 | 360 | { |
| 360 | − return (pgd_t *)__get_free_page(PGALLOC_GFP); | |
| 361 | + return (pgd_t *)__get_free_pages(PGALLOC_GFP, PGD_ALLOCATION_ORDER); | |
| 361 | 362 | } |
| 362 | 363 | |
| 363 | 364 | static inline void _pgd_free(pgd_t *pgd) |
| 364 | 365 | { |
| 365 | − free_page((unsigned long)pgd); | |
| 366 | + free_pages((unsigned long)pgd, PGD_ALLOCATION_ORDER); | |
| 366 | 367 | } |
| 367 | 368 | #endif /* CONFIG_X86_PAE */ |
| 368 | 369 | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/pagemap.h> |
| 11 | 11 | #include <linux/spinlock.h> |
| 12 | 12 | |
| 13 | +#include <asm/cpu_entry_area.h> | |
| 13 | 14 | #include <asm/pgtable.h> |
| 14 | 15 | #include <asm/pgalloc.h> |
| 15 | 16 | #include <asm/fixmap.h> |
| @@ -0,0 +1,387 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright(c) 2017 Intel Corporation. All rights reserved. | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify | |
| 5 | + * it under the terms of version 2 of the GNU General Public License as | |
| 6 | + * published by the Free Software Foundation. | |
| 7 | + * | |
| 8 | + * This program is distributed in the hope that it will be useful, but | |
| 9 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 11 | + * General Public License for more details. | |
| 12 | + * | |
| 13 | + * This code is based in part on work published here: | |
| 14 | + * | |
| 15 | + * https://github.com/IAIK/KAISER | |
| 16 | + * | |
| 17 | + * The original work was written by and and signed off by for the Linux | |
| 18 | + * kernel by: | |
| 19 | + * | |
| 20 | + * Signed-off-by: Richard Fellner <richard.fellner@student.tugraz.at> | |
| 21 | + * Signed-off-by: Moritz Lipp <moritz.lipp@iaik.tugraz.at> | |
| 22 | + * Signed-off-by: Daniel Gruss <daniel.gruss@iaik.tugraz.at> | |
| 23 | + * Signed-off-by: Michael Schwarz <michael.schwarz@iaik.tugraz.at> | |
| 24 | + * | |
| 25 | + * Major changes to the original code by: Dave Hansen <dave.hansen@intel.com> | |
| 26 | + * Mostly rewritten by Thomas Gleixner <tglx@linutronix.de> and | |
| 27 | + * Andy Lutomirsky <luto@amacapital.net> | |
| 28 | + */ | |
| 29 | +#include <linux/kernel.h> | |
| 30 | +#include <linux/errno.h> | |
| 31 | +#include <linux/string.h> | |
| 32 | +#include <linux/types.h> | |
| 33 | +#include <linux/bug.h> | |
| 34 | +#include <linux/init.h> | |
| 35 | +#include <linux/spinlock.h> | |
| 36 | +#include <linux/mm.h> | |
| 37 | +#include <linux/uaccess.h> | |
| 38 | + | |
| 39 | +#include <asm/cpufeature.h> | |
| 40 | +#include <asm/hypervisor.h> | |
| 41 | +#include <asm/vsyscall.h> | |
| 42 | +#include <asm/cmdline.h> | |
| 43 | +#include <asm/pti.h> | |
| 44 | +#include <asm/pgtable.h> | |
| 45 | +#include <asm/pgalloc.h> | |
| 46 | +#include <asm/tlbflush.h> | |
| 47 | +#include <asm/desc.h> | |
| 48 | + | |
| 49 | +#undef pr_fmt | |
| 50 | +#define pr_fmt(fmt) "Kernel/User page tables isolation: " fmt | |
| 51 | + | |
| 52 | +/* Backporting helper */ | |
| 53 | +#ifndef __GFP_NOTRACK | |
| 54 | +#define __GFP_NOTRACK 0 | |
| 55 | +#endif | |
| 56 | + | |
| 57 | +static void __init pti_print_if_insecure(const char *reason) | |
| 58 | +{ | |
| 59 | + if (boot_cpu_has_bug(X86_BUG_CPU_INSECURE)) | |
| 60 | + pr_info("%s\n", reason); | |
| 61 | +} | |
| 62 | + | |
| 63 | +static void __init pti_print_if_secure(const char *reason) | |
| 64 | +{ | |
| 65 | + if (!boot_cpu_has_bug(X86_BUG_CPU_INSECURE)) | |
| 66 | + pr_info("%s\n", reason); | |
| 67 | +} | |
| 68 | + | |
| 69 | +void __init pti_check_boottime_disable(void) | |
| 70 | +{ | |
| 71 | + char arg[5]; | |
| 72 | + int ret; | |
| 73 | + | |
| 74 | + if (hypervisor_is_type(X86_HYPER_XEN_PV)) { | |
| 75 | + pti_print_if_insecure("disabled on XEN PV."); | |
| 76 | + return; | |
| 77 | + } | |
| 78 | + | |
| 79 | + ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg)); | |
| 80 | + if (ret > 0) { | |
| 81 | + if (ret == 3 && !strncmp(arg, "off", 3)) { | |
| 82 | + pti_print_if_insecure("disabled on command line."); | |
| 83 | + return; | |
| 84 | + } | |
| 85 | + if (ret == 2 && !strncmp(arg, "on", 2)) { | |
| 86 | + pti_print_if_secure("force enabled on command line."); | |
| 87 | + goto enable; | |
| 88 | + } | |
| 89 | + if (ret == 4 && !strncmp(arg, "auto", 4)) | |
| 90 | + goto autosel; | |
| 91 | + } | |
| 92 | + | |
| 93 | + if (cmdline_find_option_bool(boot_command_line, "nopti")) { | |
| 94 | + pti_print_if_insecure("disabled on command line."); | |
| 95 | + return; | |
| 96 | + } | |
| 97 | + | |
| 98 | +autosel: | |
| 99 | + if (!boot_cpu_has_bug(X86_BUG_CPU_INSECURE)) | |
| 100 | + return; | |
| 101 | +enable: | |
| 102 | + setup_force_cpu_cap(X86_FEATURE_PTI); | |
| 103 | +} | |
| 104 | + | |
| 105 | +pgd_t __pti_set_user_pgd(pgd_t *pgdp, pgd_t pgd) | |
| 106 | +{ | |
| 107 | + /* | |
| 108 | + * Changes to the high (kernel) portion of the kernelmode page | |
| 109 | + * tables are not automatically propagated to the usermode tables. | |
| 110 | + * | |
| 111 | + * Users should keep in mind that, unlike the kernelmode tables, | |
| 112 | + * there is no vmalloc_fault equivalent for the usermode tables. | |
| 113 | + * Top-level entries added to init_mm's usermode pgd after boot | |
| 114 | + * will not be automatically propagated to other mms. | |
| 115 | + */ | |
| 116 | + if (!pgdp_maps_userspace(pgdp)) | |
| 117 | + return pgd; | |
| 118 | + | |
| 119 | + /* | |
| 120 | + * The user page tables get the full PGD, accessible from | |
| 121 | + * userspace: | |
| 122 | + */ | |
| 123 | + kernel_to_user_pgdp(pgdp)->pgd = pgd.pgd; | |
| 124 | + | |
| 125 | + /* | |
| 126 | + * If this is normal user memory, make it NX in the kernel | |
| 127 | + * pagetables so that, if we somehow screw up and return to | |
| 128 | + * usermode with the kernel CR3 loaded, we'll get a page fault | |
| 129 | + * instead of allowing user code to execute with the wrong CR3. | |
| 130 | + * | |
| 131 | + * As exceptions, we don't set NX if: | |
| 132 | + * - _PAGE_USER is not set. This could be an executable | |
| 133 | + * EFI runtime mapping or something similar, and the kernel | |
| 134 | + * may execute from it | |
| 135 | + * - we don't have NX support | |
| 136 | + * - we're clearing the PGD (i.e. the new pgd is not present). | |
| 137 | + */ | |
| 138 | + if ((pgd.pgd & (_PAGE_USER|_PAGE_PRESENT)) == (_PAGE_USER|_PAGE_PRESENT) && | |
| 139 | + (__supported_pte_mask & _PAGE_NX)) | |
| 140 | + pgd.pgd |= _PAGE_NX; | |
| 141 | + | |
| 142 | + /* return the copy of the PGD we want the kernel to use: */ | |
| 143 | + return pgd; | |
| 144 | +} | |
| 145 | + | |
| 146 | +/* | |
| 147 | + * Walk the user copy of the page tables (optionally) trying to allocate | |
| 148 | + * page table pages on the way down. | |
| 149 | + * | |
| 150 | + * Returns a pointer to a P4D on success, or NULL on failure. | |
| 151 | + */ | |
| 152 | +static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) | |
| 153 | +{ | |
| 154 | + pgd_t *pgd = kernel_to_user_pgdp(pgd_offset_k(address)); | |
| 155 | + gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); | |
| 156 | + | |
| 157 | + if (address < PAGE_OFFSET) { | |
| 158 | + WARN_ONCE(1, "attempt to walk user address\n"); | |
| 159 | + return NULL; | |
| 160 | + } | |
| 161 | + | |
| 162 | + if (pgd_none(*pgd)) { | |
| 163 | + unsigned long new_p4d_page = __get_free_page(gfp); | |
| 164 | + if (!new_p4d_page) | |
| 165 | + return NULL; | |
| 166 | + | |
| 167 | + if (pgd_none(*pgd)) { | |
| 168 | + set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(new_p4d_page))); | |
| 169 | + new_p4d_page = 0; | |
| 170 | + } | |
| 171 | + if (new_p4d_page) | |
| 172 | + free_page(new_p4d_page); | |
| 173 | + } | |
| 174 | + BUILD_BUG_ON(pgd_large(*pgd) != 0); | |
| 175 | + | |
| 176 | + return p4d_offset(pgd, address); | |
| 177 | +} | |
| 178 | + | |
| 179 | +/* | |
| 180 | + * Walk the user copy of the page tables (optionally) trying to allocate | |
| 181 | + * page table pages on the way down. | |
| 182 | + * | |
| 183 | + * Returns a pointer to a PMD on success, or NULL on failure. | |
| 184 | + */ | |
| 185 | +static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) | |
| 186 | +{ | |
| 187 | + gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); | |
| 188 | + p4d_t *p4d = pti_user_pagetable_walk_p4d(address); | |
| 189 | + pud_t *pud; | |
| 190 | + | |
| 191 | + BUILD_BUG_ON(p4d_large(*p4d) != 0); | |
| 192 | + if (p4d_none(*p4d)) { | |
| 193 | + unsigned long new_pud_page = __get_free_page(gfp); | |
| 194 | + if (!new_pud_page) | |
| 195 | + return NULL; | |
| 196 | + | |
| 197 | + if (p4d_none(*p4d)) { | |
| 198 | + set_p4d(p4d, __p4d(_KERNPG_TABLE | __pa(new_pud_page))); | |
| 199 | + new_pud_page = 0; | |
| 200 | + } | |
| 201 | + if (new_pud_page) | |
| 202 | + free_page(new_pud_page); | |
| 203 | + } | |
| 204 | + | |
| 205 | + pud = pud_offset(p4d, address); | |
| 206 | + /* The user page tables do not use large mappings: */ | |
| 207 | + if (pud_large(*pud)) { | |
| 208 | + WARN_ON(1); | |
| 209 | + return NULL; | |
| 210 | + } | |
| 211 | + if (pud_none(*pud)) { | |
| 212 | + unsigned long new_pmd_page = __get_free_page(gfp); | |
| 213 | + if (!new_pmd_page) | |
| 214 | + return NULL; | |
| 215 | + | |
| 216 | + if (pud_none(*pud)) { | |
| 217 | + set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page))); | |
| 218 | + new_pmd_page = 0; | |
| 219 | + } | |
| 220 | + if (new_pmd_page) | |
| 221 | + free_page(new_pmd_page); | |
| 222 | + } | |
| 223 | + | |
| 224 | + return pmd_offset(pud, address); | |
| 225 | +} | |
| 226 | + | |
| 227 | +#ifdef CONFIG_X86_VSYSCALL_EMULATION | |
| 228 | +/* | |
| 229 | + * Walk the shadow copy of the page tables (optionally) trying to allocate | |
| 230 | + * page table pages on the way down. Does not support large pages. | |
| 231 | + * | |
| 232 | + * Note: this is only used when mapping *new* kernel data into the | |
| 233 | + * user/shadow page tables. It is never used for userspace data. | |
| 234 | + * | |
| 235 | + * Returns a pointer to a PTE on success, or NULL on failure. | |
| 236 | + */ | |
| 237 | +static __init pte_t *pti_user_pagetable_walk_pte(unsigned long address) | |
| 238 | +{ | |
| 239 | + gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); | |
| 240 | + pmd_t *pmd = pti_user_pagetable_walk_pmd(address); | |
| 241 | + pte_t *pte; | |
| 242 | + | |
| 243 | + /* We can't do anything sensible if we hit a large mapping. */ | |
| 244 | + if (pmd_large(*pmd)) { | |
| 245 | + WARN_ON(1); | |
| 246 | + return NULL; | |
| 247 | + } | |
| 248 | + | |
| 249 | + if (pmd_none(*pmd)) { | |
| 250 | + unsigned long new_pte_page = __get_free_page(gfp); | |
| 251 | + if (!new_pte_page) | |
| 252 | + return NULL; | |
| 253 | + | |
| 254 | + if (pmd_none(*pmd)) { | |
| 255 | + set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(new_pte_page))); | |
| 256 | + new_pte_page = 0; | |
| 257 | + } | |
| 258 | + if (new_pte_page) | |
| 259 | + free_page(new_pte_page); | |
| 260 | + } | |
| 261 | + | |
| 262 | + pte = pte_offset_kernel(pmd, address); | |
| 263 | + if (pte_flags(*pte) & _PAGE_USER) { | |
| 264 | + WARN_ONCE(1, "attempt to walk to user pte\n"); | |
| 265 | + return NULL; | |
| 266 | + } | |
| 267 | + return pte; | |
| 268 | +} | |
| 269 | + | |
| 270 | +static void __init pti_setup_vsyscall(void) | |
| 271 | +{ | |
| 272 | + pte_t *pte, *target_pte; | |
| 273 | + unsigned int level; | |
| 274 | + | |
| 275 | + pte = lookup_address(VSYSCALL_ADDR, &level); | |
| 276 | + if (!pte || WARN_ON(level != PG_LEVEL_4K) || pte_none(*pte)) | |
| 277 | + return; | |
| 278 | + | |
| 279 | + target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR); | |
| 280 | + if (WARN_ON(!target_pte)) | |
| 281 | + return; | |
| 282 | + | |
| 283 | + *target_pte = *pte; | |
| 284 | + set_vsyscall_pgtable_user_bits(kernel_to_user_pgdp(swapper_pg_dir)); | |
| 285 | +} | |
| 286 | +#else | |
| 287 | +static void __init pti_setup_vsyscall(void) { } | |
| 288 | +#endif | |
| 289 | + | |
| 290 | +static void __init | |
| 291 | +pti_clone_pmds(unsigned long start, unsigned long end, pmdval_t clear) | |
| 292 | +{ | |
| 293 | + unsigned long addr; | |
| 294 | + | |
| 295 | + /* | |
| 296 | + * Clone the populated PMDs which cover start to end. These PMD areas | |
| 297 | + * can have holes. | |
| 298 | + */ | |
| 299 | + for (addr = start; addr < end; addr += PMD_SIZE) { | |
| 300 | + pmd_t *pmd, *target_pmd; | |
| 301 | + pgd_t *pgd; | |
| 302 | + p4d_t *p4d; | |
| 303 | + pud_t *pud; | |
| 304 | + | |
| 305 | + pgd = pgd_offset_k(addr); | |
| 306 | + if (WARN_ON(pgd_none(*pgd))) | |
| 307 | + return; | |
| 308 | + p4d = p4d_offset(pgd, addr); | |
| 309 | + if (WARN_ON(p4d_none(*p4d))) | |
| 310 | + return; | |
| 311 | + pud = pud_offset(p4d, addr); | |
| 312 | + if (pud_none(*pud)) | |
| 313 | + continue; | |
| 314 | + pmd = pmd_offset(pud, addr); | |
| 315 | + if (pmd_none(*pmd)) | |
| 316 | + continue; | |
| 317 | + | |
| 318 | + target_pmd = pti_user_pagetable_walk_pmd(addr); | |
| 319 | + if (WARN_ON(!target_pmd)) | |
| 320 | + return; | |
| 321 | + | |
| 322 | + /* | |
| 323 | + * Copy the PMD. That is, the kernelmode and usermode | |
| 324 | + * tables will share the last-level page tables of this | |
| 325 | + * address range | |
| 326 | + */ | |
| 327 | + *target_pmd = pmd_clear_flags(*pmd, clear); | |
| 328 | + } | |
| 329 | +} | |
| 330 | + | |
| 331 | +/* | |
| 332 | + * Clone a single p4d (i.e. a top-level entry on 4-level systems and a | |
| 333 | + * next-level entry on 5-level systems. | |
| 334 | + */ | |
| 335 | +static void __init pti_clone_p4d(unsigned long addr) | |
| 336 | +{ | |
| 337 | + p4d_t *kernel_p4d, *user_p4d; | |
| 338 | + pgd_t *kernel_pgd; | |
| 339 | + | |
| 340 | + user_p4d = pti_user_pagetable_walk_p4d(addr); | |
| 341 | + kernel_pgd = pgd_offset_k(addr); | |
| 342 | + kernel_p4d = p4d_offset(kernel_pgd, addr); | |
| 343 | + *user_p4d = *kernel_p4d; | |
| 344 | +} | |
| 345 | + | |
| 346 | +/* | |
| 347 | + * Clone the CPU_ENTRY_AREA into the user space visible page table. | |
| 348 | + */ | |
| 349 | +static void __init pti_clone_user_shared(void) | |
| 350 | +{ | |
| 351 | + pti_clone_p4d(CPU_ENTRY_AREA_BASE); | |
| 352 | +} | |
| 353 | + | |
| 354 | +/* | |
| 355 | + * Clone the ESPFIX P4D into the user space visinble page table | |
| 356 | + */ | |
| 357 | +static void __init pti_setup_espfix64(void) | |
| 358 | +{ | |
| 359 | +#ifdef CONFIG_X86_ESPFIX64 | |
| 360 | + pti_clone_p4d(ESPFIX_BASE_ADDR); | |
| 361 | +#endif | |
| 362 | +} | |
| 363 | + | |
| 364 | +/* | |
| 365 | + * Clone the populated PMDs of the entry and irqentry text and force it RO. | |
| 366 | + */ | |
| 367 | +static void __init pti_clone_entry_text(void) | |
| 368 | +{ | |
| 369 | + pti_clone_pmds((unsigned long) __entry_text_start, | |
| 370 | + (unsigned long) __irqentry_text_end, _PAGE_RW); | |
| 371 | +} | |
| 372 | + | |
| 373 | +/* | |
| 374 | + * Initialize kernel page table isolation | |
| 375 | + */ | |
| 376 | +void __init pti_init(void) | |
| 377 | +{ | |
| 378 | + if (!static_cpu_has(X86_FEATURE_PTI)) | |
| 379 | + return; | |
| 380 | + | |
| 381 | + pr_info("enabled\n"); | |
| 382 | + | |
| 383 | + pti_clone_user_shared(); | |
| 384 | + pti_clone_entry_text(); | |
| 385 | + pti_setup_espfix64(); | |
| 386 | + pti_setup_vsyscall(); | |
| 387 | +} | |
| @@ -28,6 +28,38 @@ · 27 unmodified lines | ||
| 28 | 28 | * Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi |
| 29 | 29 | */ |
| 30 | 30 | |
| 31 | +/* | |
| 32 | + * We get here when we do something requiring a TLB invalidation | |
| 33 | + * but could not go invalidate all of the contexts. We do the | |
| 34 | + * necessary invalidation by clearing out the 'ctx_id' which | |
| 35 | + * forces a TLB flush when the context is loaded. | |
| 36 | + */ | |
| 37 | +void clear_asid_other(void) | |
| 38 | +{ | |
| 39 | + u16 asid; | |
| 40 | + | |
| 41 | + /* | |
| 42 | + * This is only expected to be set if we have disabled | |
| 43 | + * kernel _PAGE_GLOBAL pages. | |
| 44 | + */ | |
| 45 | + if (!static_cpu_has(X86_FEATURE_PTI)) { | |
| 46 | + WARN_ON_ONCE(1); | |
| 47 | + return; | |
| 48 | + } | |
| 49 | + | |
| 50 | + for (asid = 0; asid < TLB_NR_DYN_ASIDS; asid++) { | |
| 51 | + /* Do not need to flush the current asid */ | |
| 52 | + if (asid == this_cpu_read(cpu_tlbstate.loaded_mm_asid)) | |
| 53 | + continue; | |
| 54 | + /* | |
| 55 | + * Make sure the next time we go to switch to | |
| 56 | + * this asid, we do a flush: | |
| 57 | + */ | |
| 58 | + this_cpu_write(cpu_tlbstate.ctxs[asid].ctx_id, 0); | |
| 59 | + } | |
| 60 | + this_cpu_write(cpu_tlbstate.invalidate_other, false); | |
| 61 | +} | |
| 62 | + | |
| 31 | 63 | atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1); |
| 32 | 64 | |
| 33 | 65 | |
| @@ -42,6 +74,9 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen, · 8 unmodified lines | ||
| 42 | 74 | return; |
| 43 | 75 | } |
| 44 | 76 | |
| 77 | + if (this_cpu_read(cpu_tlbstate.invalidate_other)) | |
| 78 | + clear_asid_other(); | |
| 79 | + | |
| 45 | 80 | for (asid = 0; asid < TLB_NR_DYN_ASIDS; asid++) { |
| 46 | 81 | if (this_cpu_read(cpu_tlbstate.ctxs[asid].ctx_id) != |
| 47 | 82 | next->context.ctx_id) |
| @@ -65,6 +100,25 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen, · 17 unmodified lines | ||
| 65 | 100 | *need_flush = true; |
| 66 | 101 | } |
| 67 | 102 | |
| 103 | +static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, bool need_flush) | |
| 104 | +{ | |
| 105 | + unsigned long new_mm_cr3; | |
| 106 | + | |
| 107 | + if (need_flush) { | |
| 108 | + invalidate_user_asid(new_asid); | |
| 109 | + new_mm_cr3 = build_cr3(pgdir, new_asid); | |
| 110 | + } else { | |
| 111 | + new_mm_cr3 = build_cr3_noflush(pgdir, new_asid); | |
| 112 | + } | |
| 113 | + | |
| 114 | + /* | |
| 115 | + * Caution: many callers of this function expect | |
| 116 | + * that load_cr3() is serializing and orders TLB | |
| 117 | + * fills with respect to the mm_cpumask writes. | |
| 118 | + */ | |
| 119 | + write_cr3(new_mm_cr3); | |
| 120 | +} | |
| 121 | + | |
| 68 | 122 | void leave_mm(int cpu) |
| 69 | 123 | { |
| 70 | 124 | struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm); |
| @@ -128,7 +182,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 57 unmodified lines | ||
| 128 | 182 | * isn't free. |
| 129 | 183 | */ |
| 130 | 184 | #ifdef CONFIG_DEBUG_VM |
| 131 | − if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev, prev_asid))) { | |
| 185 | + if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev->pgd, prev_asid))) { | |
| 132 | 186 | /* |
| 133 | 187 | * If we were to BUG here, we'd be very likely to kill |
| 134 | 188 | * the system so hard that we don't see the call trace. |
| @@ -195,7 +249,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 60 unmodified lines | ||
| 195 | 249 | if (need_flush) { |
| 196 | 250 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); |
| 197 | 251 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); |
| 198 | − write_cr3(build_cr3(next, new_asid)); | |
| 252 | + load_new_mm_cr3(next->pgd, new_asid, true); | |
| 199 | 253 | |
| 200 | 254 | /* |
| 201 | 255 | * NB: This gets called via leave_mm() in the idle path |
| @@ -208,7 +262,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 6 unmodified lines | ||
| 208 | 262 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); |
| 209 | 263 | } else { |
| 210 | 264 | /* The new ASID is already up to date. */ |
| 211 | − write_cr3(build_cr3_noflush(next, new_asid)); | |
| 265 | + load_new_mm_cr3(next->pgd, new_asid, false); | |
| 212 | 266 | |
| 213 | 267 | /* See above wrt _rcuidle. */ |
| 214 | 268 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0); |
| @@ -288,7 +342,7 @@ void initialize_tlbstate_and_flush(void) · 73 unmodified lines | ||
| 288 | 342 | !(cr4_read_shadow() & X86_CR4_PCIDE)); |
| 289 | 343 | |
| 290 | 344 | /* Force ASID 0 and force a TLB flush. */ |
| 291 | − write_cr3(build_cr3(mm, 0)); | |
| 345 | + write_cr3(build_cr3(mm->pgd, 0)); | |
| 292 | 346 | |
| 293 | 347 | /* Reinitialize tlbstate. */ |
| 294 | 348 | this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0); |
| @@ -551,7 +605,7 @@ static void do_kernel_range_flush(void *info) · 256 unmodified lines | ||
| 551 | 605 | |
| 552 | 606 | /* flush range by one by one 'invlpg' */ |
| 553 | 607 | for (addr = f->start; addr < f->end; addr += PAGE_SIZE) |
| 554 | − __flush_tlb_single(addr); | |
| 608 | + __flush_tlb_one(addr); | |
| 555 | 609 | } |
| 556 | 610 | |
| 557 | 611 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
| @@ -665,6 +665,16 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) · 664 unmodified lines | ||
| 665 | 665 | unsigned i; |
| 666 | 666 | u32 base, limit, high; |
| 667 | 667 | struct resource *res, *conflict; |
| 668 | + struct pci_dev *other; | |
| 669 | + | |
| 670 | + /* Check that we are the only device of that type */ | |
| 671 | + other = pci_get_device(dev->vendor, dev->device, NULL); | |
| 672 | + if (other != dev || | |
| 673 | + (other = pci_get_device(dev->vendor, dev->device, other))) { | |
| 674 | + /* This is a multi-socket system, don't touch it for now */ | |
| 675 | + pci_dev_put(other); | |
| 676 | + return; | |
| 677 | + } | |
| 668 | 678 | |
| 669 | 679 | for (i = 0; i < 8; i++) { |
| 670 | 680 | pci_read_config_dword(dev, AMD_141b_MMIO_BASE(i), &base); |
| @@ -696,8 +706,13 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) · 25 unmodified lines | ||
| 696 | 706 | res->end = 0xfd00000000ull - 1; |
| 697 | 707 | |
| 698 | 708 | /* Just grab the free area behind system memory for this */ |
| 699 | − while ((conflict = request_resource_conflict(&iomem_resource, res))) | |
| 709 | + while ((conflict = request_resource_conflict(&iomem_resource, res))) { | |
| 710 | + if (conflict->end >= res->end) { | |
| 711 | + kfree(res); | |
| 712 | + return; | |
| 713 | + } | |
| 700 | 714 | res->start = conflict->end + 1; |
| 715 | + } | |
| 701 | 716 | |
| 702 | 717 | dev_info(&dev->dev, "adding root bus resource %pR\n", res); |
| 703 | 718 | |
| @@ -714,10 +729,10 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) · 10 unmodified lines | ||
| 714 | 729 | |
| 715 | 730 | pci_bus_add_resource(dev->bus, res, 0); |
| 716 | 731 | } |
| 717 | −DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1401, pci_amd_enable_64bit_bar); | |
| 718 | −DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x141b, pci_amd_enable_64bit_bar); | |
| 719 | −DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar); | |
| 720 | −DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar); | |
| 721 | −DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar); | |
| 732 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1401, pci_amd_enable_64bit_bar); | |
| 733 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x141b, pci_amd_enable_64bit_bar); | |
| 734 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar); | |
| 735 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar); | |
| 736 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar); | |
| 722 | 737 | |
| 723 | 738 | #endif |
| @@ -196,6 +196,9 @@ static pgd_t *efi_pgd; · 195 unmodified lines | ||
| 196 | 196 | * because we want to avoid inserting EFI region mappings (EFI_VA_END |
| 197 | 197 | * to EFI_VA_START) into the standard kernel page tables. Everything |
| 198 | 198 | * else can be shared, see efi_sync_low_kernel_mappings(). |
| 199 | + * | |
| 200 | + * We don't want the pgd on the pgd_list and cannot use pgd_alloc() for the | |
| 201 | + * allocation. | |
| 199 | 202 | */ |
| 200 | 203 | int __init efi_alloc_page_tables(void) |
| 201 | 204 | { |
| @@ -208,7 +211,7 @@ int __init efi_alloc_page_tables(void) · 6 unmodified lines | ||
| 208 | 211 | return 0; |
| 209 | 212 | |
| 210 | 213 | gfp_mask = GFP_KERNEL | __GFP_ZERO; |
| 211 | − efi_pgd = (pgd_t *)__get_free_page(gfp_mask); | |
| 214 | + efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER); | |
| 212 | 215 | if (!efi_pgd) |
| 213 | 216 | return -ENOMEM; |
| 214 | 217 | |
| @@ -299,7 +299,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, · 298 unmodified lines | ||
| 299 | 299 | local_flush_tlb(); |
| 300 | 300 | stat->d_alltlb++; |
| 301 | 301 | } else { |
| 302 | − __flush_tlb_one(msg->address); | |
| 302 | + __flush_tlb_single(msg->address); | |
| 303 | 303 | stat->d_onetlb++; |
| 304 | 304 | } |
| 305 | 305 | stat->d_requestee++; |
| @@ -128,7 +128,7 @@ static void uv_domain_free(struct irq_domain *domain, unsigned int virq, · 127 unmodified lines | ||
| 128 | 128 | * on the specified blade to allow the sending of MSIs to the specified CPU. |
| 129 | 129 | */ |
| 130 | 130 | static int uv_domain_activate(struct irq_domain *domain, |
| 131 | − struct irq_data *irq_data, bool early) | |
| 131 | + struct irq_data *irq_data, bool reserve) | |
| 132 | 132 | { |
| 133 | 133 | uv_program_mmr(irqd_cfg(irq_data), irq_data->chip_data); |
| 134 | 134 | return 0; |
| @@ -82,12 +82,8 @@ static void __save_processor_state(struct saved_context *ctxt) · 81 unmodified lines | ||
| 82 | 82 | /* |
| 83 | 83 | * descriptor tables |
| 84 | 84 | */ |
| 85 | −#ifdef CONFIG_X86_32 | |
| 86 | 85 | store_idt(&ctxt->idt); |
| 87 | −#else | |
| 88 | −/* CONFIG_X86_64 */ | |
| 89 | − store_idt((struct desc_ptr *)&ctxt->idt_limit); | |
| 90 | −#endif | |
| 86 | + | |
| 91 | 87 | /* |
| 92 | 88 | * We save it here, but restore it only in the hibernate case. |
| 93 | 89 | * For ACPI S3 resume, this is loaded via 'early_gdt_desc' in 64-bit |
| @@ -103,22 +99,18 @@ static void __save_processor_state(struct saved_context *ctxt) · 9 unmodified lines | ||
| 103 | 99 | /* |
| 104 | 100 | * segment registers |
| 105 | 101 | */ |
| 106 | −#ifdef CONFIG_X86_32 | |
| 107 | − savesegment(es, ctxt->es); | |
| 108 | − savesegment(fs, ctxt->fs); | |
| 102 | +#ifdef CONFIG_X86_32_LAZY_GS | |
| 109 | 103 | savesegment(gs, ctxt->gs); |
| 110 | − savesegment(ss, ctxt->ss); | |
| 111 | −#else | |
| 112 | −/* CONFIG_X86_64 */ | |
| 113 | − asm volatile ("movw %%ds, %0" : "=m" (ctxt->ds)); | |
| 114 | − asm volatile ("movw %%es, %0" : "=m" (ctxt->es)); | |
| 115 | − asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs)); | |
| 116 | − asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs)); | |
| 117 | − asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss)); | |
| 104 | +#endif | |
| 105 | +#ifdef CONFIG_X86_64 | |
| 106 | + savesegment(gs, ctxt->gs); | |
| 107 | + savesegment(fs, ctxt->fs); | |
| 108 | + savesegment(ds, ctxt->ds); | |
| 109 | + savesegment(es, ctxt->es); | |
| 118 | 110 | |
| 119 | 111 | rdmsrl(MSR_FS_BASE, ctxt->fs_base); |
| 120 | − rdmsrl(MSR_GS_BASE, ctxt->gs_base); | |
| 121 | − rdmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); | |
| 112 | + rdmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); | |
| 113 | + rdmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); | |
| 122 | 114 | mtrr_save_fixed_ranges(NULL); |
| 123 | 115 | |
| 124 | 116 | rdmsrl(MSR_EFER, ctxt->efer); |
| @@ -160,17 +152,19 @@ static void do_fpu_end(void) · 35 unmodified lines | ||
| 160 | 152 | static void fix_processor_context(void) |
| 161 | 153 | { |
| 162 | 154 | int cpu = smp_processor_id(); |
| 163 | − struct tss_struct *t = &per_cpu(cpu_tss, cpu); | |
| 164 | 155 | #ifdef CONFIG_X86_64 |
| 165 | 156 | struct desc_struct *desc = get_cpu_gdt_rw(cpu); |
| 166 | 157 | tss_desc tss; |
| 167 | 158 | #endif |
| 168 | − set_tss_desc(cpu, t); /* | |
| 169 | − * This just modifies memory; should not be | |
| 170 | − * necessary. But... This is necessary, because | |
| 171 | − * 386 hardware has concept of busy TSS or some | |
| 172 | − * similar stupidity. | |
| 173 | − */ | |
| 159 | + | |
| 160 | + /* | |
| 161 | + * We need to reload TR, which requires that we change the | |
| 162 | + * GDT entry to indicate "available" first. | |
| 163 | + * | |
| 164 | + * XXX: This could probably all be replaced by a call to | |
| 165 | + * force_reload_TR(). | |
| 166 | + */ | |
| 167 | + set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); | |
| 174 | 168 | |
| 175 | 169 | #ifdef CONFIG_X86_64 |
| 176 | 170 | memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc)); |
| @@ -178,6 +172,9 @@ static void fix_processor_context(void) · 1 unmodified line | ||
| 178 | 172 | write_gdt_entry(desc, GDT_ENTRY_TSS, &tss, DESC_TSS); |
| 179 | 173 | |
| 180 | 174 | syscall_init(); /* This sets MSR_*STAR and related */ |
| 175 | +#else | |
| 176 | + if (boot_cpu_has(X86_FEATURE_SEP)) | |
| 177 | + enable_sep_cpu(); | |
| 181 | 178 | #endif |
| 182 | 179 | load_TR_desc(); /* This does ltr */ |
| 183 | 180 | load_mm_ldt(current->active_mm); /* This does lldt */ |
| @@ -190,9 +187,12 @@ static void fix_processor_context(void) · 6 unmodified lines | ||
| 190 | 187 | } |
| 191 | 188 | |
| 192 | 189 | /** |
| 193 | − * __restore_processor_state - restore the contents of CPU registers saved | |
| 194 | − * by __save_processor_state() | |
| 195 | − * @ctxt - structure to load the registers contents from | |
| 190 | + * __restore_processor_state - restore the contents of CPU registers saved | |
| 191 | + * by __save_processor_state() | |
| 192 | + * @ctxt - structure to load the registers contents from | |
| 193 | + * | |
| 194 | + * The asm code that gets us here will have restored a usable GDT, although | |
| 195 | + * it will be pointing to the wrong alias. | |
| 196 | 196 | */ |
| 197 | 197 | static void notrace __restore_processor_state(struct saved_context *ctxt) |
| 198 | 198 | { |
| @@ -215,57 +215,50 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) · 16 unmodified lines | ||
| 215 | 215 | write_cr2(ctxt->cr2); |
| 216 | 216 | write_cr0(ctxt->cr0); |
| 217 | 217 | |
| 218 | + /* Restore the IDT. */ | |
| 219 | + load_idt(&ctxt->idt); | |
| 220 | + | |
| 218 | 221 | /* |
| 219 | − * now restore the descriptor tables to their proper values | |
| 220 | − * ltr is done i fix_processor_context(). | |
| 222 | + * Just in case the asm code got us here with the SS, DS, or ES | |
| 223 | + * out of sync with the GDT, update them. | |
| 221 | 224 | */ |
| 222 | −#ifdef CONFIG_X86_32 | |
| 223 | − load_idt(&ctxt->idt); | |
| 224 | −#else | |
| 225 | −/* CONFIG_X86_64 */ | |
| 226 | − load_idt((const struct desc_ptr *)&ctxt->idt_limit); | |
| 227 | −#endif | |
| 225 | + loadsegment(ss, __KERNEL_DS); | |
| 226 | + loadsegment(ds, __USER_DS); | |
| 227 | + loadsegment(es, __USER_DS); | |
| 228 | 228 | |
| 229 | −#ifdef CONFIG_X86_64 | |
| 230 | 229 | /* |
| 231 | − * We need GSBASE restored before percpu access can work. | |
| 232 | − * percpu access can happen in exception handlers or in complicated | |
| 233 | − * helpers like load_gs_index(). | |
| 230 | + * Restore percpu access. Percpu access can happen in exception | |
| 231 | + * handlers or in complicated helpers like load_gs_index(). | |
| 234 | 232 | */ |
| 235 | − wrmsrl(MSR_GS_BASE, ctxt->gs_base); | |
| 233 | +#ifdef CONFIG_X86_64 | |
| 234 | + wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); | |
| 235 | +#else | |
| 236 | + loadsegment(fs, __KERNEL_PERCPU); | |
| 237 | + loadsegment(gs, __KERNEL_STACK_CANARY); | |
| 236 | 238 | #endif |
| 237 | 239 | |
| 240 | + /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */ | |
| 238 | 241 | fix_processor_context(); |
| 239 | 242 | |
| 240 | 243 | /* |
| 241 | − * Restore segment registers. This happens after restoring the GDT | |
| 242 | − * and LDT, which happen in fix_processor_context(). | |
| 244 | + * Now that we have descriptor tables fully restored and working | |
| 245 | + * exception handling, restore the usermode segments. | |
| 243 | 246 | */ |
| 244 | −#ifdef CONFIG_X86_32 | |
| 247 | +#ifdef CONFIG_X86_64 | |
| 248 | + loadsegment(ds, ctxt->es); | |
| 245 | 249 | loadsegment(es, ctxt->es); |
| 246 | 250 | loadsegment(fs, ctxt->fs); |
| 247 | − loadsegment(gs, ctxt->gs); | |
| 248 | − loadsegment(ss, ctxt->ss); | |
| 249 | − | |
| 250 | − /* | |
| 251 | − * sysenter MSRs | |
| 252 | − */ | |
| 253 | − if (boot_cpu_has(X86_FEATURE_SEP)) | |
| 254 | − enable_sep_cpu(); | |
| 255 | −#else | |
| 256 | −/* CONFIG_X86_64 */ | |
| 257 | − asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); | |
| 258 | − asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); | |
| 259 | − asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs)); | |
| 260 | 251 | load_gs_index(ctxt->gs); |
| 261 | − asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); | |
| 262 | 252 | |
| 263 | 253 | /* |
| 264 | − * Restore FSBASE and user GSBASE after reloading the respective | |
| 265 | − * segment selectors. | |
| 254 | + * Restore FSBASE and GSBASE after restoring the selectors, since | |
| 255 | + * restoring the selectors clobbers the bases. Keep in mind | |
| 256 | + * that MSR_KERNEL_GS_BASE is horribly misnamed. | |
| 266 | 257 | */ |
| 267 | 258 | wrmsrl(MSR_FS_BASE, ctxt->fs_base); |
| 268 | − wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); | |
| 259 | + wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); | |
| 260 | +#elif defined(CONFIG_X86_32_LAZY_GS) | |
| 261 | + loadsegment(gs, ctxt->gs); | |
| 269 | 262 | #endif |
| 270 | 263 | |
| 271 | 264 | do_fpu_end(); |
| @@ -57,7 +57,7 @@ static u32 xen_apic_read(u32 reg) · 56 unmodified lines | ||
| 57 | 57 | return 0; |
| 58 | 58 | |
| 59 | 59 | if (reg == APIC_LVR) |
| 60 | − return 0x10; | |
| 60 | + return 0x14; | |
| 61 | 61 | #ifdef CONFIG_X86_32 |
| 62 | 62 | if (reg == APIC_LDR) |
| 63 | 63 | return SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); |
| @@ -1,8 +1,12 @@ | ||
| 1 | +#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | |
| 2 | +#include <linux/bootmem.h> | |
| 3 | +#endif | |
| 1 | 4 | #include <linux/cpu.h> |
| 2 | 5 | #include <linux/kexec.h> |
| 3 | 6 | |
| 4 | 7 | #include <xen/features.h> |
| 5 | 8 | #include <xen/page.h> |
| 9 | +#include <xen/interface/memory.h> | |
| 6 | 10 | |
| 7 | 11 | #include <asm/xen/hypercall.h> |
| 8 | 12 | #include <asm/xen/hypervisor.h> |
| @@ -331,3 +335,80 @@ void xen_arch_unregister_cpu(int num) · 322 unmodified lines | ||
| 331 | 335 | } |
| 332 | 336 | EXPORT_SYMBOL(xen_arch_unregister_cpu); |
| 333 | 337 | #endif |
| 338 | + | |
| 339 | +#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | |
| 340 | +void __init arch_xen_balloon_init(struct resource *hostmem_resource) | |
| 341 | +{ | |
| 342 | + struct xen_memory_map memmap; | |
| 343 | + int rc; | |
| 344 | + unsigned int i, last_guest_ram; | |
| 345 | + phys_addr_t max_addr = PFN_PHYS(max_pfn); | |
| 346 | + struct e820_table *xen_e820_table; | |
| 347 | + const struct e820_entry *entry; | |
| 348 | + struct resource *res; | |
| 349 | + | |
| 350 | + if (!xen_initial_domain()) | |
| 351 | + return; | |
| 352 | + | |
| 353 | + xen_e820_table = kmalloc(sizeof(*xen_e820_table), GFP_KERNEL); | |
| 354 | + if (!xen_e820_table) | |
| 355 | + return; | |
| 356 | + | |
| 357 | + memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries); | |
| 358 | + set_xen_guest_handle(memmap.buffer, xen_e820_table->entries); | |
| 359 | + rc = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap); | |
| 360 | + if (rc) { | |
| 361 | + pr_warn("%s: Can't read host e820 (%d)\n", __func__, rc); | |
| 362 | + goto out; | |
| 363 | + } | |
| 364 | + | |
| 365 | + last_guest_ram = 0; | |
| 366 | + for (i = 0; i < memmap.nr_entries; i++) { | |
| 367 | + if (xen_e820_table->entries[i].addr >= max_addr) | |
| 368 | + break; | |
| 369 | + if (xen_e820_table->entries[i].type == E820_TYPE_RAM) | |
| 370 | + last_guest_ram = i; | |
| 371 | + } | |
| 372 | + | |
| 373 | + entry = &xen_e820_table->entries[last_guest_ram]; | |
| 374 | + if (max_addr >= entry->addr + entry->size) | |
| 375 | + goto out; /* No unallocated host RAM. */ | |
| 376 | + | |
| 377 | + hostmem_resource->start = max_addr; | |
| 378 | + hostmem_resource->end = entry->addr + entry->size; | |
| 379 | + | |
| 380 | + /* | |
| 381 | + * Mark non-RAM regions between the end of dom0 RAM and end of host RAM | |
| 382 | + * as unavailable. The rest of that region can be used for hotplug-based | |
| 383 | + * ballooning. | |
| 384 | + */ | |
| 385 | + for (; i < memmap.nr_entries; i++) { | |
| 386 | + entry = &xen_e820_table->entries[i]; | |
| 387 | + | |
| 388 | + if (entry->type == E820_TYPE_RAM) | |
| 389 | + continue; | |
| 390 | + | |
| 391 | + if (entry->addr >= hostmem_resource->end) | |
| 392 | + break; | |
| 393 | + | |
| 394 | + res = kzalloc(sizeof(*res), GFP_KERNEL); | |
| 395 | + if (!res) | |
| 396 | + goto out; | |
| 397 | + | |
| 398 | + res->name = "Unavailable host RAM"; | |
| 399 | + res->start = entry->addr; | |
| 400 | + res->end = (entry->addr + entry->size < hostmem_resource->end) ? | |
| 401 | + entry->addr + entry->size : hostmem_resource->end; | |
| 402 | + rc = insert_resource(hostmem_resource, res); | |
| 403 | + if (rc) { | |
| 404 | + pr_warn("%s: Can't insert [%llx - %llx) (%d)\n", | |
| 405 | + __func__, res->start, res->end, rc); | |
| 406 | + kfree(res); | |
| 407 | + goto out; | |
| 408 | + } | |
| 409 | + } | |
| 410 | + | |
| 411 | + out: | |
| 412 | + kfree(xen_e820_table); | |
| 413 | +} | |
| 414 | +#endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */ | |
| @@ -88,6 +88,8 @@ · 87 unmodified lines | ||
| 88 | 88 | #include "multicalls.h" |
| 89 | 89 | #include "pmu.h" |
| 90 | 90 | |
| 91 | +#include "../kernel/cpu/cpu.h" /* get_cpu_cap() */ | |
| 92 | + | |
| 91 | 93 | void *xen_initial_gdt; |
| 92 | 94 | |
| 93 | 95 | static int xen_cpu_up_prepare_pv(unsigned int cpu); |
| @@ -826,7 +828,7 @@ static void xen_load_sp0(unsigned long sp0) · 732 unmodified lines | ||
| 826 | 828 | mcs = xen_mc_entry(0); |
| 827 | 829 | MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0); |
| 828 | 830 | xen_mc_issue(PARAVIRT_LAZY_CPU); |
| 829 | − this_cpu_write(cpu_tss.x86_tss.sp0, sp0); | |
| 831 | + this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0); | |
| 830 | 832 | } |
| 831 | 833 | |
| 832 | 834 | void xen_set_iopl_mask(unsigned mask) |
| @@ -1258,6 +1260,7 @@ asmlinkage __visible void __init xen_start_kernel(void) · 425 unmodified lines | ||
| 1258 | 1260 | __userpte_alloc_gfp &= ~__GFP_HIGHMEM; |
| 1259 | 1261 | |
| 1260 | 1262 | /* Work out if we support NX */ |
| 1263 | + get_cpu_cap(&boot_cpu_data); | |
| 1261 | 1264 | x86_configure_nx(); |
| 1262 | 1265 | |
| 1263 | 1266 | /* Get mfn list */ |
| @@ -1902,6 +1902,18 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) · 1901 unmodified lines | ||
| 1902 | 1902 | /* Graft it onto L4[511][510] */ |
| 1903 | 1903 | copy_page(level2_kernel_pgt, l2); |
| 1904 | 1904 | |
| 1905 | + /* | |
| 1906 | + * Zap execute permission from the ident map. Due to the sharing of | |
| 1907 | + * L1 entries we need to do this in the L2. | |
| 1908 | + */ | |
| 1909 | + if (__supported_pte_mask & _PAGE_NX) { | |
| 1910 | + for (i = 0; i < PTRS_PER_PMD; ++i) { | |
| 1911 | + if (pmd_none(level2_ident_pgt[i])) | |
| 1912 | + continue; | |
| 1913 | + level2_ident_pgt[i] = pmd_set_flags(level2_ident_pgt[i], _PAGE_NX); | |
| 1914 | + } | |
| 1915 | + } | |
| 1916 | + | |
| 1905 | 1917 | /* Copy the initial P->M table mappings if necessary. */ |
| 1906 | 1918 | i = pgd_index(xen_start_info->mfn_list); |
| 1907 | 1919 | if (i && i < pgd_index(__START_KERNEL_map)) |
| @@ -2261,7 +2273,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) · 353 unmodified lines | ||
| 2261 | 2273 | |
| 2262 | 2274 | switch (idx) { |
| 2263 | 2275 | case FIX_BTMAP_END ... FIX_BTMAP_BEGIN: |
| 2264 | − case FIX_RO_IDT: | |
| 2265 | 2276 | #ifdef CONFIG_X86_32 |
| 2266 | 2277 | case FIX_WP_TEST: |
| 2267 | 2278 | # ifdef CONFIG_HIGHMEM |
| @@ -2272,7 +2283,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) · 4 unmodified lines | ||
| 2272 | 2283 | #endif |
| 2273 | 2284 | case FIX_TEXT_POKE0: |
| 2274 | 2285 | case FIX_TEXT_POKE1: |
| 2275 | − case FIX_GDT_REMAP_BEGIN ... FIX_GDT_REMAP_END: | |
| 2276 | 2286 | /* All local page mappings */ |
| 2277 | 2287 | pte = pfn_pte(phys, prot); |
| 2278 | 2288 | break; |
| @@ -808,7 +808,6 @@ char * __init xen_memory_setup(void) · 807 unmodified lines | ||
| 808 | 808 | addr = xen_e820_table.entries[0].addr; |
| 809 | 809 | size = xen_e820_table.entries[0].size; |
| 810 | 810 | while (i < xen_e820_table.nr_entries) { |
| 811 | − bool discard = false; | |
| 812 | 811 | |
| 813 | 812 | chunk_size = size; |
| 814 | 813 | type = xen_e820_table.entries[i].type; |
| @@ -824,11 +823,10 @@ char * __init xen_memory_setup(void) · 9 unmodified lines | ||
| 824 | 823 | xen_add_extra_mem(pfn_s, n_pfns); |
| 825 | 824 | xen_max_p2m_pfn = pfn_s + n_pfns; |
| 826 | 825 | } else |
| 827 | − discard = true; | |
| 826 | + type = E820_TYPE_UNUSABLE; | |
| 828 | 827 | } |
| 829 | 828 | |
| 830 | − if (!discard) | |
| 831 | − xen_align_and_add_e820_region(addr, chunk_size, type); | |
| 829 | + xen_align_and_add_e820_region(addr, chunk_size, type); | |
| 832 | 830 | |
| 833 | 831 | addr += chunk_size; |
| 834 | 832 | size -= chunk_size; |
| @@ -599,6 +599,8 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src) · 598 unmodified lines | ||
| 599 | 599 | bio->bi_disk = bio_src->bi_disk; |
| 600 | 600 | bio->bi_partno = bio_src->bi_partno; |
| 601 | 601 | bio_set_flag(bio, BIO_CLONED); |
| 602 | + if (bio_flagged(bio_src, BIO_THROTTLED)) | |
| 603 | + bio_set_flag(bio, BIO_THROTTLED); | |
| 602 | 604 | bio->bi_opf = bio_src->bi_opf; |
| 603 | 605 | bio->bi_write_hint = bio_src->bi_write_hint; |
| 604 | 606 | bio->bi_iter = bio_src->bi_iter; |
| @@ -12,22 +12,29 @@ · 11 unmodified lines | ||
| 12 | 12 | #include "blk.h" |
| 13 | 13 | |
| 14 | 14 | /* |
| 15 | − * Append a bio to a passthrough request. Only works can be merged into | |
| 16 | − * the request based on the driver constraints. | |
| 15 | + * Append a bio to a passthrough request. Only works if the bio can be merged | |
| 16 | + * into the request based on the driver constraints. | |
| 17 | 17 | */ |
| 18 | −int blk_rq_append_bio(struct request *rq, struct bio *bio) | |
| 18 | +int blk_rq_append_bio(struct request *rq, struct bio **bio) | |
| 19 | 19 | { |
| 20 | − blk_queue_bounce(rq->q, &bio); | |
| 20 | + struct bio *orig_bio = *bio; | |
| 21 | + | |
| 22 | + blk_queue_bounce(rq->q, bio); | |
| 21 | 23 | |
| 22 | 24 | if (!rq->bio) { |
| 23 | − blk_rq_bio_prep(rq->q, rq, bio); | |
| 25 | + blk_rq_bio_prep(rq->q, rq, *bio); | |
| 24 | 26 | } else { |
| 25 | − if (!ll_back_merge_fn(rq->q, rq, bio)) | |
| 27 | + if (!ll_back_merge_fn(rq->q, rq, *bio)) { | |
| 28 | + if (orig_bio != *bio) { | |
| 29 | + bio_put(*bio); | |
| 30 | + *bio = orig_bio; | |
| 31 | + } | |
| 26 | 32 | return -EINVAL; |
| 33 | + } | |
| 27 | 34 | |
| 28 | − rq->biotail->bi_next = bio; | |
| 29 | − rq->biotail = bio; | |
| 30 | − rq->__data_len += bio->bi_iter.bi_size; | |
| 35 | + rq->biotail->bi_next = *bio; | |
| 36 | + rq->biotail = *bio; | |
| 37 | + rq->__data_len += (*bio)->bi_iter.bi_size; | |
| 31 | 38 | } |
| 32 | 39 | |
| 33 | 40 | return 0; |
| @@ -73,14 +80,12 @@ static int __blk_rq_map_user_iov(struct request *rq, · 39 unmodified lines | ||
| 73 | 80 | * We link the bounce buffer in and could have to traverse it |
| 74 | 81 | * later so we have to get a ref to prevent it from being freed |
| 75 | 82 | */ |
| 76 | − ret = blk_rq_append_bio(rq, bio); | |
| 77 | − bio_get(bio); | |
| 83 | + ret = blk_rq_append_bio(rq, &bio); | |
| 78 | 84 | if (ret) { |
| 79 | − bio_endio(bio); | |
| 80 | 85 | __blk_rq_unmap_user(orig_bio); |
| 81 | − bio_put(bio); | |
| 82 | 86 | return ret; |
| 83 | 87 | } |
| 88 | + bio_get(bio); | |
| 84 | 89 | |
| 85 | 90 | return 0; |
| 86 | 91 | } |
| @@ -213,7 +218,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, · 126 unmodified lines | ||
| 213 | 218 | int reading = rq_data_dir(rq) == READ; |
| 214 | 219 | unsigned long addr = (unsigned long) kbuf; |
| 215 | 220 | int do_copy = 0; |
| 216 | − struct bio *bio; | |
| 221 | + struct bio *bio, *orig_bio; | |
| 217 | 222 | int ret; |
| 218 | 223 | |
| 219 | 224 | if (len > (queue_max_hw_sectors(q) << 9)) |
| @@ -236,10 +241,11 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, · 16 unmodified lines | ||
| 236 | 241 | if (do_copy) |
| 237 | 242 | rq->rq_flags |= RQF_COPY_USER; |
| 238 | 243 | |
| 239 | − ret = blk_rq_append_bio(rq, bio); | |
| 244 | + orig_bio = bio; | |
| 245 | + ret = blk_rq_append_bio(rq, &bio); | |
| 240 | 246 | if (unlikely(ret)) { |
| 241 | 247 | /* request is too big */ |
| 242 | − bio_put(bio); | |
| 248 | + bio_put(orig_bio); | |
| 243 | 249 | return ret; |
| 244 | 250 | } |
| 245 | 251 | |
| @@ -2226,13 +2226,7 @@ again: · 2225 unmodified lines | ||
| 2226 | 2226 | out_unlock: |
| 2227 | 2227 | spin_unlock_irq(q->queue_lock); |
| 2228 | 2228 | out: |
| 2229 | − /* | |
| 2230 | − * As multiple blk-throtls may stack in the same issue path, we | |
| 2231 | − * don't want bios to leave with the flag set. Clear the flag if | |
| 2232 | − * being issued. | |
| 2233 | − */ | |
| 2234 | − if (!throttled) | |
| 2235 | − bio_clear_flag(bio, BIO_THROTTLED); | |
| 2229 | + bio_set_flag(bio, BIO_THROTTLED); | |
| 2236 | 2230 | |
| 2237 | 2231 | #ifdef CONFIG_BLK_DEV_THROTTLING_LOW |
| 2238 | 2232 | if (throttled || !td->track_bio_latency) |
| @@ -200,6 +200,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, · 199 unmodified lines | ||
| 200 | 200 | unsigned i = 0; |
| 201 | 201 | bool bounce = false; |
| 202 | 202 | int sectors = 0; |
| 203 | + bool passthrough = bio_is_passthrough(*bio_orig); | |
| 203 | 204 | |
| 204 | 205 | bio_for_each_segment(from, *bio_orig, iter) { |
| 205 | 206 | if (i++ < BIO_MAX_PAGES) |
| @@ -210,13 +211,14 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, · 4 unmodified lines | ||
| 210 | 211 | if (!bounce) |
| 211 | 212 | return; |
| 212 | 213 | |
| 213 | − if (sectors < bio_sectors(*bio_orig)) { | |
| 214 | + if (!passthrough && sectors < bio_sectors(*bio_orig)) { | |
| 214 | 215 | bio = bio_split(*bio_orig, sectors, GFP_NOIO, bounce_bio_split); |
| 215 | 216 | bio_chain(bio, *bio_orig); |
| 216 | 217 | generic_make_request(*bio_orig); |
| 217 | 218 | *bio_orig = bio; |
| 218 | 219 | } |
| 219 | − bio = bio_clone_bioset(*bio_orig, GFP_NOIO, bounce_bio_set); | |
| 220 | + bio = bio_clone_bioset(*bio_orig, GFP_NOIO, passthrough ? NULL : | |
| 221 | + bounce_bio_set); | |
| 220 | 222 | |
| 221 | 223 | bio_for_each_segment_all(to, bio, i) { |
| 222 | 224 | struct page *page = to->bv_page; |
| @@ -100,9 +100,13 @@ struct kyber_hctx_data { · 99 unmodified lines | ||
| 100 | 100 | unsigned int cur_domain; |
| 101 | 101 | unsigned int batching; |
| 102 | 102 | wait_queue_entry_t domain_wait[KYBER_NUM_DOMAINS]; |
| 103 | + struct sbq_wait_state *domain_ws[KYBER_NUM_DOMAINS]; | |
| 103 | 104 | atomic_t wait_index[KYBER_NUM_DOMAINS]; |
| 104 | 105 | }; |
| 105 | 106 | |
| 107 | +static int kyber_domain_wake(wait_queue_entry_t *wait, unsigned mode, int flags, | |
| 108 | + void *key); | |
| 109 | + | |
| 106 | 110 | static int rq_sched_domain(const struct request *rq) |
| 107 | 111 | { |
| 108 | 112 | unsigned int op = rq->cmd_flags; |
| @@ -385,6 +389,9 @@ static int kyber_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) · 276 unmodified lines | ||
| 385 | 389 | |
| 386 | 390 | for (i = 0; i < KYBER_NUM_DOMAINS; i++) { |
| 387 | 391 | INIT_LIST_HEAD(&khd->rqs[i]); |
| 392 | + init_waitqueue_func_entry(&khd->domain_wait[i], | |
| 393 | + kyber_domain_wake); | |
| 394 | + khd->domain_wait[i].private = hctx; | |
| 388 | 395 | INIT_LIST_HEAD(&khd->domain_wait[i].entry); |
| 389 | 396 | atomic_set(&khd->wait_index[i], 0); |
| 390 | 397 | } |
| @@ -524,35 +531,39 @@ static int kyber_get_domain_token(struct kyber_queue_data *kqd, · 133 unmodified lines | ||
| 524 | 531 | int nr; |
| 525 | 532 | |
| 526 | 533 | nr = __sbitmap_queue_get(domain_tokens); |
| 527 | − if (nr >= 0) | |
| 528 | − return nr; | |
| 529 | 534 | |
| 530 | 535 | /* |
| 531 | 536 | * If we failed to get a domain token, make sure the hardware queue is |
| 532 | 537 | * run when one becomes available. Note that this is serialized on |
| 533 | 538 | * khd->lock, but we still need to be careful about the waker. |
| 534 | 539 | */ |
| 535 | − if (list_empty_careful(&wait->entry)) { | |
| 536 | − init_waitqueue_func_entry(wait, kyber_domain_wake); | |
| 537 | − wait->private = hctx; | |
| 540 | + if (nr < 0 && list_empty_careful(&wait->entry)) { | |
| 538 | 541 | ws = sbq_wait_ptr(domain_tokens, |
| 539 | 542 | &khd->wait_index[sched_domain]); |
| 543 | + khd->domain_ws[sched_domain] = ws; | |
| 540 | 544 | add_wait_queue(&ws->wait, wait); |
| 541 | 545 | |
| 542 | 546 | /* |
| 543 | 547 | * Try again in case a token was freed before we got on the wait |
| 544 | − * queue. The waker may have already removed the entry from the | |
| 545 | − * wait queue, but list_del_init() is okay with that. | |
| 548 | + * queue. | |
| 546 | 549 | */ |
| 547 | 550 | nr = __sbitmap_queue_get(domain_tokens); |
| 548 | − if (nr >= 0) { | |
| 549 | − unsigned long flags; | |
| 551 | + } | |
| 550 | 552 | |
| 551 | − spin_lock_irqsave(&ws->wait.lock, flags); | |
| 552 | − list_del_init(&wait->entry); | |
| 553 | − spin_unlock_irqrestore(&ws->wait.lock, flags); | |
| 554 | − } | |
| 553 | + /* | |
| 554 | + * If we got a token while we were on the wait queue, remove ourselves | |
| 555 | + * from the wait queue to ensure that all wake ups make forward | |
| 556 | + * progress. It's possible that the waker already deleted the entry | |
| 557 | + * between the !list_empty_careful() check and us grabbing the lock, but | |
| 558 | + * list_del_init() is okay with that. | |
| 559 | + */ | |
| 560 | + if (nr >= 0 && !list_empty_careful(&wait->entry)) { | |
| 561 | + ws = khd->domain_ws[sched_domain]; | |
| 562 | + spin_lock_irq(&ws->wait.lock); | |
| 563 | + list_del_init(&wait->entry); | |
| 564 | + spin_unlock_irq(&ws->wait.lock); | |
| 555 | 565 | } |
| 566 | + | |
| 556 | 567 | return nr; |
| 557 | 568 | } |
| 558 | 569 | |
| @@ -672,14 +672,15 @@ void af_alg_free_areq_sgls(struct af_alg_async_req *areq) · 671 unmodified lines | ||
| 672 | 672 | } |
| 673 | 673 | |
| 674 | 674 | tsgl = areq->tsgl; |
| 675 | − for_each_sg(tsgl, sg, areq->tsgl_entries, i) { | |
| 676 | − if (!sg_page(sg)) | |
| 677 | − continue; | |
| 678 | − put_page(sg_page(sg)); | |
| 679 | − } | |
| 675 | + if (tsgl) { | |
| 676 | + for_each_sg(tsgl, sg, areq->tsgl_entries, i) { | |
| 677 | + if (!sg_page(sg)) | |
| 678 | + continue; | |
| 679 | + put_page(sg_page(sg)); | |
| 680 | + } | |
| 680 | 681 | |
| 681 | − if (areq->tsgl && areq->tsgl_entries) | |
| 682 | 682 | sock_kfree_s(sk, tsgl, areq->tsgl_entries * sizeof(*tsgl)); |
| 683 | + } | |
| 683 | 684 | } |
| 684 | 685 | EXPORT_SYMBOL_GPL(af_alg_free_areq_sgls); |
| 685 | 686 | |
| @@ -1137,12 +1138,6 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, · 451 unmodified lines | ||
| 1137 | 1138 | if (!af_alg_readable(sk)) |
| 1138 | 1139 | break; |
| 1139 | 1140 | |
| 1140 | − if (!ctx->used) { | |
| 1141 | − err = af_alg_wait_for_data(sk, flags); | |
| 1142 | − if (err) | |
| 1143 | − return err; | |
| 1144 | − } | |
| 1145 | − | |
| 1146 | 1141 | seglen = min_t(size_t, (maxsize - len), |
| 1147 | 1142 | msg_data_left(msg)); |
| 1148 | 1143 | |
| @@ -111,6 +111,12 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, · 110 unmodified lines | ||
| 111 | 111 | size_t usedpages = 0; /* [in] RX bufs to be used from user */ |
| 112 | 112 | size_t processed = 0; /* [in] TX bufs to be consumed */ |
| 113 | 113 | |
| 114 | + if (!ctx->used) { | |
| 115 | + err = af_alg_wait_for_data(sk, flags); | |
| 116 | + if (err) | |
| 117 | + return err; | |
| 118 | + } | |
| 119 | + | |
| 114 | 120 | /* |
| 115 | 121 | * Data length provided by caller via sendmsg/sendpage that has not |
| 116 | 122 | * yet been processed. |
| @@ -285,6 +291,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, · 168 unmodified lines | ||
| 285 | 291 | /* AIO operation */ |
| 286 | 292 | sock_hold(sk); |
| 287 | 293 | areq->iocb = msg->msg_iocb; |
| 294 | + | |
| 295 | + /* Remember output size that will be generated. */ | |
| 296 | + areq->outlen = outlen; | |
| 297 | + | |
| 288 | 298 | aead_request_set_callback(&areq->cra_u.aead_req, |
| 289 | 299 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 290 | 300 | af_alg_async_cb, areq); |
| @@ -292,12 +302,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, · 1 unmodified line | ||
| 292 | 302 | crypto_aead_decrypt(&areq->cra_u.aead_req); |
| 293 | 303 | |
| 294 | 304 | /* AIO operation in progress */ |
| 295 | − if (err == -EINPROGRESS || err == -EBUSY) { | |
| 296 | − /* Remember output size that will be generated. */ | |
| 297 | − areq->outlen = outlen; | |
| 298 | − | |
| 305 | + if (err == -EINPROGRESS || err == -EBUSY) | |
| 299 | 306 | return -EIOCBQUEUED; |
| 300 | − } | |
| 301 | 307 | |
| 302 | 308 | sock_put(sk); |
| 303 | 309 | } else { |
| @@ -503,6 +509,7 @@ static void aead_release(void *private) · 199 unmodified lines | ||
| 503 | 509 | struct aead_tfm *tfm = private; |
| 504 | 510 | |
| 505 | 511 | crypto_free_aead(tfm->aead); |
| 512 | + crypto_put_default_null_skcipher2(); | |
| 506 | 513 | kfree(tfm); |
| 507 | 514 | } |
| 508 | 515 | |
| @@ -535,7 +542,6 @@ static void aead_sock_destruct(struct sock *sk) · 26 unmodified lines | ||
| 535 | 542 | unsigned int ivlen = crypto_aead_ivsize(tfm); |
| 536 | 543 | |
| 537 | 544 | af_alg_pull_tsgl(sk, ctx->used, NULL, 0); |
| 538 | − crypto_put_default_null_skcipher2(); | |
| 539 | 545 | sock_kzfree_s(sk, ctx->iv, ivlen); |
| 540 | 546 | sock_kfree_s(sk, ctx, ctx->len); |
| 541 | 547 | af_alg_release_parent(sk); |
| @@ -72,6 +72,12 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, · 71 unmodified lines | ||
| 72 | 72 | int err = 0; |
| 73 | 73 | size_t len = 0; |
| 74 | 74 | |
| 75 | + if (!ctx->used) { | |
| 76 | + err = af_alg_wait_for_data(sk, flags); | |
| 77 | + if (err) | |
| 78 | + return err; | |
| 79 | + } | |
| 80 | + | |
| 75 | 81 | /* Allocate cipher request for current operation. */ |
| 76 | 82 | areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) + |
| 77 | 83 | crypto_skcipher_reqsize(tfm)); |
| @@ -119,6 +125,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, · 41 unmodified lines | ||
| 119 | 125 | /* AIO operation */ |
| 120 | 126 | sock_hold(sk); |
| 121 | 127 | areq->iocb = msg->msg_iocb; |
| 128 | + | |
| 129 | + /* Remember output size that will be generated. */ | |
| 130 | + areq->outlen = len; | |
| 131 | + | |
| 122 | 132 | skcipher_request_set_callback(&areq->cra_u.skcipher_req, |
| 123 | 133 | CRYPTO_TFM_REQ_MAY_SLEEP, |
| 124 | 134 | af_alg_async_cb, areq); |
| @@ -127,12 +137,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, · 2 unmodified lines | ||
| 127 | 137 | crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); |
| 128 | 138 | |
| 129 | 139 | /* AIO operation in progress */ |
| 130 | − if (err == -EINPROGRESS || err == -EBUSY) { | |
| 131 | − /* Remember output size that will be generated. */ | |
| 132 | − areq->outlen = len; | |
| 133 | − | |
| 140 | + if (err == -EINPROGRESS || err == -EBUSY) | |
| 134 | 141 | return -EIOCBQUEUED; |
| 135 | − } | |
| 136 | 142 | |
| 137 | 143 | sock_put(sk); |
| 138 | 144 | } else { |
| @@ -195,11 +195,15 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) · 194 unmodified lines | ||
| 195 | 195 | salg = shash_attr_alg(tb[1], 0, 0); |
| 196 | 196 | if (IS_ERR(salg)) |
| 197 | 197 | return PTR_ERR(salg); |
| 198 | + alg = &salg->base; | |
| 198 | 199 | |
| 200 | + /* The underlying hash algorithm must be unkeyed */ | |
| 199 | 201 | err = -EINVAL; |
| 202 | + if (crypto_shash_alg_has_setkey(salg)) | |
| 203 | + goto out_put_alg; | |
| 204 | + | |
| 200 | 205 | ds = salg->digestsize; |
| 201 | 206 | ss = salg->statesize; |
| 202 | − alg = &salg->base; | |
| 203 | 207 | if (ds > alg->cra_blocksize || |
| 204 | 208 | ss < alg->cra_blocksize) |
| 205 | 209 | goto out_put_alg; |
| @@ -81,6 +81,7 @@ static int mcryptd_init_queue(struct mcryptd_queue *queue, · 80 unmodified lines | ||
| 81 | 81 | pr_debug("cpu_queue #%d %p\n", cpu, queue->cpu_queue); |
| 82 | 82 | crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); |
| 83 | 83 | INIT_WORK(&cpu_queue->work, mcryptd_queue_worker); |
| 84 | + spin_lock_init(&cpu_queue->q_lock); | |
| 84 | 85 | } |
| 85 | 86 | return 0; |
| 86 | 87 | } |
| @@ -104,15 +105,16 @@ static int mcryptd_enqueue_request(struct mcryptd_queue *queue, · 17 unmodified lines | ||
| 104 | 105 | int cpu, err; |
| 105 | 106 | struct mcryptd_cpu_queue *cpu_queue; |
| 106 | 107 | |
| 107 | − cpu = get_cpu(); | |
| 108 | − cpu_queue = this_cpu_ptr(queue->cpu_queue); | |
| 109 | − rctx->tag.cpu = cpu; | |
| 108 | + cpu_queue = raw_cpu_ptr(queue->cpu_queue); | |
| 109 | + spin_lock(&cpu_queue->q_lock); | |
| 110 | + cpu = smp_processor_id(); | |
| 111 | + rctx->tag.cpu = smp_processor_id(); | |
| 110 | 112 | |
| 111 | 113 | err = crypto_enqueue_request(&cpu_queue->queue, request); |
| 112 | 114 | pr_debug("enqueue request: cpu %d cpu_queue %p request %p\n", |
| 113 | 115 | cpu, cpu_queue, request); |
| 116 | + spin_unlock(&cpu_queue->q_lock); | |
| 114 | 117 | queue_work_on(cpu, kcrypto_wq, &cpu_queue->work); |
| 115 | − put_cpu(); | |
| 116 | 118 | |
| 117 | 119 | return err; |
| 118 | 120 | } |
| @@ -161,16 +163,11 @@ static void mcryptd_queue_worker(struct work_struct *work) · 42 unmodified lines | ||
| 161 | 163 | cpu_queue = container_of(work, struct mcryptd_cpu_queue, work); |
| 162 | 164 | i = 0; |
| 163 | 165 | while (i < MCRYPTD_BATCH || single_task_running()) { |
| 164 | − /* | |
| 165 | − * preempt_disable/enable is used to prevent | |
| 166 | − * being preempted by mcryptd_enqueue_request() | |
| 167 | − */ | |
| 168 | − local_bh_disable(); | |
| 169 | − preempt_disable(); | |
| 166 | + | |
| 167 | + spin_lock_bh(&cpu_queue->q_lock); | |
| 170 | 168 | backlog = crypto_get_backlog(&cpu_queue->queue); |
| 171 | 169 | req = crypto_dequeue_request(&cpu_queue->queue); |
| 172 | − preempt_enable(); | |
| 173 | − local_bh_enable(); | |
| 170 | + spin_unlock_bh(&cpu_queue->q_lock); | |
| 174 | 171 | |
| 175 | 172 | if (!req) { |
| 176 | 173 | mcryptd_opportunistic_flush(); |
| @@ -185,7 +182,7 @@ static void mcryptd_queue_worker(struct work_struct *work) · 8 unmodified lines | ||
| 185 | 182 | ++i; |
| 186 | 183 | } |
| 187 | 184 | if (cpu_queue->queue.qlen) |
| 188 | − queue_work(kcrypto_wq, &cpu_queue->work); | |
| 185 | + queue_work_on(smp_processor_id(), kcrypto_wq, &cpu_queue->work); | |
| 189 | 186 | } |
| 190 | 187 | |
| 191 | 188 | void mcryptd_flusher(struct work_struct *__work) |
| @@ -30,7 +30,7 @@ int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, · 29 unmodified lines | ||
| 30 | 30 | return -EINVAL; |
| 31 | 31 | |
| 32 | 32 | if (fips_enabled) { |
| 33 | − while (!*ptr && n_sz) { | |
| 33 | + while (n_sz && !*ptr) { | |
| 34 | 34 | ptr++; |
| 35 | 35 | n_sz--; |
| 36 | 36 | } |
| @@ -188,13 +188,6 @@ static int encrypt(struct blkcipher_desc *desc, · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | salsa20_ivsetup(ctx, walk.iv); |
| 190 | 190 | |
| 191 | − if (likely(walk.nbytes == nbytes)) | |
| 192 | − { | |
| 193 | − salsa20_encrypt_bytes(ctx, walk.dst.virt.addr, | |
| 194 | − walk.src.virt.addr, nbytes); | |
| 195 | − return blkcipher_walk_done(desc, &walk, 0); | |
| 196 | − } | |
| 197 | − | |
| 198 | 191 | while (walk.nbytes >= 64) { |
| 199 | 192 | salsa20_encrypt_bytes(ctx, walk.dst.virt.addr, |
| 200 | 193 | walk.src.virt.addr, |
| @@ -25,11 +25,12 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | static const struct crypto_type crypto_shash_type; |
| 27 | 27 | |
| 28 | −static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, | |
| 29 | − unsigned int keylen) | |
| 28 | +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, | |
| 29 | + unsigned int keylen) | |
| 30 | 30 | { |
| 31 | 31 | return -ENOSYS; |
| 32 | 32 | } |
| 33 | +EXPORT_SYMBOL_GPL(shash_no_setkey); | |
| 33 | 34 | |
| 34 | 35 | static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, |
| 35 | 36 | unsigned int keylen) |
| @@ -449,6 +449,8 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk, · 448 unmodified lines | ||
| 449 | 449 | |
| 450 | 450 | walk->total = req->cryptlen; |
| 451 | 451 | walk->nbytes = 0; |
| 452 | + walk->iv = req->iv; | |
| 453 | + walk->oiv = req->iv; | |
| 452 | 454 | |
| 453 | 455 | if (unlikely(!walk->total)) |
| 454 | 456 | return 0; |
| @@ -456,9 +458,6 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk, · 1 unmodified line | ||
| 456 | 458 | scatterwalk_start(&walk->in, req->src); |
| 457 | 459 | scatterwalk_start(&walk->out, req->dst); |
| 458 | 460 | |
| 459 | − walk->iv = req->iv; | |
| 460 | − walk->oiv = req->iv; | |
| 461 | − | |
| 462 | 461 | walk->flags &= ~SKCIPHER_WALK_SLEEP; |
| 463 | 462 | walk->flags |= req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? |
| 464 | 463 | SKCIPHER_WALK_SLEEP : 0; |
| @@ -510,6 +509,8 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk, · 45 unmodified lines | ||
| 510 | 509 | int err; |
| 511 | 510 | |
| 512 | 511 | walk->nbytes = 0; |
| 512 | + walk->iv = req->iv; | |
| 513 | + walk->oiv = req->iv; | |
| 513 | 514 | |
| 514 | 515 | if (unlikely(!walk->total)) |
| 515 | 516 | return 0; |
| @@ -525,9 +526,6 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk, · 9 unmodified lines | ||
| 525 | 526 | scatterwalk_done(&walk->in, 0, walk->total); |
| 526 | 527 | scatterwalk_done(&walk->out, 0, walk->total); |
| 527 | 528 | |
| 528 | − walk->iv = req->iv; | |
| 529 | − walk->oiv = req->iv; | |
| 530 | − | |
| 531 | 529 | if (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) |
| 532 | 530 | walk->flags |= SKCIPHER_WALK_SLEEP; |
| 533 | 531 | else |
| @@ -1007,7 +1007,7 @@ skip: · 1006 unmodified lines | ||
| 1007 | 1007 | /* The record may be cleared by others, try read next record */ |
| 1008 | 1008 | if (len == -ENOENT) |
| 1009 | 1009 | goto skip; |
| 1010 | − else if (len < sizeof(*rcd)) { | |
| 1010 | + else if (len < 0 || len < sizeof(*rcd)) { | |
| 1011 | 1011 | rc = -EIO; |
| 1012 | 1012 | goto out; |
| 1013 | 1013 | } |
| @@ -1171,7 +1171,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) · 1170 unmodified lines | ||
| 1171 | 1171 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); |
| 1172 | 1172 | struct cpc_register_resource *desired_reg; |
| 1173 | 1173 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); |
| 1174 | − struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | |
| 1174 | + struct cppc_pcc_data *pcc_ss_data; | |
| 1175 | 1175 | int ret = 0; |
| 1176 | 1176 | |
| 1177 | 1177 | if (!cpc_desc || pcc_ss_id < 0) { |
| @@ -1138,7 +1138,7 @@ int acpi_subsys_thaw_noirq(struct device *dev) · 1137 unmodified lines | ||
| 1138 | 1138 | * skip all of the subsequent "thaw" callbacks for the device. |
| 1139 | 1139 | */ |
| 1140 | 1140 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
| 1141 | − dev->power.direct_complete = true; | |
| 1141 | + dev_pm_skip_next_resume_phases(dev); | |
| 1142 | 1142 | return 0; |
| 1143 | 1143 | } |
| 1144 | 1144 | |
| @@ -1670,6 +1670,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, · 1669 unmodified lines | ||
| 1670 | 1670 | dev_name(&adev_dimm->dev)); |
| 1671 | 1671 | return -ENXIO; |
| 1672 | 1672 | } |
| 1673 | + /* | |
| 1674 | + * Record nfit_mem for the notification path to track back to | |
| 1675 | + * the nfit sysfs attributes for this dimm device object. | |
| 1676 | + */ | |
| 1677 | + dev_set_drvdata(&adev_dimm->dev, nfit_mem); | |
| 1673 | 1678 | |
| 1674 | 1679 | /* |
| 1675 | 1680 | * Until standardization materializes we need to consider 4 |
| @@ -1752,9 +1757,11 @@ static void shutdown_dimm_notify(void *data) · 76 unmodified lines | ||
| 1752 | 1757 | sysfs_put(nfit_mem->flags_attr); |
| 1753 | 1758 | nfit_mem->flags_attr = NULL; |
| 1754 | 1759 | } |
| 1755 | − if (adev_dimm) | |
| 1760 | + if (adev_dimm) { | |
| 1756 | 1761 | acpi_remove_notify_handler(adev_dimm->handle, |
| 1757 | 1762 | ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); |
| 1763 | + dev_set_drvdata(&adev_dimm->dev, NULL); | |
| 1764 | + } | |
| 1758 | 1765 | } |
| 1759 | 1766 | mutex_unlock(&acpi_desc->init_mutex); |
| 1760 | 1767 | } |
| @@ -482,7 +482,8 @@ enum binder_deferred_state { · 481 unmodified lines | ||
| 482 | 482 | * @tsk task_struct for group_leader of process |
| 483 | 483 | * (invariant after initialized) |
| 484 | 484 | * @files files_struct for process |
| 485 | − * (invariant after initialized) | |
| 485 | + * (protected by @files_lock) | |
| 486 | + * @files_lock mutex to protect @files | |
| 486 | 487 | * @deferred_work_node: element for binder_deferred_list |
| 487 | 488 | * (protected by binder_deferred_lock) |
| 488 | 489 | * @deferred_work: bitmap of deferred work to perform |
| @@ -530,6 +531,7 @@ struct binder_proc { · 41 unmodified lines | ||
| 530 | 531 | int pid; |
| 531 | 532 | struct task_struct *tsk; |
| 532 | 533 | struct files_struct *files; |
| 534 | + struct mutex files_lock; | |
| 533 | 535 | struct hlist_node deferred_work_node; |
| 534 | 536 | int deferred_work; |
| 535 | 537 | bool is_dead; |
| @@ -924,20 +926,26 @@ static void binder_inc_node_tmpref_ilocked(struct binder_node *node); · 388 unmodified lines | ||
| 924 | 926 | |
| 925 | 927 | static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
| 926 | 928 | { |
| 927 | − struct files_struct *files = proc->files; | |
| 928 | 929 | unsigned long rlim_cur; |
| 929 | 930 | unsigned long irqs; |
| 931 | + int ret; | |
| 930 | 932 | |
| 931 | − if (files == NULL) | |
| 932 | − return -ESRCH; | |
| 933 | − | |
| 934 | − if (!lock_task_sighand(proc->tsk, &irqs)) | |
| 935 | − return -EMFILE; | |
| 936 | − | |
| 933 | + mutex_lock(&proc->files_lock); | |
| 934 | + if (proc->files == NULL) { | |
| 935 | + ret = -ESRCH; | |
| 936 | + goto err; | |
| 937 | + } | |
| 938 | + if (!lock_task_sighand(proc->tsk, &irqs)) { | |
| 939 | + ret = -EMFILE; | |
| 940 | + goto err; | |
| 941 | + } | |
| 937 | 942 | rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); |
| 938 | 943 | unlock_task_sighand(proc->tsk, &irqs); |
| 939 | 944 | |
| 940 | − return __alloc_fd(files, 0, rlim_cur, flags); | |
| 945 | + ret = __alloc_fd(proc->files, 0, rlim_cur, flags); | |
| 946 | +err: | |
| 947 | + mutex_unlock(&proc->files_lock); | |
| 948 | + return ret; | |
| 941 | 949 | } |
| 942 | 950 | |
| 943 | 951 | /* |
| @@ -946,8 +954,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) · 2 unmodified lines | ||
| 946 | 954 | static void task_fd_install( |
| 947 | 955 | struct binder_proc *proc, unsigned int fd, struct file *file) |
| 948 | 956 | { |
| 957 | + mutex_lock(&proc->files_lock); | |
| 949 | 958 | if (proc->files) |
| 950 | 959 | __fd_install(proc->files, fd, file); |
| 960 | + mutex_unlock(&proc->files_lock); | |
| 951 | 961 | } |
| 952 | 962 | |
| 953 | 963 | /* |
| @@ -957,9 +967,11 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) · 3 unmodified lines | ||
| 957 | 967 | { |
| 958 | 968 | int retval; |
| 959 | 969 | |
| 960 | − if (proc->files == NULL) | |
| 961 | − return -ESRCH; | |
| 962 | − | |
| 970 | + mutex_lock(&proc->files_lock); | |
| 971 | + if (proc->files == NULL) { | |
| 972 | + retval = -ESRCH; | |
| 973 | + goto err; | |
| 974 | + } | |
| 963 | 975 | retval = __close_fd(proc->files, fd); |
| 964 | 976 | /* can't restart close syscall because file table entry was cleared */ |
| 965 | 977 | if (unlikely(retval == -ERESTARTSYS || |
| @@ -967,7 +979,8 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) · 1 unmodified line | ||
| 967 | 979 | retval == -ERESTARTNOHAND || |
| 968 | 980 | retval == -ERESTART_RESTARTBLOCK)) |
| 969 | 981 | retval = -EINTR; |
| 970 | − | |
| 982 | +err: | |
| 983 | + mutex_unlock(&proc->files_lock); | |
| 971 | 984 | return retval; |
| 972 | 985 | } |
| 973 | 986 | |
| @@ -4690,7 +4703,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) · 3716 unmodified lines | ||
| 4690 | 4703 | ret = binder_alloc_mmap_handler(&proc->alloc, vma); |
| 4691 | 4704 | if (ret) |
| 4692 | 4705 | return ret; |
| 4706 | + mutex_lock(&proc->files_lock); | |
| 4693 | 4707 | proc->files = get_files_struct(current); |
| 4708 | + mutex_unlock(&proc->files_lock); | |
| 4694 | 4709 | return 0; |
| 4695 | 4710 | |
| 4696 | 4711 | err_bad_arg: |
| @@ -4714,6 +4729,7 @@ static int binder_open(struct inode *nodp, struct file *filp) · 17 unmodified lines | ||
| 4714 | 4729 | spin_lock_init(&proc->outer_lock); |
| 4715 | 4730 | get_task_struct(current->group_leader); |
| 4716 | 4731 | proc->tsk = current->group_leader; |
| 4732 | + mutex_init(&proc->files_lock); | |
| 4717 | 4733 | INIT_LIST_HEAD(&proc->todo); |
| 4718 | 4734 | proc->default_priority = task_nice(current); |
| 4719 | 4735 | binder_dev = container_of(filp->private_data, struct binder_device, |
| @@ -4966,9 +4982,11 @@ static void binder_deferred_func(struct work_struct *work) · 246 unmodified lines | ||
| 4966 | 4982 | |
| 4967 | 4983 | files = NULL; |
| 4968 | 4984 | if (defer & BINDER_DEFERRED_PUT_FILES) { |
| 4985 | + mutex_lock(&proc->files_lock); | |
| 4969 | 4986 | files = proc->files; |
| 4970 | 4987 | if (files) |
| 4971 | 4988 | proc->files = NULL; |
| 4989 | + mutex_unlock(&proc->files_lock); | |
| 4972 | 4990 | } |
| 4973 | 4991 | |
| 4974 | 4992 | if (defer & BINDER_DEFERRED_FLUSH) |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * MeidaTek AHCI SATA driver | |
| 2 | + * MediaTek AHCI SATA driver | |
| 3 | 3 | * |
| 4 | 4 | * Copyright (c) 2017 MediaTek Inc. |
| 5 | 5 | * Author: Ryder Lee <ryder.lee@mediatek.com> |
| @@ -25,7 +25,7 @@ · 19 unmodified lines | ||
| 25 | 25 | #include <linux/reset.h> |
| 26 | 26 | #include "ahci.h" |
| 27 | 27 | |
| 28 | −#define DRV_NAME "ahci" | |
| 28 | +#define DRV_NAME "ahci-mtk" | |
| 29 | 29 | |
| 30 | 30 | #define SYS_CFG 0x14 |
| 31 | 31 | #define SYS_CFG_SATA_MSK GENMASK(31, 30) |
| @@ -192,5 +192,5 @@ static struct platform_driver mtk_ahci_driver = { · 160 unmodified lines | ||
| 192 | 192 | }; |
| 193 | 193 | module_platform_driver(mtk_ahci_driver); |
| 194 | 194 | |
| 195 | −MODULE_DESCRIPTION("MeidaTek SATA AHCI Driver"); | |
| 195 | +MODULE_DESCRIPTION("MediaTek SATA AHCI Driver"); | |
| 196 | 196 | MODULE_LICENSE("GPL v2"); |
| @@ -35,6 +35,8 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | /* port register default value */ |
| 37 | 37 | #define AHCI_PORT_PHY_1_CFG 0xa003fffe |
| 38 | +#define AHCI_PORT_PHY2_CFG 0x28184d1f | |
| 39 | +#define AHCI_PORT_PHY3_CFG 0x0e081509 | |
| 38 | 40 | #define AHCI_PORT_TRANS_CFG 0x08000029 |
| 39 | 41 | #define AHCI_PORT_AXICC_CFG 0x3fffffff |
| 40 | 42 | |
| @@ -183,6 +185,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) · 142 unmodified lines | ||
| 183 | 185 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, |
| 184 | 186 | qpriv->ecc_addr); |
| 185 | 187 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 188 | + writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | |
| 189 | + writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | |
| 186 | 190 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 187 | 191 | if (qpriv->is_dmacoherent) |
| 188 | 192 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -190,6 +194,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) · 1 unmodified line | ||
| 190 | 194 | |
| 191 | 195 | case AHCI_LS2080A: |
| 192 | 196 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 197 | + writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | |
| 198 | + writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | |
| 193 | 199 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 194 | 200 | if (qpriv->is_dmacoherent) |
| 195 | 201 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -201,6 +207,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) · 5 unmodified lines | ||
| 201 | 207 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, |
| 202 | 208 | qpriv->ecc_addr); |
| 203 | 209 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 210 | + writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | |
| 211 | + writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | |
| 204 | 212 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 205 | 213 | if (qpriv->is_dmacoherent) |
| 206 | 214 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -212,6 +220,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) · 5 unmodified lines | ||
| 212 | 220 | writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A, |
| 213 | 221 | qpriv->ecc_addr); |
| 214 | 222 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 223 | + writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | |
| 224 | + writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | |
| 215 | 225 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 216 | 226 | if (qpriv->is_dmacoherent) |
| 217 | 227 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -219,6 +229,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) · 1 unmodified line | ||
| 219 | 229 | |
| 220 | 230 | case AHCI_LS2088A: |
| 221 | 231 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 232 | + writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | |
| 233 | + writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | |
| 222 | 234 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 223 | 235 | if (qpriv->is_dmacoherent) |
| 224 | 236 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -3082,13 +3082,19 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) · 3081 unmodified lines | ||
| 3082 | 3082 | bit = fls(mask) - 1; |
| 3083 | 3083 | mask &= ~(1 << bit); |
| 3084 | 3084 | |
| 3085 | − /* Mask off all speeds higher than or equal to the current | |
| 3086 | − * one. Force 1.5Gbps if current SPD is not available. | |
| 3085 | + /* | |
| 3086 | + * Mask off all speeds higher than or equal to the current one. At | |
| 3087 | + * this point, if current SPD is not available and we previously | |
| 3088 | + * recorded the link speed from SStatus, the driver has already | |
| 3089 | + * masked off the highest bit so mask should already be 1 or 0. | |
| 3090 | + * Otherwise, we should not force 1.5Gbps on a link where we have | |
| 3091 | + * not previously recorded speed from SStatus. Just return in this | |
| 3092 | + * case. | |
| 3087 | 3093 | */ |
| 3088 | 3094 | if (spd > 1) |
| 3089 | 3095 | mask &= (1 << (spd - 1)) - 1; |
| 3090 | 3096 | else |
| 3091 | − mask &= 1; | |
| 3097 | + return -EINVAL; | |
| 3092 | 3098 | |
| 3093 | 3099 | /* were we already at the bottom? */ |
| 3094 | 3100 | if (!mask) |
| @@ -82,7 +82,7 @@ static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed · 81 unmodified lines | ||
| 82 | 82 | * is issued to the device. However, if the controller clock is 133MHz, |
| 83 | 83 | * the following tables must be used. |
| 84 | 84 | */ |
| 85 | −static struct pdc2027x_pio_timing { | |
| 85 | +static const struct pdc2027x_pio_timing { | |
| 86 | 86 | u8 value0, value1, value2; |
| 87 | 87 | } pdc2027x_pio_timing_tbl[] = { |
| 88 | 88 | { 0xfb, 0x2b, 0xac }, /* PIO mode 0 */ |
| @@ -92,7 +92,7 @@ static struct pdc2027x_pio_timing { · 3 unmodified lines | ||
| 92 | 92 | { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | −static struct pdc2027x_mdma_timing { | |
| 95 | +static const struct pdc2027x_mdma_timing { | |
| 96 | 96 | u8 value0, value1; |
| 97 | 97 | } pdc2027x_mdma_timing_tbl[] = { |
| 98 | 98 | { 0xdf, 0x5f }, /* MDMA mode 0 */ |
| @@ -100,7 +100,7 @@ static struct pdc2027x_mdma_timing { · 1 unmodified line | ||
| 100 | 100 | { 0x69, 0x25 }, /* MDMA mode 2 */ |
| 101 | 101 | }; |
| 102 | 102 | |
| 103 | −static struct pdc2027x_udma_timing { | |
| 103 | +static const struct pdc2027x_udma_timing { | |
| 104 | 104 | u8 value0, value1, value2; |
| 105 | 105 | } pdc2027x_udma_timing_tbl[] = { |
| 106 | 106 | { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ |
| @@ -649,7 +649,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) · 542 unmodified lines | ||
| 649 | 649 | * @host: target ATA host |
| 650 | 650 | * @board_idx: board identifier |
| 651 | 651 | */ |
| 652 | −static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx) | |
| 652 | +static void pdc_hardware_init(struct ata_host *host, unsigned int board_idx) | |
| 653 | 653 | { |
| 654 | 654 | long pll_clock; |
| 655 | 655 | |
| @@ -665,8 +665,6 @@ static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx) · 9 unmodified lines | ||
| 665 | 665 | |
| 666 | 666 | /* Adjust PLL control register */ |
| 667 | 667 | pdc_adjust_pll(host, pll_clock, board_idx); |
| 668 | − | |
| 669 | − return 0; | |
| 670 | 668 | } |
| 671 | 669 | |
| 672 | 670 | /** |
| @@ -753,8 +751,7 @@ static int pdc2027x_init_one(struct pci_dev *pdev, · 80 unmodified lines | ||
| 753 | 751 | //pci_enable_intx(pdev); |
| 754 | 752 | |
| 755 | 753 | /* initialize adapter */ |
| 756 | − if (pdc_hardware_init(host, board_idx) != 0) | |
| 757 | − return -EIO; | |
| 754 | + pdc_hardware_init(host, board_idx); | |
| 758 | 755 | |
| 759 | 756 | pci_set_master(pdev); |
| 760 | 757 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
| @@ -778,8 +775,7 @@ static int pdc2027x_reinit_one(struct pci_dev *pdev) · 17 unmodified lines | ||
| 778 | 775 | else |
| 779 | 776 | board_idx = PDC_UDMA_133; |
| 780 | 777 | |
| 781 | − if (pdc_hardware_init(host, board_idx)) | |
| 782 | − return -EIO; | |
| 778 | + pdc_hardware_init(host, board_idx); | |
| 783 | 779 | |
| 784 | 780 | ata_host_resume(host); |
| 785 | 781 | return 0; |
| @@ -186,6 +186,11 @@ static void cache_associativity(struct cacheinfo *this_leaf) · 185 unmodified lines | ||
| 186 | 186 | this_leaf->ways_of_associativity = (size / nr_sets) / line_size; |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | +static bool cache_node_is_unified(struct cacheinfo *this_leaf) | |
| 190 | +{ | |
| 191 | + return of_property_read_bool(this_leaf->of_node, "cache-unified"); | |
| 192 | +} | |
| 193 | + | |
| 189 | 194 | static void cache_of_override_properties(unsigned int cpu) |
| 190 | 195 | { |
| 191 | 196 | int index; |
| @@ -194,6 +199,14 @@ static void cache_of_override_properties(unsigned int cpu) · 2 unmodified lines | ||
| 194 | 199 | |
| 195 | 200 | for (index = 0; index < cache_leaves(cpu); index++) { |
| 196 | 201 | this_leaf = this_cpu_ci->info_list + index; |
| 202 | + /* | |
| 203 | + * init_cache_level must setup the cache level correctly | |
| 204 | + * overriding the architecturally specified levels, so | |
| 205 | + * if type is NONE at this stage, it should be unified | |
| 206 | + */ | |
| 207 | + if (this_leaf->type == CACHE_TYPE_NOCACHE && | |
| 208 | + cache_node_is_unified(this_leaf)) | |
| 209 | + this_leaf->type = CACHE_TYPE_UNIFIED; | |
| 197 | 210 | cache_size(this_leaf); |
| 198 | 211 | cache_get_line_size(this_leaf); |
| 199 | 212 | cache_nr_sets(this_leaf); |
| @@ -525,6 +525,21 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd) · 524 unmodified lines | ||
| 525 | 525 | |
| 526 | 526 | /*------------------------- Resume routines -------------------------*/ |
| 527 | 527 | |
| 528 | +/** | |
| 529 | + * dev_pm_skip_next_resume_phases - Skip next system resume phases for device. | |
| 530 | + * @dev: Target device. | |
| 531 | + * | |
| 532 | + * Make the core skip the "early resume" and "resume" phases for @dev. | |
| 533 | + * | |
| 534 | + * This function can be called by middle-layer code during the "noirq" phase of | |
| 535 | + * system resume if necessary, but not by device drivers. | |
| 536 | + */ | |
| 537 | +void dev_pm_skip_next_resume_phases(struct device *dev) | |
| 538 | +{ | |
| 539 | + dev->power.is_late_suspended = false; | |
| 540 | + dev->power.is_suspended = false; | |
| 541 | +} | |
| 542 | + | |
| 528 | 543 | /** |
| 529 | 544 | * device_resume_noirq - Execute a "noirq resume" callback for given device. |
| 530 | 545 | * @dev: Device to handle. |
| @@ -35,13 +35,13 @@ static inline u64 mb_per_tick(int mbps) · 34 unmodified lines | ||
| 35 | 35 | struct nullb_cmd { |
| 36 | 36 | struct list_head list; |
| 37 | 37 | struct llist_node ll_list; |
| 38 | − call_single_data_t csd; | |
| 38 | + struct __call_single_data csd; | |
| 39 | 39 | struct request *rq; |
| 40 | 40 | struct bio *bio; |
| 41 | 41 | unsigned int tag; |
| 42 | + blk_status_t error; | |
| 42 | 43 | struct nullb_queue *nq; |
| 43 | 44 | struct hrtimer timer; |
| 44 | − blk_status_t error; | |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | 47 | struct nullb_queue { |
| @@ -199,6 +199,9 @@ struct smi_info { · 198 unmodified lines | ||
| 199 | 199 | /* The timer for this si. */ |
| 200 | 200 | struct timer_list si_timer; |
| 201 | 201 | |
| 202 | + /* This flag is set, if the timer can be set */ | |
| 203 | + bool timer_can_start; | |
| 204 | + | |
| 202 | 205 | /* This flag is set, if the timer is running (timer_pending() isn't enough) */ |
| 203 | 206 | bool timer_running; |
| 204 | 207 | |
| @@ -355,6 +358,8 @@ out: · 150 unmodified lines | ||
| 355 | 358 | |
| 356 | 359 | static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val) |
| 357 | 360 | { |
| 361 | + if (!smi_info->timer_can_start) | |
| 362 | + return; | |
| 358 | 363 | smi_info->last_timeout_jiffies = jiffies; |
| 359 | 364 | mod_timer(&smi_info->si_timer, new_val); |
| 360 | 365 | smi_info->timer_running = true; |
| @@ -374,21 +379,18 @@ static void start_new_msg(struct smi_info *smi_info, unsigned char *msg, · 13 unmodified lines | ||
| 374 | 379 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, size); |
| 375 | 380 | } |
| 376 | 381 | |
| 377 | −static void start_check_enables(struct smi_info *smi_info, bool start_timer) | |
| 382 | +static void start_check_enables(struct smi_info *smi_info) | |
| 378 | 383 | { |
| 379 | 384 | unsigned char msg[2]; |
| 380 | 385 | |
| 381 | 386 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); |
| 382 | 387 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; |
| 383 | 388 | |
| 384 | − if (start_timer) | |
| 385 | − start_new_msg(smi_info, msg, 2); | |
| 386 | − else | |
| 387 | − smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | |
| 389 | + start_new_msg(smi_info, msg, 2); | |
| 388 | 390 | smi_info->si_state = SI_CHECKING_ENABLES; |
| 389 | 391 | } |
| 390 | 392 | |
| 391 | −static void start_clear_flags(struct smi_info *smi_info, bool start_timer) | |
| 393 | +static void start_clear_flags(struct smi_info *smi_info) | |
| 392 | 394 | { |
| 393 | 395 | unsigned char msg[3]; |
| 394 | 396 | |
| @@ -397,10 +399,7 @@ static void start_clear_flags(struct smi_info *smi_info, bool start_timer) · 2 unmodified lines | ||
| 397 | 399 | msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; |
| 398 | 400 | msg[2] = WDT_PRE_TIMEOUT_INT; |
| 399 | 401 | |
| 400 | − if (start_timer) | |
| 401 | − start_new_msg(smi_info, msg, 3); | |
| 402 | − else | |
| 403 | − smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3); | |
| 402 | + start_new_msg(smi_info, msg, 3); | |
| 404 | 403 | smi_info->si_state = SI_CLEARING_FLAGS; |
| 405 | 404 | } |
| 406 | 405 | |
| @@ -435,11 +434,11 @@ static void start_getting_events(struct smi_info *smi_info) · 28 unmodified lines | ||
| 435 | 434 | * Note that we cannot just use disable_irq(), since the interrupt may |
| 436 | 435 | * be shared. |
| 437 | 436 | */ |
| 438 | −static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer) | |
| 437 | +static inline bool disable_si_irq(struct smi_info *smi_info) | |
| 439 | 438 | { |
| 440 | 439 | if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) { |
| 441 | 440 | smi_info->interrupt_disabled = true; |
| 442 | − start_check_enables(smi_info, start_timer); | |
| 441 | + start_check_enables(smi_info); | |
| 443 | 442 | return true; |
| 444 | 443 | } |
| 445 | 444 | return false; |
| @@ -449,7 +448,7 @@ static inline bool enable_si_irq(struct smi_info *smi_info) · 3 unmodified lines | ||
| 449 | 448 | { |
| 450 | 449 | if ((smi_info->io.irq) && (smi_info->interrupt_disabled)) { |
| 451 | 450 | smi_info->interrupt_disabled = false; |
| 452 | − start_check_enables(smi_info, true); | |
| 451 | + start_check_enables(smi_info); | |
| 453 | 452 | return true; |
| 454 | 453 | } |
| 455 | 454 | return false; |
| @@ -467,7 +466,7 @@ static struct ipmi_smi_msg *alloc_msg_handle_irq(struct smi_info *smi_info) · 11 unmodified lines | ||
| 467 | 466 | |
| 468 | 467 | msg = ipmi_alloc_smi_msg(); |
| 469 | 468 | if (!msg) { |
| 470 | − if (!disable_si_irq(smi_info, true)) | |
| 469 | + if (!disable_si_irq(smi_info)) | |
| 471 | 470 | smi_info->si_state = SI_NORMAL; |
| 472 | 471 | } else if (enable_si_irq(smi_info)) { |
| 473 | 472 | ipmi_free_smi_msg(msg); |
| @@ -483,7 +482,7 @@ retry: · 9 unmodified lines | ||
| 483 | 482 | /* Watchdog pre-timeout */ |
| 484 | 483 | smi_inc_stat(smi_info, watchdog_pretimeouts); |
| 485 | 484 | |
| 486 | − start_clear_flags(smi_info, true); | |
| 485 | + start_clear_flags(smi_info); | |
| 487 | 486 | smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; |
| 488 | 487 | if (smi_info->intf) |
| 489 | 488 | ipmi_smi_watchdog_pretimeout(smi_info->intf); |
| @@ -866,7 +865,7 @@ restart: · 376 unmodified lines | ||
| 866 | 865 | * disable and messages disabled. |
| 867 | 866 | */ |
| 868 | 867 | if (smi_info->supports_event_msg_buff || smi_info->io.irq) { |
| 869 | − start_check_enables(smi_info, true); | |
| 868 | + start_check_enables(smi_info); | |
| 870 | 869 | } else { |
| 871 | 870 | smi_info->curr_msg = alloc_msg_handle_irq(smi_info); |
| 872 | 871 | if (!smi_info->curr_msg) |
| @@ -1167,6 +1166,7 @@ static int smi_start_processing(void *send_info, · 294 unmodified lines | ||
| 1167 | 1166 | |
| 1168 | 1167 | /* Set up the timer that drives the interface. */ |
| 1169 | 1168 | timer_setup(&new_smi->si_timer, smi_timeout, 0); |
| 1169 | + new_smi->timer_can_start = true; | |
| 1170 | 1170 | smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); |
| 1171 | 1171 | |
| 1172 | 1172 | /* Try to claim any interrupts. */ |
| @@ -1936,10 +1936,12 @@ static void check_for_broken_irqs(struct smi_info *smi_info) · 763 unmodified lines | ||
| 1936 | 1936 | check_set_rcv_irq(smi_info); |
| 1937 | 1937 | } |
| 1938 | 1938 | |
| 1939 | −static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | |
| 1939 | +static inline void stop_timer_and_thread(struct smi_info *smi_info) | |
| 1940 | 1940 | { |
| 1941 | 1941 | if (smi_info->thread != NULL) |
| 1942 | 1942 | kthread_stop(smi_info->thread); |
| 1943 | + | |
| 1944 | + smi_info->timer_can_start = false; | |
| 1943 | 1945 | if (smi_info->timer_running) |
| 1944 | 1946 | del_timer_sync(&smi_info->si_timer); |
| 1945 | 1947 | } |
| @@ -2152,7 +2154,7 @@ static int try_smi_init(struct smi_info *new_smi) · 206 unmodified lines | ||
| 2152 | 2154 | * Start clearing the flags before we enable interrupts or the |
| 2153 | 2155 | * timer to avoid racing with the timer. |
| 2154 | 2156 | */ |
| 2155 | − start_clear_flags(new_smi, false); | |
| 2157 | + start_clear_flags(new_smi); | |
| 2156 | 2158 | |
| 2157 | 2159 | /* |
| 2158 | 2160 | * IRQ is defined to be set when non-zero. req_events will |
| @@ -2238,7 +2240,7 @@ out_err_remove_attrs: · 79 unmodified lines | ||
| 2238 | 2240 | dev_set_drvdata(new_smi->io.dev, NULL); |
| 2239 | 2241 | |
| 2240 | 2242 | out_err_stop_timer: |
| 2241 | − wait_for_timer_and_thread(new_smi); | |
| 2243 | + stop_timer_and_thread(new_smi); | |
| 2242 | 2244 | |
| 2243 | 2245 | out_err: |
| 2244 | 2246 | new_smi->interrupt_disabled = true; |
| @@ -2388,7 +2390,7 @@ static void cleanup_one_si(struct smi_info *to_clean) · 143 unmodified lines | ||
| 2388 | 2390 | */ |
| 2389 | 2391 | if (to_clean->io.irq_cleanup) |
| 2390 | 2392 | to_clean->io.irq_cleanup(&to_clean->io); |
| 2391 | − wait_for_timer_and_thread(to_clean); | |
| 2393 | + stop_timer_and_thread(to_clean); | |
| 2392 | 2394 | |
| 2393 | 2395 | /* |
| 2394 | 2396 | * Timeouts are stopped, now make sure the interrupts are off |
| @@ -2400,7 +2402,7 @@ static void cleanup_one_si(struct smi_info *to_clean) · 5 unmodified lines | ||
| 2400 | 2402 | schedule_timeout_uninterruptible(1); |
| 2401 | 2403 | } |
| 2402 | 2404 | if (to_clean->handlers) |
| 2403 | − disable_si_irq(to_clean, false); | |
| 2405 | + disable_si_irq(to_clean); | |
| 2404 | 2406 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
| 2405 | 2407 | poll(to_clean); |
| 2406 | 2408 | schedule_timeout_uninterruptible(1); |
| @@ -10,6 +10,8 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev) · 9 unmodified lines | ||
| 10 | 10 | { |
| 11 | 11 | struct si_sm_io io; |
| 12 | 12 | |
| 13 | + memset(&io, 0, sizeof(io)); | |
| 14 | + | |
| 13 | 15 | io.si_type = SI_KCS; |
| 14 | 16 | io.addr_source = SI_DEVICETREE; |
| 15 | 17 | io.addr_type = IPMI_MEM_ADDR_SPACE; |
| @@ -103,10 +103,13 @@ static int ipmi_pci_probe(struct pci_dev *pdev, · 102 unmodified lines | ||
| 103 | 103 | io.addr_source_cleanup = ipmi_pci_cleanup; |
| 104 | 104 | io.addr_source_data = pdev; |
| 105 | 105 | |
| 106 | − if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) | |
| 106 | + if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { | |
| 107 | 107 | io.addr_type = IPMI_IO_ADDR_SPACE; |
| 108 | − else | |
| 108 | + io.io_setup = ipmi_si_port_setup; | |
| 109 | + } else { | |
| 109 | 110 | io.addr_type = IPMI_MEM_ADDR_SPACE; |
| 111 | + io.io_setup = ipmi_si_mem_setup; | |
| 112 | + } | |
| 110 | 113 | io.addr_data = pci_resource_start(pdev, 0); |
| 111 | 114 | |
| 112 | 115 | io.regspacing = ipmi_pci_probe_regspacing(&io); |
| @@ -220,7 +220,8 @@ static bool clk_core_is_enabled(struct clk_core *core) · 219 unmodified lines | ||
| 220 | 220 | |
| 221 | 221 | ret = core->ops->is_enabled(core->hw); |
| 222 | 222 | done: |
| 223 | − clk_pm_runtime_put(core); | |
| 223 | + if (core->dev) | |
| 224 | + pm_runtime_put(core->dev); | |
| 224 | 225 | |
| 225 | 226 | return ret; |
| 226 | 227 | } |
| @@ -1564,6 +1565,9 @@ static void clk_change_rate(struct clk_core *core) · 1337 unmodified lines | ||
| 1564 | 1565 | best_parent_rate = core->parent->rate; |
| 1565 | 1566 | } |
| 1566 | 1567 | |
| 1568 | + if (clk_pm_runtime_get(core)) | |
| 1569 | + return; | |
| 1570 | + | |
| 1567 | 1571 | if (core->flags & CLK_SET_RATE_UNGATE) { |
| 1568 | 1572 | unsigned long flags; |
| 1569 | 1573 | |
| @@ -1634,6 +1638,8 @@ static void clk_change_rate(struct clk_core *core) · 64 unmodified lines | ||
| 1634 | 1638 | /* handle the new child who might not be in core->children yet */ |
| 1635 | 1639 | if (core->new_child) |
| 1636 | 1640 | clk_change_rate(core->new_child); |
| 1641 | + | |
| 1642 | + clk_pm_runtime_put(core); | |
| 1637 | 1643 | } |
| 1638 | 1644 | |
| 1639 | 1645 | static int clk_core_set_rate_nolock(struct clk_core *core, |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #include <linux/clk.h> |
| 18 | 18 | #include <linux/clk-provider.h> |
| 19 | +#include <linux/delay.h> | |
| 19 | 20 | #include <linux/init.h> |
| 20 | 21 | #include <linux/of.h> |
| 21 | 22 | #include <linux/of_device.h> |
| @@ -83,9 +84,20 @@ static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev, · 61 unmodified lines | ||
| 83 | 84 | return 0; |
| 84 | 85 | } |
| 85 | 86 | |
| 87 | +static int sun9i_mmc_reset_reset(struct reset_controller_dev *rcdev, | |
| 88 | + unsigned long id) | |
| 89 | +{ | |
| 90 | + sun9i_mmc_reset_assert(rcdev, id); | |
| 91 | + udelay(10); | |
| 92 | + sun9i_mmc_reset_deassert(rcdev, id); | |
| 93 | + | |
| 94 | + return 0; | |
| 95 | +} | |
| 96 | + | |
| 86 | 97 | static const struct reset_control_ops sun9i_mmc_reset_ops = { |
| 87 | 98 | .assert = sun9i_mmc_reset_assert, |
| 88 | 99 | .deassert = sun9i_mmc_reset_deassert, |
| 100 | + .reset = sun9i_mmc_reset_reset, | |
| 89 | 101 | }; |
| 90 | 102 | |
| 91 | 103 | static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #include "cpufreq_governor.h" |
| 24 | 24 | |
| 25 | +#define CPUFREQ_DBS_MIN_SAMPLING_INTERVAL (2 * TICK_NSEC / NSEC_PER_USEC) | |
| 26 | + | |
| 25 | 27 | static DEFINE_PER_CPU(struct cpu_dbs_info, cpu_dbs); |
| 26 | 28 | |
| 27 | 29 | static DEFINE_MUTEX(gov_dbs_data_mutex); |
| @@ -47,11 +49,15 @@ ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf, · 19 unmodified lines | ||
| 47 | 49 | { |
| 48 | 50 | struct dbs_data *dbs_data = to_dbs_data(attr_set); |
| 49 | 51 | struct policy_dbs_info *policy_dbs; |
| 52 | + unsigned int sampling_interval; | |
| 50 | 53 | int ret; |
| 51 | − ret = sscanf(buf, "%u", &dbs_data->sampling_rate); | |
| 52 | − if (ret != 1) | |
| 54 | + | |
| 55 | + ret = sscanf(buf, "%u", &sampling_interval); | |
| 56 | + if (ret != 1 || sampling_interval < CPUFREQ_DBS_MIN_SAMPLING_INTERVAL) | |
| 53 | 57 | return -EINVAL; |
| 54 | 58 | |
| 59 | + dbs_data->sampling_rate = sampling_interval; | |
| 60 | + | |
| 55 | 61 | /* |
| 56 | 62 | * We are operating under dbs_data->mutex and so the list and its |
| 57 | 63 | * entries can't be freed concurrently. |
| @@ -430,7 +436,14 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) · 372 unmodified lines | ||
| 430 | 436 | if (ret) |
| 431 | 437 | goto free_policy_dbs_info; |
| 432 | 438 | |
| 433 | − dbs_data->sampling_rate = cpufreq_policy_transition_delay_us(policy); | |
| 439 | + /* | |
| 440 | + * The sampling interval should not be less than the transition latency | |
| 441 | + * of the CPU and it also cannot be too small for dbs_update() to work | |
| 442 | + * correctly. | |
| 443 | + */ | |
| 444 | + dbs_data->sampling_rate = max_t(unsigned int, | |
| 445 | + CPUFREQ_DBS_MIN_SAMPLING_INTERVAL, | |
| 446 | + cpufreq_policy_transition_delay_us(policy)); | |
| 434 | 447 | |
| 435 | 448 | if (!have_governor_per_policy()) |
| 436 | 449 | gov->gdbs_data = dbs_data; |
| @@ -226,17 +226,18 @@ static void imx6q_opp_check_speed_grading(struct device *dev) · 225 unmodified lines | ||
| 226 | 226 | val >>= OCOTP_CFG3_SPEED_SHIFT; |
| 227 | 227 | val &= 0x3; |
| 228 | 228 | |
| 229 | − if ((val != OCOTP_CFG3_SPEED_1P2GHZ) && | |
| 230 | − of_machine_is_compatible("fsl,imx6q")) | |
| 231 | − if (dev_pm_opp_disable(dev, 1200000000)) | |
| 232 | − dev_warn(dev, "failed to disable 1.2GHz OPP\n"); | |
| 233 | 229 | if (val < OCOTP_CFG3_SPEED_996MHZ) |
| 234 | 230 | if (dev_pm_opp_disable(dev, 996000000)) |
| 235 | 231 | dev_warn(dev, "failed to disable 996MHz OPP\n"); |
| 236 | − if (of_machine_is_compatible("fsl,imx6q")) { | |
| 232 | + | |
| 233 | + if (of_machine_is_compatible("fsl,imx6q") || | |
| 234 | + of_machine_is_compatible("fsl,imx6qp")) { | |
| 237 | 235 | if (val != OCOTP_CFG3_SPEED_852MHZ) |
| 238 | 236 | if (dev_pm_opp_disable(dev, 852000000)) |
| 239 | 237 | dev_warn(dev, "failed to disable 852MHz OPP\n"); |
| 238 | + if (val != OCOTP_CFG3_SPEED_1P2GHZ) | |
| 239 | + if (dev_pm_opp_disable(dev, 1200000000)) | |
| 240 | + dev_warn(dev, "failed to disable 1.2GHz OPP\n"); | |
| 240 | 241 | } |
| 241 | 242 | iounmap(base); |
| 242 | 243 | put_node: |
| @@ -708,7 +708,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, · 707 unmodified lines | ||
| 708 | 708 | unsigned long flags) |
| 709 | 709 | { |
| 710 | 710 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
| 711 | − struct data_chunk *first = xt->sgl; | |
| 711 | + struct data_chunk *first; | |
| 712 | 712 | struct at_desc *desc = NULL; |
| 713 | 713 | size_t xfer_count; |
| 714 | 714 | unsigned int dwidth; |
| @@ -720,6 +720,8 @@ atc_prep_dma_interleaved(struct dma_chan *chan, · 5 unmodified lines | ||
| 720 | 720 | if (unlikely(!xt || xt->numf != 1 || !xt->frame_size)) |
| 721 | 721 | return NULL; |
| 722 | 722 | |
| 723 | + first = xt->sgl; | |
| 724 | + | |
| 723 | 725 | dev_info(chan2dev(chan), |
| 724 | 726 | "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", |
| 725 | 727 | __func__, &xt->src_start, &xt->dst_start, xt->numf, |
| @@ -555,7 +555,7 @@ static int jz4740_dma_probe(struct platform_device *pdev) · 554 unmodified lines | ||
| 555 | 555 | |
| 556 | 556 | ret = dma_async_device_register(dd); |
| 557 | 557 | if (ret) |
| 558 | − return ret; | |
| 558 | + goto err_clk; | |
| 559 | 559 | |
| 560 | 560 | irq = platform_get_irq(pdev, 0); |
| 561 | 561 | ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); |
| @@ -568,6 +568,8 @@ static int jz4740_dma_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 568 | 568 | |
| 569 | 569 | err_unregister: |
| 570 | 570 | dma_async_device_unregister(dd); |
| 571 | +err_clk: | |
| 572 | + clk_disable_unprepare(dmadev->clk); | |
| 571 | 573 | return ret; |
| 572 | 574 | } |
| 573 | 575 | |
| @@ -155,6 +155,12 @@ MODULE_PARM_DESC(run, "Run the test (default: false)"); · 154 unmodified lines | ||
| 155 | 155 | #define PATTERN_COUNT_MASK 0x1f |
| 156 | 156 | #define PATTERN_MEMSET_IDX 0x01 |
| 157 | 157 | |
| 158 | +/* poor man's completion - we want to use wait_event_freezable() on it */ | |
| 159 | +struct dmatest_done { | |
| 160 | + bool done; | |
| 161 | + wait_queue_head_t *wait; | |
| 162 | +}; | |
| 163 | + | |
| 158 | 164 | struct dmatest_thread { |
| 159 | 165 | struct list_head node; |
| 160 | 166 | struct dmatest_info *info; |
| @@ -165,6 +171,8 @@ struct dmatest_thread { · 4 unmodified lines | ||
| 165 | 171 | u8 **dsts; |
| 166 | 172 | u8 **udsts; |
| 167 | 173 | enum dma_transaction_type type; |
| 174 | + wait_queue_head_t done_wait; | |
| 175 | + struct dmatest_done test_done; | |
| 168 | 176 | bool done; |
| 169 | 177 | }; |
| 170 | 178 | |
| @@ -342,18 +350,25 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start, · 171 unmodified lines | ||
| 342 | 350 | return error_count; |
| 343 | 351 | } |
| 344 | 352 | |
| 345 | −/* poor man's completion - we want to use wait_event_freezable() on it */ | |
| 346 | −struct dmatest_done { | |
| 347 | − bool done; | |
| 348 | − wait_queue_head_t *wait; | |
| 349 | −}; | |
| 350 | 353 | |
| 351 | 354 | static void dmatest_callback(void *arg) |
| 352 | 355 | { |
| 353 | 356 | struct dmatest_done *done = arg; |
| 354 | − | |
| 355 | − done->done = true; | |
| 356 | − wake_up_all(done->wait); | |
| 357 | + struct dmatest_thread *thread = | |
| 358 | + container_of(arg, struct dmatest_thread, done_wait); | |
| 359 | + if (!thread->done) { | |
| 360 | + done->done = true; | |
| 361 | + wake_up_all(done->wait); | |
| 362 | + } else { | |
| 363 | + /* | |
| 364 | + * If thread->done, it means that this callback occurred | |
| 365 | + * after the parent thread has cleaned up. This can | |
| 366 | + * happen in the case that driver doesn't implement | |
| 367 | + * the terminate_all() functionality and a dma operation | |
| 368 | + * did not occur within the timeout period | |
| 369 | + */ | |
| 370 | + WARN(1, "dmatest: Kernel memory may be corrupted!!\n"); | |
| 371 | + } | |
| 357 | 372 | } |
| 358 | 373 | |
| 359 | 374 | static unsigned int min_odd(unsigned int x, unsigned int y) |
| @@ -424,9 +439,8 @@ static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len) · 64 unmodified lines | ||
| 424 | 439 | */ |
| 425 | 440 | static int dmatest_func(void *data) |
| 426 | 441 | { |
| 427 | − DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait); | |
| 428 | 442 | struct dmatest_thread *thread = data; |
| 429 | − struct dmatest_done done = { .wait = &done_wait }; | |
| 443 | + struct dmatest_done *done = &thread->test_done; | |
| 430 | 444 | struct dmatest_info *info; |
| 431 | 445 | struct dmatest_params *params; |
| 432 | 446 | struct dma_chan *chan; |
| @@ -673,9 +687,9 @@ static int dmatest_func(void *data) · 240 unmodified lines | ||
| 673 | 687 | continue; |
| 674 | 688 | } |
| 675 | 689 | |
| 676 | − done.done = false; | |
| 690 | + done->done = false; | |
| 677 | 691 | tx->callback = dmatest_callback; |
| 678 | − tx->callback_param = &done; | |
| 692 | + tx->callback_param = done; | |
| 679 | 693 | cookie = tx->tx_submit(tx); |
| 680 | 694 | |
| 681 | 695 | if (dma_submit_error(cookie)) { |
| @@ -688,21 +702,12 @@ static int dmatest_func(void *data) · 6 unmodified lines | ||
| 688 | 702 | } |
| 689 | 703 | dma_async_issue_pending(chan); |
| 690 | 704 | |
| 691 | − wait_event_freezable_timeout(done_wait, done.done, | |
| 705 | + wait_event_freezable_timeout(thread->done_wait, done->done, | |
| 692 | 706 | msecs_to_jiffies(params->timeout)); |
| 693 | 707 | |
| 694 | 708 | status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); |
| 695 | 709 | |
| 696 | − if (!done.done) { | |
| 697 | − /* | |
| 698 | − * We're leaving the timed out dma operation with | |
| 699 | − * dangling pointer to done_wait. To make this | |
| 700 | − * correct, we'll need to allocate wait_done for | |
| 701 | − * each test iteration and perform "who's gonna | |
| 702 | − * free it this time?" dancing. For now, just | |
| 703 | − * leave it dangling. | |
| 704 | − */ | |
| 705 | − WARN(1, "dmatest: Kernel stack may be corrupted!!\n"); | |
| 710 | + if (!done->done) { | |
| 706 | 711 | dmaengine_unmap_put(um); |
| 707 | 712 | result("test timed out", total_tests, src_off, dst_off, |
| 708 | 713 | len, 0); |
| @@ -789,7 +794,7 @@ err_thread_type: · 80 unmodified lines | ||
| 789 | 794 | dmatest_KBs(runtime, total_len), ret); |
| 790 | 795 | |
| 791 | 796 | /* terminate all transfers on specified channels */ |
| 792 | − if (ret) | |
| 797 | + if (ret || failed_tests) | |
| 793 | 798 | dmaengine_terminate_all(chan); |
| 794 | 799 | |
| 795 | 800 | thread->done = true; |
| @@ -849,6 +854,8 @@ static int dmatest_add_threads(struct dmatest_info *info, · 53 unmodified lines | ||
| 849 | 854 | thread->info = info; |
| 850 | 855 | thread->chan = dtc->chan; |
| 851 | 856 | thread->type = type; |
| 857 | + thread->test_done.wait = &thread->done_wait; | |
| 858 | + init_waitqueue_head(&thread->done_wait); | |
| 852 | 859 | smp_wmb(); |
| 853 | 860 | thread->task = kthread_create(dmatest_func, thread, "%s-%s%u", |
| 854 | 861 | dma_chan_name(chan), op, i); |
| @@ -863,11 +863,11 @@ static void fsl_edma_irq_exit( · 862 unmodified lines | ||
| 863 | 863 | } |
| 864 | 864 | } |
| 865 | 865 | |
| 866 | −static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma) | |
| 866 | +static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks) | |
| 867 | 867 | { |
| 868 | 868 | int i; |
| 869 | 869 | |
| 870 | − for (i = 0; i < DMAMUX_NR; i++) | |
| 870 | + for (i = 0; i < nr_clocks; i++) | |
| 871 | 871 | clk_disable_unprepare(fsl_edma->muxclk[i]); |
| 872 | 872 | } |
| 873 | 873 | |
| @@ -904,25 +904,25 @@ static int fsl_edma_probe(struct platform_device *pdev) · 30 unmodified lines | ||
| 904 | 904 | |
| 905 | 905 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); |
| 906 | 906 | fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res); |
| 907 | − if (IS_ERR(fsl_edma->muxbase[i])) | |
| 907 | + if (IS_ERR(fsl_edma->muxbase[i])) { | |
| 908 | + /* on error: disable all previously enabled clks */ | |
| 909 | + fsl_disable_clocks(fsl_edma, i); | |
| 908 | 910 | return PTR_ERR(fsl_edma->muxbase[i]); |
| 911 | + } | |
| 909 | 912 | |
| 910 | 913 | sprintf(clkname, "dmamux%d", i); |
| 911 | 914 | fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname); |
| 912 | 915 | if (IS_ERR(fsl_edma->muxclk[i])) { |
| 913 | 916 | dev_err(&pdev->dev, "Missing DMAMUX block clock.\n"); |
| 917 | + /* on error: disable all previously enabled clks */ | |
| 918 | + fsl_disable_clocks(fsl_edma, i); | |
| 914 | 919 | return PTR_ERR(fsl_edma->muxclk[i]); |
| 915 | 920 | } |
| 916 | 921 | |
| 917 | 922 | ret = clk_prepare_enable(fsl_edma->muxclk[i]); |
| 918 | − if (ret) { | |
| 919 | − /* disable only clks which were enabled on error */ | |
| 920 | − for (; i >= 0; i--) | |
| 921 | − clk_disable_unprepare(fsl_edma->muxclk[i]); | |
| 922 | − | |
| 923 | − dev_err(&pdev->dev, "DMAMUX clk block failed.\n"); | |
| 924 | − return ret; | |
| 925 | − } | |
| 923 | + if (ret) | |
| 924 | + /* on error: disable all previously enabled clks */ | |
| 925 | + fsl_disable_clocks(fsl_edma, i); | |
| 926 | 926 | |
| 927 | 927 | } |
| 928 | 928 | |
| @@ -976,7 +976,7 @@ static int fsl_edma_probe(struct platform_device *pdev) · 47 unmodified lines | ||
| 976 | 976 | if (ret) { |
| 977 | 977 | dev_err(&pdev->dev, |
| 978 | 978 | "Can't register Freescale eDMA engine. (%d)\n", ret); |
| 979 | − fsl_disable_clocks(fsl_edma); | |
| 979 | + fsl_disable_clocks(fsl_edma, DMAMUX_NR); | |
| 980 | 980 | return ret; |
| 981 | 981 | } |
| 982 | 982 | |
| @@ -985,7 +985,7 @@ static int fsl_edma_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 985 | 985 | dev_err(&pdev->dev, |
| 986 | 986 | "Can't register Freescale eDMA of_dma. (%d)\n", ret); |
| 987 | 987 | dma_async_device_unregister(&fsl_edma->dma_dev); |
| 988 | − fsl_disable_clocks(fsl_edma); | |
| 988 | + fsl_disable_clocks(fsl_edma, DMAMUX_NR); | |
| 989 | 989 | return ret; |
| 990 | 990 | } |
| 991 | 991 | |
| @@ -1015,7 +1015,7 @@ static int fsl_edma_remove(struct platform_device *pdev) · 23 unmodified lines | ||
| 1015 | 1015 | fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); |
| 1016 | 1016 | of_dma_controller_free(np); |
| 1017 | 1017 | dma_async_device_unregister(&fsl_edma->dma_dev); |
| 1018 | − fsl_disable_clocks(fsl_edma); | |
| 1018 | + fsl_disable_clocks(fsl_edma, DMAMUX_NR); | |
| 1019 | 1019 | |
| 1020 | 1020 | return 0; |
| 1021 | 1021 | } |
| @@ -390,7 +390,7 @@ static int ioat_dma_self_test(struct ioatdma_device *ioat_dma) · 389 unmodified lines | ||
| 390 | 390 | if (memcmp(src, dest, IOAT_TEST_SIZE)) { |
| 391 | 391 | dev_err(dev, "Self-test copy failed compare, disabling\n"); |
| 392 | 392 | err = -ENODEV; |
| 393 | − goto free_resources; | |
| 393 | + goto unmap_dma; | |
| 394 | 394 | } |
| 395 | 395 | |
| 396 | 396 | unmap_dma: |
| @@ -522,6 +522,7 @@ static struct of_device_id const bcm_kona_gpio_of_match[] = { · 521 unmodified lines | ||
| 522 | 522 | * category than their parents, so it won't report false recursion. |
| 523 | 523 | */ |
| 524 | 524 | static struct lock_class_key gpio_lock_class; |
| 525 | +static struct lock_class_key gpio_request_class; | |
| 525 | 526 | |
| 526 | 527 | static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
| 527 | 528 | irq_hw_number_t hwirq) |
| @@ -531,7 +532,7 @@ static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq, · 3 unmodified lines | ||
| 531 | 532 | ret = irq_set_chip_data(irq, d->host_data); |
| 532 | 533 | if (ret < 0) |
| 533 | 534 | return ret; |
| 534 | − irq_set_lockdep_class(irq, &gpio_lock_class); | |
| 535 | + irq_set_lockdep_class(irq, &gpio_lock_class, &gpio_request_class); | |
| 535 | 536 | irq_set_chip_and_handler(irq, &bcm_gpio_irq_chip, handle_simple_irq); |
| 536 | 537 | irq_set_noprobe(irq); |
| 537 | 538 | |
| @@ -327,6 +327,7 @@ static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank( · 326 unmodified lines | ||
| 327 | 327 | * category than their parents, so it won't report false recursion. |
| 328 | 328 | */ |
| 329 | 329 | static struct lock_class_key brcmstb_gpio_irq_lock_class; |
| 330 | +static struct lock_class_key brcmstb_gpio_irq_request_class; | |
| 330 | 331 | |
| 331 | 332 | |
| 332 | 333 | static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
| @@ -346,7 +347,8 @@ static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq, · 13 unmodified lines | ||
| 346 | 347 | ret = irq_set_chip_data(irq, &bank->gc); |
| 347 | 348 | if (ret < 0) |
| 348 | 349 | return ret; |
| 349 | − irq_set_lockdep_class(irq, &brcmstb_gpio_irq_lock_class); | |
| 350 | + irq_set_lockdep_class(irq, &brcmstb_gpio_irq_lock_class, | |
| 351 | + &brcmstb_gpio_irq_request_class); | |
| 350 | 352 | irq_set_chip_and_handler(irq, &priv->irq_chip, handle_level_irq); |
| 351 | 353 | irq_set_noprobe(irq); |
| 352 | 354 | return 0; |
| @@ -103,8 +103,8 @@ static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset) · 102 unmodified lines | ||
| 103 | 103 | struct gpio_reg *r = to_gpio_reg(gc); |
| 104 | 104 | int irq = r->irqs[offset]; |
| 105 | 105 | |
| 106 | − if (irq >= 0 && r->irq.domain) | |
| 107 | − irq = irq_find_mapping(r->irq.domain, irq); | |
| 106 | + if (irq >= 0 && r->irqdomain) | |
| 107 | + irq = irq_find_mapping(r->irqdomain, irq); | |
| 108 | 108 | |
| 109 | 109 | return irq; |
| 110 | 110 | } |
| @@ -565,6 +565,7 @@ static const struct dev_pm_ops tegra_gpio_pm_ops = { · 564 unmodified lines | ||
| 565 | 565 | * than their parents, so it won't report false recursion. |
| 566 | 566 | */ |
| 567 | 567 | static struct lock_class_key gpio_lock_class; |
| 568 | +static struct lock_class_key gpio_request_class; | |
| 568 | 569 | |
| 569 | 570 | static int tegra_gpio_probe(struct platform_device *pdev) |
| 570 | 571 | { |
| @@ -670,7 +671,8 @@ static int tegra_gpio_probe(struct platform_device *pdev) · 99 unmodified lines | ||
| 670 | 671 | |
| 671 | 672 | bank = &tgi->bank_info[GPIO_BANK(gpio)]; |
| 672 | 673 | |
| 673 | − irq_set_lockdep_class(irq, &gpio_lock_class); | |
| 674 | + irq_set_lockdep_class(irq, &gpio_lock_class, | |
| 675 | + &gpio_request_class); | |
| 674 | 676 | irq_set_chip_data(irq, bank); |
| 675 | 677 | irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq); |
| 676 | 678 | } |
| @@ -139,7 +139,7 @@ static int xgene_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio) · 138 unmodified lines | ||
| 139 | 139 | |
| 140 | 140 | static int xgene_gpio_sb_domain_activate(struct irq_domain *d, |
| 141 | 141 | struct irq_data *irq_data, |
| 142 | − bool early) | |
| 142 | + bool reserve) | |
| 143 | 143 | { |
| 144 | 144 | struct xgene_gpio_sb *priv = d->host_data; |
| 145 | 145 | u32 gpio = HWIRQ_TO_GPIO(priv, irq_data->hwirq); |
| @@ -1074,7 +1074,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) · 1073 unmodified lines | ||
| 1074 | 1074 | } |
| 1075 | 1075 | |
| 1076 | 1076 | if (!chip->names) |
| 1077 | − devprop_gpiochip_set_names(chip); | |
| 1077 | + devprop_gpiochip_set_names(chip, dev_fwnode(chip->parent)); | |
| 1078 | 1078 | |
| 1079 | 1079 | acpi_gpiochip_request_regions(acpi_gpio); |
| 1080 | 1080 | acpi_gpiochip_scan_gpios(acpi_gpio); |
| @@ -19,30 +19,27 @@ · 18 unmodified lines | ||
| 19 | 19 | /** |
| 20 | 20 | * devprop_gpiochip_set_names - Set GPIO line names using device properties |
| 21 | 21 | * @chip: GPIO chip whose lines should be named, if possible |
| 22 | + * @fwnode: Property Node containing the gpio-line-names property | |
| 22 | 23 | * |
| 23 | 24 | * Looks for device property "gpio-line-names" and if it exists assigns |
| 24 | 25 | * GPIO line names for the chip. The memory allocated for the assigned |
| 25 | 26 | * names belong to the underlying firmware node and should not be released |
| 26 | 27 | * by the caller. |
| 27 | 28 | */ |
| 28 | −void devprop_gpiochip_set_names(struct gpio_chip *chip) | |
| 29 | +void devprop_gpiochip_set_names(struct gpio_chip *chip, | |
| 30 | + const struct fwnode_handle *fwnode) | |
| 29 | 31 | { |
| 30 | 32 | struct gpio_device *gdev = chip->gpiodev; |
| 31 | 33 | const char **names; |
| 32 | 34 | int ret, i; |
| 33 | 35 | |
| 34 | − if (!chip->parent) { | |
| 35 | − dev_warn(&gdev->dev, "GPIO chip parent is NULL\n"); | |
| 36 | − return; | |
| 37 | − } | |
| 38 | − | |
| 39 | − ret = device_property_read_string_array(chip->parent, "gpio-line-names", | |
| 36 | + ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", | |
| 40 | 37 | NULL, 0); |
| 41 | 38 | if (ret < 0) |
| 42 | 39 | return; |
| 43 | 40 | |
| 44 | 41 | if (ret != gdev->ngpio) { |
| 45 | − dev_warn(chip->parent, | |
| 42 | + dev_warn(&gdev->dev, | |
| 46 | 43 | "names %d do not match number of GPIOs %d\n", ret, |
| 47 | 44 | gdev->ngpio); |
| 48 | 45 | return; |
| @@ -52,10 +49,10 @@ void devprop_gpiochip_set_names(struct gpio_chip *chip) · 3 unmodified lines | ||
| 52 | 49 | if (!names) |
| 53 | 50 | return; |
| 54 | 51 | |
| 55 | − ret = device_property_read_string_array(chip->parent, "gpio-line-names", | |
| 52 | + ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", | |
| 56 | 53 | names, gdev->ngpio); |
| 57 | 54 | if (ret < 0) { |
| 58 | − dev_warn(chip->parent, "failed to read GPIO line names\n"); | |
| 55 | + dev_warn(&gdev->dev, "failed to read GPIO line names\n"); | |
| 59 | 56 | kfree(names); |
| 60 | 57 | return; |
| 61 | 58 | } |
| @@ -493,7 +493,8 @@ int of_gpiochip_add(struct gpio_chip *chip) · 492 unmodified lines | ||
| 493 | 493 | |
| 494 | 494 | /* If the chip defines names itself, these take precedence */ |
| 495 | 495 | if (!chip->names) |
| 496 | − devprop_gpiochip_set_names(chip); | |
| 496 | + devprop_gpiochip_set_names(chip, | |
| 497 | + of_fwnode_handle(chip->of_node)); | |
| 497 | 498 | |
| 498 | 499 | of_node_get(chip->of_node); |
| 499 | 500 | |
| @@ -73,7 +73,8 @@ LIST_HEAD(gpio_devices); · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | static void gpiochip_free_hogs(struct gpio_chip *chip); |
| 75 | 75 | static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, |
| 76 | − struct lock_class_key *key); | |
| 76 | + struct lock_class_key *lock_key, | |
| 77 | + struct lock_class_key *request_key); | |
| 77 | 78 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); |
| 78 | 79 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); |
| 79 | 80 | static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); |
| @@ -1100,7 +1101,8 @@ static void gpiochip_setup_devs(void) · 1020 unmodified lines | ||
| 1100 | 1101 | } |
| 1101 | 1102 | |
| 1102 | 1103 | int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, |
| 1103 | − struct lock_class_key *key) | |
| 1104 | + struct lock_class_key *lock_key, | |
| 1105 | + struct lock_class_key *request_key) | |
| 1104 | 1106 | { |
| 1105 | 1107 | unsigned long flags; |
| 1106 | 1108 | int status = 0; |
| @@ -1246,7 +1248,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, · 139 unmodified lines | ||
| 1246 | 1248 | if (status) |
| 1247 | 1249 | goto err_remove_from_list; |
| 1248 | 1250 | |
| 1249 | − status = gpiochip_add_irqchip(chip, key); | |
| 1251 | + status = gpiochip_add_irqchip(chip, lock_key, request_key); | |
| 1250 | 1252 | if (status) |
| 1251 | 1253 | goto err_remove_chip; |
| 1252 | 1254 | |
| @@ -1632,7 +1634,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, · 379 unmodified lines | ||
| 1632 | 1634 | * This lock class tells lockdep that GPIO irqs are in a different |
| 1633 | 1635 | * category than their parents, so it won't report false recursion. |
| 1634 | 1636 | */ |
| 1635 | − irq_set_lockdep_class(irq, chip->irq.lock_key); | |
| 1637 | + irq_set_lockdep_class(irq, chip->irq.lock_key, chip->irq.request_key); | |
| 1636 | 1638 | irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq.handler); |
| 1637 | 1639 | /* Chips that use nested thread handlers have them marked */ |
| 1638 | 1640 | if (chip->irq.threaded) |
| @@ -1712,10 +1714,12 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) · 73 unmodified lines | ||
| 1712 | 1714 | /** |
| 1713 | 1715 | * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip |
| 1714 | 1716 | * @gpiochip: the GPIO chip to add the IRQ chip to |
| 1715 | − * @lock_key: lockdep class | |
| 1717 | + * @lock_key: lockdep class for IRQ lock | |
| 1718 | + * @request_key: lockdep class for IRQ request | |
| 1716 | 1719 | */ |
| 1717 | 1720 | static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, |
| 1718 | − struct lock_class_key *lock_key) | |
| 1721 | + struct lock_class_key *lock_key, | |
| 1722 | + struct lock_class_key *request_key) | |
| 1719 | 1723 | { |
| 1720 | 1724 | struct irq_chip *irqchip = gpiochip->irq.chip; |
| 1721 | 1725 | const struct irq_domain_ops *ops; |
| @@ -1753,6 +1757,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, · 31 unmodified lines | ||
| 1753 | 1757 | gpiochip->to_irq = gpiochip_to_irq; |
| 1754 | 1758 | gpiochip->irq.default_type = type; |
| 1755 | 1759 | gpiochip->irq.lock_key = lock_key; |
| 1760 | + gpiochip->irq.request_key = request_key; | |
| 1756 | 1761 | |
| 1757 | 1762 | if (gpiochip->irq.domain_ops) |
| 1758 | 1763 | ops = gpiochip->irq.domain_ops; |
| @@ -1850,7 +1855,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) · 91 unmodified lines | ||
| 1850 | 1855 | * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE |
| 1851 | 1856 | * to have the core avoid setting up any default type in the hardware. |
| 1852 | 1857 | * @threaded: whether this irqchip uses a nested thread handler |
| 1853 | − * @lock_key: lockdep class | |
| 1858 | + * @lock_key: lockdep class for IRQ lock | |
| 1859 | + * @request_key: lockdep class for IRQ request | |
| 1854 | 1860 | * |
| 1855 | 1861 | * This function closely associates a certain irqchip with a certain |
| 1856 | 1862 | * gpiochip, providing an irq domain to translate the local IRQs to |
| @@ -1872,7 +1878,8 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, · 15 unmodified lines | ||
| 1872 | 1878 | irq_flow_handler_t handler, |
| 1873 | 1879 | unsigned int type, |
| 1874 | 1880 | bool threaded, |
| 1875 | − struct lock_class_key *lock_key) | |
| 1881 | + struct lock_class_key *lock_key, | |
| 1882 | + struct lock_class_key *request_key) | |
| 1876 | 1883 | { |
| 1877 | 1884 | struct device_node *of_node; |
| 1878 | 1885 | |
| @@ -1913,6 +1920,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, · 34 unmodified lines | ||
| 1913 | 1920 | gpiochip->irq.default_type = type; |
| 1914 | 1921 | gpiochip->to_irq = gpiochip_to_irq; |
| 1915 | 1922 | gpiochip->irq.lock_key = lock_key; |
| 1923 | + gpiochip->irq.request_key = request_key; | |
| 1916 | 1924 | gpiochip->irq.domain = irq_domain_add_simple(of_node, |
| 1917 | 1925 | gpiochip->ngpio, first_irq, |
| 1918 | 1926 | &gpiochip_domain_ops, gpiochip); |
| @@ -1940,7 +1948,8 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key); · 21 unmodified lines | ||
| 1940 | 1948 | #else /* CONFIG_GPIOLIB_IRQCHIP */ |
| 1941 | 1949 | |
| 1942 | 1950 | static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, |
| 1943 | − struct lock_class_key *key) | |
| 1951 | + struct lock_class_key *lock_key, | |
| 1952 | + struct lock_class_key *request_key) | |
| 1944 | 1953 | { |
| 1945 | 1954 | return 0; |
| 1946 | 1955 | } |
| @@ -228,7 +228,8 @@ static inline int gpio_chip_hwgpio(const struct gpio_desc *desc) · 227 unmodified lines | ||
| 228 | 228 | return desc - &desc->gdev->descs[0]; |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | −void devprop_gpiochip_set_names(struct gpio_chip *chip); | |
| 231 | +void devprop_gpiochip_set_names(struct gpio_chip *chip, | |
| 232 | + const struct fwnode_handle *fwnode); | |
| 232 | 233 | |
| 233 | 234 | /* With descriptor prefix */ |
| 234 | 235 | |
| @@ -2467,7 +2467,7 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev) · 2466 unmodified lines | ||
| 2467 | 2467 | PACKET3_MAP_QUEUES_PIPE(ring->pipe) | |
| 2468 | 2468 | PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) | |
| 2469 | 2469 | PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ |
| 2470 | − PACKET3_MAP_QUEUES_ALLOC_FORMAT(1) | /* alloc format: all_on_one_pipe */ | |
| 2470 | + PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */ | |
| 2471 | 2471 | PACKET3_MAP_QUEUES_ENGINE_SEL(0) | /* engine_sel: compute */ |
| 2472 | 2472 | PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */ |
| 2473 | 2473 | amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index)); |
| @@ -2336,7 +2336,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 2335 unmodified lines | ||
| 2336 | 2336 | const struct dm_connector_state *dm_state) |
| 2337 | 2337 | { |
| 2338 | 2338 | struct drm_display_mode *preferred_mode = NULL; |
| 2339 | − const struct drm_connector *drm_connector; | |
| 2339 | + struct drm_connector *drm_connector; | |
| 2340 | 2340 | struct dc_stream_state *stream = NULL; |
| 2341 | 2341 | struct drm_display_mode mode = *drm_mode; |
| 2342 | 2342 | bool native_mode_found = false; |
| @@ -2355,11 +2355,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 12 unmodified lines | ||
| 2355 | 2355 | |
| 2356 | 2356 | if (!aconnector->dc_sink) { |
| 2357 | 2357 | /* |
| 2358 | − * Exclude MST from creating fake_sink | |
| 2359 | − * TODO: need to enable MST into fake_sink feature | |
| 2358 | + * Create dc_sink when necessary to MST | |
| 2359 | + * Don't apply fake_sink to MST | |
| 2360 | 2360 | */ |
| 2361 | − if (aconnector->mst_port) | |
| 2362 | − goto stream_create_fail; | |
| 2361 | + if (aconnector->mst_port) { | |
| 2362 | + dm_dp_mst_dc_sink_create(drm_connector); | |
| 2363 | + goto mst_dc_sink_create_done; | |
| 2364 | + } | |
| 2363 | 2365 | |
| 2364 | 2366 | if (create_fake_sink(aconnector)) |
| 2365 | 2367 | goto stream_create_fail; |
| @@ -2410,6 +2412,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 44 unmodified lines | ||
| 2410 | 2412 | stream_create_fail: |
| 2411 | 2413 | dm_state_null: |
| 2412 | 2414 | drm_connector_null: |
| 2415 | +mst_dc_sink_create_done: | |
| 2413 | 2416 | return stream; |
| 2414 | 2417 | } |
| 2415 | 2418 | |
| @@ -189,6 +189,8 @@ struct amdgpu_dm_connector { · 188 unmodified lines | ||
| 189 | 189 | struct mutex hpd_lock; |
| 190 | 190 | |
| 191 | 191 | bool fake_enable; |
| 192 | + | |
| 193 | + bool mst_connected; | |
| 192 | 194 | }; |
| 193 | 195 | |
| 194 | 196 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) |
| @@ -185,6 +185,42 @@ static int dm_connector_update_modes(struct drm_connector *connector, · 184 unmodified lines | ||
| 185 | 185 | return ret; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | +void dm_dp_mst_dc_sink_create(struct drm_connector *connector) | |
| 189 | +{ | |
| 190 | + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | |
| 191 | + struct edid *edid; | |
| 192 | + struct dc_sink *dc_sink; | |
| 193 | + struct dc_sink_init_data init_params = { | |
| 194 | + .link = aconnector->dc_link, | |
| 195 | + .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | |
| 196 | + | |
| 197 | + edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); | |
| 198 | + | |
| 199 | + if (!edid) { | |
| 200 | + drm_mode_connector_update_edid_property( | |
| 201 | + &aconnector->base, | |
| 202 | + NULL); | |
| 203 | + return; | |
| 204 | + } | |
| 205 | + | |
| 206 | + aconnector->edid = edid; | |
| 207 | + | |
| 208 | + dc_sink = dc_link_add_remote_sink( | |
| 209 | + aconnector->dc_link, | |
| 210 | + (uint8_t *)aconnector->edid, | |
| 211 | + (aconnector->edid->extensions + 1) * EDID_LENGTH, | |
| 212 | + &init_params); | |
| 213 | + | |
| 214 | + dc_sink->priv = aconnector; | |
| 215 | + aconnector->dc_sink = dc_sink; | |
| 216 | + | |
| 217 | + amdgpu_dm_add_sink_to_freesync_module( | |
| 218 | + connector, aconnector->edid); | |
| 219 | + | |
| 220 | + drm_mode_connector_update_edid_property( | |
| 221 | + &aconnector->base, aconnector->edid); | |
| 222 | +} | |
| 223 | + | |
| 188 | 224 | static int dm_dp_mst_get_modes(struct drm_connector *connector) |
| 189 | 225 | { |
| 190 | 226 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| @@ -311,6 +347,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 120 unmodified lines | ||
| 311 | 347 | drm_mode_connector_set_path_property(connector, pathprop); |
| 312 | 348 | |
| 313 | 349 | drm_connector_list_iter_end(&conn_iter); |
| 350 | + aconnector->mst_connected = true; | |
| 314 | 351 | return &aconnector->base; |
| 315 | 352 | } |
| 316 | 353 | } |
| @@ -363,6 +400,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 46 unmodified lines | ||
| 363 | 400 | */ |
| 364 | 401 | amdgpu_dm_connector_funcs_reset(connector); |
| 365 | 402 | |
| 403 | + aconnector->mst_connected = true; | |
| 404 | + | |
| 366 | 405 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", |
| 367 | 406 | aconnector, connector->base.id, aconnector->mst_port); |
| 368 | 407 | |
| @@ -394,6 +433,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 25 unmodified lines | ||
| 394 | 433 | drm_mode_connector_update_edid_property( |
| 395 | 434 | &aconnector->base, |
| 396 | 435 | NULL); |
| 436 | + | |
| 437 | + aconnector->mst_connected = false; | |
| 397 | 438 | } |
| 398 | 439 | |
| 399 | 440 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) |
| @@ -404,10 +445,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) · 4 unmodified lines | ||
| 404 | 445 | drm_kms_helper_hotplug_event(dev); |
| 405 | 446 | } |
| 406 | 447 | |
| 448 | +static void dm_dp_mst_link_status_reset(struct drm_connector *connector) | |
| 449 | +{ | |
| 450 | + mutex_lock(&connector->dev->mode_config.mutex); | |
| 451 | + drm_mode_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD); | |
| 452 | + mutex_unlock(&connector->dev->mode_config.mutex); | |
| 453 | +} | |
| 454 | + | |
| 407 | 455 | static void dm_dp_mst_register_connector(struct drm_connector *connector) |
| 408 | 456 | { |
| 409 | 457 | struct drm_device *dev = connector->dev; |
| 410 | 458 | struct amdgpu_device *adev = dev->dev_private; |
| 459 | + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | |
| 411 | 460 | |
| 412 | 461 | if (adev->mode_info.rfbdev) |
| 413 | 462 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); |
| @@ -416,6 +465,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) · 2 unmodified lines | ||
| 416 | 465 | |
| 417 | 466 | drm_connector_register(connector); |
| 418 | 467 | |
| 468 | + if (aconnector->mst_connected) | |
| 469 | + dm_dp_mst_link_status_reset(connector); | |
| 419 | 470 | } |
| 420 | 471 | |
| 421 | 472 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { |
| @@ -31,5 +31,6 @@ struct amdgpu_dm_connector; · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, |
| 33 | 33 | struct amdgpu_dm_connector *aconnector); |
| 34 | +void dm_dp_mst_dc_sink_create(struct drm_connector *connector); | |
| 34 | 35 | |
| 35 | 36 | #endif |
| @@ -900,6 +900,15 @@ bool dcn_validate_bandwidth( · 899 unmodified lines | ||
| 900 | 900 | v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps; |
| 901 | 901 | v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c; |
| 902 | 902 | v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c; |
| 903 | + /* | |
| 904 | + * Spreadsheet doesn't handle taps_c is one properly, | |
| 905 | + * need to force Chroma to always be scaled to pass | |
| 906 | + * bandwidth validation. | |
| 907 | + */ | |
| 908 | + if (v->override_hta_pschroma[input_idx] == 1) | |
| 909 | + v->override_hta_pschroma[input_idx] = 2; | |
| 910 | + if (v->override_vta_pschroma[input_idx] == 1) | |
| 911 | + v->override_vta_pschroma[input_idx] = 2; | |
| 903 | 912 | v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor; |
| 904 | 913 | } |
| 905 | 914 | if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) |
| @@ -1801,7 +1801,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal) · 1800 unmodified lines | ||
| 1801 | 1801 | link->link_enc->funcs->disable_output(link->link_enc, signal, link); |
| 1802 | 1802 | } |
| 1803 | 1803 | |
| 1804 | −bool dp_active_dongle_validate_timing( | |
| 1804 | +static bool dp_active_dongle_validate_timing( | |
| 1805 | 1805 | const struct dc_crtc_timing *timing, |
| 1806 | 1806 | const struct dc_dongle_caps *dongle_caps) |
| 1807 | 1807 | { |
| @@ -1833,6 +1833,8 @@ bool dp_active_dongle_validate_timing( · 25 unmodified lines | ||
| 1833 | 1833 | /* Check Color Depth and Pixel Clock */ |
| 1834 | 1834 | if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
| 1835 | 1835 | required_pix_clk /= 2; |
| 1836 | + else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) | |
| 1837 | + required_pix_clk = required_pix_clk * 2 / 3; | |
| 1836 | 1838 | |
| 1837 | 1839 | switch (timing->display_color_depth) { |
| 1838 | 1840 | case COLOR_DEPTH_666: |
| @@ -2866,16 +2866,19 @@ static void dce110_apply_ctx_for_surface( · 2865 unmodified lines | ||
| 2866 | 2866 | int num_planes, |
| 2867 | 2867 | struct dc_state *context) |
| 2868 | 2868 | { |
| 2869 | − int i, be_idx; | |
| 2869 | + int i; | |
| 2870 | 2870 | |
| 2871 | 2871 | if (num_planes == 0) |
| 2872 | 2872 | return; |
| 2873 | 2873 | |
| 2874 | − be_idx = -1; | |
| 2875 | 2874 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 2876 | − if (stream == context->res_ctx.pipe_ctx[i].stream) { | |
| 2877 | − be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst; | |
| 2878 | − break; | |
| 2875 | + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | |
| 2876 | + struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2877 | + | |
| 2878 | + if (stream == pipe_ctx->stream) { | |
| 2879 | + if (!pipe_ctx->top_pipe && | |
| 2880 | + (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) | |
| 2881 | + dc->hwss.pipe_control_lock(dc, pipe_ctx, true); | |
| 2879 | 2882 | } |
| 2880 | 2883 | } |
| 2881 | 2884 | |
| @@ -2895,9 +2898,22 @@ static void dce110_apply_ctx_for_surface( · 13 unmodified lines | ||
| 2895 | 2898 | context->stream_count); |
| 2896 | 2899 | |
| 2897 | 2900 | dce110_program_front_end_for_pipe(dc, pipe_ctx); |
| 2901 | + | |
| 2902 | + dc->hwss.update_plane_addr(dc, pipe_ctx); | |
| 2903 | + | |
| 2898 | 2904 | program_surface_visibility(dc, pipe_ctx); |
| 2899 | 2905 | |
| 2900 | 2906 | } |
| 2907 | + | |
| 2908 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 2909 | + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | |
| 2910 | + struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2911 | + | |
| 2912 | + if ((stream == pipe_ctx->stream) && | |
| 2913 | + (!pipe_ctx->top_pipe) && | |
| 2914 | + (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) | |
| 2915 | + dc->hwss.pipe_control_lock(dc, pipe_ctx, false); | |
| 2916 | + } | |
| 2901 | 2917 | } |
| 2902 | 2918 | |
| 2903 | 2919 | static void dce110_power_down_fe(struct dc *dc, int fe_idx) |
| @@ -159,11 +159,10 @@ bool dpp_get_optimal_number_of_taps( · 158 unmodified lines | ||
| 159 | 159 | scl_data->taps.h_taps = 1; |
| 160 | 160 | if (IDENTITY_RATIO(scl_data->ratios.vert)) |
| 161 | 161 | scl_data->taps.v_taps = 1; |
| 162 | − /* | |
| 163 | − * Spreadsheet doesn't handle taps_c is one properly, | |
| 164 | − * need to force Chroma to always be scaled to pass | |
| 165 | − * bandwidth validation. | |
| 166 | − */ | |
| 162 | + if (IDENTITY_RATIO(scl_data->ratios.horz_c)) | |
| 163 | + scl_data->taps.h_taps_c = 1; | |
| 164 | + if (IDENTITY_RATIO(scl_data->ratios.vert_c)) | |
| 165 | + scl_data->taps.v_taps_c = 1; | |
| 167 | 166 | } |
| 168 | 167 | |
| 169 | 168 | return true; |
| @@ -152,14 +152,23 @@ static void drm_connector_free(struct kref *kref) · 151 unmodified lines | ||
| 152 | 152 | connector->funcs->destroy(connector); |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | −static void drm_connector_free_work_fn(struct work_struct *work) | |
| 155 | +void drm_connector_free_work_fn(struct work_struct *work) | |
| 156 | 156 | { |
| 157 | − struct drm_connector *connector = | |
| 158 | − container_of(work, struct drm_connector, free_work); | |
| 159 | − struct drm_device *dev = connector->dev; | |
| 157 | + struct drm_connector *connector, *n; | |
| 158 | + struct drm_device *dev = | |
| 159 | + container_of(work, struct drm_device, mode_config.connector_free_work); | |
| 160 | + struct drm_mode_config *config = &dev->mode_config; | |
| 161 | + unsigned long flags; | |
| 162 | + struct llist_node *freed; | |
| 160 | 163 | |
| 161 | − drm_mode_object_unregister(dev, &connector->base); | |
| 162 | − connector->funcs->destroy(connector); | |
| 164 | + spin_lock_irqsave(&config->connector_list_lock, flags); | |
| 165 | + freed = llist_del_all(&config->connector_free_list); | |
| 166 | + spin_unlock_irqrestore(&config->connector_list_lock, flags); | |
| 167 | + | |
| 168 | + llist_for_each_entry_safe(connector, n, freed, free_node) { | |
| 169 | + drm_mode_object_unregister(dev, &connector->base); | |
| 170 | + connector->funcs->destroy(connector); | |
| 171 | + } | |
| 163 | 172 | } |
| 164 | 173 | |
| 165 | 174 | /** |
| @@ -191,8 +200,6 @@ int drm_connector_init(struct drm_device *dev, · 25 unmodified lines | ||
| 191 | 200 | if (ret) |
| 192 | 201 | return ret; |
| 193 | 202 | |
| 194 | − INIT_WORK(&connector->free_work, drm_connector_free_work_fn); | |
| 195 | − | |
| 196 | 203 | connector->base.properties = &connector->properties; |
| 197 | 204 | connector->dev = dev; |
| 198 | 205 | connector->funcs = funcs; |
| @@ -547,10 +554,17 @@ EXPORT_SYMBOL(drm_connector_list_iter_begin); · 348 unmodified lines | ||
| 547 | 554 | * actually release the connector when dropping our final reference. |
| 548 | 555 | */ |
| 549 | 556 | static void |
| 550 | −drm_connector_put_safe(struct drm_connector *conn) | |
| 557 | +__drm_connector_put_safe(struct drm_connector *conn) | |
| 551 | 558 | { |
| 552 | − if (refcount_dec_and_test(&conn->base.refcount.refcount)) | |
| 553 | − schedule_work(&conn->free_work); | |
| 559 | + struct drm_mode_config *config = &conn->dev->mode_config; | |
| 560 | + | |
| 561 | + lockdep_assert_held(&config->connector_list_lock); | |
| 562 | + | |
| 563 | + if (!refcount_dec_and_test(&conn->base.refcount.refcount)) | |
| 564 | + return; | |
| 565 | + | |
| 566 | + llist_add(&conn->free_node, &config->connector_free_list); | |
| 567 | + schedule_work(&config->connector_free_work); | |
| 554 | 568 | } |
| 555 | 569 | |
| 556 | 570 | /** |
| @@ -582,10 +596,10 @@ drm_connector_list_iter_next(struct drm_connector_list_iter *iter) · 25 unmodified lines | ||
| 582 | 596 | |
| 583 | 597 | /* loop until it's not a zombie connector */ |
| 584 | 598 | } while (!kref_get_unless_zero(&iter->conn->base.refcount)); |
| 585 | − spin_unlock_irqrestore(&config->connector_list_lock, flags); | |
| 586 | 599 | |
| 587 | 600 | if (old_conn) |
| 588 | − drm_connector_put_safe(old_conn); | |
| 601 | + __drm_connector_put_safe(old_conn); | |
| 602 | + spin_unlock_irqrestore(&config->connector_list_lock, flags); | |
| 589 | 603 | |
| 590 | 604 | return iter->conn; |
| 591 | 605 | } |
| @@ -602,9 +616,15 @@ EXPORT_SYMBOL(drm_connector_list_iter_next); · 10 unmodified lines | ||
| 602 | 616 | */ |
| 603 | 617 | void drm_connector_list_iter_end(struct drm_connector_list_iter *iter) |
| 604 | 618 | { |
| 619 | + struct drm_mode_config *config = &iter->dev->mode_config; | |
| 620 | + unsigned long flags; | |
| 621 | + | |
| 605 | 622 | iter->dev = NULL; |
| 606 | − if (iter->conn) | |
| 607 | − drm_connector_put_safe(iter->conn); | |
| 623 | + if (iter->conn) { | |
| 624 | + spin_lock_irqsave(&config->connector_list_lock, flags); | |
| 625 | + __drm_connector_put_safe(iter->conn); | |
| 626 | + spin_unlock_irqrestore(&config->connector_list_lock, flags); | |
| 627 | + } | |
| 608 | 628 | lock_release(&connector_list_iter_dep_map, 0, _RET_IP_); |
| 609 | 629 | } |
| 610 | 630 | EXPORT_SYMBOL(drm_connector_list_iter_end); |
| @@ -1231,6 +1251,19 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector, · 620 unmodified lines | ||
| 1231 | 1251 | if (edid) |
| 1232 | 1252 | size = EDID_LENGTH * (1 + edid->extensions); |
| 1233 | 1253 | |
| 1254 | + /* Set the display info, using edid if available, otherwise | |
| 1255 | + * reseting the values to defaults. This duplicates the work | |
| 1256 | + * done in drm_add_edid_modes, but that function is not | |
| 1257 | + * consistently called before this one in all drivers and the | |
| 1258 | + * computation is cheap enough that it seems better to | |
| 1259 | + * duplicate it rather than attempt to ensure some arbitrary | |
| 1260 | + * ordering of calls. | |
| 1261 | + */ | |
| 1262 | + if (edid) | |
| 1263 | + drm_add_display_info(connector, edid); | |
| 1264 | + else | |
| 1265 | + drm_reset_display_info(connector); | |
| 1266 | + | |
| 1234 | 1267 | drm_object_property_set_value(&connector->base, |
| 1235 | 1268 | dev->mode_config.non_desktop_property, |
| 1236 | 1269 | connector->display_info.non_desktop); |
| @@ -142,6 +142,7 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, · 141 unmodified lines | ||
| 142 | 142 | uint64_t value); |
| 143 | 143 | int drm_connector_create_standard_properties(struct drm_device *dev); |
| 144 | 144 | const char *drm_get_connector_force_name(enum drm_connector_force force); |
| 145 | +void drm_connector_free_work_fn(struct work_struct *work); | |
| 145 | 146 | |
| 146 | 147 | /* IOCTL */ |
| 147 | 148 | int drm_mode_connector_property_set_ioctl(struct drm_device *dev, |
| @@ -1731,7 +1731,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); · 1730 unmodified lines | ||
| 1731 | 1731 | * |
| 1732 | 1732 | * Returns true if @vendor is in @edid, false otherwise |
| 1733 | 1733 | */ |
| 1734 | −static bool edid_vendor(struct edid *edid, const char *vendor) | |
| 1734 | +static bool edid_vendor(const struct edid *edid, const char *vendor) | |
| 1735 | 1735 | { |
| 1736 | 1736 | char edid_vendor[3]; |
| 1737 | 1737 | |
| @@ -1749,7 +1749,7 @@ static bool edid_vendor(struct edid *edid, const char *vendor) · 11 unmodified lines | ||
| 1749 | 1749 | * |
| 1750 | 1750 | * This tells subsequent routines what fixes they need to apply. |
| 1751 | 1751 | */ |
| 1752 | −static u32 edid_get_quirks(struct edid *edid) | |
| 1752 | +static u32 edid_get_quirks(const struct edid *edid) | |
| 1753 | 1753 | { |
| 1754 | 1754 | const struct edid_quirk *quirk; |
| 1755 | 1755 | int i; |
| @@ -2813,7 +2813,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, · 1057 unmodified lines | ||
| 2813 | 2813 | /* |
| 2814 | 2814 | * Search EDID for CEA extension block. |
| 2815 | 2815 | */ |
| 2816 | −static u8 *drm_find_edid_extension(struct edid *edid, int ext_id) | |
| 2816 | +static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id) | |
| 2817 | 2817 | { |
| 2818 | 2818 | u8 *edid_ext = NULL; |
| 2819 | 2819 | int i; |
| @@ -2835,12 +2835,12 @@ static u8 *drm_find_edid_extension(struct edid *edid, int ext_id) · 15 unmodified lines | ||
| 2835 | 2835 | return edid_ext; |
| 2836 | 2836 | } |
| 2837 | 2837 | |
| 2838 | −static u8 *drm_find_cea_extension(struct edid *edid) | |
| 2838 | +static u8 *drm_find_cea_extension(const struct edid *edid) | |
| 2839 | 2839 | { |
| 2840 | 2840 | return drm_find_edid_extension(edid, CEA_EXT); |
| 2841 | 2841 | } |
| 2842 | 2842 | |
| 2843 | −static u8 *drm_find_displayid_extension(struct edid *edid) | |
| 2843 | +static u8 *drm_find_displayid_extension(const struct edid *edid) | |
| 2844 | 2844 | { |
| 2845 | 2845 | return drm_find_edid_extension(edid, DISPLAYID_EXT); |
| 2846 | 2846 | } |
| @@ -4363,7 +4363,7 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db) · 1516 unmodified lines | ||
| 4363 | 4363 | } |
| 4364 | 4364 | |
| 4365 | 4365 | static void drm_parse_cea_ext(struct drm_connector *connector, |
| 4366 | − struct edid *edid) | |
| 4366 | + const struct edid *edid) | |
| 4367 | 4367 | { |
| 4368 | 4368 | struct drm_display_info *info = &connector->display_info; |
| 4369 | 4369 | const u8 *edid_ext; |
| @@ -4397,11 +4397,33 @@ static void drm_parse_cea_ext(struct drm_connector *connector, · 27 unmodified lines | ||
| 4397 | 4397 | } |
| 4398 | 4398 | } |
| 4399 | 4399 | |
| 4400 | −static void drm_add_display_info(struct drm_connector *connector, | |
| 4401 | − struct edid *edid, u32 quirks) | |
| 4400 | +/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset | |
| 4401 | + * all of the values which would have been set from EDID | |
| 4402 | + */ | |
| 4403 | +void | |
| 4404 | +drm_reset_display_info(struct drm_connector *connector) | |
| 4402 | 4405 | { |
| 4403 | 4406 | struct drm_display_info *info = &connector->display_info; |
| 4404 | 4407 | |
| 4408 | + info->width_mm = 0; | |
| 4409 | + info->height_mm = 0; | |
| 4410 | + | |
| 4411 | + info->bpc = 0; | |
| 4412 | + info->color_formats = 0; | |
| 4413 | + info->cea_rev = 0; | |
| 4414 | + info->max_tmds_clock = 0; | |
| 4415 | + info->dvi_dual = false; | |
| 4416 | + | |
| 4417 | + info->non_desktop = 0; | |
| 4418 | +} | |
| 4419 | +EXPORT_SYMBOL_GPL(drm_reset_display_info); | |
| 4420 | + | |
| 4421 | +u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) | |
| 4422 | +{ | |
| 4423 | + struct drm_display_info *info = &connector->display_info; | |
| 4424 | + | |
| 4425 | + u32 quirks = edid_get_quirks(edid); | |
| 4426 | + | |
| 4405 | 4427 | info->width_mm = edid->width_cm * 10; |
| 4406 | 4428 | info->height_mm = edid->height_cm * 10; |
| 4407 | 4429 | |
| @@ -4414,11 +4436,13 @@ static void drm_add_display_info(struct drm_connector *connector, · 6 unmodified lines | ||
| 4414 | 4436 | |
| 4415 | 4437 | info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP); |
| 4416 | 4438 | |
| 4439 | + DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop); | |
| 4440 | + | |
| 4417 | 4441 | if (edid->revision < 3) |
| 4418 | − return; | |
| 4442 | + return quirks; | |
| 4419 | 4443 | |
| 4420 | 4444 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) |
| 4421 | − return; | |
| 4445 | + return quirks; | |
| 4422 | 4446 | |
| 4423 | 4447 | drm_parse_cea_ext(connector, edid); |
| 4424 | 4448 | |
| @@ -4438,7 +4462,7 @@ static void drm_add_display_info(struct drm_connector *connector, · 13 unmodified lines | ||
| 4438 | 4462 | |
| 4439 | 4463 | /* Only defined for 1.4 with digital displays */ |
| 4440 | 4464 | if (edid->revision < 4) |
| 4441 | − return; | |
| 4465 | + return quirks; | |
| 4442 | 4466 | |
| 4443 | 4467 | switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { |
| 4444 | 4468 | case DRM_EDID_DIGITAL_DEPTH_6: |
| @@ -4473,7 +4497,9 @@ static void drm_add_display_info(struct drm_connector *connector, · 28 unmodified lines | ||
| 4473 | 4497 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
| 4474 | 4498 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) |
| 4475 | 4499 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
| 4500 | + return quirks; | |
| 4476 | 4501 | } |
| 4502 | +EXPORT_SYMBOL_GPL(drm_add_display_info); | |
| 4477 | 4503 | |
| 4478 | 4504 | static int validate_displayid(u8 *displayid, int length, int idx) |
| 4479 | 4505 | { |
| @@ -4627,14 +4653,12 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) · 147 unmodified lines | ||
| 4627 | 4653 | return 0; |
| 4628 | 4654 | } |
| 4629 | 4655 | |
| 4630 | − quirks = edid_get_quirks(edid); | |
| 4631 | − | |
| 4632 | 4656 | /* |
| 4633 | 4657 | * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks. |
| 4634 | 4658 | * To avoid multiple parsing of same block, lets parse that map |
| 4635 | 4659 | * from sink info, before parsing CEA modes. |
| 4636 | 4660 | */ |
| 4637 | − drm_add_display_info(connector, edid, quirks); | |
| 4661 | + quirks = drm_add_display_info(connector, edid); | |
| 4638 | 4662 | |
| 4639 | 4663 | /* |
| 4640 | 4664 | * EDID spec says modes should be preferred in this order: |
| @@ -220,17 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr · 219 unmodified lines | ||
| 220 | 220 | |
| 221 | 221 | mutex_lock(&dev->mode_config.idr_mutex); |
| 222 | 222 | |
| 223 | − /* Insert the new lessee into the tree */ | |
| 224 | − id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); | |
| 225 | − if (id < 0) { | |
| 226 | − error = id; | |
| 227 | − goto out_lessee; | |
| 228 | − } | |
| 229 | − | |
| 230 | − lessee->lessee_id = id; | |
| 231 | − lessee->lessor = drm_master_get(lessor); | |
| 232 | − list_add_tail(&lessee->lessee_list, &lessor->lessees); | |
| 233 | − | |
| 234 | 223 | idr_for_each_entry(leases, entry, object) { |
| 235 | 224 | error = 0; |
| 236 | 225 | if (!idr_find(&dev->mode_config.crtc_idr, object)) |
| @@ -246,6 +235,17 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr · 9 unmodified lines | ||
| 246 | 235 | } |
| 247 | 236 | } |
| 248 | 237 | |
| 238 | + /* Insert the new lessee into the tree */ | |
| 239 | + id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); | |
| 240 | + if (id < 0) { | |
| 241 | + error = id; | |
| 242 | + goto out_lessee; | |
| 243 | + } | |
| 244 | + | |
| 245 | + lessee->lessee_id = id; | |
| 246 | + lessee->lessor = drm_master_get(lessor); | |
| 247 | + list_add_tail(&lessee->lessee_list, &lessor->lessees); | |
| 248 | + | |
| 249 | 249 | /* Move the leases over */ |
| 250 | 250 | lessee->leases = *leases; |
| 251 | 251 | DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor); |
| @@ -254,10 +254,10 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr · 2 unmodified lines | ||
| 254 | 254 | return lessee; |
| 255 | 255 | |
| 256 | 256 | out_lessee: |
| 257 | − drm_master_put(&lessee); | |
| 258 | − | |
| 259 | 257 | mutex_unlock(&dev->mode_config.idr_mutex); |
| 260 | 258 | |
| 259 | + drm_master_put(&lessee); | |
| 260 | + | |
| 261 | 261 | return ERR_PTR(error); |
| 262 | 262 | } |
| 263 | 263 | |
| @@ -575,21 +575,23 @@ EXPORT_SYMBOL(drm_mm_remove_node); · 574 unmodified lines | ||
| 575 | 575 | */ |
| 576 | 576 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) |
| 577 | 577 | { |
| 578 | + struct drm_mm *mm = old->mm; | |
| 579 | + | |
| 578 | 580 | DRM_MM_BUG_ON(!old->allocated); |
| 579 | 581 | |
| 580 | 582 | *new = *old; |
| 581 | 583 | |
| 582 | 584 | list_replace(&old->node_list, &new->node_list); |
| 583 | − rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree.rb_root); | |
| 585 | + rb_replace_node_cached(&old->rb, &new->rb, &mm->interval_tree); | |
| 584 | 586 | |
| 585 | 587 | if (drm_mm_hole_follows(old)) { |
| 586 | 588 | list_replace(&old->hole_stack, &new->hole_stack); |
| 587 | 589 | rb_replace_node(&old->rb_hole_size, |
| 588 | 590 | &new->rb_hole_size, |
| 589 | − &old->mm->holes_size); | |
| 591 | + &mm->holes_size); | |
| 590 | 592 | rb_replace_node(&old->rb_hole_addr, |
| 591 | 593 | &new->rb_hole_addr, |
| 592 | − &old->mm->holes_addr); | |
| 594 | + &mm->holes_addr); | |
| 593 | 595 | } |
| 594 | 596 | |
| 595 | 597 | old->allocated = false; |
| @@ -382,6 +382,9 @@ void drm_mode_config_init(struct drm_device *dev) · 381 unmodified lines | ||
| 382 | 382 | ida_init(&dev->mode_config.connector_ida); |
| 383 | 383 | spin_lock_init(&dev->mode_config.connector_list_lock); |
| 384 | 384 | |
| 385 | + init_llist_head(&dev->mode_config.connector_free_list); | |
| 386 | + INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn); | |
| 387 | + | |
| 385 | 388 | drm_mode_create_standard_properties(dev); |
| 386 | 389 | |
| 387 | 390 | /* Just to be sure */ |
| @@ -432,7 +435,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) · 44 unmodified lines | ||
| 432 | 435 | } |
| 433 | 436 | drm_connector_list_iter_end(&conn_iter); |
| 434 | 437 | /* connector_iter drops references in a work item. */ |
| 435 | − flush_scheduled_work(); | |
| 438 | + flush_work(&dev->mode_config.connector_free_work); | |
| 436 | 439 | if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) { |
| 437 | 440 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 438 | 441 | drm_for_each_connector_iter(connector, &conn_iter) |
| @@ -558,11 +558,10 @@ int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) · 557 unmodified lines | ||
| 558 | 558 | } |
| 559 | 559 | |
| 560 | 560 | /* |
| 561 | − * setplane_internal - setplane handler for internal callers | |
| 561 | + * __setplane_internal - setplane handler for internal callers | |
| 562 | 562 | * |
| 563 | − * Note that we assume an extra reference has already been taken on fb. If the | |
| 564 | − * update fails, this reference will be dropped before return; if it succeeds, | |
| 565 | − * the previous framebuffer (if any) will be unreferenced instead. | |
| 563 | + * This function will take a reference on the new fb for the plane | |
| 564 | + * on success. | |
| 566 | 565 | * |
| 567 | 566 | * src_{x,y,w,h} are provided in 16.16 fixed point format |
| 568 | 567 | */ |
| @@ -630,14 +629,12 @@ static int __setplane_internal(struct drm_plane *plane, · 61 unmodified lines | ||
| 630 | 629 | if (!ret) { |
| 631 | 630 | plane->crtc = crtc; |
| 632 | 631 | plane->fb = fb; |
| 633 | − fb = NULL; | |
| 632 | + drm_framebuffer_get(plane->fb); | |
| 634 | 633 | } else { |
| 635 | 634 | plane->old_fb = NULL; |
| 636 | 635 | } |
| 637 | 636 | |
| 638 | 637 | out: |
| 639 | − if (fb) | |
| 640 | − drm_framebuffer_put(fb); | |
| 641 | 638 | if (plane->old_fb) |
| 642 | 639 | drm_framebuffer_put(plane->old_fb); |
| 643 | 640 | plane->old_fb = NULL; |
| @@ -685,6 +682,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 41 unmodified lines | ||
| 685 | 682 | struct drm_plane *plane; |
| 686 | 683 | struct drm_crtc *crtc = NULL; |
| 687 | 684 | struct drm_framebuffer *fb = NULL; |
| 685 | + int ret; | |
| 688 | 686 | |
| 689 | 687 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 690 | 688 | return -EINVAL; |
| @@ -717,15 +715,16 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 26 unmodified lines | ||
| 717 | 715 | } |
| 718 | 716 | } |
| 719 | 717 | |
| 720 | − /* | |
| 721 | − * setplane_internal will take care of deref'ing either the old or new | |
| 722 | − * framebuffer depending on success. | |
| 723 | − */ | |
| 724 | − return setplane_internal(plane, crtc, fb, | |
| 725 | − plane_req->crtc_x, plane_req->crtc_y, | |
| 726 | − plane_req->crtc_w, plane_req->crtc_h, | |
| 727 | − plane_req->src_x, plane_req->src_y, | |
| 728 | − plane_req->src_w, plane_req->src_h); | |
| 718 | + ret = setplane_internal(plane, crtc, fb, | |
| 719 | + plane_req->crtc_x, plane_req->crtc_y, | |
| 720 | + plane_req->crtc_w, plane_req->crtc_h, | |
| 721 | + plane_req->src_x, plane_req->src_y, | |
| 722 | + plane_req->src_w, plane_req->src_h); | |
| 723 | + | |
| 724 | + if (fb) | |
| 725 | + drm_framebuffer_put(fb); | |
| 726 | + | |
| 727 | + return ret; | |
| 729 | 728 | } |
| 730 | 729 | |
| 731 | 730 | static int drm_mode_cursor_universal(struct drm_crtc *crtc, |
| @@ -788,13 +787,12 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, · 56 unmodified lines | ||
| 788 | 787 | src_h = fb->height << 16; |
| 789 | 788 | } |
| 790 | 789 | |
| 791 | − /* | |
| 792 | − * setplane_internal will take care of deref'ing either the old or new | |
| 793 | − * framebuffer depending on success. | |
| 794 | − */ | |
| 795 | 790 | ret = __setplane_internal(crtc->cursor, crtc, fb, |
| 796 | − crtc_x, crtc_y, crtc_w, crtc_h, | |
| 797 | − 0, 0, src_w, src_h, ctx); | |
| 791 | + crtc_x, crtc_y, crtc_w, crtc_h, | |
| 792 | + 0, 0, src_w, src_h, ctx); | |
| 793 | + | |
| 794 | + if (fb) | |
| 795 | + drm_framebuffer_put(fb); | |
| 798 | 796 | |
| 799 | 797 | /* Update successful; save new cursor position, if necessary */ |
| 800 | 798 | if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { |
| @@ -369,40 +369,26 @@ static const struct file_operations drm_syncobj_file_fops = { · 368 unmodified lines | ||
| 369 | 369 | .release = drm_syncobj_file_release, |
| 370 | 370 | }; |
| 371 | 371 | |
| 372 | −static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj) | |
| 373 | −{ | |
| 374 | − struct file *file = anon_inode_getfile("syncobj_file", | |
| 375 | − &drm_syncobj_file_fops, | |
| 376 | − syncobj, 0); | |
| 377 | − if (IS_ERR(file)) | |
| 378 | − return PTR_ERR(file); | |
| 379 | − | |
| 380 | − drm_syncobj_get(syncobj); | |
| 381 | − if (cmpxchg(&syncobj->file, NULL, file)) { | |
| 382 | − /* lost the race */ | |
| 383 | − fput(file); | |
| 384 | − } | |
| 385 | − | |
| 386 | − return 0; | |
| 387 | −} | |
| 388 | − | |
| 389 | 372 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) |
| 390 | 373 | { |
| 391 | − int ret; | |
| 374 | + struct file *file; | |
| 392 | 375 | int fd; |
| 393 | 376 | |
| 394 | 377 | fd = get_unused_fd_flags(O_CLOEXEC); |
| 395 | 378 | if (fd < 0) |
| 396 | 379 | return fd; |
| 397 | 380 | |
| 398 | − if (!syncobj->file) { | |
| 399 | − ret = drm_syncobj_alloc_file(syncobj); | |
| 400 | − if (ret) { | |
| 401 | − put_unused_fd(fd); | |
| 402 | − return ret; | |
| 403 | − } | |
| 381 | + file = anon_inode_getfile("syncobj_file", | |
| 382 | + &drm_syncobj_file_fops, | |
| 383 | + syncobj, 0); | |
| 384 | + if (IS_ERR(file)) { | |
| 385 | + put_unused_fd(fd); | |
| 386 | + return PTR_ERR(file); | |
| 404 | 387 | } |
| 405 | − fd_install(fd, syncobj->file); | |
| 388 | + | |
| 389 | + drm_syncobj_get(syncobj); | |
| 390 | + fd_install(fd, file); | |
| 391 | + | |
| 406 | 392 | *p_fd = fd; |
| 407 | 393 | return 0; |
| 408 | 394 | } |
| @@ -422,31 +408,24 @@ static int drm_syncobj_handle_to_fd(struct drm_file *file_private, · 13 unmodified lines | ||
| 422 | 408 | return ret; |
| 423 | 409 | } |
| 424 | 410 | |
| 425 | −static struct drm_syncobj *drm_syncobj_fdget(int fd) | |
| 426 | −{ | |
| 427 | − struct file *file = fget(fd); | |
| 428 | − | |
| 429 | − if (!file) | |
| 430 | − return NULL; | |
| 431 | − if (file->f_op != &drm_syncobj_file_fops) | |
| 432 | − goto err; | |
| 433 | − | |
| 434 | − return file->private_data; | |
| 435 | −err: | |
| 436 | − fput(file); | |
| 437 | − return NULL; | |
| 438 | −}; | |
| 439 | − | |
| 440 | 411 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, |
| 441 | 412 | int fd, u32 *handle) |
| 442 | 413 | { |
| 443 | − struct drm_syncobj *syncobj = drm_syncobj_fdget(fd); | |
| 414 | + struct drm_syncobj *syncobj; | |
| 415 | + struct file *file; | |
| 444 | 416 | int ret; |
| 445 | 417 | |
| 446 | − if (!syncobj) | |
| 418 | + file = fget(fd); | |
| 419 | + if (!file) | |
| 447 | 420 | return -EINVAL; |
| 448 | 421 | |
| 422 | + if (file->f_op != &drm_syncobj_file_fops) { | |
| 423 | + fput(file); | |
| 424 | + return -EINVAL; | |
| 425 | + } | |
| 426 | + | |
| 449 | 427 | /* take a reference to put in the idr */ |
| 428 | + syncobj = file->private_data; | |
| 450 | 429 | drm_syncobj_get(syncobj); |
| 451 | 430 | |
| 452 | 431 | idr_preload(GFP_KERNEL); |
| @@ -455,12 +434,14 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private, · 2 unmodified lines | ||
| 455 | 434 | spin_unlock(&file_private->syncobj_table_lock); |
| 456 | 435 | idr_preload_end(); |
| 457 | 436 | |
| 458 | − if (ret < 0) { | |
| 459 | − fput(syncobj->file); | |
| 460 | − return ret; | |
| 461 | − } | |
| 462 | − *handle = ret; | |
| 463 | − return 0; | |
| 437 | + if (ret > 0) { | |
| 438 | + *handle = ret; | |
| 439 | + ret = 0; | |
| 440 | + } else | |
| 441 | + drm_syncobj_put(syncobj); | |
| 442 | + | |
| 443 | + fput(file); | |
| 444 | + return ret; | |
| 464 | 445 | } |
| 465 | 446 | |
| 466 | 447 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, |
| @@ -266,6 +266,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 265 unmodified lines | ||
| 266 | 266 | /* Clear host CRT status, so guest couldn't detect this host CRT. */ |
| 267 | 267 | if (IS_BROADWELL(dev_priv)) |
| 268 | 268 | vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; |
| 269 | + | |
| 270 | + vgpu_vreg(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; | |
| 269 | 271 | } |
| 270 | 272 | |
| 271 | 273 | static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) |
| @@ -282,7 +284,6 @@ static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) · 10 unmodified lines | ||
| 282 | 284 | static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, |
| 283 | 285 | int type, unsigned int resolution) |
| 284 | 286 | { |
| 285 | − struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | |
| 286 | 287 | struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); |
| 287 | 288 | |
| 288 | 289 | if (WARN_ON(resolution >= GVT_EDID_NUM)) |
| @@ -308,7 +309,7 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, · 19 unmodified lines | ||
| 308 | 309 | port->type = type; |
| 309 | 310 | |
| 310 | 311 | emulate_monitor_status_change(vgpu); |
| 311 | − vgpu_vreg(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; | |
| 312 | + | |
| 312 | 313 | return 0; |
| 313 | 314 | } |
| 314 | 315 | |
| @@ -330,17 +330,10 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) · 329 unmodified lines | ||
| 330 | 330 | * must wait for all rendering to complete to the object (as unbinding |
| 331 | 331 | * must anyway), and retire the requests. |
| 332 | 332 | */ |
| 333 | − ret = i915_gem_object_wait(obj, | |
| 334 | − I915_WAIT_INTERRUPTIBLE | | |
| 335 | − I915_WAIT_LOCKED | | |
| 336 | − I915_WAIT_ALL, | |
| 337 | − MAX_SCHEDULE_TIMEOUT, | |
| 338 | − NULL); | |
| 333 | + ret = i915_gem_object_set_to_cpu_domain(obj, false); | |
| 339 | 334 | if (ret) |
| 340 | 335 | return ret; |
| 341 | 336 | |
| 342 | − i915_gem_retire_requests(to_i915(obj->base.dev)); | |
| 343 | − | |
| 344 | 337 | while ((vma = list_first_entry_or_null(&obj->vma_list, |
| 345 | 338 | struct i915_vma, |
| 346 | 339 | obj_link))) { |
| @@ -367,6 +367,7 @@ struct i915_sw_dma_fence_cb { · 366 unmodified lines | ||
| 367 | 367 | struct dma_fence *dma; |
| 368 | 368 | struct timer_list timer; |
| 369 | 369 | struct irq_work work; |
| 370 | + struct rcu_head rcu; | |
| 370 | 371 | }; |
| 371 | 372 | |
| 372 | 373 | static void timer_i915_sw_fence_wake(struct timer_list *t) |
| @@ -406,7 +407,7 @@ static void irq_i915_sw_fence_work(struct irq_work *wrk) · 33 unmodified lines | ||
| 406 | 407 | del_timer_sync(&cb->timer); |
| 407 | 408 | dma_fence_put(cb->dma); |
| 408 | 409 | |
| 409 | − kfree(cb); | |
| 410 | + kfree_rcu(cb, rcu); | |
| 410 | 411 | } |
| 411 | 412 | |
| 412 | 413 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, |
| @@ -186,7 +186,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) · 185 unmodified lines | ||
| 186 | 186 | struct intel_wait *wait, *n, *first; |
| 187 | 187 | |
| 188 | 188 | if (!b->irq_armed) |
| 189 | − return; | |
| 189 | + goto wakeup_signaler; | |
| 190 | 190 | |
| 191 | 191 | /* We only disarm the irq when we are idle (all requests completed), |
| 192 | 192 | * so if the bottom-half remains asleep, it missed the request |
| @@ -208,6 +208,14 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) · 15 unmodified lines | ||
| 208 | 208 | b->waiters = RB_ROOT; |
| 209 | 209 | |
| 210 | 210 | spin_unlock_irq(&b->rb_lock); |
| 211 | + | |
| 212 | + /* | |
| 213 | + * The signaling thread may be asleep holding a reference to a request, | |
| 214 | + * that had its signaling cancelled prior to being preempted. We need | |
| 215 | + * to kick the signaler, just in case, to release any such reference. | |
| 216 | + */ | |
| 217 | +wakeup_signaler: | |
| 218 | + wake_up_process(b->signaler); | |
| 211 | 219 | } |
| 212 | 220 | |
| 213 | 221 | static bool use_fake_irq(const struct intel_breadcrumbs *b) |
| @@ -651,23 +659,15 @@ static int intel_breadcrumbs_signaler(void *arg) · 437 unmodified lines | ||
| 651 | 659 | } |
| 652 | 660 | |
| 653 | 661 | if (unlikely(do_schedule)) { |
| 654 | − DEFINE_WAIT(exec); | |
| 655 | − | |
| 656 | 662 | if (kthread_should_park()) |
| 657 | 663 | kthread_parkme(); |
| 658 | 664 | |
| 659 | − if (kthread_should_stop()) { | |
| 660 | − GEM_BUG_ON(request); | |
| 665 | + if (unlikely(kthread_should_stop())) { | |
| 666 | + i915_gem_request_put(request); | |
| 661 | 667 | break; |
| 662 | 668 | } |
| 663 | 669 | |
| 664 | − if (request) | |
| 665 | − add_wait_queue(&request->execute, &exec); | |
| 666 | − | |
| 667 | 670 | schedule(); |
| 668 | − | |
| 669 | − if (request) | |
| 670 | − remove_wait_queue(&request->execute, &exec); | |
| 671 | 671 | } |
| 672 | 672 | i915_gem_request_put(request); |
| 673 | 673 | } while (1); |
| @@ -2128,6 +2128,8 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, · 2127 unmodified lines | ||
| 2128 | 2128 | if (WARN_ON(!pll)) |
| 2129 | 2129 | return; |
| 2130 | 2130 | |
| 2131 | + mutex_lock(&dev_priv->dpll_lock); | |
| 2132 | + | |
| 2131 | 2133 | if (IS_CANNONLAKE(dev_priv)) { |
| 2132 | 2134 | /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ |
| 2133 | 2135 | val = I915_READ(DPCLKA_CFGCR0); |
| @@ -2157,6 +2159,8 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, · 23 unmodified lines | ||
| 2157 | 2159 | } else if (INTEL_INFO(dev_priv)->gen < 9) { |
| 2158 | 2160 | I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); |
| 2159 | 2161 | } |
| 2162 | + | |
| 2163 | + mutex_unlock(&dev_priv->dpll_lock); | |
| 2160 | 2164 | } |
| 2161 | 2165 | |
| 2162 | 2166 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) |
| @@ -9944,11 +9944,10 @@ found: · 9943 unmodified lines | ||
| 9944 | 9944 | } |
| 9945 | 9945 | |
| 9946 | 9946 | ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0); |
| 9947 | + drm_framebuffer_put(fb); | |
| 9947 | 9948 | if (ret) |
| 9948 | 9949 | goto fail; |
| 9949 | 9950 | |
| 9950 | − drm_framebuffer_put(fb); | |
| 9951 | − | |
| 9952 | 9951 | ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); |
| 9953 | 9952 | if (ret) |
| 9954 | 9953 | goto fail; |
| @@ -13195,7 +13194,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) · 3240 unmodified lines | ||
| 13195 | 13194 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); |
| 13196 | 13195 | primary->check_plane = intel_check_primary_plane; |
| 13197 | 13196 | |
| 13198 | − if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { | |
| 13197 | + if (INTEL_GEN(dev_priv) >= 10) { | |
| 13199 | 13198 | intel_primary_formats = skl_primary_formats; |
| 13200 | 13199 | num_formats = ARRAY_SIZE(skl_primary_formats); |
| 13201 | 13200 | modifiers = skl_format_modifiers_ccs; |
| @@ -193,7 +193,7 @@ static bool lpe_audio_detect(struct drm_i915_private *dev_priv) · 192 unmodified lines | ||
| 193 | 193 | }; |
| 194 | 194 | |
| 195 | 195 | if (!pci_dev_present(atom_hdaudio_ids)) { |
| 196 | − DRM_INFO("%s\n", "HDaudio controller not detected, using LPE audio instead\n"); | |
| 196 | + DRM_INFO("HDaudio controller not detected, using LPE audio instead\n"); | |
| 197 | 197 | lpe_present = true; |
| 198 | 198 | } |
| 199 | 199 | } |
| @@ -224,7 +224,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, · 223 unmodified lines | ||
| 224 | 224 | /* Determine if we can get a cache-coherent map, forcing |
| 225 | 225 | * uncached mapping if we can't. |
| 226 | 226 | */ |
| 227 | − if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | |
| 227 | + if (!nouveau_drm_use_coherent_gpu_mapping(drm)) | |
| 228 | 228 | nvbo->force_coherent = true; |
| 229 | 229 | } |
| 230 | 230 | |
| @@ -262,7 +262,8 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, · 31 unmodified lines | ||
| 262 | 262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && |
| 263 | 263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) |
| 264 | 264 | continue; |
| 265 | − if ((flags & TTM_PL_FLAG_TT ) && !vmm->page[i].host) | |
| 265 | + if ((flags & TTM_PL_FLAG_TT) && | |
| 266 | + (!vmm->page[i].host || vmm->page[i].shift > PAGE_SHIFT)) | |
| 266 | 267 | continue; |
| 267 | 268 | |
| 268 | 269 | /* Select this page size if it's the first that supports |
| @@ -152,9 +152,9 @@ nouveau_cli_work_queue(struct nouveau_cli *cli, struct dma_fence *fence, · 151 unmodified lines | ||
| 152 | 152 | work->cli = cli; |
| 153 | 153 | mutex_lock(&cli->lock); |
| 154 | 154 | list_add_tail(&work->head, &cli->worker); |
| 155 | − mutex_unlock(&cli->lock); | |
| 156 | 155 | if (dma_fence_add_callback(fence, &work->cb, nouveau_cli_work_fence)) |
| 157 | 156 | nouveau_cli_work_fence(fence, &work->cb); |
| 157 | + mutex_unlock(&cli->lock); | |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | 160 | static void |
| @@ -157,8 +157,8 @@ struct nouveau_drm { · 156 unmodified lines | ||
| 157 | 157 | struct nvif_object copy; |
| 158 | 158 | int mtrr; |
| 159 | 159 | int type_vram; |
| 160 | − int type_host; | |
| 161 | − int type_ncoh; | |
| 160 | + int type_host[2]; | |
| 161 | + int type_ncoh[2]; | |
| 162 | 162 | } ttm; |
| 163 | 163 | |
| 164 | 164 | /* GEM interface support */ |
| @@ -217,6 +217,13 @@ nouveau_drm(struct drm_device *dev) · 52 unmodified lines | ||
| 217 | 217 | return dev->dev_private; |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | +static inline bool | |
| 221 | +nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm) | |
| 222 | +{ | |
| 223 | + struct nvif_mmu *mmu = &drm->client.mmu; | |
| 224 | + return !(mmu->type[drm->ttm.type_host[0]].type & NVIF_MEM_UNCACHED); | |
| 225 | +} | |
| 226 | + | |
| 220 | 227 | int nouveau_pmops_suspend(struct device *); |
| 221 | 228 | int nouveau_pmops_resume(struct device *); |
| 222 | 229 | bool nouveau_pmops_runtime(void); |
| @@ -429,7 +429,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) · 428 unmodified lines | ||
| 429 | 429 | drm_fb_helper_unregister_fbi(&fbcon->helper); |
| 430 | 430 | drm_fb_helper_fini(&fbcon->helper); |
| 431 | 431 | |
| 432 | − if (nouveau_fb->nvbo) { | |
| 432 | + if (nouveau_fb && nouveau_fb->nvbo) { | |
| 433 | 433 | nouveau_vma_del(&nouveau_fb->vma); |
| 434 | 434 | nouveau_bo_unmap(nouveau_fb->nvbo); |
| 435 | 435 | nouveau_bo_unpin(nouveau_fb->nvbo); |
| @@ -103,10 +103,10 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) · 102 unmodified lines | ||
| 103 | 103 | u8 type; |
| 104 | 104 | int ret; |
| 105 | 105 | |
| 106 | − if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | |
| 107 | − type = drm->ttm.type_ncoh; | |
| 106 | + if (!nouveau_drm_use_coherent_gpu_mapping(drm)) | |
| 107 | + type = drm->ttm.type_ncoh[!!mem->kind]; | |
| 108 | 108 | else |
| 109 | − type = drm->ttm.type_host; | |
| 109 | + type = drm->ttm.type_host[0]; | |
| 110 | 110 | |
| 111 | 111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) |
| 112 | 112 | mem->comp = mem->kind = 0; |
| @@ -235,27 +235,46 @@ nouveau_ttm_global_release(struct nouveau_drm *drm) · 234 unmodified lines | ||
| 235 | 235 | drm->ttm.mem_global_ref.release = NULL; |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | −int | |
| 239 | −nouveau_ttm_init(struct nouveau_drm *drm) | |
| 238 | +static int | |
| 239 | +nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind) | |
| 240 | 240 | { |
| 241 | − struct nvkm_device *device = nvxx_device(&drm->client.device); | |
| 242 | − struct nvkm_pci *pci = device->pci; | |
| 243 | 241 | struct nvif_mmu *mmu = &drm->client.mmu; |
| 244 | − struct drm_device *dev = drm->dev; | |
| 245 | − int typei, ret; | |
| 242 | + int typei; | |
| 246 | 243 | |
| 247 | 244 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | |
| 248 | − NVIF_MEM_COHERENT); | |
| 245 | + kind | NVIF_MEM_COHERENT); | |
| 249 | 246 | if (typei < 0) |
| 250 | 247 | return -ENOSYS; |
| 251 | 248 | |
| 252 | − drm->ttm.type_host = typei; | |
| 249 | + drm->ttm.type_host[!!kind] = typei; | |
| 253 | 250 | |
| 254 | − typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE); | |
| 251 | + typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | kind); | |
| 255 | 252 | if (typei < 0) |
| 256 | 253 | return -ENOSYS; |
| 257 | 254 | |
| 258 | − drm->ttm.type_ncoh = typei; | |
| 255 | + drm->ttm.type_ncoh[!!kind] = typei; | |
| 256 | + return 0; | |
| 257 | +} | |
| 258 | + | |
| 259 | +int | |
| 260 | +nouveau_ttm_init(struct nouveau_drm *drm) | |
| 261 | +{ | |
| 262 | + struct nvkm_device *device = nvxx_device(&drm->client.device); | |
| 263 | + struct nvkm_pci *pci = device->pci; | |
| 264 | + struct nvif_mmu *mmu = &drm->client.mmu; | |
| 265 | + struct drm_device *dev = drm->dev; | |
| 266 | + int typei, ret; | |
| 267 | + | |
| 268 | + ret = nouveau_ttm_init_host(drm, 0); | |
| 269 | + if (ret) | |
| 270 | + return ret; | |
| 271 | + | |
| 272 | + if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA && | |
| 273 | + drm->client.device.info.chipset != 0x50) { | |
| 274 | + ret = nouveau_ttm_init_host(drm, NVIF_MEM_KIND); | |
| 275 | + if (ret) | |
| 276 | + return ret; | |
| 277 | + } | |
| 259 | 278 | |
| 260 | 279 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && |
| 261 | 280 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
| @@ -67,8 +67,8 @@ nouveau_vma_del(struct nouveau_vma **pvma) · 66 unmodified lines | ||
| 67 | 67 | nvif_vmm_put(&vma->vmm->vmm, &tmp); |
| 68 | 68 | } |
| 69 | 69 | list_del(&vma->head); |
| 70 | − *pvma = NULL; | |
| 71 | 70 | kfree(*pvma); |
| 71 | + *pvma = NULL; | |
| 72 | 72 | } |
| 73 | 73 | } |
| 74 | 74 | |
| @@ -2369,7 +2369,7 @@ nv13b_chipset = { · 2368 unmodified lines | ||
| 2369 | 2369 | .imem = gk20a_instmem_new, |
| 2370 | 2370 | .ltc = gp100_ltc_new, |
| 2371 | 2371 | .mc = gp10b_mc_new, |
| 2372 | − .mmu = gf100_mmu_new, | |
| 2372 | + .mmu = gp10b_mmu_new, | |
| 2373 | 2373 | .secboot = gp10b_secboot_new, |
| 2374 | 2374 | .pmu = gm20b_pmu_new, |
| 2375 | 2375 | .timer = gk20a_timer_new, |
| @@ -36,6 +36,7 @@ nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) · 35 unmodified lines | ||
| 36 | 36 | if (data) { |
| 37 | 37 | *ver = nvbios_rd08(bios, data + 0x00); |
| 38 | 38 | switch (*ver) { |
| 39 | + case 0x20: | |
| 39 | 40 | case 0x21: |
| 40 | 41 | case 0x30: |
| 41 | 42 | case 0x40: |
| @@ -63,6 +64,7 @@ nvbios_dpout_entry(struct nvkm_bios *bios, u8 idx, · 21 unmodified lines | ||
| 63 | 64 | if (data && idx < *cnt) { |
| 64 | 65 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); |
| 65 | 66 | switch (*ver * !!outp) { |
| 67 | + case 0x20: | |
| 66 | 68 | case 0x21: |
| 67 | 69 | case 0x30: |
| 68 | 70 | *hdr = nvbios_rd08(bios, data + 0x04); |
| @@ -96,12 +98,16 @@ nvbios_dpout_parse(struct nvkm_bios *bios, u8 idx, · 27 unmodified lines | ||
| 96 | 98 | info->type = nvbios_rd16(bios, data + 0x00); |
| 97 | 99 | info->mask = nvbios_rd16(bios, data + 0x02); |
| 98 | 100 | switch (*ver) { |
| 101 | + case 0x20: | |
| 102 | + info->mask |= 0x00c0; /* match any link */ | |
| 103 | + /* fall-through */ | |
| 99 | 104 | case 0x21: |
| 100 | 105 | case 0x30: |
| 101 | 106 | info->flags = nvbios_rd08(bios, data + 0x05); |
| 102 | 107 | info->script[0] = nvbios_rd16(bios, data + 0x06); |
| 103 | 108 | info->script[1] = nvbios_rd16(bios, data + 0x08); |
| 104 | − info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | |
| 109 | + if (*len >= 0x0c) | |
| 110 | + info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | |
| 105 | 111 | if (*len >= 0x0f) { |
| 106 | 112 | info->script[2] = nvbios_rd16(bios, data + 0x0c); |
| 107 | 113 | info->script[3] = nvbios_rd16(bios, data + 0x0e); |
| @@ -170,6 +176,7 @@ nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, · 62 unmodified lines | ||
| 170 | 176 | memset(info, 0x00, sizeof(*info)); |
| 171 | 177 | if (data) { |
| 172 | 178 | switch (*ver) { |
| 179 | + case 0x20: | |
| 173 | 180 | case 0x21: |
| 174 | 181 | info->dc = nvbios_rd08(bios, data + 0x02); |
| 175 | 182 | info->pe = nvbios_rd08(bios, data + 0x03); |
| @@ -249,7 +249,7 @@ nv50_instobj_acquire(struct nvkm_memory *memory) · 248 unmodified lines | ||
| 249 | 249 | iobj->base.memory.ptrs = &nv50_instobj_fast; |
| 250 | 250 | else |
| 251 | 251 | iobj->base.memory.ptrs = &nv50_instobj_slow; |
| 252 | − refcount_inc(&iobj->maps); | |
| 252 | + refcount_set(&iobj->maps, 1); | |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | 255 | mutex_unlock(&imem->subdev.mutex); |
| @@ -136,6 +136,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev) · 135 unmodified lines | ||
| 136 | 136 | return ret; |
| 137 | 137 | |
| 138 | 138 | pci->irq = pdev->irq; |
| 139 | + | |
| 140 | + /* Ensure MSI interrupts are armed, for the case where there are | |
| 141 | + * already interrupts pending (for whatever reason) at load time. | |
| 142 | + */ | |
| 143 | + if (pci->msi) | |
| 144 | + pci->func->msi_rearm(pci); | |
| 145 | + | |
| 139 | 146 | return ret; |
| 140 | 147 | } |
| 141 | 148 | |
| @@ -175,11 +175,31 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, · 174 unmodified lines | ||
| 175 | 175 | writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | +static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, | |
| 179 | + const struct drm_display_mode *mode) | |
| 180 | +{ | |
| 181 | + struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); | |
| 182 | + unsigned long rate = mode->clock * 1000; | |
| 183 | + unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ | |
| 184 | + long rounded_rate; | |
| 185 | + | |
| 186 | + /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ | |
| 187 | + if (rate > 165000000) | |
| 188 | + return MODE_CLOCK_HIGH; | |
| 189 | + rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); | |
| 190 | + if (rounded_rate > 0 && | |
| 191 | + max_t(unsigned long, rounded_rate, rate) - | |
| 192 | + min_t(unsigned long, rounded_rate, rate) < diff) | |
| 193 | + return MODE_OK; | |
| 194 | + return MODE_NOCLOCK; | |
| 195 | +} | |
| 196 | + | |
| 178 | 197 | static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { |
| 179 | 198 | .atomic_check = sun4i_hdmi_atomic_check, |
| 180 | 199 | .disable = sun4i_hdmi_disable, |
| 181 | 200 | .enable = sun4i_hdmi_enable, |
| 182 | 201 | .mode_set = sun4i_hdmi_mode_set, |
| 202 | + .mode_valid = sun4i_hdmi_mode_valid, | |
| 183 | 203 | }; |
| 184 | 204 | |
| 185 | 205 | static const struct drm_encoder_funcs sun4i_hdmi_funcs = { |
| @@ -724,12 +724,12 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, · 723 unmodified lines | ||
| 724 | 724 | if (IS_ERR(tcon->crtc)) { |
| 725 | 725 | dev_err(dev, "Couldn't create our CRTC\n"); |
| 726 | 726 | ret = PTR_ERR(tcon->crtc); |
| 727 | − goto err_free_clocks; | |
| 727 | + goto err_free_dotclock; | |
| 728 | 728 | } |
| 729 | 729 | |
| 730 | 730 | ret = sun4i_rgb_init(drm, tcon); |
| 731 | 731 | if (ret < 0) |
| 732 | − goto err_free_clocks; | |
| 732 | + goto err_free_dotclock; | |
| 733 | 733 | |
| 734 | 734 | if (tcon->quirks->needs_de_be_mux) { |
| 735 | 735 | /* |
| @@ -455,6 +455,7 @@ ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) · 454 unmodified lines | ||
| 455 | 455 | freed += (nr_free_pool - shrink_pages) << pool->order; |
| 456 | 456 | if (freed >= sc->nr_to_scan) |
| 457 | 457 | break; |
| 458 | + shrink_pages <<= pool->order; | |
| 458 | 459 | } |
| 459 | 460 | mutex_unlock(&lock); |
| 460 | 461 | return freed; |
| @@ -543,7 +544,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, · 82 unmodified lines | ||
| 543 | 544 | int r = 0; |
| 544 | 545 | unsigned i, j, cpages; |
| 545 | 546 | unsigned npages = 1 << order; |
| 546 | − unsigned max_cpages = min(count, (unsigned)NUM_PAGES_TO_ALLOC); | |
| 547 | + unsigned max_cpages = min(count << order, (unsigned)NUM_PAGES_TO_ALLOC); | |
| 547 | 548 | |
| 548 | 549 | /* allocate array for page caching change */ |
| 549 | 550 | caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); |
| @@ -888,8 +888,10 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) · 887 unmodified lines | ||
| 888 | 888 | /* If we got force-completed because of GPU reset rather than |
| 889 | 889 | * through our IRQ handler, signal the fence now. |
| 890 | 890 | */ |
| 891 | − if (exec->fence) | |
| 891 | + if (exec->fence) { | |
| 892 | 892 | dma_fence_signal(exec->fence); |
| 893 | + dma_fence_put(exec->fence); | |
| 894 | + } | |
| 893 | 895 | |
| 894 | 896 | if (exec->bo) { |
| 895 | 897 | for (i = 0; i < exec->bo_count; i++) { |
| @@ -139,6 +139,7 @@ vc4_irq_finish_render_job(struct drm_device *dev) · 138 unmodified lines | ||
| 139 | 139 | list_move_tail(&exec->head, &vc4->job_done_list); |
| 140 | 140 | if (exec->fence) { |
| 141 | 141 | dma_fence_signal_locked(exec->fence); |
| 142 | + dma_fence_put(exec->fence); | |
| 142 | 143 | exec->fence = NULL; |
| 143 | 144 | } |
| 144 | 145 | vc4_submit_next_render_job(dev); |
| @@ -551,7 +551,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) · 550 unmodified lines | ||
| 551 | 551 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); |
| 552 | 552 | break; |
| 553 | 553 | default: |
| 554 | − hid_err(parser->device, "unknown main item tag 0x%x\n", item->tag); | |
| 554 | + hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag); | |
| 555 | 555 | ret = 0; |
| 556 | 556 | } |
| 557 | 557 | |
| @@ -696,8 +696,16 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, · 695 unmodified lines | ||
| 696 | 696 | (u8 *)&word, 2); |
| 697 | 697 | break; |
| 698 | 698 | case I2C_SMBUS_I2C_BLOCK_DATA: |
| 699 | − size = I2C_SMBUS_BLOCK_DATA; | |
| 700 | − /* fallthrough */ | |
| 699 | + if (read_write == I2C_SMBUS_READ) { | |
| 700 | + read_length = data->block[0]; | |
| 701 | + count = cp2112_write_read_req(buf, addr, read_length, | |
| 702 | + command, NULL, 0); | |
| 703 | + } else { | |
| 704 | + count = cp2112_write_req(buf, addr, command, | |
| 705 | + data->block + 1, | |
| 706 | + data->block[0]); | |
| 707 | + } | |
| 708 | + break; | |
| 701 | 709 | case I2C_SMBUS_BLOCK_DATA: |
| 702 | 710 | if (I2C_SMBUS_READ == read_write) { |
| 703 | 711 | count = cp2112_write_read_req(buf, addr, |
| @@ -785,6 +793,9 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, · 81 unmodified lines | ||
| 785 | 793 | case I2C_SMBUS_WORD_DATA: |
| 786 | 794 | data->word = le16_to_cpup((__le16 *)buf); |
| 787 | 795 | break; |
| 796 | + case I2C_SMBUS_I2C_BLOCK_DATA: | |
| 797 | + memcpy(data->block + 1, buf, read_length); | |
| 798 | + break; | |
| 788 | 799 | case I2C_SMBUS_BLOCK_DATA: |
| 789 | 800 | if (read_length > I2C_SMBUS_BLOCK_MAX) { |
| 790 | 801 | ret = -EPROTO; |
| @@ -32,10 +32,6 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #ifdef CONFIG_HOLTEK_FF |
| 34 | 34 | |
| 35 | −MODULE_LICENSE("GPL"); | |
| 36 | −MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); | |
| 37 | −MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices"); | |
| 38 | − | |
| 39 | 35 | /* |
| 40 | 36 | * These commands and parameters are currently known: |
| 41 | 37 | * |
| @@ -223,3 +219,7 @@ static struct hid_driver holtek_driver = { · 181 unmodified lines | ||
| 223 | 219 | .probe = holtek_probe, |
| 224 | 220 | }; |
| 225 | 221 | module_hid_driver(holtek_driver); |
| 222 | + | |
| 223 | +MODULE_LICENSE("GPL"); | |
| 224 | +MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); | |
| 225 | +MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices"); | |
| @@ -1378,6 +1378,8 @@ void vmbus_device_unregister(struct hv_device *device_obj) · 1377 unmodified lines | ||
| 1378 | 1378 | pr_debug("child device %s unregistered\n", |
| 1379 | 1379 | dev_name(&device_obj->device)); |
| 1380 | 1380 | |
| 1381 | + kset_unregister(device_obj->channels_kset); | |
| 1382 | + | |
| 1381 | 1383 | /* |
| 1382 | 1384 | * Kick off the process of unregistering the device. |
| 1383 | 1385 | * This will call vmbus_remove() and eventually vmbus_device_release() |
| @@ -143,6 +143,7 @@ static int hwmon_thermal_add_sensor(struct device *dev, · 142 unmodified lines | ||
| 143 | 143 | struct hwmon_device *hwdev, int index) |
| 144 | 144 | { |
| 145 | 145 | struct hwmon_thermal_data *tdata; |
| 146 | + struct thermal_zone_device *tzd; | |
| 146 | 147 | |
| 147 | 148 | tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); |
| 148 | 149 | if (!tdata) |
| @@ -151,8 +152,14 @@ static int hwmon_thermal_add_sensor(struct device *dev, · 2 unmodified lines | ||
| 151 | 152 | tdata->hwdev = hwdev; |
| 152 | 153 | tdata->index = index; |
| 153 | 154 | |
| 154 | − devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, | |
| 155 | − &hwmon_thermal_ops); | |
| 155 | + tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, | |
| 156 | + &hwmon_thermal_ops); | |
| 157 | + /* | |
| 158 | + * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, | |
| 159 | + * so ignore that error but forward any other error. | |
| 160 | + */ | |
| 161 | + if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) | |
| 162 | + return PTR_ERR(tzd); | |
| 156 | 163 | |
| 157 | 164 | return 0; |
| 158 | 165 | } |
| @@ -621,14 +628,20 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, · 462 unmodified lines | ||
| 621 | 628 | if (!chip->ops->is_visible(drvdata, hwmon_temp, |
| 622 | 629 | hwmon_temp_input, j)) |
| 623 | 630 | continue; |
| 624 | − if (info[i]->config[j] & HWMON_T_INPUT) | |
| 625 | − hwmon_thermal_add_sensor(dev, hwdev, j); | |
| 631 | + if (info[i]->config[j] & HWMON_T_INPUT) { | |
| 632 | + err = hwmon_thermal_add_sensor(dev, | |
| 633 | + hwdev, j); | |
| 634 | + if (err) | |
| 635 | + goto free_device; | |
| 636 | + } | |
| 626 | 637 | } |
| 627 | 638 | } |
| 628 | 639 | } |
| 629 | 640 | |
| 630 | 641 | return hdev; |
| 631 | 642 | |
| 643 | +free_device: | |
| 644 | + device_unregister(hdev); | |
| 632 | 645 | free_hwmon: |
| 633 | 646 | kfree(hwdev); |
| 634 | 647 | ida_remove: |
| @@ -42,9 +42,11 @@ static struct stm_ftrace { · 41 unmodified lines | ||
| 42 | 42 | * @len: length of the data packet |
| 43 | 43 | */ |
| 44 | 44 | static void notrace |
| 45 | −stm_ftrace_write(const void *buf, unsigned int len) | |
| 45 | +stm_ftrace_write(struct trace_export *export, const void *buf, unsigned int len) | |
| 46 | 46 | { |
| 47 | − stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len); | |
| 47 | + struct stm_ftrace *stm = container_of(export, struct stm_ftrace, ftrace); | |
| 48 | + | |
| 49 | + stm_source_write(&stm->data, STM_FTRACE_CHAN, buf, len); | |
| 48 | 50 | } |
| 49 | 51 | |
| 50 | 52 | static int stm_ftrace_link(struct stm_source_data *data) |
| @@ -379,7 +379,7 @@ static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev) · 378 unmodified lines | ||
| 379 | 379 | return 0; |
| 380 | 380 | } |
| 381 | 381 | |
| 382 | −static struct platform_device_id cht_wc_i2c_adap_id_table[] = { | |
| 382 | +static const struct platform_device_id cht_wc_i2c_adap_id_table[] = { | |
| 383 | 383 | { .name = "cht_wcove_ext_chgr" }, |
| 384 | 384 | {}, |
| 385 | 385 | }; |
| @@ -983,7 +983,7 @@ static void piix4_adap_remove(struct i2c_adapter *adap) · 982 unmodified lines | ||
| 983 | 983 | |
| 984 | 984 | if (adapdata->smba) { |
| 985 | 985 | i2c_del_adapter(adap); |
| 986 | − if (adapdata->port == (0 << 1)) { | |
| 986 | + if (adapdata->port == (0 << piix4_port_shift_sb800)) { | |
| 987 | 987 | release_region(adapdata->smba, SMBIOSIZE); |
| 988 | 988 | if (adapdata->sb800_main) |
| 989 | 989 | release_region(SB800_PIIX4_SMB_IDX, 2); |
| @@ -1,10 +1,11 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 1 | 2 | /* |
| 2 | 3 | * i2c-stm32.h |
| 3 | 4 | * |
| 4 | 5 | * Copyright (C) M'boumba Cedric Madianga 2017 |
| 6 | + * Copyright (C) STMicroelectronics 2017 | |
| 5 | 7 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> |
| 6 | 8 | * |
| 7 | − * License terms: GNU General Public License (GPL), version 2 | |
| 8 | 9 | */ |
| 9 | 10 | |
| 10 | 11 | #ifndef _I2C_STM32_H |
| @@ -1,3 +1,4 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 1 | 2 | /* |
| 2 | 3 | * Driver for STMicroelectronics STM32 I2C controller |
| 3 | 4 | * |
| @@ -6,11 +7,11 @@ · 2 unmodified lines | ||
| 6 | 7 | * http://www.st.com/resource/en/reference_manual/DM00031020.pdf |
| 7 | 8 | * |
| 8 | 9 | * Copyright (C) M'boumba Cedric Madianga 2016 |
| 10 | + * Copyright (C) STMicroelectronics 2017 | |
| 9 | 11 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> |
| 10 | 12 | * |
| 11 | 13 | * This driver is based on i2c-st.c |
| 12 | 14 | * |
| 13 | − * License terms: GNU General Public License (GPL), version 2 | |
| 14 | 15 | */ |
| 15 | 16 | |
| 16 | 17 | #include <linux/clk.h> |
| @@ -1,3 +1,4 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 1 | 2 | /* |
| 2 | 3 | * Driver for STMicroelectronics STM32F7 I2C controller |
| 3 | 4 | * |
| @@ -7,11 +8,11 @@ · 3 unmodified lines | ||
| 7 | 8 | * http://www.st.com/resource/en/reference_manual/dm00124865.pdf |
| 8 | 9 | * |
| 9 | 10 | * Copyright (C) M'boumba Cedric Madianga 2017 |
| 11 | + * Copyright (C) STMicroelectronics 2017 | |
| 10 | 12 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> |
| 11 | 13 | * |
| 12 | 14 | * This driver is based on i2c-stm32f4.c |
| 13 | 15 | * |
| 14 | − * License terms: GNU General Public License (GPL), version 2 | |
| 15 | 16 | */ |
| 16 | 17 | #include <linux/clk.h> |
| 17 | 18 | #include <linux/delay.h> |
| @@ -4458,7 +4458,7 @@ out: · 4457 unmodified lines | ||
| 4458 | 4458 | return skb->len; |
| 4459 | 4459 | } |
| 4460 | 4460 | |
| 4461 | −static const struct rdma_nl_cbs cma_cb_table[] = { | |
| 4461 | +static const struct rdma_nl_cbs cma_cb_table[RDMA_NL_RDMA_CM_NUM_OPS] = { | |
| 4462 | 4462 | [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats}, |
| 4463 | 4463 | }; |
| 4464 | 4464 | |
| @@ -1146,7 +1146,7 @@ struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, · 1145 unmodified lines | ||
| 1146 | 1146 | } |
| 1147 | 1147 | EXPORT_SYMBOL(ib_get_net_dev_by_params); |
| 1148 | 1148 | |
| 1149 | −static const struct rdma_nl_cbs ibnl_ls_cb_table[] = { | |
| 1149 | +static const struct rdma_nl_cbs ibnl_ls_cb_table[RDMA_NL_LS_NUM_OPS] = { | |
| 1150 | 1150 | [RDMA_NL_LS_OP_RESOLVE] = { |
| 1151 | 1151 | .doit = ib_nl_handle_resolve_resp, |
| 1152 | 1152 | .flags = RDMA_NL_ADMIN_PERM, |
| @@ -80,7 +80,7 @@ const char *__attribute_const__ iwcm_reject_msg(int reason) · 79 unmodified lines | ||
| 80 | 80 | } |
| 81 | 81 | EXPORT_SYMBOL(iwcm_reject_msg); |
| 82 | 82 | |
| 83 | −static struct rdma_nl_cbs iwcm_nl_cb_table[] = { | |
| 83 | +static struct rdma_nl_cbs iwcm_nl_cb_table[RDMA_NL_IWPM_NUM_OPS] = { | |
| 84 | 84 | [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, |
| 85 | 85 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, |
| 86 | 86 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, |
| @@ -303,7 +303,7 @@ out: cb->args[0] = idx; · 302 unmodified lines | ||
| 303 | 303 | return skb->len; |
| 304 | 304 | } |
| 305 | 305 | |
| 306 | −static const struct rdma_nl_cbs nldev_cb_table[] = { | |
| 306 | +static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = { | |
| 307 | 307 | [RDMA_NLDEV_CMD_GET] = { |
| 308 | 308 | .doit = nldev_get_doit, |
| 309 | 309 | .dump = nldev_get_dumpit, |
| @@ -386,6 +386,9 @@ int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev) · 385 unmodified lines | ||
| 386 | 386 | if (ret) |
| 387 | 387 | return ret; |
| 388 | 388 | |
| 389 | + if (!qp->qp_sec) | |
| 390 | + return 0; | |
| 391 | + | |
| 389 | 392 | mutex_lock(&real_qp->qp_sec->mutex); |
| 390 | 393 | ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys, |
| 391 | 394 | qp->qp_sec); |
| @@ -739,8 +742,11 @@ int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index) · 347 unmodified lines | ||
| 739 | 742 | if (!rdma_protocol_ib(map->agent.device, map->agent.port_num)) |
| 740 | 743 | return 0; |
| 741 | 744 | |
| 742 | − if (map->agent.qp->qp_type == IB_QPT_SMI && !map->agent.smp_allowed) | |
| 743 | − return -EACCES; | |
| 745 | + if (map->agent.qp->qp_type == IB_QPT_SMI) { | |
| 746 | + if (!map->agent.smp_allowed) | |
| 747 | + return -EACCES; | |
| 748 | + return 0; | |
| 749 | + } | |
| 744 | 750 | |
| 745 | 751 | return ib_security_pkey_access(map->agent.device, |
| 746 | 752 | map->agent.port_num, |
| @@ -1971,6 +1971,12 @@ static int modify_qp(struct ib_uverbs_file *file, · 1970 unmodified lines | ||
| 1971 | 1971 | goto release_qp; |
| 1972 | 1972 | } |
| 1973 | 1973 | |
| 1974 | + if ((cmd->base.attr_mask & IB_QP_ALT_PATH) && | |
| 1975 | + !rdma_is_port_valid(qp->device, cmd->base.alt_port_num)) { | |
| 1976 | + ret = -EINVAL; | |
| 1977 | + goto release_qp; | |
| 1978 | + } | |
| 1979 | + | |
| 1974 | 1980 | attr->qp_state = cmd->base.qp_state; |
| 1975 | 1981 | attr->cur_qp_state = cmd->base.cur_qp_state; |
| 1976 | 1982 | attr->path_mtu = cmd->base.path_mtu; |
| @@ -2068,8 +2074,8 @@ int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file, · 91 unmodified lines | ||
| 2068 | 2074 | return -EOPNOTSUPP; |
| 2069 | 2075 | |
| 2070 | 2076 | if (ucore->inlen > sizeof(cmd)) { |
| 2071 | − if (ib_is_udata_cleared(ucore, sizeof(cmd), | |
| 2072 | − ucore->inlen - sizeof(cmd))) | |
| 2077 | + if (!ib_is_udata_cleared(ucore, sizeof(cmd), | |
| 2078 | + ucore->inlen - sizeof(cmd))) | |
| 2073 | 2079 | return -EOPNOTSUPP; |
| 2074 | 2080 | } |
| 2075 | 2081 | |
| @@ -1438,7 +1438,8 @@ int ib_close_qp(struct ib_qp *qp) · 1437 unmodified lines | ||
| 1438 | 1438 | spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags); |
| 1439 | 1439 | |
| 1440 | 1440 | atomic_dec(&real_qp->usecnt); |
| 1441 | − ib_close_shared_qp_security(qp->qp_sec); | |
| 1441 | + if (qp->qp_sec) | |
| 1442 | + ib_close_shared_qp_security(qp->qp_sec); | |
| 1442 | 1443 | kfree(qp); |
| 1443 | 1444 | |
| 1444 | 1445 | return 0; |
| @@ -395,6 +395,11 @@ next_cqe: · 394 unmodified lines | ||
| 395 | 395 | |
| 396 | 396 | static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq) |
| 397 | 397 | { |
| 398 | + if (DRAIN_CQE(cqe)) { | |
| 399 | + WARN_ONCE(1, "Unexpected DRAIN CQE qp id %u!\n", wq->sq.qid); | |
| 400 | + return 0; | |
| 401 | + } | |
| 402 | + | |
| 398 | 403 | if (CQE_OPCODE(cqe) == FW_RI_TERMINATE) |
| 399 | 404 | return 0; |
| 400 | 405 | |
| @@ -489,7 +494,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, · 88 unmodified lines | ||
| 489 | 494 | /* |
| 490 | 495 | * Special cqe for drain WR completions... |
| 491 | 496 | */ |
| 492 | − if (CQE_OPCODE(hw_cqe) == C4IW_DRAIN_OPCODE) { | |
| 497 | + if (DRAIN_CQE(hw_cqe)) { | |
| 493 | 498 | *cookie = CQE_DRAIN_COOKIE(hw_cqe); |
| 494 | 499 | *cqe = *hw_cqe; |
| 495 | 500 | goto skip_cqe; |
| @@ -566,10 +571,10 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, · 70 unmodified lines | ||
| 566 | 571 | ret = -EAGAIN; |
| 567 | 572 | goto skip_cqe; |
| 568 | 573 | } |
| 569 | − if (unlikely((CQE_WRID_MSN(hw_cqe) != (wq->rq.msn)))) { | |
| 574 | + if (unlikely(!CQE_STATUS(hw_cqe) && | |
| 575 | + CQE_WRID_MSN(hw_cqe) != wq->rq.msn)) { | |
| 570 | 576 | t4_set_wq_in_error(wq); |
| 571 | − hw_cqe->header |= htonl(CQE_STATUS_V(T4_ERR_MSN)); | |
| 572 | − goto proc_cqe; | |
| 577 | + hw_cqe->header |= cpu_to_be32(CQE_STATUS_V(T4_ERR_MSN)); | |
| 573 | 578 | } |
| 574 | 579 | goto proc_cqe; |
| 575 | 580 | } |
| @@ -743,9 +748,6 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc) · 167 unmodified lines | ||
| 743 | 748 | c4iw_invalidate_mr(qhp->rhp, |
| 744 | 749 | CQE_WRID_FR_STAG(&cqe)); |
| 745 | 750 | break; |
| 746 | − case C4IW_DRAIN_OPCODE: | |
| 747 | − wc->opcode = IB_WC_SEND; | |
| 748 | − break; | |
| 749 | 751 | default: |
| 750 | 752 | pr_err("Unexpected opcode %d in the CQE received for QPID=0x%0x\n", |
| 751 | 753 | CQE_OPCODE(&cqe), CQE_QPID(&cqe)); |
| @@ -693,8 +693,6 @@ static inline int to_ib_qp_state(int c4iw_qp_state) · 692 unmodified lines | ||
| 693 | 693 | return IB_QPS_ERR; |
| 694 | 694 | } |
| 695 | 695 | |
| 696 | −#define C4IW_DRAIN_OPCODE FW_RI_SGE_EC_CR_RETURN | |
| 697 | − | |
| 698 | 696 | static inline u32 c4iw_ib_to_tpt_access(int a) |
| 699 | 697 | { |
| 700 | 698 | return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) | |
| @@ -790,21 +790,57 @@ static int ring_kernel_rq_db(struct c4iw_qp *qhp, u16 inc) · 789 unmodified lines | ||
| 790 | 790 | return 0; |
| 791 | 791 | } |
| 792 | 792 | |
| 793 | −static void complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | |
| 793 | +static int ib_to_fw_opcode(int ib_opcode) | |
| 794 | +{ | |
| 795 | + int opcode; | |
| 796 | + | |
| 797 | + switch (ib_opcode) { | |
| 798 | + case IB_WR_SEND_WITH_INV: | |
| 799 | + opcode = FW_RI_SEND_WITH_INV; | |
| 800 | + break; | |
| 801 | + case IB_WR_SEND: | |
| 802 | + opcode = FW_RI_SEND; | |
| 803 | + break; | |
| 804 | + case IB_WR_RDMA_WRITE: | |
| 805 | + opcode = FW_RI_RDMA_WRITE; | |
| 806 | + break; | |
| 807 | + case IB_WR_RDMA_READ: | |
| 808 | + case IB_WR_RDMA_READ_WITH_INV: | |
| 809 | + opcode = FW_RI_READ_REQ; | |
| 810 | + break; | |
| 811 | + case IB_WR_REG_MR: | |
| 812 | + opcode = FW_RI_FAST_REGISTER; | |
| 813 | + break; | |
| 814 | + case IB_WR_LOCAL_INV: | |
| 815 | + opcode = FW_RI_LOCAL_INV; | |
| 816 | + break; | |
| 817 | + default: | |
| 818 | + opcode = -EINVAL; | |
| 819 | + } | |
| 820 | + return opcode; | |
| 821 | +} | |
| 822 | + | |
| 823 | +static int complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | |
| 794 | 824 | { |
| 795 | 825 | struct t4_cqe cqe = {}; |
| 796 | 826 | struct c4iw_cq *schp; |
| 797 | 827 | unsigned long flag; |
| 798 | 828 | struct t4_cq *cq; |
| 829 | + int opcode; | |
| 799 | 830 | |
| 800 | 831 | schp = to_c4iw_cq(qhp->ibqp.send_cq); |
| 801 | 832 | cq = &schp->cq; |
| 802 | 833 | |
| 834 | + opcode = ib_to_fw_opcode(wr->opcode); | |
| 835 | + if (opcode < 0) | |
| 836 | + return opcode; | |
| 837 | + | |
| 803 | 838 | cqe.u.drain_cookie = wr->wr_id; |
| 804 | 839 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | |
| 805 | − CQE_OPCODE_V(C4IW_DRAIN_OPCODE) | | |
| 840 | + CQE_OPCODE_V(opcode) | | |
| 806 | 841 | CQE_TYPE_V(1) | |
| 807 | 842 | CQE_SWCQE_V(1) | |
| 843 | + CQE_DRAIN_V(1) | | |
| 808 | 844 | CQE_QPID_V(qhp->wq.sq.qid)); |
| 809 | 845 | |
| 810 | 846 | spin_lock_irqsave(&schp->lock, flag); |
| @@ -819,6 +855,23 @@ static void complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) · 8 unmodified lines | ||
| 819 | 855 | schp->ibcq.cq_context); |
| 820 | 856 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); |
| 821 | 857 | } |
| 858 | + return 0; | |
| 859 | +} | |
| 860 | + | |
| 861 | +static int complete_sq_drain_wrs(struct c4iw_qp *qhp, struct ib_send_wr *wr, | |
| 862 | + struct ib_send_wr **bad_wr) | |
| 863 | +{ | |
| 864 | + int ret = 0; | |
| 865 | + | |
| 866 | + while (wr) { | |
| 867 | + ret = complete_sq_drain_wr(qhp, wr); | |
| 868 | + if (ret) { | |
| 869 | + *bad_wr = wr; | |
| 870 | + break; | |
| 871 | + } | |
| 872 | + wr = wr->next; | |
| 873 | + } | |
| 874 | + return ret; | |
| 822 | 875 | } |
| 823 | 876 | |
| 824 | 877 | static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) |
| @@ -833,9 +886,10 @@ static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) · 8 unmodified lines | ||
| 833 | 886 | |
| 834 | 887 | cqe.u.drain_cookie = wr->wr_id; |
| 835 | 888 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | |
| 836 | − CQE_OPCODE_V(C4IW_DRAIN_OPCODE) | | |
| 889 | + CQE_OPCODE_V(FW_RI_SEND) | | |
| 837 | 890 | CQE_TYPE_V(0) | |
| 838 | 891 | CQE_SWCQE_V(1) | |
| 892 | + CQE_DRAIN_V(1) | | |
| 839 | 893 | CQE_QPID_V(qhp->wq.sq.qid)); |
| 840 | 894 | |
| 841 | 895 | spin_lock_irqsave(&rchp->lock, flag); |
| @@ -852,6 +906,14 @@ static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) · 10 unmodified lines | ||
| 852 | 906 | } |
| 853 | 907 | } |
| 854 | 908 | |
| 909 | +static void complete_rq_drain_wrs(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | |
| 910 | +{ | |
| 911 | + while (wr) { | |
| 912 | + complete_rq_drain_wr(qhp, wr); | |
| 913 | + wr = wr->next; | |
| 914 | + } | |
| 915 | +} | |
| 916 | + | |
| 855 | 917 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
| 856 | 918 | struct ib_send_wr **bad_wr) |
| 857 | 919 | { |
| @@ -868,9 +930,14 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 10 unmodified lines | ||
| 868 | 930 | |
| 869 | 931 | qhp = to_c4iw_qp(ibqp); |
| 870 | 932 | spin_lock_irqsave(&qhp->lock, flag); |
| 871 | − if (t4_wq_in_error(&qhp->wq)) { | |
| 933 | + | |
| 934 | + /* | |
| 935 | + * If the qp has been flushed, then just insert a special | |
| 936 | + * drain cqe. | |
| 937 | + */ | |
| 938 | + if (qhp->wq.flushed) { | |
| 872 | 939 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 873 | − complete_sq_drain_wr(qhp, wr); | |
| 940 | + err = complete_sq_drain_wrs(qhp, wr, bad_wr); | |
| 874 | 941 | return err; |
| 875 | 942 | } |
| 876 | 943 | num_wrs = t4_sq_avail(&qhp->wq); |
| @@ -1011,9 +1078,14 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, · 134 unmodified lines | ||
| 1011 | 1078 | |
| 1012 | 1079 | qhp = to_c4iw_qp(ibqp); |
| 1013 | 1080 | spin_lock_irqsave(&qhp->lock, flag); |
| 1014 | − if (t4_wq_in_error(&qhp->wq)) { | |
| 1081 | + | |
| 1082 | + /* | |
| 1083 | + * If the qp has been flushed, then just insert a special | |
| 1084 | + * drain cqe. | |
| 1085 | + */ | |
| 1086 | + if (qhp->wq.flushed) { | |
| 1015 | 1087 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 1016 | − complete_rq_drain_wr(qhp, wr); | |
| 1088 | + complete_rq_drain_wrs(qhp, wr); | |
| 1017 | 1089 | return err; |
| 1018 | 1090 | } |
| 1019 | 1091 | num_wrs = t4_rq_avail(&qhp->wq); |
| @@ -1285,21 +1357,21 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, · 265 unmodified lines | ||
| 1285 | 1357 | spin_unlock_irqrestore(&rchp->lock, flag); |
| 1286 | 1358 | |
| 1287 | 1359 | if (schp == rchp) { |
| 1288 | − if (t4_clear_cq_armed(&rchp->cq) && | |
| 1289 | − (rq_flushed || sq_flushed)) { | |
| 1360 | + if ((rq_flushed || sq_flushed) && | |
| 1361 | + t4_clear_cq_armed(&rchp->cq)) { | |
| 1290 | 1362 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); |
| 1291 | 1363 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, |
| 1292 | 1364 | rchp->ibcq.cq_context); |
| 1293 | 1365 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); |
| 1294 | 1366 | } |
| 1295 | 1367 | } else { |
| 1296 | − if (t4_clear_cq_armed(&rchp->cq) && rq_flushed) { | |
| 1368 | + if (rq_flushed && t4_clear_cq_armed(&rchp->cq)) { | |
| 1297 | 1369 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); |
| 1298 | 1370 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, |
| 1299 | 1371 | rchp->ibcq.cq_context); |
| 1300 | 1372 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); |
| 1301 | 1373 | } |
| 1302 | − if (t4_clear_cq_armed(&schp->cq) && sq_flushed) { | |
| 1374 | + if (sq_flushed && t4_clear_cq_armed(&schp->cq)) { | |
| 1303 | 1375 | spin_lock_irqsave(&schp->comp_handler_lock, flag); |
| 1304 | 1376 | (*schp->ibcq.comp_handler)(&schp->ibcq, |
| 1305 | 1377 | schp->ibcq.cq_context); |
| @@ -197,6 +197,11 @@ struct t4_cqe { · 196 unmodified lines | ||
| 197 | 197 | #define CQE_SWCQE_G(x) ((((x) >> CQE_SWCQE_S)) & CQE_SWCQE_M) |
| 198 | 198 | #define CQE_SWCQE_V(x) ((x)<<CQE_SWCQE_S) |
| 199 | 199 | |
| 200 | +#define CQE_DRAIN_S 10 | |
| 201 | +#define CQE_DRAIN_M 0x1 | |
| 202 | +#define CQE_DRAIN_G(x) ((((x) >> CQE_DRAIN_S)) & CQE_DRAIN_M) | |
| 203 | +#define CQE_DRAIN_V(x) ((x)<<CQE_DRAIN_S) | |
| 204 | + | |
| 200 | 205 | #define CQE_STATUS_S 5 |
| 201 | 206 | #define CQE_STATUS_M 0x1F |
| 202 | 207 | #define CQE_STATUS_G(x) ((((x) >> CQE_STATUS_S)) & CQE_STATUS_M) |
| @@ -213,6 +218,7 @@ struct t4_cqe { · 10 unmodified lines | ||
| 213 | 218 | #define CQE_OPCODE_V(x) ((x)<<CQE_OPCODE_S) |
| 214 | 219 | |
| 215 | 220 | #define SW_CQE(x) (CQE_SWCQE_G(be32_to_cpu((x)->header))) |
| 221 | +#define DRAIN_CQE(x) (CQE_DRAIN_G(be32_to_cpu((x)->header))) | |
| 216 | 222 | #define CQE_QPID(x) (CQE_QPID_G(be32_to_cpu((x)->header))) |
| 217 | 223 | #define CQE_TYPE(x) (CQE_TYPE_G(be32_to_cpu((x)->header))) |
| 218 | 224 | #define SQ_TYPE(x) (CQE_TYPE((x))) |
| @@ -1131,7 +1131,6 @@ struct hfi1_devdata { · 1130 unmodified lines | ||
| 1131 | 1131 | u16 pcie_lnkctl; |
| 1132 | 1132 | u16 pcie_devctl2; |
| 1133 | 1133 | u32 pci_msix0; |
| 1134 | − u32 pci_lnkctl3; | |
| 1135 | 1134 | u32 pci_tph2; |
| 1136 | 1135 | |
| 1137 | 1136 | /* |
| @@ -411,15 +411,12 @@ int restore_pci_variables(struct hfi1_devdata *dd) · 410 unmodified lines | ||
| 411 | 411 | if (ret) |
| 412 | 412 | goto error; |
| 413 | 413 | |
| 414 | − ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, | |
| 415 | − dd->pci_lnkctl3); | |
| 416 | − if (ret) | |
| 417 | − goto error; | |
| 418 | − | |
| 419 | − ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, dd->pci_tph2); | |
| 420 | − if (ret) | |
| 421 | − goto error; | |
| 422 | − | |
| 414 | + if (pci_find_ext_capability(dd->pcidev, PCI_EXT_CAP_ID_TPH)) { | |
| 415 | + ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, | |
| 416 | + dd->pci_tph2); | |
| 417 | + if (ret) | |
| 418 | + goto error; | |
| 419 | + } | |
| 423 | 420 | return 0; |
| 424 | 421 | |
| 425 | 422 | error: |
| @@ -469,15 +466,12 @@ int save_pci_variables(struct hfi1_devdata *dd) · 43 unmodified lines | ||
| 469 | 466 | if (ret) |
| 470 | 467 | goto error; |
| 471 | 468 | |
| 472 | − ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, | |
| 473 | − &dd->pci_lnkctl3); | |
| 474 | − if (ret) | |
| 475 | − goto error; | |
| 476 | − | |
| 477 | − ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, &dd->pci_tph2); | |
| 478 | − if (ret) | |
| 479 | − goto error; | |
| 480 | − | |
| 469 | + if (pci_find_ext_capability(dd->pcidev, PCI_EXT_CAP_ID_TPH)) { | |
| 470 | + ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, | |
| 471 | + &dd->pci_tph2); | |
| 472 | + if (ret) | |
| 473 | + goto error; | |
| 474 | + } | |
| 481 | 475 | return 0; |
| 482 | 476 | |
| 483 | 477 | error: |
| @@ -666,6 +666,19 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, · 665 unmodified lines | ||
| 666 | 666 | return (-EOPNOTSUPP); |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | + if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | | |
| 670 | + MLX4_IB_RX_HASH_DST_IPV4 | | |
| 671 | + MLX4_IB_RX_HASH_SRC_IPV6 | | |
| 672 | + MLX4_IB_RX_HASH_DST_IPV6 | | |
| 673 | + MLX4_IB_RX_HASH_SRC_PORT_TCP | | |
| 674 | + MLX4_IB_RX_HASH_DST_PORT_TCP | | |
| 675 | + MLX4_IB_RX_HASH_SRC_PORT_UDP | | |
| 676 | + MLX4_IB_RX_HASH_DST_PORT_UDP)) { | |
| 677 | + pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", | |
| 678 | + ucmd->rx_hash_fields_mask); | |
| 679 | + return (-EOPNOTSUPP); | |
| 680 | + } | |
| 681 | + | |
| 669 | 682 | if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV4) && |
| 670 | 683 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV4)) { |
| 671 | 684 | rss_ctx->flags = MLX4_RSS_IPV4; |
| @@ -691,11 +704,11 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, · 19 unmodified lines | ||
| 691 | 704 | return (-EOPNOTSUPP); |
| 692 | 705 | } |
| 693 | 706 | |
| 694 | − if (rss_ctx->flags & MLX4_RSS_IPV4) { | |
| 707 | + if (rss_ctx->flags & MLX4_RSS_IPV4) | |
| 695 | 708 | rss_ctx->flags |= MLX4_RSS_UDP_IPV4; |
| 696 | − } else if (rss_ctx->flags & MLX4_RSS_IPV6) { | |
| 709 | + if (rss_ctx->flags & MLX4_RSS_IPV6) | |
| 697 | 710 | rss_ctx->flags |= MLX4_RSS_UDP_IPV6; |
| 698 | − } else { | |
| 711 | + if (!(rss_ctx->flags & (MLX4_RSS_IPV6 | MLX4_RSS_IPV4))) { | |
| 699 | 712 | pr_debug("RX Hash fields_mask is not supported - UDP must be set with IPv4 or IPv6\n"); |
| 700 | 713 | return (-EOPNOTSUPP); |
| 701 | 714 | } |
| @@ -707,15 +720,14 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, · 5 unmodified lines | ||
| 707 | 720 | |
| 708 | 721 | if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) && |
| 709 | 722 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) { |
| 710 | − if (rss_ctx->flags & MLX4_RSS_IPV4) { | |
| 723 | + if (rss_ctx->flags & MLX4_RSS_IPV4) | |
| 711 | 724 | rss_ctx->flags |= MLX4_RSS_TCP_IPV4; |
| 712 | − } else if (rss_ctx->flags & MLX4_RSS_IPV6) { | |
| 725 | + if (rss_ctx->flags & MLX4_RSS_IPV6) | |
| 713 | 726 | rss_ctx->flags |= MLX4_RSS_TCP_IPV6; |
| 714 | − } else { | |
| 727 | + if (!(rss_ctx->flags & (MLX4_RSS_IPV6 | MLX4_RSS_IPV4))) { | |
| 715 | 728 | pr_debug("RX Hash fields_mask is not supported - TCP must be set with IPv4 or IPv6\n"); |
| 716 | 729 | return (-EOPNOTSUPP); |
| 717 | 730 | } |
| 718 | − | |
| 719 | 731 | } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) || |
| 720 | 732 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) { |
| 721 | 733 | pr_debug("RX Hash fields_mask is not supported - both TCP SRC and DST must be set\n"); |
| @@ -47,17 +47,6 @@ int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey) · 46 unmodified lines | ||
| 47 | 47 | return err; |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | −int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | |
| 51 | − bool reset, void *out, int out_size) | |
| 52 | −{ | |
| 53 | − u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { }; | |
| 54 | − | |
| 55 | − MLX5_SET(query_cong_statistics_in, in, opcode, | |
| 56 | − MLX5_CMD_OP_QUERY_CONG_STATISTICS); | |
| 57 | − MLX5_SET(query_cong_statistics_in, in, clear, reset); | |
| 58 | − return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | |
| 59 | −} | |
| 60 | − | |
| 61 | 50 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
| 62 | 51 | void *out, int out_size) |
| 63 | 52 | { |
| @@ -37,8 +37,6 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <linux/mlx5/driver.h> |
| 38 | 38 | |
| 39 | 39 | int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); |
| 40 | −int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | |
| 41 | − bool reset, void *out, int out_size); | |
| 42 | 40 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
| 43 | 41 | void *out, int out_size); |
| 44 | 42 | int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, |
| @@ -1463,6 +1463,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, · 1462 unmodified lines | ||
| 1463 | 1463 | } |
| 1464 | 1464 | |
| 1465 | 1465 | INIT_LIST_HEAD(&context->vma_private_list); |
| 1466 | + mutex_init(&context->vma_private_list_mutex); | |
| 1466 | 1467 | INIT_LIST_HEAD(&context->db_page_list); |
| 1467 | 1468 | mutex_init(&context->db_page_mutex); |
| 1468 | 1469 | |
| @@ -1624,7 +1625,9 @@ static void mlx5_ib_vma_close(struct vm_area_struct *area) · 155 unmodified lines | ||
| 1624 | 1625 | * mlx5_ib_disassociate_ucontext(). |
| 1625 | 1626 | */ |
| 1626 | 1627 | mlx5_ib_vma_priv_data->vma = NULL; |
| 1628 | + mutex_lock(mlx5_ib_vma_priv_data->vma_private_list_mutex); | |
| 1627 | 1629 | list_del(&mlx5_ib_vma_priv_data->list); |
| 1630 | + mutex_unlock(mlx5_ib_vma_priv_data->vma_private_list_mutex); | |
| 1628 | 1631 | kfree(mlx5_ib_vma_priv_data); |
| 1629 | 1632 | } |
| 1630 | 1633 | |
| @@ -1644,10 +1647,13 @@ static int mlx5_ib_set_vma_data(struct vm_area_struct *vma, · 13 unmodified lines | ||
| 1644 | 1647 | return -ENOMEM; |
| 1645 | 1648 | |
| 1646 | 1649 | vma_prv->vma = vma; |
| 1650 | + vma_prv->vma_private_list_mutex = &ctx->vma_private_list_mutex; | |
| 1647 | 1651 | vma->vm_private_data = vma_prv; |
| 1648 | 1652 | vma->vm_ops = &mlx5_ib_vm_ops; |
| 1649 | 1653 | |
| 1654 | + mutex_lock(&ctx->vma_private_list_mutex); | |
| 1650 | 1655 | list_add(&vma_prv->list, vma_head); |
| 1656 | + mutex_unlock(&ctx->vma_private_list_mutex); | |
| 1651 | 1657 | |
| 1652 | 1658 | return 0; |
| 1653 | 1659 | } |
| @@ -1690,6 +1696,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) · 36 unmodified lines | ||
| 1690 | 1696 | * mlx5_ib_vma_close. |
| 1691 | 1697 | */ |
| 1692 | 1698 | down_write(&owning_mm->mmap_sem); |
| 1699 | + mutex_lock(&context->vma_private_list_mutex); | |
| 1693 | 1700 | list_for_each_entry_safe(vma_private, n, &context->vma_private_list, |
| 1694 | 1701 | list) { |
| 1695 | 1702 | vma = vma_private->vma; |
| @@ -1704,6 +1711,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) · 8 unmodified lines | ||
| 1704 | 1711 | list_del(&vma_private->list); |
| 1705 | 1712 | kfree(vma_private); |
| 1706 | 1713 | } |
| 1714 | + mutex_unlock(&context->vma_private_list_mutex); | |
| 1707 | 1715 | up_write(&owning_mm->mmap_sem); |
| 1708 | 1716 | mmput(owning_mm); |
| 1709 | 1717 | put_task_struct(owning_process); |
| @@ -3737,34 +3745,6 @@ free: · 2027 unmodified lines | ||
| 3737 | 3745 | return ret; |
| 3738 | 3746 | } |
| 3739 | 3747 | |
| 3740 | −static int mlx5_ib_query_cong_counters(struct mlx5_ib_dev *dev, | |
| 3741 | − struct mlx5_ib_port *port, | |
| 3742 | − struct rdma_hw_stats *stats) | |
| 3743 | −{ | |
| 3744 | − int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); | |
| 3745 | − void *out; | |
| 3746 | − int ret, i; | |
| 3747 | − int offset = port->cnts.num_q_counters; | |
| 3748 | − | |
| 3749 | − out = kvzalloc(outlen, GFP_KERNEL); | |
| 3750 | − if (!out) | |
| 3751 | − return -ENOMEM; | |
| 3752 | − | |
| 3753 | − ret = mlx5_cmd_query_cong_counter(dev->mdev, false, out, outlen); | |
| 3754 | − if (ret) | |
| 3755 | − goto free; | |
| 3756 | − | |
| 3757 | − for (i = 0; i < port->cnts.num_cong_counters; i++) { | |
| 3758 | − stats->value[i + offset] = | |
| 3759 | − be64_to_cpup((__be64 *)(out + | |
| 3760 | − port->cnts.offsets[i + offset])); | |
| 3761 | − } | |
| 3762 | − | |
| 3763 | −free: | |
| 3764 | − kvfree(out); | |
| 3765 | − return ret; | |
| 3766 | −} | |
| 3767 | − | |
| 3768 | 3748 | static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, |
| 3769 | 3749 | struct rdma_hw_stats *stats, |
| 3770 | 3750 | u8 port_num, int index) |
| @@ -3782,7 +3762,12 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, · 11 unmodified lines | ||
| 3782 | 3762 | num_counters = port->cnts.num_q_counters; |
| 3783 | 3763 | |
| 3784 | 3764 | if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { |
| 3785 | − ret = mlx5_ib_query_cong_counters(dev, port, stats); | |
| 3765 | + ret = mlx5_lag_query_cong_counters(dev->mdev, | |
| 3766 | + stats->value + | |
| 3767 | + port->cnts.num_q_counters, | |
| 3768 | + port->cnts.num_cong_counters, | |
| 3769 | + port->cnts.offsets + | |
| 3770 | + port->cnts.num_q_counters); | |
| 3786 | 3771 | if (ret) |
| 3787 | 3772 | return ret; |
| 3788 | 3773 | num_counters += port->cnts.num_cong_counters; |
| @@ -115,6 +115,8 @@ enum { · 114 unmodified lines | ||
| 115 | 115 | struct mlx5_ib_vma_private_data { |
| 116 | 116 | struct list_head list; |
| 117 | 117 | struct vm_area_struct *vma; |
| 118 | + /* protect vma_private_list add/del */ | |
| 119 | + struct mutex *vma_private_list_mutex; | |
| 118 | 120 | }; |
| 119 | 121 | |
| 120 | 122 | struct mlx5_ib_ucontext { |
| @@ -129,6 +131,8 @@ struct mlx5_ib_ucontext { · 8 unmodified lines | ||
| 129 | 131 | /* Transport Domain number */ |
| 130 | 132 | u32 tdn; |
| 131 | 133 | struct list_head vma_private_list; |
| 134 | + /* protect vma_private_list add/del */ | |
| 135 | + struct mutex vma_private_list_mutex; | |
| 132 | 136 | |
| 133 | 137 | unsigned long upd_xlt_page; |
| 134 | 138 | /* protect ODP/KSM */ |
| @@ -1637,6 +1637,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, · 1636 unmodified lines | ||
| 1637 | 1637 | MLX5_SET(mkc, mkc, access_mode, mr->access_mode); |
| 1638 | 1638 | MLX5_SET(mkc, mkc, umr_en, 1); |
| 1639 | 1639 | |
| 1640 | + mr->ibmr.device = pd->device; | |
| 1640 | 1641 | err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); |
| 1641 | 1642 | if (err) |
| 1642 | 1643 | goto err_destroy_psv; |
| @@ -94,7 +94,7 @@ struct pvrdma_cq { · 93 unmodified lines | ||
| 94 | 94 | u32 cq_handle; |
| 95 | 95 | bool is_kernel; |
| 96 | 96 | atomic_t refcnt; |
| 97 | − wait_queue_head_t wait; | |
| 97 | + struct completion free; | |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | 100 | struct pvrdma_id_table { |
| @@ -175,7 +175,7 @@ struct pvrdma_srq { · 74 unmodified lines | ||
| 175 | 175 | u32 srq_handle; |
| 176 | 176 | int npages; |
| 177 | 177 | refcount_t refcnt; |
| 178 | − wait_queue_head_t wait; | |
| 178 | + struct completion free; | |
| 179 | 179 | }; |
| 180 | 180 | |
| 181 | 181 | struct pvrdma_qp { |
| @@ -197,7 +197,7 @@ struct pvrdma_qp { · 15 unmodified lines | ||
| 197 | 197 | bool is_kernel; |
| 198 | 198 | struct mutex mutex; /* QP state mutex. */ |
| 199 | 199 | atomic_t refcnt; |
| 200 | − wait_queue_head_t wait; | |
| 200 | + struct completion free; | |
| 201 | 201 | }; |
| 202 | 202 | |
| 203 | 203 | struct pvrdma_dev { |
| @@ -179,7 +179,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, · 178 unmodified lines | ||
| 179 | 179 | pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0); |
| 180 | 180 | |
| 181 | 181 | atomic_set(&cq->refcnt, 1); |
| 182 | − init_waitqueue_head(&cq->wait); | |
| 182 | + init_completion(&cq->free); | |
| 183 | 183 | spin_lock_init(&cq->cq_lock); |
| 184 | 184 | |
| 185 | 185 | memset(cmd, 0, sizeof(*cmd)); |
| @@ -230,8 +230,9 @@ err_cq: · 44 unmodified lines | ||
| 230 | 230 | |
| 231 | 231 | static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq) |
| 232 | 232 | { |
| 233 | − atomic_dec(&cq->refcnt); | |
| 234 | − wait_event(cq->wait, !atomic_read(&cq->refcnt)); | |
| 233 | + if (atomic_dec_and_test(&cq->refcnt)) | |
| 234 | + complete(&cq->free); | |
| 235 | + wait_for_completion(&cq->free); | |
| 235 | 236 | |
| 236 | 237 | if (!cq->is_kernel) |
| 237 | 238 | ib_umem_release(cq->umem); |
| @@ -346,9 +346,8 @@ static void pvrdma_qp_event(struct pvrdma_dev *dev, u32 qpn, int type) · 345 unmodified lines | ||
| 346 | 346 | ibqp->event_handler(&e, ibqp->qp_context); |
| 347 | 347 | } |
| 348 | 348 | if (qp) { |
| 349 | − atomic_dec(&qp->refcnt); | |
| 350 | − if (atomic_read(&qp->refcnt) == 0) | |
| 351 | − wake_up(&qp->wait); | |
| 349 | + if (atomic_dec_and_test(&qp->refcnt)) | |
| 350 | + complete(&qp->free); | |
| 352 | 351 | } |
| 353 | 352 | } |
| 354 | 353 | |
| @@ -373,9 +372,8 @@ static void pvrdma_cq_event(struct pvrdma_dev *dev, u32 cqn, int type) · 18 unmodified lines | ||
| 373 | 372 | ibcq->event_handler(&e, ibcq->cq_context); |
| 374 | 373 | } |
| 375 | 374 | if (cq) { |
| 376 | − atomic_dec(&cq->refcnt); | |
| 377 | − if (atomic_read(&cq->refcnt) == 0) | |
| 378 | − wake_up(&cq->wait); | |
| 375 | + if (atomic_dec_and_test(&cq->refcnt)) | |
| 376 | + complete(&cq->free); | |
| 379 | 377 | } |
| 380 | 378 | } |
| 381 | 379 | |
| @@ -404,7 +402,7 @@ static void pvrdma_srq_event(struct pvrdma_dev *dev, u32 srqn, int type) · 22 unmodified lines | ||
| 404 | 402 | } |
| 405 | 403 | if (srq) { |
| 406 | 404 | if (refcount_dec_and_test(&srq->refcnt)) |
| 407 | − wake_up(&srq->wait); | |
| 405 | + complete(&srq->free); | |
| 408 | 406 | } |
| 409 | 407 | } |
| 410 | 408 | |
| @@ -539,9 +537,8 @@ static irqreturn_t pvrdma_intrx_handler(int irq, void *dev_id) · 128 unmodified lines | ||
| 539 | 537 | if (cq && cq->ibcq.comp_handler) |
| 540 | 538 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); |
| 541 | 539 | if (cq) { |
| 542 | − atomic_dec(&cq->refcnt); | |
| 543 | − if (atomic_read(&cq->refcnt)) | |
| 544 | − wake_up(&cq->wait); | |
| 540 | + if (atomic_dec_and_test(&cq->refcnt)) | |
| 541 | + complete(&cq->free); | |
| 545 | 542 | } |
| 546 | 543 | pvrdma_idx_ring_inc(&ring->cons_head, ring_slots); |
| 547 | 544 | } |
| @@ -246,7 +246,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, · 245 unmodified lines | ||
| 246 | 246 | spin_lock_init(&qp->rq.lock); |
| 247 | 247 | mutex_init(&qp->mutex); |
| 248 | 248 | atomic_set(&qp->refcnt, 1); |
| 249 | − init_waitqueue_head(&qp->wait); | |
| 249 | + init_completion(&qp->free); | |
| 250 | 250 | |
| 251 | 251 | qp->state = IB_QPS_RESET; |
| 252 | 252 | |
| @@ -428,8 +428,16 @@ static void pvrdma_free_qp(struct pvrdma_qp *qp) · 175 unmodified lines | ||
| 428 | 428 | |
| 429 | 429 | pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags); |
| 430 | 430 | |
| 431 | − atomic_dec(&qp->refcnt); | |
| 432 | − wait_event(qp->wait, !atomic_read(&qp->refcnt)); | |
| 431 | + if (atomic_dec_and_test(&qp->refcnt)) | |
| 432 | + complete(&qp->free); | |
| 433 | + wait_for_completion(&qp->free); | |
| 434 | + | |
| 435 | + if (!qp->is_kernel) { | |
| 436 | + if (qp->rumem) | |
| 437 | + ib_umem_release(qp->rumem); | |
| 438 | + if (qp->sumem) | |
| 439 | + ib_umem_release(qp->sumem); | |
| 440 | + } | |
| 433 | 441 | |
| 434 | 442 | pvrdma_page_dir_cleanup(dev, &qp->pdir); |
| 435 | 443 | |
| @@ -149,7 +149,7 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd, · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | spin_lock_init(&srq->lock); |
| 151 | 151 | refcount_set(&srq->refcnt, 1); |
| 152 | − init_waitqueue_head(&srq->wait); | |
| 152 | + init_completion(&srq->free); | |
| 153 | 153 | |
| 154 | 154 | dev_dbg(&dev->pdev->dev, |
| 155 | 155 | "create shared receive queue from user space\n"); |
| @@ -236,8 +236,9 @@ static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq) · 80 unmodified lines | ||
| 236 | 236 | dev->srq_tbl[srq->srq_handle] = NULL; |
| 237 | 237 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); |
| 238 | 238 | |
| 239 | − refcount_dec(&srq->refcnt); | |
| 240 | − wait_event(srq->wait, !refcount_read(&srq->refcnt)); | |
| 239 | + if (refcount_dec_and_test(&srq->refcnt)) | |
| 240 | + complete(&srq->free); | |
| 241 | + wait_for_completion(&srq->free); | |
| 241 | 242 | |
| 242 | 243 | /* There is no support for kernel clients, so this is safe. */ |
| 243 | 244 | ib_umem_release(srq->umem); |
| @@ -1145,6 +1145,7 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn, · 1144 unmodified lines | ||
| 1145 | 1145 | noio_flag = memalloc_noio_save(); |
| 1146 | 1146 | p->tx_ring = vzalloc(ipoib_sendq_size * sizeof(*p->tx_ring)); |
| 1147 | 1147 | if (!p->tx_ring) { |
| 1148 | + memalloc_noio_restore(noio_flag); | |
| 1148 | 1149 | ret = -ENOMEM; |
| 1149 | 1150 | goto err_tx; |
| 1150 | 1151 | } |
| @@ -1236,13 +1236,10 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, · 1235 unmodified lines | ||
| 1236 | 1236 | ipoib_ib_dev_down(dev); |
| 1237 | 1237 | |
| 1238 | 1238 | if (level == IPOIB_FLUSH_HEAVY) { |
| 1239 | − rtnl_lock(); | |
| 1240 | 1239 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 1241 | 1240 | ipoib_ib_dev_stop(dev); |
| 1242 | 1241 | |
| 1243 | − result = ipoib_ib_dev_open(dev); | |
| 1244 | − rtnl_unlock(); | |
| 1245 | − if (result) | |
| 1242 | + if (ipoib_ib_dev_open(dev)) | |
| 1246 | 1243 | return; |
| 1247 | 1244 | |
| 1248 | 1245 | if (netif_queue_stopped(dev)) |
| @@ -1282,7 +1279,9 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work) · 33 unmodified lines | ||
| 1282 | 1279 | struct ipoib_dev_priv *priv = |
| 1283 | 1280 | container_of(work, struct ipoib_dev_priv, flush_heavy); |
| 1284 | 1281 | |
| 1282 | + rtnl_lock(); | |
| 1285 | 1283 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY, 0); |
| 1284 | + rtnl_unlock(); | |
| 1286 | 1285 | } |
| 1287 | 1286 | |
| 1288 | 1287 | void ipoib_ib_dev_cleanup(struct net_device *dev) |
| @@ -4184,7 +4184,7 @@ static void amd_ir_update_irte(struct irq_data *irqd, struct amd_iommu *iommu, · 4183 unmodified lines | ||
| 4184 | 4184 | struct irq_cfg *cfg); |
| 4185 | 4185 | |
| 4186 | 4186 | static int irq_remapping_activate(struct irq_domain *domain, |
| 4187 | − struct irq_data *irq_data, bool early) | |
| 4187 | + struct irq_data *irq_data, bool reserve) | |
| 4188 | 4188 | { |
| 4189 | 4189 | struct amd_ir_data *data = irq_data->chip_data; |
| 4190 | 4190 | struct irq_2_irte *irte_info = &data->irq_2_irte; |
| @@ -1397,7 +1397,7 @@ static void intel_irq_remapping_free(struct irq_domain *domain, · 1396 unmodified lines | ||
| 1397 | 1397 | } |
| 1398 | 1398 | |
| 1399 | 1399 | static int intel_irq_remapping_activate(struct irq_domain *domain, |
| 1400 | − struct irq_data *irq_data, bool early) | |
| 1400 | + struct irq_data *irq_data, bool reserve) | |
| 1401 | 1401 | { |
| 1402 | 1402 | intel_ir_reconfigure_irte(irq_data, true); |
| 1403 | 1403 | return 0; |
| @@ -2303,7 +2303,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, · 2302 unmodified lines | ||
| 2303 | 2303 | } |
| 2304 | 2304 | |
| 2305 | 2305 | static int its_irq_domain_activate(struct irq_domain *domain, |
| 2306 | − struct irq_data *d, bool early) | |
| 2306 | + struct irq_data *d, bool reserve) | |
| 2307 | 2307 | { |
| 2308 | 2308 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); |
| 2309 | 2309 | u32 event = its_get_event_id(d); |
| @@ -2818,7 +2818,7 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq · 508 unmodified lines | ||
| 2818 | 2818 | } |
| 2819 | 2819 | |
| 2820 | 2820 | static int its_vpe_irq_domain_activate(struct irq_domain *domain, |
| 2821 | − struct irq_data *d, bool early) | |
| 2821 | + struct irq_data *d, bool reserve) | |
| 2822 | 2822 | { |
| 2823 | 2823 | struct its_vpe *vpe = irq_data_get_irq_chip_data(d); |
| 2824 | 2824 | struct its_node *its; |
| @@ -342,6 +342,9 @@ static irqreturn_t intc_irqpin_shared_irq_handler(int irq, void *dev_id) · 341 unmodified lines | ||
| 342 | 342 | */ |
| 343 | 343 | static struct lock_class_key intc_irqpin_irq_lock_class; |
| 344 | 344 | |
| 345 | +/* And this is for the request mutex */ | |
| 346 | +static struct lock_class_key intc_irqpin_irq_request_class; | |
| 347 | + | |
| 345 | 348 | static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, |
| 346 | 349 | irq_hw_number_t hw) |
| 347 | 350 | { |
| @@ -352,7 +355,8 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, · 4 unmodified lines | ||
| 352 | 355 | |
| 353 | 356 | intc_irqpin_dbg(&p->irq[hw], "map"); |
| 354 | 357 | irq_set_chip_data(virq, h->host_data); |
| 355 | − irq_set_lockdep_class(virq, &intc_irqpin_irq_lock_class); | |
| 358 | + irq_set_lockdep_class(virq, &intc_irqpin_irq_lock_class, | |
| 359 | + &intc_irqpin_irq_request_class); | |
| 356 | 360 | irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); |
| 357 | 361 | return 0; |
| 358 | 362 | } |
| @@ -186,7 +186,7 @@ void led_blink_set(struct led_classdev *led_cdev, · 185 unmodified lines | ||
| 186 | 186 | unsigned long *delay_on, |
| 187 | 187 | unsigned long *delay_off) |
| 188 | 188 | { |
| 189 | − del_timer_sync(&led_cdev->blink_timer); | |
| 189 | + led_stop_software_blink(led_cdev); | |
| 190 | 190 | |
| 191 | 191 | clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags); |
| 192 | 192 | clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags); |
| @@ -1611,7 +1611,8 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, · 1610 unmodified lines | ||
| 1611 | 1611 | int l; |
| 1612 | 1612 | struct dm_buffer *b, *tmp; |
| 1613 | 1613 | unsigned long freed = 0; |
| 1614 | − unsigned long count = nr_to_scan; | |
| 1614 | + unsigned long count = c->n_buffers[LIST_CLEAN] + | |
| 1615 | + c->n_buffers[LIST_DIRTY]; | |
| 1615 | 1616 | unsigned long retain_target = get_retain_buffers(c); |
| 1616 | 1617 | |
| 1617 | 1618 | for (l = 0; l < LIST_SIZE; l++) { |
| @@ -1647,8 +1648,11 @@ static unsigned long · 29 unmodified lines | ||
| 1647 | 1648 | dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) |
| 1648 | 1649 | { |
| 1649 | 1650 | struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1651 | + unsigned long count = READ_ONCE(c->n_buffers[LIST_CLEAN]) + | |
| 1652 | + READ_ONCE(c->n_buffers[LIST_DIRTY]); | |
| 1653 | + unsigned long retain_target = get_retain_buffers(c); | |
| 1650 | 1654 | |
| 1651 | − return READ_ONCE(c->n_buffers[LIST_CLEAN]) + READ_ONCE(c->n_buffers[LIST_DIRTY]); | |
| 1655 | + return (count < retain_target) ? 0 : (count - retain_target); | |
| 1652 | 1656 | } |
| 1653 | 1657 | |
| 1654 | 1658 | /* |
| @@ -3472,18 +3472,18 @@ static int __init dm_cache_init(void) · 3471 unmodified lines | ||
| 3472 | 3472 | { |
| 3473 | 3473 | int r; |
| 3474 | 3474 | |
| 3475 | − r = dm_register_target(&cache_target); | |
| 3476 | − if (r) { | |
| 3477 | − DMERR("cache target registration failed: %d", r); | |
| 3478 | − return r; | |
| 3479 | − } | |
| 3480 | − | |
| 3481 | 3475 | migration_cache = KMEM_CACHE(dm_cache_migration, 0); |
| 3482 | 3476 | if (!migration_cache) { |
| 3483 | 3477 | dm_unregister_target(&cache_target); |
| 3484 | 3478 | return -ENOMEM; |
| 3485 | 3479 | } |
| 3486 | 3480 | |
| 3481 | + r = dm_register_target(&cache_target); | |
| 3482 | + if (r) { | |
| 3483 | + DMERR("cache target registration failed: %d", r); | |
| 3484 | + return r; | |
| 3485 | + } | |
| 3486 | + | |
| 3487 | 3487 | return 0; |
| 3488 | 3488 | } |
| 3489 | 3489 | |
| @@ -457,6 +457,38 @@ do { \ · 456 unmodified lines | ||
| 457 | 457 | dm_noflush_suspending((m)->ti)); \ |
| 458 | 458 | } while (0) |
| 459 | 459 | |
| 460 | +/* | |
| 461 | + * Check whether bios must be queued in the device-mapper core rather | |
| 462 | + * than here in the target. | |
| 463 | + * | |
| 464 | + * If MPATHF_QUEUE_IF_NO_PATH and MPATHF_SAVED_QUEUE_IF_NO_PATH hold | |
| 465 | + * the same value then we are not between multipath_presuspend() | |
| 466 | + * and multipath_resume() calls and we have no need to check | |
| 467 | + * for the DMF_NOFLUSH_SUSPENDING flag. | |
| 468 | + */ | |
| 469 | +static bool __must_push_back(struct multipath *m, unsigned long flags) | |
| 470 | +{ | |
| 471 | + return ((test_bit(MPATHF_QUEUE_IF_NO_PATH, &flags) != | |
| 472 | + test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &flags)) && | |
| 473 | + dm_noflush_suspending(m->ti)); | |
| 474 | +} | |
| 475 | + | |
| 476 | +/* | |
| 477 | + * Following functions use READ_ONCE to get atomic access to | |
| 478 | + * all m->flags to avoid taking spinlock | |
| 479 | + */ | |
| 480 | +static bool must_push_back_rq(struct multipath *m) | |
| 481 | +{ | |
| 482 | + unsigned long flags = READ_ONCE(m->flags); | |
| 483 | + return test_bit(MPATHF_QUEUE_IF_NO_PATH, &flags) || __must_push_back(m, flags); | |
| 484 | +} | |
| 485 | + | |
| 486 | +static bool must_push_back_bio(struct multipath *m) | |
| 487 | +{ | |
| 488 | + unsigned long flags = READ_ONCE(m->flags); | |
| 489 | + return __must_push_back(m, flags); | |
| 490 | +} | |
| 491 | + | |
| 460 | 492 | /* |
| 461 | 493 | * Map cloned requests (request-based multipath) |
| 462 | 494 | */ |
| @@ -478,7 +510,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, · 15 unmodified lines | ||
| 478 | 510 | pgpath = choose_pgpath(m, nr_bytes); |
| 479 | 511 | |
| 480 | 512 | if (!pgpath) { |
| 481 | − if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) | |
| 513 | + if (must_push_back_rq(m)) | |
| 482 | 514 | return DM_MAPIO_DELAY_REQUEUE; |
| 483 | 515 | dm_report_EIO(m); /* Failed */ |
| 484 | 516 | return DM_MAPIO_KILL; |
| @@ -553,7 +585,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m · 68 unmodified lines | ||
| 553 | 585 | } |
| 554 | 586 | |
| 555 | 587 | if (!pgpath) { |
| 556 | − if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) | |
| 588 | + if (must_push_back_bio(m)) | |
| 557 | 589 | return DM_MAPIO_REQUEUE; |
| 558 | 590 | dm_report_EIO(m); |
| 559 | 591 | return DM_MAPIO_KILL; |
| @@ -651,8 +683,7 @@ static int queue_if_no_path(struct multipath *m, bool queue_if_no_path, · 91 unmodified lines | ||
| 651 | 683 | assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags, |
| 652 | 684 | (save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) || |
| 653 | 685 | (!save_old_value && queue_if_no_path)); |
| 654 | − assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, | |
| 655 | − queue_if_no_path || dm_noflush_suspending(m->ti)); | |
| 686 | + assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, queue_if_no_path); | |
| 656 | 687 | spin_unlock_irqrestore(&m->lock, flags); |
| 657 | 688 | |
| 658 | 689 | if (!queue_if_no_path) { |
| @@ -1486,7 +1517,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, · 827 unmodified lines | ||
| 1486 | 1517 | fail_path(pgpath); |
| 1487 | 1518 | |
| 1488 | 1519 | if (atomic_read(&m->nr_valid_paths) == 0 && |
| 1489 | − !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | |
| 1520 | + !must_push_back_rq(m)) { | |
| 1490 | 1521 | if (error == BLK_STS_IOERR) |
| 1491 | 1522 | dm_report_EIO(m); |
| 1492 | 1523 | /* complete with the original error */ |
| @@ -1521,8 +1552,12 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, · 28 unmodified lines | ||
| 1521 | 1552 | |
| 1522 | 1553 | if (atomic_read(&m->nr_valid_paths) == 0 && |
| 1523 | 1554 | !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { |
| 1524 | − dm_report_EIO(m); | |
| 1525 | − *error = BLK_STS_IOERR; | |
| 1555 | + if (must_push_back_bio(m)) { | |
| 1556 | + r = DM_ENDIO_REQUEUE; | |
| 1557 | + } else { | |
| 1558 | + dm_report_EIO(m); | |
| 1559 | + *error = BLK_STS_IOERR; | |
| 1560 | + } | |
| 1526 | 1561 | goto done; |
| 1527 | 1562 | } |
| 1528 | 1563 | |
| @@ -1957,13 +1992,6 @@ static int __init dm_multipath_init(void) · 428 unmodified lines | ||
| 1957 | 1992 | { |
| 1958 | 1993 | int r; |
| 1959 | 1994 | |
| 1960 | − r = dm_register_target(&multipath_target); | |
| 1961 | − if (r < 0) { | |
| 1962 | − DMERR("request-based register failed %d", r); | |
| 1963 | − r = -EINVAL; | |
| 1964 | − goto bad_register_target; | |
| 1965 | − } | |
| 1966 | − | |
| 1967 | 1995 | kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0); |
| 1968 | 1996 | if (!kmultipathd) { |
| 1969 | 1997 | DMERR("failed to create workqueue kmpathd"); |
| @@ -1985,13 +2013,20 @@ static int __init dm_multipath_init(void) · 15 unmodified lines | ||
| 1985 | 2013 | goto bad_alloc_kmpath_handlerd; |
| 1986 | 2014 | } |
| 1987 | 2015 | |
| 2016 | + r = dm_register_target(&multipath_target); | |
| 2017 | + if (r < 0) { | |
| 2018 | + DMERR("request-based register failed %d", r); | |
| 2019 | + r = -EINVAL; | |
| 2020 | + goto bad_register_target; | |
| 2021 | + } | |
| 2022 | + | |
| 1988 | 2023 | return 0; |
| 1989 | 2024 | |
| 2025 | +bad_register_target: | |
| 2026 | + destroy_workqueue(kmpath_handlerd); | |
| 1990 | 2027 | bad_alloc_kmpath_handlerd: |
| 1991 | 2028 | destroy_workqueue(kmultipathd); |
| 1992 | 2029 | bad_alloc_kmultipathd: |
| 1993 | − dm_unregister_target(&multipath_target); | |
| 1994 | −bad_register_target: | |
| 1995 | 2030 | return r; |
| 1996 | 2031 | } |
| 1997 | 2032 | |
| @@ -2411,24 +2411,6 @@ static int __init dm_snapshot_init(void) · 2410 unmodified lines | ||
| 2411 | 2411 | return r; |
| 2412 | 2412 | } |
| 2413 | 2413 | |
| 2414 | − r = dm_register_target(&snapshot_target); | |
| 2415 | − if (r < 0) { | |
| 2416 | − DMERR("snapshot target register failed %d", r); | |
| 2417 | − goto bad_register_snapshot_target; | |
| 2418 | − } | |
| 2419 | − | |
| 2420 | − r = dm_register_target(&origin_target); | |
| 2421 | − if (r < 0) { | |
| 2422 | − DMERR("Origin target register failed %d", r); | |
| 2423 | − goto bad_register_origin_target; | |
| 2424 | − } | |
| 2425 | − | |
| 2426 | − r = dm_register_target(&merge_target); | |
| 2427 | − if (r < 0) { | |
| 2428 | − DMERR("Merge target register failed %d", r); | |
| 2429 | − goto bad_register_merge_target; | |
| 2430 | − } | |
| 2431 | − | |
| 2432 | 2414 | r = init_origin_hash(); |
| 2433 | 2415 | if (r) { |
| 2434 | 2416 | DMERR("init_origin_hash failed."); |
| @@ -2449,19 +2431,37 @@ static int __init dm_snapshot_init(void) · 14 unmodified lines | ||
| 2449 | 2431 | goto bad_pending_cache; |
| 2450 | 2432 | } |
| 2451 | 2433 | |
| 2434 | + r = dm_register_target(&snapshot_target); | |
| 2435 | + if (r < 0) { | |
| 2436 | + DMERR("snapshot target register failed %d", r); | |
| 2437 | + goto bad_register_snapshot_target; | |
| 2438 | + } | |
| 2439 | + | |
| 2440 | + r = dm_register_target(&origin_target); | |
| 2441 | + if (r < 0) { | |
| 2442 | + DMERR("Origin target register failed %d", r); | |
| 2443 | + goto bad_register_origin_target; | |
| 2444 | + } | |
| 2445 | + | |
| 2446 | + r = dm_register_target(&merge_target); | |
| 2447 | + if (r < 0) { | |
| 2448 | + DMERR("Merge target register failed %d", r); | |
| 2449 | + goto bad_register_merge_target; | |
| 2450 | + } | |
| 2451 | + | |
| 2452 | 2452 | return 0; |
| 2453 | 2453 | |
| 2454 | −bad_pending_cache: | |
| 2455 | − kmem_cache_destroy(exception_cache); | |
| 2456 | −bad_exception_cache: | |
| 2457 | − exit_origin_hash(); | |
| 2458 | −bad_origin_hash: | |
| 2459 | − dm_unregister_target(&merge_target); | |
| 2460 | 2454 | bad_register_merge_target: |
| 2461 | 2455 | dm_unregister_target(&origin_target); |
| 2462 | 2456 | bad_register_origin_target: |
| 2463 | 2457 | dm_unregister_target(&snapshot_target); |
| 2464 | 2458 | bad_register_snapshot_target: |
| 2459 | + kmem_cache_destroy(pending_cache); | |
| 2460 | +bad_pending_cache: | |
| 2461 | + kmem_cache_destroy(exception_cache); | |
| 2462 | +bad_exception_cache: | |
| 2463 | + exit_origin_hash(); | |
| 2464 | +bad_origin_hash: | |
| 2465 | 2465 | dm_exception_store_exit(); |
| 2466 | 2466 | |
| 2467 | 2467 | return r; |
| @@ -453,14 +453,15 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, · 452 unmodified lines | ||
| 453 | 453 | |
| 454 | 454 | refcount_set(&dd->count, 1); |
| 455 | 455 | list_add(&dd->list, &t->devices); |
| 456 | + goto out; | |
| 456 | 457 | |
| 457 | 458 | } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { |
| 458 | 459 | r = upgrade_mode(dd, mode, t->md); |
| 459 | 460 | if (r) |
| 460 | 461 | return r; |
| 461 | − refcount_inc(&dd->count); | |
| 462 | 462 | } |
| 463 | − | |
| 463 | + refcount_inc(&dd->count); | |
| 464 | +out: | |
| 464 | 465 | *result = dd->dm_dev; |
| 465 | 466 | return 0; |
| 466 | 467 | } |
| @@ -4355,30 +4355,28 @@ static struct target_type thin_target = { · 4354 unmodified lines | ||
| 4355 | 4355 | |
| 4356 | 4356 | static int __init dm_thin_init(void) |
| 4357 | 4357 | { |
| 4358 | − int r; | |
| 4358 | + int r = -ENOMEM; | |
| 4359 | 4359 | |
| 4360 | 4360 | pool_table_init(); |
| 4361 | 4361 | |
| 4362 | + _new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0); | |
| 4363 | + if (!_new_mapping_cache) | |
| 4364 | + return r; | |
| 4365 | + | |
| 4362 | 4366 | r = dm_register_target(&thin_target); |
| 4363 | 4367 | if (r) |
| 4364 | − return r; | |
| 4368 | + goto bad_new_mapping_cache; | |
| 4365 | 4369 | |
| 4366 | 4370 | r = dm_register_target(&pool_target); |
| 4367 | 4371 | if (r) |
| 4368 | − goto bad_pool_target; | |
| 4369 | − | |
| 4370 | − r = -ENOMEM; | |
| 4371 | − | |
| 4372 | − _new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0); | |
| 4373 | − if (!_new_mapping_cache) | |
| 4374 | − goto bad_new_mapping_cache; | |
| 4372 | + goto bad_thin_target; | |
| 4375 | 4373 | |
| 4376 | 4374 | return 0; |
| 4377 | 4375 | |
| 4378 | −bad_new_mapping_cache: | |
| 4379 | − dm_unregister_target(&pool_target); | |
| 4380 | −bad_pool_target: | |
| 4376 | +bad_thin_target: | |
| 4381 | 4377 | dm_unregister_target(&thin_target); |
| 4378 | +bad_new_mapping_cache: | |
| 4379 | + kmem_cache_destroy(_new_mapping_cache); | |
| 4382 | 4380 | |
| 4383 | 4381 | return r; |
| 4384 | 4382 | } |
| @@ -184,6 +184,7 @@ static struct irq_chip arizona_irq_chip = { · 183 unmodified lines | ||
| 184 | 184 | }; |
| 185 | 185 | |
| 186 | 186 | static struct lock_class_key arizona_irq_lock_class; |
| 187 | +static struct lock_class_key arizona_irq_request_class; | |
| 187 | 188 | |
| 188 | 189 | static int arizona_irq_map(struct irq_domain *h, unsigned int virq, |
| 189 | 190 | irq_hw_number_t hw) |
| @@ -191,7 +192,8 @@ static int arizona_irq_map(struct irq_domain *h, unsigned int virq, · 1 unmodified line | ||
| 191 | 192 | struct arizona *data = h->host_data; |
| 192 | 193 | |
| 193 | 194 | irq_set_chip_data(virq, data); |
| 194 | − irq_set_lockdep_class(virq, &arizona_irq_lock_class); | |
| 195 | + irq_set_lockdep_class(virq, &arizona_irq_lock_class, | |
| 196 | + &arizona_irq_request_class); | |
| 195 | 197 | irq_set_chip_and_handler(virq, &arizona_irq_chip, handle_simple_irq); |
| 196 | 198 | irq_set_nested_thread(virq, 1); |
| 197 | 199 | irq_set_noprobe(virq); |
| @@ -377,6 +377,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, · 376 unmodified lines | ||
| 377 | 377 | u8 *ptr; |
| 378 | 378 | u8 *rx_buf; |
| 379 | 379 | u8 sum; |
| 380 | + u8 rx_byte; | |
| 380 | 381 | int ret = 0, final_ret; |
| 381 | 382 | |
| 382 | 383 | len = cros_ec_prepare_tx(ec_dev, ec_msg); |
| @@ -421,25 +422,22 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, · 38 unmodified lines | ||
| 421 | 422 | if (!ret) { |
| 422 | 423 | /* Verify that EC can process command */ |
| 423 | 424 | for (i = 0; i < len; i++) { |
| 424 | − switch (rx_buf[i]) { | |
| 425 | − case EC_SPI_PAST_END: | |
| 426 | − case EC_SPI_RX_BAD_DATA: | |
| 427 | − case EC_SPI_NOT_READY: | |
| 428 | − ret = -EAGAIN; | |
| 429 | − ec_msg->result = EC_RES_IN_PROGRESS; | |
| 430 | − default: | |
| 425 | + rx_byte = rx_buf[i]; | |
| 426 | + if (rx_byte == EC_SPI_PAST_END || | |
| 427 | + rx_byte == EC_SPI_RX_BAD_DATA || | |
| 428 | + rx_byte == EC_SPI_NOT_READY) { | |
| 429 | + ret = -EREMOTEIO; | |
| 431 | 430 | break; |
| 432 | 431 | } |
| 433 | − if (ret) | |
| 434 | − break; | |
| 435 | 432 | } |
| 436 | − if (!ret) | |
| 437 | − ret = cros_ec_spi_receive_packet(ec_dev, | |
| 438 | − ec_msg->insize + sizeof(*response)); | |
| 439 | − } else { | |
| 440 | − dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | |
| 441 | 433 | } |
| 442 | 434 | |
| 435 | + if (!ret) | |
| 436 | + ret = cros_ec_spi_receive_packet(ec_dev, | |
| 437 | + ec_msg->insize + sizeof(*response)); | |
| 438 | + else | |
| 439 | + dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | |
| 440 | + | |
| 443 | 441 | final_ret = terminate_request(ec_dev); |
| 444 | 442 | |
| 445 | 443 | spi_bus_unlock(ec_spi->spi->master); |
| @@ -508,6 +506,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, · 62 unmodified lines | ||
| 508 | 506 | int i, len; |
| 509 | 507 | u8 *ptr; |
| 510 | 508 | u8 *rx_buf; |
| 509 | + u8 rx_byte; | |
| 511 | 510 | int sum; |
| 512 | 511 | int ret = 0, final_ret; |
| 513 | 512 | |
| @@ -544,25 +543,22 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, · 30 unmodified lines | ||
| 544 | 543 | if (!ret) { |
| 545 | 544 | /* Verify that EC can process command */ |
| 546 | 545 | for (i = 0; i < len; i++) { |
| 547 | − switch (rx_buf[i]) { | |
| 548 | − case EC_SPI_PAST_END: | |
| 549 | − case EC_SPI_RX_BAD_DATA: | |
| 550 | − case EC_SPI_NOT_READY: | |
| 551 | − ret = -EAGAIN; | |
| 552 | − ec_msg->result = EC_RES_IN_PROGRESS; | |
| 553 | − default: | |
| 546 | + rx_byte = rx_buf[i]; | |
| 547 | + if (rx_byte == EC_SPI_PAST_END || | |
| 548 | + rx_byte == EC_SPI_RX_BAD_DATA || | |
| 549 | + rx_byte == EC_SPI_NOT_READY) { | |
| 550 | + ret = -EREMOTEIO; | |
| 554 | 551 | break; |
| 555 | 552 | } |
| 556 | − if (ret) | |
| 557 | − break; | |
| 558 | 553 | } |
| 559 | − if (!ret) | |
| 560 | − ret = cros_ec_spi_receive_response(ec_dev, | |
| 561 | − ec_msg->insize + EC_MSG_TX_PROTO_BYTES); | |
| 562 | − } else { | |
| 563 | − dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | |
| 564 | 554 | } |
| 565 | 555 | |
| 556 | + if (!ret) | |
| 557 | + ret = cros_ec_spi_receive_response(ec_dev, | |
| 558 | + ec_msg->insize + EC_MSG_TX_PROTO_BYTES); | |
| 559 | + else | |
| 560 | + dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | |
| 561 | + | |
| 566 | 562 | final_ret = terminate_request(ec_dev); |
| 567 | 563 | |
| 568 | 564 | spi_bus_unlock(ec_spi->spi->master); |
| @@ -667,6 +663,7 @@ static int cros_ec_spi_probe(struct spi_device *spi) · 98 unmodified lines | ||
| 667 | 663 | sizeof(struct ec_response_get_protocol_info); |
| 668 | 664 | ec_dev->dout_size = sizeof(struct ec_host_request); |
| 669 | 665 | |
| 666 | + ec_spi->last_transfer_ns = ktime_get_ns(); | |
| 670 | 667 | |
| 671 | 668 | err = cros_ec_register(ec_dev); |
| 672 | 669 | if (err) { |
| @@ -159,13 +159,18 @@ unsigned int twl4030_audio_get_mclk(void) · 158 unmodified lines | ||
| 159 | 159 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); |
| 160 | 160 | |
| 161 | 161 | static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata, |
| 162 | − struct device_node *node) | |
| 162 | + struct device_node *parent) | |
| 163 | 163 | { |
| 164 | + struct device_node *node; | |
| 165 | + | |
| 164 | 166 | if (pdata && pdata->codec) |
| 165 | 167 | return true; |
| 166 | 168 | |
| 167 | − if (of_find_node_by_name(node, "codec")) | |
| 169 | + node = of_get_child_by_name(parent, "codec"); | |
| 170 | + if (node) { | |
| 171 | + of_node_put(node); | |
| 168 | 172 | return true; |
| 173 | + } | |
| 169 | 174 | |
| 170 | 175 | return false; |
| 171 | 176 | } |
| @@ -97,12 +97,16 @@ static struct reg_sequence twl6040_patch[] = { · 96 unmodified lines | ||
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | 99 | |
| 100 | −static bool twl6040_has_vibra(struct device_node *node) | |
| 100 | +static bool twl6040_has_vibra(struct device_node *parent) | |
| 101 | 101 | { |
| 102 | −#ifdef CONFIG_OF | |
| 103 | − if (of_find_node_by_name(node, "vibra")) | |
| 102 | + struct device_node *node; | |
| 103 | + | |
| 104 | + node = of_get_child_by_name(parent, "vibra"); | |
| 105 | + if (node) { | |
| 106 | + of_node_put(node); | |
| 104 | 107 | return true; |
| 105 | −#endif | |
| 108 | + } | |
| 109 | + | |
| 106 | 110 | return false; |
| 107 | 111 | } |
| 108 | 112 | |
| @@ -562,7 +562,7 @@ static ssize_t at24_eeprom_write_i2c(struct at24_data *at24, const char *buf, · 561 unmodified lines | ||
| 562 | 562 | static int at24_read(void *priv, unsigned int off, void *val, size_t count) |
| 563 | 563 | { |
| 564 | 564 | struct at24_data *at24 = priv; |
| 565 | − struct i2c_client *client; | |
| 565 | + struct device *dev = &at24->client[0]->dev; | |
| 566 | 566 | char *buf = val; |
| 567 | 567 | int ret; |
| 568 | 568 | |
| @@ -572,11 +572,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) · 3 unmodified lines | ||
| 572 | 572 | if (off + count > at24->chip.byte_len) |
| 573 | 573 | return -EINVAL; |
| 574 | 574 | |
| 575 | − client = at24_translate_offset(at24, &off); | |
| 576 | − | |
| 577 | − ret = pm_runtime_get_sync(&client->dev); | |
| 575 | + ret = pm_runtime_get_sync(dev); | |
| 578 | 576 | if (ret < 0) { |
| 579 | − pm_runtime_put_noidle(&client->dev); | |
| 577 | + pm_runtime_put_noidle(dev); | |
| 580 | 578 | return ret; |
| 581 | 579 | } |
| 582 | 580 | |
| @@ -592,7 +590,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) · 9 unmodified lines | ||
| 592 | 590 | status = at24->read_func(at24, buf, off, count); |
| 593 | 591 | if (status < 0) { |
| 594 | 592 | mutex_unlock(&at24->lock); |
| 595 | − pm_runtime_put(&client->dev); | |
| 593 | + pm_runtime_put(dev); | |
| 596 | 594 | return status; |
| 597 | 595 | } |
| 598 | 596 | buf += status; |
| @@ -602,7 +600,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) · 3 unmodified lines | ||
| 602 | 600 | |
| 603 | 601 | mutex_unlock(&at24->lock); |
| 604 | 602 | |
| 605 | − pm_runtime_put(&client->dev); | |
| 603 | + pm_runtime_put(dev); | |
| 606 | 604 | |
| 607 | 605 | return 0; |
| 608 | 606 | } |
| @@ -610,7 +608,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) · 1 unmodified line | ||
| 610 | 608 | static int at24_write(void *priv, unsigned int off, void *val, size_t count) |
| 611 | 609 | { |
| 612 | 610 | struct at24_data *at24 = priv; |
| 613 | − struct i2c_client *client; | |
| 611 | + struct device *dev = &at24->client[0]->dev; | |
| 614 | 612 | char *buf = val; |
| 615 | 613 | int ret; |
| 616 | 614 | |
| @@ -620,11 +618,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) · 3 unmodified lines | ||
| 620 | 618 | if (off + count > at24->chip.byte_len) |
| 621 | 619 | return -EINVAL; |
| 622 | 620 | |
| 623 | − client = at24_translate_offset(at24, &off); | |
| 624 | − | |
| 625 | − ret = pm_runtime_get_sync(&client->dev); | |
| 621 | + ret = pm_runtime_get_sync(dev); | |
| 626 | 622 | if (ret < 0) { |
| 627 | − pm_runtime_put_noidle(&client->dev); | |
| 623 | + pm_runtime_put_noidle(dev); | |
| 628 | 624 | return ret; |
| 629 | 625 | } |
| 630 | 626 | |
| @@ -640,7 +636,7 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) · 9 unmodified lines | ||
| 640 | 636 | status = at24->write_func(at24, buf, off, count); |
| 641 | 637 | if (status < 0) { |
| 642 | 638 | mutex_unlock(&at24->lock); |
| 643 | − pm_runtime_put(&client->dev); | |
| 639 | + pm_runtime_put(dev); | |
| 644 | 640 | return status; |
| 645 | 641 | } |
| 646 | 642 | buf += status; |
| @@ -650,7 +646,7 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) · 3 unmodified lines | ||
| 650 | 646 | |
| 651 | 647 | mutex_unlock(&at24->lock); |
| 652 | 648 | |
| 653 | − pm_runtime_put(&client->dev); | |
| 649 | + pm_runtime_put(dev); | |
| 654 | 650 | |
| 655 | 651 | return 0; |
| 656 | 652 | } |
| @@ -880,7 +876,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) · 223 unmodified lines | ||
| 880 | 876 | at24->nvmem_config.reg_read = at24_read; |
| 881 | 877 | at24->nvmem_config.reg_write = at24_write; |
| 882 | 878 | at24->nvmem_config.priv = at24; |
| 883 | − at24->nvmem_config.stride = 4; | |
| 879 | + at24->nvmem_config.stride = 1; | |
| 884 | 880 | at24->nvmem_config.word_size = 1; |
| 885 | 881 | at24->nvmem_config.size = chip.byte_len; |
| 886 | 882 | |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <linux/pci.h> |
| 33 | 33 | #include <linux/mutex.h> |
| 34 | 34 | #include <linux/miscdevice.h> |
| 35 | −#include <linux/pti.h> | |
| 35 | +#include <linux/intel-pti.h> | |
| 36 | 36 | #include <linux/slab.h> |
| 37 | 37 | #include <linux/uaccess.h> |
| 38 | 38 | |
| @@ -75,9 +75,11 @@ struct mmc_fixup { · 74 unmodified lines | ||
| 75 | 75 | #define EXT_CSD_REV_ANY (-1u) |
| 76 | 76 | |
| 77 | 77 | #define CID_MANFID_SANDISK 0x2 |
| 78 | +#define CID_MANFID_ATP 0x9 | |
| 78 | 79 | #define CID_MANFID_TOSHIBA 0x11 |
| 79 | 80 | #define CID_MANFID_MICRON 0x13 |
| 80 | 81 | #define CID_MANFID_SAMSUNG 0x15 |
| 82 | +#define CID_MANFID_APACER 0x27 | |
| 81 | 83 | #define CID_MANFID_KINGSTON 0x70 |
| 82 | 84 | #define CID_MANFID_HYNIX 0x90 |
| 83 | 85 | |
| @@ -1290,7 +1290,7 @@ out_err: · 1289 unmodified lines | ||
| 1290 | 1290 | |
| 1291 | 1291 | static void mmc_select_driver_type(struct mmc_card *card) |
| 1292 | 1292 | { |
| 1293 | − int card_drv_type, drive_strength, drv_type; | |
| 1293 | + int card_drv_type, drive_strength, drv_type = 0; | |
| 1294 | 1294 | int fixed_drv_type = card->host->fixed_drv_type; |
| 1295 | 1295 | |
| 1296 | 1296 | card_drv_type = card->ext_csd.raw_driver_strength | |
| @@ -52,6 +52,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = { · 51 unmodified lines | ||
| 52 | 52 | MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
| 53 | 53 | MMC_QUIRK_BLK_NO_CMD23), |
| 54 | 54 | |
| 55 | + /* | |
| 56 | + * Some SD cards lockup while using CMD23 multiblock transfers. | |
| 57 | + */ | |
| 58 | + MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd, | |
| 59 | + MMC_QUIRK_BLK_NO_CMD23), | |
| 60 | + MMC_FIXUP("APUSD", CID_MANFID_APACER, 0x5048, add_quirk_sd, | |
| 61 | + MMC_QUIRK_BLK_NO_CMD23), | |
| 62 | + | |
| 55 | 63 | /* |
| 56 | 64 | * Some MMC cards need longer data read timeout than indicated in CSD. |
| 57 | 65 | */ |
| @@ -1114,7 +1114,7 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs, · 1113 unmodified lines | ||
| 1114 | 1114 | if (!ops->oobbuf) |
| 1115 | 1115 | ops->ooblen = 0; |
| 1116 | 1116 | |
| 1117 | − if (offs < 0 || offs + ops->len >= mtd->size) | |
| 1117 | + if (offs < 0 || offs + ops->len > mtd->size) | |
| 1118 | 1118 | return -EINVAL; |
| 1119 | 1119 | |
| 1120 | 1120 | if (ops->ooblen) { |
| @@ -1763,7 +1763,7 @@ try_dmaread: · 1762 unmodified lines | ||
| 1763 | 1763 | err = brcmstb_nand_verify_erased_page(mtd, chip, buf, |
| 1764 | 1764 | addr); |
| 1765 | 1765 | /* erased page bitflips corrected */ |
| 1766 | − if (err > 0) | |
| 1766 | + if (err >= 0) | |
| 1767 | 1767 | return err; |
| 1768 | 1768 | } |
| 1769 | 1769 | |
| @@ -253,9 +253,9 @@ static int gpio_nand_probe(struct platform_device *pdev) · 252 unmodified lines | ||
| 253 | 253 | goto out_ce; |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | − gpiomtd->nwp = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); | |
| 257 | − if (IS_ERR(gpiomtd->nwp)) { | |
| 258 | − ret = PTR_ERR(gpiomtd->nwp); | |
| 256 | + gpiomtd->ale = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); | |
| 257 | + if (IS_ERR(gpiomtd->ale)) { | |
| 258 | + ret = PTR_ERR(gpiomtd->ale); | |
| 259 | 259 | goto out_ce; |
| 260 | 260 | } |
| 261 | 261 | |
| @@ -1067,9 +1067,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, · 1066 unmodified lines | ||
| 1067 | 1067 | return ret; |
| 1068 | 1068 | } |
| 1069 | 1069 | |
| 1070 | − /* handle the block mark swapping */ | |
| 1071 | − block_mark_swapping(this, payload_virt, auxiliary_virt); | |
| 1072 | − | |
| 1073 | 1070 | /* Loop over status bytes, accumulating ECC status. */ |
| 1074 | 1071 | status = auxiliary_virt + nfc_geo->auxiliary_status_offset; |
| 1075 | 1072 | |
| @@ -1158,6 +1155,9 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, · 82 unmodified lines | ||
| 1158 | 1155 | max_bitflips = max_t(unsigned int, max_bitflips, *status); |
| 1159 | 1156 | } |
| 1160 | 1157 | |
| 1158 | + /* handle the block mark swapping */ | |
| 1159 | + block_mark_swapping(this, buf, auxiliary_virt); | |
| 1160 | + | |
| 1161 | 1161 | if (oob_required) { |
| 1162 | 1162 | /* |
| 1163 | 1163 | * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() |
| @@ -338,6 +338,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, · 337 unmodified lines | ||
| 338 | 338 | cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; |
| 339 | 339 | break; |
| 340 | 340 | case PHY_INTERFACE_MODE_XGMII: |
| 341 | + case PHY_INTERFACE_MODE_XAUI: | |
| 341 | 342 | cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; |
| 342 | 343 | break; |
| 343 | 344 | case PHY_INTERFACE_MODE_RXAUI: |
| @@ -50,7 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #define AQ_CFG_PCI_FUNC_MSIX_IRQS 9U |
| 51 | 51 | #define AQ_CFG_PCI_FUNC_PORTS 2U |
| 52 | 52 | |
| 53 | −#define AQ_CFG_SERVICE_TIMER_INTERVAL (2 * HZ) | |
| 53 | +#define AQ_CFG_SERVICE_TIMER_INTERVAL (1 * HZ) | |
| 54 | 54 | #define AQ_CFG_POLLING_TIMER_INTERVAL ((unsigned int)(2 * HZ)) |
| 55 | 55 | |
| 56 | 56 | #define AQ_CFG_SKB_FRAGS_MAX 32U |
| @@ -80,6 +80,7 @@ · 23 unmodified lines | ||
| 80 | 80 | #define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\ |
| 81 | 81 | __stringify(NIC_MINOR_DRIVER_VERSION)"."\ |
| 82 | 82 | __stringify(NIC_BUILD_DRIVER_VERSION)"."\ |
| 83 | − __stringify(NIC_REVISION_DRIVER_VERSION) | |
| 83 | + __stringify(NIC_REVISION_DRIVER_VERSION) \ | |
| 84 | + AQ_CFG_DRV_VERSION_SUFFIX | |
| 84 | 85 | |
| 85 | 86 | #endif /* AQ_CFG_H */ |
| @@ -66,14 +66,14 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { · 65 unmodified lines | ||
| 66 | 66 | "OutUCast", |
| 67 | 67 | "OutMCast", |
| 68 | 68 | "OutBCast", |
| 69 | − "InUCastOctects", | |
| 70 | − "OutUCastOctects", | |
| 71 | − "InMCastOctects", | |
| 72 | − "OutMCastOctects", | |
| 73 | − "InBCastOctects", | |
| 74 | − "OutBCastOctects", | |
| 75 | − "InOctects", | |
| 76 | − "OutOctects", | |
| 69 | + "InUCastOctets", | |
| 70 | + "OutUCastOctets", | |
| 71 | + "InMCastOctets", | |
| 72 | + "OutMCastOctets", | |
| 73 | + "InBCastOctets", | |
| 74 | + "OutBCastOctets", | |
| 75 | + "InOctets", | |
| 76 | + "OutOctets", | |
| 77 | 77 | "InPacketsDma", |
| 78 | 78 | "OutPacketsDma", |
| 79 | 79 | "InOctetsDma", |
| @@ -46,6 +46,28 @@ struct aq_hw_link_status_s { · 45 unmodified lines | ||
| 46 | 46 | unsigned int mbps; |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | +struct aq_stats_s { | |
| 50 | + u64 uprc; | |
| 51 | + u64 mprc; | |
| 52 | + u64 bprc; | |
| 53 | + u64 erpt; | |
| 54 | + u64 uptc; | |
| 55 | + u64 mptc; | |
| 56 | + u64 bptc; | |
| 57 | + u64 erpr; | |
| 58 | + u64 mbtc; | |
| 59 | + u64 bbtc; | |
| 60 | + u64 mbrc; | |
| 61 | + u64 bbrc; | |
| 62 | + u64 ubrc; | |
| 63 | + u64 ubtc; | |
| 64 | + u64 dpc; | |
| 65 | + u64 dma_pkt_rc; | |
| 66 | + u64 dma_pkt_tc; | |
| 67 | + u64 dma_oct_rc; | |
| 68 | + u64 dma_oct_tc; | |
| 69 | +}; | |
| 70 | + | |
| 49 | 71 | #define AQ_HW_IRQ_INVALID 0U |
| 50 | 72 | #define AQ_HW_IRQ_LEGACY 1U |
| 51 | 73 | #define AQ_HW_IRQ_MSI 2U |
| @@ -85,7 +107,9 @@ struct aq_hw_ops { · 33 unmodified lines | ||
| 85 | 107 | void (*destroy)(struct aq_hw_s *self); |
| 86 | 108 | |
| 87 | 109 | int (*get_hw_caps)(struct aq_hw_s *self, |
| 88 | − struct aq_hw_caps_s *aq_hw_caps); | |
| 110 | + struct aq_hw_caps_s *aq_hw_caps, | |
| 111 | + unsigned short device, | |
| 112 | + unsigned short subsystem_device); | |
| 89 | 113 | |
| 90 | 114 | int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring, |
| 91 | 115 | unsigned int frags); |
| @@ -164,8 +188,7 @@ struct aq_hw_ops { · 72 unmodified lines | ||
| 164 | 188 | |
| 165 | 189 | int (*hw_update_stats)(struct aq_hw_s *self); |
| 166 | 190 | |
| 167 | − int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data, | |
| 168 | − unsigned int *p_count); | |
| 191 | + struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self); | |
| 169 | 192 | |
| 170 | 193 | int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version); |
| 171 | 194 | |
| @@ -37,6 +37,8 @@ static unsigned int aq_itr_rx; · 36 unmodified lines | ||
| 37 | 37 | module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644); |
| 38 | 38 | MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate"); |
| 39 | 39 | |
| 40 | +static void aq_nic_update_ndev_stats(struct aq_nic_s *self); | |
| 41 | + | |
| 40 | 42 | static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues) |
| 41 | 43 | { |
| 42 | 44 | struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; |
| @@ -166,11 +168,8 @@ static int aq_nic_update_link_status(struct aq_nic_s *self) · 123 unmodified lines | ||
| 166 | 168 | static void aq_nic_service_timer_cb(struct timer_list *t) |
| 167 | 169 | { |
| 168 | 170 | struct aq_nic_s *self = from_timer(self, t, service_timer); |
| 169 | − struct net_device *ndev = aq_nic_get_ndev(self); | |
| 171 | + int ctimer = AQ_CFG_SERVICE_TIMER_INTERVAL; | |
| 170 | 172 | int err = 0; |
| 171 | − unsigned int i = 0U; | |
| 172 | − struct aq_ring_stats_rx_s stats_rx; | |
| 173 | − struct aq_ring_stats_tx_s stats_tx; | |
| 174 | 173 | |
| 175 | 174 | if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) |
| 176 | 175 | goto err_exit; |
| @@ -182,23 +181,14 @@ static void aq_nic_service_timer_cb(struct timer_list *t) · 5 unmodified lines | ||
| 182 | 181 | if (self->aq_hw_ops.hw_update_stats) |
| 183 | 182 | self->aq_hw_ops.hw_update_stats(self->aq_hw); |
| 184 | 183 | |
| 185 | − memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); | |
| 186 | − memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); | |
| 187 | − for (i = AQ_DIMOF(self->aq_vec); i--;) { | |
| 188 | − if (self->aq_vec[i]) | |
| 189 | − aq_vec_add_stats(self->aq_vec[i], &stats_rx, &stats_tx); | |
| 190 | − } | |
| 184 | + aq_nic_update_ndev_stats(self); | |
| 191 | 185 | |
| 192 | − ndev->stats.rx_packets = stats_rx.packets; | |
| 193 | − ndev->stats.rx_bytes = stats_rx.bytes; | |
| 194 | − ndev->stats.rx_errors = stats_rx.errors; | |
| 195 | − ndev->stats.tx_packets = stats_tx.packets; | |
| 196 | − ndev->stats.tx_bytes = stats_tx.bytes; | |
| 197 | − ndev->stats.tx_errors = stats_tx.errors; | |
| 186 | + /* If no link - use faster timer rate to detect link up asap */ | |
| 187 | + if (!netif_carrier_ok(self->ndev)) | |
| 188 | + ctimer = max(ctimer / 2, 1); | |
| 198 | 189 | |
| 199 | 190 | err_exit: |
| 200 | − mod_timer(&self->service_timer, | |
| 201 | − jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL); | |
| 191 | + mod_timer(&self->service_timer, jiffies + ctimer); | |
| 202 | 192 | } |
| 203 | 193 | |
| 204 | 194 | static void aq_nic_polling_timer_cb(struct timer_list *t) |
| @@ -222,7 +212,7 @@ static struct net_device *aq_nic_ndev_alloc(void) · 17 unmodified lines | ||
| 222 | 212 | |
| 223 | 213 | struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, |
| 224 | 214 | const struct ethtool_ops *et_ops, |
| 225 | − struct device *dev, | |
| 215 | + struct pci_dev *pdev, | |
| 226 | 216 | struct aq_pci_func_s *aq_pci_func, |
| 227 | 217 | unsigned int port, |
| 228 | 218 | const struct aq_hw_ops *aq_hw_ops) |
| @@ -242,7 +232,7 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, · 13 unmodified lines | ||
| 242 | 232 | ndev->netdev_ops = ndev_ops; |
| 243 | 233 | ndev->ethtool_ops = et_ops; |
| 244 | 234 | |
| 245 | − SET_NETDEV_DEV(ndev, dev); | |
| 235 | + SET_NETDEV_DEV(ndev, &pdev->dev); | |
| 246 | 236 | |
| 247 | 237 | ndev->if_port = port; |
| 248 | 238 | self->ndev = ndev; |
| @@ -254,7 +244,8 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, · 5 unmodified lines | ||
| 254 | 244 | |
| 255 | 245 | self->aq_hw = self->aq_hw_ops.create(aq_pci_func, self->port, |
| 256 | 246 | &self->aq_hw_ops); |
| 257 | − err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps); | |
| 247 | + err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps, | |
| 248 | + pdev->device, pdev->subsystem_device); | |
| 258 | 249 | if (err < 0) |
| 259 | 250 | goto err_exit; |
| 260 | 251 | |
| @@ -749,16 +740,40 @@ int aq_nic_get_regs_count(struct aq_nic_s *self) · 488 unmodified lines | ||
| 749 | 740 | |
| 750 | 741 | void aq_nic_get_stats(struct aq_nic_s *self, u64 *data) |
| 751 | 742 | { |
| 752 | − struct aq_vec_s *aq_vec = NULL; | |
| 753 | 743 | unsigned int i = 0U; |
| 754 | 744 | unsigned int count = 0U; |
| 755 | − int err = 0; | |
| 745 | + struct aq_vec_s *aq_vec = NULL; | |
| 746 | + struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw); | |
| 756 | 747 | |
| 757 | − err = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw, data, &count); | |
| 758 | − if (err < 0) | |
| 748 | + if (!stats) | |
| 759 | 749 | goto err_exit; |
| 760 | 750 | |
| 761 | − data += count; | |
| 751 | + data[i] = stats->uprc + stats->mprc + stats->bprc; | |
| 752 | + data[++i] = stats->uprc; | |
| 753 | + data[++i] = stats->mprc; | |
| 754 | + data[++i] = stats->bprc; | |
| 755 | + data[++i] = stats->erpt; | |
| 756 | + data[++i] = stats->uptc + stats->mptc + stats->bptc; | |
| 757 | + data[++i] = stats->uptc; | |
| 758 | + data[++i] = stats->mptc; | |
| 759 | + data[++i] = stats->bptc; | |
| 760 | + data[++i] = stats->ubrc; | |
| 761 | + data[++i] = stats->ubtc; | |
| 762 | + data[++i] = stats->mbrc; | |
| 763 | + data[++i] = stats->mbtc; | |
| 764 | + data[++i] = stats->bbrc; | |
| 765 | + data[++i] = stats->bbtc; | |
| 766 | + data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | |
| 767 | + data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | |
| 768 | + data[++i] = stats->dma_pkt_rc; | |
| 769 | + data[++i] = stats->dma_pkt_tc; | |
| 770 | + data[++i] = stats->dma_oct_rc; | |
| 771 | + data[++i] = stats->dma_oct_tc; | |
| 772 | + data[++i] = stats->dpc; | |
| 773 | + | |
| 774 | + i++; | |
| 775 | + | |
| 776 | + data += i; | |
| 762 | 777 | count = 0U; |
| 763 | 778 | |
| 764 | 779 | for (i = 0U, aq_vec = self->aq_vec[0]; |
| @@ -768,7 +783,20 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data) · 3 unmodified lines | ||
| 768 | 783 | } |
| 769 | 784 | |
| 770 | 785 | err_exit:; |
| 771 | − (void)err; | |
| 786 | +} | |
| 787 | + | |
| 788 | +static void aq_nic_update_ndev_stats(struct aq_nic_s *self) | |
| 789 | +{ | |
| 790 | + struct net_device *ndev = self->ndev; | |
| 791 | + struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw); | |
| 792 | + | |
| 793 | + ndev->stats.rx_packets = stats->uprc + stats->mprc + stats->bprc; | |
| 794 | + ndev->stats.rx_bytes = stats->ubrc + stats->mbrc + stats->bbrc; | |
| 795 | + ndev->stats.rx_errors = stats->erpr; | |
| 796 | + ndev->stats.tx_packets = stats->uptc + stats->mptc + stats->bptc; | |
| 797 | + ndev->stats.tx_bytes = stats->ubtc + stats->mbtc + stats->bbtc; | |
| 798 | + ndev->stats.tx_errors = stats->erpt; | |
| 799 | + ndev->stats.multicast = stats->mprc; | |
| 772 | 800 | } |
| 773 | 801 | |
| 774 | 802 | void aq_nic_get_link_ksettings(struct aq_nic_s *self, |
| @@ -71,7 +71,7 @@ struct aq_nic_cfg_s { · 70 unmodified lines | ||
| 71 | 71 | |
| 72 | 72 | struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, |
| 73 | 73 | const struct ethtool_ops *et_ops, |
| 74 | − struct device *dev, | |
| 74 | + struct pci_dev *pdev, | |
| 75 | 75 | struct aq_pci_func_s *aq_pci_func, |
| 76 | 76 | unsigned int port, |
| 77 | 77 | const struct aq_hw_ops *aq_hw_ops); |
| @@ -51,7 +51,8 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops, · 50 unmodified lines | ||
| 51 | 51 | pci_set_drvdata(pdev, self); |
| 52 | 52 | self->pdev = pdev; |
| 53 | 53 | |
| 54 | − err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps); | |
| 54 | + err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps, pdev->device, | |
| 55 | + pdev->subsystem_device); | |
| 55 | 56 | if (err < 0) |
| 56 | 57 | goto err_exit; |
| 57 | 58 | |
| @@ -59,7 +60,7 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops, · 1 unmodified line | ||
| 59 | 60 | |
| 60 | 61 | for (port = 0; port < self->ports; ++port) { |
| 61 | 62 | struct aq_nic_s *aq_nic = aq_nic_alloc_cold(ndev_ops, eth_ops, |
| 62 | − &pdev->dev, self, | |
| 63 | + pdev, self, | |
| 63 | 64 | port, aq_hw_ops); |
| 64 | 65 | |
| 65 | 66 | if (!aq_nic) { |
| @@ -18,9 +18,20 @@ · 17 unmodified lines | ||
| 18 | 18 | #include "hw_atl_a0_internal.h" |
| 19 | 19 | |
| 20 | 20 | static int hw_atl_a0_get_hw_caps(struct aq_hw_s *self, |
| 21 | − struct aq_hw_caps_s *aq_hw_caps) | |
| 21 | + struct aq_hw_caps_s *aq_hw_caps, | |
| 22 | + unsigned short device, | |
| 23 | + unsigned short subsystem_device) | |
| 22 | 24 | { |
| 23 | 25 | memcpy(aq_hw_caps, &hw_atl_a0_hw_caps_, sizeof(*aq_hw_caps)); |
| 26 | + | |
| 27 | + if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001) | |
| 28 | + aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G; | |
| 29 | + | |
| 30 | + if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) { | |
| 31 | + aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G; | |
| 32 | + aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_5G; | |
| 33 | + } | |
| 34 | + | |
| 24 | 35 | return 0; |
| 25 | 36 | } |
| 26 | 37 | |
| @@ -333,6 +344,10 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, · 306 unmodified lines | ||
| 333 | 344 | hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss); |
| 334 | 345 | hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); |
| 335 | 346 | |
| 347 | + /* Reset link status and read out initial hardware counters */ | |
| 348 | + self->aq_link_status.mbps = 0; | |
| 349 | + hw_atl_utils_update_stats(self); | |
| 350 | + | |
| 336 | 351 | err = aq_hw_err_from_flags(self); |
| 337 | 352 | if (err < 0) |
| 338 | 353 | goto err_exit; |
| @@ -16,11 +16,23 @@ · 15 unmodified lines | ||
| 16 | 16 | #include "hw_atl_utils.h" |
| 17 | 17 | #include "hw_atl_llh.h" |
| 18 | 18 | #include "hw_atl_b0_internal.h" |
| 19 | +#include "hw_atl_llh_internal.h" | |
| 19 | 20 | |
| 20 | 21 | static int hw_atl_b0_get_hw_caps(struct aq_hw_s *self, |
| 21 | − struct aq_hw_caps_s *aq_hw_caps) | |
| 22 | + struct aq_hw_caps_s *aq_hw_caps, | |
| 23 | + unsigned short device, | |
| 24 | + unsigned short subsystem_device) | |
| 22 | 25 | { |
| 23 | 26 | memcpy(aq_hw_caps, &hw_atl_b0_hw_caps_, sizeof(*aq_hw_caps)); |
| 27 | + | |
| 28 | + if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001) | |
| 29 | + aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G; | |
| 30 | + | |
| 31 | + if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) { | |
| 32 | + aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G; | |
| 33 | + aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_5G; | |
| 34 | + } | |
| 35 | + | |
| 24 | 36 | return 0; |
| 25 | 37 | } |
| 26 | 38 | |
| @@ -357,6 +369,7 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, · 330 unmodified lines | ||
| 357 | 369 | }; |
| 358 | 370 | |
| 359 | 371 | int err = 0; |
| 372 | + u32 val; | |
| 360 | 373 | |
| 361 | 374 | self->aq_nic_cfg = aq_nic_cfg; |
| 362 | 375 | |
| @@ -374,6 +387,20 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, · 11 unmodified lines | ||
| 374 | 387 | hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss); |
| 375 | 388 | hw_atl_b0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); |
| 376 | 389 | |
| 390 | + /* Force limit MRRS on RDM/TDM to 2K */ | |
| 391 | + val = aq_hw_read_reg(self, pci_reg_control6_adr); | |
| 392 | + aq_hw_write_reg(self, pci_reg_control6_adr, (val & ~0x707) | 0x404); | |
| 393 | + | |
| 394 | + /* TX DMA total request limit. B0 hardware is not capable to | |
| 395 | + * handle more than (8K-MRRS) incoming DMA data. | |
| 396 | + * Value 24 in 256byte units | |
| 397 | + */ | |
| 398 | + aq_hw_write_reg(self, tx_dma_total_req_limit_adr, 24); | |
| 399 | + | |
| 400 | + /* Reset link status and read out initial hardware counters */ | |
| 401 | + self->aq_link_status.mbps = 0; | |
| 402 | + hw_atl_utils_update_stats(self); | |
| 403 | + | |
| 377 | 404 | err = aq_hw_err_from_flags(self); |
| 378 | 405 | if (err < 0) |
| 379 | 406 | goto err_exit; |
| @@ -2343,6 +2343,9 @@ · 2342 unmodified lines | ||
| 2343 | 2343 | #define tx_dma_desc_base_addrmsw_adr(descriptor) \ |
| 2344 | 2344 | (0x00007c04u + (descriptor) * 0x40) |
| 2345 | 2345 | |
| 2346 | +/* tx dma total request limit */ | |
| 2347 | +#define tx_dma_total_req_limit_adr 0x00007b20u | |
| 2348 | + | |
| 2346 | 2349 | /* tx interrupt moderation control register definitions |
| 2347 | 2350 | * Preprocessor definitions for TX Interrupt Moderation Control Register |
| 2348 | 2351 | * Base Address: 0x00008980 |
| @@ -2369,6 +2372,9 @@ · 20 unmodified lines | ||
| 2369 | 2372 | /* default value of bitfield reg_res_dsbl */ |
| 2370 | 2373 | #define pci_reg_res_dsbl_default 0x1 |
| 2371 | 2374 | |
| 2375 | +/* PCI core control register */ | |
| 2376 | +#define pci_reg_control6_adr 0x1014u | |
| 2377 | + | |
| 2372 | 2378 | /* global microprocessor scratch pad definitions */ |
| 2373 | 2379 | #define glb_cpu_scratch_scp_adr(scratch_scp) (0x00000300u + (scratch_scp) * 0x4) |
| 2374 | 2380 | |
| @@ -503,73 +503,43 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self) · 502 unmodified lines | ||
| 503 | 503 | struct hw_atl_s *hw_self = PHAL_ATLANTIC; |
| 504 | 504 | struct hw_aq_atl_utils_mbox mbox; |
| 505 | 505 | |
| 506 | − if (!self->aq_link_status.mbps) | |
| 507 | − return 0; | |
| 508 | − | |
| 509 | 506 | hw_atl_utils_mpi_read_stats(self, &mbox); |
| 510 | 507 | |
| 511 | 508 | #define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \ |
| 512 | 509 | mbox.stats._N_ - hw_self->last_stats._N_) |
| 513 | − | |
| 514 | − AQ_SDELTA(uprc); | |
| 515 | − AQ_SDELTA(mprc); | |
| 516 | − AQ_SDELTA(bprc); | |
| 517 | − AQ_SDELTA(erpt); | |
| 518 | − | |
| 519 | − AQ_SDELTA(uptc); | |
| 520 | − AQ_SDELTA(mptc); | |
| 521 | − AQ_SDELTA(bptc); | |
| 522 | − AQ_SDELTA(erpr); | |
| 523 | − | |
| 524 | − AQ_SDELTA(ubrc); | |
| 525 | − AQ_SDELTA(ubtc); | |
| 526 | − AQ_SDELTA(mbrc); | |
| 527 | − AQ_SDELTA(mbtc); | |
| 528 | − AQ_SDELTA(bbrc); | |
| 529 | − AQ_SDELTA(bbtc); | |
| 530 | − AQ_SDELTA(dpc); | |
| 531 | − | |
| 510 | + if (self->aq_link_status.mbps) { | |
| 511 | + AQ_SDELTA(uprc); | |
| 512 | + AQ_SDELTA(mprc); | |
| 513 | + AQ_SDELTA(bprc); | |
| 514 | + AQ_SDELTA(erpt); | |
| 515 | + | |
| 516 | + AQ_SDELTA(uptc); | |
| 517 | + AQ_SDELTA(mptc); | |
| 518 | + AQ_SDELTA(bptc); | |
| 519 | + AQ_SDELTA(erpr); | |
| 520 | + | |
| 521 | + AQ_SDELTA(ubrc); | |
| 522 | + AQ_SDELTA(ubtc); | |
| 523 | + AQ_SDELTA(mbrc); | |
| 524 | + AQ_SDELTA(mbtc); | |
| 525 | + AQ_SDELTA(bbrc); | |
| 526 | + AQ_SDELTA(bbtc); | |
| 527 | + AQ_SDELTA(dpc); | |
| 528 | + } | |
| 532 | 529 | #undef AQ_SDELTA |
| 530 | + hw_self->curr_stats.dma_pkt_rc = stats_rx_dma_good_pkt_counterlsw_get(self); | |
| 531 | + hw_self->curr_stats.dma_pkt_tc = stats_tx_dma_good_pkt_counterlsw_get(self); | |
| 532 | + hw_self->curr_stats.dma_oct_rc = stats_rx_dma_good_octet_counterlsw_get(self); | |
| 533 | + hw_self->curr_stats.dma_oct_tc = stats_tx_dma_good_octet_counterlsw_get(self); | |
| 533 | 534 | |
| 534 | 535 | memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats)); |
| 535 | 536 | |
| 536 | 537 | return 0; |
| 537 | 538 | } |
| 538 | 539 | |
| 539 | −int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, | |
| 540 | − u64 *data, unsigned int *p_count) | |
| 540 | +struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self) | |
| 541 | 541 | { |
| 542 | − struct hw_atl_s *hw_self = PHAL_ATLANTIC; | |
| 543 | − struct hw_atl_stats_s *stats = &hw_self->curr_stats; | |
| 544 | − int i = 0; | |
| 545 | − | |
| 546 | − data[i] = stats->uprc + stats->mprc + stats->bprc; | |
| 547 | − data[++i] = stats->uprc; | |
| 548 | − data[++i] = stats->mprc; | |
| 549 | − data[++i] = stats->bprc; | |
| 550 | − data[++i] = stats->erpt; | |
| 551 | − data[++i] = stats->uptc + stats->mptc + stats->bptc; | |
| 552 | − data[++i] = stats->uptc; | |
| 553 | − data[++i] = stats->mptc; | |
| 554 | − data[++i] = stats->bptc; | |
| 555 | − data[++i] = stats->ubrc; | |
| 556 | − data[++i] = stats->ubtc; | |
| 557 | − data[++i] = stats->mbrc; | |
| 558 | − data[++i] = stats->mbtc; | |
| 559 | − data[++i] = stats->bbrc; | |
| 560 | − data[++i] = stats->bbtc; | |
| 561 | − data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | |
| 562 | − data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | |
| 563 | − data[++i] = stats_rx_dma_good_pkt_counterlsw_get(self); | |
| 564 | − data[++i] = stats_tx_dma_good_pkt_counterlsw_get(self); | |
| 565 | − data[++i] = stats_rx_dma_good_octet_counterlsw_get(self); | |
| 566 | − data[++i] = stats_tx_dma_good_octet_counterlsw_get(self); | |
| 567 | − data[++i] = stats->dpc; | |
| 568 | − | |
| 569 | − if (p_count) | |
| 570 | − *p_count = ++i; | |
| 571 | − | |
| 572 | − return 0; | |
| 542 | + return &PHAL_ATLANTIC->curr_stats; | |
| 573 | 543 | } |
| 574 | 544 | |
| 575 | 545 | static const u32 hw_atl_utils_hw_mac_regs[] = { |
| @@ -129,7 +129,7 @@ struct __packed hw_aq_atl_utils_mbox { · 128 unmodified lines | ||
| 129 | 129 | struct __packed hw_atl_s { |
| 130 | 130 | struct aq_hw_s base; |
| 131 | 131 | struct hw_atl_stats_s last_stats; |
| 132 | − struct hw_atl_stats_s curr_stats; | |
| 132 | + struct aq_stats_s curr_stats; | |
| 133 | 133 | u64 speed; |
| 134 | 134 | unsigned int chip_features; |
| 135 | 135 | u32 fw_ver_actual; |
| @@ -207,8 +207,6 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version); · 71 unmodified lines | ||
| 207 | 207 | |
| 208 | 208 | int hw_atl_utils_update_stats(struct aq_hw_s *self); |
| 209 | 209 | |
| 210 | −int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, | |
| 211 | − u64 *data, | |
| 212 | − unsigned int *p_count); | |
| 210 | +struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self); | |
| 213 | 211 | |
| 214 | 212 | #endif /* HW_ATL_UTILS_H */ |
| @@ -11,8 +11,10 @@ · 10 unmodified lines | ||
| 11 | 11 | #define VER_H |
| 12 | 12 | |
| 13 | 13 | #define NIC_MAJOR_DRIVER_VERSION 1 |
| 14 | −#define NIC_MINOR_DRIVER_VERSION 5 | |
| 15 | −#define NIC_BUILD_DRIVER_VERSION 345 | |
| 14 | +#define NIC_MINOR_DRIVER_VERSION 6 | |
| 15 | +#define NIC_BUILD_DRIVER_VERSION 13 | |
| 16 | 16 | #define NIC_REVISION_DRIVER_VERSION 0 |
| 17 | 17 | |
| 18 | +#define AQ_CFG_DRV_VERSION_SUFFIX "-kern" | |
| 19 | + | |
| 18 | 20 | #endif /* VER_H */ |
| @@ -159,6 +159,8 @@ struct arc_emac_priv { · 158 unmodified lines | ||
| 159 | 159 | unsigned int link; |
| 160 | 160 | unsigned int duplex; |
| 161 | 161 | unsigned int speed; |
| 162 | + | |
| 163 | + unsigned int rx_missed_errors; | |
| 162 | 164 | }; |
| 163 | 165 | |
| 164 | 166 | /** |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #include "emac.h" |
| 28 | 28 | |
| 29 | +static void arc_emac_restart(struct net_device *ndev); | |
| 30 | + | |
| 29 | 31 | /** |
| 30 | 32 | * arc_emac_tx_avail - Return the number of available slots in the tx ring. |
| 31 | 33 | * @priv: Pointer to ARC EMAC private data structure. |
| @@ -210,39 +212,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget) · 178 unmodified lines | ||
| 210 | 212 | continue; |
| 211 | 213 | } |
| 212 | 214 | |
| 213 | − pktlen = info & LEN_MASK; | |
| 214 | − stats->rx_packets++; | |
| 215 | − stats->rx_bytes += pktlen; | |
| 216 | − skb = rx_buff->skb; | |
| 217 | − skb_put(skb, pktlen); | |
| 218 | − skb->dev = ndev; | |
| 219 | − skb->protocol = eth_type_trans(skb, ndev); | |
| 220 | − | |
| 221 | − dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), | |
| 222 | − dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); | |
| 223 | − | |
| 224 | − /* Prepare the BD for next cycle */ | |
| 225 | − rx_buff->skb = netdev_alloc_skb_ip_align(ndev, | |
| 226 | − EMAC_BUFFER_SIZE); | |
| 227 | − if (unlikely(!rx_buff->skb)) { | |
| 215 | + /* Prepare the BD for next cycle. netif_receive_skb() | |
| 216 | + * only if new skb was allocated and mapped to avoid holes | |
| 217 | + * in the RX fifo. | |
| 218 | + */ | |
| 219 | + skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE); | |
| 220 | + if (unlikely(!skb)) { | |
| 221 | + if (net_ratelimit()) | |
| 222 | + netdev_err(ndev, "cannot allocate skb\n"); | |
| 223 | + /* Return ownership to EMAC */ | |
| 224 | + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); | |
| 228 | 225 | stats->rx_errors++; |
| 229 | − /* Because receive_skb is below, increment rx_dropped */ | |
| 230 | 226 | stats->rx_dropped++; |
| 231 | 227 | continue; |
| 232 | 228 | } |
| 233 | 229 | |
| 234 | − /* receive_skb only if new skb was allocated to avoid holes */ | |
| 235 | − netif_receive_skb(skb); | |
| 236 | − | |
| 237 | − addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data, | |
| 230 | + addr = dma_map_single(&ndev->dev, (void *)skb->data, | |
| 238 | 231 | EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); |
| 239 | 232 | if (dma_mapping_error(&ndev->dev, addr)) { |
| 240 | 233 | if (net_ratelimit()) |
| 241 | − netdev_err(ndev, "cannot dma map\n"); | |
| 242 | − dev_kfree_skb(rx_buff->skb); | |
| 234 | + netdev_err(ndev, "cannot map dma buffer\n"); | |
| 235 | + dev_kfree_skb(skb); | |
| 236 | + /* Return ownership to EMAC */ | |
| 237 | + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); | |
| 243 | 238 | stats->rx_errors++; |
| 239 | + stats->rx_dropped++; | |
| 244 | 240 | continue; |
| 245 | 241 | } |
| 242 | + | |
| 243 | + /* unmap previosly mapped skb */ | |
| 244 | + dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), | |
| 245 | + dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); | |
| 246 | + | |
| 247 | + pktlen = info & LEN_MASK; | |
| 248 | + stats->rx_packets++; | |
| 249 | + stats->rx_bytes += pktlen; | |
| 250 | + skb_put(rx_buff->skb, pktlen); | |
| 251 | + rx_buff->skb->dev = ndev; | |
| 252 | + rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev); | |
| 253 | + | |
| 254 | + netif_receive_skb(rx_buff->skb); | |
| 255 | + | |
| 256 | + rx_buff->skb = skb; | |
| 246 | 257 | dma_unmap_addr_set(rx_buff, addr, addr); |
| 247 | 258 | dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE); |
| 248 | 259 | |
| @@ -258,6 +269,53 @@ static int arc_emac_rx(struct net_device *ndev, int budget) · 9 unmodified lines | ||
| 258 | 269 | return work_done; |
| 259 | 270 | } |
| 260 | 271 | |
| 272 | +/** | |
| 273 | + * arc_emac_rx_miss_handle - handle R_MISS register | |
| 274 | + * @ndev: Pointer to the net_device structure. | |
| 275 | + */ | |
| 276 | +static void arc_emac_rx_miss_handle(struct net_device *ndev) | |
| 277 | +{ | |
| 278 | + struct arc_emac_priv *priv = netdev_priv(ndev); | |
| 279 | + struct net_device_stats *stats = &ndev->stats; | |
| 280 | + unsigned int miss; | |
| 281 | + | |
| 282 | + miss = arc_reg_get(priv, R_MISS); | |
| 283 | + if (miss) { | |
| 284 | + stats->rx_errors += miss; | |
| 285 | + stats->rx_missed_errors += miss; | |
| 286 | + priv->rx_missed_errors += miss; | |
| 287 | + } | |
| 288 | +} | |
| 289 | + | |
| 290 | +/** | |
| 291 | + * arc_emac_rx_stall_check - check RX stall | |
| 292 | + * @ndev: Pointer to the net_device structure. | |
| 293 | + * @budget: How many BDs requested to process on 1 call. | |
| 294 | + * @work_done: How many BDs processed | |
| 295 | + * | |
| 296 | + * Under certain conditions EMAC stop reception of incoming packets and | |
| 297 | + * continuously increment R_MISS register instead of saving data into | |
| 298 | + * provided buffer. This function detect that condition and restart | |
| 299 | + * EMAC. | |
| 300 | + */ | |
| 301 | +static void arc_emac_rx_stall_check(struct net_device *ndev, | |
| 302 | + int budget, unsigned int work_done) | |
| 303 | +{ | |
| 304 | + struct arc_emac_priv *priv = netdev_priv(ndev); | |
| 305 | + struct arc_emac_bd *rxbd; | |
| 306 | + | |
| 307 | + if (work_done) | |
| 308 | + priv->rx_missed_errors = 0; | |
| 309 | + | |
| 310 | + if (priv->rx_missed_errors && budget) { | |
| 311 | + rxbd = &priv->rxbd[priv->last_rx_bd]; | |
| 312 | + if (le32_to_cpu(rxbd->info) & FOR_EMAC) { | |
| 313 | + arc_emac_restart(ndev); | |
| 314 | + priv->rx_missed_errors = 0; | |
| 315 | + } | |
| 316 | + } | |
| 317 | +} | |
| 318 | + | |
| 261 | 319 | /** |
| 262 | 320 | * arc_emac_poll - NAPI poll handler. |
| 263 | 321 | * @napi: Pointer to napi_struct structure. |
| @@ -272,6 +330,7 @@ static int arc_emac_poll(struct napi_struct *napi, int budget) · 8 unmodified lines | ||
| 272 | 330 | unsigned int work_done; |
| 273 | 331 | |
| 274 | 332 | arc_emac_tx_clean(ndev); |
| 333 | + arc_emac_rx_miss_handle(ndev); | |
| 275 | 334 | |
| 276 | 335 | work_done = arc_emac_rx(ndev, budget); |
| 277 | 336 | if (work_done < budget) { |
| @@ -279,6 +338,8 @@ static int arc_emac_poll(struct napi_struct *napi, int budget) · 1 unmodified line | ||
| 279 | 338 | arc_reg_or(priv, R_ENABLE, RXINT_MASK | TXINT_MASK); |
| 280 | 339 | } |
| 281 | 340 | |
| 341 | + arc_emac_rx_stall_check(ndev, budget, work_done); | |
| 342 | + | |
| 282 | 343 | return work_done; |
| 283 | 344 | } |
| 284 | 345 | |
| @@ -320,6 +381,8 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance) · 35 unmodified lines | ||
| 320 | 381 | if (status & MSER_MASK) { |
| 321 | 382 | stats->rx_missed_errors += 0x100; |
| 322 | 383 | stats->rx_errors += 0x100; |
| 384 | + priv->rx_missed_errors += 0x100; | |
| 385 | + napi_schedule(&priv->napi); | |
| 323 | 386 | } |
| 324 | 387 | |
| 325 | 388 | if (status & RXCR_MASK) { |
| @@ -732,6 +795,63 @@ static int arc_emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) · 406 unmodified lines | ||
| 732 | 795 | } |
| 733 | 796 | |
| 734 | 797 | |
| 798 | +/** | |
| 799 | + * arc_emac_restart - Restart EMAC | |
| 800 | + * @ndev: Pointer to net_device structure. | |
| 801 | + * | |
| 802 | + * This function do hardware reset of EMAC in order to restore | |
| 803 | + * network packets reception. | |
| 804 | + */ | |
| 805 | +static void arc_emac_restart(struct net_device *ndev) | |
| 806 | +{ | |
| 807 | + struct arc_emac_priv *priv = netdev_priv(ndev); | |
| 808 | + struct net_device_stats *stats = &ndev->stats; | |
| 809 | + int i; | |
| 810 | + | |
| 811 | + if (net_ratelimit()) | |
| 812 | + netdev_warn(ndev, "restarting stalled EMAC\n"); | |
| 813 | + | |
| 814 | + netif_stop_queue(ndev); | |
| 815 | + | |
| 816 | + /* Disable interrupts */ | |
| 817 | + arc_reg_clr(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK); | |
| 818 | + | |
| 819 | + /* Disable EMAC */ | |
| 820 | + arc_reg_clr(priv, R_CTRL, EN_MASK); | |
| 821 | + | |
| 822 | + /* Return the sk_buff to system */ | |
| 823 | + arc_free_tx_queue(ndev); | |
| 824 | + | |
| 825 | + /* Clean Tx BD's */ | |
| 826 | + priv->txbd_curr = 0; | |
| 827 | + priv->txbd_dirty = 0; | |
| 828 | + memset(priv->txbd, 0, TX_RING_SZ); | |
| 829 | + | |
| 830 | + for (i = 0; i < RX_BD_NUM; i++) { | |
| 831 | + struct arc_emac_bd *rxbd = &priv->rxbd[i]; | |
| 832 | + unsigned int info = le32_to_cpu(rxbd->info); | |
| 833 | + | |
| 834 | + if (!(info & FOR_EMAC)) { | |
| 835 | + stats->rx_errors++; | |
| 836 | + stats->rx_dropped++; | |
| 837 | + } | |
| 838 | + /* Return ownership to EMAC */ | |
| 839 | + rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); | |
| 840 | + } | |
| 841 | + priv->last_rx_bd = 0; | |
| 842 | + | |
| 843 | + /* Make sure info is visible to EMAC before enable */ | |
| 844 | + wmb(); | |
| 845 | + | |
| 846 | + /* Enable interrupts */ | |
| 847 | + arc_reg_set(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK); | |
| 848 | + | |
| 849 | + /* Enable EMAC */ | |
| 850 | + arc_reg_or(priv, R_CTRL, EN_MASK); | |
| 851 | + | |
| 852 | + netif_start_queue(ndev); | |
| 853 | +} | |
| 854 | + | |
| 735 | 855 | static const struct net_device_ops arc_emac_netdev_ops = { |
| 736 | 856 | .ndo_open = arc_emac_open, |
| 737 | 857 | .ndo_stop = arc_emac_stop, |
| @@ -199,9 +199,11 @@ static int emac_rockchip_probe(struct platform_device *pdev) · 198 unmodified lines | ||
| 199 | 199 | |
| 200 | 200 | /* RMII interface needs always a rate of 50MHz */ |
| 201 | 201 | err = clk_set_rate(priv->refclk, 50000000); |
| 202 | − if (err) | |
| 202 | + if (err) { | |
| 203 | 203 | dev_err(dev, |
| 204 | 204 | "failed to change reference clock rate (%d)\n", err); |
| 205 | + goto out_regulator_disable; | |
| 206 | + } | |
| 205 | 207 | |
| 206 | 208 | if (priv->soc_data->need_div_macclk) { |
| 207 | 209 | priv->macclk = devm_clk_get(dev, "macclk"); |
| @@ -230,12 +232,14 @@ static int emac_rockchip_probe(struct platform_device *pdev) · 22 unmodified lines | ||
| 230 | 232 | err = arc_emac_probe(ndev, interface); |
| 231 | 233 | if (err) { |
| 232 | 234 | dev_err(dev, "failed to probe arc emac (%d)\n", err); |
| 233 | − goto out_regulator_disable; | |
| 235 | + goto out_clk_disable_macclk; | |
| 234 | 236 | } |
| 235 | 237 | |
| 236 | 238 | return 0; |
| 239 | + | |
| 237 | 240 | out_clk_disable_macclk: |
| 238 | − clk_disable_unprepare(priv->macclk); | |
| 241 | + if (priv->soc_data->need_div_macclk) | |
| 242 | + clk_disable_unprepare(priv->macclk); | |
| 239 | 243 | out_regulator_disable: |
| 240 | 244 | if (priv->regulator) |
| 241 | 245 | regulator_disable(priv->regulator); |
| @@ -3030,7 +3030,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) · 3029 unmodified lines | ||
| 3030 | 3030 | |
| 3031 | 3031 | del_timer_sync(&bp->timer); |
| 3032 | 3032 | |
| 3033 | − if (IS_PF(bp)) { | |
| 3033 | + if (IS_PF(bp) && !BP_NOMCP(bp)) { | |
| 3034 | 3034 | /* Set ALWAYS_ALIVE bit in shmem */ |
| 3035 | 3035 | bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; |
| 3036 | 3036 | bnx2x_drv_pulse(bp); |
| @@ -3116,7 +3116,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) · 79 unmodified lines | ||
| 3116 | 3116 | bp->cnic_loaded = false; |
| 3117 | 3117 | |
| 3118 | 3118 | /* Clear driver version indication in shmem */ |
| 3119 | − if (IS_PF(bp)) | |
| 3119 | + if (IS_PF(bp) && !BP_NOMCP(bp)) | |
| 3120 | 3120 | bnx2x_update_mng_version(bp); |
| 3121 | 3121 | |
| 3122 | 3122 | /* Check if there are pending parity attentions. If there are - set |
| @@ -9578,6 +9578,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp) · 9577 unmodified lines | ||
| 9578 | 9578 | |
| 9579 | 9579 | do { |
| 9580 | 9580 | bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); |
| 9581 | + | |
| 9582 | + /* If we read all 0xFFs, means we are in PCI error state and | |
| 9583 | + * should bail out to avoid crashes on adapter's FW reads. | |
| 9584 | + */ | |
| 9585 | + if (bp->common.shmem_base == 0xFFFFFFFF) { | |
| 9586 | + bp->flags |= NO_MCP_FLAG; | |
| 9587 | + return -ENODEV; | |
| 9588 | + } | |
| 9589 | + | |
| 9581 | 9590 | if (bp->common.shmem_base) { |
| 9582 | 9591 | val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); |
| 9583 | 9592 | if (val & SHR_MEM_VALIDITY_MB) |
| @@ -14320,7 +14329,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) · 4736 unmodified lines | ||
| 14320 | 14329 | BNX2X_ERR("IO slot reset --> driver unload\n"); |
| 14321 | 14330 | |
| 14322 | 14331 | /* MCP should have been reset; Need to wait for validity */ |
| 14323 | − bnx2x_init_shmem(bp); | |
| 14332 | + if (bnx2x_init_shmem(bp)) { | |
| 14333 | + rtnl_unlock(); | |
| 14334 | + return PCI_ERS_RESULT_DISCONNECT; | |
| 14335 | + } | |
| 14324 | 14336 | |
| 14325 | 14337 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { |
| 14326 | 14338 | u32 v; |
| @@ -4,11 +4,13 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
| 5 | 5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) |
| 6 | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
| 7 | − * Copyright (C) 2005-2014 Broadcom Corporation. | |
| 7 | + * Copyright (C) 2005-2016 Broadcom Corporation. | |
| 8 | + * Copyright (C) 2016-2017 Broadcom Limited. | |
| 8 | 9 | * |
| 9 | 10 | * Firmware is: |
| 10 | 11 | * Derived from proprietary unpublished source code, |
| 11 | − * Copyright (C) 2000-2003 Broadcom Corporation. | |
| 12 | + * Copyright (C) 2000-2016 Broadcom Corporation. | |
| 13 | + * Copyright (C) 2016-2017 Broadcom Ltd. | |
| 12 | 14 | * |
| 13 | 15 | * Permission is hereby granted for the distribution of this firmware |
| 14 | 16 | * data in hexadecimal or equivalent format, provided this copyright |
| @@ -10052,6 +10054,16 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) · 10037 unmodified lines | ||
| 10052 | 10054 | |
| 10053 | 10055 | tw32(GRC_MODE, tp->grc_mode | val); |
| 10054 | 10056 | |
| 10057 | + /* On one of the AMD platform, MRRS is restricted to 4000 because of | |
| 10058 | + * south bridge limitation. As a workaround, Driver is setting MRRS | |
| 10059 | + * to 2048 instead of default 4096. | |
| 10060 | + */ | |
| 10061 | + if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && | |
| 10062 | + tp->pdev->subsystem_device == TG3PCI_SUBDEVICE_ID_DELL_5762) { | |
| 10063 | + val = tr32(TG3PCI_DEV_STATUS_CTRL) & ~MAX_READ_REQ_MASK; | |
| 10064 | + tw32(TG3PCI_DEV_STATUS_CTRL, val | MAX_READ_REQ_SIZE_2048); | |
| 10065 | + } | |
| 10066 | + | |
| 10055 | 10067 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ |
| 10056 | 10068 | val = tr32(GRC_MISC_CFG); |
| 10057 | 10069 | val &= ~0xff; |
| @@ -14225,7 +14237,10 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) · 4167 unmodified lines | ||
| 14225 | 14237 | /* Reset PHY, otherwise the read DMA engine will be in a mode that |
| 14226 | 14238 | * breaks all requests to 256 bytes. |
| 14227 | 14239 | */ |
| 14228 | − if (tg3_asic_rev(tp) == ASIC_REV_57766) | |
| 14240 | + if (tg3_asic_rev(tp) == ASIC_REV_57766 || | |
| 14241 | + tg3_asic_rev(tp) == ASIC_REV_5717 || | |
| 14242 | + tg3_asic_rev(tp) == ASIC_REV_5719 || | |
| 14243 | + tg3_asic_rev(tp) == ASIC_REV_5720) | |
| 14229 | 14244 | reset_phy = true; |
| 14230 | 14245 | |
| 14231 | 14246 | err = tg3_restart_hw(tp, reset_phy); |
| @@ -5,7 +5,8 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
| 6 | 6 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) |
| 7 | 7 | * Copyright (C) 2004 Sun Microsystems Inc. |
| 8 | − * Copyright (C) 2007-2014 Broadcom Corporation. | |
| 8 | + * Copyright (C) 2007-2016 Broadcom Corporation. | |
| 9 | + * Copyright (C) 2016-2017 Broadcom Limited. | |
| 9 | 10 | */ |
| 10 | 11 | |
| 11 | 12 | #ifndef _T3_H |
| @@ -96,6 +97,7 @@ · 84 unmodified lines | ||
| 96 | 97 | #define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 |
| 97 | 98 | #define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 |
| 98 | 99 | #define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a |
| 100 | +#define TG3PCI_SUBDEVICE_ID_DELL_5762 0x07f0 | |
| 99 | 101 | #define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ |
| 100 | 102 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c |
| 101 | 103 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a |
| @@ -281,6 +283,9 @@ · 179 unmodified lines | ||
| 281 | 283 | #define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ |
| 282 | 284 | #define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ |
| 283 | 285 | /* 0xa8 --> 0xb8 unused */ |
| 286 | +#define TG3PCI_DEV_STATUS_CTRL 0x000000b4 | |
| 287 | +#define MAX_READ_REQ_SIZE_2048 0x00004000 | |
| 288 | +#define MAX_READ_REQ_MASK 0x00007000 | |
| 284 | 289 | #define TG3PCI_DUAL_MAC_CTRL 0x000000b8 |
| 285 | 290 | #define DUAL_MAC_CTRL_CH_MASK 0x00000003 |
| 286 | 291 | #define DUAL_MAC_CTRL_ID 0x00000004 |
| @@ -818,6 +818,12 @@ static void fec_enet_bd_init(struct net_device *dev) · 817 unmodified lines | ||
| 818 | 818 | for (i = 0; i < txq->bd.ring_size; i++) { |
| 819 | 819 | /* Initialize the BD for every fragment in the page. */ |
| 820 | 820 | bdp->cbd_sc = cpu_to_fec16(0); |
| 821 | + if (bdp->cbd_bufaddr && | |
| 822 | + !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr))) | |
| 823 | + dma_unmap_single(&fep->pdev->dev, | |
| 824 | + fec32_to_cpu(bdp->cbd_bufaddr), | |
| 825 | + fec16_to_cpu(bdp->cbd_datlen), | |
| 826 | + DMA_TO_DEVICE); | |
| 821 | 827 | if (txq->tx_skbuff[i]) { |
| 822 | 828 | dev_kfree_skb_any(txq->tx_skbuff[i]); |
| 823 | 829 | txq->tx_skbuff[i] = NULL; |
| @@ -1214,6 +1214,10 @@ static void mvneta_port_disable(struct mvneta_port *pp) · 1213 unmodified lines | ||
| 1214 | 1214 | val &= ~MVNETA_GMAC0_PORT_ENABLE; |
| 1215 | 1215 | mvreg_write(pp, MVNETA_GMAC_CTRL_0, val); |
| 1216 | 1216 | |
| 1217 | + pp->link = 0; | |
| 1218 | + pp->duplex = -1; | |
| 1219 | + pp->speed = 0; | |
| 1220 | + | |
| 1217 | 1221 | udelay(200); |
| 1218 | 1222 | } |
| 1219 | 1223 | |
| @@ -1958,9 +1962,9 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo, · 738 unmodified lines | ||
| 1958 | 1962 | |
| 1959 | 1963 | if (!mvneta_rxq_desc_is_first_last(rx_status) || |
| 1960 | 1964 | (rx_status & MVNETA_RXD_ERR_SUMMARY)) { |
| 1965 | + mvneta_rx_error(pp, rx_desc); | |
| 1961 | 1966 | err_drop_frame: |
| 1962 | 1967 | dev->stats.rx_errors++; |
| 1963 | − mvneta_rx_error(pp, rx_desc); | |
| 1964 | 1968 | /* leave the descriptor untouched */ |
| 1965 | 1969 | continue; |
| 1966 | 1970 | } |
| @@ -3011,7 +3015,7 @@ static void mvneta_cleanup_rxqs(struct mvneta_port *pp) · 1044 unmodified lines | ||
| 3011 | 3015 | { |
| 3012 | 3016 | int queue; |
| 3013 | 3017 | |
| 3014 | − for (queue = 0; queue < txq_number; queue++) | |
| 3018 | + for (queue = 0; queue < rxq_number; queue++) | |
| 3015 | 3019 | mvneta_rxq_deinit(pp, &pp->rxqs[queue]); |
| 3016 | 3020 | } |
| 3017 | 3021 | |
| @@ -4081,7 +4081,6 @@ static void skge_remove(struct pci_dev *pdev) · 4080 unmodified lines | ||
| 4081 | 4081 | if (hw->ports > 1) { |
| 4082 | 4082 | skge_write32(hw, B0_IMSK, 0); |
| 4083 | 4083 | skge_read32(hw, B0_IMSK); |
| 4084 | − free_irq(pdev->irq, hw); | |
| 4085 | 4084 | } |
| 4086 | 4085 | spin_unlock_irq(&hw->hw_lock); |
| 4087 | 4086 | |
| @@ -1961,11 +1961,12 @@ static int mtk_hw_init(struct mtk_eth *eth) · 1960 unmodified lines | ||
| 1961 | 1961 | /* set GE2 TUNE */ |
| 1962 | 1962 | regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); |
| 1963 | 1963 | |
| 1964 | − /* GE1, Force 1000M/FD, FC ON */ | |
| 1965 | − mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0)); | |
| 1966 | − | |
| 1967 | − /* GE2, Force 1000M/FD, FC ON */ | |
| 1968 | − mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1)); | |
| 1964 | + /* Set linkdown as the default for each GMAC. Its own MCR would be set | |
| 1965 | + * up with the more appropriate value when mtk_phy_link_adjust call is | |
| 1966 | + * being invoked. | |
| 1967 | + */ | |
| 1968 | + for (i = 0; i < MTK_MAC_COUNT; i++) | |
| 1969 | + mtk_w32(eth, 0, MTK_MAC_MCR(i)); | |
| 1969 | 1970 | |
| 1970 | 1971 | /* Indicates CDM to parse the MTK special tag from CPU |
| 1971 | 1972 | * which also is working out for untag packets. |
| @@ -188,7 +188,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) · 187 unmodified lines | ||
| 188 | 188 | struct net_device *dev = mdev->pndev[port]; |
| 189 | 189 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 190 | 190 | struct net_device_stats *stats = &dev->stats; |
| 191 | − struct mlx4_cmd_mailbox *mailbox; | |
| 191 | + struct mlx4_cmd_mailbox *mailbox, *mailbox_priority; | |
| 192 | 192 | u64 in_mod = reset << 8 | port; |
| 193 | 193 | int err; |
| 194 | 194 | int i, counter_index; |
| @@ -198,6 +198,13 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) · 3 unmodified lines | ||
| 198 | 198 | mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); |
| 199 | 199 | if (IS_ERR(mailbox)) |
| 200 | 200 | return PTR_ERR(mailbox); |
| 201 | + | |
| 202 | + mailbox_priority = mlx4_alloc_cmd_mailbox(mdev->dev); | |
| 203 | + if (IS_ERR(mailbox_priority)) { | |
| 204 | + mlx4_free_cmd_mailbox(mdev->dev, mailbox); | |
| 205 | + return PTR_ERR(mailbox_priority); | |
| 206 | + } | |
| 207 | + | |
| 201 | 208 | err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0, |
| 202 | 209 | MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B, |
| 203 | 210 | MLX4_CMD_NATIVE); |
| @@ -206,6 +213,28 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) · 2 unmodified lines | ||
| 206 | 213 | |
| 207 | 214 | mlx4_en_stats = mailbox->buf; |
| 208 | 215 | |
| 216 | + memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats)); | |
| 217 | + counter_index = mlx4_get_default_counter_index(mdev->dev, port); | |
| 218 | + err = mlx4_get_counter_stats(mdev->dev, counter_index, | |
| 219 | + &tmp_counter_stats, reset); | |
| 220 | + | |
| 221 | + /* 0xffs indicates invalid value */ | |
| 222 | + memset(mailbox_priority->buf, 0xff, | |
| 223 | + sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | |
| 224 | + | |
| 225 | + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) { | |
| 226 | + memset(mailbox_priority->buf, 0, | |
| 227 | + sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | |
| 228 | + err = mlx4_cmd_box(mdev->dev, 0, mailbox_priority->dma, | |
| 229 | + in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL, | |
| 230 | + 0, MLX4_CMD_DUMP_ETH_STATS, | |
| 231 | + MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | |
| 232 | + if (err) | |
| 233 | + goto out; | |
| 234 | + } | |
| 235 | + | |
| 236 | + flowstats = mailbox_priority->buf; | |
| 237 | + | |
| 209 | 238 | spin_lock_bh(&priv->stats_lock); |
| 210 | 239 | |
| 211 | 240 | mlx4_en_fold_software_stats(dev); |
| @@ -345,31 +374,6 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) · 133 unmodified lines | ||
| 345 | 374 | priv->pkstats.tx_prio[8][0] = be64_to_cpu(mlx4_en_stats->TTOT_novlan); |
| 346 | 375 | priv->pkstats.tx_prio[8][1] = be64_to_cpu(mlx4_en_stats->TOCT_novlan); |
| 347 | 376 | |
| 348 | − spin_unlock_bh(&priv->stats_lock); | |
| 349 | − | |
| 350 | − memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats)); | |
| 351 | − counter_index = mlx4_get_default_counter_index(mdev->dev, port); | |
| 352 | − err = mlx4_get_counter_stats(mdev->dev, counter_index, | |
| 353 | − &tmp_counter_stats, reset); | |
| 354 | − | |
| 355 | − /* 0xffs indicates invalid value */ | |
| 356 | − memset(mailbox->buf, 0xff, sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | |
| 357 | − | |
| 358 | − if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) { | |
| 359 | − memset(mailbox->buf, 0, | |
| 360 | − sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | |
| 361 | − err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, | |
| 362 | − in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL, | |
| 363 | − 0, MLX4_CMD_DUMP_ETH_STATS, | |
| 364 | − MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | |
| 365 | − if (err) | |
| 366 | − goto out; | |
| 367 | − } | |
| 368 | − | |
| 369 | − flowstats = mailbox->buf; | |
| 370 | − | |
| 371 | − spin_lock_bh(&priv->stats_lock); | |
| 372 | − | |
| 373 | 377 | if (tmp_counter_stats.counter_mode == 0) { |
| 374 | 378 | priv->pf_stats.rx_bytes = be64_to_cpu(tmp_counter_stats.rx_bytes); |
| 375 | 379 | priv->pf_stats.tx_bytes = be64_to_cpu(tmp_counter_stats.tx_bytes); |
| @@ -410,6 +414,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) · 34 unmodified lines | ||
| 410 | 414 | |
| 411 | 415 | out: |
| 412 | 416 | mlx4_free_cmd_mailbox(mdev->dev, mailbox); |
| 417 | + mlx4_free_cmd_mailbox(mdev->dev, mailbox_priority); | |
| 413 | 418 | return err; |
| 414 | 419 | } |
| 415 | 420 | |
| @@ -185,7 +185,7 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) · 184 unmodified lines | ||
| 185 | 185 | if (priv->mdev->dev->caps.flags & |
| 186 | 186 | MLX4_DEV_CAP_FLAG_UC_LOOPBACK) { |
| 187 | 187 | buf[3] = mlx4_en_test_registers(priv); |
| 188 | − if (priv->port_up) | |
| 188 | + if (priv->port_up && dev->mtu >= MLX4_SELFTEST_LB_MIN_MTU) | |
| 189 | 189 | buf[4] = mlx4_en_test_loopback(priv); |
| 190 | 190 | } |
| 191 | 191 | |
| @@ -153,6 +153,9 @@ · 152 unmodified lines | ||
| 153 | 153 | #define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN) |
| 154 | 154 | #define HEADER_COPY_SIZE (128 - NET_IP_ALIGN) |
| 155 | 155 | #define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN) |
| 156 | +#define PREAMBLE_LEN 8 | |
| 157 | +#define MLX4_SELFTEST_LB_MIN_MTU (MLX4_LOOPBACK_TEST_PAYLOAD + NET_IP_ALIGN + \ | |
| 158 | + ETH_HLEN + PREAMBLE_LEN) | |
| 156 | 159 | |
| 157 | 160 | #define MLX4_EN_MIN_MTU 46 |
| 158 | 161 | /* VLAN_HLEN is added twice,to support skb vlan tagged with multiple |
| @@ -611,7 +611,6 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) · 610 unmodified lines | ||
| 611 | 611 | MLX4_MAX_PORTS; |
| 612 | 612 | else |
| 613 | 613 | res_alloc->guaranteed[t] = 0; |
| 614 | − res_alloc->res_free -= res_alloc->guaranteed[t]; | |
| 615 | 614 | break; |
| 616 | 615 | default: |
| 617 | 616 | break; |
| @@ -362,7 +362,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, · 361 unmodified lines | ||
| 362 | 362 | case MLX5_CMD_OP_QUERY_VPORT_COUNTER: |
| 363 | 363 | case MLX5_CMD_OP_ALLOC_Q_COUNTER: |
| 364 | 364 | case MLX5_CMD_OP_QUERY_Q_COUNTER: |
| 365 | − case MLX5_CMD_OP_SET_RATE_LIMIT: | |
| 365 | + case MLX5_CMD_OP_SET_PP_RATE_LIMIT: | |
| 366 | 366 | case MLX5_CMD_OP_QUERY_RATE_LIMIT: |
| 367 | 367 | case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: |
| 368 | 368 | case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: |
| @@ -505,7 +505,7 @@ const char *mlx5_command_str(int command) · 136 unmodified lines | ||
| 505 | 505 | MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER); |
| 506 | 506 | MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER); |
| 507 | 507 | MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER); |
| 508 | − MLX5_COMMAND_STR_CASE(SET_RATE_LIMIT); | |
| 508 | + MLX5_COMMAND_STR_CASE(SET_PP_RATE_LIMIT); | |
| 509 | 509 | MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT); |
| 510 | 510 | MLX5_COMMAND_STR_CASE(CREATE_SCHEDULING_ELEMENT); |
| 511 | 511 | MLX5_COMMAND_STR_CASE(DESTROY_SCHEDULING_ELEMENT); |
| @@ -82,6 +82,9 @@ · 81 unmodified lines | ||
| 82 | 82 | max_t(u32, MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(mdev), req) |
| 83 | 83 | #define MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 6) |
| 84 | 84 | #define MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 8) |
| 85 | +#define MLX5E_MPWQE_STRIDE_SZ(mdev, cqe_cmprs) \ | |
| 86 | + (cqe_cmprs ? MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : \ | |
| 87 | + MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev)) | |
| 85 | 88 | |
| 86 | 89 | #define MLX5_MPWRQ_LOG_WQE_SZ 18 |
| 87 | 90 | #define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \ |
| @@ -590,6 +593,7 @@ struct mlx5e_channel { · 502 unmodified lines | ||
| 590 | 593 | struct mlx5_core_dev *mdev; |
| 591 | 594 | struct hwtstamp_config *tstamp; |
| 592 | 595 | int ix; |
| 596 | + int cpu; | |
| 593 | 597 | }; |
| 594 | 598 | |
| 595 | 599 | struct mlx5e_channels { |
| @@ -935,8 +939,9 @@ void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, · 339 unmodified lines | ||
| 935 | 939 | u8 cq_period_mode); |
| 936 | 940 | void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, |
| 937 | 941 | u8 cq_period_mode); |
| 938 | −void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, | |
| 939 | − struct mlx5e_params *params, u8 rq_type); | |
| 942 | +void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, | |
| 943 | + struct mlx5e_params *params, | |
| 944 | + u8 rq_type); | |
| 940 | 945 | |
| 941 | 946 | static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev) |
| 942 | 947 | { |
| @@ -274,6 +274,7 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) · 273 unmodified lines | ||
| 274 | 274 | static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, |
| 275 | 275 | struct ieee_ets *ets) |
| 276 | 276 | { |
| 277 | + bool have_ets_tc = false; | |
| 277 | 278 | int bw_sum = 0; |
| 278 | 279 | int i; |
| 279 | 280 | |
| @@ -288,11 +289,14 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, · 8 unmodified lines | ||
| 288 | 289 | } |
| 289 | 290 | |
| 290 | 291 | /* Validate Bandwidth Sum */ |
| 291 | − for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) | |
| 292 | − if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) | |
| 292 | + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { | |
| 293 | + if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { | |
| 294 | + have_ets_tc = true; | |
| 293 | 295 | bw_sum += ets->tc_tx_bw[i]; |
| 296 | + } | |
| 297 | + } | |
| 294 | 298 | |
| 295 | − if (bw_sum != 0 && bw_sum != 100) { | |
| 299 | + if (have_ets_tc && bw_sum != 100) { | |
| 296 | 300 | netdev_err(netdev, |
| 297 | 301 | "Failed to validate ETS: BW sum is illegal\n"); |
| 298 | 302 | return -EINVAL; |
| @@ -1523,8 +1523,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val · 1522 unmodified lines | ||
| 1523 | 1523 | new_channels.params = priv->channels.params; |
| 1524 | 1524 | MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val); |
| 1525 | 1525 | |
| 1526 | − mlx5e_set_rq_type_params(priv->mdev, &new_channels.params, | |
| 1527 | − new_channels.params.rq_wq_type); | |
| 1526 | + new_channels.params.mpwqe_log_stride_sz = | |
| 1527 | + MLX5E_MPWQE_STRIDE_SZ(priv->mdev, new_val); | |
| 1528 | + new_channels.params.mpwqe_log_num_strides = | |
| 1529 | + MLX5_MPWRQ_LOG_WQE_SZ - new_channels.params.mpwqe_log_stride_sz; | |
| 1528 | 1530 | |
| 1529 | 1531 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 1530 | 1532 | priv->channels.params = new_channels.params; |
| @@ -1536,6 +1538,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val · 5 unmodified lines | ||
| 1536 | 1538 | return err; |
| 1537 | 1539 | |
| 1538 | 1540 | mlx5e_switch_priv_channels(priv, &new_channels, NULL); |
| 1541 | + mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n", | |
| 1542 | + MLX5E_GET_PFLAG(&priv->channels.params, | |
| 1543 | + MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF"); | |
| 1544 | + | |
| 1539 | 1545 | return 0; |
| 1540 | 1546 | } |
| 1541 | 1547 | |
| @@ -71,11 +71,6 @@ struct mlx5e_channel_param { · 70 unmodified lines | ||
| 71 | 71 | struct mlx5e_cq_param icosq_cq; |
| 72 | 72 | }; |
| 73 | 73 | |
| 74 | −static int mlx5e_get_node(struct mlx5e_priv *priv, int ix) | |
| 75 | −{ | |
| 76 | − return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix); | |
| 77 | −} | |
| 78 | − | |
| 79 | 74 | static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) |
| 80 | 75 | { |
| 81 | 76 | return MLX5_CAP_GEN(mdev, striding_rq) && |
| @@ -83,8 +78,8 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) · 1 unmodified line | ||
| 83 | 78 | MLX5_CAP_ETH(mdev, reg_umr_sq); |
| 84 | 79 | } |
| 85 | 80 | |
| 86 | −void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, | |
| 87 | − struct mlx5e_params *params, u8 rq_type) | |
| 81 | +void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, | |
| 82 | + struct mlx5e_params *params, u8 rq_type) | |
| 88 | 83 | { |
| 89 | 84 | params->rq_wq_type = rq_type; |
| 90 | 85 | params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; |
| @@ -93,10 +88,8 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, · 2 unmodified lines | ||
| 93 | 88 | params->log_rq_size = is_kdump_kernel() ? |
| 94 | 89 | MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW : |
| 95 | 90 | MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW; |
| 96 | − params->mpwqe_log_stride_sz = | |
| 97 | − MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS) ? | |
| 98 | − MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : | |
| 99 | − MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev); | |
| 91 | + params->mpwqe_log_stride_sz = MLX5E_MPWQE_STRIDE_SZ(mdev, | |
| 92 | + MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); | |
| 100 | 93 | params->mpwqe_log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ - |
| 101 | 94 | params->mpwqe_log_stride_sz; |
| 102 | 95 | break; |
| @@ -120,13 +113,14 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, · 17 unmodified lines | ||
| 120 | 113 | MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); |
| 121 | 114 | } |
| 122 | 115 | |
| 123 | −static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, struct mlx5e_params *params) | |
| 116 | +static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, | |
| 117 | + struct mlx5e_params *params) | |
| 124 | 118 | { |
| 125 | 119 | u8 rq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) && |
| 126 | 120 | !params->xdp_prog && !MLX5_IPSEC_DEV(mdev) ? |
| 127 | 121 | MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ : |
| 128 | 122 | MLX5_WQ_TYPE_LINKED_LIST; |
| 129 | − mlx5e_set_rq_type_params(mdev, params, rq_type); | |
| 123 | + mlx5e_init_rq_type_params(mdev, params, rq_type); | |
| 130 | 124 | } |
| 131 | 125 | |
| 132 | 126 | static void mlx5e_update_carrier(struct mlx5e_priv *priv) |
| @@ -444,17 +438,16 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, · 311 unmodified lines | ||
| 444 | 438 | int wq_sz = mlx5_wq_ll_get_size(&rq->wq); |
| 445 | 439 | int mtt_sz = mlx5e_get_wqe_mtt_sz(); |
| 446 | 440 | int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1; |
| 447 | − int node = mlx5e_get_node(c->priv, c->ix); | |
| 448 | 441 | int i; |
| 449 | 442 | |
| 450 | 443 | rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info), |
| 451 | − GFP_KERNEL, node); | |
| 444 | + GFP_KERNEL, cpu_to_node(c->cpu)); | |
| 452 | 445 | if (!rq->mpwqe.info) |
| 453 | 446 | goto err_out; |
| 454 | 447 | |
| 455 | 448 | /* We allocate more than mtt_sz as we will align the pointer */ |
| 456 | − rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, | |
| 457 | − GFP_KERNEL, node); | |
| 449 | + rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL, | |
| 450 | + cpu_to_node(c->cpu)); | |
| 458 | 451 | if (unlikely(!rq->mpwqe.mtt_no_align)) |
| 459 | 452 | goto err_free_wqe_info; |
| 460 | 453 | |
| @@ -562,7 +555,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, · 101 unmodified lines | ||
| 562 | 555 | int err; |
| 563 | 556 | int i; |
| 564 | 557 | |
| 565 | − rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | |
| 558 | + rqp->wq.db_numa_node = cpu_to_node(c->cpu); | |
| 566 | 559 | |
| 567 | 560 | err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq, |
| 568 | 561 | &rq->wq_ctrl); |
| @@ -629,8 +622,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, · 60 unmodified lines | ||
| 629 | 622 | default: /* MLX5_WQ_TYPE_LINKED_LIST */ |
| 630 | 623 | rq->wqe.frag_info = |
| 631 | 624 | kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info), |
| 632 | − GFP_KERNEL, | |
| 633 | − mlx5e_get_node(c->priv, c->ix)); | |
| 625 | + GFP_KERNEL, cpu_to_node(c->cpu)); | |
| 634 | 626 | if (!rq->wqe.frag_info) { |
| 635 | 627 | err = -ENOMEM; |
| 636 | 628 | goto err_rq_wq_destroy; |
| @@ -1000,13 +992,13 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c, · 363 unmodified lines | ||
| 1000 | 992 | sq->uar_map = mdev->mlx5e_res.bfreg.map; |
| 1001 | 993 | sq->min_inline_mode = params->tx_min_inline_mode; |
| 1002 | 994 | |
| 1003 | − param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | |
| 995 | + param->wq.db_numa_node = cpu_to_node(c->cpu); | |
| 1004 | 996 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); |
| 1005 | 997 | if (err) |
| 1006 | 998 | return err; |
| 1007 | 999 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; |
| 1008 | 1000 | |
| 1009 | − err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix)); | |
| 1001 | + err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu)); | |
| 1010 | 1002 | if (err) |
| 1011 | 1003 | goto err_sq_wq_destroy; |
| 1012 | 1004 | |
| @@ -1053,13 +1045,13 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c, · 40 unmodified lines | ||
| 1053 | 1045 | sq->channel = c; |
| 1054 | 1046 | sq->uar_map = mdev->mlx5e_res.bfreg.map; |
| 1055 | 1047 | |
| 1056 | − param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | |
| 1048 | + param->wq.db_numa_node = cpu_to_node(c->cpu); | |
| 1057 | 1049 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); |
| 1058 | 1050 | if (err) |
| 1059 | 1051 | return err; |
| 1060 | 1052 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; |
| 1061 | 1053 | |
| 1062 | − err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix)); | |
| 1054 | + err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu)); | |
| 1063 | 1055 | if (err) |
| 1064 | 1056 | goto err_sq_wq_destroy; |
| 1065 | 1057 | |
| @@ -1126,13 +1118,13 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, · 60 unmodified lines | ||
| 1126 | 1118 | if (MLX5_IPSEC_DEV(c->priv->mdev)) |
| 1127 | 1119 | set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state); |
| 1128 | 1120 | |
| 1129 | − param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | |
| 1121 | + param->wq.db_numa_node = cpu_to_node(c->cpu); | |
| 1130 | 1122 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); |
| 1131 | 1123 | if (err) |
| 1132 | 1124 | return err; |
| 1133 | 1125 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; |
| 1134 | 1126 | |
| 1135 | − err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix)); | |
| 1127 | + err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu)); | |
| 1136 | 1128 | if (err) |
| 1137 | 1129 | goto err_sq_wq_destroy; |
| 1138 | 1130 | |
| @@ -1504,8 +1496,8 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c, · 365 unmodified lines | ||
| 1504 | 1496 | struct mlx5_core_dev *mdev = c->priv->mdev; |
| 1505 | 1497 | int err; |
| 1506 | 1498 | |
| 1507 | − param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix); | |
| 1508 | − param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | |
| 1499 | + param->wq.buf_numa_node = cpu_to_node(c->cpu); | |
| 1500 | + param->wq.db_numa_node = cpu_to_node(c->cpu); | |
| 1509 | 1501 | param->eq_ix = c->ix; |
| 1510 | 1502 | |
| 1511 | 1503 | err = mlx5e_alloc_cq_common(mdev, param, cq); |
| @@ -1604,6 +1596,11 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq) · 92 unmodified lines | ||
| 1604 | 1596 | mlx5e_free_cq(cq); |
| 1605 | 1597 | } |
| 1606 | 1598 | |
| 1599 | +static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix) | |
| 1600 | +{ | |
| 1601 | + return cpumask_first(priv->mdev->priv.irq_info[ix].mask); | |
| 1602 | +} | |
| 1603 | + | |
| 1607 | 1604 | static int mlx5e_open_tx_cqs(struct mlx5e_channel *c, |
| 1608 | 1605 | struct mlx5e_params *params, |
| 1609 | 1606 | struct mlx5e_channel_param *cparam) |
| @@ -1752,12 +1749,13 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, · 142 unmodified lines | ||
| 1752 | 1749 | { |
| 1753 | 1750 | struct mlx5e_cq_moder icocq_moder = {0, 0}; |
| 1754 | 1751 | struct net_device *netdev = priv->netdev; |
| 1752 | + int cpu = mlx5e_get_cpu(priv, ix); | |
| 1755 | 1753 | struct mlx5e_channel *c; |
| 1756 | 1754 | unsigned int irq; |
| 1757 | 1755 | int err; |
| 1758 | 1756 | int eqn; |
| 1759 | 1757 | |
| 1760 | − c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix)); | |
| 1758 | + c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); | |
| 1761 | 1759 | if (!c) |
| 1762 | 1760 | return -ENOMEM; |
| 1763 | 1761 | |
| @@ -1765,6 +1763,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, · 1 unmodified line | ||
| 1765 | 1763 | c->mdev = priv->mdev; |
| 1766 | 1764 | c->tstamp = &priv->tstamp; |
| 1767 | 1765 | c->ix = ix; |
| 1766 | + c->cpu = cpu; | |
| 1768 | 1767 | c->pdev = &priv->mdev->pdev->dev; |
| 1769 | 1768 | c->netdev = priv->netdev; |
| 1770 | 1769 | c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key); |
| @@ -1853,8 +1852,7 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c) · 82 unmodified lines | ||
| 1853 | 1852 | for (tc = 0; tc < c->num_tc; tc++) |
| 1854 | 1853 | mlx5e_activate_txqsq(&c->sq[tc]); |
| 1855 | 1854 | mlx5e_activate_rq(&c->rq); |
| 1856 | − netif_set_xps_queue(c->netdev, | |
| 1857 | − mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix); | |
| 1855 | + netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix); | |
| 1858 | 1856 | } |
| 1859 | 1857 | |
| 1860 | 1858 | static void mlx5e_deactivate_channel(struct mlx5e_channel *c) |
| @@ -3679,6 +3677,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, · 1818 unmodified lines | ||
| 3679 | 3677 | struct sk_buff *skb, |
| 3680 | 3678 | netdev_features_t features) |
| 3681 | 3679 | { |
| 3680 | + unsigned int offset = 0; | |
| 3682 | 3681 | struct udphdr *udph; |
| 3683 | 3682 | u8 proto; |
| 3684 | 3683 | u16 port; |
| @@ -3688,7 +3687,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, · 3 unmodified lines | ||
| 3688 | 3687 | proto = ip_hdr(skb)->protocol; |
| 3689 | 3688 | break; |
| 3690 | 3689 | case htons(ETH_P_IPV6): |
| 3691 | − proto = ipv6_hdr(skb)->nexthdr; | |
| 3690 | + proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL); | |
| 3692 | 3691 | break; |
| 3693 | 3692 | default: |
| 3694 | 3693 | goto out; |
| @@ -466,7 +466,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr) · 465 unmodified lines | ||
| 466 | 466 | break; |
| 467 | 467 | case MLX5_EVENT_TYPE_CQ_ERROR: |
| 468 | 468 | cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff; |
| 469 | − mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrom 0x%x\n", | |
| 469 | + mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n", | |
| 470 | 470 | cqn, eqe->data.cq_err.syndrome); |
| 471 | 471 | mlx5_cq_event(dev, cqn, eqe->type); |
| 472 | 472 | break; |
| @@ -775,7 +775,7 @@ err1: · 302 unmodified lines | ||
| 775 | 775 | return err; |
| 776 | 776 | } |
| 777 | 777 | |
| 778 | −int mlx5_stop_eqs(struct mlx5_core_dev *dev) | |
| 778 | +void mlx5_stop_eqs(struct mlx5_core_dev *dev) | |
| 779 | 779 | { |
| 780 | 780 | struct mlx5_eq_table *table = &dev->priv.eq_table; |
| 781 | 781 | int err; |
| @@ -784,22 +784,26 @@ int mlx5_stop_eqs(struct mlx5_core_dev *dev) · 2 unmodified lines | ||
| 784 | 784 | if (MLX5_CAP_GEN(dev, pg)) { |
| 785 | 785 | err = mlx5_destroy_unmap_eq(dev, &table->pfault_eq); |
| 786 | 786 | if (err) |
| 787 | − return err; | |
| 787 | + mlx5_core_err(dev, "failed to destroy page fault eq, err(%d)\n", | |
| 788 | + err); | |
| 788 | 789 | } |
| 789 | 790 | #endif |
| 790 | 791 | |
| 791 | 792 | err = mlx5_destroy_unmap_eq(dev, &table->pages_eq); |
| 792 | 793 | if (err) |
| 793 | − return err; | |
| 794 | + mlx5_core_err(dev, "failed to destroy pages eq, err(%d)\n", | |
| 795 | + err); | |
| 794 | 796 | |
| 795 | − mlx5_destroy_unmap_eq(dev, &table->async_eq); | |
| 797 | + err = mlx5_destroy_unmap_eq(dev, &table->async_eq); | |
| 798 | + if (err) | |
| 799 | + mlx5_core_err(dev, "failed to destroy async eq, err(%d)\n", | |
| 800 | + err); | |
| 796 | 801 | mlx5_cmd_use_polling(dev); |
| 797 | 802 | |
| 798 | 803 | err = mlx5_destroy_unmap_eq(dev, &table->cmd_eq); |
| 799 | 804 | if (err) |
| 800 | − mlx5_cmd_use_events(dev); | |
| 801 | − | |
| 802 | − return err; | |
| 805 | + mlx5_core_err(dev, "failed to destroy command eq, err(%d)\n", | |
| 806 | + err); | |
| 803 | 807 | } |
| 804 | 808 | |
| 805 | 809 | int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, |
| @@ -66,6 +66,9 @@ static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size, · 65 unmodified lines | ||
| 66 | 66 | u8 actual_size; |
| 67 | 67 | int err; |
| 68 | 68 | |
| 69 | + if (!size) | |
| 70 | + return -EINVAL; | |
| 71 | + | |
| 69 | 72 | if (!fdev->mdev) |
| 70 | 73 | return -ENOTCONN; |
| 71 | 74 | |
| @@ -95,6 +98,9 @@ static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size, · 23 unmodified lines | ||
| 95 | 98 | u8 actual_size; |
| 96 | 99 | int err; |
| 97 | 100 | |
| 101 | + if (!size) | |
| 102 | + return -EINVAL; | |
| 103 | + | |
| 98 | 104 | if (!fdev->mdev) |
| 99 | 105 | return -ENOTCONN; |
| 100 | 106 | |
| @@ -174,6 +174,8 @@ static void del_hw_fte(struct fs_node *node); · 173 unmodified lines | ||
| 174 | 174 | static void del_sw_flow_table(struct fs_node *node); |
| 175 | 175 | static void del_sw_flow_group(struct fs_node *node); |
| 176 | 176 | static void del_sw_fte(struct fs_node *node); |
| 177 | +static void del_sw_prio(struct fs_node *node); | |
| 178 | +static void del_sw_ns(struct fs_node *node); | |
| 177 | 179 | /* Delete rule (destination) is special case that |
| 178 | 180 | * requires to lock the FTE for all the deletion process. |
| 179 | 181 | */ |
| @@ -408,6 +410,16 @@ static inline struct mlx5_core_dev *get_dev(struct fs_node *node) · 228 unmodified lines | ||
| 408 | 410 | return NULL; |
| 409 | 411 | } |
| 410 | 412 | |
| 413 | +static void del_sw_ns(struct fs_node *node) | |
| 414 | +{ | |
| 415 | + kfree(node); | |
| 416 | +} | |
| 417 | + | |
| 418 | +static void del_sw_prio(struct fs_node *node) | |
| 419 | +{ | |
| 420 | + kfree(node); | |
| 421 | +} | |
| 422 | + | |
| 411 | 423 | static void del_hw_flow_table(struct fs_node *node) |
| 412 | 424 | { |
| 413 | 425 | struct mlx5_flow_table *ft; |
| @@ -2064,7 +2076,7 @@ static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns, · 1650 unmodified lines | ||
| 2064 | 2076 | return ERR_PTR(-ENOMEM); |
| 2065 | 2077 | |
| 2066 | 2078 | fs_prio->node.type = FS_TYPE_PRIO; |
| 2067 | − tree_init_node(&fs_prio->node, NULL, NULL); | |
| 2079 | + tree_init_node(&fs_prio->node, NULL, del_sw_prio); | |
| 2068 | 2080 | tree_add_node(&fs_prio->node, &ns->node); |
| 2069 | 2081 | fs_prio->num_levels = num_levels; |
| 2070 | 2082 | fs_prio->prio = prio; |
| @@ -2090,7 +2102,7 @@ static struct mlx5_flow_namespace *fs_create_namespace(struct fs_prio *prio) · 19 unmodified lines | ||
| 2090 | 2102 | return ERR_PTR(-ENOMEM); |
| 2091 | 2103 | |
| 2092 | 2104 | fs_init_namespace(ns); |
| 2093 | − tree_init_node(&ns->node, NULL, NULL); | |
| 2105 | + tree_init_node(&ns->node, NULL, del_sw_ns); | |
| 2094 | 2106 | tree_add_node(&ns->node, &prio->node); |
| 2095 | 2107 | list_add_tail(&ns->node.list, &prio->node.children); |
| 2096 | 2108 | |
| @@ -241,7 +241,7 @@ static void print_health_info(struct mlx5_core_dev *dev) · 240 unmodified lines | ||
| 241 | 241 | u32 fw; |
| 242 | 242 | int i; |
| 243 | 243 | |
| 244 | − /* If the syndrom is 0, the device is OK and no need to print buffer */ | |
| 244 | + /* If the syndrome is 0, the device is OK and no need to print buffer */ | |
| 245 | 245 | if (!ioread8(&h->synd)) |
| 246 | 246 | return; |
| 247 | 247 | |
| @@ -57,7 +57,7 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, · 56 unmodified lines | ||
| 57 | 57 | struct mlx5e_params *params) |
| 58 | 58 | { |
| 59 | 59 | /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */ |
| 60 | − mlx5e_set_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); | |
| 60 | + mlx5e_init_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); | |
| 61 | 61 | |
| 62 | 62 | /* RQ size in ipoib by default is 512 */ |
| 63 | 63 | params->log_rq_size = is_kdump_kernel() ? |
| @@ -137,6 +137,17 @@ int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev) · 136 unmodified lines | ||
| 137 | 137 | } |
| 138 | 138 | EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag); |
| 139 | 139 | |
| 140 | +static int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | |
| 141 | + bool reset, void *out, int out_size) | |
| 142 | +{ | |
| 143 | + u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { }; | |
| 144 | + | |
| 145 | + MLX5_SET(query_cong_statistics_in, in, opcode, | |
| 146 | + MLX5_CMD_OP_QUERY_CONG_STATISTICS); | |
| 147 | + MLX5_SET(query_cong_statistics_in, in, clear, reset); | |
| 148 | + return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | |
| 149 | +} | |
| 150 | + | |
| 140 | 151 | static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev) |
| 141 | 152 | { |
| 142 | 153 | return dev->priv.lag; |
| @@ -633,3 +644,48 @@ bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv) · 490 unmodified lines | ||
| 633 | 644 | /* If bonded, we do not add an IB device for PF1. */ |
| 634 | 645 | return false; |
| 635 | 646 | } |
| 647 | + | |
| 648 | +int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, | |
| 649 | + u64 *values, | |
| 650 | + int num_counters, | |
| 651 | + size_t *offsets) | |
| 652 | +{ | |
| 653 | + int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); | |
| 654 | + struct mlx5_core_dev *mdev[MLX5_MAX_PORTS]; | |
| 655 | + struct mlx5_lag *ldev; | |
| 656 | + int num_ports; | |
| 657 | + int ret, i, j; | |
| 658 | + void *out; | |
| 659 | + | |
| 660 | + out = kvzalloc(outlen, GFP_KERNEL); | |
| 661 | + if (!out) | |
| 662 | + return -ENOMEM; | |
| 663 | + | |
| 664 | + memset(values, 0, sizeof(*values) * num_counters); | |
| 665 | + | |
| 666 | + mutex_lock(&lag_mutex); | |
| 667 | + ldev = mlx5_lag_dev_get(dev); | |
| 668 | + if (ldev && mlx5_lag_is_bonded(ldev)) { | |
| 669 | + num_ports = MLX5_MAX_PORTS; | |
| 670 | + mdev[0] = ldev->pf[0].dev; | |
| 671 | + mdev[1] = ldev->pf[1].dev; | |
| 672 | + } else { | |
| 673 | + num_ports = 1; | |
| 674 | + mdev[0] = dev; | |
| 675 | + } | |
| 676 | + | |
| 677 | + for (i = 0; i < num_ports; ++i) { | |
| 678 | + ret = mlx5_cmd_query_cong_counter(mdev[i], false, out, outlen); | |
| 679 | + if (ret) | |
| 680 | + goto unlock; | |
| 681 | + | |
| 682 | + for (j = 0; j < num_counters; ++j) | |
| 683 | + values[j] += be64_to_cpup((__be64 *)(out + offsets[j])); | |
| 684 | + } | |
| 685 | + | |
| 686 | +unlock: | |
| 687 | + mutex_unlock(&lag_mutex); | |
| 688 | + kvfree(out); | |
| 689 | + return ret; | |
| 690 | +} | |
| 691 | +EXPORT_SYMBOL(mlx5_lag_query_cong_counters); | |
| @@ -317,9 +317,6 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) · 316 unmodified lines | ||
| 317 | 317 | { |
| 318 | 318 | struct mlx5_priv *priv = &dev->priv; |
| 319 | 319 | struct mlx5_eq_table *table = &priv->eq_table; |
| 320 | − struct irq_affinity irqdesc = { | |
| 321 | − .pre_vectors = MLX5_EQ_VEC_COMP_BASE, | |
| 322 | − }; | |
| 323 | 320 | int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq); |
| 324 | 321 | int nvec; |
| 325 | 322 | |
| @@ -333,10 +330,9 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) · 7 unmodified lines | ||
| 333 | 330 | if (!priv->irq_info) |
| 334 | 331 | goto err_free_msix; |
| 335 | 332 | |
| 336 | − nvec = pci_alloc_irq_vectors_affinity(dev->pdev, | |
| 333 | + nvec = pci_alloc_irq_vectors(dev->pdev, | |
| 337 | 334 | MLX5_EQ_VEC_COMP_BASE + 1, nvec, |
| 338 | − PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, | |
| 339 | − &irqdesc); | |
| 335 | + PCI_IRQ_MSIX); | |
| 340 | 336 | if (nvec < 0) |
| 341 | 337 | return nvec; |
| 342 | 338 | |
| @@ -622,6 +618,63 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev) · 279 unmodified lines | ||
| 622 | 618 | return (u64)timer_l | (u64)timer_h1 << 32; |
| 623 | 619 | } |
| 624 | 620 | |
| 621 | +static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) | |
| 622 | +{ | |
| 623 | + struct mlx5_priv *priv = &mdev->priv; | |
| 624 | + int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i); | |
| 625 | + | |
| 626 | + if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { | |
| 627 | + mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); | |
| 628 | + return -ENOMEM; | |
| 629 | + } | |
| 630 | + | |
| 631 | + cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), | |
| 632 | + priv->irq_info[i].mask); | |
| 633 | + | |
| 634 | + if (IS_ENABLED(CONFIG_SMP) && | |
| 635 | + irq_set_affinity_hint(irq, priv->irq_info[i].mask)) | |
| 636 | + mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); | |
| 637 | + | |
| 638 | + return 0; | |
| 639 | +} | |
| 640 | + | |
| 641 | +static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) | |
| 642 | +{ | |
| 643 | + struct mlx5_priv *priv = &mdev->priv; | |
| 644 | + int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i); | |
| 645 | + | |
| 646 | + irq_set_affinity_hint(irq, NULL); | |
| 647 | + free_cpumask_var(priv->irq_info[i].mask); | |
| 648 | +} | |
| 649 | + | |
| 650 | +static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev) | |
| 651 | +{ | |
| 652 | + int err; | |
| 653 | + int i; | |
| 654 | + | |
| 655 | + for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) { | |
| 656 | + err = mlx5_irq_set_affinity_hint(mdev, i); | |
| 657 | + if (err) | |
| 658 | + goto err_out; | |
| 659 | + } | |
| 660 | + | |
| 661 | + return 0; | |
| 662 | + | |
| 663 | +err_out: | |
| 664 | + for (i--; i >= 0; i--) | |
| 665 | + mlx5_irq_clear_affinity_hint(mdev, i); | |
| 666 | + | |
| 667 | + return err; | |
| 668 | +} | |
| 669 | + | |
| 670 | +static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev) | |
| 671 | +{ | |
| 672 | + int i; | |
| 673 | + | |
| 674 | + for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) | |
| 675 | + mlx5_irq_clear_affinity_hint(mdev, i); | |
| 676 | +} | |
| 677 | + | |
| 625 | 678 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, |
| 626 | 679 | unsigned int *irqn) |
| 627 | 680 | { |
| @@ -1097,6 +1150,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, · 469 unmodified lines | ||
| 1097 | 1150 | goto err_stop_eqs; |
| 1098 | 1151 | } |
| 1099 | 1152 | |
| 1153 | + err = mlx5_irq_set_affinity_hints(dev); | |
| 1154 | + if (err) { | |
| 1155 | + dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n"); | |
| 1156 | + goto err_affinity_hints; | |
| 1157 | + } | |
| 1158 | + | |
| 1100 | 1159 | err = mlx5_init_fs(dev); |
| 1101 | 1160 | if (err) { |
| 1102 | 1161 | dev_err(&pdev->dev, "Failed to init flow steering\n"); |
| @@ -1154,6 +1213,9 @@ err_sriov: · 51 unmodified lines | ||
| 1154 | 1213 | mlx5_cleanup_fs(dev); |
| 1155 | 1214 | |
| 1156 | 1215 | err_fs: |
| 1216 | + mlx5_irq_clear_affinity_hints(dev); | |
| 1217 | + | |
| 1218 | +err_affinity_hints: | |
| 1157 | 1219 | free_comp_eqs(dev); |
| 1158 | 1220 | |
| 1159 | 1221 | err_stop_eqs: |
| @@ -1222,6 +1284,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, · 62 unmodified lines | ||
| 1222 | 1284 | |
| 1223 | 1285 | mlx5_sriov_detach(dev); |
| 1224 | 1286 | mlx5_cleanup_fs(dev); |
| 1287 | + mlx5_irq_clear_affinity_hints(dev); | |
| 1225 | 1288 | free_comp_eqs(dev); |
| 1226 | 1289 | mlx5_stop_eqs(dev); |
| 1227 | 1290 | mlx5_put_uars_page(dev, priv->uar); |
| @@ -213,8 +213,8 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev, · 212 unmodified lines | ||
| 213 | 213 | err_cmd: |
| 214 | 214 | memset(din, 0, sizeof(din)); |
| 215 | 215 | memset(dout, 0, sizeof(dout)); |
| 216 | − MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP); | |
| 217 | − MLX5_SET(destroy_qp_in, in, qpn, qp->qpn); | |
| 216 | + MLX5_SET(destroy_qp_in, din, opcode, MLX5_CMD_OP_DESTROY_QP); | |
| 217 | + MLX5_SET(destroy_qp_in, din, qpn, qp->qpn); | |
| 218 | 218 | mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout)); |
| 219 | 219 | return err; |
| 220 | 220 | } |
| @@ -125,16 +125,16 @@ static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table, · 124 unmodified lines | ||
| 125 | 125 | return ret_entry; |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | −static int mlx5_set_rate_limit_cmd(struct mlx5_core_dev *dev, | |
| 128 | +static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev, | |
| 129 | 129 | u32 rate, u16 index) |
| 130 | 130 | { |
| 131 | − u32 in[MLX5_ST_SZ_DW(set_rate_limit_in)] = {0}; | |
| 132 | − u32 out[MLX5_ST_SZ_DW(set_rate_limit_out)] = {0}; | |
| 131 | + u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {0}; | |
| 132 | + u32 out[MLX5_ST_SZ_DW(set_pp_rate_limit_out)] = {0}; | |
| 133 | 133 | |
| 134 | − MLX5_SET(set_rate_limit_in, in, opcode, | |
| 135 | − MLX5_CMD_OP_SET_RATE_LIMIT); | |
| 136 | − MLX5_SET(set_rate_limit_in, in, rate_limit_index, index); | |
| 137 | − MLX5_SET(set_rate_limit_in, in, rate_limit, rate); | |
| 134 | + MLX5_SET(set_pp_rate_limit_in, in, opcode, | |
| 135 | + MLX5_CMD_OP_SET_PP_RATE_LIMIT); | |
| 136 | + MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, index); | |
| 137 | + MLX5_SET(set_pp_rate_limit_in, in, rate_limit, rate); | |
| 138 | 138 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
| 139 | 139 | } |
| 140 | 140 | |
| @@ -173,7 +173,7 @@ int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index) · 32 unmodified lines | ||
| 173 | 173 | entry->refcount++; |
| 174 | 174 | } else { |
| 175 | 175 | /* new rate limit */ |
| 176 | − err = mlx5_set_rate_limit_cmd(dev, rate, entry->index); | |
| 176 | + err = mlx5_set_pp_rate_limit_cmd(dev, rate, entry->index); | |
| 177 | 177 | if (err) { |
| 178 | 178 | mlx5_core_err(dev, "Failed configuring rate: %u (%d)\n", |
| 179 | 179 | rate, err); |
| @@ -209,7 +209,7 @@ void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, u32 rate) · 29 unmodified lines | ||
| 209 | 209 | entry->refcount--; |
| 210 | 210 | if (!entry->refcount) { |
| 211 | 211 | /* need to remove rate */ |
| 212 | − mlx5_set_rate_limit_cmd(dev, 0, entry->index); | |
| 212 | + mlx5_set_pp_rate_limit_cmd(dev, 0, entry->index); | |
| 213 | 213 | entry->rate = 0; |
| 214 | 214 | } |
| 215 | 215 | |
| @@ -262,8 +262,8 @@ void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev) · 46 unmodified lines | ||
| 262 | 262 | /* Clear all configured rates */ |
| 263 | 263 | for (i = 0; i < table->max_size; i++) |
| 264 | 264 | if (table->rl_entry[i].rate) |
| 265 | − mlx5_set_rate_limit_cmd(dev, 0, | |
| 266 | − table->rl_entry[i].index); | |
| 265 | + mlx5_set_pp_rate_limit_cmd(dev, 0, | |
| 266 | + table->rl_entry[i].index); | |
| 267 | 267 | |
| 268 | 268 | kfree(dev->priv.rl_table.rl_entry); |
| 269 | 269 | } |
| @@ -71,9 +71,9 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) · 70 unmodified lines | ||
| 71 | 71 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 72 | 72 | struct mlx5e_vxlan *vxlan; |
| 73 | 73 | |
| 74 | − spin_lock(&vxlan_db->lock); | |
| 74 | + spin_lock_bh(&vxlan_db->lock); | |
| 75 | 75 | vxlan = radix_tree_lookup(&vxlan_db->tree, port); |
| 76 | − spin_unlock(&vxlan_db->lock); | |
| 76 | + spin_unlock_bh(&vxlan_db->lock); | |
| 77 | 77 | |
| 78 | 78 | return vxlan; |
| 79 | 79 | } |
| @@ -88,8 +88,12 @@ static void mlx5e_vxlan_add_port(struct work_struct *work) · 8 unmodified lines | ||
| 88 | 88 | struct mlx5e_vxlan *vxlan; |
| 89 | 89 | int err; |
| 90 | 90 | |
| 91 | − if (mlx5e_vxlan_lookup_port(priv, port)) | |
| 91 | + mutex_lock(&priv->state_lock); | |
| 92 | + vxlan = mlx5e_vxlan_lookup_port(priv, port); | |
| 93 | + if (vxlan) { | |
| 94 | + atomic_inc(&vxlan->refcount); | |
| 92 | 95 | goto free_work; |
| 96 | + } | |
| 93 | 97 | |
| 94 | 98 | if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) |
| 95 | 99 | goto free_work; |
| @@ -99,10 +103,11 @@ static void mlx5e_vxlan_add_port(struct work_struct *work) · 3 unmodified lines | ||
| 99 | 103 | goto err_delete_port; |
| 100 | 104 | |
| 101 | 105 | vxlan->udp_port = port; |
| 106 | + atomic_set(&vxlan->refcount, 1); | |
| 102 | 107 | |
| 103 | − spin_lock_irq(&vxlan_db->lock); | |
| 108 | + spin_lock_bh(&vxlan_db->lock); | |
| 104 | 109 | err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan); |
| 105 | − spin_unlock_irq(&vxlan_db->lock); | |
| 110 | + spin_unlock_bh(&vxlan_db->lock); | |
| 106 | 111 | if (err) |
| 107 | 112 | goto err_free; |
| 108 | 113 | |
| @@ -113,35 +118,39 @@ err_free: · 4 unmodified lines | ||
| 113 | 118 | err_delete_port: |
| 114 | 119 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); |
| 115 | 120 | free_work: |
| 121 | + mutex_unlock(&priv->state_lock); | |
| 116 | 122 | kfree(vxlan_work); |
| 117 | 123 | } |
| 118 | 124 | |
| 119 | −static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) | |
| 125 | +static void mlx5e_vxlan_del_port(struct work_struct *work) | |
| 120 | 126 | { |
| 127 | + struct mlx5e_vxlan_work *vxlan_work = | |
| 128 | + container_of(work, struct mlx5e_vxlan_work, work); | |
| 129 | + struct mlx5e_priv *priv = vxlan_work->priv; | |
| 121 | 130 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 131 | + u16 port = vxlan_work->port; | |
| 122 | 132 | struct mlx5e_vxlan *vxlan; |
| 133 | + bool remove = false; | |
| 123 | 134 | |
| 124 | − spin_lock_irq(&vxlan_db->lock); | |
| 125 | − vxlan = radix_tree_delete(&vxlan_db->tree, port); | |
| 126 | − spin_unlock_irq(&vxlan_db->lock); | |
| 127 | − | |
| 135 | + mutex_lock(&priv->state_lock); | |
| 136 | + spin_lock_bh(&vxlan_db->lock); | |
| 137 | + vxlan = radix_tree_lookup(&vxlan_db->tree, port); | |
| 128 | 138 | if (!vxlan) |
| 129 | − return; | |
| 130 | − | |
| 131 | − mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port); | |
| 132 | − | |
| 133 | − kfree(vxlan); | |
| 134 | −} | |
| 139 | + goto out_unlock; | |
| 135 | 140 | |
| 136 | −static void mlx5e_vxlan_del_port(struct work_struct *work) | |
| 137 | −{ | |
| 138 | − struct mlx5e_vxlan_work *vxlan_work = | |
| 139 | − container_of(work, struct mlx5e_vxlan_work, work); | |
| 140 | − struct mlx5e_priv *priv = vxlan_work->priv; | |
| 141 | − u16 port = vxlan_work->port; | |
| 141 | + if (atomic_dec_and_test(&vxlan->refcount)) { | |
| 142 | + radix_tree_delete(&vxlan_db->tree, port); | |
| 143 | + remove = true; | |
| 144 | + } | |
| 142 | 145 | |
| 143 | − __mlx5e_vxlan_core_del_port(priv, port); | |
| 146 | +out_unlock: | |
| 147 | + spin_unlock_bh(&vxlan_db->lock); | |
| 144 | 148 | |
| 149 | + if (remove) { | |
| 150 | + mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); | |
| 151 | + kfree(vxlan); | |
| 152 | + } | |
| 153 | + mutex_unlock(&priv->state_lock); | |
| 145 | 154 | kfree(vxlan_work); |
| 146 | 155 | } |
| 147 | 156 | |
| @@ -171,12 +180,11 @@ void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) · 23 unmodified lines | ||
| 171 | 180 | struct mlx5e_vxlan *vxlan; |
| 172 | 181 | unsigned int port = 0; |
| 173 | 182 | |
| 174 | − spin_lock_irq(&vxlan_db->lock); | |
| 183 | + /* Lockless since we are the only radix-tree consumers, wq is disabled */ | |
| 175 | 184 | while (radix_tree_gang_lookup(&vxlan_db->tree, (void **)&vxlan, port, 1)) { |
| 176 | 185 | port = vxlan->udp_port; |
| 177 | − spin_unlock_irq(&vxlan_db->lock); | |
| 178 | − __mlx5e_vxlan_core_del_port(priv, (u16)port); | |
| 179 | − spin_lock_irq(&vxlan_db->lock); | |
| 186 | + radix_tree_delete(&vxlan_db->tree, port); | |
| 187 | + mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); | |
| 188 | + kfree(vxlan); | |
| 180 | 189 | } |
| 181 | − spin_unlock_irq(&vxlan_db->lock); | |
| 182 | 190 | } |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include "en.h" |
| 37 | 37 | |
| 38 | 38 | struct mlx5e_vxlan { |
| 39 | + atomic_t refcount; | |
| 39 | 40 | u16 udp_port; |
| 40 | 41 | }; |
| 41 | 42 | |
| @@ -4300,6 +4300,7 @@ static int mlxsw_sp_port_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, · 4299 unmodified lines | ||
| 4300 | 4300 | |
| 4301 | 4301 | static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port) |
| 4302 | 4302 | { |
| 4303 | + u16 vid = 1; | |
| 4303 | 4304 | int err; |
| 4304 | 4305 | |
| 4305 | 4306 | err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true); |
| @@ -4312,8 +4313,19 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port) · 6 unmodified lines | ||
| 4312 | 4313 | true, false); |
| 4313 | 4314 | if (err) |
| 4314 | 4315 | goto err_port_vlan_set; |
| 4316 | + | |
| 4317 | + for (; vid <= VLAN_N_VID - 1; vid++) { | |
| 4318 | + err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, | |
| 4319 | + vid, false); | |
| 4320 | + if (err) | |
| 4321 | + goto err_vid_learning_set; | |
| 4322 | + } | |
| 4323 | + | |
| 4315 | 4324 | return 0; |
| 4316 | 4325 | |
| 4326 | +err_vid_learning_set: | |
| 4327 | + for (vid--; vid >= 1; vid--) | |
| 4328 | + mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true); | |
| 4317 | 4329 | err_port_vlan_set: |
| 4318 | 4330 | mlxsw_sp_port_stp_set(mlxsw_sp_port, false); |
| 4319 | 4331 | err_port_stp_set: |
| @@ -4323,6 +4335,12 @@ err_port_stp_set: · 3 unmodified lines | ||
| 4323 | 4335 | |
| 4324 | 4336 | static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port) |
| 4325 | 4337 | { |
| 4338 | + u16 vid; | |
| 4339 | + | |
| 4340 | + for (vid = VLAN_N_VID - 1; vid >= 1; vid--) | |
| 4341 | + mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, | |
| 4342 | + vid, true); | |
| 4343 | + | |
| 4326 | 4344 | mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1, |
| 4327 | 4345 | false, false); |
| 4328 | 4346 | mlxsw_sp_port_stp_set(mlxsw_sp_port, false); |
| @@ -2436,25 +2436,16 @@ static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp) · 2435 unmodified lines | ||
| 2436 | 2436 | rhashtable_destroy(&mlxsw_sp->router->neigh_ht); |
| 2437 | 2437 | } |
| 2438 | 2438 | |
| 2439 | −static int mlxsw_sp_neigh_rif_flush(struct mlxsw_sp *mlxsw_sp, | |
| 2440 | − const struct mlxsw_sp_rif *rif) | |
| 2441 | −{ | |
| 2442 | − char rauht_pl[MLXSW_REG_RAUHT_LEN]; | |
| 2443 | − | |
| 2444 | − mlxsw_reg_rauht_pack(rauht_pl, MLXSW_REG_RAUHT_OP_WRITE_DELETE_ALL, | |
| 2445 | − rif->rif_index, rif->addr); | |
| 2446 | − return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); | |
| 2447 | −} | |
| 2448 | − | |
| 2449 | 2439 | static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, |
| 2450 | 2440 | struct mlxsw_sp_rif *rif) |
| 2451 | 2441 | { |
| 2452 | 2442 | struct mlxsw_sp_neigh_entry *neigh_entry, *tmp; |
| 2453 | 2443 | |
| 2454 | − mlxsw_sp_neigh_rif_flush(mlxsw_sp, rif); | |
| 2455 | 2444 | list_for_each_entry_safe(neigh_entry, tmp, &rif->neigh_list, |
| 2456 | − rif_list_node) | |
| 2445 | + rif_list_node) { | |
| 2446 | + mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, false); | |
| 2457 | 2447 | mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); |
| 2448 | + } | |
| 2458 | 2449 | } |
| 2459 | 2450 | |
| 2460 | 2451 | enum mlxsw_sp_nexthop_type { |
| @@ -82,10 +82,33 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn) · 81 unmodified lines | ||
| 82 | 82 | return nfp_net_ebpf_capable(nn) ? "BPF" : ""; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | +static int | |
| 86 | +nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) | |
| 87 | +{ | |
| 88 | + int err; | |
| 89 | + | |
| 90 | + nn->app_priv = kzalloc(sizeof(struct nfp_bpf_vnic), GFP_KERNEL); | |
| 91 | + if (!nn->app_priv) | |
| 92 | + return -ENOMEM; | |
| 93 | + | |
| 94 | + err = nfp_app_nic_vnic_alloc(app, nn, id); | |
| 95 | + if (err) | |
| 96 | + goto err_free_priv; | |
| 97 | + | |
| 98 | + return 0; | |
| 99 | +err_free_priv: | |
| 100 | + kfree(nn->app_priv); | |
| 101 | + return err; | |
| 102 | +} | |
| 103 | + | |
| 85 | 104 | static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn) |
| 86 | 105 | { |
| 106 | + struct nfp_bpf_vnic *bv = nn->app_priv; | |
| 107 | + | |
| 87 | 108 | if (nn->dp.bpf_offload_xdp) |
| 88 | 109 | nfp_bpf_xdp_offload(app, nn, NULL); |
| 110 | + WARN_ON(bv->tc_prog); | |
| 111 | + kfree(bv); | |
| 89 | 112 | } |
| 90 | 113 | |
| 91 | 114 | static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, |
| @@ -93,6 +116,9 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, · 1 unmodified line | ||
| 93 | 116 | { |
| 94 | 117 | struct tc_cls_bpf_offload *cls_bpf = type_data; |
| 95 | 118 | struct nfp_net *nn = cb_priv; |
| 119 | + struct bpf_prog *oldprog; | |
| 120 | + struct nfp_bpf_vnic *bv; | |
| 121 | + int err; | |
| 96 | 122 | |
| 97 | 123 | if (type != TC_SETUP_CLSBPF || |
| 98 | 124 | !tc_can_offload(nn->dp.netdev) || |
| @@ -100,8 +126,6 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, · 1 unmodified line | ||
| 100 | 126 | cls_bpf->common.protocol != htons(ETH_P_ALL) || |
| 101 | 127 | cls_bpf->common.chain_index) |
| 102 | 128 | return -EOPNOTSUPP; |
| 103 | − if (nn->dp.bpf_offload_xdp) | |
| 104 | − return -EBUSY; | |
| 105 | 129 | |
| 106 | 130 | /* Only support TC direct action */ |
| 107 | 131 | if (!cls_bpf->exts_integrated || |
| @@ -110,16 +134,25 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, · 2 unmodified lines | ||
| 110 | 134 | return -EOPNOTSUPP; |
| 111 | 135 | } |
| 112 | 136 | |
| 113 | − switch (cls_bpf->command) { | |
| 114 | − case TC_CLSBPF_REPLACE: | |
| 115 | − return nfp_net_bpf_offload(nn, cls_bpf->prog, true); | |
| 116 | − case TC_CLSBPF_ADD: | |
| 117 | − return nfp_net_bpf_offload(nn, cls_bpf->prog, false); | |
| 118 | − case TC_CLSBPF_DESTROY: | |
| 119 | − return nfp_net_bpf_offload(nn, NULL, true); | |
| 120 | − default: | |
| 137 | + if (cls_bpf->command != TC_CLSBPF_OFFLOAD) | |
| 121 | 138 | return -EOPNOTSUPP; |
| 139 | + | |
| 140 | + bv = nn->app_priv; | |
| 141 | + oldprog = cls_bpf->oldprog; | |
| 142 | + | |
| 143 | + /* Don't remove if oldprog doesn't match driver's state */ | |
| 144 | + if (bv->tc_prog != oldprog) { | |
| 145 | + oldprog = NULL; | |
| 146 | + if (!cls_bpf->prog) | |
| 147 | + return 0; | |
| 122 | 148 | } |
| 149 | + | |
| 150 | + err = nfp_net_bpf_offload(nn, cls_bpf->prog, oldprog); | |
| 151 | + if (err) | |
| 152 | + return err; | |
| 153 | + | |
| 154 | + bv->tc_prog = cls_bpf->prog; | |
| 155 | + return 0; | |
| 123 | 156 | } |
| 124 | 157 | |
| 125 | 158 | static int nfp_bpf_setup_tc_block(struct net_device *netdev, |
| @@ -167,7 +200,7 @@ const struct nfp_app_type app_bpf = { · 41 unmodified lines | ||
| 167 | 200 | |
| 168 | 201 | .extra_cap = nfp_bpf_extra_cap, |
| 169 | 202 | |
| 170 | − .vnic_alloc = nfp_app_nic_vnic_alloc, | |
| 203 | + .vnic_alloc = nfp_bpf_vnic_alloc, | |
| 171 | 204 | .vnic_free = nfp_bpf_vnic_free, |
| 172 | 205 | |
| 173 | 206 | .setup_tc = nfp_bpf_setup_tc, |
| @@ -172,6 +172,14 @@ struct nfp_prog { · 171 unmodified lines | ||
| 172 | 172 | struct list_head insns; |
| 173 | 173 | }; |
| 174 | 174 | |
| 175 | +/** | |
| 176 | + * struct nfp_bpf_vnic - per-vNIC BPF priv structure | |
| 177 | + * @tc_prog: currently loaded cls_bpf program | |
| 178 | + */ | |
| 179 | +struct nfp_bpf_vnic { | |
| 180 | + struct bpf_prog *tc_prog; | |
| 181 | +}; | |
| 182 | + | |
| 175 | 183 | int nfp_bpf_jit(struct nfp_prog *prog); |
| 176 | 184 | |
| 177 | 185 | extern const struct bpf_ext_analyzer_ops nfp_bpf_analyzer_ops; |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #define MDIO_CLK_25_28 7 |
| 48 | 48 | |
| 49 | 49 | #define MDIO_WAIT_TIMES 1000 |
| 50 | +#define MDIO_STATUS_DELAY_TIME 1 | |
| 50 | 51 | |
| 51 | 52 | static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum) |
| 52 | 53 | { |
| @@ -65,7 +66,7 @@ static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum) · 12 unmodified lines | ||
| 65 | 66 | |
| 66 | 67 | if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg, |
| 67 | 68 | !(reg & (MDIO_START | MDIO_BUSY)), |
| 68 | − 100, MDIO_WAIT_TIMES * 100)) | |
| 69 | + MDIO_STATUS_DELAY_TIME, MDIO_WAIT_TIMES * 100)) | |
| 69 | 70 | return -EIO; |
| 70 | 71 | |
| 71 | 72 | return (reg >> MDIO_DATA_SHFT) & MDIO_DATA_BMSK; |
| @@ -88,8 +89,8 @@ static int emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val) · 16 unmodified lines | ||
| 88 | 89 | writel(reg, adpt->base + EMAC_MDIO_CTRL); |
| 89 | 90 | |
| 90 | 91 | if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg, |
| 91 | − !(reg & (MDIO_START | MDIO_BUSY)), 100, | |
| 92 | − MDIO_WAIT_TIMES * 100)) | |
| 92 | + !(reg & (MDIO_START | MDIO_BUSY)), | |
| 93 | + MDIO_STATUS_DELAY_TIME, MDIO_WAIT_TIMES * 100)) | |
| 93 | 94 | return -EIO; |
| 94 | 95 | |
| 95 | 96 | return 0; |
| @@ -253,18 +253,18 @@ static int emac_open(struct net_device *netdev) · 252 unmodified lines | ||
| 253 | 253 | return ret; |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | − ret = emac_mac_up(adpt); | |
| 256 | + ret = adpt->phy.open(adpt); | |
| 257 | 257 | if (ret) { |
| 258 | 258 | emac_mac_rx_tx_rings_free_all(adpt); |
| 259 | 259 | free_irq(irq->irq, irq); |
| 260 | 260 | return ret; |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | − ret = adpt->phy.open(adpt); | |
| 263 | + ret = emac_mac_up(adpt); | |
| 264 | 264 | if (ret) { |
| 265 | − emac_mac_down(adpt); | |
| 266 | 265 | emac_mac_rx_tx_rings_free_all(adpt); |
| 267 | 266 | free_irq(irq->irq, irq); |
| 267 | + adpt->phy.close(adpt); | |
| 268 | 268 | return ret; |
| 269 | 269 | } |
| 270 | 270 | |
| @@ -2308,32 +2308,9 @@ static int __maybe_unused ravb_resume(struct device *dev) · 2307 unmodified lines | ||
| 2308 | 2308 | struct ravb_private *priv = netdev_priv(ndev); |
| 2309 | 2309 | int ret = 0; |
| 2310 | 2310 | |
| 2311 | − if (priv->wol_enabled) { | |
| 2312 | − /* Reduce the usecount of the clock to zero and then | |
| 2313 | − * restore it to its original value. This is done to force | |
| 2314 | − * the clock to be re-enabled which is a workaround | |
| 2315 | − * for renesas-cpg-mssr driver which do not enable clocks | |
| 2316 | − * when resuming from PSCI suspend/resume. | |
| 2317 | − * | |
| 2318 | − * Without this workaround the driver fails to communicate | |
| 2319 | − * with the hardware if WoL was enabled when the system | |
| 2320 | − * entered PSCI suspend. This is due to that if WoL is enabled | |
| 2321 | − * we explicitly keep the clock from being turned off when | |
| 2322 | − * suspending, but in PSCI sleep power is cut so the clock | |
| 2323 | − * is disabled anyhow, the clock driver is not aware of this | |
| 2324 | − * so the clock is not turned back on when resuming. | |
| 2325 | − * | |
| 2326 | − * TODO: once the renesas-cpg-mssr suspend/resume is working | |
| 2327 | − * this clock dance should be removed. | |
| 2328 | − */ | |
| 2329 | − clk_disable(priv->clk); | |
| 2330 | − clk_disable(priv->clk); | |
| 2331 | − clk_enable(priv->clk); | |
| 2332 | − clk_enable(priv->clk); | |
| 2333 | − | |
| 2334 | − /* Set reset mode to rearm the WoL logic */ | |
| 2311 | + /* If WoL is enabled set reset mode to rearm the WoL logic */ | |
| 2312 | + if (priv->wol_enabled) | |
| 2335 | 2313 | ravb_write(ndev, CCC_OPC_RESET, CCC); |
| 2336 | − } | |
| 2337 | 2314 | |
| 2338 | 2315 | /* All register have been reset to default values. |
| 2339 | 2316 | * Restore all registers which where setup at probe time and |
| @@ -1892,6 +1892,16 @@ static int sh_eth_phy_init(struct net_device *ndev) · 1891 unmodified lines | ||
| 1892 | 1892 | return PTR_ERR(phydev); |
| 1893 | 1893 | } |
| 1894 | 1894 | |
| 1895 | + /* mask with MAC supported features */ | |
| 1896 | + if (mdp->cd->register_type != SH_ETH_REG_GIGABIT) { | |
| 1897 | + int err = phy_set_max_speed(phydev, SPEED_100); | |
| 1898 | + if (err) { | |
| 1899 | + netdev_err(ndev, "failed to limit PHY to 100 Mbit/s\n"); | |
| 1900 | + phy_disconnect(phydev); | |
| 1901 | + return err; | |
| 1902 | + } | |
| 1903 | + } | |
| 1904 | + | |
| 1895 | 1905 | phy_attached_info(phydev); |
| 1896 | 1906 | |
| 1897 | 1907 | return 0; |
| @@ -409,7 +409,7 @@ struct stmmac_desc_ops { · 408 unmodified lines | ||
| 409 | 409 | /* get timestamp value */ |
| 410 | 410 | u64(*get_timestamp) (void *desc, u32 ats); |
| 411 | 411 | /* get rx timestamp status */ |
| 412 | − int (*get_rx_timestamp_status) (void *desc, u32 ats); | |
| 412 | + int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats); | |
| 413 | 413 | /* Display ring */ |
| 414 | 414 | void (*display_ring)(void *head, unsigned int size, bool rx); |
| 415 | 415 | /* set MSS via context descriptor */ |
| @@ -258,7 +258,8 @@ static int dwmac4_rx_check_timestamp(void *desc) · 257 unmodified lines | ||
| 258 | 258 | return ret; |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | −static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) | |
| 261 | +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, void *next_desc, | |
| 262 | + u32 ats) | |
| 262 | 263 | { |
| 263 | 264 | struct dma_desc *p = (struct dma_desc *)desc; |
| 264 | 265 | int ret = -EINVAL; |
| @@ -270,7 +271,7 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) · 5 unmodified lines | ||
| 270 | 271 | |
| 271 | 272 | /* Check if timestamp is OK from context descriptor */ |
| 272 | 273 | do { |
| 273 | − ret = dwmac4_rx_check_timestamp(desc); | |
| 274 | + ret = dwmac4_rx_check_timestamp(next_desc); | |
| 274 | 275 | if (ret < 0) |
| 275 | 276 | goto exit; |
| 276 | 277 | i++; |
| @@ -400,7 +400,8 @@ static u64 enh_desc_get_timestamp(void *desc, u32 ats) · 399 unmodified lines | ||
| 400 | 400 | return ns; |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | −static int enh_desc_get_rx_timestamp_status(void *desc, u32 ats) | |
| 403 | +static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc, | |
| 404 | + u32 ats) | |
| 404 | 405 | { |
| 405 | 406 | if (ats) { |
| 406 | 407 | struct dma_extended_desc *p = (struct dma_extended_desc *)desc; |
| @@ -265,7 +265,7 @@ static u64 ndesc_get_timestamp(void *desc, u32 ats) · 264 unmodified lines | ||
| 265 | 265 | return ns; |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | −static int ndesc_get_rx_timestamp_status(void *desc, u32 ats) | |
| 268 | +static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats) | |
| 269 | 269 | { |
| 270 | 270 | struct dma_desc *p = (struct dma_desc *)desc; |
| 271 | 271 | |
| @@ -34,6 +34,7 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, · 33 unmodified lines | ||
| 34 | 34 | { |
| 35 | 35 | u32 value = readl(ioaddr + PTP_TCR); |
| 36 | 36 | unsigned long data; |
| 37 | + u32 reg_value; | |
| 37 | 38 | |
| 38 | 39 | /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second |
| 39 | 40 | * formula = (1/ptp_clock) * 1000000000 |
| @@ -50,10 +51,11 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, · 10 unmodified lines | ||
| 50 | 51 | |
| 51 | 52 | data &= PTP_SSIR_SSINC_MASK; |
| 52 | 53 | |
| 54 | + reg_value = data; | |
| 53 | 55 | if (gmac4) |
| 54 | − data = data << GMAC4_PTP_SSIR_SSINC_SHIFT; | |
| 56 | + reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT; | |
| 55 | 57 | |
| 56 | − writel(data, ioaddr + PTP_SSIR); | |
| 58 | + writel(reg_value, ioaddr + PTP_SSIR); | |
| 57 | 59 | |
| 58 | 60 | return data; |
| 59 | 61 | } |
| @@ -482,7 +482,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, · 481 unmodified lines | ||
| 482 | 482 | desc = np; |
| 483 | 483 | |
| 484 | 484 | /* Check if timestamp is available */ |
| 485 | − if (priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) { | |
| 485 | + if (priv->hw->desc->get_rx_timestamp_status(p, np, priv->adv_ts)) { | |
| 486 | 486 | ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); |
| 487 | 487 | netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); |
| 488 | 488 | shhwtstamp = skb_hwtstamps(skb); |
| @@ -1379,8 +1379,8 @@ static int rr_close(struct net_device *dev) · 1378 unmodified lines | ||
| 1379 | 1379 | rrpriv->info_dma); |
| 1380 | 1380 | rrpriv->info = NULL; |
| 1381 | 1381 | |
| 1382 | − free_irq(pdev->irq, dev); | |
| 1383 | 1382 | spin_unlock_irqrestore(&rrpriv->lock, flags); |
| 1383 | + free_irq(pdev->irq, dev); | |
| 1384 | 1384 | |
| 1385 | 1385 | return 0; |
| 1386 | 1386 | } |
| @@ -239,14 +239,10 @@ static int at803x_resume(struct phy_device *phydev) · 238 unmodified lines | ||
| 239 | 239 | { |
| 240 | 240 | int value; |
| 241 | 241 | |
| 242 | − mutex_lock(&phydev->lock); | |
| 243 | − | |
| 244 | 242 | value = phy_read(phydev, MII_BMCR); |
| 245 | 243 | value &= ~(BMCR_PDOWN | BMCR_ISOLATE); |
| 246 | 244 | phy_write(phydev, MII_BMCR, value); |
| 247 | 245 | |
| 248 | − mutex_unlock(&phydev->lock); | |
| 249 | − | |
| 250 | 246 | return 0; |
| 251 | 247 | } |
| 252 | 248 | |
| @@ -637,6 +637,10 @@ static int m88e1510_config_aneg(struct phy_device *phydev) · 636 unmodified lines | ||
| 637 | 637 | if (err < 0) |
| 638 | 638 | goto error; |
| 639 | 639 | |
| 640 | + /* Do not touch the fiber page if we're in copper->sgmii mode */ | |
| 641 | + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) | |
| 642 | + return 0; | |
| 643 | + | |
| 640 | 644 | /* Then the fiber link */ |
| 641 | 645 | err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); |
| 642 | 646 | if (err < 0) |
| @@ -875,6 +879,8 @@ static int m88e1510_config_init(struct phy_device *phydev) · 232 unmodified lines | ||
| 875 | 879 | |
| 876 | 880 | /* SGMII-to-Copper mode initialization */ |
| 877 | 881 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
| 882 | + u32 pause; | |
| 883 | + | |
| 878 | 884 | /* Select page 18 */ |
| 879 | 885 | err = marvell_set_page(phydev, 18); |
| 880 | 886 | if (err < 0) |
| @@ -898,6 +904,16 @@ static int m88e1510_config_init(struct phy_device *phydev) · 17 unmodified lines | ||
| 898 | 904 | err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); |
| 899 | 905 | if (err < 0) |
| 900 | 906 | return err; |
| 907 | + | |
| 908 | + /* There appears to be a bug in the 88e1512 when used in | |
| 909 | + * SGMII to copper mode, where the AN advertisment register | |
| 910 | + * clears the pause bits each time a negotiation occurs. | |
| 911 | + * This means we can never be truely sure what was advertised, | |
| 912 | + * so disable Pause support. | |
| 913 | + */ | |
| 914 | + pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause; | |
| 915 | + phydev->supported &= ~pause; | |
| 916 | + phydev->advertising &= ~pause; | |
| 901 | 917 | } |
| 902 | 918 | |
| 903 | 919 | return m88e1121_config_init(phydev); |
| @@ -2069,7 +2085,7 @@ static struct phy_driver marvell_drivers[] = { · 1165 unmodified lines | ||
| 2069 | 2085 | .flags = PHY_HAS_INTERRUPT, |
| 2070 | 2086 | .probe = marvell_probe, |
| 2071 | 2087 | .config_init = &m88e1145_config_init, |
| 2072 | − .config_aneg = &marvell_config_aneg, | |
| 2088 | + .config_aneg = &m88e1101_config_aneg, | |
| 2073 | 2089 | .read_status = &genphy_read_status, |
| 2074 | 2090 | .ack_interrupt = &marvell_ack_interrupt, |
| 2075 | 2091 | .config_intr = &marvell_config_intr, |
| @@ -194,8 +194,11 @@ static int xgene_mdio_reset(struct xgene_mdio_pdata *pdata) · 193 unmodified lines | ||
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | ret = xgene_enet_ecc_init(pdata); |
| 197 | − if (ret) | |
| 197 | + if (ret) { | |
| 198 | + if (pdata->dev->of_node) | |
| 199 | + clk_disable_unprepare(pdata->clk); | |
| 198 | 200 | return ret; |
| 201 | + } | |
| 199 | 202 | xgene_gmac_reset(pdata); |
| 200 | 203 | |
| 201 | 204 | return 0; |
| @@ -388,8 +391,10 @@ static int xgene_mdio_probe(struct platform_device *pdev) · 186 unmodified lines | ||
| 388 | 391 | return ret; |
| 389 | 392 | |
| 390 | 393 | mdio_bus = mdiobus_alloc(); |
| 391 | − if (!mdio_bus) | |
| 392 | − return -ENOMEM; | |
| 394 | + if (!mdio_bus) { | |
| 395 | + ret = -ENOMEM; | |
| 396 | + goto out_clk; | |
| 397 | + } | |
| 393 | 398 | |
| 394 | 399 | mdio_bus->name = "APM X-Gene MDIO bus"; |
| 395 | 400 | |
| @@ -418,7 +423,7 @@ static int xgene_mdio_probe(struct platform_device *pdev) · 22 unmodified lines | ||
| 418 | 423 | mdio_bus->phy_mask = ~0; |
| 419 | 424 | ret = mdiobus_register(mdio_bus); |
| 420 | 425 | if (ret) |
| 421 | − goto out; | |
| 426 | + goto out_mdiobus; | |
| 422 | 427 | |
| 423 | 428 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1, |
| 424 | 429 | acpi_register_phy, NULL, mdio_bus, NULL); |
| @@ -426,16 +431,20 @@ static int xgene_mdio_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 426 | 431 | } |
| 427 | 432 | |
| 428 | 433 | if (ret) |
| 429 | − goto out; | |
| 434 | + goto out_mdiobus; | |
| 430 | 435 | |
| 431 | 436 | pdata->mdio_bus = mdio_bus; |
| 432 | 437 | xgene_mdio_status = true; |
| 433 | 438 | |
| 434 | 439 | return 0; |
| 435 | 440 | |
| 436 | −out: | |
| 441 | +out_mdiobus: | |
| 437 | 442 | mdiobus_free(mdio_bus); |
| 438 | 443 | |
| 444 | +out_clk: | |
| 445 | + if (dev->of_node) | |
| 446 | + clk_disable_unprepare(pdata->clk); | |
| 447 | + | |
| 439 | 448 | return ret; |
| 440 | 449 | } |
| 441 | 450 | |
| @@ -270,6 +270,7 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus, · 269 unmodified lines | ||
| 270 | 270 | |
| 271 | 271 | if (addr == mdiodev->addr) { |
| 272 | 272 | dev->of_node = child; |
| 273 | + dev->fwnode = of_fwnode_handle(child); | |
| 273 | 274 | return; |
| 274 | 275 | } |
| 275 | 276 | } |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/ethtool.h> |
| 23 | 23 | #include <linux/phy.h> |
| 24 | 24 | #include <linux/netdevice.h> |
| 25 | +#include <linux/bitfield.h> | |
| 25 | 26 | |
| 26 | 27 | static int meson_gxl_config_init(struct phy_device *phydev) |
| 27 | 28 | { |
| @@ -50,6 +51,77 @@ static int meson_gxl_config_init(struct phy_device *phydev) · 22 unmodified lines | ||
| 50 | 51 | return 0; |
| 51 | 52 | } |
| 52 | 53 | |
| 54 | +/* This function is provided to cope with the possible failures of this phy | |
| 55 | + * during aneg process. When aneg fails, the PHY reports that aneg is done | |
| 56 | + * but the value found in MII_LPA is wrong: | |
| 57 | + * - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that | |
| 58 | + * the link partner (LP) supports aneg but the LP never acked our base | |
| 59 | + * code word, it is likely that we never sent it to begin with. | |
| 60 | + * - Late failures: MII_LPA is filled with a value which seems to make sense | |
| 61 | + * but it actually is not what the LP is advertising. It seems that we | |
| 62 | + * can detect this using a magic bit in the WOL bank (reg 12 - bit 12). | |
| 63 | + * If this particular bit is not set when aneg is reported being done, | |
| 64 | + * it means MII_LPA is likely to be wrong. | |
| 65 | + * | |
| 66 | + * In both case, forcing a restart of the aneg process solve the problem. | |
| 67 | + * When this failure happens, the first retry is usually successful but, | |
| 68 | + * in some cases, it may take up to 6 retries to get a decent result | |
| 69 | + */ | |
| 70 | +static int meson_gxl_read_status(struct phy_device *phydev) | |
| 71 | +{ | |
| 72 | + int ret, wol, lpa, exp; | |
| 73 | + | |
| 74 | + if (phydev->autoneg == AUTONEG_ENABLE) { | |
| 75 | + ret = genphy_aneg_done(phydev); | |
| 76 | + if (ret < 0) | |
| 77 | + return ret; | |
| 78 | + else if (!ret) | |
| 79 | + goto read_status_continue; | |
| 80 | + | |
| 81 | + /* Need to access WOL bank, make sure the access is open */ | |
| 82 | + ret = phy_write(phydev, 0x14, 0x0000); | |
| 83 | + if (ret) | |
| 84 | + return ret; | |
| 85 | + ret = phy_write(phydev, 0x14, 0x0400); | |
| 86 | + if (ret) | |
| 87 | + return ret; | |
| 88 | + ret = phy_write(phydev, 0x14, 0x0000); | |
| 89 | + if (ret) | |
| 90 | + return ret; | |
| 91 | + ret = phy_write(phydev, 0x14, 0x0400); | |
| 92 | + if (ret) | |
| 93 | + return ret; | |
| 94 | + | |
| 95 | + /* Request LPI_STATUS WOL register */ | |
| 96 | + ret = phy_write(phydev, 0x14, 0x8D80); | |
| 97 | + if (ret) | |
| 98 | + return ret; | |
| 99 | + | |
| 100 | + /* Read LPI_STATUS value */ | |
| 101 | + wol = phy_read(phydev, 0x15); | |
| 102 | + if (wol < 0) | |
| 103 | + return wol; | |
| 104 | + | |
| 105 | + lpa = phy_read(phydev, MII_LPA); | |
| 106 | + if (lpa < 0) | |
| 107 | + return lpa; | |
| 108 | + | |
| 109 | + exp = phy_read(phydev, MII_EXPANSION); | |
| 110 | + if (exp < 0) | |
| 111 | + return exp; | |
| 112 | + | |
| 113 | + if (!(wol & BIT(12)) || | |
| 114 | + ((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) { | |
| 115 | + /* Looks like aneg failed after all */ | |
| 116 | + phydev_dbg(phydev, "LPA corruption - aneg restart\n"); | |
| 117 | + return genphy_restart_aneg(phydev); | |
| 118 | + } | |
| 119 | + } | |
| 120 | + | |
| 121 | +read_status_continue: | |
| 122 | + return genphy_read_status(phydev); | |
| 123 | +} | |
| 124 | + | |
| 53 | 125 | static struct phy_driver meson_gxl_phy[] = { |
| 54 | 126 | { |
| 55 | 127 | .phy_id = 0x01814400, |
| @@ -60,7 +132,7 @@ static struct phy_driver meson_gxl_phy[] = { · 4 unmodified lines | ||
| 60 | 132 | .config_init = meson_gxl_config_init, |
| 61 | 133 | .config_aneg = genphy_config_aneg, |
| 62 | 134 | .aneg_done = genphy_aneg_done, |
| 63 | − .read_status = genphy_read_status, | |
| 135 | + .read_status = meson_gxl_read_status, | |
| 64 | 136 | .suspend = genphy_suspend, |
| 65 | 137 | .resume = genphy_resume, |
| 66 | 138 | }, |
| @@ -624,6 +624,7 @@ static int ksz9031_read_status(struct phy_device *phydev) · 623 unmodified lines | ||
| 624 | 624 | phydev->link = 0; |
| 625 | 625 | if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) |
| 626 | 626 | phydev->drv->config_intr(phydev); |
| 627 | + return genphy_config_aneg(phydev); | |
| 627 | 628 | } |
| 628 | 629 | |
| 629 | 630 | return 0; |
| @@ -828,7 +828,6 @@ EXPORT_SYMBOL(phy_stop); · 827 unmodified lines | ||
| 828 | 828 | */ |
| 829 | 829 | void phy_start(struct phy_device *phydev) |
| 830 | 830 | { |
| 831 | − bool do_resume = false; | |
| 832 | 831 | int err = 0; |
| 833 | 832 | |
| 834 | 833 | mutex_lock(&phydev->lock); |
| @@ -841,6 +840,9 @@ void phy_start(struct phy_device *phydev) · 6 unmodified lines | ||
| 841 | 840 | phydev->state = PHY_UP; |
| 842 | 841 | break; |
| 843 | 842 | case PHY_HALTED: |
| 843 | + /* if phy was suspended, bring the physical link up again */ | |
| 844 | + phy_resume(phydev); | |
| 845 | + | |
| 844 | 846 | /* make sure interrupts are re-enabled for the PHY */ |
| 845 | 847 | if (phydev->irq != PHY_POLL) { |
| 846 | 848 | err = phy_enable_interrupts(phydev); |
| @@ -849,17 +851,12 @@ void phy_start(struct phy_device *phydev) · 2 unmodified lines | ||
| 849 | 851 | } |
| 850 | 852 | |
| 851 | 853 | phydev->state = PHY_RESUMING; |
| 852 | − do_resume = true; | |
| 853 | 854 | break; |
| 854 | 855 | default: |
| 855 | 856 | break; |
| 856 | 857 | } |
| 857 | 858 | mutex_unlock(&phydev->lock); |
| 858 | 859 | |
| 859 | − /* if phy was suspended, bring the physical link up again */ | |
| 860 | − if (do_resume) | |
| 861 | − phy_resume(phydev); | |
| 862 | − | |
| 863 | 860 | phy_trigger_machine(phydev, true); |
| 864 | 861 | } |
| 865 | 862 | EXPORT_SYMBOL(phy_start); |
| @@ -135,7 +135,9 @@ static int mdio_bus_phy_resume(struct device *dev) · 134 unmodified lines | ||
| 135 | 135 | if (!mdio_bus_phy_may_suspend(phydev)) |
| 136 | 136 | goto no_resume; |
| 137 | 137 | |
| 138 | + mutex_lock(&phydev->lock); | |
| 138 | 139 | ret = phy_resume(phydev); |
| 140 | + mutex_unlock(&phydev->lock); | |
| 139 | 141 | if (ret < 0) |
| 140 | 142 | return ret; |
| 141 | 143 | |
| @@ -1026,7 +1028,9 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, · 884 unmodified lines | ||
| 1026 | 1028 | if (err) |
| 1027 | 1029 | goto error; |
| 1028 | 1030 | |
| 1031 | + mutex_lock(&phydev->lock); | |
| 1029 | 1032 | phy_resume(phydev); |
| 1033 | + mutex_unlock(&phydev->lock); | |
| 1030 | 1034 | phy_led_triggers_register(phydev); |
| 1031 | 1035 | |
| 1032 | 1036 | return err; |
| @@ -1157,6 +1161,8 @@ int phy_resume(struct phy_device *phydev) · 124 unmodified lines | ||
| 1157 | 1161 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
| 1158 | 1162 | int ret = 0; |
| 1159 | 1163 | |
| 1164 | + WARN_ON(!mutex_is_locked(&phydev->lock)); | |
| 1165 | + | |
| 1160 | 1166 | if (phydev->drv && phydrv->resume) |
| 1161 | 1167 | ret = phydrv->resume(phydev); |
| 1162 | 1168 | |
| @@ -1639,13 +1645,9 @@ int genphy_resume(struct phy_device *phydev) · 476 unmodified lines | ||
| 1639 | 1645 | { |
| 1640 | 1646 | int value; |
| 1641 | 1647 | |
| 1642 | − mutex_lock(&phydev->lock); | |
| 1643 | − | |
| 1644 | 1648 | value = phy_read(phydev, MII_BMCR); |
| 1645 | 1649 | phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); |
| 1646 | 1650 | |
| 1647 | − mutex_unlock(&phydev->lock); | |
| 1648 | − | |
| 1649 | 1651 | return 0; |
| 1650 | 1652 | } |
| 1651 | 1653 | EXPORT_SYMBOL(genphy_resume); |
| @@ -526,6 +526,7 @@ struct phylink *phylink_create(struct net_device *ndev, struct device_node *np, · 525 unmodified lines | ||
| 526 | 526 | pl->link_config.pause = MLO_PAUSE_AN; |
| 527 | 527 | pl->link_config.speed = SPEED_UNKNOWN; |
| 528 | 528 | pl->link_config.duplex = DUPLEX_UNKNOWN; |
| 529 | + pl->link_config.an_enabled = true; | |
| 529 | 530 | pl->ops = ops; |
| 530 | 531 | __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); |
| 531 | 532 | |
| @@ -951,6 +952,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, · 419 unmodified lines | ||
| 951 | 952 | mutex_lock(&pl->state_mutex); |
| 952 | 953 | /* Configure the MAC to match the new settings */ |
| 953 | 954 | linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); |
| 955 | + pl->link_config.interface = config.interface; | |
| 954 | 956 | pl->link_config.speed = our_kset.base.speed; |
| 955 | 957 | pl->link_config.duplex = our_kset.base.duplex; |
| 956 | 958 | pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; |
| @@ -1204,12 +1204,14 @@ static const struct usb_device_id products[] = { · 1203 unmodified lines | ||
| 1204 | 1204 | {QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */ |
| 1205 | 1205 | {QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */ |
| 1206 | 1206 | {QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */ |
| 1207 | + {QMI_FIXED_INTF(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */ | |
| 1207 | 1208 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
| 1208 | 1209 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ |
| 1209 | 1210 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
| 1210 | 1211 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
| 1211 | 1212 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ |
| 1212 | 1213 | {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ |
| 1214 | + {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ | |
| 1213 | 1215 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
| 1214 | 1216 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ |
| 1215 | 1217 | {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */ |
| @@ -2155,6 +2155,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 2154 unmodified lines | ||
| 2155 | 2155 | } |
| 2156 | 2156 | |
| 2157 | 2157 | ndst = &rt->dst; |
| 2158 | + if (skb_dst(skb)) { | |
| 2159 | + int mtu = dst_mtu(ndst) - VXLAN_HEADROOM; | |
| 2160 | + | |
| 2161 | + skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, | |
| 2162 | + skb, mtu); | |
| 2163 | + } | |
| 2164 | + | |
| 2158 | 2165 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); |
| 2159 | 2166 | ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); |
| 2160 | 2167 | err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), |
| @@ -2190,6 +2197,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 29 unmodified lines | ||
| 2190 | 2197 | goto out_unlock; |
| 2191 | 2198 | } |
| 2192 | 2199 | |
| 2200 | + if (skb_dst(skb)) { | |
| 2201 | + int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM; | |
| 2202 | + | |
| 2203 | + skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, | |
| 2204 | + skb, mtu); | |
| 2205 | + } | |
| 2206 | + | |
| 2193 | 2207 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); |
| 2194 | 2208 | ttl = ttl ? : ip6_dst_hoplimit(ndst); |
| 2195 | 2209 | skb_scrub_packet(skb, xnet); |
| @@ -3103,6 +3117,11 @@ static void vxlan_config_apply(struct net_device *dev, · 907 unmodified lines | ||
| 3103 | 3117 | |
| 3104 | 3118 | max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : |
| 3105 | 3119 | VXLAN_HEADROOM); |
| 3120 | + if (max_mtu < ETH_MIN_MTU) | |
| 3121 | + max_mtu = ETH_MIN_MTU; | |
| 3122 | + | |
| 3123 | + if (!changelink && !conf->mtu) | |
| 3124 | + dev->mtu = max_mtu; | |
| 3106 | 3125 | } |
| 3107 | 3126 | |
| 3108 | 3127 | if (dev->mtu > max_mtu) |
| @@ -684,6 +684,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, · 683 unmodified lines | ||
| 684 | 684 | hdr = skb_put(skb, sizeof(*hdr) - ETH_ALEN); |
| 685 | 685 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | |
| 686 | 686 | IEEE80211_STYPE_NULLFUNC | |
| 687 | + IEEE80211_FCTL_TODS | | |
| 687 | 688 | (ps ? IEEE80211_FCTL_PM : 0)); |
| 688 | 689 | hdr->duration_id = cpu_to_le16(0); |
| 689 | 690 | memcpy(hdr->addr1, vp->bssid, ETH_ALEN); |
| @@ -3215,7 +3216,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) · 2525 unmodified lines | ||
| 3215 | 3216 | if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) |
| 3216 | 3217 | continue; |
| 3217 | 3218 | |
| 3218 | − skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | |
| 3219 | + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); | |
| 3219 | 3220 | if (!skb) { |
| 3220 | 3221 | res = -ENOMEM; |
| 3221 | 3222 | goto out_err; |
| @@ -211,12 +211,12 @@ static int btt_map_read(struct arena_info *arena, u32 lba, u32 *mapping, · 210 unmodified lines | ||
| 211 | 211 | return ret; |
| 212 | 212 | } |
| 213 | 213 | |
| 214 | −static int btt_log_read_pair(struct arena_info *arena, u32 lane, | |
| 215 | − struct log_entry *ent) | |
| 214 | +static int btt_log_group_read(struct arena_info *arena, u32 lane, | |
| 215 | + struct log_group *log) | |
| 216 | 216 | { |
| 217 | 217 | return arena_read_bytes(arena, |
| 218 | − arena->logoff + (2 * lane * LOG_ENT_SIZE), ent, | |
| 219 | − 2 * LOG_ENT_SIZE, 0); | |
| 218 | + arena->logoff + (lane * LOG_GRP_SIZE), log, | |
| 219 | + LOG_GRP_SIZE, 0); | |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | 222 | static struct dentry *debugfs_root; |
| @@ -256,6 +256,8 @@ static void arena_debugfs_init(struct arena_info *a, struct dentry *parent, · 33 unmodified lines | ||
| 256 | 256 | debugfs_create_x64("logoff", S_IRUGO, d, &a->logoff); |
| 257 | 257 | debugfs_create_x64("info2off", S_IRUGO, d, &a->info2off); |
| 258 | 258 | debugfs_create_x32("flags", S_IRUGO, d, &a->flags); |
| 259 | + debugfs_create_u32("log_index_0", S_IRUGO, d, &a->log_index[0]); | |
| 260 | + debugfs_create_u32("log_index_1", S_IRUGO, d, &a->log_index[1]); | |
| 259 | 261 | } |
| 260 | 262 | |
| 261 | 263 | static void btt_debugfs_init(struct btt *btt) |
| @@ -274,6 +276,11 @@ static void btt_debugfs_init(struct btt *btt) · 12 unmodified lines | ||
| 274 | 276 | } |
| 275 | 277 | } |
| 276 | 278 | |
| 279 | +static u32 log_seq(struct log_group *log, int log_idx) | |
| 280 | +{ | |
| 281 | + return le32_to_cpu(log->ent[log_idx].seq); | |
| 282 | +} | |
| 283 | + | |
| 277 | 284 | /* |
| 278 | 285 | * This function accepts two log entries, and uses the |
| 279 | 286 | * sequence number to find the 'older' entry. |
| @@ -283,8 +290,10 @@ static void btt_debugfs_init(struct btt *btt) · 3 unmodified lines | ||
| 283 | 290 | * |
| 284 | 291 | * TODO The logic feels a bit kludge-y. make it better.. |
| 285 | 292 | */ |
| 286 | −static int btt_log_get_old(struct log_entry *ent) | |
| 293 | +static int btt_log_get_old(struct arena_info *a, struct log_group *log) | |
| 287 | 294 | { |
| 295 | + int idx0 = a->log_index[0]; | |
| 296 | + int idx1 = a->log_index[1]; | |
| 288 | 297 | int old; |
| 289 | 298 | |
| 290 | 299 | /* |
| @@ -292,23 +301,23 @@ static int btt_log_get_old(struct log_entry *ent) · 1 unmodified line | ||
| 292 | 301 | * the next time, the following logic works out to put this |
| 293 | 302 | * (next) entry into [1] |
| 294 | 303 | */ |
| 295 | − if (ent[0].seq == 0) { | |
| 296 | − ent[0].seq = cpu_to_le32(1); | |
| 304 | + if (log_seq(log, idx0) == 0) { | |
| 305 | + log->ent[idx0].seq = cpu_to_le32(1); | |
| 297 | 306 | return 0; |
| 298 | 307 | } |
| 299 | 308 | |
| 300 | − if (ent[0].seq == ent[1].seq) | |
| 309 | + if (log_seq(log, idx0) == log_seq(log, idx1)) | |
| 301 | 310 | return -EINVAL; |
| 302 | − if (le32_to_cpu(ent[0].seq) + le32_to_cpu(ent[1].seq) > 5) | |
| 311 | + if (log_seq(log, idx0) + log_seq(log, idx1) > 5) | |
| 303 | 312 | return -EINVAL; |
| 304 | 313 | |
| 305 | − if (le32_to_cpu(ent[0].seq) < le32_to_cpu(ent[1].seq)) { | |
| 306 | − if (le32_to_cpu(ent[1].seq) - le32_to_cpu(ent[0].seq) == 1) | |
| 314 | + if (log_seq(log, idx0) < log_seq(log, idx1)) { | |
| 315 | + if ((log_seq(log, idx1) - log_seq(log, idx0)) == 1) | |
| 307 | 316 | old = 0; |
| 308 | 317 | else |
| 309 | 318 | old = 1; |
| 310 | 319 | } else { |
| 311 | − if (le32_to_cpu(ent[0].seq) - le32_to_cpu(ent[1].seq) == 1) | |
| 320 | + if ((log_seq(log, idx0) - log_seq(log, idx1)) == 1) | |
| 312 | 321 | old = 1; |
| 313 | 322 | else |
| 314 | 323 | old = 0; |
| @@ -328,17 +337,18 @@ static int btt_log_read(struct arena_info *arena, u32 lane, · 13 unmodified lines | ||
| 328 | 337 | { |
| 329 | 338 | int ret; |
| 330 | 339 | int old_ent, ret_ent; |
| 331 | − struct log_entry log[2]; | |
| 340 | + struct log_group log; | |
| 332 | 341 | |
| 333 | − ret = btt_log_read_pair(arena, lane, log); | |
| 342 | + ret = btt_log_group_read(arena, lane, &log); | |
| 334 | 343 | if (ret) |
| 335 | 344 | return -EIO; |
| 336 | 345 | |
| 337 | − old_ent = btt_log_get_old(log); | |
| 346 | + old_ent = btt_log_get_old(arena, &log); | |
| 338 | 347 | if (old_ent < 0 || old_ent > 1) { |
| 339 | 348 | dev_err(to_dev(arena), |
| 340 | 349 | "log corruption (%d): lane %d seq [%d, %d]\n", |
| 341 | − old_ent, lane, log[0].seq, log[1].seq); | |
| 350 | + old_ent, lane, log.ent[arena->log_index[0]].seq, | |
| 351 | + log.ent[arena->log_index[1]].seq); | |
| 342 | 352 | /* TODO set error state? */ |
| 343 | 353 | return -EIO; |
| 344 | 354 | } |
| @@ -346,7 +356,7 @@ static int btt_log_read(struct arena_info *arena, u32 lane, · 1 unmodified line | ||
| 346 | 356 | ret_ent = (old_flag ? old_ent : (1 - old_ent)); |
| 347 | 357 | |
| 348 | 358 | if (ent != NULL) |
| 349 | − memcpy(ent, &log[ret_ent], LOG_ENT_SIZE); | |
| 359 | + memcpy(ent, &log.ent[arena->log_index[ret_ent]], LOG_ENT_SIZE); | |
| 350 | 360 | |
| 351 | 361 | return ret_ent; |
| 352 | 362 | } |
| @@ -360,17 +370,13 @@ static int __btt_log_write(struct arena_info *arena, u32 lane, · 7 unmodified lines | ||
| 360 | 370 | u32 sub, struct log_entry *ent, unsigned long flags) |
| 361 | 371 | { |
| 362 | 372 | int ret; |
| 363 | − /* | |
| 364 | − * Ignore the padding in log_entry for calculating log_half. | |
| 365 | − * The entry is 'committed' when we write the sequence number, | |
| 366 | − * and we want to ensure that that is the last thing written. | |
| 367 | − * We don't bother writing the padding as that would be extra | |
| 368 | − * media wear and write amplification | |
| 369 | − */ | |
| 370 | − unsigned int log_half = (LOG_ENT_SIZE - 2 * sizeof(u64)) / 2; | |
| 371 | − u64 ns_off = arena->logoff + (((2 * lane) + sub) * LOG_ENT_SIZE); | |
| 373 | + u32 group_slot = arena->log_index[sub]; | |
| 374 | + unsigned int log_half = LOG_ENT_SIZE / 2; | |
| 372 | 375 | void *src = ent; |
| 376 | + u64 ns_off; | |
| 373 | 377 | |
| 378 | + ns_off = arena->logoff + (lane * LOG_GRP_SIZE) + | |
| 379 | + (group_slot * LOG_ENT_SIZE); | |
| 374 | 380 | /* split the 16B write into atomic, durable halves */ |
| 375 | 381 | ret = arena_write_bytes(arena, ns_off, src, log_half, flags); |
| 376 | 382 | if (ret) |
| @@ -453,7 +459,7 @@ static int btt_log_init(struct arena_info *arena) · 76 unmodified lines | ||
| 453 | 459 | { |
| 454 | 460 | size_t logsize = arena->info2off - arena->logoff; |
| 455 | 461 | size_t chunk_size = SZ_4K, offset = 0; |
| 456 | − struct log_entry log; | |
| 462 | + struct log_entry ent; | |
| 457 | 463 | void *zerobuf; |
| 458 | 464 | int ret; |
| 459 | 465 | u32 i; |
| @@ -485,11 +491,11 @@ static int btt_log_init(struct arena_info *arena) · 25 unmodified lines | ||
| 485 | 491 | } |
| 486 | 492 | |
| 487 | 493 | for (i = 0; i < arena->nfree; i++) { |
| 488 | − log.lba = cpu_to_le32(i); | |
| 489 | − log.old_map = cpu_to_le32(arena->external_nlba + i); | |
| 490 | − log.new_map = cpu_to_le32(arena->external_nlba + i); | |
| 491 | − log.seq = cpu_to_le32(LOG_SEQ_INIT); | |
| 492 | − ret = __btt_log_write(arena, i, 0, &log, 0); | |
| 494 | + ent.lba = cpu_to_le32(i); | |
| 495 | + ent.old_map = cpu_to_le32(arena->external_nlba + i); | |
| 496 | + ent.new_map = cpu_to_le32(arena->external_nlba + i); | |
| 497 | + ent.seq = cpu_to_le32(LOG_SEQ_INIT); | |
| 498 | + ret = __btt_log_write(arena, i, 0, &ent, 0); | |
| 493 | 499 | if (ret) |
| 494 | 500 | goto free; |
| 495 | 501 | } |
| @@ -594,6 +600,123 @@ static int btt_freelist_init(struct arena_info *arena) · 98 unmodified lines | ||
| 594 | 600 | return 0; |
| 595 | 601 | } |
| 596 | 602 | |
| 603 | +static bool ent_is_padding(struct log_entry *ent) | |
| 604 | +{ | |
| 605 | + return (ent->lba == 0) && (ent->old_map == 0) && (ent->new_map == 0) | |
| 606 | + && (ent->seq == 0); | |
| 607 | +} | |
| 608 | + | |
| 609 | +/* | |
| 610 | + * Detecting valid log indices: We read a log group (see the comments in btt.h | |
| 611 | + * for a description of a 'log_group' and its 'slots'), and iterate over its | |
| 612 | + * four slots. We expect that a padding slot will be all-zeroes, and use this | |
| 613 | + * to detect a padding slot vs. an actual entry. | |
| 614 | + * | |
| 615 | + * If a log_group is in the initial state, i.e. hasn't been used since the | |
| 616 | + * creation of this BTT layout, it will have three of the four slots with | |
| 617 | + * zeroes. We skip over these log_groups for the detection of log_index. If | |
| 618 | + * all log_groups are in the initial state (i.e. the BTT has never been | |
| 619 | + * written to), it is safe to assume the 'new format' of log entries in slots | |
| 620 | + * (0, 1). | |
| 621 | + */ | |
| 622 | +static int log_set_indices(struct arena_info *arena) | |
| 623 | +{ | |
| 624 | + bool idx_set = false, initial_state = true; | |
| 625 | + int ret, log_index[2] = {-1, -1}; | |
| 626 | + u32 i, j, next_idx = 0; | |
| 627 | + struct log_group log; | |
| 628 | + u32 pad_count = 0; | |
| 629 | + | |
| 630 | + for (i = 0; i < arena->nfree; i++) { | |
| 631 | + ret = btt_log_group_read(arena, i, &log); | |
| 632 | + if (ret < 0) | |
| 633 | + return ret; | |
| 634 | + | |
| 635 | + for (j = 0; j < 4; j++) { | |
| 636 | + if (!idx_set) { | |
| 637 | + if (ent_is_padding(&log.ent[j])) { | |
| 638 | + pad_count++; | |
| 639 | + continue; | |
| 640 | + } else { | |
| 641 | + /* Skip if index has been recorded */ | |
| 642 | + if ((next_idx == 1) && | |
| 643 | + (j == log_index[0])) | |
| 644 | + continue; | |
| 645 | + /* valid entry, record index */ | |
| 646 | + log_index[next_idx] = j; | |
| 647 | + next_idx++; | |
| 648 | + } | |
| 649 | + if (next_idx == 2) { | |
| 650 | + /* two valid entries found */ | |
| 651 | + idx_set = true; | |
| 652 | + } else if (next_idx > 2) { | |
| 653 | + /* too many valid indices */ | |
| 654 | + return -ENXIO; | |
| 655 | + } | |
| 656 | + } else { | |
| 657 | + /* | |
| 658 | + * once the indices have been set, just verify | |
| 659 | + * that all subsequent log groups are either in | |
| 660 | + * their initial state or follow the same | |
| 661 | + * indices. | |
| 662 | + */ | |
| 663 | + if (j == log_index[0]) { | |
| 664 | + /* entry must be 'valid' */ | |
| 665 | + if (ent_is_padding(&log.ent[j])) | |
| 666 | + return -ENXIO; | |
| 667 | + } else if (j == log_index[1]) { | |
| 668 | + ; | |
| 669 | + /* | |
| 670 | + * log_index[1] can be padding if the | |
| 671 | + * lane never got used and it is still | |
| 672 | + * in the initial state (three 'padding' | |
| 673 | + * entries) | |
| 674 | + */ | |
| 675 | + } else { | |
| 676 | + /* entry must be invalid (padding) */ | |
| 677 | + if (!ent_is_padding(&log.ent[j])) | |
| 678 | + return -ENXIO; | |
| 679 | + } | |
| 680 | + } | |
| 681 | + } | |
| 682 | + /* | |
| 683 | + * If any of the log_groups have more than one valid, | |
| 684 | + * non-padding entry, then the we are no longer in the | |
| 685 | + * initial_state | |
| 686 | + */ | |
| 687 | + if (pad_count < 3) | |
| 688 | + initial_state = false; | |
| 689 | + pad_count = 0; | |
| 690 | + } | |
| 691 | + | |
| 692 | + if (!initial_state && !idx_set) | |
| 693 | + return -ENXIO; | |
| 694 | + | |
| 695 | + /* | |
| 696 | + * If all the entries in the log were in the initial state, | |
| 697 | + * assume new padding scheme | |
| 698 | + */ | |
| 699 | + if (initial_state) | |
| 700 | + log_index[1] = 1; | |
| 701 | + | |
| 702 | + /* | |
| 703 | + * Only allow the known permutations of log/padding indices, | |
| 704 | + * i.e. (0, 1), and (0, 2) | |
| 705 | + */ | |
| 706 | + if ((log_index[0] == 0) && ((log_index[1] == 1) || (log_index[1] == 2))) | |
| 707 | + ; /* known index possibilities */ | |
| 708 | + else { | |
| 709 | + dev_err(to_dev(arena), "Found an unknown padding scheme\n"); | |
| 710 | + return -ENXIO; | |
| 711 | + } | |
| 712 | + | |
| 713 | + arena->log_index[0] = log_index[0]; | |
| 714 | + arena->log_index[1] = log_index[1]; | |
| 715 | + dev_dbg(to_dev(arena), "log_index_0 = %d\n", log_index[0]); | |
| 716 | + dev_dbg(to_dev(arena), "log_index_1 = %d\n", log_index[1]); | |
| 717 | + return 0; | |
| 718 | +} | |
| 719 | + | |
| 597 | 720 | static int btt_rtt_init(struct arena_info *arena) |
| 598 | 721 | { |
| 599 | 722 | arena->rtt = kcalloc(arena->nfree, sizeof(u32), GFP_KERNEL); |
| @@ -650,8 +773,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, · 50 unmodified lines | ||
| 650 | 773 | available -= 2 * BTT_PG_SIZE; |
| 651 | 774 | |
| 652 | 775 | /* The log takes a fixed amount of space based on nfree */ |
| 653 | − logsize = roundup(2 * arena->nfree * sizeof(struct log_entry), | |
| 654 | − BTT_PG_SIZE); | |
| 776 | + logsize = roundup(arena->nfree * LOG_GRP_SIZE, BTT_PG_SIZE); | |
| 655 | 777 | available -= logsize; |
| 656 | 778 | |
| 657 | 779 | /* Calculate optimal split between map and data area */ |
| @@ -668,6 +790,10 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, · 10 unmodified lines | ||
| 668 | 790 | arena->mapoff = arena->dataoff + datasize; |
| 669 | 791 | arena->logoff = arena->mapoff + mapsize; |
| 670 | 792 | arena->info2off = arena->logoff + logsize; |
| 793 | + | |
| 794 | + /* Default log indices are (0,1) */ | |
| 795 | + arena->log_index[0] = 0; | |
| 796 | + arena->log_index[1] = 1; | |
| 671 | 797 | return arena; |
| 672 | 798 | } |
| 673 | 799 | |
| @@ -758,6 +884,13 @@ static int discover_arenas(struct btt *btt) · 84 unmodified lines | ||
| 758 | 884 | arena->external_lba_start = cur_nlba; |
| 759 | 885 | parse_arena_meta(arena, super, cur_off); |
| 760 | 886 | |
| 887 | + ret = log_set_indices(arena); | |
| 888 | + if (ret) { | |
| 889 | + dev_err(to_dev(arena), | |
| 890 | + "Unable to deduce log/padding indices\n"); | |
| 891 | + goto out; | |
| 892 | + } | |
| 893 | + | |
| 761 | 894 | mutex_init(&arena->err_lock); |
| 762 | 895 | ret = btt_freelist_init(arena); |
| 763 | 896 | if (ret) |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) |
| 28 | 28 | #define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) |
| 29 | 29 | #define MAP_ENT_NORMAL 0xC0000000 |
| 30 | +#define LOG_GRP_SIZE sizeof(struct log_group) | |
| 30 | 31 | #define LOG_ENT_SIZE sizeof(struct log_entry) |
| 31 | 32 | #define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ |
| 32 | 33 | #define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ |
| @@ -50,12 +51,52 @@ enum btt_init_state { · 17 unmodified lines | ||
| 50 | 51 | INIT_READY |
| 51 | 52 | }; |
| 52 | 53 | |
| 54 | +/* | |
| 55 | + * A log group represents one log 'lane', and consists of four log entries. | |
| 56 | + * Two of the four entries are valid entries, and the remaining two are | |
| 57 | + * padding. Due to an old bug in the padding location, we need to perform a | |
| 58 | + * test to determine the padding scheme being used, and use that scheme | |
| 59 | + * thereafter. | |
| 60 | + * | |
| 61 | + * In kernels prior to 4.15, 'log group' would have actual log entries at | |
| 62 | + * indices (0, 2) and padding at indices (1, 3), where as the correct/updated | |
| 63 | + * format has log entries at indices (0, 1) and padding at indices (2, 3). | |
| 64 | + * | |
| 65 | + * Old (pre 4.15) format: | |
| 66 | + * +-----------------+-----------------+ | |
| 67 | + * | ent[0] | ent[1] | | |
| 68 | + * | 16B | 16B | | |
| 69 | + * | lba/old/new/seq | pad | | |
| 70 | + * +-----------------------------------+ | |
| 71 | + * | ent[2] | ent[3] | | |
| 72 | + * | 16B | 16B | | |
| 73 | + * | lba/old/new/seq | pad | | |
| 74 | + * +-----------------+-----------------+ | |
| 75 | + * | |
| 76 | + * New format: | |
| 77 | + * +-----------------+-----------------+ | |
| 78 | + * | ent[0] | ent[1] | | |
| 79 | + * | 16B | 16B | | |
| 80 | + * | lba/old/new/seq | lba/old/new/seq | | |
| 81 | + * +-----------------------------------+ | |
| 82 | + * | ent[2] | ent[3] | | |
| 83 | + * | 16B | 16B | | |
| 84 | + * | pad | pad | | |
| 85 | + * +-----------------+-----------------+ | |
| 86 | + * | |
| 87 | + * We detect during start-up which format is in use, and set | |
| 88 | + * arena->log_index[(0, 1)] with the detected format. | |
| 89 | + */ | |
| 90 | + | |
| 53 | 91 | struct log_entry { |
| 54 | 92 | __le32 lba; |
| 55 | 93 | __le32 old_map; |
| 56 | 94 | __le32 new_map; |
| 57 | 95 | __le32 seq; |
| 58 | − __le64 padding[2]; | |
| 96 | +}; | |
| 97 | + | |
| 98 | +struct log_group { | |
| 99 | + struct log_entry ent[4]; | |
| 59 | 100 | }; |
| 60 | 101 | |
| 61 | 102 | struct btt_sb { |
| @@ -125,6 +166,8 @@ struct aligned_lock { · 63 unmodified lines | ||
| 125 | 166 | * @list: List head for list of arenas |
| 126 | 167 | * @debugfs_dir: Debugfs dentry |
| 127 | 168 | * @flags: Arena flags - may signify error states. |
| 169 | + * @err_lock: Mutex for synchronizing error clearing. | |
| 170 | + * @log_index: Indices of the valid log entries in a log_group | |
| 128 | 171 | * |
| 129 | 172 | * arena_info is a per-arena handle. Once an arena is narrowed down for an |
| 130 | 173 | * IO, this struct is passed around for the duration of the IO. |
| @@ -157,6 +200,7 @@ struct arena_info { · 26 unmodified lines | ||
| 157 | 200 | /* Arena flags */ |
| 158 | 201 | u32 flags; |
| 159 | 202 | struct mutex err_lock; |
| 203 | + int log_index[2]; | |
| 160 | 204 | }; |
| 161 | 205 | |
| 162 | 206 | /** |
| @@ -176,6 +220,7 @@ struct arena_info { · 13 unmodified lines | ||
| 176 | 220 | * @init_lock: Mutex used for the BTT initialization |
| 177 | 221 | * @init_state: Flag describing the initialization state for the BTT |
| 178 | 222 | * @num_arenas: Number of arenas in the BTT instance |
| 223 | + * @phys_bb: Pointer to the namespace's badblocks structure | |
| 179 | 224 | */ |
| 180 | 225 | struct btt { |
| 181 | 226 | struct gendisk *btt_disk; |
| @@ -364,9 +364,9 @@ struct device *nd_pfn_create(struct nd_region *nd_region) · 363 unmodified lines | ||
| 364 | 364 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
| 365 | 365 | { |
| 366 | 366 | u64 checksum, offset; |
| 367 | − unsigned long align; | |
| 368 | 367 | enum nd_pfn_mode mode; |
| 369 | 368 | struct nd_namespace_io *nsio; |
| 369 | + unsigned long align, start_pad; | |
| 370 | 370 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
| 371 | 371 | struct nd_namespace_common *ndns = nd_pfn->ndns; |
| 372 | 372 | const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); |
| @@ -410,6 +410,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) · 37 unmodified lines | ||
| 410 | 410 | |
| 411 | 411 | align = le32_to_cpu(pfn_sb->align); |
| 412 | 412 | offset = le64_to_cpu(pfn_sb->dataoff); |
| 413 | + start_pad = le32_to_cpu(pfn_sb->start_pad); | |
| 413 | 414 | if (align == 0) |
| 414 | 415 | align = 1UL << ilog2(offset); |
| 415 | 416 | mode = le32_to_cpu(pfn_sb->mode); |
| @@ -468,7 +469,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) · 52 unmodified lines | ||
| 468 | 469 | return -EBUSY; |
| 469 | 470 | } |
| 470 | 471 | |
| 471 | − if ((align && !IS_ALIGNED(offset, align)) | |
| 472 | + if ((align && !IS_ALIGNED(nsio->res.start + offset + start_pad, align)) | |
| 472 | 473 | || !IS_ALIGNED(offset, PAGE_SIZE)) { |
| 473 | 474 | dev_err(&nd_pfn->dev, |
| 474 | 475 | "bad offset: %#llx dax disabled align: %#lx\n", |
| @@ -582,6 +583,12 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, · 107 unmodified lines | ||
| 582 | 583 | return altmap; |
| 583 | 584 | } |
| 584 | 585 | |
| 586 | +static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys) | |
| 587 | +{ | |
| 588 | + return min_t(u64, PHYS_SECTION_ALIGN_DOWN(phys), | |
| 589 | + ALIGN_DOWN(phys, nd_pfn->align)); | |
| 590 | +} | |
| 591 | + | |
| 585 | 592 | static int nd_pfn_init(struct nd_pfn *nd_pfn) |
| 586 | 593 | { |
| 587 | 594 | u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; |
| @@ -637,13 +644,16 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 49 unmodified lines | ||
| 637 | 644 | start = nsio->res.start; |
| 638 | 645 | size = PHYS_SECTION_ALIGN_UP(start + size) - start; |
| 639 | 646 | if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, |
| 640 | − IORES_DESC_NONE) == REGION_MIXED) { | |
| 647 | + IORES_DESC_NONE) == REGION_MIXED | |
| 648 | + || !IS_ALIGNED(start + resource_size(&nsio->res), | |
| 649 | + nd_pfn->align)) { | |
| 641 | 650 | size = resource_size(&nsio->res); |
| 642 | − end_trunc = start + size - PHYS_SECTION_ALIGN_DOWN(start + size); | |
| 651 | + end_trunc = start + size - phys_pmem_align_down(nd_pfn, | |
| 652 | + start + size); | |
| 643 | 653 | } |
| 644 | 654 | |
| 645 | 655 | if (start_pad + end_trunc) |
| 646 | − dev_info(&nd_pfn->dev, "%s section collision, truncate %d bytes\n", | |
| 656 | + dev_info(&nd_pfn->dev, "%s alignment collision, truncate %d bytes\n", | |
| 647 | 657 | dev_name(&ndns->dev), start_pad + end_trunc); |
| 648 | 658 | |
| 649 | 659 | /* |
| @@ -1287,7 +1287,7 @@ static void nvme_config_discard(struct nvme_ctrl *ctrl, · 1286 unmodified lines | ||
| 1287 | 1287 | BUILD_BUG_ON(PAGE_SIZE / sizeof(struct nvme_dsm_range) < |
| 1288 | 1288 | NVME_DSM_MAX_RANGES); |
| 1289 | 1289 | |
| 1290 | − queue->limits.discard_alignment = size; | |
| 1290 | + queue->limits.discard_alignment = 0; | |
| 1291 | 1291 | queue->limits.discard_granularity = size; |
| 1292 | 1292 | |
| 1293 | 1293 | blk_queue_max_discard_sectors(queue, UINT_MAX); |
| @@ -1705,7 +1705,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, · 411 unmodified lines | ||
| 1705 | 1705 | blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); |
| 1706 | 1706 | blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); |
| 1707 | 1707 | } |
| 1708 | − if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) | |
| 1708 | + if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && | |
| 1709 | + is_power_of_2(ctrl->max_hw_sectors)) | |
| 1709 | 1710 | blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); |
| 1710 | 1711 | blk_queue_virt_boundary(q, ctrl->page_size - 1); |
| 1711 | 1712 | if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) |
| @@ -2869,7 +2870,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 1157 unmodified lines | ||
| 2869 | 2870 | |
| 2870 | 2871 | blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); |
| 2871 | 2872 | nvme_set_queue_limits(ctrl, ns->queue); |
| 2872 | − nvme_setup_streams_ns(ctrl, ns); | |
| 2873 | 2873 | |
| 2874 | 2874 | id = nvme_identify_ns(ctrl, nsid); |
| 2875 | 2875 | if (!id) |
| @@ -2880,6 +2880,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 4 unmodified lines | ||
| 2880 | 2880 | |
| 2881 | 2881 | if (nvme_init_ns_head(ns, nsid, id, &new)) |
| 2882 | 2882 | goto out_free_id; |
| 2883 | + nvme_setup_streams_ns(ctrl, ns); | |
| 2883 | 2884 | |
| 2884 | 2885 | #ifdef CONFIG_NVME_MULTIPATH |
| 2885 | 2886 | /* |
| @@ -2965,8 +2966,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) · 79 unmodified lines | ||
| 2965 | 2966 | return; |
| 2966 | 2967 | |
| 2967 | 2968 | if (ns->disk && ns->disk->flags & GENHD_FL_UP) { |
| 2968 | − if (blk_get_integrity(ns->disk)) | |
| 2969 | − blk_integrity_unregister(ns->disk); | |
| 2970 | 2969 | nvme_mpath_remove_disk_links(ns); |
| 2971 | 2970 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, |
| 2972 | 2971 | &nvme_ns_id_attr_group); |
| @@ -2974,6 +2973,8 @@ static void nvme_ns_remove(struct nvme_ns *ns) · 1 unmodified line | ||
| 2974 | 2973 | nvme_nvm_unregister_sysfs(ns); |
| 2975 | 2974 | del_gendisk(ns->disk); |
| 2976 | 2975 | blk_cleanup_queue(ns->queue); |
| 2976 | + if (blk_get_integrity(ns->disk)) | |
| 2977 | + blk_integrity_unregister(ns->disk); | |
| 2977 | 2978 | } |
| 2978 | 2979 | |
| 2979 | 2980 | mutex_lock(&ns->ctrl->subsys->lock); |
| @@ -3221,7 +3221,6 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · 3220 unmodified lines | ||
| 3221 | 3221 | |
| 3222 | 3222 | /* initiate nvme ctrl ref counting teardown */ |
| 3223 | 3223 | nvme_uninit_ctrl(&ctrl->ctrl); |
| 3224 | − nvme_put_ctrl(&ctrl->ctrl); | |
| 3225 | 3224 | |
| 3226 | 3225 | /* Remove core ctrl ref. */ |
| 3227 | 3226 | nvme_put_ctrl(&ctrl->ctrl); |
| @@ -156,8 +156,8 @@ static int meson_mx_efuse_read(void *context, unsigned int offset, · 155 unmodified lines | ||
| 156 | 156 | MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE, |
| 157 | 157 | MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE); |
| 158 | 158 | |
| 159 | − for (i = offset; i < offset + bytes; i += efuse->config.word_size) { | |
| 160 | − addr = i / efuse->config.word_size; | |
| 159 | + for (i = 0; i < bytes; i += efuse->config.word_size) { | |
| 160 | + addr = (offset + i) / efuse->config.word_size; | |
| 161 | 161 | |
| 162 | 162 | err = meson_mx_efuse_read_addr(efuse, addr, &tmp); |
| 163 | 163 | if (err) |
| @@ -81,6 +81,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, · 80 unmodified lines | ||
| 81 | 81 | * can be looked up later */ |
| 82 | 82 | of_node_get(child); |
| 83 | 83 | phy->mdio.dev.of_node = child; |
| 84 | + phy->mdio.dev.fwnode = of_fwnode_handle(child); | |
| 84 | 85 | |
| 85 | 86 | /* All data is now stored in the phy struct; |
| 86 | 87 | * register it */ |
| @@ -111,6 +112,7 @@ static int of_mdiobus_register_device(struct mii_bus *mdio, · 24 unmodified lines | ||
| 111 | 112 | */ |
| 112 | 113 | of_node_get(child); |
| 113 | 114 | mdiodev->dev.of_node = child; |
| 115 | + mdiodev->dev.fwnode = of_fwnode_handle(child); | |
| 114 | 116 | |
| 115 | 117 | /* All data is now stored in the mdiodev struct; register it. */ |
| 116 | 118 | rc = mdio_device_register(mdiodev); |
| @@ -206,6 +208,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) · 89 unmodified lines | ||
| 206 | 208 | mdio->phy_mask = ~0; |
| 207 | 209 | |
| 208 | 210 | mdio->dev.of_node = np; |
| 211 | + mdio->dev.fwnode = of_fwnode_handle(np); | |
| 209 | 212 | |
| 210 | 213 | /* Get bus level PHY reset GPIO details */ |
| 211 | 214 | mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY; |
| @@ -1692,3 +1692,36 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) · 1691 unmodified lines | ||
| 1692 | 1692 | iounmap(base_addr); |
| 1693 | 1693 | } |
| 1694 | 1694 | |
| 1695 | + | |
| 1696 | +/* | |
| 1697 | + * The design of the Diva management card in rp34x0 machines (rp3410, rp3440) | |
| 1698 | + * seems rushed, so that many built-in components simply don't work. | |
| 1699 | + * The following quirks disable the serial AUX port and the built-in ATI RV100 | |
| 1700 | + * Radeon 7000 graphics card which both don't have any external connectors and | |
| 1701 | + * thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as | |
| 1702 | + * such makes those machines the only PARISC machines on which we can't use | |
| 1703 | + * ttyS0 as boot console. | |
| 1704 | + */ | |
| 1705 | +static void quirk_diva_ati_card(struct pci_dev *dev) | |
| 1706 | +{ | |
| 1707 | + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || | |
| 1708 | + dev->subsystem_device != 0x1292) | |
| 1709 | + return; | |
| 1710 | + | |
| 1711 | + dev_info(&dev->dev, "Hiding Diva built-in ATI card"); | |
| 1712 | + dev->device = 0; | |
| 1713 | +} | |
| 1714 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, | |
| 1715 | + quirk_diva_ati_card); | |
| 1716 | + | |
| 1717 | +static void quirk_diva_aux_disable(struct pci_dev *dev) | |
| 1718 | +{ | |
| 1719 | + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || | |
| 1720 | + dev->subsystem_device != 0x1291) | |
| 1721 | + return; | |
| 1722 | + | |
| 1723 | + dev_info(&dev->dev, "Hiding Diva built-in AUX serial device"); | |
| 1724 | + dev->device = 0; | |
| 1725 | +} | |
| 1726 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, | |
| 1727 | + quirk_diva_aux_disable); | |
| @@ -985,9 +985,7 @@ static u32 hv_compose_msi_req_v1( · 984 unmodified lines | ||
| 985 | 985 | int_pkt->wslot.slot = slot; |
| 986 | 986 | int_pkt->int_desc.vector = vector; |
| 987 | 987 | int_pkt->int_desc.vector_count = 1; |
| 988 | − int_pkt->int_desc.delivery_mode = | |
| 989 | − (apic->irq_delivery_mode == dest_LowestPrio) ? | |
| 990 | − dest_LowestPrio : dest_Fixed; | |
| 988 | + int_pkt->int_desc.delivery_mode = dest_Fixed; | |
| 991 | 989 | |
| 992 | 990 | /* |
| 993 | 991 | * Create MSI w/ dummy vCPU set, overwritten by subsequent retarget in |
| @@ -1008,9 +1006,7 @@ static u32 hv_compose_msi_req_v2( · 14 unmodified lines | ||
| 1008 | 1006 | int_pkt->wslot.slot = slot; |
| 1009 | 1007 | int_pkt->int_desc.vector = vector; |
| 1010 | 1008 | int_pkt->int_desc.vector_count = 1; |
| 1011 | − int_pkt->int_desc.delivery_mode = | |
| 1012 | − (apic->irq_delivery_mode == dest_LowestPrio) ? | |
| 1013 | − dest_LowestPrio : dest_Fixed; | |
| 1009 | + int_pkt->int_desc.delivery_mode = dest_Fixed; | |
| 1014 | 1010 | |
| 1015 | 1011 | /* |
| 1016 | 1012 | * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten |
| @@ -1128,12 +1128,12 @@ static int rcar_pcie_probe(struct platform_device *pdev) · 1127 unmodified lines | ||
| 1128 | 1128 | err = rcar_pcie_get_resources(pcie); |
| 1129 | 1129 | if (err < 0) { |
| 1130 | 1130 | dev_err(dev, "failed to request resources: %d\n", err); |
| 1131 | − goto err_free_bridge; | |
| 1131 | + goto err_free_resource_list; | |
| 1132 | 1132 | } |
| 1133 | 1133 | |
| 1134 | 1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); |
| 1135 | 1135 | if (err) |
| 1136 | − goto err_free_bridge; | |
| 1136 | + goto err_free_resource_list; | |
| 1137 | 1137 | |
| 1138 | 1138 | pm_runtime_enable(dev); |
| 1139 | 1139 | err = pm_runtime_get_sync(dev); |
| @@ -1176,9 +1176,9 @@ err_pm_put: · 36 unmodified lines | ||
| 1176 | 1176 | err_pm_disable: |
| 1177 | 1177 | pm_runtime_disable(dev); |
| 1178 | 1178 | |
| 1179 | −err_free_bridge: | |
| 1180 | − pci_free_host_bridge(bridge); | |
| 1179 | +err_free_resource_list: | |
| 1181 | 1180 | pci_free_resource_list(&pcie->resources); |
| 1181 | + pci_free_host_bridge(bridge); | |
| 1182 | 1182 | |
| 1183 | 1183 | return err; |
| 1184 | 1184 | } |
| @@ -999,7 +999,7 @@ static int pci_pm_thaw_noirq(struct device *dev) · 998 unmodified lines | ||
| 999 | 999 | * the subsequent "thaw" callbacks for the device. |
| 1000 | 1000 | */ |
| 1001 | 1001 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
| 1002 | − dev->power.direct_complete = true; | |
| 1002 | + dev_pm_skip_next_resume_phases(dev); | |
| 1003 | 1003 | return 0; |
| 1004 | 1004 | } |
| 1005 | 1005 | |
| @@ -1012,7 +1012,12 @@ static int pci_pm_thaw_noirq(struct device *dev) · 6 unmodified lines | ||
| 1012 | 1012 | if (pci_has_legacy_pm_support(pci_dev)) |
| 1013 | 1013 | return pci_legacy_resume_early(dev); |
| 1014 | 1014 | |
| 1015 | − pci_update_current_state(pci_dev, PCI_D0); | |
| 1015 | + /* | |
| 1016 | + * pci_restore_state() requires the device to be in D0 (because of MSI | |
| 1017 | + * restoration among other things), so force it into D0 in case the | |
| 1018 | + * driver's "freeze" callbacks put it into a low-power state directly. | |
| 1019 | + */ | |
| 1020 | + pci_set_power_state(pci_dev, PCI_D0); | |
| 1016 | 1021 | pci_restore_state(pci_dev); |
| 1017 | 1022 | |
| 1018 | 1023 | if (drv && drv->pm && drv->pm->thaw_noirq) |
| @@ -310,7 +310,7 @@ static int cpcap_usb_init_irq(struct platform_device *pdev, · 309 unmodified lines | ||
| 310 | 310 | int irq, error; |
| 311 | 311 | |
| 312 | 312 | irq = platform_get_irq_byname(pdev, name); |
| 313 | − if (!irq) | |
| 313 | + if (irq < 0) | |
| 314 | 314 | return -ENODEV; |
| 315 | 315 | |
| 316 | 316 | error = devm_request_threaded_irq(ddata->dev, irq, NULL, |
| @@ -12,7 +12,9 @@ config PHY_RCAR_GEN3_USB2 · 11 unmodified lines | ||
| 12 | 12 | tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" |
| 13 | 13 | depends on ARCH_RENESAS |
| 14 | 14 | depends on EXTCON |
| 15 | + depends on USB_SUPPORT | |
| 15 | 16 | select GENERIC_PHY |
| 17 | + select USB_COMMON | |
| 16 | 18 | help |
| 17 | 19 | Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. |
| 18 | 20 | |
| @@ -1137,6 +1137,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) · 1136 unmodified lines | ||
| 1137 | 1137 | if (IS_ERR(phy)) { |
| 1138 | 1138 | dev_err(dev, "failed to create phy: %s\n", |
| 1139 | 1139 | child_np->name); |
| 1140 | + pm_runtime_disable(dev); | |
| 1140 | 1141 | return PTR_ERR(phy); |
| 1141 | 1142 | } |
| 1142 | 1143 | |
| @@ -1146,6 +1147,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1146 | 1147 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); |
| 1147 | 1148 | if (IS_ERR(phy_provider)) { |
| 1148 | 1149 | dev_err(dev, "Failed to register phy provider\n"); |
| 1150 | + pm_runtime_disable(dev); | |
| 1149 | 1151 | return PTR_ERR(phy_provider); |
| 1150 | 1152 | } |
| 1151 | 1153 | |
| @@ -75,14 +75,14 @@ MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); · 74 unmodified lines | ||
| 75 | 75 | static struct device_node * |
| 76 | 76 | tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) |
| 77 | 77 | { |
| 78 | − /* | |
| 79 | − * of_find_node_by_name() drops a reference, so make sure to grab one. | |
| 80 | − */ | |
| 81 | − struct device_node *np = of_node_get(padctl->dev->of_node); | |
| 78 | + struct device_node *pads, *np; | |
| 79 | + | |
| 80 | + pads = of_get_child_by_name(padctl->dev->of_node, "pads"); | |
| 81 | + if (!pads) | |
| 82 | + return NULL; | |
| 82 | 83 | |
| 83 | − np = of_find_node_by_name(np, "pads"); | |
| 84 | − if (np) | |
| 85 | − np = of_find_node_by_name(np, name); | |
| 84 | + np = of_get_child_by_name(pads, name); | |
| 85 | + of_node_put(pads); | |
| 86 | 86 | |
| 87 | 87 | return np; |
| 88 | 88 | } |
| @@ -90,16 +90,16 @@ tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) · 1 unmodified line | ||
| 90 | 90 | static struct device_node * |
| 91 | 91 | tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index) |
| 92 | 92 | { |
| 93 | − /* | |
| 94 | − * of_find_node_by_name() drops a reference, so make sure to grab one. | |
| 95 | − */ | |
| 96 | − struct device_node *np = of_node_get(pad->dev.of_node); | |
| 93 | + struct device_node *np, *lanes; | |
| 97 | 94 | |
| 98 | − np = of_find_node_by_name(np, "lanes"); | |
| 99 | − if (!np) | |
| 95 | + lanes = of_get_child_by_name(pad->dev.of_node, "lanes"); | |
| 96 | + if (!lanes) | |
| 100 | 97 | return NULL; |
| 101 | 98 | |
| 102 | − return of_find_node_by_name(np, pad->soc->lanes[index].name); | |
| 99 | + np = of_get_child_by_name(lanes, pad->soc->lanes[index].name); | |
| 100 | + of_node_put(lanes); | |
| 101 | + | |
| 102 | + return np; | |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | static int |
| @@ -195,7 +195,7 @@ int tegra_xusb_pad_register(struct tegra_xusb_pad *pad, · 89 unmodified lines | ||
| 195 | 195 | unsigned int i; |
| 196 | 196 | int err; |
| 197 | 197 | |
| 198 | − children = of_find_node_by_name(pad->dev.of_node, "lanes"); | |
| 198 | + children = of_get_child_by_name(pad->dev.of_node, "lanes"); | |
| 199 | 199 | if (!children) |
| 200 | 200 | return -ENODEV; |
| 201 | 201 | |
| @@ -444,21 +444,21 @@ static struct device_node * · 242 unmodified lines | ||
| 444 | 444 | tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, |
| 445 | 445 | unsigned int index) |
| 446 | 446 | { |
| 447 | − /* | |
| 448 | − * of_find_node_by_name() drops a reference, so make sure to grab one. | |
| 449 | − */ | |
| 450 | − struct device_node *np = of_node_get(padctl->dev->of_node); | |
| 447 | + struct device_node *ports, *np; | |
| 448 | + char *name; | |
| 451 | 449 | |
| 452 | − np = of_find_node_by_name(np, "ports"); | |
| 453 | − if (np) { | |
| 454 | − char *name; | |
| 450 | + ports = of_get_child_by_name(padctl->dev->of_node, "ports"); | |
| 451 | + if (!ports) | |
| 452 | + return NULL; | |
| 455 | 453 | |
| 456 | − name = kasprintf(GFP_KERNEL, "%s-%u", type, index); | |
| 457 | − if (!name) | |
| 458 | − return ERR_PTR(-ENOMEM); | |
| 459 | − np = of_find_node_by_name(np, name); | |
| 460 | − kfree(name); | |
| 454 | + name = kasprintf(GFP_KERNEL, "%s-%u", type, index); | |
| 455 | + if (!name) { | |
| 456 | + of_node_put(ports); | |
| 457 | + return ERR_PTR(-ENOMEM); | |
| 461 | 458 | } |
| 459 | + np = of_get_child_by_name(ports, name); | |
| 460 | + kfree(name); | |
| 461 | + of_node_put(ports); | |
| 462 | 462 | |
| 463 | 463 | return np; |
| 464 | 464 | } |
| @@ -847,7 +847,7 @@ static void tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl) · 382 unmodified lines | ||
| 847 | 847 | |
| 848 | 848 | static int tegra_xusb_padctl_probe(struct platform_device *pdev) |
| 849 | 849 | { |
| 850 | − struct device_node *np = of_node_get(pdev->dev.of_node); | |
| 850 | + struct device_node *np = pdev->dev.of_node; | |
| 851 | 851 | const struct tegra_xusb_padctl_soc *soc; |
| 852 | 852 | struct tegra_xusb_padctl *padctl; |
| 853 | 853 | const struct of_device_id *match; |
| @@ -855,7 +855,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 855 | 855 | int err; |
| 856 | 856 | |
| 857 | 857 | /* for backwards compatibility with old device trees */ |
| 858 | − np = of_find_node_by_name(np, "pads"); | |
| 858 | + np = of_get_child_by_name(np, "pads"); | |
| 859 | 859 | if (!np) { |
| 860 | 860 | dev_warn(&pdev->dev, "deprecated DT, using legacy driver\n"); |
| 861 | 861 | return tegra_xusb_padctl_legacy_probe(pdev); |
| @@ -1620,6 +1620,22 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) · 1619 unmodified lines | ||
| 1620 | 1620 | clear_bit(i, chip->irq.valid_mask); |
| 1621 | 1621 | } |
| 1622 | 1622 | |
| 1623 | + /* | |
| 1624 | + * The same set of machines in chv_no_valid_mask[] have incorrectly | |
| 1625 | + * configured GPIOs that generate spurious interrupts so we use | |
| 1626 | + * this same list to apply another quirk for them. | |
| 1627 | + * | |
| 1628 | + * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. | |
| 1629 | + */ | |
| 1630 | + if (!need_valid_mask) { | |
| 1631 | + /* | |
| 1632 | + * Mask all interrupts the community is able to generate | |
| 1633 | + * but leave the ones that can only generate GPEs unmasked. | |
| 1634 | + */ | |
| 1635 | + chv_writel(GENMASK(31, pctrl->community->nirqs), | |
| 1636 | + pctrl->regs + CHV_INTMASK); | |
| 1637 | + } | |
| 1638 | + | |
| 1623 | 1639 | /* Clear all interrupts */ |
| 1624 | 1640 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); |
| 1625 | 1641 | |
| @@ -222,6 +222,9 @@ static enum pin_config_param pcs_bias[] = { · 221 unmodified lines | ||
| 222 | 222 | */ |
| 223 | 223 | static struct lock_class_key pcs_lock_class; |
| 224 | 224 | |
| 225 | +/* Class for the IRQ request mutex */ | |
| 226 | +static struct lock_class_key pcs_request_class; | |
| 227 | + | |
| 225 | 228 | /* |
| 226 | 229 | * REVISIT: Reads and writes could eventually use regmap or something |
| 227 | 230 | * generic. But at least on omaps, some mux registers are performance |
| @@ -1486,7 +1489,7 @@ static int pcs_irqdomain_map(struct irq_domain *d, unsigned int irq, · 1258 unmodified lines | ||
| 1486 | 1489 | irq_set_chip_data(irq, pcs_soc); |
| 1487 | 1490 | irq_set_chip_and_handler(irq, &pcs->chip, |
| 1488 | 1491 | handle_level_irq); |
| 1489 | − irq_set_lockdep_class(irq, &pcs_lock_class); | |
| 1492 | + irq_set_lockdep_class(irq, &pcs_lock_class, &pcs_request_class); | |
| 1490 | 1493 | irq_set_noprobe(irq); |
| 1491 | 1494 | |
| 1492 | 1495 | return 0; |
| @@ -290,7 +290,7 @@ static int stm32_gpio_domain_translate(struct irq_domain *d, · 289 unmodified lines | ||
| 290 | 290 | } |
| 291 | 291 | |
| 292 | 292 | static int stm32_gpio_domain_activate(struct irq_domain *d, |
| 293 | − struct irq_data *irq_data, bool early) | |
| 293 | + struct irq_data *irq_data, bool reserve) | |
| 294 | 294 | { |
| 295 | 295 | struct stm32_gpio_bank *bank = d->host_data; |
| 296 | 296 | struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); |
| @@ -118,6 +118,7 @@ static void asus_wireless_notify(struct acpi_device *adev, u32 event) · 117 unmodified lines | ||
| 118 | 118 | return; |
| 119 | 119 | } |
| 120 | 120 | input_report_key(data->idev, KEY_RFKILL, 1); |
| 121 | + input_sync(data->idev); | |
| 121 | 122 | input_report_key(data->idev, KEY_RFKILL, 0); |
| 122 | 123 | input_sync(data->idev); |
| 123 | 124 | } |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | struct quirk_entry { |
| 39 | 39 | u8 touchpad_led; |
| 40 | + u8 kbd_led_levels_off_1; | |
| 40 | 41 | |
| 41 | 42 | int needs_kbd_timeouts; |
| 42 | 43 | /* |
| @@ -67,6 +68,10 @@ static struct quirk_entry quirk_dell_xps13_9333 = { · 24 unmodified lines | ||
| 67 | 68 | .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 }, |
| 68 | 69 | }; |
| 69 | 70 | |
| 71 | +static struct quirk_entry quirk_dell_latitude_e6410 = { | |
| 72 | + .kbd_led_levels_off_1 = 1, | |
| 73 | +}; | |
| 74 | + | |
| 70 | 75 | static struct platform_driver platform_driver = { |
| 71 | 76 | .driver = { |
| 72 | 77 | .name = "dell-laptop", |
| @@ -269,6 +274,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = { · 196 unmodified lines | ||
| 269 | 274 | }, |
| 270 | 275 | .driver_data = &quirk_dell_xps13_9333, |
| 271 | 276 | }, |
| 277 | + { | |
| 278 | + .callback = dmi_matched, | |
| 279 | + .ident = "Dell Latitude E6410", | |
| 280 | + .matches = { | |
| 281 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 282 | + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6410"), | |
| 283 | + }, | |
| 284 | + .driver_data = &quirk_dell_latitude_e6410, | |
| 285 | + }, | |
| 272 | 286 | { } |
| 273 | 287 | }; |
| 274 | 288 | |
| @@ -1149,6 +1163,9 @@ static int kbd_get_info(struct kbd_info *info) · 874 unmodified lines | ||
| 1149 | 1163 | units = (buffer->output[2] >> 8) & 0xFF; |
| 1150 | 1164 | info->levels = (buffer->output[2] >> 16) & 0xFF; |
| 1151 | 1165 | |
| 1166 | + if (quirks && quirks->kbd_led_levels_off_1 && info->levels) | |
| 1167 | + info->levels--; | |
| 1168 | + | |
| 1152 | 1169 | if (units & BIT(0)) |
| 1153 | 1170 | info->seconds = (buffer->output[3] >> 0) & 0xFF; |
| 1154 | 1171 | if (units & BIT(1)) |
| @@ -639,6 +639,8 @@ static int dell_wmi_events_set_enabled(bool enable) · 638 unmodified lines | ||
| 639 | 639 | int ret; |
| 640 | 640 | |
| 641 | 641 | buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL); |
| 642 | + if (!buffer) | |
| 643 | + return -ENOMEM; | |
| 642 | 644 | buffer->cmd_class = CLASS_INFO; |
| 643 | 645 | buffer->cmd_select = SELECT_APP_REGISTRATION; |
| 644 | 646 | buffer->input[0] = 0x10000; |
| @@ -565,9 +565,9 @@ enum qeth_cq { · 564 unmodified lines | ||
| 565 | 565 | }; |
| 566 | 566 | |
| 567 | 567 | struct qeth_ipato { |
| 568 | − int enabled; | |
| 569 | − int invert4; | |
| 570 | − int invert6; | |
| 568 | + bool enabled; | |
| 569 | + bool invert4; | |
| 570 | + bool invert6; | |
| 571 | 571 | struct list_head entries; |
| 572 | 572 | }; |
| 573 | 573 | |
| @@ -1480,9 +1480,9 @@ static int qeth_setup_card(struct qeth_card *card) · 1479 unmodified lines | ||
| 1480 | 1480 | qeth_set_intial_options(card); |
| 1481 | 1481 | /* IP address takeover */ |
| 1482 | 1482 | INIT_LIST_HEAD(&card->ipato.entries); |
| 1483 | − card->ipato.enabled = 0; | |
| 1484 | − card->ipato.invert4 = 0; | |
| 1485 | − card->ipato.invert6 = 0; | |
| 1483 | + card->ipato.enabled = false; | |
| 1484 | + card->ipato.invert4 = false; | |
| 1485 | + card->ipato.invert6 = false; | |
| 1486 | 1486 | /* init QDIO stuff */ |
| 1487 | 1487 | qeth_init_qdio_info(card); |
| 1488 | 1488 | INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); |
| @@ -5386,6 +5386,13 @@ out: · 3897 unmodified lines | ||
| 5386 | 5386 | } |
| 5387 | 5387 | EXPORT_SYMBOL_GPL(qeth_poll); |
| 5388 | 5388 | |
| 5389 | +static int qeth_setassparms_inspect_rc(struct qeth_ipa_cmd *cmd) | |
| 5390 | +{ | |
| 5391 | + if (!cmd->hdr.return_code) | |
| 5392 | + cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code; | |
| 5393 | + return cmd->hdr.return_code; | |
| 5394 | +} | |
| 5395 | + | |
| 5389 | 5396 | int qeth_setassparms_cb(struct qeth_card *card, |
| 5390 | 5397 | struct qeth_reply *reply, unsigned long data) |
| 5391 | 5398 | { |
| @@ -6242,7 +6249,7 @@ static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card, · 850 unmodified lines | ||
| 6242 | 6249 | (struct qeth_checksum_cmd *)reply->param; |
| 6243 | 6250 | |
| 6244 | 6251 | QETH_CARD_TEXT(card, 4, "chkdoccb"); |
| 6245 | − if (cmd->hdr.return_code) | |
| 6252 | + if (qeth_setassparms_inspect_rc(cmd)) | |
| 6246 | 6253 | return 0; |
| 6247 | 6254 | |
| 6248 | 6255 | memset(chksum_cb, 0, sizeof(*chksum_cb)); |
| @@ -82,7 +82,7 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *); · 81 unmodified lines | ||
| 82 | 82 | int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); |
| 83 | 83 | void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, |
| 84 | 84 | const u8 *); |
| 85 | −int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *); | |
| 85 | +void qeth_l3_update_ipato(struct qeth_card *card); | |
| 86 | 86 | struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions); |
| 87 | 87 | int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *); |
| 88 | 88 | int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *); |
| @@ -164,8 +164,8 @@ static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len) · 163 unmodified lines | ||
| 164 | 164 | } |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | −int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, | |
| 168 | − struct qeth_ipaddr *addr) | |
| 167 | +static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, | |
| 168 | + struct qeth_ipaddr *addr) | |
| 169 | 169 | { |
| 170 | 170 | struct qeth_ipato_entry *ipatoe; |
| 171 | 171 | u8 addr_bits[128] = {0, }; |
| @@ -174,6 +174,8 @@ int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, · 2 unmodified lines | ||
| 174 | 174 | |
| 175 | 175 | if (!card->ipato.enabled) |
| 176 | 176 | return 0; |
| 177 | + if (addr->type != QETH_IP_TYPE_NORMAL) | |
| 178 | + return 0; | |
| 177 | 179 | |
| 178 | 180 | qeth_l3_convert_addr_to_bits((u8 *) &addr->u, addr_bits, |
| 179 | 181 | (addr->proto == QETH_PROT_IPV4)? 4:16); |
| @@ -290,8 +292,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) · 110 unmodified lines | ||
| 290 | 292 | memcpy(addr, tmp_addr, sizeof(struct qeth_ipaddr)); |
| 291 | 293 | addr->ref_counter = 1; |
| 292 | 294 | |
| 293 | − if (addr->type == QETH_IP_TYPE_NORMAL && | |
| 294 | − qeth_l3_is_addr_covered_by_ipato(card, addr)) { | |
| 295 | + if (qeth_l3_is_addr_covered_by_ipato(card, addr)) { | |
| 295 | 296 | QETH_CARD_TEXT(card, 2, "tkovaddr"); |
| 296 | 297 | addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG; |
| 297 | 298 | } |
| @@ -605,6 +606,27 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) · 307 unmodified lines | ||
| 605 | 606 | /* |
| 606 | 607 | * IP address takeover related functions |
| 607 | 608 | */ |
| 609 | + | |
| 610 | +/** | |
| 611 | + * qeth_l3_update_ipato() - Update 'takeover' property, for all NORMAL IPs. | |
| 612 | + * | |
| 613 | + * Caller must hold ip_lock. | |
| 614 | + */ | |
| 615 | +void qeth_l3_update_ipato(struct qeth_card *card) | |
| 616 | +{ | |
| 617 | + struct qeth_ipaddr *addr; | |
| 618 | + unsigned int i; | |
| 619 | + | |
| 620 | + hash_for_each(card->ip_htable, i, addr, hnode) { | |
| 621 | + if (addr->type != QETH_IP_TYPE_NORMAL) | |
| 622 | + continue; | |
| 623 | + if (qeth_l3_is_addr_covered_by_ipato(card, addr)) | |
| 624 | + addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG; | |
| 625 | + else | |
| 626 | + addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG; | |
| 627 | + } | |
| 628 | +} | |
| 629 | + | |
| 608 | 630 | static void qeth_l3_clear_ipato_list(struct qeth_card *card) |
| 609 | 631 | { |
| 610 | 632 | struct qeth_ipato_entry *ipatoe, *tmp; |
| @@ -616,6 +638,7 @@ static void qeth_l3_clear_ipato_list(struct qeth_card *card) · 5 unmodified lines | ||
| 616 | 638 | kfree(ipatoe); |
| 617 | 639 | } |
| 618 | 640 | |
| 641 | + qeth_l3_update_ipato(card); | |
| 619 | 642 | spin_unlock_bh(&card->ip_lock); |
| 620 | 643 | } |
| 621 | 644 | |
| @@ -640,8 +663,10 @@ int qeth_l3_add_ipato_entry(struct qeth_card *card, · 18 unmodified lines | ||
| 640 | 663 | } |
| 641 | 664 | } |
| 642 | 665 | |
| 643 | − if (!rc) | |
| 666 | + if (!rc) { | |
| 644 | 667 | list_add_tail(&new->entry, &card->ipato.entries); |
| 668 | + qeth_l3_update_ipato(card); | |
| 669 | + } | |
| 645 | 670 | |
| 646 | 671 | spin_unlock_bh(&card->ip_lock); |
| 647 | 672 | |
| @@ -664,6 +689,7 @@ void qeth_l3_del_ipato_entry(struct qeth_card *card, · 16 unmodified lines | ||
| 664 | 689 | (proto == QETH_PROT_IPV4)? 4:16) && |
| 665 | 690 | (ipatoe->mask_bits == mask_bits)) { |
| 666 | 691 | list_del(&ipatoe->entry); |
| 692 | + qeth_l3_update_ipato(card); | |
| 667 | 693 | kfree(ipatoe); |
| 668 | 694 | } |
| 669 | 695 | } |
| @@ -370,8 +370,8 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, · 369 unmodified lines | ||
| 370 | 370 | struct device_attribute *attr, const char *buf, size_t count) |
| 371 | 371 | { |
| 372 | 372 | struct qeth_card *card = dev_get_drvdata(dev); |
| 373 | − struct qeth_ipaddr *addr; | |
| 374 | − int i, rc = 0; | |
| 373 | + bool enable; | |
| 374 | + int rc = 0; | |
| 375 | 375 | |
| 376 | 376 | if (!card) |
| 377 | 377 | return -EINVAL; |
| @@ -384,25 +384,18 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, · 6 unmodified lines | ||
| 384 | 384 | } |
| 385 | 385 | |
| 386 | 386 | if (sysfs_streq(buf, "toggle")) { |
| 387 | − card->ipato.enabled = (card->ipato.enabled)? 0 : 1; | |
| 388 | − } else if (sysfs_streq(buf, "1")) { | |
| 389 | − card->ipato.enabled = 1; | |
| 390 | − hash_for_each(card->ip_htable, i, addr, hnode) { | |
| 391 | − if ((addr->type == QETH_IP_TYPE_NORMAL) && | |
| 392 | − qeth_l3_is_addr_covered_by_ipato(card, addr)) | |
| 393 | − addr->set_flags |= | |
| 394 | − QETH_IPA_SETIP_TAKEOVER_FLAG; | |
| 395 | − } | |
| 396 | − } else if (sysfs_streq(buf, "0")) { | |
| 397 | − card->ipato.enabled = 0; | |
| 398 | − hash_for_each(card->ip_htable, i, addr, hnode) { | |
| 399 | − if (addr->set_flags & | |
| 400 | − QETH_IPA_SETIP_TAKEOVER_FLAG) | |
| 401 | − addr->set_flags &= | |
| 402 | − ~QETH_IPA_SETIP_TAKEOVER_FLAG; | |
| 403 | − } | |
| 404 | − } else | |
| 387 | + enable = !card->ipato.enabled; | |
| 388 | + } else if (kstrtobool(buf, &enable)) { | |
| 405 | 389 | rc = -EINVAL; |
| 390 | + goto out; | |
| 391 | + } | |
| 392 | + | |
| 393 | + if (card->ipato.enabled != enable) { | |
| 394 | + card->ipato.enabled = enable; | |
| 395 | + spin_lock_bh(&card->ip_lock); | |
| 396 | + qeth_l3_update_ipato(card); | |
| 397 | + spin_unlock_bh(&card->ip_lock); | |
| 398 | + } | |
| 406 | 399 | out: |
| 407 | 400 | mutex_unlock(&card->conf_mutex); |
| 408 | 401 | return rc ? rc : count; |
| @@ -428,20 +421,27 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, · 19 unmodified lines | ||
| 428 | 421 | const char *buf, size_t count) |
| 429 | 422 | { |
| 430 | 423 | struct qeth_card *card = dev_get_drvdata(dev); |
| 424 | + bool invert; | |
| 431 | 425 | int rc = 0; |
| 432 | 426 | |
| 433 | 427 | if (!card) |
| 434 | 428 | return -EINVAL; |
| 435 | 429 | |
| 436 | 430 | mutex_lock(&card->conf_mutex); |
| 437 | − if (sysfs_streq(buf, "toggle")) | |
| 438 | − card->ipato.invert4 = (card->ipato.invert4)? 0 : 1; | |
| 439 | − else if (sysfs_streq(buf, "1")) | |
| 440 | − card->ipato.invert4 = 1; | |
| 441 | − else if (sysfs_streq(buf, "0")) | |
| 442 | − card->ipato.invert4 = 0; | |
| 443 | − else | |
| 431 | + if (sysfs_streq(buf, "toggle")) { | |
| 432 | + invert = !card->ipato.invert4; | |
| 433 | + } else if (kstrtobool(buf, &invert)) { | |
| 444 | 434 | rc = -EINVAL; |
| 435 | + goto out; | |
| 436 | + } | |
| 437 | + | |
| 438 | + if (card->ipato.invert4 != invert) { | |
| 439 | + card->ipato.invert4 = invert; | |
| 440 | + spin_lock_bh(&card->ip_lock); | |
| 441 | + qeth_l3_update_ipato(card); | |
| 442 | + spin_unlock_bh(&card->ip_lock); | |
| 443 | + } | |
| 444 | +out: | |
| 445 | 445 | mutex_unlock(&card->conf_mutex); |
| 446 | 446 | return rc ? rc : count; |
| 447 | 447 | } |
| @@ -607,20 +607,27 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, · 159 unmodified lines | ||
| 607 | 607 | struct device_attribute *attr, const char *buf, size_t count) |
| 608 | 608 | { |
| 609 | 609 | struct qeth_card *card = dev_get_drvdata(dev); |
| 610 | + bool invert; | |
| 610 | 611 | int rc = 0; |
| 611 | 612 | |
| 612 | 613 | if (!card) |
| 613 | 614 | return -EINVAL; |
| 614 | 615 | |
| 615 | 616 | mutex_lock(&card->conf_mutex); |
| 616 | − if (sysfs_streq(buf, "toggle")) | |
| 617 | − card->ipato.invert6 = (card->ipato.invert6)? 0 : 1; | |
| 618 | − else if (sysfs_streq(buf, "1")) | |
| 619 | − card->ipato.invert6 = 1; | |
| 620 | − else if (sysfs_streq(buf, "0")) | |
| 621 | − card->ipato.invert6 = 0; | |
| 622 | − else | |
| 617 | + if (sysfs_streq(buf, "toggle")) { | |
| 618 | + invert = !card->ipato.invert6; | |
| 619 | + } else if (kstrtobool(buf, &invert)) { | |
| 623 | 620 | rc = -EINVAL; |
| 621 | + goto out; | |
| 622 | + } | |
| 623 | + | |
| 624 | + if (card->ipato.invert6 != invert) { | |
| 625 | + card->ipato.invert6 = invert; | |
| 626 | + spin_lock_bh(&card->ip_lock); | |
| 627 | + qeth_l3_update_ipato(card); | |
| 628 | + spin_unlock_bh(&card->ip_lock); | |
| 629 | + } | |
| 630 | +out: | |
| 624 | 631 | mutex_unlock(&card->conf_mutex); |
| 625 | 632 | return rc ? rc : count; |
| 626 | 633 | } |
| @@ -1725,6 +1725,7 @@ struct aac_dev · 1724 unmodified lines | ||
| 1725 | 1725 | #define FIB_CONTEXT_FLAG_NATIVE_HBA (0x00000010) |
| 1726 | 1726 | #define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF (0x00000020) |
| 1727 | 1727 | #define FIB_CONTEXT_FLAG_SCSI_CMD (0x00000040) |
| 1728 | +#define FIB_CONTEXT_FLAG_EH_RESET (0x00000080) | |
| 1728 | 1729 | |
| 1729 | 1730 | /* |
| 1730 | 1731 | * Define the command values |
| @@ -2482,8 +2482,8 @@ int aac_command_thread(void *data) · 2481 unmodified lines | ||
| 2482 | 2482 | /* Synchronize our watches */ |
| 2483 | 2483 | if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec) |
| 2484 | 2484 | && (now.tv_nsec > (NSEC_PER_SEC / HZ))) |
| 2485 | − difference = (((NSEC_PER_SEC - now.tv_nsec) * HZ) | |
| 2486 | − + NSEC_PER_SEC / 2) / NSEC_PER_SEC; | |
| 2485 | + difference = HZ + HZ / 2 - | |
| 2486 | + now.tv_nsec / (NSEC_PER_SEC / HZ); | |
| 2487 | 2487 | else { |
| 2488 | 2488 | if (now.tv_nsec > NSEC_PER_SEC / 2) |
| 2489 | 2489 | ++now.tv_sec; |
| @@ -2507,6 +2507,10 @@ int aac_command_thread(void *data) · 17 unmodified lines | ||
| 2507 | 2507 | if (kthread_should_stop()) |
| 2508 | 2508 | break; |
| 2509 | 2509 | |
| 2510 | + /* | |
| 2511 | + * we probably want usleep_range() here instead of the | |
| 2512 | + * jiffies computation | |
| 2513 | + */ | |
| 2510 | 2514 | schedule_timeout(difference); |
| 2511 | 2515 | |
| 2512 | 2516 | if (kthread_should_stop()) |
| @@ -1037,7 +1037,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd) · 1036 unmodified lines | ||
| 1037 | 1037 | info = &aac->hba_map[bus][cid]; |
| 1038 | 1038 | if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || |
| 1039 | 1039 | info->devtype != AAC_DEVTYPE_NATIVE_RAW) { |
| 1040 | − fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | |
| 1040 | + fib->flags |= FIB_CONTEXT_FLAG_EH_RESET; | |
| 1041 | 1041 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; |
| 1042 | 1042 | } |
| 1043 | 1043 | } |
| @@ -3135,7 +3135,8 @@ bfad_im_bsg_vendor_request(struct bsg_job *job) · 3134 unmodified lines | ||
| 3135 | 3135 | struct fc_bsg_request *bsg_request = job->request; |
| 3136 | 3136 | struct fc_bsg_reply *bsg_reply = job->reply; |
| 3137 | 3137 | uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; |
| 3138 | − struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job)); | |
| 3138 | + struct Scsi_Host *shost = fc_bsg_to_shost(job); | |
| 3139 | + struct bfad_im_port_s *im_port = bfad_get_im_port(shost); | |
| 3139 | 3140 | struct bfad_s *bfad = im_port->bfad; |
| 3140 | 3141 | void *payload_kbuf; |
| 3141 | 3142 | int rc = -EINVAL; |
| @@ -3350,7 +3351,8 @@ int · 208 unmodified lines | ||
| 3350 | 3351 | bfad_im_bsg_els_ct_request(struct bsg_job *job) |
| 3351 | 3352 | { |
| 3352 | 3353 | struct bfa_bsg_data *bsg_data; |
| 3353 | − struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job)); | |
| 3354 | + struct Scsi_Host *shost = fc_bsg_to_shost(job); | |
| 3355 | + struct bfad_im_port_s *im_port = bfad_get_im_port(shost); | |
| 3354 | 3356 | struct bfad_s *bfad = im_port->bfad; |
| 3355 | 3357 | bfa_bsg_fcpt_t *bsg_fcpt; |
| 3356 | 3358 | struct bfad_fcxp *drv_fcxp; |
| @@ -546,6 +546,7 @@ int · 545 unmodified lines | ||
| 546 | 546 | bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, |
| 547 | 547 | struct device *dev) |
| 548 | 548 | { |
| 549 | + struct bfad_im_port_pointer *im_portp; | |
| 549 | 550 | int error = 1; |
| 550 | 551 | |
| 551 | 552 | mutex_lock(&bfad_mutex); |
| @@ -564,7 +565,8 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, · 12 unmodified lines | ||
| 564 | 565 | goto out_free_idr; |
| 565 | 566 | } |
| 566 | 567 | |
| 567 | − im_port->shost->hostdata[0] = (unsigned long)im_port; | |
| 568 | + im_portp = shost_priv(im_port->shost); | |
| 569 | + im_portp->p = im_port; | |
| 568 | 570 | im_port->shost->unique_id = im_port->idr_id; |
| 569 | 571 | im_port->shost->this_id = -1; |
| 570 | 572 | im_port->shost->max_id = MAX_FCP_TARGET; |
| @@ -748,7 +750,7 @@ bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad) · 177 unmodified lines | ||
| 748 | 750 | |
| 749 | 751 | sht->sg_tablesize = bfad->cfg_data.io_max_sge; |
| 750 | 752 | |
| 751 | − return scsi_host_alloc(sht, sizeof(unsigned long)); | |
| 753 | + return scsi_host_alloc(sht, sizeof(struct bfad_im_port_pointer)); | |
| 752 | 754 | } |
| 753 | 755 | |
| 754 | 756 | void |
| @@ -69,6 +69,16 @@ struct bfad_im_port_s { · 68 unmodified lines | ||
| 69 | 69 | struct fc_vport *fc_vport; |
| 70 | 70 | }; |
| 71 | 71 | |
| 72 | +struct bfad_im_port_pointer { | |
| 73 | + struct bfad_im_port_s *p; | |
| 74 | +}; | |
| 75 | + | |
| 76 | +static inline struct bfad_im_port_s *bfad_get_im_port(struct Scsi_Host *host) | |
| 77 | +{ | |
| 78 | + struct bfad_im_port_pointer *im_portp = shost_priv(host); | |
| 79 | + return im_portp->p; | |
| 80 | +} | |
| 81 | + | |
| 72 | 82 | enum bfad_itnim_state { |
| 73 | 83 | ITNIM_STATE_NONE, |
| 74 | 84 | ITNIM_STATE_ONLINE, |
| @@ -904,10 +904,14 @@ static void fc_lport_recv_els_req(struct fc_lport *lport, · 903 unmodified lines | ||
| 904 | 904 | case ELS_FLOGI: |
| 905 | 905 | if (!lport->point_to_multipoint) |
| 906 | 906 | fc_lport_recv_flogi_req(lport, fp); |
| 907 | + else | |
| 908 | + fc_rport_recv_req(lport, fp); | |
| 907 | 909 | break; |
| 908 | 910 | case ELS_LOGO: |
| 909 | 911 | if (fc_frame_sid(fp) == FC_FID_FLOGI) |
| 910 | 912 | fc_lport_recv_logo_req(lport, fp); |
| 913 | + else | |
| 914 | + fc_rport_recv_req(lport, fp); | |
| 911 | 915 | break; |
| 912 | 916 | case ELS_RSCN: |
| 913 | 917 | lport->tt.disc_recv_req(lport, fp); |
| @@ -2145,7 +2145,7 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, · 2144 unmodified lines | ||
| 2145 | 2145 | struct sas_rphy *rphy) |
| 2146 | 2146 | { |
| 2147 | 2147 | struct domain_device *dev; |
| 2148 | − unsigned int reslen = 0; | |
| 2148 | + unsigned int rcvlen = 0; | |
| 2149 | 2149 | int ret = -EINVAL; |
| 2150 | 2150 | |
| 2151 | 2151 | /* no rphy means no smp target support (ie aic94xx host) */ |
| @@ -2179,12 +2179,12 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, · 27 unmodified lines | ||
| 2179 | 2179 | |
| 2180 | 2180 | ret = smp_execute_task_sg(dev, job->request_payload.sg_list, |
| 2181 | 2181 | job->reply_payload.sg_list); |
| 2182 | − if (ret > 0) { | |
| 2183 | − /* positive number is the untransferred residual */ | |
| 2184 | − reslen = ret; | |
| 2182 | + if (ret >= 0) { | |
| 2183 | + /* bsg_job_done() requires the length received */ | |
| 2184 | + rcvlen = job->reply_payload.payload_len - ret; | |
| 2185 | 2185 | ret = 0; |
| 2186 | 2186 | } |
| 2187 | 2187 | |
| 2188 | 2188 | out: |
| 2189 | − bsg_job_done(job, ret, reslen); | |
| 2189 | + bsg_job_done(job, ret, rcvlen); | |
| 2190 | 2190 | } |
| @@ -753,12 +753,12 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) · 752 unmodified lines | ||
| 753 | 753 | drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); |
| 754 | 754 | rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); |
| 755 | 755 | if (rc < 0) { |
| 756 | − (rqbp->rqb_free_buffer)(phba, rqb_entry); | |
| 757 | 756 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 758 | 757 | "6409 Cannot post to RQ %d: %x %x\n", |
| 759 | 758 | rqb_entry->hrq->queue_id, |
| 760 | 759 | rqb_entry->hrq->host_index, |
| 761 | 760 | rqb_entry->hrq->hba_index); |
| 761 | + (rqbp->rqb_free_buffer)(phba, rqb_entry); | |
| 762 | 762 | } else { |
| 763 | 763 | list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); |
| 764 | 764 | rqbp->buffer_count++; |
| @@ -1576,7 +1576,9 @@ static struct request *_make_request(struct request_queue *q, bool has_write, · 1575 unmodified lines | ||
| 1576 | 1576 | return req; |
| 1577 | 1577 | |
| 1578 | 1578 | for_each_bio(bio) { |
| 1579 | − ret = blk_rq_append_bio(req, bio); | |
| 1579 | + struct bio *bounce_bio = bio; | |
| 1580 | + | |
| 1581 | + ret = blk_rq_append_bio(req, &bounce_bio); | |
| 1580 | 1582 | if (ret) |
| 1581 | 1583 | return ERR_PTR(ret); |
| 1582 | 1584 | } |
| @@ -8,9 +8,11 @@ void scsi_show_rq(struct seq_file *m, struct request *rq) · 7 unmodified lines | ||
| 8 | 8 | { |
| 9 | 9 | struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req); |
| 10 | 10 | int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); |
| 11 | − char buf[80]; | |
| 11 | + const u8 *const cdb = READ_ONCE(cmd->cmnd); | |
| 12 | + char buf[80] = "(?)"; | |
| 12 | 13 | |
| 13 | − __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len); | |
| 14 | + if (cdb) | |
| 15 | + __scsi_format_command(buf, sizeof(buf), cdb, cmd->cmd_len); | |
| 14 | 16 | seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf, |
| 15 | 17 | cmd->retries, msecs / 1000, msecs % 1000); |
| 16 | 18 | } |
| @@ -34,7 +34,6 @@ struct scsi_dev_info_list_table { · 33 unmodified lines | ||
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | 36 | |
| 37 | −static const char spaces[] = " "; /* 16 of them */ | |
| 38 | 37 | static blist_flags_t scsi_default_dev_flags; |
| 39 | 38 | static LIST_HEAD(scsi_dev_info_list); |
| 40 | 39 | static char scsi_dev_flags[256]; |
| @@ -298,20 +297,13 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, · 257 unmodified lines | ||
| 298 | 297 | size_t from_length; |
| 299 | 298 | |
| 300 | 299 | from_length = strlen(from); |
| 301 | − strncpy(to, from, min(to_length, from_length)); | |
| 302 | − if (from_length < to_length) { | |
| 303 | − if (compatible) { | |
| 304 | − /* | |
| 305 | − * NUL terminate the string if it is short. | |
| 306 | − */ | |
| 307 | − to[from_length] = '\0'; | |
| 308 | − } else { | |
| 309 | − /* | |
| 310 | − * space pad the string if it is short. | |
| 311 | − */ | |
| 312 | − strncpy(&to[from_length], spaces, | |
| 313 | − to_length - from_length); | |
| 314 | − } | |
| 300 | + /* This zero-pads the destination */ | |
| 301 | + strncpy(to, from, to_length); | |
| 302 | + if (from_length < to_length && !compatible) { | |
| 303 | + /* | |
| 304 | + * space pad the string if it is short. | |
| 305 | + */ | |
| 306 | + memset(&to[from_length], ' ', to_length - from_length); | |
| 315 | 307 | } |
| 316 | 308 | if (from_length > to_length) |
| 317 | 309 | printk(KERN_WARNING "%s: %s string '%s' is too long\n", |
| @@ -382,10 +374,8 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, · 64 unmodified lines | ||
| 382 | 374 | model, compatible); |
| 383 | 375 | |
| 384 | 376 | if (strflags) |
| 385 | − devinfo->flags = simple_strtoul(strflags, NULL, 0); | |
| 386 | − else | |
| 387 | − devinfo->flags = flags; | |
| 388 | − | |
| 377 | + flags = (__force blist_flags_t)simple_strtoul(strflags, NULL, 0); | |
| 378 | + devinfo->flags = flags; | |
| 389 | 379 | devinfo->compatible = compatible; |
| 390 | 380 | |
| 391 | 381 | if (compatible) |
| @@ -458,7 +448,8 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, · 66 unmodified lines | ||
| 458 | 448 | /* |
| 459 | 449 | * vendor strings must be an exact match |
| 460 | 450 | */ |
| 461 | − if (vmax != strlen(devinfo->vendor) || | |
| 451 | + if (vmax != strnlen(devinfo->vendor, | |
| 452 | + sizeof(devinfo->vendor)) || | |
| 462 | 453 | memcmp(devinfo->vendor, vskip, vmax)) |
| 463 | 454 | continue; |
| 464 | 455 | |
| @@ -466,7 +457,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, · 1 unmodified line | ||
| 466 | 457 | * @model specifies the full string, and |
| 467 | 458 | * must be larger or equal to devinfo->model |
| 468 | 459 | */ |
| 469 | − mlen = strlen(devinfo->model); | |
| 460 | + mlen = strnlen(devinfo->model, sizeof(devinfo->model)); | |
| 470 | 461 | if (mmax < mlen || memcmp(devinfo->model, mskip, mlen)) |
| 471 | 462 | continue; |
| 472 | 463 | return devinfo; |
| @@ -1967,6 +1967,8 @@ static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) · 1966 unmodified lines | ||
| 1967 | 1967 | out_put_device: |
| 1968 | 1968 | put_device(&sdev->sdev_gendev); |
| 1969 | 1969 | out: |
| 1970 | + if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) | |
| 1971 | + blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); | |
| 1970 | 1972 | return false; |
| 1971 | 1973 | } |
| 1972 | 1974 | |
| @@ -770,7 +770,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, · 769 unmodified lines | ||
| 770 | 770 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
| 771 | 771 | **/ |
| 772 | 772 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, |
| 773 | − int *bflags, int async) | |
| 773 | + blist_flags_t *bflags, int async) | |
| 774 | 774 | { |
| 775 | 775 | int ret; |
| 776 | 776 | |
| @@ -1049,14 +1049,15 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq, · 272 unmodified lines | ||
| 1049 | 1049 | * - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
| 1050 | 1050 | **/ |
| 1051 | 1051 | static int scsi_probe_and_add_lun(struct scsi_target *starget, |
| 1052 | − u64 lun, int *bflagsp, | |
| 1052 | + u64 lun, blist_flags_t *bflagsp, | |
| 1053 | 1053 | struct scsi_device **sdevp, |
| 1054 | 1054 | enum scsi_scan_mode rescan, |
| 1055 | 1055 | void *hostdata) |
| 1056 | 1056 | { |
| 1057 | 1057 | struct scsi_device *sdev; |
| 1058 | 1058 | unsigned char *result; |
| 1059 | − int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256; | |
| 1059 | + blist_flags_t bflags; | |
| 1060 | + int res = SCSI_SCAN_NO_RESPONSE, result_len = 256; | |
| 1060 | 1061 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
| 1061 | 1062 | |
| 1062 | 1063 | /* |
| @@ -1201,7 +1202,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, · 138 unmodified lines | ||
| 1201 | 1202 | * Modifies sdevscan->lun. |
| 1202 | 1203 | **/ |
| 1203 | 1204 | static void scsi_sequential_lun_scan(struct scsi_target *starget, |
| 1204 | − int bflags, int scsi_level, | |
| 1205 | + blist_flags_t bflags, int scsi_level, | |
| 1205 | 1206 | enum scsi_scan_mode rescan) |
| 1206 | 1207 | { |
| 1207 | 1208 | uint max_dev_lun; |
| @@ -1292,7 +1293,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, · 84 unmodified lines | ||
| 1292 | 1293 | * 0: scan completed (or no memory, so further scanning is futile) |
| 1293 | 1294 | * 1: could not scan with REPORT LUN |
| 1294 | 1295 | **/ |
| 1295 | −static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, | |
| 1296 | +static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags, | |
| 1296 | 1297 | enum scsi_scan_mode rescan) |
| 1297 | 1298 | { |
| 1298 | 1299 | unsigned char scsi_cmd[MAX_COMMAND_SIZE]; |
| @@ -1538,7 +1539,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, · 239 unmodified lines | ||
| 1538 | 1539 | unsigned int id, u64 lun, enum scsi_scan_mode rescan) |
| 1539 | 1540 | { |
| 1540 | 1541 | struct Scsi_Host *shost = dev_to_shost(parent); |
| 1541 | − int bflags = 0; | |
| 1542 | + blist_flags_t bflags = 0; | |
| 1542 | 1543 | int res; |
| 1543 | 1544 | struct scsi_target *starget; |
| 1544 | 1545 | |
| @@ -967,7 +967,8 @@ sdev_show_wwid(struct device *dev, struct device_attribute *attr, · 966 unmodified lines | ||
| 967 | 967 | } |
| 968 | 968 | static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL); |
| 969 | 969 | |
| 970 | −#define BLIST_FLAG_NAME(name) [ilog2(BLIST_##name)] = #name | |
| 970 | +#define BLIST_FLAG_NAME(name) \ | |
| 971 | + [ilog2((__force unsigned int)BLIST_##name)] = #name | |
| 971 | 972 | static const char *const sdev_bflags_name[] = { |
| 972 | 973 | #include "scsi_devinfo_tbl.c" |
| 973 | 974 | }; |
| @@ -984,7 +985,7 @@ sdev_show_blacklist(struct device *dev, struct device_attribute *attr, · 10 unmodified lines | ||
| 984 | 985 | for (i = 0; i < sizeof(sdev->sdev_bflags) * BITS_PER_BYTE; i++) { |
| 985 | 986 | const char *name = NULL; |
| 986 | 987 | |
| 987 | − if (!(sdev->sdev_bflags & BIT(i))) | |
| 988 | + if (!(sdev->sdev_bflags & (__force blist_flags_t)BIT(i))) | |
| 988 | 989 | continue; |
| 989 | 990 | if (i < ARRAY_SIZE(sdev_bflags_name) && sdev_bflags_name[i]) |
| 990 | 991 | name = sdev_bflags_name[i]; |
| @@ -1414,7 +1415,10 @@ static void __scsi_remove_target(struct scsi_target *starget) · 423 unmodified lines | ||
| 1414 | 1415 | * check. |
| 1415 | 1416 | */ |
| 1416 | 1417 | if (sdev->channel != starget->channel || |
| 1417 | − sdev->id != starget->id || | |
| 1418 | + sdev->id != starget->id) | |
| 1419 | + continue; | |
| 1420 | + if (sdev->sdev_state == SDEV_DEL || | |
| 1421 | + sdev->sdev_state == SDEV_CANCEL || | |
| 1418 | 1422 | !get_device(&sdev->sdev_gendev)) |
| 1419 | 1423 | continue; |
| 1420 | 1424 | spin_unlock_irqrestore(shost->host_lock, flags); |
| @@ -50,14 +50,14 @@ · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | /* Our blacklist flags */ |
| 52 | 52 | enum { |
| 53 | − SPI_BLIST_NOIUS = 0x1, | |
| 53 | + SPI_BLIST_NOIUS = (__force blist_flags_t)0x1, | |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | 56 | /* blacklist table, modelled on scsi_devinfo.c */ |
| 57 | 57 | static struct { |
| 58 | 58 | char *vendor; |
| 59 | 59 | char *model; |
| 60 | − unsigned flags; | |
| 60 | + blist_flags_t flags; | |
| 61 | 61 | } spi_static_device_list[] __initdata = { |
| 62 | 62 | {"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS }, |
| 63 | 63 | {"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS }, |
| @@ -221,9 +221,11 @@ static int spi_device_configure(struct transport_container *tc, · 157 unmodified lines | ||
| 221 | 221 | { |
| 222 | 222 | struct scsi_device *sdev = to_scsi_device(dev); |
| 223 | 223 | struct scsi_target *starget = sdev->sdev_target; |
| 224 | − unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], | |
| 225 | − &sdev->inquiry[16], | |
| 226 | − SCSI_DEVINFO_SPI); | |
| 224 | + blist_flags_t bflags; | |
| 225 | + | |
| 226 | + bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], | |
| 227 | + &sdev->inquiry[16], | |
| 228 | + SCSI_DEVINFO_SPI); | |
| 227 | 229 | |
| 228 | 230 | /* Populate the target capability fields with the values |
| 229 | 231 | * gleaned from the device inquiry */ |
| @@ -1312,6 +1312,7 @@ static int sd_init_command(struct scsi_cmnd *cmd) · 1311 unmodified lines | ||
| 1312 | 1312 | static void sd_uninit_command(struct scsi_cmnd *SCpnt) |
| 1313 | 1313 | { |
| 1314 | 1314 | struct request *rq = SCpnt->request; |
| 1315 | + u8 *cmnd; | |
| 1315 | 1316 | |
| 1316 | 1317 | if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) |
| 1317 | 1318 | sd_zbc_write_unlock_zone(SCpnt); |
| @@ -1320,9 +1321,10 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt) · 2 unmodified lines | ||
| 1320 | 1321 | __free_page(rq->special_vec.bv_page); |
| 1321 | 1322 | |
| 1322 | 1323 | if (SCpnt->cmnd != scsi_req(rq)->cmd) { |
| 1323 | − mempool_free(SCpnt->cmnd, sd_cdb_pool); | |
| 1324 | + cmnd = SCpnt->cmnd; | |
| 1324 | 1325 | SCpnt->cmnd = NULL; |
| 1325 | 1326 | SCpnt->cmd_len = 0; |
| 1327 | + mempool_free(cmnd, sd_cdb_pool); | |
| 1326 | 1328 | } |
| 1327 | 1329 | } |
| 1328 | 1330 | |
| @@ -953,10 +953,11 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, · 952 unmodified lines | ||
| 953 | 953 | case TEST_UNIT_READY: |
| 954 | 954 | break; |
| 955 | 955 | default: |
| 956 | − set_host_byte(scmnd, DID_TARGET_FAILURE); | |
| 956 | + set_host_byte(scmnd, DID_ERROR); | |
| 957 | 957 | } |
| 958 | 958 | break; |
| 959 | 959 | case SRB_STATUS_INVALID_LUN: |
| 960 | + set_host_byte(scmnd, DID_NO_CONNECT); | |
| 960 | 961 | do_work = true; |
| 961 | 962 | process_err_fn = storvsc_remove_lun; |
| 962 | 963 | break; |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | #define A3700_SPI_BYTE_LEN BIT(5) |
| 80 | 80 | #define A3700_SPI_CLK_PRESCALE BIT(0) |
| 81 | 81 | #define A3700_SPI_CLK_PRESCALE_MASK (0x1f) |
| 82 | +#define A3700_SPI_CLK_EVEN_OFFS (0x10) | |
| 82 | 83 | |
| 83 | 84 | #define A3700_SPI_WFIFO_THRS_BIT 28 |
| 84 | 85 | #define A3700_SPI_RFIFO_THRS_BIT 24 |
| @@ -220,6 +221,13 @@ static void a3700_spi_clock_set(struct a3700_spi *a3700_spi, · 135 unmodified lines | ||
| 220 | 221 | |
| 221 | 222 | prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); |
| 222 | 223 | |
| 224 | + /* For prescaler values over 15, we can only set it by steps of 2. | |
| 225 | + * Starting from A3700_SPI_CLK_EVEN_OFFS, we set values from 0 up to | |
| 226 | + * 30. We only use this range from 16 to 30. | |
| 227 | + */ | |
| 228 | + if (prescale > 15) | |
| 229 | + prescale = A3700_SPI_CLK_EVEN_OFFS + DIV_ROUND_UP(prescale, 2); | |
| 230 | + | |
| 223 | 231 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); |
| 224 | 232 | val = val & ~A3700_SPI_CLK_PRESCALE_MASK; |
| 225 | 233 | |
| @@ -1661,12 +1661,12 @@ static int atmel_spi_remove(struct platform_device *pdev) · 1660 unmodified lines | ||
| 1661 | 1661 | pm_runtime_get_sync(&pdev->dev); |
| 1662 | 1662 | |
| 1663 | 1663 | /* reset the hardware and block queue progress */ |
| 1664 | − spin_lock_irq(&as->lock); | |
| 1665 | 1664 | if (as->use_dma) { |
| 1666 | 1665 | atmel_spi_stop_dma(master); |
| 1667 | 1666 | atmel_spi_release_dma(master); |
| 1668 | 1667 | } |
| 1669 | 1668 | |
| 1669 | + spin_lock_irq(&as->lock); | |
| 1670 | 1670 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 1671 | 1671 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| 1672 | 1672 | spi_readl(as, SR); |
| @@ -377,8 +377,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size) · 376 unmodified lines | ||
| 377 | 377 | /* Sets SPCMD */ |
| 378 | 378 | rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); |
| 379 | 379 | |
| 380 | − /* Enables SPI function in master mode */ | |
| 381 | − rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR); | |
| 380 | + /* Sets RSPI mode */ | |
| 381 | + rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); | |
| 382 | 382 | |
| 383 | 383 | return 0; |
| 384 | 384 | } |
| @@ -525,7 +525,7 @@ err_free_master: · 524 unmodified lines | ||
| 525 | 525 | |
| 526 | 526 | static int sun4i_spi_remove(struct platform_device *pdev) |
| 527 | 527 | { |
| 528 | − pm_runtime_disable(&pdev->dev); | |
| 528 | + pm_runtime_force_suspend(&pdev->dev); | |
| 529 | 529 | |
| 530 | 530 | return 0; |
| 531 | 531 | } |
| @@ -271,6 +271,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) · 270 unmodified lines | ||
| 271 | 271 | while (remaining_words) { |
| 272 | 272 | int n_words, tx_words, rx_words; |
| 273 | 273 | u32 sr; |
| 274 | + int stalled; | |
| 274 | 275 | |
| 275 | 276 | n_words = min(remaining_words, xspi->buffer_size); |
| 276 | 277 | |
| @@ -299,7 +300,17 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) · 22 unmodified lines | ||
| 299 | 300 | |
| 300 | 301 | /* Read out all the data from the Rx FIFO */ |
| 301 | 302 | rx_words = n_words; |
| 303 | + stalled = 10; | |
| 302 | 304 | while (rx_words) { |
| 305 | + if (rx_words == n_words && !(stalled--) && | |
| 306 | + !(sr & XSPI_SR_TX_EMPTY_MASK) && | |
| 307 | + (sr & XSPI_SR_RX_EMPTY_MASK)) { | |
| 308 | + dev_err(&spi->dev, | |
| 309 | + "Detected stall. Check C_SPI_MODE and C_SPI_MEMORY\n"); | |
| 310 | + xspi_init_hw(xspi); | |
| 311 | + return -EIO; | |
| 312 | + } | |
| 313 | + | |
| 303 | 314 | if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) { |
| 304 | 315 | xilinx_spi_rx(xspi); |
| 305 | 316 | rx_words--; |
| @@ -37,7 +37,7 @@ config ION_CHUNK_HEAP · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | config ION_CMA_HEAP |
| 39 | 39 | bool "Ion CMA heap support" |
| 40 | − depends on ION && CMA | |
| 40 | + depends on ION && DMA_CMA | |
| 41 | 41 | help |
| 42 | 42 | Choose this option to enable CMA heaps with Ion. This heap is backed |
| 43 | 43 | by the Contiguous Memory Allocator (CMA). If your system has these |
| @@ -346,7 +346,7 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, · 345 unmodified lines | ||
| 346 | 346 | mutex_lock(&buffer->lock); |
| 347 | 347 | list_for_each_entry(a, &buffer->attachments, list) { |
| 348 | 348 | dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, |
| 349 | − DMA_BIDIRECTIONAL); | |
| 349 | + direction); | |
| 350 | 350 | } |
| 351 | 351 | mutex_unlock(&buffer->lock); |
| 352 | 352 | |
| @@ -368,7 +368,7 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, · 15 unmodified lines | ||
| 368 | 368 | mutex_lock(&buffer->lock); |
| 369 | 369 | list_for_each_entry(a, &buffer->attachments, list) { |
| 370 | 370 | dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, |
| 371 | − DMA_BIDIRECTIONAL); | |
| 371 | + direction); | |
| 372 | 372 | } |
| 373 | 373 | mutex_unlock(&buffer->lock); |
| 374 | 374 | |
| @@ -39,9 +39,15 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, · 38 unmodified lines | ||
| 39 | 39 | struct ion_cma_heap *cma_heap = to_cma_heap(heap); |
| 40 | 40 | struct sg_table *table; |
| 41 | 41 | struct page *pages; |
| 42 | + unsigned long size = PAGE_ALIGN(len); | |
| 43 | + unsigned long nr_pages = size >> PAGE_SHIFT; | |
| 44 | + unsigned long align = get_order(size); | |
| 42 | 45 | int ret; |
| 43 | 46 | |
| 44 | − pages = cma_alloc(cma_heap->cma, len, 0, GFP_KERNEL); | |
| 47 | + if (align > CONFIG_CMA_ALIGNMENT) | |
| 48 | + align = CONFIG_CMA_ALIGNMENT; | |
| 49 | + | |
| 50 | + pages = cma_alloc(cma_heap->cma, nr_pages, align, GFP_KERNEL); | |
| 45 | 51 | if (!pages) |
| 46 | 52 | return -ENOMEM; |
| 47 | 53 | |
| @@ -53,7 +59,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, · 5 unmodified lines | ||
| 53 | 59 | if (ret) |
| 54 | 60 | goto free_mem; |
| 55 | 61 | |
| 56 | − sg_set_page(table->sgl, pages, len, 0); | |
| 62 | + sg_set_page(table->sgl, pages, size, 0); | |
| 57 | 63 | |
| 58 | 64 | buffer->priv_virt = pages; |
| 59 | 65 | buffer->sg_table = table; |
| @@ -62,7 +68,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, · 2 unmodified lines | ||
| 62 | 68 | free_mem: |
| 63 | 69 | kfree(table); |
| 64 | 70 | err: |
| 65 | − cma_release(cma_heap->cma, pages, buffer->size); | |
| 71 | + cma_release(cma_heap->cma, pages, nr_pages); | |
| 66 | 72 | return -ENOMEM; |
| 67 | 73 | } |
| 68 | 74 | |
| @@ -70,9 +76,10 @@ static void ion_cma_free(struct ion_buffer *buffer) · 1 unmodified line | ||
| 70 | 76 | { |
| 71 | 77 | struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); |
| 72 | 78 | struct page *pages = buffer->priv_virt; |
| 79 | + unsigned long nr_pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; | |
| 73 | 80 | |
| 74 | 81 | /* release memory */ |
| 75 | − cma_release(cma_heap->cma, pages, buffer->size); | |
| 82 | + cma_release(cma_heap->cma, pages, nr_pages); | |
| 76 | 83 | /* release sg table */ |
| 77 | 84 | sg_free_table(buffer->sg_table); |
| 78 | 85 | kfree(buffer->sg_table); |
| @@ -1769,7 +1769,7 @@ static int ssi_ahash_import(struct ahash_request *req, const void *in) · 1768 unmodified lines | ||
| 1769 | 1769 | struct device *dev = drvdata_to_dev(ctx->drvdata); |
| 1770 | 1770 | struct ahash_req_ctx *state = ahash_request_ctx(req); |
| 1771 | 1771 | u32 tmp; |
| 1772 | − int rc; | |
| 1772 | + int rc = 0; | |
| 1773 | 1773 | |
| 1774 | 1774 | memcpy(&tmp, in, sizeof(u32)); |
| 1775 | 1775 | if (tmp != CC_EXPORT_MAGIC) { |
| @@ -487,21 +487,18 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, · 486 unmodified lines | ||
| 487 | 487 | ksocknal_nid2peerlist(id.nid)); |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | − route2 = NULL; | |
| 491 | 490 | list_for_each_entry(route2, &peer->ksnp_routes, ksnr_list) { |
| 492 | − if (route2->ksnr_ipaddr == ipaddr) | |
| 493 | − break; | |
| 494 | − | |
| 495 | − route2 = NULL; | |
| 496 | − } | |
| 497 | − if (!route2) { | |
| 498 | − ksocknal_add_route_locked(peer, route); | |
| 499 | − route->ksnr_share_count++; | |
| 500 | − } else { | |
| 501 | − ksocknal_route_decref(route); | |
| 502 | − route2->ksnr_share_count++; | |
| 491 | + if (route2->ksnr_ipaddr == ipaddr) { | |
| 492 | + /* Route already exists, use the old one */ | |
| 493 | + ksocknal_route_decref(route); | |
| 494 | + route2->ksnr_share_count++; | |
| 495 | + goto out; | |
| 496 | + } | |
| 503 | 497 | } |
| 504 | − | |
| 498 | + /* Route doesn't already exist, add the new one */ | |
| 499 | + ksocknal_add_route_locked(peer, route); | |
| 500 | + route->ksnr_share_count++; | |
| 501 | +out: | |
| 505 | 502 | write_unlock_bh(&ksocknal_data.ksnd_global_lock); |
| 506 | 503 | |
| 507 | 504 | return 0; |
| @@ -102,7 +102,7 @@ enum modulation rf69_get_modulation(struct spi_device *spi) · 101 unmodified lines | ||
| 102 | 102 | |
| 103 | 103 | currentValue = READ_REG(REG_DATAMODUL); |
| 104 | 104 | |
| 105 | − switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE >> 3) { // TODO improvement: change 3 to define | |
| 105 | + switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE) { | |
| 106 | 106 | case DATAMODUL_MODULATION_TYPE_OOK: return OOK; |
| 107 | 107 | case DATAMODUL_MODULATION_TYPE_FSK: return FSK; |
| 108 | 108 | default: return undefined; |
| @@ -920,7 +920,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, · 919 unmodified lines | ||
| 920 | 920 | " %d i: %d bio: %p, allocating another" |
| 921 | 921 | " bio\n", bio->bi_vcnt, i, bio); |
| 922 | 922 | |
| 923 | − rc = blk_rq_append_bio(req, bio); | |
| 923 | + rc = blk_rq_append_bio(req, &bio); | |
| 924 | 924 | if (rc) { |
| 925 | 925 | pr_err("pSCSI: failed to append bio\n"); |
| 926 | 926 | goto fail; |
| @@ -938,7 +938,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, · 11 unmodified lines | ||
| 938 | 938 | } |
| 939 | 939 | |
| 940 | 940 | if (bio) { |
| 941 | − rc = blk_rq_append_bio(req, bio); | |
| 941 | + rc = blk_rq_append_bio(req, &bio); | |
| 942 | 942 | if (rc) { |
| 943 | 943 | pr_err("pSCSI: failed to append bio\n"); |
| 944 | 944 | goto fail; |
| @@ -339,7 +339,7 @@ static void __ring_interrupt(struct tb_ring *ring) · 338 unmodified lines | ||
| 339 | 339 | return; |
| 340 | 340 | |
| 341 | 341 | if (ring->start_poll) { |
| 342 | − __ring_interrupt_mask(ring, false); | |
| 342 | + __ring_interrupt_mask(ring, true); | |
| 343 | 343 | ring->start_poll(ring->poll_data); |
| 344 | 344 | } else { |
| 345 | 345 | schedule_work(&ring->work); |
| @@ -1762,7 +1762,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) · 1761 unmodified lines | ||
| 1762 | 1762 | { |
| 1763 | 1763 | struct n_tty_data *ldata = tty->disc_data; |
| 1764 | 1764 | |
| 1765 | − if (!old || (old->c_lflag ^ tty->termios.c_lflag) & ICANON) { | |
| 1765 | + if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) { | |
| 1766 | 1766 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); |
| 1767 | 1767 | ldata->line_start = ldata->read_tail; |
| 1768 | 1768 | if (!L_ICANON(tty) || !read_cnt(ldata)) { |
| @@ -2425,7 +2425,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, · 656 unmodified lines | ||
| 2425 | 2425 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); |
| 2426 | 2426 | case TIOCINQ: |
| 2427 | 2427 | down_write(&tty->termios_rwsem); |
| 2428 | − if (L_ICANON(tty)) | |
| 2428 | + if (L_ICANON(tty) && !L_EXTPROC(tty)) | |
| 2429 | 2429 | retval = inq_canon(ldata); |
| 2430 | 2430 | else |
| 2431 | 2431 | retval = read_cnt(ldata); |
| @@ -247,7 +247,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) · 246 unmodified lines | ||
| 247 | 247 | if (ret) |
| 248 | 248 | goto err_mux; |
| 249 | 249 | |
| 250 | − ulpi_node = of_find_node_by_name(of_node_get(pdev->dev.of_node), "ulpi"); | |
| 250 | + ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi"); | |
| 251 | 251 | if (ulpi_node) { |
| 252 | 252 | phy_node = of_get_next_available_child(ulpi_node, NULL); |
| 253 | 253 | ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); |
| @@ -555,6 +555,9 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, · 554 unmodified lines | ||
| 555 | 555 | unsigned iad_num = 0; |
| 556 | 556 | |
| 557 | 557 | memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); |
| 558 | + nintf = nintf_orig = config->desc.bNumInterfaces; | |
| 559 | + config->desc.bNumInterfaces = 0; // Adjusted later | |
| 560 | + | |
| 558 | 561 | if (config->desc.bDescriptorType != USB_DT_CONFIG || |
| 559 | 562 | config->desc.bLength < USB_DT_CONFIG_SIZE || |
| 560 | 563 | config->desc.bLength > size) { |
| @@ -568,7 +571,6 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, · 7 unmodified lines | ||
| 568 | 571 | buffer += config->desc.bLength; |
| 569 | 572 | size -= config->desc.bLength; |
| 570 | 573 | |
| 571 | − nintf = nintf_orig = config->desc.bNumInterfaces; | |
| 572 | 574 | if (nintf > USB_MAXINTERFACES) { |
| 573 | 575 | dev_warn(ddev, "config %d has too many interfaces: %d, " |
| 574 | 576 | "using maximum allowed: %d\n", |
| @@ -1005,7 +1007,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) · 430 unmodified lines | ||
| 1005 | 1007 | case USB_SSP_CAP_TYPE: |
| 1006 | 1008 | ssp_cap = (struct usb_ssp_cap_descriptor *)buffer; |
| 1007 | 1009 | ssac = (le32_to_cpu(ssp_cap->bmAttributes) & |
| 1008 | − USB_SSP_SUBLINK_SPEED_ATTRIBS) + 1; | |
| 1010 | + USB_SSP_SUBLINK_SPEED_ATTRIBS); | |
| 1009 | 1011 | if (length >= USB_DT_USB_SSP_CAP_SIZE(ssac)) |
| 1010 | 1012 | dev->bos->ssp_cap = ssp_cap; |
| 1011 | 1013 | break; |
| @@ -52,10 +52,11 @@ static const struct usb_device_id usb_quirk_list[] = { · 51 unmodified lines | ||
| 52 | 52 | /* Microsoft LifeCam-VX700 v2.0 */ |
| 53 | 53 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 54 | 54 | |
| 55 | − /* Logitech HD Pro Webcams C920, C920-C and C930e */ | |
| 55 | + /* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */ | |
| 56 | 56 | { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 57 | 57 | { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 58 | 58 | { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 59 | + { USB_DEVICE(0x046d, 0x085b), .driver_info = USB_QUIRK_DELAY_INIT }, | |
| 59 | 60 | |
| 60 | 61 | /* Logitech ConferenceCam CC3000e */ |
| 61 | 62 | { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT }, |
| @@ -149,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = { · 87 unmodified lines | ||
| 149 | 150 | /* Genesys Logic hub, internally used by KY-688 USB 3.1 Type-C Hub */ |
| 150 | 151 | { USB_DEVICE(0x05e3, 0x0612), .driver_info = USB_QUIRK_NO_LPM }, |
| 151 | 152 | |
| 153 | + /* ELSA MicroLink 56K */ | |
| 154 | + { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_RESET_RESUME }, | |
| 155 | + | |
| 152 | 156 | /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */ |
| 153 | 157 | { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM }, |
| 154 | 158 | |
| @@ -537,6 +537,7 @@ struct dwc2_core_params { · 536 unmodified lines | ||
| 537 | 537 | * 2 - Internal DMA |
| 538 | 538 | * @power_optimized Are power optimizations enabled? |
| 539 | 539 | * @num_dev_ep Number of device endpoints available |
| 540 | + * @num_dev_in_eps Number of device IN endpoints available | |
| 540 | 541 | * @num_dev_perio_in_ep Number of device periodic IN endpoints |
| 541 | 542 | * available |
| 542 | 543 | * @dev_token_q_depth Device Mode IN Token Sequence Learning Queue |
| @@ -565,6 +566,7 @@ struct dwc2_core_params { · 22 unmodified lines | ||
| 565 | 566 | * 2 - 8 or 16 bits |
| 566 | 567 | * @snpsid: Value from SNPSID register |
| 567 | 568 | * @dev_ep_dirs: Direction of device endpoints (GHWCFG1) |
| 569 | + * @g_tx_fifo_size[] Power-on values of TxFIFO sizes | |
| 568 | 570 | */ |
| 569 | 571 | struct dwc2_hw_params { |
| 570 | 572 | unsigned op_mode:3; |
| @@ -586,12 +588,14 @@ struct dwc2_hw_params { · 15 unmodified lines | ||
| 586 | 588 | unsigned fs_phy_type:2; |
| 587 | 589 | unsigned i2c_enable:1; |
| 588 | 590 | unsigned num_dev_ep:4; |
| 591 | + unsigned num_dev_in_eps : 4; | |
| 589 | 592 | unsigned num_dev_perio_in_ep:4; |
| 590 | 593 | unsigned total_fifo_size:16; |
| 591 | 594 | unsigned power_optimized:1; |
| 592 | 595 | unsigned utmi_phy_data_width:2; |
| 593 | 596 | u32 snpsid; |
| 594 | 597 | u32 dev_ep_dirs; |
| 598 | + u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; | |
| 595 | 599 | }; |
| 596 | 600 | |
| 597 | 601 | /* Size of control and EP0 buffers */ |
| @@ -195,55 +195,18 @@ int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg) · 194 unmodified lines | ||
| 195 | 195 | { |
| 196 | 196 | if (hsotg->hw_params.en_multiple_tx_fifo) |
| 197 | 197 | /* In dedicated FIFO mode we need count of IN EPs */ |
| 198 | − return (dwc2_readl(hsotg->regs + GHWCFG4) & | |
| 199 | − GHWCFG4_NUM_IN_EPS_MASK) >> GHWCFG4_NUM_IN_EPS_SHIFT; | |
| 198 | + return hsotg->hw_params.num_dev_in_eps; | |
| 200 | 199 | else |
| 201 | 200 | /* In shared FIFO mode we need count of Periodic IN EPs */ |
| 202 | 201 | return hsotg->hw_params.num_dev_perio_in_ep; |
| 203 | 202 | } |
| 204 | 203 | |
| 205 | −/** | |
| 206 | − * dwc2_hsotg_ep_info_size - return Endpoint Info Control block size in DWORDs | |
| 207 | − */ | |
| 208 | −static int dwc2_hsotg_ep_info_size(struct dwc2_hsotg *hsotg) | |
| 209 | −{ | |
| 210 | − int val = 0; | |
| 211 | − int i; | |
| 212 | − u32 ep_dirs; | |
| 213 | − | |
| 214 | − /* | |
| 215 | − * Don't need additional space for ep info control registers in | |
| 216 | − * slave mode. | |
| 217 | − */ | |
| 218 | − if (!using_dma(hsotg)) { | |
| 219 | − dev_dbg(hsotg->dev, "Buffer DMA ep info size 0\n"); | |
| 220 | − return 0; | |
| 221 | − } | |
| 222 | − | |
| 223 | − /* | |
| 224 | − * Buffer DMA mode - 1 location per endpoit | |
| 225 | − * Descriptor DMA mode - 4 locations per endpoint | |
| 226 | − */ | |
| 227 | − ep_dirs = hsotg->hw_params.dev_ep_dirs; | |
| 228 | − | |
| 229 | − for (i = 0; i <= hsotg->hw_params.num_dev_ep; i++) { | |
| 230 | − val += ep_dirs & 3 ? 1 : 2; | |
| 231 | − ep_dirs >>= 2; | |
| 232 | − } | |
| 233 | − | |
| 234 | − if (using_desc_dma(hsotg)) | |
| 235 | − val = val * 4; | |
| 236 | − | |
| 237 | − return val; | |
| 238 | −} | |
| 239 | − | |
| 240 | 204 | /** |
| 241 | 205 | * dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for |
| 242 | 206 | * device mode TX FIFOs |
| 243 | 207 | */ |
| 244 | 208 | int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) |
| 245 | 209 | { |
| 246 | − int ep_info_size; | |
| 247 | 210 | int addr; |
| 248 | 211 | int tx_addr_max; |
| 249 | 212 | u32 np_tx_fifo_size; |
| @@ -252,8 +215,7 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) · 2 unmodified lines | ||
| 252 | 215 | hsotg->params.g_np_tx_fifo_size); |
| 253 | 216 | |
| 254 | 217 | /* Get Endpoint Info Control block size in DWORDs. */ |
| 255 | − ep_info_size = dwc2_hsotg_ep_info_size(hsotg); | |
| 256 | − tx_addr_max = hsotg->hw_params.total_fifo_size - ep_info_size; | |
| 218 | + tx_addr_max = hsotg->hw_params.total_fifo_size; | |
| 257 | 219 | |
| 258 | 220 | addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size; |
| 259 | 221 | if (tx_addr_max <= addr) |
| @@ -484,8 +484,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg) · 483 unmodified lines | ||
| 484 | 484 | } |
| 485 | 485 | |
| 486 | 486 | for (fifo = 1; fifo <= fifo_count; fifo++) { |
| 487 | − dptxfszn = (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) & | |
| 488 | − FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; | |
| 487 | + dptxfszn = hsotg->hw_params.g_tx_fifo_size[fifo]; | |
| 489 | 488 | |
| 490 | 489 | if (hsotg->params.g_tx_fifo_size[fifo] < min || |
| 491 | 490 | hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) { |
| @@ -609,6 +608,7 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg) · 117 unmodified lines | ||
| 609 | 608 | struct dwc2_hw_params *hw = &hsotg->hw_params; |
| 610 | 609 | bool forced; |
| 611 | 610 | u32 gnptxfsiz; |
| 611 | + int fifo, fifo_count; | |
| 612 | 612 | |
| 613 | 613 | if (hsotg->dr_mode == USB_DR_MODE_HOST) |
| 614 | 614 | return; |
| @@ -617,6 +617,14 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg) · 2 unmodified lines | ||
| 617 | 617 | |
| 618 | 618 | gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); |
| 619 | 619 | |
| 620 | + fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); | |
| 621 | + | |
| 622 | + for (fifo = 1; fifo <= fifo_count; fifo++) { | |
| 623 | + hw->g_tx_fifo_size[fifo] = | |
| 624 | + (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) & | |
| 625 | + FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; | |
| 626 | + } | |
| 627 | + | |
| 620 | 628 | if (forced) |
| 621 | 629 | dwc2_clear_force_mode(hsotg); |
| 622 | 630 | |
| @@ -661,14 +669,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) · 38 unmodified lines | ||
| 661 | 669 | hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4); |
| 662 | 670 | grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); |
| 663 | 671 | |
| 664 | − /* | |
| 665 | − * Host specific hardware parameters. Reading these parameters | |
| 666 | − * requires the controller to be in host mode. The mode will | |
| 667 | − * be forced, if necessary, to read these values. | |
| 668 | − */ | |
| 669 | − dwc2_get_host_hwparams(hsotg); | |
| 670 | − dwc2_get_dev_hwparams(hsotg); | |
| 671 | − | |
| 672 | 672 | /* hwcfg1 */ |
| 673 | 673 | hw->dev_ep_dirs = hwcfg1; |
| 674 | 674 | |
| @@ -711,6 +711,8 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) · 36 unmodified lines | ||
| 711 | 711 | hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN); |
| 712 | 712 | hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >> |
| 713 | 713 | GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT; |
| 714 | + hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >> | |
| 715 | + GHWCFG4_NUM_IN_EPS_SHIFT; | |
| 714 | 716 | hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA); |
| 715 | 717 | hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ); |
| 716 | 718 | hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >> |
| @@ -719,6 +721,13 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) · 2 unmodified lines | ||
| 719 | 721 | /* fifo sizes */ |
| 720 | 722 | hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> |
| 721 | 723 | GRXFSIZ_DEPTH_SHIFT; |
| 724 | + /* | |
| 725 | + * Host specific hardware parameters. Reading these parameters | |
| 726 | + * requires the controller to be in host mode. The mode will | |
| 727 | + * be forced, if necessary, to read these values. | |
| 728 | + */ | |
| 729 | + dwc2_get_host_hwparams(hsotg); | |
| 730 | + dwc2_get_dev_hwparams(hsotg); | |
| 722 | 731 | |
| 723 | 732 | return 0; |
| 724 | 733 | } |
| @@ -51,8 +51,10 @@ static int dwc3_of_simple_clk_init(struct dwc3_of_simple *simple, int count) · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | clk = of_clk_get(np, i); |
| 53 | 53 | if (IS_ERR(clk)) { |
| 54 | − while (--i >= 0) | |
| 54 | + while (--i >= 0) { | |
| 55 | + clk_disable_unprepare(simple->clks[i]); | |
| 55 | 56 | clk_put(simple->clks[i]); |
| 57 | + } | |
| 56 | 58 | return PTR_ERR(clk); |
| 57 | 59 | } |
| 58 | 60 | |
| @@ -203,6 +205,7 @@ static struct platform_driver dwc3_of_simple_driver = { · 144 unmodified lines | ||
| 203 | 205 | .driver = { |
| 204 | 206 | .name = "dwc3-of-simple", |
| 205 | 207 | .of_match_table = of_dwc3_simple_match, |
| 208 | + .pm = &dwc3_of_simple_dev_pm_ops, | |
| 206 | 209 | }, |
| 207 | 210 | }; |
| 208 | 211 | |
| @@ -259,7 +259,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, · 258 unmodified lines | ||
| 259 | 259 | { |
| 260 | 260 | const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; |
| 261 | 261 | struct dwc3 *dwc = dep->dwc; |
| 262 | − u32 timeout = 500; | |
| 262 | + u32 timeout = 1000; | |
| 263 | 263 | u32 reg; |
| 264 | 264 | |
| 265 | 265 | int cmd_status = 0; |
| @@ -912,7 +912,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, · 646 unmodified lines | ||
| 912 | 912 | */ |
| 913 | 913 | if (speed == USB_SPEED_HIGH) { |
| 914 | 914 | struct usb_ep *ep = &dep->endpoint; |
| 915 | − unsigned int mult = ep->mult - 1; | |
| 915 | + unsigned int mult = 2; | |
| 916 | 916 | unsigned int maxp = usb_endpoint_maxp(ep->desc); |
| 917 | 917 | |
| 918 | 918 | if (length <= (2 * maxp)) |
| @@ -508,8 +508,8 @@ choice · 507 unmodified lines | ||
| 508 | 508 | controller, and the relevant drivers for each function declared |
| 509 | 509 | by the device. |
| 510 | 510 | |
| 511 | −endchoice | |
| 512 | − | |
| 513 | 511 | source "drivers/usb/gadget/legacy/Kconfig" |
| 514 | 512 | |
| 513 | +endchoice | |
| 514 | + | |
| 515 | 515 | endif # USB_GADGET |
| @@ -13,14 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). |
| 14 | 14 | # |
| 15 | 15 | |
| 16 | −menuconfig USB_GADGET_LEGACY | |
| 17 | − bool "Legacy USB Gadget Support" | |
| 18 | − help | |
| 19 | − Legacy USB gadgets are USB gadgets that do not use the USB gadget | |
| 20 | − configfs interface. | |
| 21 | − | |
| 22 | −if USB_GADGET_LEGACY | |
| 23 | − | |
| 24 | 16 | config USB_ZERO |
| 25 | 17 | tristate "Gadget Zero (DEVELOPMENT)" |
| 26 | 18 | select USB_LIBCOMPOSITE |
| @@ -487,7 +479,7 @@ endif · 460 unmodified lines | ||
| 487 | 479 | # or video class gadget drivers), or specific hardware, here. |
| 488 | 480 | config USB_G_WEBCAM |
| 489 | 481 | tristate "USB Webcam Gadget" |
| 490 | − depends on VIDEO_DEV | |
| 482 | + depends on VIDEO_V4L2 | |
| 491 | 483 | select USB_LIBCOMPOSITE |
| 492 | 484 | select VIDEOBUF2_VMALLOC |
| 493 | 485 | select USB_F_UVC |
| @@ -498,5 +490,3 @@ config USB_G_WEBCAM · 4 unmodified lines | ||
| 498 | 490 | |
| 499 | 491 | Say "y" to link the driver statically, or "m" to build a |
| 500 | 492 | dynamically linked module called "g_webcam". |
| 501 | − | |
| 502 | −endif | |
| @@ -162,7 +162,7 @@ static void xhci_debugfs_extcap_regset(struct xhci_hcd *xhci, int cap_id, · 161 unmodified lines | ||
| 162 | 162 | static int xhci_ring_enqueue_show(struct seq_file *s, void *unused) |
| 163 | 163 | { |
| 164 | 164 | dma_addr_t dma; |
| 165 | − struct xhci_ring *ring = s->private; | |
| 165 | + struct xhci_ring *ring = *(struct xhci_ring **)s->private; | |
| 166 | 166 | |
| 167 | 167 | dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); |
| 168 | 168 | seq_printf(s, "%pad\n", &dma); |
| @@ -173,7 +173,7 @@ static int xhci_ring_enqueue_show(struct seq_file *s, void *unused) · 4 unmodified lines | ||
| 173 | 173 | static int xhci_ring_dequeue_show(struct seq_file *s, void *unused) |
| 174 | 174 | { |
| 175 | 175 | dma_addr_t dma; |
| 176 | − struct xhci_ring *ring = s->private; | |
| 176 | + struct xhci_ring *ring = *(struct xhci_ring **)s->private; | |
| 177 | 177 | |
| 178 | 178 | dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
| 179 | 179 | seq_printf(s, "%pad\n", &dma); |
| @@ -183,7 +183,7 @@ static int xhci_ring_dequeue_show(struct seq_file *s, void *unused) · 3 unmodified lines | ||
| 183 | 183 | |
| 184 | 184 | static int xhci_ring_cycle_show(struct seq_file *s, void *unused) |
| 185 | 185 | { |
| 186 | − struct xhci_ring *ring = s->private; | |
| 186 | + struct xhci_ring *ring = *(struct xhci_ring **)s->private; | |
| 187 | 187 | |
| 188 | 188 | seq_printf(s, "%d\n", ring->cycle_state); |
| 189 | 189 | |
| @@ -346,7 +346,7 @@ static void xhci_debugfs_create_files(struct xhci_hcd *xhci, · 156 unmodified lines | ||
| 346 | 346 | } |
| 347 | 347 | |
| 348 | 348 | static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci, |
| 349 | − struct xhci_ring *ring, | |
| 349 | + struct xhci_ring **ring, | |
| 350 | 350 | const char *name, |
| 351 | 351 | struct dentry *parent) |
| 352 | 352 | { |
| @@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, · 34 unmodified lines | ||
| 387 | 387 | |
| 388 | 388 | snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); |
| 389 | 389 | epriv->root = xhci_debugfs_create_ring_dir(xhci, |
| 390 | − dev->eps[ep_index].new_ring, | |
| 390 | + &dev->eps[ep_index].new_ring, | |
| 391 | 391 | epriv->name, |
| 392 | 392 | spriv->root); |
| 393 | 393 | spriv->eps[ep_index] = epriv; |
| @@ -423,7 +423,7 @@ void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id) · 29 unmodified lines | ||
| 423 | 423 | priv->dev = dev; |
| 424 | 424 | dev->debugfs_private = priv; |
| 425 | 425 | |
| 426 | − xhci_debugfs_create_ring_dir(xhci, dev->eps[0].ring, | |
| 426 | + xhci_debugfs_create_ring_dir(xhci, &dev->eps[0].ring, | |
| 427 | 427 | "ep00", priv->root); |
| 428 | 428 | |
| 429 | 429 | xhci_debugfs_create_context_files(xhci, priv->root, slot_id); |
| @@ -488,11 +488,11 @@ void xhci_debugfs_init(struct xhci_hcd *xhci) · 58 unmodified lines | ||
| 488 | 488 | ARRAY_SIZE(xhci_extcap_dbc), |
| 489 | 489 | "reg-ext-dbc"); |
| 490 | 490 | |
| 491 | − xhci_debugfs_create_ring_dir(xhci, xhci->cmd_ring, | |
| 491 | + xhci_debugfs_create_ring_dir(xhci, &xhci->cmd_ring, | |
| 492 | 492 | "command-ring", |
| 493 | 493 | xhci->debugfs_root); |
| 494 | 494 | |
| 495 | − xhci_debugfs_create_ring_dir(xhci, xhci->event_ring, | |
| 495 | + xhci_debugfs_create_ring_dir(xhci, &xhci->event_ring, | |
| 496 | 496 | "event-ring", |
| 497 | 497 | xhci->debugfs_root); |
| 498 | 498 | |
| @@ -971,10 +971,9 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, · 970 unmodified lines | ||
| 971 | 971 | return 0; |
| 972 | 972 | } |
| 973 | 973 | |
| 974 | − xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags); | |
| 975 | − if (!xhci->devs[slot_id]) | |
| 974 | + dev = kzalloc(sizeof(*dev), flags); | |
| 975 | + if (!dev) | |
| 976 | 976 | return 0; |
| 977 | − dev = xhci->devs[slot_id]; | |
| 978 | 977 | |
| 979 | 978 | /* Allocate the (output) device context that will be used in the HC. */ |
| 980 | 979 | dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags); |
| @@ -1015,9 +1014,17 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, · 34 unmodified lines | ||
| 1015 | 1014 | |
| 1016 | 1015 | trace_xhci_alloc_virt_device(dev); |
| 1017 | 1016 | |
| 1017 | + xhci->devs[slot_id] = dev; | |
| 1018 | + | |
| 1018 | 1019 | return 1; |
| 1019 | 1020 | fail: |
| 1020 | − xhci_free_virt_device(xhci, slot_id); | |
| 1021 | + | |
| 1022 | + if (dev->in_ctx) | |
| 1023 | + xhci_free_container_ctx(xhci, dev->in_ctx); | |
| 1024 | + if (dev->out_ctx) | |
| 1025 | + xhci_free_container_ctx(xhci, dev->out_ctx); | |
| 1026 | + kfree(dev); | |
| 1027 | + | |
| 1021 | 1028 | return 0; |
| 1022 | 1029 | } |
| 1023 | 1030 | |
| @@ -177,6 +177,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 176 unmodified lines | ||
| 177 | 177 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
| 178 | 178 | xhci->quirks |= XHCI_BROKEN_STREAMS; |
| 179 | 179 | } |
| 180 | + if (pdev->vendor == PCI_VENDOR_ID_RENESAS && | |
| 181 | + pdev->device == 0x0014) | |
| 182 | + xhci->quirks |= XHCI_TRUST_TX_LENGTH; | |
| 180 | 183 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && |
| 181 | 184 | pdev->device == 0x0015) |
| 182 | 185 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| @@ -3112,7 +3112,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, · 3111 unmodified lines | ||
| 3112 | 3112 | { |
| 3113 | 3113 | u32 maxp, total_packet_count; |
| 3114 | 3114 | |
| 3115 | − /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */ | |
| 3115 | + /* MTK xHCI 0.96 contains some features from 1.0 */ | |
| 3116 | 3116 | if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST)) |
| 3117 | 3117 | return ((td_total_len - transferred) >> 10); |
| 3118 | 3118 | |
| @@ -3121,8 +3121,8 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, · 2 unmodified lines | ||
| 3121 | 3121 | trb_buff_len == td_total_len) |
| 3122 | 3122 | return 0; |
| 3123 | 3123 | |
| 3124 | − /* for MTK xHCI, TD size doesn't include this TRB */ | |
| 3125 | − if (xhci->quirks & XHCI_MTK_HOST) | |
| 3124 | + /* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */ | |
| 3125 | + if ((xhci->quirks & XHCI_MTK_HOST) && (xhci->hci_version < 0x100)) | |
| 3126 | 3126 | trb_buff_len = 0; |
| 3127 | 3127 | |
| 3128 | 3128 | maxp = usb_endpoint_maxp(&urb->ep->desc); |
| @@ -3525,8 +3525,6 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) · 3524 unmodified lines | ||
| 3525 | 3525 | struct xhci_slot_ctx *slot_ctx; |
| 3526 | 3526 | int i, ret; |
| 3527 | 3527 | |
| 3528 | − xhci_debugfs_remove_slot(xhci, udev->slot_id); | |
| 3529 | − | |
| 3530 | 3528 | #ifndef CONFIG_USB_DEFAULT_PERSIST |
| 3531 | 3529 | /* |
| 3532 | 3530 | * We called pm_runtime_get_noresume when the device was attached. |
| @@ -3555,8 +3553,10 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) · 22 unmodified lines | ||
| 3555 | 3553 | } |
| 3556 | 3554 | |
| 3557 | 3555 | ret = xhci_disable_slot(xhci, udev->slot_id); |
| 3558 | − if (ret) | |
| 3556 | + if (ret) { | |
| 3557 | + xhci_debugfs_remove_slot(xhci, udev->slot_id); | |
| 3559 | 3558 | xhci_free_virt_device(xhci, udev->slot_id); |
| 3559 | + } | |
| 3560 | 3560 | } |
| 3561 | 3561 | |
| 3562 | 3562 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) |
| @@ -284,7 +284,15 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) · 283 unmodified lines | ||
| 284 | 284 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
| 285 | 285 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); |
| 286 | 286 | del_timer(&musb->dev_timer); |
| 287 | − } else { | |
| 287 | + } else if (!(musb->int_usb & MUSB_INTR_BABBLE)) { | |
| 288 | + /* | |
| 289 | + * When babble condition happens, drvvbus interrupt | |
| 290 | + * is also generated. Ignore this drvvbus interrupt | |
| 291 | + * and let babble interrupt handler recovers the | |
| 292 | + * controller; otherwise, the host-mode flag is lost | |
| 293 | + * due to the MUSB_DEV_MODE() call below and babble | |
| 294 | + * recovery logic will not be called. | |
| 295 | + */ | |
| 288 | 296 | musb->is_active = 0; |
| 289 | 297 | MUSB_DEV_MODE(musb); |
| 290 | 298 | otg->default_a = 0; |
| @@ -1013,6 +1013,7 @@ static const struct usb_device_id id_table_combined[] = { · 1012 unmodified lines | ||
| 1013 | 1013 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 1014 | 1014 | { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, |
| 1015 | 1015 | { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, |
| 1016 | + { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) }, | |
| 1016 | 1017 | { } /* Terminating entry */ |
| 1017 | 1018 | }; |
| 1018 | 1019 | |
| @@ -914,6 +914,12 @@ · 913 unmodified lines | ||
| 914 | 914 | #define ICPDAS_I7561U_PID 0x0104 |
| 915 | 915 | #define ICPDAS_I7563U_PID 0x0105 |
| 916 | 916 | |
| 917 | +/* | |
| 918 | + * Airbus Defence and Space | |
| 919 | + */ | |
| 920 | +#define AIRBUS_DS_VID 0x1e8e /* Vendor ID */ | |
| 921 | +#define AIRBUS_DS_P8GR 0x6001 /* Tetra P8GR */ | |
| 922 | + | |
| 917 | 923 | /* |
| 918 | 924 | * RT Systems programming cables for various ham radios |
| 919 | 925 | */ |
| @@ -233,6 +233,8 @@ static void option_instat_callback(struct urb *urb); · 232 unmodified lines | ||
| 233 | 233 | /* These Quectel products use Qualcomm's vendor ID */ |
| 234 | 234 | #define QUECTEL_PRODUCT_UC20 0x9003 |
| 235 | 235 | #define QUECTEL_PRODUCT_UC15 0x9090 |
| 236 | +/* These Yuga products use Qualcomm's vendor ID */ | |
| 237 | +#define YUGA_PRODUCT_CLM920_NC5 0x9625 | |
| 236 | 238 | |
| 237 | 239 | #define QUECTEL_VENDOR_ID 0x2c7c |
| 238 | 240 | /* These Quectel products use Quectel's vendor ID */ |
| @@ -280,6 +282,7 @@ static void option_instat_callback(struct urb *urb); · 41 unmodified lines | ||
| 280 | 282 | #define TELIT_PRODUCT_LE922_USBCFG3 0x1043 |
| 281 | 283 | #define TELIT_PRODUCT_LE922_USBCFG5 0x1045 |
| 282 | 284 | #define TELIT_PRODUCT_ME910 0x1100 |
| 285 | +#define TELIT_PRODUCT_ME910_DUAL_MODEM 0x1101 | |
| 283 | 286 | #define TELIT_PRODUCT_LE920 0x1200 |
| 284 | 287 | #define TELIT_PRODUCT_LE910 0x1201 |
| 285 | 288 | #define TELIT_PRODUCT_LE910_USBCFG4 0x1206 |
| @@ -645,6 +648,11 @@ static const struct option_blacklist_info telit_me910_blacklist = { · 359 unmodified lines | ||
| 645 | 648 | .reserved = BIT(1) | BIT(3), |
| 646 | 649 | }; |
| 647 | 650 | |
| 651 | +static const struct option_blacklist_info telit_me910_dual_modem_blacklist = { | |
| 652 | + .sendsetup = BIT(0), | |
| 653 | + .reserved = BIT(3), | |
| 654 | +}; | |
| 655 | + | |
| 648 | 656 | static const struct option_blacklist_info telit_le910_blacklist = { |
| 649 | 657 | .sendsetup = BIT(0), |
| 650 | 658 | .reserved = BIT(1) | BIT(2), |
| @@ -674,6 +682,10 @@ static const struct option_blacklist_info cinterion_rmnet2_blacklist = { · 23 unmodified lines | ||
| 674 | 682 | .reserved = BIT(4) | BIT(5), |
| 675 | 683 | }; |
| 676 | 684 | |
| 685 | +static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { | |
| 686 | + .reserved = BIT(1) | BIT(4), | |
| 687 | +}; | |
| 688 | + | |
| 677 | 689 | static const struct usb_device_id option_ids[] = { |
| 678 | 690 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 679 | 691 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -1178,6 +1190,9 @@ static const struct usb_device_id option_ids[] = { · 498 unmodified lines | ||
| 1178 | 1190 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, |
| 1179 | 1191 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), |
| 1180 | 1192 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 1193 | + /* Yuga products use Qualcomm vendor ID */ | |
| 1194 | + { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), | |
| 1195 | + .driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist }, | |
| 1181 | 1196 | /* Quectel products using Quectel vendor ID */ |
| 1182 | 1197 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), |
| 1183 | 1198 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| @@ -1244,6 +1259,8 @@ static const struct usb_device_id option_ids[] = { · 60 unmodified lines | ||
| 1244 | 1259 | .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, |
| 1245 | 1260 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), |
| 1246 | 1261 | .driver_info = (kernel_ulong_t)&telit_me910_blacklist }, |
| 1262 | + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), | |
| 1263 | + .driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist }, | |
| 1247 | 1264 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), |
| 1248 | 1265 | .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, |
| 1249 | 1266 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), |
| @@ -162,6 +162,8 @@ static const struct usb_device_id id_table[] = { · 161 unmodified lines | ||
| 162 | 162 | {DEVICE_SWI(0x1199, 0x9079)}, /* Sierra Wireless EM74xx */ |
| 163 | 163 | {DEVICE_SWI(0x1199, 0x907a)}, /* Sierra Wireless EM74xx QDL */ |
| 164 | 164 | {DEVICE_SWI(0x1199, 0x907b)}, /* Sierra Wireless EM74xx */ |
| 165 | + {DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */ | |
| 166 | + {DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */ | |
| 165 | 167 | {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ |
| 166 | 168 | {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ |
| 167 | 169 | {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ |
| @@ -342,6 +344,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) · 174 unmodified lines | ||
| 342 | 344 | break; |
| 343 | 345 | case 2: |
| 344 | 346 | dev_dbg(dev, "NMEA GPS interface found\n"); |
| 347 | + sendsetup = true; | |
| 345 | 348 | break; |
| 346 | 349 | case 3: |
| 347 | 350 | dev_dbg(dev, "Modem port found\n"); |
| @@ -2100,6 +2100,13 @@ UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0116, · 2099 unmodified lines | ||
| 2100 | 2100 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 2101 | 2101 | US_FL_BROKEN_FUA ), |
| 2102 | 2102 | |
| 2103 | +/* Reported by David Kozub <zub@linux.fjfi.cvut.cz> */ | |
| 2104 | +UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, | |
| 2105 | + "JMicron", | |
| 2106 | + "JMS567", | |
| 2107 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 2108 | + US_FL_BROKEN_FUA), | |
| 2109 | + | |
| 2103 | 2110 | /* |
| 2104 | 2111 | * Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br> |
| 2105 | 2112 | * JMicron responds to USN and several other SCSI ioctls with a |
| @@ -129,6 +129,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, · 128 unmodified lines | ||
| 129 | 129 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 130 | 130 | US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES), |
| 131 | 131 | |
| 132 | +/* Reported-by: David Kozub <zub@linux.fjfi.cvut.cz> */ | |
| 133 | +UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, | |
| 134 | + "JMicron", | |
| 135 | + "JMS567", | |
| 136 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 137 | + US_FL_BROKEN_FUA), | |
| 138 | + | |
| 132 | 139 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ |
| 133 | 140 | UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, |
| 134 | 141 | "VIA", |
| @@ -149,8 +149,7 @@ static void stub_shutdown_connection(struct usbip_device *ud) · 148 unmodified lines | ||
| 149 | 149 | * step 1? |
| 150 | 150 | */ |
| 151 | 151 | if (ud->tcp_socket) { |
| 152 | − dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n", | |
| 153 | − ud->tcp_socket); | |
| 152 | + dev_dbg(&sdev->udev->dev, "shutdown sockfd %d\n", ud->sockfd); | |
| 154 | 153 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); |
| 155 | 154 | } |
| 156 | 155 | |
| @@ -237,11 +237,12 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) · 236 unmodified lines | ||
| 237 | 237 | struct stub_priv *priv; |
| 238 | 238 | struct urb *urb; |
| 239 | 239 | |
| 240 | − dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); | |
| 240 | + dev_dbg(&sdev->udev->dev, "Stub device cleaning up urbs\n"); | |
| 241 | 241 | |
| 242 | 242 | while ((priv = stub_priv_pop(sdev))) { |
| 243 | 243 | urb = priv->urb; |
| 244 | − dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); | |
| 244 | + dev_dbg(&sdev->udev->dev, "free urb seqnum %lu\n", | |
| 245 | + priv->seqnum); | |
| 245 | 246 | usb_kill_urb(urb); |
| 246 | 247 | |
| 247 | 248 | kmem_cache_free(stub_priv_cache, priv); |
| @@ -211,9 +211,6 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev, · 210 unmodified lines | ||
| 211 | 211 | if (priv->seqnum != pdu->u.cmd_unlink.seqnum) |
| 212 | 212 | continue; |
| 213 | 213 | |
| 214 | − dev_info(&priv->urb->dev->dev, "unlink urb %p\n", | |
| 215 | − priv->urb); | |
| 216 | − | |
| 217 | 214 | /* |
| 218 | 215 | * This matched urb is not completed yet (i.e., be in |
| 219 | 216 | * flight in usb hcd hardware/driver). Now we are |
| @@ -252,8 +249,8 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev, · 32 unmodified lines | ||
| 252 | 249 | ret = usb_unlink_urb(priv->urb); |
| 253 | 250 | if (ret != -EINPROGRESS) |
| 254 | 251 | dev_err(&priv->urb->dev->dev, |
| 255 | − "failed to unlink a urb %p, ret %d\n", | |
| 256 | − priv->urb, ret); | |
| 252 | + "failed to unlink a urb # %lu, ret %d\n", | |
| 253 | + priv->seqnum, ret); | |
| 257 | 254 | |
| 258 | 255 | return 0; |
| 259 | 256 | } |
| @@ -322,23 +319,26 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, · 62 unmodified lines | ||
| 322 | 319 | return priv; |
| 323 | 320 | } |
| 324 | 321 | |
| 325 | −static int get_pipe(struct stub_device *sdev, int epnum, int dir) | |
| 322 | +static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) | |
| 326 | 323 | { |
| 327 | 324 | struct usb_device *udev = sdev->udev; |
| 328 | 325 | struct usb_host_endpoint *ep; |
| 329 | 326 | struct usb_endpoint_descriptor *epd = NULL; |
| 327 | + int epnum = pdu->base.ep; | |
| 328 | + int dir = pdu->base.direction; | |
| 329 | + | |
| 330 | + if (epnum < 0 || epnum > 15) | |
| 331 | + goto err_ret; | |
| 330 | 332 | |
| 331 | 333 | if (dir == USBIP_DIR_IN) |
| 332 | 334 | ep = udev->ep_in[epnum & 0x7f]; |
| 333 | 335 | else |
| 334 | 336 | ep = udev->ep_out[epnum & 0x7f]; |
| 335 | − if (!ep) { | |
| 336 | − dev_err(&sdev->udev->dev, "no such endpoint?, %d\n", | |
| 337 | − epnum); | |
| 338 | − BUG(); | |
| 339 | − } | |
| 337 | + if (!ep) | |
| 338 | + goto err_ret; | |
| 340 | 339 | |
| 341 | 340 | epd = &ep->desc; |
| 341 | + | |
| 342 | 342 | if (usb_endpoint_xfer_control(epd)) { |
| 343 | 343 | if (dir == USBIP_DIR_OUT) |
| 344 | 344 | return usb_sndctrlpipe(udev, epnum); |
| @@ -361,15 +361,31 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir) · 16 unmodified lines | ||
| 361 | 361 | } |
| 362 | 362 | |
| 363 | 363 | if (usb_endpoint_xfer_isoc(epd)) { |
| 364 | + /* validate packet size and number of packets */ | |
| 365 | + unsigned int maxp, packets, bytes; | |
| 366 | + | |
| 367 | + maxp = usb_endpoint_maxp(epd); | |
| 368 | + maxp *= usb_endpoint_maxp_mult(epd); | |
| 369 | + bytes = pdu->u.cmd_submit.transfer_buffer_length; | |
| 370 | + packets = DIV_ROUND_UP(bytes, maxp); | |
| 371 | + | |
| 372 | + if (pdu->u.cmd_submit.number_of_packets < 0 || | |
| 373 | + pdu->u.cmd_submit.number_of_packets > packets) { | |
| 374 | + dev_err(&sdev->udev->dev, | |
| 375 | + "CMD_SUBMIT: isoc invalid num packets %d\n", | |
| 376 | + pdu->u.cmd_submit.number_of_packets); | |
| 377 | + return -1; | |
| 378 | + } | |
| 364 | 379 | if (dir == USBIP_DIR_OUT) |
| 365 | 380 | return usb_sndisocpipe(udev, epnum); |
| 366 | 381 | else |
| 367 | 382 | return usb_rcvisocpipe(udev, epnum); |
| 368 | 383 | } |
| 369 | 384 | |
| 385 | +err_ret: | |
| 370 | 386 | /* NOT REACHED */ |
| 371 | − dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum); | |
| 372 | − return 0; | |
| 387 | + dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum); | |
| 388 | + return -1; | |
| 373 | 389 | } |
| 374 | 390 | |
| 375 | 391 | static void masking_bogus_flags(struct urb *urb) |
| @@ -433,7 +449,10 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, · 57 unmodified lines | ||
| 433 | 449 | struct stub_priv *priv; |
| 434 | 450 | struct usbip_device *ud = &sdev->ud; |
| 435 | 451 | struct usb_device *udev = sdev->udev; |
| 436 | − int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); | |
| 452 | + int pipe = get_pipe(sdev, pdu); | |
| 453 | + | |
| 454 | + if (pipe == -1) | |
| 455 | + return; | |
| 437 | 456 | |
| 438 | 457 | priv = stub_priv_alloc(sdev, pdu); |
| 439 | 458 | if (!priv) |
| @@ -88,7 +88,7 @@ void stub_complete(struct urb *urb) · 87 unmodified lines | ||
| 88 | 88 | /* link a urb to the queue of tx. */ |
| 89 | 89 | spin_lock_irqsave(&sdev->priv_lock, flags); |
| 90 | 90 | if (sdev->ud.tcp_socket == NULL) { |
| 91 | − usbip_dbg_stub_tx("ignore urb for closed connection %p", urb); | |
| 91 | + usbip_dbg_stub_tx("ignore urb for closed connection\n"); | |
| 92 | 92 | /* It will be freed in stub_device_cleanup_urbs(). */ |
| 93 | 93 | } else if (priv->unlinking) { |
| 94 | 94 | stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); |
| @@ -167,6 +167,13 @@ static int stub_send_ret_submit(struct stub_device *sdev) · 72 unmodified lines | ||
| 167 | 167 | memset(&pdu_header, 0, sizeof(pdu_header)); |
| 168 | 168 | memset(&msg, 0, sizeof(msg)); |
| 169 | 169 | |
| 170 | + if (urb->actual_length > 0 && !urb->transfer_buffer) { | |
| 171 | + dev_err(&sdev->udev->dev, | |
| 172 | + "urb: actual_length %d transfer_buffer null\n", | |
| 173 | + urb->actual_length); | |
| 174 | + return -1; | |
| 175 | + } | |
| 176 | + | |
| 170 | 177 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) |
| 171 | 178 | iovnum = 2 + urb->number_of_packets; |
| 172 | 179 | else |
| @@ -183,8 +190,8 @@ static int stub_send_ret_submit(struct stub_device *sdev) · 10 unmodified lines | ||
| 183 | 190 | |
| 184 | 191 | /* 1. setup usbip_header */ |
| 185 | 192 | setup_ret_submit_pdu(&pdu_header, urb); |
| 186 | − usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", | |
| 187 | − pdu_header.base.seqnum, urb); | |
| 193 | + usbip_dbg_stub_tx("setup txdata seqnum: %d\n", | |
| 194 | + pdu_header.base.seqnum); | |
| 188 | 195 | usbip_header_correct_endian(&pdu_header, 1); |
| 189 | 196 | |
| 190 | 197 | iov[iovnum].iov_base = &pdu_header; |
| @@ -317,26 +317,20 @@ int usbip_recv(struct socket *sock, void *buf, int size) · 316 unmodified lines | ||
| 317 | 317 | struct msghdr msg = {.msg_flags = MSG_NOSIGNAL}; |
| 318 | 318 | int total = 0; |
| 319 | 319 | |
| 320 | + if (!sock || !buf || !size) | |
| 321 | + return -EINVAL; | |
| 322 | + | |
| 320 | 323 | iov_iter_kvec(&msg.msg_iter, READ|ITER_KVEC, &iov, 1, size); |
| 321 | 324 | |
| 322 | 325 | usbip_dbg_xmit("enter\n"); |
| 323 | 326 | |
| 324 | − if (!sock || !buf || !size) { | |
| 325 | − pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, | |
| 326 | − size); | |
| 327 | − return -EINVAL; | |
| 328 | − } | |
| 329 | − | |
| 330 | 327 | do { |
| 331 | − int sz = msg_data_left(&msg); | |
| 328 | + msg_data_left(&msg); | |
| 332 | 329 | sock->sk->sk_allocation = GFP_NOIO; |
| 333 | 330 | |
| 334 | 331 | result = sock_recvmsg(sock, &msg, MSG_WAITALL); |
| 335 | − if (result <= 0) { | |
| 336 | − pr_debug("receive sock %p buf %p size %u ret %d total %d\n", | |
| 337 | − sock, buf + total, sz, result, total); | |
| 332 | + if (result <= 0) | |
| 338 | 333 | goto err; |
| 339 | − } | |
| 340 | 334 | |
| 341 | 335 | total += result; |
| 342 | 336 | } while (msg_data_left(&msg)); |
| @@ -256,6 +256,7 @@ struct usbip_device { · 255 unmodified lines | ||
| 256 | 256 | /* lock for status */ |
| 257 | 257 | spinlock_t lock; |
| 258 | 258 | |
| 259 | + int sockfd; | |
| 259 | 260 | struct socket *tcp_socket; |
| 260 | 261 | |
| 261 | 262 | struct task_struct *tcp_rx; |
| @@ -656,9 +656,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag · 655 unmodified lines | ||
| 656 | 656 | struct vhci_device *vdev; |
| 657 | 657 | unsigned long flags; |
| 658 | 658 | |
| 659 | − usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", | |
| 660 | − hcd, urb, mem_flags); | |
| 661 | − | |
| 662 | 659 | if (portnum > VHCI_HC_PORTS) { |
| 663 | 660 | pr_err("invalid port number %d\n", portnum); |
| 664 | 661 | return -ENODEV; |
| @@ -822,8 +819,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 157 unmodified lines | ||
| 822 | 819 | struct vhci_device *vdev; |
| 823 | 820 | unsigned long flags; |
| 824 | 821 | |
| 825 | − pr_info("dequeue a urb %p\n", urb); | |
| 826 | − | |
| 827 | 822 | spin_lock_irqsave(&vhci->lock, flags); |
| 828 | 823 | |
| 829 | 824 | priv = urb->hcpriv; |
| @@ -851,7 +846,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 21 unmodified lines | ||
| 851 | 846 | /* tcp connection is closed */ |
| 852 | 847 | spin_lock(&vdev->priv_lock); |
| 853 | 848 | |
| 854 | − pr_info("device %p seems to be disconnected\n", vdev); | |
| 855 | 849 | list_del(&priv->list); |
| 856 | 850 | kfree(priv); |
| 857 | 851 | urb->hcpriv = NULL; |
| @@ -863,8 +857,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 5 unmodified lines | ||
| 863 | 857 | * vhci_rx will receive RET_UNLINK and give back the URB. |
| 864 | 858 | * Otherwise, we give back it here. |
| 865 | 859 | */ |
| 866 | − pr_info("gives back urb %p\n", urb); | |
| 867 | − | |
| 868 | 860 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
| 869 | 861 | |
| 870 | 862 | spin_unlock_irqrestore(&vhci->lock, flags); |
| @@ -892,8 +884,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 21 unmodified lines | ||
| 892 | 884 | |
| 893 | 885 | unlink->unlink_seqnum = priv->seqnum; |
| 894 | 886 | |
| 895 | − pr_info("device %p seems to be still connected\n", vdev); | |
| 896 | − | |
| 897 | 887 | /* send cmd_unlink and try to cancel the pending URB in the |
| 898 | 888 | * peer */ |
| 899 | 889 | list_add_tail(&unlink->list, &vdev->unlink_tx); |
| @@ -975,7 +965,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) · 75 unmodified lines | ||
| 975 | 965 | |
| 976 | 966 | /* need this? see stub_dev.c */ |
| 977 | 967 | if (ud->tcp_socket) { |
| 978 | − pr_debug("shutdown tcp_socket %p\n", ud->tcp_socket); | |
| 968 | + pr_debug("shutdown tcp_socket %d\n", ud->sockfd); | |
| 979 | 969 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); |
| 980 | 970 | } |
| 981 | 971 | |
| @@ -23,24 +23,23 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum) · 22 unmodified lines | ||
| 23 | 23 | urb = priv->urb; |
| 24 | 24 | status = urb->status; |
| 25 | 25 | |
| 26 | − usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", | |
| 27 | − urb, priv, seqnum); | |
| 26 | + usbip_dbg_vhci_rx("find urb seqnum %u\n", seqnum); | |
| 28 | 27 | |
| 29 | 28 | switch (status) { |
| 30 | 29 | case -ENOENT: |
| 31 | 30 | /* fall through */ |
| 32 | 31 | case -ECONNRESET: |
| 33 | − dev_info(&urb->dev->dev, | |
| 34 | − "urb %p was unlinked %ssynchronuously.\n", urb, | |
| 35 | − status == -ENOENT ? "" : "a"); | |
| 32 | + dev_dbg(&urb->dev->dev, | |
| 33 | + "urb seq# %u was unlinked %ssynchronuously\n", | |
| 34 | + seqnum, status == -ENOENT ? "" : "a"); | |
| 36 | 35 | break; |
| 37 | 36 | case -EINPROGRESS: |
| 38 | 37 | /* no info output */ |
| 39 | 38 | break; |
| 40 | 39 | default: |
| 41 | − dev_info(&urb->dev->dev, | |
| 42 | − "urb %p may be in a error, status %d\n", urb, | |
| 43 | − status); | |
| 40 | + dev_dbg(&urb->dev->dev, | |
| 41 | + "urb seq# %u may be in a error, status %d\n", | |
| 42 | + seqnum, status); | |
| 44 | 43 | } |
| 45 | 44 | |
| 46 | 45 | list_del(&priv->list); |
| @@ -67,8 +66,8 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, · 20 unmodified lines | ||
| 67 | 66 | spin_unlock_irqrestore(&vdev->priv_lock, flags); |
| 68 | 67 | |
| 69 | 68 | if (!urb) { |
| 70 | − pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); | |
| 71 | − pr_info("max seqnum %d\n", | |
| 69 | + pr_err("cannot find a urb of seqnum %u max seqnum %d\n", | |
| 70 | + pdu->base.seqnum, | |
| 72 | 71 | atomic_read(&vhci_hcd->seqnum)); |
| 73 | 72 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); |
| 74 | 73 | return; |
| @@ -91,7 +90,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, · 16 unmodified lines | ||
| 91 | 90 | if (usbip_dbg_flag_vhci_rx) |
| 92 | 91 | usbip_dump_urb(urb); |
| 93 | 92 | |
| 94 | − usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | |
| 93 | + usbip_dbg_vhci_rx("now giveback urb %u\n", pdu->base.seqnum); | |
| 95 | 94 | |
| 96 | 95 | spin_lock_irqsave(&vhci->lock, flags); |
| 97 | 96 | usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb); |
| @@ -158,7 +157,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, · 60 unmodified lines | ||
| 158 | 157 | pr_info("the urb (seqnum %d) was already given back\n", |
| 159 | 158 | pdu->base.seqnum); |
| 160 | 159 | } else { |
| 161 | − usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | |
| 160 | + usbip_dbg_vhci_rx("now giveback urb %d\n", pdu->base.seqnum); | |
| 162 | 161 | |
| 163 | 162 | /* If unlink is successful, status is -ECONNRESET */ |
| 164 | 163 | urb->status = pdu->u.ret_unlink.status; |
| @@ -17,15 +17,20 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | /* |
| 19 | 19 | * output example: |
| 20 | − * hub port sta spd dev socket local_busid | |
| 21 | − * hs 0000 004 000 00000000 c5a7bb80 1-2.3 | |
| 20 | + * hub port sta spd dev sockfd local_busid | |
| 21 | + * hs 0000 004 000 00000000 3 1-2.3 | |
| 22 | 22 | * ................................................ |
| 23 | − * ss 0008 004 000 00000000 d8cee980 2-3.4 | |
| 23 | + * ss 0008 004 000 00000000 4 2-3.4 | |
| 24 | 24 | * ................................................ |
| 25 | 25 | * |
| 26 | − * IP address can be retrieved from a socket pointer address by looking | |
| 27 | − * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a | |
| 28 | − * port number and its peer IP address. | |
| 26 | + * Output includes socket fd instead of socket pointer address to avoid | |
| 27 | + * leaking kernel memory address in: | |
| 28 | + * /sys/devices/platform/vhci_hcd.0/status and in debug output. | |
| 29 | + * The socket pointer address is not used at the moment and it was made | |
| 30 | + * visible as a convenient way to find IP address from socket pointer | |
| 31 | + * address by looking up /proc/net/{tcp,tcp6}. As this opens a security | |
| 32 | + * hole, the change is made to use sockfd instead. | |
| 33 | + * | |
| 29 | 34 | */ |
| 30 | 35 | static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) |
| 31 | 36 | { |
| @@ -39,8 +44,8 @@ static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vd · 7 unmodified lines | ||
| 39 | 44 | if (vdev->ud.status == VDEV_ST_USED) { |
| 40 | 45 | *out += sprintf(*out, "%03u %08x ", |
| 41 | 46 | vdev->speed, vdev->devid); |
| 42 | − *out += sprintf(*out, "%16p %s", | |
| 43 | − vdev->ud.tcp_socket, | |
| 47 | + *out += sprintf(*out, "%u %s", | |
| 48 | + vdev->ud.sockfd, | |
| 44 | 49 | dev_name(&vdev->udev->dev)); |
| 45 | 50 | |
| 46 | 51 | } else { |
| @@ -160,7 +165,8 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, · 113 unmodified lines | ||
| 160 | 165 | char *s = out; |
| 161 | 166 | |
| 162 | 167 | /* |
| 163 | − * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. | |
| 168 | + * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, | |
| 169 | + * thus the * 2. | |
| 164 | 170 | */ |
| 165 | 171 | out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); |
| 166 | 172 | return out - s; |
| @@ -366,6 +372,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, · 199 unmodified lines | ||
| 366 | 372 | |
| 367 | 373 | vdev->devid = devid; |
| 368 | 374 | vdev->speed = speed; |
| 375 | + vdev->ud.sockfd = sockfd; | |
| 369 | 376 | vdev->ud.tcp_socket = socket; |
| 370 | 377 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
| 371 | 378 | |
| @@ -69,7 +69,8 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) · 68 unmodified lines | ||
| 69 | 69 | memset(&msg, 0, sizeof(msg)); |
| 70 | 70 | memset(&iov, 0, sizeof(iov)); |
| 71 | 71 | |
| 72 | − usbip_dbg_vhci_tx("setup txdata urb %p\n", urb); | |
| 72 | + usbip_dbg_vhci_tx("setup txdata urb seqnum %lu\n", | |
| 73 | + priv->seqnum); | |
| 73 | 74 | |
| 74 | 75 | /* 1. setup usbip_header */ |
| 75 | 76 | setup_cmd_submit_pdu(&pdu_header, urb); |
| @@ -522,10 +522,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) · 521 unmodified lines | ||
| 522 | 522 | return -EBUSY; |
| 523 | 523 | |
| 524 | 524 | vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); |
| 525 | − if (!vm_dev) { | |
| 526 | − rc = -ENOMEM; | |
| 527 | − goto free_mem; | |
| 528 | − } | |
| 525 | + if (!vm_dev) | |
| 526 | + return -ENOMEM; | |
| 529 | 527 | |
| 530 | 528 | vm_dev->vdev.dev.parent = &pdev->dev; |
| 531 | 529 | vm_dev->vdev.dev.release = virtio_mmio_release_dev; |
| @@ -535,17 +533,14 @@ static int virtio_mmio_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 535 | 533 | spin_lock_init(&vm_dev->lock); |
| 536 | 534 | |
| 537 | 535 | vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
| 538 | − if (vm_dev->base == NULL) { | |
| 539 | − rc = -EFAULT; | |
| 540 | − goto free_vmdev; | |
| 541 | − } | |
| 536 | + if (vm_dev->base == NULL) | |
| 537 | + return -EFAULT; | |
| 542 | 538 | |
| 543 | 539 | /* Check magic value */ |
| 544 | 540 | magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); |
| 545 | 541 | if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { |
| 546 | 542 | dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); |
| 547 | − rc = -ENODEV; | |
| 548 | − goto unmap; | |
| 543 | + return -ENODEV; | |
| 549 | 544 | } |
| 550 | 545 | |
| 551 | 546 | /* Check device version */ |
| @@ -553,8 +548,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 553 | 548 | if (vm_dev->version < 1 || vm_dev->version > 2) { |
| 554 | 549 | dev_err(&pdev->dev, "Version %ld not supported!\n", |
| 555 | 550 | vm_dev->version); |
| 556 | − rc = -ENXIO; | |
| 557 | − goto unmap; | |
| 551 | + return -ENXIO; | |
| 558 | 552 | } |
| 559 | 553 | |
| 560 | 554 | vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); |
| @@ -563,8 +557,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 563 | 557 | * virtio-mmio device with an ID 0 is a (dummy) placeholder |
| 564 | 558 | * with no function. End probing now with no error reported. |
| 565 | 559 | */ |
| 566 | − rc = -ENODEV; | |
| 567 | − goto unmap; | |
| 560 | + return -ENODEV; | |
| 568 | 561 | } |
| 569 | 562 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); |
| 570 | 563 | |
| @@ -590,33 +583,15 @@ static int virtio_mmio_probe(struct platform_device *pdev) · 19 unmodified lines | ||
| 590 | 583 | platform_set_drvdata(pdev, vm_dev); |
| 591 | 584 | |
| 592 | 585 | rc = register_virtio_device(&vm_dev->vdev); |
| 593 | − if (rc) { | |
| 594 | − iounmap(vm_dev->base); | |
| 595 | − devm_release_mem_region(&pdev->dev, mem->start, | |
| 596 | − resource_size(mem)); | |
| 586 | + if (rc) | |
| 597 | 587 | put_device(&vm_dev->vdev.dev); |
| 598 | − } | |
| 599 | − return rc; | |
| 600 | −unmap: | |
| 601 | − iounmap(vm_dev->base); | |
| 602 | −free_mem: | |
| 603 | − devm_release_mem_region(&pdev->dev, mem->start, | |
| 604 | − resource_size(mem)); | |
| 605 | −free_vmdev: | |
| 606 | − devm_kfree(&pdev->dev, vm_dev); | |
| 588 | + | |
| 607 | 589 | return rc; |
| 608 | 590 | } |
| 609 | 591 | |
| 610 | 592 | static int virtio_mmio_remove(struct platform_device *pdev) |
| 611 | 593 | { |
| 612 | 594 | struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev); |
| 613 | − struct resource *mem; | |
| 614 | − | |
| 615 | − iounmap(vm_dev->base); | |
| 616 | − mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 617 | − if (mem) | |
| 618 | − devm_release_mem_region(&pdev->dev, mem->start, | |
| 619 | − resource_size(mem)); | |
| 620 | 595 | unregister_virtio_device(&vm_dev->vdev); |
| 621 | 596 | |
| 622 | 597 | return 0; |
| @@ -269,7 +269,7 @@ config XEN_ACPI_HOTPLUG_CPU · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | config XEN_ACPI_PROCESSOR |
| 271 | 271 | tristate "Xen ACPI processor" |
| 272 | − depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ | |
| 272 | + depends on XEN && XEN_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ | |
| 273 | 273 | default m |
| 274 | 274 | help |
| 275 | 275 | This ACPI processor uploads Power Management information to the Xen |
| @@ -257,10 +257,25 @@ static void release_memory_resource(struct resource *resource) · 256 unmodified lines | ||
| 257 | 257 | kfree(resource); |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | +/* | |
| 261 | + * Host memory not allocated to dom0. We can use this range for hotplug-based | |
| 262 | + * ballooning. | |
| 263 | + * | |
| 264 | + * It's a type-less resource. Setting IORESOURCE_MEM will make resource | |
| 265 | + * management algorithms (arch_remove_reservations()) look into guest e820, | |
| 266 | + * which we don't want. | |
| 267 | + */ | |
| 268 | +static struct resource hostmem_resource = { | |
| 269 | + .name = "Host RAM", | |
| 270 | +}; | |
| 271 | + | |
| 272 | +void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res) | |
| 273 | +{} | |
| 274 | + | |
| 260 | 275 | static struct resource *additional_memory_resource(phys_addr_t size) |
| 261 | 276 | { |
| 262 | − struct resource *res; | |
| 263 | − int ret; | |
| 277 | + struct resource *res, *res_hostmem; | |
| 278 | + int ret = -ENOMEM; | |
| 264 | 279 | |
| 265 | 280 | res = kzalloc(sizeof(*res), GFP_KERNEL); |
| 266 | 281 | if (!res) |
| @@ -269,13 +284,42 @@ static struct resource *additional_memory_resource(phys_addr_t size) · 2 unmodified lines | ||
| 269 | 284 | res->name = "System RAM"; |
| 270 | 285 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 271 | 286 | |
| 272 | − ret = allocate_resource(&iomem_resource, res, | |
| 273 | − size, 0, -1, | |
| 274 | − PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | |
| 275 | − if (ret < 0) { | |
| 276 | − pr_err("Cannot allocate new System RAM resource\n"); | |
| 277 | − kfree(res); | |
| 278 | − return NULL; | |
| 287 | + res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); | |
| 288 | + if (res_hostmem) { | |
| 289 | + /* Try to grab a range from hostmem */ | |
| 290 | + res_hostmem->name = "Host memory"; | |
| 291 | + ret = allocate_resource(&hostmem_resource, res_hostmem, | |
| 292 | + size, 0, -1, | |
| 293 | + PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | |
| 294 | + } | |
| 295 | + | |
| 296 | + if (!ret) { | |
| 297 | + /* | |
| 298 | + * Insert this resource into iomem. Because hostmem_resource | |
| 299 | + * tracks portion of guest e820 marked as UNUSABLE noone else | |
| 300 | + * should try to use it. | |
| 301 | + */ | |
| 302 | + res->start = res_hostmem->start; | |
| 303 | + res->end = res_hostmem->end; | |
| 304 | + ret = insert_resource(&iomem_resource, res); | |
| 305 | + if (ret < 0) { | |
| 306 | + pr_err("Can't insert iomem_resource [%llx - %llx]\n", | |
| 307 | + res->start, res->end); | |
| 308 | + release_memory_resource(res_hostmem); | |
| 309 | + res_hostmem = NULL; | |
| 310 | + res->start = res->end = 0; | |
| 311 | + } | |
| 312 | + } | |
| 313 | + | |
| 314 | + if (ret) { | |
| 315 | + ret = allocate_resource(&iomem_resource, res, | |
| 316 | + size, 0, -1, | |
| 317 | + PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | |
| 318 | + if (ret < 0) { | |
| 319 | + pr_err("Cannot allocate new System RAM resource\n"); | |
| 320 | + kfree(res); | |
| 321 | + return NULL; | |
| 322 | + } | |
| 279 | 323 | } |
| 280 | 324 | |
| 281 | 325 | #ifdef CONFIG_SPARSEMEM |
| @@ -287,6 +331,7 @@ static struct resource *additional_memory_resource(phys_addr_t size) · 5 unmodified lines | ||
| 287 | 331 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", |
| 288 | 332 | pfn, limit); |
| 289 | 333 | release_memory_resource(res); |
| 334 | + release_memory_resource(res_hostmem); | |
| 290 | 335 | return NULL; |
| 291 | 336 | } |
| 292 | 337 | } |
| @@ -765,6 +810,8 @@ static int __init balloon_init(void) · 472 unmodified lines | ||
| 765 | 810 | set_online_page_callback(&xen_online_page); |
| 766 | 811 | register_memory_notifier(&xen_memory_nb); |
| 767 | 812 | register_sysctl_table(xen_root); |
| 813 | + | |
| 814 | + arch_xen_balloon_init(&hostmem_resource); | |
| 768 | 815 | #endif |
| 769 | 816 | |
| 770 | 817 | #ifdef CONFIG_XEN_PV |
| @@ -170,7 +170,6 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, · 169 unmodified lines | ||
| 170 | 170 | |
| 171 | 171 | mutex_unlock(&sbi->wq_mutex); |
| 172 | 172 | |
| 173 | − if (autofs4_write(sbi, pipe, &pkt, pktsz)) | |
| 174 | 173 | switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { |
| 175 | 174 | case 0: |
| 176 | 175 | break; |
| @@ -1440,6 +1440,29 @@ static int __close_session(struct ceph_mds_client *mdsc, · 1439 unmodified lines | ||
| 1440 | 1440 | return request_close_session(mdsc, session); |
| 1441 | 1441 | } |
| 1442 | 1442 | |
| 1443 | +static bool drop_negative_children(struct dentry *dentry) | |
| 1444 | +{ | |
| 1445 | + struct dentry *child; | |
| 1446 | + bool all_negative = true; | |
| 1447 | + | |
| 1448 | + if (!d_is_dir(dentry)) | |
| 1449 | + goto out; | |
| 1450 | + | |
| 1451 | + spin_lock(&dentry->d_lock); | |
| 1452 | + list_for_each_entry(child, &dentry->d_subdirs, d_child) { | |
| 1453 | + if (d_really_is_positive(child)) { | |
| 1454 | + all_negative = false; | |
| 1455 | + break; | |
| 1456 | + } | |
| 1457 | + } | |
| 1458 | + spin_unlock(&dentry->d_lock); | |
| 1459 | + | |
| 1460 | + if (all_negative) | |
| 1461 | + shrink_dcache_parent(dentry); | |
| 1462 | +out: | |
| 1463 | + return all_negative; | |
| 1464 | +} | |
| 1465 | + | |
| 1443 | 1466 | /* |
| 1444 | 1467 | * Trim old(er) caps. |
| 1445 | 1468 | * |
| @@ -1490,16 +1513,27 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) · 44 unmodified lines | ||
| 1490 | 1513 | if ((used | wanted) & ~oissued & mine) |
| 1491 | 1514 | goto out; /* we need these caps */ |
| 1492 | 1515 | |
| 1493 | − session->s_trim_caps--; | |
| 1494 | 1516 | if (oissued) { |
| 1495 | 1517 | /* we aren't the only cap.. just remove us */ |
| 1496 | 1518 | __ceph_remove_cap(cap, true); |
| 1519 | + session->s_trim_caps--; | |
| 1497 | 1520 | } else { |
| 1521 | + struct dentry *dentry; | |
| 1498 | 1522 | /* try dropping referring dentries */ |
| 1499 | 1523 | spin_unlock(&ci->i_ceph_lock); |
| 1500 | − d_prune_aliases(inode); | |
| 1501 | − dout("trim_caps_cb %p cap %p pruned, count now %d\n", | |
| 1502 | − inode, cap, atomic_read(&inode->i_count)); | |
| 1524 | + dentry = d_find_any_alias(inode); | |
| 1525 | + if (dentry && drop_negative_children(dentry)) { | |
| 1526 | + int count; | |
| 1527 | + dput(dentry); | |
| 1528 | + d_prune_aliases(inode); | |
| 1529 | + count = atomic_read(&inode->i_count); | |
| 1530 | + if (count == 1) | |
| 1531 | + session->s_trim_caps--; | |
| 1532 | + dout("trim_caps_cb %p cap %p pruned, count now %d\n", | |
| 1533 | + inode, cap, count); | |
| 1534 | + } else { | |
| 1535 | + dput(dentry); | |
| 1536 | + } | |
| 1503 | 1537 | return 0; |
| 1504 | 1538 | } |
| 1505 | 1539 | |
| @@ -1406,7 +1406,8 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, · 1405 unmodified lines | ||
| 1406 | 1406 | } while (rc == -EAGAIN); |
| 1407 | 1407 | |
| 1408 | 1408 | if (rc) { |
| 1409 | − cifs_dbg(VFS, "ioctl error in smb2_get_dfs_refer rc=%d\n", rc); | |
| 1409 | + if (rc != -ENOENT) | |
| 1410 | + cifs_dbg(VFS, "ioctl error in smb2_get_dfs_refer rc=%d\n", rc); | |
| 1410 | 1411 | goto out; |
| 1411 | 1412 | } |
| 1412 | 1413 | |
| @@ -2678,27 +2678,27 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, · 2677 unmodified lines | ||
| 2678 | 2678 | cifs_small_buf_release(req); |
| 2679 | 2679 | |
| 2680 | 2680 | rsp = (struct smb2_read_rsp *)rsp_iov.iov_base; |
| 2681 | − shdr = get_sync_hdr(rsp); | |
| 2682 | 2681 | |
| 2683 | − if (shdr->Status == STATUS_END_OF_FILE) { | |
| 2682 | + if (rc) { | |
| 2683 | + if (rc != -ENODATA) { | |
| 2684 | + cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); | |
| 2685 | + cifs_dbg(VFS, "Send error in read = %d\n", rc); | |
| 2686 | + } | |
| 2684 | 2687 | free_rsp_buf(resp_buftype, rsp_iov.iov_base); |
| 2685 | − return 0; | |
| 2688 | + return rc == -ENODATA ? 0 : rc; | |
| 2686 | 2689 | } |
| 2687 | 2690 | |
| 2688 | − if (rc) { | |
| 2689 | − cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); | |
| 2690 | − cifs_dbg(VFS, "Send error in read = %d\n", rc); | |
| 2691 | − } else { | |
| 2692 | − *nbytes = le32_to_cpu(rsp->DataLength); | |
| 2693 | − if ((*nbytes > CIFS_MAX_MSGSIZE) || | |
| 2694 | − (*nbytes > io_parms->length)) { | |
| 2695 | − cifs_dbg(FYI, "bad length %d for count %d\n", | |
| 2696 | − *nbytes, io_parms->length); | |
| 2697 | − rc = -EIO; | |
| 2698 | − *nbytes = 0; | |
| 2699 | − } | |
| 2691 | + *nbytes = le32_to_cpu(rsp->DataLength); | |
| 2692 | + if ((*nbytes > CIFS_MAX_MSGSIZE) || | |
| 2693 | + (*nbytes > io_parms->length)) { | |
| 2694 | + cifs_dbg(FYI, "bad length %d for count %d\n", | |
| 2695 | + *nbytes, io_parms->length); | |
| 2696 | + rc = -EIO; | |
| 2697 | + *nbytes = 0; | |
| 2700 | 2698 | } |
| 2701 | 2699 | |
| 2700 | + shdr = get_sync_hdr(rsp); | |
| 2701 | + | |
| 2702 | 2702 | if (*buf) { |
| 2703 | 2703 | memcpy(*buf, (char *)shdr + rsp->DataOffset, *nbytes); |
| 2704 | 2704 | free_rsp_buf(resp_buftype, rsp_iov.iov_base); |
| @@ -34,6 +34,7 @@ config CRAMFS_BLOCKDEV · 33 unmodified lines | ||
| 34 | 34 | config CRAMFS_MTD |
| 35 | 35 | bool "Support CramFs image directly mapped in physical memory" |
| 36 | 36 | depends on CRAMFS && MTD |
| 37 | + depends on CRAMFS=m || MTD=y | |
| 37 | 38 | default y if !CRAMFS_BLOCKDEV |
| 38 | 39 | help |
| 39 | 40 | This option allows the CramFs driver to load data directly from |
| @@ -627,8 +627,7 @@ static void dax_mapping_entry_mkclean(struct address_space *mapping, · 626 unmodified lines | ||
| 627 | 627 | |
| 628 | 628 | if (pfn != pmd_pfn(*pmdp)) |
| 629 | 629 | goto unlock_pmd; |
| 630 | − if (!pmd_dirty(*pmdp) | |
| 631 | − && !pmd_access_permitted(*pmdp, WRITE)) | |
| 630 | + if (!pmd_dirty(*pmdp) && !pmd_write(*pmdp)) | |
| 632 | 631 | goto unlock_pmd; |
| 633 | 632 | |
| 634 | 633 | flush_cache_page(vma, address, pfn); |
| @@ -1216,15 +1216,14 @@ killed: · 1215 unmodified lines | ||
| 1216 | 1216 | return -EAGAIN; |
| 1217 | 1217 | } |
| 1218 | 1218 | |
| 1219 | −char *get_task_comm(char *buf, struct task_struct *tsk) | |
| 1219 | +char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk) | |
| 1220 | 1220 | { |
| 1221 | − /* buf must be at least sizeof(tsk->comm) in size */ | |
| 1222 | 1221 | task_lock(tsk); |
| 1223 | − strncpy(buf, tsk->comm, sizeof(tsk->comm)); | |
| 1222 | + strncpy(buf, tsk->comm, buf_size); | |
| 1224 | 1223 | task_unlock(tsk); |
| 1225 | 1224 | return buf; |
| 1226 | 1225 | } |
| 1227 | −EXPORT_SYMBOL_GPL(get_task_comm); | |
| 1226 | +EXPORT_SYMBOL_GPL(__get_task_comm); | |
| 1228 | 1227 | |
| 1229 | 1228 | /* |
| 1230 | 1229 | * These functions flushes out all traces of the currently running executable |
| @@ -1340,15 +1339,10 @@ void setup_new_exec(struct linux_binprm * bprm) · 109 unmodified lines | ||
| 1340 | 1339 | * avoid bad behavior from the prior rlimits. This has to |
| 1341 | 1340 | * happen before arch_pick_mmap_layout(), which examines |
| 1342 | 1341 | * RLIMIT_STACK, but after the point of no return to avoid |
| 1343 | − * races from other threads changing the limits. This also | |
| 1344 | − * must be protected from races with prlimit() calls. | |
| 1342 | + * needing to clean up the change on failure. | |
| 1345 | 1343 | */ |
| 1346 | − task_lock(current->group_leader); | |
| 1347 | 1344 | if (current->signal->rlim[RLIMIT_STACK].rlim_cur > _STK_LIM) |
| 1348 | 1345 | current->signal->rlim[RLIMIT_STACK].rlim_cur = _STK_LIM; |
| 1349 | − if (current->signal->rlim[RLIMIT_STACK].rlim_max > _STK_LIM) | |
| 1350 | − current->signal->rlim[RLIMIT_STACK].rlim_max = _STK_LIM; | |
| 1351 | − task_unlock(current->group_leader); | |
| 1352 | 1346 | } |
| 1353 | 1347 | |
| 1354 | 1348 | arch_pick_mmap_layout(current->mm); |
| @@ -4722,6 +4722,7 @@ retry: · 4721 unmodified lines | ||
| 4722 | 4722 | EXT4_INODE_EOFBLOCKS); |
| 4723 | 4723 | } |
| 4724 | 4724 | ext4_mark_inode_dirty(handle, inode); |
| 4725 | + ext4_update_inode_fsync_trans(handle, inode, 1); | |
| 4725 | 4726 | ret2 = ext4_journal_stop(handle); |
| 4726 | 4727 | if (ret2) |
| 4727 | 4728 | break; |
| @@ -816,6 +816,8 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, · 815 unmodified lines | ||
| 816 | 816 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
| 817 | 817 | struct posix_acl *p = get_acl(dir, ACL_TYPE_DEFAULT); |
| 818 | 818 | |
| 819 | + if (IS_ERR(p)) | |
| 820 | + return ERR_CAST(p); | |
| 819 | 821 | if (p) { |
| 820 | 822 | int acl_size = p->a_count * sizeof(ext4_acl_entry); |
| 821 | 823 | |
| @@ -149,6 +149,15 @@ static int ext4_meta_trans_blocks(struct inode *inode, int lblocks, · 148 unmodified lines | ||
| 149 | 149 | */ |
| 150 | 150 | int ext4_inode_is_fast_symlink(struct inode *inode) |
| 151 | 151 | { |
| 152 | + if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) { | |
| 153 | + int ea_blocks = EXT4_I(inode)->i_file_acl ? | |
| 154 | + EXT4_CLUSTER_SIZE(inode->i_sb) >> 9 : 0; | |
| 155 | + | |
| 156 | + if (ext4_has_inline_data(inode)) | |
| 157 | + return 0; | |
| 158 | + | |
| 159 | + return (S_ISLNK(inode->i_mode) && inode->i_blocks - ea_blocks == 0); | |
| 160 | + } | |
| 152 | 161 | return S_ISLNK(inode->i_mode) && inode->i_size && |
| 153 | 162 | (inode->i_size < EXT4_N_BLOCKS * 4); |
| 154 | 163 | } |
| @@ -1399,6 +1399,10 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, · 1398 unmodified lines | ||
| 1399 | 1399 | "falling back\n")); |
| 1400 | 1400 | } |
| 1401 | 1401 | nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); |
| 1402 | + if (!nblocks) { | |
| 1403 | + ret = NULL; | |
| 1404 | + goto cleanup_and_exit; | |
| 1405 | + } | |
| 1402 | 1406 | start = EXT4_I(dir)->i_dir_start_lookup; |
| 1403 | 1407 | if (start >= nblocks) |
| 1404 | 1408 | start = 0; |
| @@ -2826,6 +2826,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, · 2825 unmodified lines | ||
| 2826 | 2826 | SB_DIRSYNC | |
| 2827 | 2827 | SB_SILENT | |
| 2828 | 2828 | SB_POSIXACL | |
| 2829 | + SB_LAZYTIME | | |
| 2829 | 2830 | SB_I_VERSION); |
| 2830 | 2831 | |
| 2831 | 2832 | if (flags & MS_REMOUNT) |
| @@ -291,12 +291,23 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat · 290 unmodified lines | ||
| 291 | 291 | const struct sockaddr *sap = data->addr; |
| 292 | 292 | struct nfs_net *nn = net_generic(data->net, nfs_net_id); |
| 293 | 293 | |
| 294 | +again: | |
| 294 | 295 | list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { |
| 295 | 296 | const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; |
| 296 | 297 | /* Don't match clients that failed to initialise properly */ |
| 297 | 298 | if (clp->cl_cons_state < 0) |
| 298 | 299 | continue; |
| 299 | 300 | |
| 301 | + /* If a client is still initializing then we need to wait */ | |
| 302 | + if (clp->cl_cons_state > NFS_CS_READY) { | |
| 303 | + refcount_inc(&clp->cl_count); | |
| 304 | + spin_unlock(&nn->nfs_client_lock); | |
| 305 | + nfs_wait_client_init_complete(clp); | |
| 306 | + nfs_put_client(clp); | |
| 307 | + spin_lock(&nn->nfs_client_lock); | |
| 308 | + goto again; | |
| 309 | + } | |
| 310 | + | |
| 300 | 311 | /* Different NFS versions cannot share the same nfs_client */ |
| 301 | 312 | if (clp->rpc_ops != data->nfs_mod->rpc_ops) |
| 302 | 313 | continue; |
| @@ -404,15 +404,19 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, · 403 unmodified lines | ||
| 404 | 404 | if (error < 0) |
| 405 | 405 | goto error; |
| 406 | 406 | |
| 407 | − if (!nfs4_has_session(clp)) | |
| 408 | − nfs_mark_client_ready(clp, NFS_CS_READY); | |
| 409 | − | |
| 410 | 407 | error = nfs4_discover_server_trunking(clp, &old); |
| 411 | 408 | if (error < 0) |
| 412 | 409 | goto error; |
| 413 | 410 | |
| 414 | − if (clp != old) | |
| 411 | + if (clp != old) { | |
| 415 | 412 | clp->cl_preserve_clid = true; |
| 413 | + /* | |
| 414 | + * Mark the client as having failed initialization so other | |
| 415 | + * processes walking the nfs_client_list in nfs_match_client() | |
| 416 | + * won't try to use it. | |
| 417 | + */ | |
| 418 | + nfs_mark_client_ready(clp, -EPERM); | |
| 419 | + } | |
| 416 | 420 | nfs_put_client(clp); |
| 417 | 421 | clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags); |
| 418 | 422 | return old; |
| @@ -539,6 +543,9 @@ int nfs40_walk_client_list(struct nfs_client *new, · 120 unmodified lines | ||
| 539 | 543 | spin_lock(&nn->nfs_client_lock); |
| 540 | 544 | list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { |
| 541 | 545 | |
| 546 | + if (pos == new) | |
| 547 | + goto found; | |
| 548 | + | |
| 542 | 549 | status = nfs4_match_client(pos, new, &prev, nn); |
| 543 | 550 | if (status < 0) |
| 544 | 551 | goto out_unlock; |
| @@ -559,6 +566,7 @@ int nfs40_walk_client_list(struct nfs_client *new, · 14 unmodified lines | ||
| 559 | 566 | * way that a SETCLIENTID_CONFIRM to pos can succeed is |
| 560 | 567 | * if new and pos point to the same server: |
| 561 | 568 | */ |
| 569 | +found: | |
| 562 | 570 | refcount_inc(&pos->cl_count); |
| 563 | 571 | spin_unlock(&nn->nfs_client_lock); |
| 564 | 572 | |
| @@ -572,6 +580,7 @@ int nfs40_walk_client_list(struct nfs_client *new, · 7 unmodified lines | ||
| 572 | 580 | case 0: |
| 573 | 581 | nfs4_swap_callback_idents(pos, new); |
| 574 | 582 | pos->cl_confirm = new->cl_confirm; |
| 583 | + nfs_mark_client_ready(pos, NFS_CS_READY); | |
| 575 | 584 | |
| 576 | 585 | prev = NULL; |
| 577 | 586 | *result = pos; |
| @@ -1890,6 +1890,8 @@ int nfs_commit_inode(struct inode *inode, int how) · 1889 unmodified lines | ||
| 1890 | 1890 | if (res) |
| 1891 | 1891 | error = nfs_generic_commit_list(inode, &head, how, &cinfo); |
| 1892 | 1892 | nfs_commit_end(cinfo.mds); |
| 1893 | + if (res == 0) | |
| 1894 | + return res; | |
| 1893 | 1895 | if (error < 0) |
| 1894 | 1896 | goto out_error; |
| 1895 | 1897 | if (!may_wait) |
| @@ -60,6 +60,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) · 59 unmodified lines | ||
| 60 | 60 | gi->gid[i] = exp->ex_anon_gid; |
| 61 | 61 | else |
| 62 | 62 | gi->gid[i] = rqgi->gid[i]; |
| 63 | + | |
| 64 | + /* Each thread allocates its own gi, no race */ | |
| 65 | + groups_sort(gi); | |
| 63 | 66 | } |
| 64 | 67 | } else { |
| 65 | 68 | gi = get_group_info(rqgi); |
| @@ -24,6 +24,16 @@ config OVERLAY_FS_REDIRECT_DIR · 23 unmodified lines | ||
| 24 | 24 | an overlay which has redirects on a kernel that doesn't support this |
| 25 | 25 | feature will have unexpected results. |
| 26 | 26 | |
| 27 | +config OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW | |
| 28 | + bool "Overlayfs: follow redirects even if redirects are turned off" | |
| 29 | + default y | |
| 30 | + depends on OVERLAY_FS | |
| 31 | + help | |
| 32 | + Disable this to get a possibly more secure configuration, but that | |
| 33 | + might not be backward compatible with previous kernels. | |
| 34 | + | |
| 35 | + For more information, see Documentation/filesystems/overlayfs.txt | |
| 36 | + | |
| 27 | 37 | config OVERLAY_FS_INDEX |
| 28 | 38 | bool "Overlayfs: turn on inodes index feature by default" |
| 29 | 39 | depends on OVERLAY_FS |
| @@ -887,7 +887,8 @@ static int ovl_set_redirect(struct dentry *dentry, bool samedir) · 886 unmodified lines | ||
| 887 | 887 | spin_unlock(&dentry->d_lock); |
| 888 | 888 | } else { |
| 889 | 889 | kfree(redirect); |
| 890 | − pr_warn_ratelimited("overlay: failed to set redirect (%i)\n", err); | |
| 890 | + pr_warn_ratelimited("overlayfs: failed to set redirect (%i)\n", | |
| 891 | + err); | |
| 891 | 892 | /* Fall back to userspace copy-up */ |
| 892 | 893 | err = -EXDEV; |
| 893 | 894 | } |
| @@ -435,7 +435,7 @@ int ovl_verify_index(struct dentry *index, struct ovl_path *lower, · 434 unmodified lines | ||
| 435 | 435 | |
| 436 | 436 | /* Check if index is orphan and don't warn before cleaning it */ |
| 437 | 437 | if (d_inode(index)->i_nlink == 1 && |
| 438 | − ovl_get_nlink(index, origin.dentry, 0) == 0) | |
| 438 | + ovl_get_nlink(origin.dentry, index, 0) == 0) | |
| 439 | 439 | err = -ENOENT; |
| 440 | 440 | |
| 441 | 441 | dput(origin.dentry); |
| @@ -681,6 +681,22 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, · 239 unmodified lines | ||
| 681 | 681 | if (d.stop) |
| 682 | 682 | break; |
| 683 | 683 | |
| 684 | + /* | |
| 685 | + * Following redirects can have security consequences: it's like | |
| 686 | + * a symlink into the lower layer without the permission checks. | |
| 687 | + * This is only a problem if the upper layer is untrusted (e.g | |
| 688 | + * comes from an USB drive). This can allow a non-readable file | |
| 689 | + * or directory to become readable. | |
| 690 | + * | |
| 691 | + * Only following redirects when redirects are enabled disables | |
| 692 | + * this attack vector when not necessary. | |
| 693 | + */ | |
| 694 | + err = -EPERM; | |
| 695 | + if (d.redirect && !ofs->config.redirect_follow) { | |
| 696 | + pr_warn_ratelimited("overlay: refusing to follow redirect for (%pd2)\n", dentry); | |
| 697 | + goto out_put; | |
| 698 | + } | |
| 699 | + | |
| 684 | 700 | if (d.redirect && d.redirect[0] == '/' && poe != roe) { |
| 685 | 701 | poe = roe; |
| 686 | 702 | |
| @@ -180,7 +180,7 @@ static inline int ovl_do_whiteout(struct inode *dir, struct dentry *dentry) · 179 unmodified lines | ||
| 180 | 180 | static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode) |
| 181 | 181 | { |
| 182 | 182 | struct dentry *ret = vfs_tmpfile(dentry, mode, 0); |
| 183 | − int err = IS_ERR(ret) ? PTR_ERR(ret) : 0; | |
| 183 | + int err = PTR_ERR_OR_ZERO(ret); | |
| 184 | 184 | |
| 185 | 185 | pr_debug("tmpfile(%pd2, 0%o) = %i\n", dentry, mode, err); |
| 186 | 186 | return ret; |
| @@ -14,6 +14,8 @@ struct ovl_config { · 13 unmodified lines | ||
| 14 | 14 | char *workdir; |
| 15 | 15 | bool default_permissions; |
| 16 | 16 | bool redirect_dir; |
| 17 | + bool redirect_follow; | |
| 18 | + const char *redirect_mode; | |
| 17 | 19 | bool index; |
| 18 | 20 | }; |
| 19 | 21 | |
| @@ -499,7 +499,7 @@ out: · 498 unmodified lines | ||
| 499 | 499 | return err; |
| 500 | 500 | |
| 501 | 501 | fail: |
| 502 | − pr_warn_ratelimited("overlay: failed to look up (%s) for ino (%i)\n", | |
| 502 | + pr_warn_ratelimited("overlayfs: failed to look up (%s) for ino (%i)\n", | |
| 503 | 503 | p->name, err); |
| 504 | 504 | goto out; |
| 505 | 505 | } |
| @@ -663,7 +663,10 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx) · 157 unmodified lines | ||
| 663 | 663 | return PTR_ERR(rdt.cache); |
| 664 | 664 | } |
| 665 | 665 | |
| 666 | − return iterate_dir(od->realfile, &rdt.ctx); | |
| 666 | + err = iterate_dir(od->realfile, &rdt.ctx); | |
| 667 | + ctx->pos = rdt.ctx.pos; | |
| 668 | + | |
| 669 | + return err; | |
| 667 | 670 | } |
| 668 | 671 | |
| 669 | 672 | |
| @@ -33,6 +33,13 @@ module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644); · 32 unmodified lines | ||
| 33 | 33 | MODULE_PARM_DESC(ovl_redirect_dir_def, |
| 34 | 34 | "Default to on or off for the redirect_dir feature"); |
| 35 | 35 | |
| 36 | +static bool ovl_redirect_always_follow = | |
| 37 | + IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW); | |
| 38 | +module_param_named(redirect_always_follow, ovl_redirect_always_follow, | |
| 39 | + bool, 0644); | |
| 40 | +MODULE_PARM_DESC(ovl_redirect_always_follow, | |
| 41 | + "Follow redirects even if redirect_dir feature is turned off"); | |
| 42 | + | |
| 36 | 43 | static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX); |
| 37 | 44 | module_param_named(index, ovl_index_def, bool, 0644); |
| 38 | 45 | MODULE_PARM_DESC(ovl_index_def, |
| @@ -232,6 +239,7 @@ static void ovl_free_fs(struct ovl_fs *ofs) · 193 unmodified lines | ||
| 232 | 239 | kfree(ofs->config.lowerdir); |
| 233 | 240 | kfree(ofs->config.upperdir); |
| 234 | 241 | kfree(ofs->config.workdir); |
| 242 | + kfree(ofs->config.redirect_mode); | |
| 235 | 243 | if (ofs->creator_cred) |
| 236 | 244 | put_cred(ofs->creator_cred); |
| 237 | 245 | kfree(ofs); |
| @@ -244,6 +252,7 @@ static void ovl_put_super(struct super_block *sb) · 6 unmodified lines | ||
| 244 | 252 | ovl_free_fs(ofs); |
| 245 | 253 | } |
| 246 | 254 | |
| 255 | +/* Sync real dirty inodes in upper filesystem (if it exists) */ | |
| 247 | 256 | static int ovl_sync_fs(struct super_block *sb, int wait) |
| 248 | 257 | { |
| 249 | 258 | struct ovl_fs *ofs = sb->s_fs_info; |
| @@ -252,14 +261,24 @@ static int ovl_sync_fs(struct super_block *sb, int wait) · 2 unmodified lines | ||
| 252 | 261 | |
| 253 | 262 | if (!ofs->upper_mnt) |
| 254 | 263 | return 0; |
| 255 | − upper_sb = ofs->upper_mnt->mnt_sb; | |
| 256 | − if (!upper_sb->s_op->sync_fs) | |
| 264 | + | |
| 265 | + /* | |
| 266 | + * If this is a sync(2) call or an emergency sync, all the super blocks | |
| 267 | + * will be iterated, including upper_sb, so no need to do anything. | |
| 268 | + * | |
| 269 | + * If this is a syncfs(2) call, then we do need to call | |
| 270 | + * sync_filesystem() on upper_sb, but enough if we do it when being | |
| 271 | + * called with wait == 1. | |
| 272 | + */ | |
| 273 | + if (!wait) | |
| 257 | 274 | return 0; |
| 258 | 275 | |
| 259 | − /* real inodes have already been synced by sync_filesystem(ovl_sb) */ | |
| 276 | + upper_sb = ofs->upper_mnt->mnt_sb; | |
| 277 | + | |
| 260 | 278 | down_read(&upper_sb->s_umount); |
| 261 | − ret = upper_sb->s_op->sync_fs(upper_sb, wait); | |
| 279 | + ret = sync_filesystem(upper_sb); | |
| 262 | 280 | up_read(&upper_sb->s_umount); |
| 281 | + | |
| 263 | 282 | return ret; |
| 264 | 283 | } |
| 265 | 284 | |
| @@ -295,6 +314,11 @@ static bool ovl_force_readonly(struct ovl_fs *ofs) · 29 unmodified lines | ||
| 295 | 314 | return (!ofs->upper_mnt || !ofs->workdir); |
| 296 | 315 | } |
| 297 | 316 | |
| 317 | +static const char *ovl_redirect_mode_def(void) | |
| 318 | +{ | |
| 319 | + return ovl_redirect_dir_def ? "on" : "off"; | |
| 320 | +} | |
| 321 | + | |
| 298 | 322 | /** |
| 299 | 323 | * ovl_show_options |
| 300 | 324 | * |
| @@ -313,12 +337,10 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry) · 12 unmodified lines | ||
| 313 | 337 | } |
| 314 | 338 | if (ofs->config.default_permissions) |
| 315 | 339 | seq_puts(m, ",default_permissions"); |
| 316 | − if (ofs->config.redirect_dir != ovl_redirect_dir_def) | |
| 317 | − seq_printf(m, ",redirect_dir=%s", | |
| 318 | − ofs->config.redirect_dir ? "on" : "off"); | |
| 340 | + if (strcmp(ofs->config.redirect_mode, ovl_redirect_mode_def()) != 0) | |
| 341 | + seq_printf(m, ",redirect_dir=%s", ofs->config.redirect_mode); | |
| 319 | 342 | if (ofs->config.index != ovl_index_def) |
| 320 | − seq_printf(m, ",index=%s", | |
| 321 | − ofs->config.index ? "on" : "off"); | |
| 343 | + seq_printf(m, ",index=%s", ofs->config.index ? "on" : "off"); | |
| 322 | 344 | return 0; |
| 323 | 345 | } |
| 324 | 346 | |
| @@ -348,8 +370,7 @@ enum { · 23 unmodified lines | ||
| 348 | 370 | OPT_UPPERDIR, |
| 349 | 371 | OPT_WORKDIR, |
| 350 | 372 | OPT_DEFAULT_PERMISSIONS, |
| 351 | − OPT_REDIRECT_DIR_ON, | |
| 352 | − OPT_REDIRECT_DIR_OFF, | |
| 373 | + OPT_REDIRECT_DIR, | |
| 353 | 374 | OPT_INDEX_ON, |
| 354 | 375 | OPT_INDEX_OFF, |
| 355 | 376 | OPT_ERR, |
| @@ -360,8 +381,7 @@ static const match_table_t ovl_tokens = { · 4 unmodified lines | ||
| 360 | 381 | {OPT_UPPERDIR, "upperdir=%s"}, |
| 361 | 382 | {OPT_WORKDIR, "workdir=%s"}, |
| 362 | 383 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, |
| 363 | − {OPT_REDIRECT_DIR_ON, "redirect_dir=on"}, | |
| 364 | − {OPT_REDIRECT_DIR_OFF, "redirect_dir=off"}, | |
| 384 | + {OPT_REDIRECT_DIR, "redirect_dir=%s"}, | |
| 365 | 385 | {OPT_INDEX_ON, "index=on"}, |
| 366 | 386 | {OPT_INDEX_OFF, "index=off"}, |
| 367 | 387 | {OPT_ERR, NULL} |
| @@ -390,10 +410,37 @@ static char *ovl_next_opt(char **s) · 22 unmodified lines | ||
| 390 | 410 | return sbegin; |
| 391 | 411 | } |
| 392 | 412 | |
| 413 | +static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode) | |
| 414 | +{ | |
| 415 | + if (strcmp(mode, "on") == 0) { | |
| 416 | + config->redirect_dir = true; | |
| 417 | + /* | |
| 418 | + * Does not make sense to have redirect creation without | |
| 419 | + * redirect following. | |
| 420 | + */ | |
| 421 | + config->redirect_follow = true; | |
| 422 | + } else if (strcmp(mode, "follow") == 0) { | |
| 423 | + config->redirect_follow = true; | |
| 424 | + } else if (strcmp(mode, "off") == 0) { | |
| 425 | + if (ovl_redirect_always_follow) | |
| 426 | + config->redirect_follow = true; | |
| 427 | + } else if (strcmp(mode, "nofollow") != 0) { | |
| 428 | + pr_err("overlayfs: bad mount option \"redirect_dir=%s\"\n", | |
| 429 | + mode); | |
| 430 | + return -EINVAL; | |
| 431 | + } | |
| 432 | + | |
| 433 | + return 0; | |
| 434 | +} | |
| 435 | + | |
| 393 | 436 | static int ovl_parse_opt(char *opt, struct ovl_config *config) |
| 394 | 437 | { |
| 395 | 438 | char *p; |
| 396 | 439 | |
| 440 | + config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL); | |
| 441 | + if (!config->redirect_mode) | |
| 442 | + return -ENOMEM; | |
| 443 | + | |
| 397 | 444 | while ((p = ovl_next_opt(&opt)) != NULL) { |
| 398 | 445 | int token; |
| 399 | 446 | substring_t args[MAX_OPT_ARGS]; |
| @@ -428,12 +475,11 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config) · 28 unmodified lines | ||
| 428 | 475 | config->default_permissions = true; |
| 429 | 476 | break; |
| 430 | 477 | |
| 431 | − case OPT_REDIRECT_DIR_ON: | |
| 432 | − config->redirect_dir = true; | |
| 433 | − break; | |
| 434 | − | |
| 435 | − case OPT_REDIRECT_DIR_OFF: | |
| 436 | − config->redirect_dir = false; | |
| 478 | + case OPT_REDIRECT_DIR: | |
| 479 | + kfree(config->redirect_mode); | |
| 480 | + config->redirect_mode = match_strdup(&args[0]); | |
| 481 | + if (!config->redirect_mode) | |
| 482 | + return -ENOMEM; | |
| 437 | 483 | break; |
| 438 | 484 | |
| 439 | 485 | case OPT_INDEX_ON: |
| @@ -458,7 +504,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config) · 18 unmodified lines | ||
| 458 | 504 | config->workdir = NULL; |
| 459 | 505 | } |
| 460 | 506 | |
| 461 | − return 0; | |
| 507 | + return ovl_parse_redirect_mode(config, config->redirect_mode); | |
| 462 | 508 | } |
| 463 | 509 | |
| 464 | 510 | #define OVL_WORKDIR_NAME "work" |
| @@ -1160,7 +1206,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) · 695 unmodified lines | ||
| 1160 | 1206 | if (!cred) |
| 1161 | 1207 | goto out_err; |
| 1162 | 1208 | |
| 1163 | − ofs->config.redirect_dir = ovl_redirect_dir_def; | |
| 1164 | 1209 | ofs->config.index = ovl_index_def; |
| 1165 | 1210 | err = ovl_parse_opt((char *) data, &ofs->config); |
| 1166 | 1211 | if (err) |
| @@ -191,6 +191,24 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, · 190 unmodified lines | ||
| 191 | 191 | |
| 192 | 192 | INIT_LIST_HEAD(&s->s_mounts); |
| 193 | 193 | s->s_user_ns = get_user_ns(user_ns); |
| 194 | + init_rwsem(&s->s_umount); | |
| 195 | + lockdep_set_class(&s->s_umount, &type->s_umount_key); | |
| 196 | + /* | |
| 197 | + * sget() can have s_umount recursion. | |
| 198 | + * | |
| 199 | + * When it cannot find a suitable sb, it allocates a new | |
| 200 | + * one (this one), and tries again to find a suitable old | |
| 201 | + * one. | |
| 202 | + * | |
| 203 | + * In case that succeeds, it will acquire the s_umount | |
| 204 | + * lock of the old one. Since these are clearly distrinct | |
| 205 | + * locks, and this object isn't exposed yet, there's no | |
| 206 | + * risk of deadlocks. | |
| 207 | + * | |
| 208 | + * Annotate this by putting this lock in a different | |
| 209 | + * subclass. | |
| 210 | + */ | |
| 211 | + down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | |
| 194 | 212 | |
| 195 | 213 | if (security_sb_alloc(s)) |
| 196 | 214 | goto fail; |
| @@ -218,25 +236,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, · 21 unmodified lines | ||
| 218 | 236 | goto fail; |
| 219 | 237 | if (list_lru_init_memcg(&s->s_inode_lru)) |
| 220 | 238 | goto fail; |
| 221 | − | |
| 222 | − init_rwsem(&s->s_umount); | |
| 223 | − lockdep_set_class(&s->s_umount, &type->s_umount_key); | |
| 224 | − /* | |
| 225 | − * sget() can have s_umount recursion. | |
| 226 | − * | |
| 227 | − * When it cannot find a suitable sb, it allocates a new | |
| 228 | − * one (this one), and tries again to find a suitable old | |
| 229 | − * one. | |
| 230 | − * | |
| 231 | − * In case that succeeds, it will acquire the s_umount | |
| 232 | − * lock of the old one. Since these are clearly distrinct | |
| 233 | − * locks, and this object isn't exposed yet, there's no | |
| 234 | − * risk of deadlocks. | |
| 235 | − * | |
| 236 | − * Annotate this by putting this lock in a different | |
| 237 | − * subclass. | |
| 238 | − */ | |
| 239 | − down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | |
| 240 | 239 | s->s_count = 1; |
| 241 | 240 | atomic_set(&s->s_active, 1); |
| 242 | 241 | mutex_init(&s->s_vfs_rename_mutex); |
| @@ -702,7 +702,7 @@ xfs_alloc_ag_vextent( · 701 unmodified lines | ||
| 702 | 702 | ASSERT(args->agbno % args->alignment == 0); |
| 703 | 703 | |
| 704 | 704 | /* if not file data, insert new block into the reverse map btree */ |
| 705 | − if (args->oinfo.oi_owner != XFS_RMAP_OWN_UNKNOWN) { | |
| 705 | + if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) { | |
| 706 | 706 | error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, |
| 707 | 707 | args->agbno, args->len, &args->oinfo); |
| 708 | 708 | if (error) |
| @@ -1682,7 +1682,7 @@ xfs_free_ag_extent( · 973 unmodified lines | ||
| 1682 | 1682 | bno_cur = cnt_cur = NULL; |
| 1683 | 1683 | mp = tp->t_mountp; |
| 1684 | 1684 | |
| 1685 | − if (oinfo->oi_owner != XFS_RMAP_OWN_UNKNOWN) { | |
| 1685 | + if (!xfs_rmap_should_skip_owner_update(oinfo)) { | |
| 1686 | 1686 | error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo); |
| 1687 | 1687 | if (error) |
| 1688 | 1688 | goto error0; |
| @@ -212,6 +212,7 @@ xfs_attr_set( · 211 unmodified lines | ||
| 212 | 212 | int flags) |
| 213 | 213 | { |
| 214 | 214 | struct xfs_mount *mp = dp->i_mount; |
| 215 | + struct xfs_buf *leaf_bp = NULL; | |
| 215 | 216 | struct xfs_da_args args; |
| 216 | 217 | struct xfs_defer_ops dfops; |
| 217 | 218 | struct xfs_trans_res tres; |
| @@ -327,9 +328,16 @@ xfs_attr_set( · 109 unmodified lines | ||
| 327 | 328 | * GROT: another possible req'mt for a double-split btree op. |
| 328 | 329 | */ |
| 329 | 330 | xfs_defer_init(args.dfops, args.firstblock); |
| 330 | − error = xfs_attr_shortform_to_leaf(&args); | |
| 331 | + error = xfs_attr_shortform_to_leaf(&args, &leaf_bp); | |
| 331 | 332 | if (error) |
| 332 | 333 | goto out_defer_cancel; |
| 334 | + /* | |
| 335 | + * Prevent the leaf buffer from being unlocked so that a | |
| 336 | + * concurrent AIL push cannot grab the half-baked leaf | |
| 337 | + * buffer and run into problems with the write verifier. | |
| 338 | + */ | |
| 339 | + xfs_trans_bhold(args.trans, leaf_bp); | |
| 340 | + xfs_defer_bjoin(args.dfops, leaf_bp); | |
| 333 | 341 | xfs_defer_ijoin(args.dfops, dp); |
| 334 | 342 | error = xfs_defer_finish(&args.trans, args.dfops); |
| 335 | 343 | if (error) |
| @@ -337,13 +345,14 @@ xfs_attr_set( · 1 unmodified line | ||
| 337 | 345 | |
| 338 | 346 | /* |
| 339 | 347 | * Commit the leaf transformation. We'll need another (linked) |
| 340 | − * transaction to add the new attribute to the leaf. | |
| 348 | + * transaction to add the new attribute to the leaf, which | |
| 349 | + * means that we have to hold & join the leaf buffer here too. | |
| 341 | 350 | */ |
| 342 | − | |
| 343 | 351 | error = xfs_trans_roll_inode(&args.trans, dp); |
| 344 | 352 | if (error) |
| 345 | 353 | goto out; |
| 346 | − | |
| 354 | + xfs_trans_bjoin(args.trans, leaf_bp); | |
| 355 | + leaf_bp = NULL; | |
| 347 | 356 | } |
| 348 | 357 | |
| 349 | 358 | if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) |
| @@ -374,8 +383,9 @@ xfs_attr_set( · 24 unmodified lines | ||
| 374 | 383 | |
| 375 | 384 | out_defer_cancel: |
| 376 | 385 | xfs_defer_cancel(&dfops); |
| 377 | − args.trans = NULL; | |
| 378 | 386 | out: |
| 387 | + if (leaf_bp) | |
| 388 | + xfs_trans_brelse(args.trans, leaf_bp); | |
| 379 | 389 | if (args.trans) |
| 380 | 390 | xfs_trans_cancel(args.trans); |
| 381 | 391 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
| @@ -735,10 +735,13 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) · 734 unmodified lines | ||
| 735 | 735 | } |
| 736 | 736 | |
| 737 | 737 | /* |
| 738 | − * Convert from using the shortform to the leaf. | |
| 738 | + * Convert from using the shortform to the leaf. On success, return the | |
| 739 | + * buffer so that we can keep it locked until we're totally done with it. | |
| 739 | 740 | */ |
| 740 | 741 | int |
| 741 | −xfs_attr_shortform_to_leaf(xfs_da_args_t *args) | |
| 742 | +xfs_attr_shortform_to_leaf( | |
| 743 | + struct xfs_da_args *args, | |
| 744 | + struct xfs_buf **leaf_bp) | |
| 742 | 745 | { |
| 743 | 746 | xfs_inode_t *dp; |
| 744 | 747 | xfs_attr_shortform_t *sf; |
| @@ -818,7 +821,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) · 73 unmodified lines | ||
| 818 | 821 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); |
| 819 | 822 | } |
| 820 | 823 | error = 0; |
| 821 | − | |
| 824 | + *leaf_bp = bp; | |
| 822 | 825 | out: |
| 823 | 826 | kmem_free(tmpbuffer); |
| 824 | 827 | return error; |
| @@ -48,7 +48,8 @@ void xfs_attr_shortform_create(struct xfs_da_args *args); · 47 unmodified lines | ||
| 48 | 48 | void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff); |
| 49 | 49 | int xfs_attr_shortform_lookup(struct xfs_da_args *args); |
| 50 | 50 | int xfs_attr_shortform_getvalue(struct xfs_da_args *args); |
| 51 | −int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); | |
| 51 | +int xfs_attr_shortform_to_leaf(struct xfs_da_args *args, | |
| 52 | + struct xfs_buf **leaf_bp); | |
| 52 | 53 | int xfs_attr_shortform_remove(struct xfs_da_args *args); |
| 53 | 54 | int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); |
| 54 | 55 | int xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes); |
| @@ -5136,7 +5136,7 @@ __xfs_bunmapi( · 5135 unmodified lines | ||
| 5136 | 5136 | * blowing out the transaction with a mix of EFIs and reflink |
| 5137 | 5137 | * adjustments. |
| 5138 | 5138 | */ |
| 5139 | − if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) | |
| 5139 | + if (tp && xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) | |
| 5140 | 5140 | max_len = min(len, xfs_refcount_max_unmap(tp->t_log_res)); |
| 5141 | 5141 | else |
| 5142 | 5142 | max_len = len; |
| @@ -249,6 +249,10 @@ xfs_defer_trans_roll( · 248 unmodified lines | ||
| 249 | 249 | for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) |
| 250 | 250 | xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); |
| 251 | 251 | |
| 252 | + /* Hold the (previously bjoin'd) buffer locked across the roll. */ | |
| 253 | + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) | |
| 254 | + xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); | |
| 255 | + | |
| 252 | 256 | trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); |
| 253 | 257 | |
| 254 | 258 | /* Roll the transaction. */ |
| @@ -264,6 +268,12 @@ xfs_defer_trans_roll( · 9 unmodified lines | ||
| 264 | 268 | for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) |
| 265 | 269 | xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); |
| 266 | 270 | |
| 271 | + /* Rejoin the buffers and dirty them so the log moves forward. */ | |
| 272 | + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { | |
| 273 | + xfs_trans_bjoin(*tp, dop->dop_bufs[i]); | |
| 274 | + xfs_trans_bhold(*tp, dop->dop_bufs[i]); | |
| 275 | + } | |
| 276 | + | |
| 267 | 277 | return error; |
| 268 | 278 | } |
| 269 | 279 | |
| @@ -295,6 +305,31 @@ xfs_defer_ijoin( · 25 unmodified lines | ||
| 295 | 305 | } |
| 296 | 306 | } |
| 297 | 307 | |
| 308 | + ASSERT(0); | |
| 309 | + return -EFSCORRUPTED; | |
| 310 | +} | |
| 311 | + | |
| 312 | +/* | |
| 313 | + * Add this buffer to the deferred op. Each joined buffer is relogged | |
| 314 | + * each time we roll the transaction. | |
| 315 | + */ | |
| 316 | +int | |
| 317 | +xfs_defer_bjoin( | |
| 318 | + struct xfs_defer_ops *dop, | |
| 319 | + struct xfs_buf *bp) | |
| 320 | +{ | |
| 321 | + int i; | |
| 322 | + | |
| 323 | + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) { | |
| 324 | + if (dop->dop_bufs[i] == bp) | |
| 325 | + return 0; | |
| 326 | + else if (dop->dop_bufs[i] == NULL) { | |
| 327 | + dop->dop_bufs[i] = bp; | |
| 328 | + return 0; | |
| 329 | + } | |
| 330 | + } | |
| 331 | + | |
| 332 | + ASSERT(0); | |
| 298 | 333 | return -EFSCORRUPTED; |
| 299 | 334 | } |
| 300 | 335 | |
| @@ -493,9 +528,7 @@ xfs_defer_init( · 192 unmodified lines | ||
| 493 | 528 | struct xfs_defer_ops *dop, |
| 494 | 529 | xfs_fsblock_t *fbp) |
| 495 | 530 | { |
| 496 | − dop->dop_committed = false; | |
| 497 | − dop->dop_low = false; | |
| 498 | − memset(&dop->dop_inodes, 0, sizeof(dop->dop_inodes)); | |
| 531 | + memset(dop, 0, sizeof(struct xfs_defer_ops)); | |
| 499 | 532 | *fbp = NULLFSBLOCK; |
| 500 | 533 | INIT_LIST_HEAD(&dop->dop_intake); |
| 501 | 534 | INIT_LIST_HEAD(&dop->dop_pending); |
| @@ -59,6 +59,7 @@ enum xfs_defer_ops_type { · 58 unmodified lines | ||
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | 61 | #define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ |
| 62 | +#define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ | |
| 62 | 63 | |
| 63 | 64 | struct xfs_defer_ops { |
| 64 | 65 | bool dop_committed; /* did any trans commit? */ |
| @@ -66,8 +67,9 @@ struct xfs_defer_ops { · 1 unmodified line | ||
| 66 | 67 | struct list_head dop_intake; /* unlogged pending work */ |
| 67 | 68 | struct list_head dop_pending; /* logged pending work */ |
| 68 | 69 | |
| 69 | − /* relog these inodes with each roll */ | |
| 70 | + /* relog these with each roll */ | |
| 70 | 71 | struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; |
| 72 | + struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; | |
11 more lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 36 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 15 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 39 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 31 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 97 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 10 lines aren’t shown here.
This diff is large: its 38 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 155 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 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 53 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 31 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 10 lines aren’t shown here.
This diff is large: its 12 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 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 482 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 12 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 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 760 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 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 53 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 155 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 100 lines aren’t shown here.
This diff is large: its 47 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 57 lines aren’t shown here.
This diff is large: its 22 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 13 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 27 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 26 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 84 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 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 63 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 22 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 51 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 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 33 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 72 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 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 24 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 353 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 38 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 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 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 10 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 17 lines aren’t shown here.
This diff is large: its 145 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 18 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 37 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 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 54 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 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
Binary file not shown.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 108 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 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 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 21 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 9 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 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 39 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 12 lines aren’t shown here.
This diff is large: its 168 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 43 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 29 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 47 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 863 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 78 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 24 lines aren’t shown here.