Unified · Split
| @@ -10,6 +10,8 @@ · 9 unmodified lines | ||
| 10 | 10 | # Please keep this list dictionary sorted. |
| 11 | 11 | # |
| 12 | 12 | Aaron Durbin <adurbin@google.com> |
| 13 | +Abel Vesa <abelvesa@kernel.org> <abel.vesa@nxp.com> | |
| 14 | +Abel Vesa <abelvesa@kernel.org> <abelvesa@gmail.com> | |
| 13 | 15 | Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org> |
| 14 | 16 | Adam Oldham <oldhamca@gmail.com> |
| 15 | 17 | Adam Radford <aradford@gmail.com> |
| @@ -85,6 +87,7 @@ Christian Borntraeger <borntraeger@linux.ibm.com> <borntrae@de.ibm.com> · 69 unmodified lines | ||
| 85 | 87 | Christian Brauner <brauner@kernel.org> <christian@brauner.io> |
| 86 | 88 | Christian Brauner <brauner@kernel.org> <christian.brauner@canonical.com> |
| 87 | 89 | Christian Brauner <brauner@kernel.org> <christian.brauner@ubuntu.com> |
| 90 | +Christian Marangi <ansuelsmth@gmail.com> | |
| 88 | 91 | Christophe Ricard <christophe.ricard@gmail.com> |
| 89 | 92 | Christoph Hellwig <hch@lst.de> |
| 90 | 93 | Colin Ian King <colin.king@intel.com> <colin.king@canonical.com> |
| @@ -165,6 +168,7 @@ Jan Glauber <jan.glauber@gmail.com> <jang@de.ibm.com> · 74 unmodified lines | ||
| 165 | 168 | Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com> |
| 166 | 169 | Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com> |
| 167 | 170 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> |
| 171 | +Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> | |
| 168 | 172 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> |
| 169 | 173 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> |
| 170 | 174 | Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com> |
| @@ -1,4 +1,4 @@ | ||
| 1 | −What: /sys/bus/iio/devices/iio:deviceX/conversion_mode | |
| 1 | +What: /sys/bus/iio/devices/iio:deviceX/in_conversion_mode | |
| 2 | 2 | KernelVersion: 4.2 |
| 3 | 3 | Contact: linux-iio@vger.kernel.org |
| 4 | 4 | Description: |
| @@ -526,6 +526,7 @@ What: /sys/devices/system/cpu/vulnerabilities · 525 unmodified lines | ||
| 526 | 526 | /sys/devices/system/cpu/vulnerabilities/srbds |
| 527 | 527 | /sys/devices/system/cpu/vulnerabilities/tsx_async_abort |
| 528 | 528 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit |
| 529 | + /sys/devices/system/cpu/vulnerabilities/mmio_stale_data | |
| 529 | 530 | Date: January 2018 |
| 530 | 531 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
| 531 | 532 | Description: Information about CPU vulnerabilities |
| @@ -17,3 +17,4 @@ are configurable at compile, boot or run time. · 16 unmodified lines | ||
| 17 | 17 | special-register-buffer-data-sampling.rst |
| 18 | 18 | core-scheduling.rst |
| 19 | 19 | l1d_flush.rst |
| 20 | + processor_mmio_stale_data.rst | |
| @@ -0,0 +1,246 @@ | ||
| 1 | +========================================= | |
| 2 | +Processor MMIO Stale Data Vulnerabilities | |
| 3 | +========================================= | |
| 4 | + | |
| 5 | +Processor MMIO Stale Data Vulnerabilities are a class of memory-mapped I/O | |
| 6 | +(MMIO) vulnerabilities that can expose data. The sequences of operations for | |
| 7 | +exposing data range from simple to very complex. Because most of the | |
| 8 | +vulnerabilities require the attacker to have access to MMIO, many environments | |
| 9 | +are not affected. System environments using virtualization where MMIO access is | |
| 10 | +provided to untrusted guests may need mitigation. These vulnerabilities are | |
| 11 | +not transient execution attacks. However, these vulnerabilities may propagate | |
| 12 | +stale data into core fill buffers where the data can subsequently be inferred | |
| 13 | +by an unmitigated transient execution attack. Mitigation for these | |
| 14 | +vulnerabilities includes a combination of microcode update and software | |
| 15 | +changes, depending on the platform and usage model. Some of these mitigations | |
| 16 | +are similar to those used to mitigate Microarchitectural Data Sampling (MDS) or | |
| 17 | +those used to mitigate Special Register Buffer Data Sampling (SRBDS). | |
| 18 | + | |
| 19 | +Data Propagators | |
| 20 | +================ | |
| 21 | +Propagators are operations that result in stale data being copied or moved from | |
| 22 | +one microarchitectural buffer or register to another. Processor MMIO Stale Data | |
| 23 | +Vulnerabilities are operations that may result in stale data being directly | |
| 24 | +read into an architectural, software-visible state or sampled from a buffer or | |
| 25 | +register. | |
| 26 | + | |
| 27 | +Fill Buffer Stale Data Propagator (FBSDP) | |
| 28 | +----------------------------------------- | |
| 29 | +Stale data may propagate from fill buffers (FB) into the non-coherent portion | |
| 30 | +of the uncore on some non-coherent writes. Fill buffer propagation by itself | |
| 31 | +does not make stale data architecturally visible. Stale data must be propagated | |
| 32 | +to a location where it is subject to reading or sampling. | |
| 33 | + | |
| 34 | +Sideband Stale Data Propagator (SSDP) | |
| 35 | +------------------------------------- | |
| 36 | +The sideband stale data propagator (SSDP) is limited to the client (including | |
| 37 | +Intel Xeon server E3) uncore implementation. The sideband response buffer is | |
| 38 | +shared by all client cores. For non-coherent reads that go to sideband | |
| 39 | +destinations, the uncore logic returns 64 bytes of data to the core, including | |
| 40 | +both requested data and unrequested stale data, from a transaction buffer and | |
| 41 | +the sideband response buffer. As a result, stale data from the sideband | |
| 42 | +response and transaction buffers may now reside in a core fill buffer. | |
| 43 | + | |
| 44 | +Primary Stale Data Propagator (PSDP) | |
| 45 | +------------------------------------ | |
| 46 | +The primary stale data propagator (PSDP) is limited to the client (including | |
| 47 | +Intel Xeon server E3) uncore implementation. Similar to the sideband response | |
| 48 | +buffer, the primary response buffer is shared by all client cores. For some | |
| 49 | +processors, MMIO primary reads will return 64 bytes of data to the core fill | |
| 50 | +buffer including both requested data and unrequested stale data. This is | |
| 51 | +similar to the sideband stale data propagator. | |
| 52 | + | |
| 53 | +Vulnerabilities | |
| 54 | +=============== | |
| 55 | +Device Register Partial Write (DRPW) (CVE-2022-21166) | |
| 56 | +----------------------------------------------------- | |
| 57 | +Some endpoint MMIO registers incorrectly handle writes that are smaller than | |
| 58 | +the register size. Instead of aborting the write or only copying the correct | |
| 59 | +subset of bytes (for example, 2 bytes for a 2-byte write), more bytes than | |
| 60 | +specified by the write transaction may be written to the register. On | |
| 61 | +processors affected by FBSDP, this may expose stale data from the fill buffers | |
| 62 | +of the core that created the write transaction. | |
| 63 | + | |
| 64 | +Shared Buffers Data Sampling (SBDS) (CVE-2022-21125) | |
| 65 | +---------------------------------------------------- | |
| 66 | +After propagators may have moved data around the uncore and copied stale data | |
| 67 | +into client core fill buffers, processors affected by MFBDS can leak data from | |
| 68 | +the fill buffer. It is limited to the client (including Intel Xeon server E3) | |
| 69 | +uncore implementation. | |
| 70 | + | |
| 71 | +Shared Buffers Data Read (SBDR) (CVE-2022-21123) | |
| 72 | +------------------------------------------------ | |
| 73 | +It is similar to Shared Buffer Data Sampling (SBDS) except that the data is | |
| 74 | +directly read into the architectural software-visible state. It is limited to | |
| 75 | +the client (including Intel Xeon server E3) uncore implementation. | |
| 76 | + | |
| 77 | +Affected Processors | |
| 78 | +=================== | |
| 79 | +Not all the CPUs are affected by all the variants. For instance, most | |
| 80 | +processors for the server market (excluding Intel Xeon E3 processors) are | |
| 81 | +impacted by only Device Register Partial Write (DRPW). | |
| 82 | + | |
| 83 | +Below is the list of affected Intel processors [#f1]_: | |
| 84 | + | |
| 85 | + =================== ============ ========= | |
| 86 | + Common name Family_Model Steppings | |
| 87 | + =================== ============ ========= | |
| 88 | + HASWELL_X 06_3FH 2,4 | |
| 89 | + SKYLAKE_L 06_4EH 3 | |
| 90 | + BROADWELL_X 06_4FH All | |
| 91 | + SKYLAKE_X 06_55H 3,4,6,7,11 | |
| 92 | + BROADWELL_D 06_56H 3,4,5 | |
| 93 | + SKYLAKE 06_5EH 3 | |
| 94 | + ICELAKE_X 06_6AH 4,5,6 | |
| 95 | + ICELAKE_D 06_6CH 1 | |
| 96 | + ICELAKE_L 06_7EH 5 | |
| 97 | + ATOM_TREMONT_D 06_86H All | |
| 98 | + LAKEFIELD 06_8AH 1 | |
| 99 | + KABYLAKE_L 06_8EH 9 to 12 | |
| 100 | + ATOM_TREMONT 06_96H 1 | |
| 101 | + ATOM_TREMONT_L 06_9CH 0 | |
| 102 | + KABYLAKE 06_9EH 9 to 13 | |
| 103 | + COMETLAKE 06_A5H 2,3,5 | |
| 104 | + COMETLAKE_L 06_A6H 0,1 | |
| 105 | + ROCKETLAKE 06_A7H 1 | |
| 106 | + =================== ============ ========= | |
| 107 | + | |
| 108 | +If a CPU is in the affected processor list, but not affected by a variant, it | |
| 109 | +is indicated by new bits in MSR IA32_ARCH_CAPABILITIES. As described in a later | |
| 110 | +section, mitigation largely remains the same for all the variants, i.e. to | |
| 111 | +clear the CPU fill buffers via VERW instruction. | |
| 112 | + | |
| 113 | +New bits in MSRs | |
| 114 | +================ | |
| 115 | +Newer processors and microcode update on existing affected processors added new | |
| 116 | +bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate | |
| 117 | +specific variants of Processor MMIO Stale Data vulnerabilities and mitigation | |
| 118 | +capability. | |
| 119 | + | |
| 120 | +MSR IA32_ARCH_CAPABILITIES | |
| 121 | +-------------------------- | |
| 122 | +Bit 13 - SBDR_SSDP_NO - When set, processor is not affected by either the | |
| 123 | + Shared Buffers Data Read (SBDR) vulnerability or the sideband stale | |
| 124 | + data propagator (SSDP). | |
| 125 | +Bit 14 - FBSDP_NO - When set, processor is not affected by the Fill Buffer | |
| 126 | + Stale Data Propagator (FBSDP). | |
| 127 | +Bit 15 - PSDP_NO - When set, processor is not affected by Primary Stale Data | |
| 128 | + Propagator (PSDP). | |
| 129 | +Bit 17 - FB_CLEAR - When set, VERW instruction will overwrite CPU fill buffer | |
| 130 | + values as part of MD_CLEAR operations. Processors that do not | |
| 131 | + enumerate MDS_NO (meaning they are affected by MDS) but that do | |
| 132 | + enumerate support for both L1D_FLUSH and MD_CLEAR implicitly enumerate | |
| 133 | + FB_CLEAR as part of their MD_CLEAR support. | |
| 134 | +Bit 18 - FB_CLEAR_CTRL - Processor supports read and write to MSR | |
| 135 | + IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]. On such processors, the FB_CLEAR_DIS | |
| 136 | + bit can be set to cause the VERW instruction to not perform the | |
| 137 | + FB_CLEAR action. Not all processors that support FB_CLEAR will support | |
| 138 | + FB_CLEAR_CTRL. | |
| 139 | + | |
| 140 | +MSR IA32_MCU_OPT_CTRL | |
| 141 | +--------------------- | |
| 142 | +Bit 3 - FB_CLEAR_DIS - When set, VERW instruction does not perform the FB_CLEAR | |
| 143 | +action. This may be useful to reduce the performance impact of FB_CLEAR in | |
| 144 | +cases where system software deems it warranted (for example, when performance | |
| 145 | +is more critical, or the untrusted software has no MMIO access). Note that | |
| 146 | +FB_CLEAR_DIS has no impact on enumeration (for example, it does not change | |
| 147 | +FB_CLEAR or MD_CLEAR enumeration) and it may not be supported on all processors | |
| 148 | +that enumerate FB_CLEAR. | |
| 149 | + | |
| 150 | +Mitigation | |
| 151 | +========== | |
| 152 | +Like MDS, all variants of Processor MMIO Stale Data vulnerabilities have the | |
| 153 | +same mitigation strategy to force the CPU to clear the affected buffers before | |
| 154 | +an attacker can extract the secrets. | |
| 155 | + | |
| 156 | +This is achieved by using the otherwise unused and obsolete VERW instruction in | |
| 157 | +combination with a microcode update. The microcode clears the affected CPU | |
| 158 | +buffers when the VERW instruction is executed. | |
| 159 | + | |
| 160 | +Kernel reuses the MDS function to invoke the buffer clearing: | |
| 161 | + | |
| 162 | + mds_clear_cpu_buffers() | |
| 163 | + | |
| 164 | +On MDS affected CPUs, the kernel already invokes CPU buffer clear on | |
| 165 | +kernel/userspace, hypervisor/guest and C-state (idle) transitions. No | |
| 166 | +additional mitigation is needed on such CPUs. | |
| 167 | + | |
| 168 | +For CPUs not affected by MDS or TAA, mitigation is needed only for the attacker | |
| 169 | +with MMIO capability. Therefore, VERW is not required for kernel/userspace. For | |
| 170 | +virtualization case, VERW is only needed at VMENTER for a guest with MMIO | |
| 171 | +capability. | |
| 172 | + | |
| 173 | +Mitigation points | |
| 174 | +----------------- | |
| 175 | +Return to user space | |
| 176 | +^^^^^^^^^^^^^^^^^^^^ | |
| 177 | +Same mitigation as MDS when affected by MDS/TAA, otherwise no mitigation | |
| 178 | +needed. | |
| 179 | + | |
| 180 | +C-State transition | |
| 181 | +^^^^^^^^^^^^^^^^^^ | |
| 182 | +Control register writes by CPU during C-state transition can propagate data | |
| 183 | +from fill buffer to uncore buffers. Execute VERW before C-state transition to | |
| 184 | +clear CPU fill buffers. | |
| 185 | + | |
| 186 | +Guest entry point | |
| 187 | +^^^^^^^^^^^^^^^^^ | |
| 188 | +Same mitigation as MDS when processor is also affected by MDS/TAA, otherwise | |
| 189 | +execute VERW at VMENTER only for MMIO capable guests. On CPUs not affected by | |
| 190 | +MDS/TAA, guest without MMIO access cannot extract secrets using Processor MMIO | |
| 191 | +Stale Data vulnerabilities, so there is no need to execute VERW for such guests. | |
| 192 | + | |
| 193 | +Mitigation control on the kernel command line | |
| 194 | +--------------------------------------------- | |
| 195 | +The kernel command line allows to control the Processor MMIO Stale Data | |
| 196 | +mitigations at boot time with the option "mmio_stale_data=". The valid | |
| 197 | +arguments for this option are: | |
| 198 | + | |
| 199 | + ========== ================================================================= | |
| 200 | + full If the CPU is vulnerable, enable mitigation; CPU buffer clearing | |
| 201 | + on exit to userspace and when entering a VM. Idle transitions are | |
| 202 | + protected as well. It does not automatically disable SMT. | |
| 203 | + full,nosmt Same as full, with SMT disabled on vulnerable CPUs. This is the | |
| 204 | + complete mitigation. | |
| 205 | + off Disables mitigation completely. | |
| 206 | + ========== ================================================================= | |
| 207 | + | |
| 208 | +If the CPU is affected and mmio_stale_data=off is not supplied on the kernel | |
| 209 | +command line, then the kernel selects the appropriate mitigation. | |
| 210 | + | |
| 211 | +Mitigation status information | |
| 212 | +----------------------------- | |
| 213 | +The Linux kernel provides a sysfs interface to enumerate the current | |
| 214 | +vulnerability status of the system: whether the system is vulnerable, and | |
| 215 | +which mitigations are active. The relevant sysfs file is: | |
| 216 | + | |
| 217 | + /sys/devices/system/cpu/vulnerabilities/mmio_stale_data | |
| 218 | + | |
| 219 | +The possible values in this file are: | |
| 220 | + | |
| 221 | + .. list-table:: | |
| 222 | + | |
| 223 | + * - 'Not affected' | |
| 224 | + - The processor is not vulnerable | |
| 225 | + * - 'Vulnerable' | |
| 226 | + - The processor is vulnerable, but no mitigation enabled | |
| 227 | + * - 'Vulnerable: Clear CPU buffers attempted, no microcode' | |
| 228 | + - The processor is vulnerable, but microcode is not updated. The | |
| 229 | + mitigation is enabled on a best effort basis. | |
| 230 | + * - 'Mitigation: Clear CPU buffers' | |
| 231 | + - The processor is vulnerable and the CPU buffer clearing mitigation is | |
| 232 | + enabled. | |
| 233 | + | |
| 234 | +If the processor is vulnerable then the following information is appended to | |
| 235 | +the above information: | |
| 236 | + | |
| 237 | + ======================== =========================================== | |
| 238 | + 'SMT vulnerable' SMT is enabled | |
| 239 | + 'SMT disabled' SMT is disabled | |
| 240 | + 'SMT Host state unknown' Kernel runs in a VM, Host SMT state unknown | |
| 241 | + ======================== =========================================== | |
| 242 | + | |
| 243 | +References | |
| 244 | +---------- | |
| 245 | +.. [#f1] Affected Processors | |
| 246 | + https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html | |
| @@ -2469,7 +2469,6 @@ · 2468 unmodified lines | ||
| 2469 | 2469 | |
| 2470 | 2470 | protected: nVHE-based mode with support for guests whose |
| 2471 | 2471 | state is kept private from the host. |
| 2472 | − Not valid if the kernel is running in EL2. | |
| 2473 | 2472 | |
| 2474 | 2473 | Defaults to VHE/nVHE based on hardware support. Setting |
| 2475 | 2474 | mode to "protected" will disable kexec and hibernation |
| @@ -3176,6 +3175,7 @@ · 700 unmodified lines | ||
| 3176 | 3175 | srbds=off [X86,INTEL] |
| 3177 | 3176 | no_entry_flush [PPC] |
| 3178 | 3177 | no_uaccess_flush [PPC] |
| 3178 | + mmio_stale_data=off [X86] | |
| 3179 | 3179 | |
| 3180 | 3180 | Exceptions: |
| 3181 | 3181 | This does not have any effect on |
| @@ -3197,6 +3197,7 @@ · 15 unmodified lines | ||
| 3197 | 3197 | Equivalent to: l1tf=flush,nosmt [X86] |
| 3198 | 3198 | mds=full,nosmt [X86] |
| 3199 | 3199 | tsx_async_abort=full,nosmt [X86] |
| 3200 | + mmio_stale_data=full,nosmt [X86] | |
| 3200 | 3201 | |
| 3201 | 3202 | mminit_loglevel= |
| 3202 | 3203 | [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this |
| @@ -3206,6 +3207,40 @@ · 3 unmodified lines | ||
| 3206 | 3207 | log everything. Information is printed at KERN_DEBUG |
| 3207 | 3208 | so loglevel=8 may also need to be specified. |
| 3208 | 3209 | |
| 3210 | + mmio_stale_data= | |
| 3211 | + [X86,INTEL] Control mitigation for the Processor | |
| 3212 | + MMIO Stale Data vulnerabilities. | |
| 3213 | + | |
| 3214 | + Processor MMIO Stale Data is a class of | |
| 3215 | + vulnerabilities that may expose data after an MMIO | |
| 3216 | + operation. Exposed data could originate or end in | |
| 3217 | + the same CPU buffers as affected by MDS and TAA. | |
| 3218 | + Therefore, similar to MDS and TAA, the mitigation | |
| 3219 | + is to clear the affected CPU buffers. | |
| 3220 | + | |
| 3221 | + This parameter controls the mitigation. The | |
| 3222 | + options are: | |
| 3223 | + | |
| 3224 | + full - Enable mitigation on vulnerable CPUs | |
| 3225 | + | |
| 3226 | + full,nosmt - Enable mitigation and disable SMT on | |
| 3227 | + vulnerable CPUs. | |
| 3228 | + | |
| 3229 | + off - Unconditionally disable mitigation | |
| 3230 | + | |
| 3231 | + On MDS or TAA affected machines, | |
| 3232 | + mmio_stale_data=off can be prevented by an active | |
| 3233 | + MDS or TAA mitigation as these vulnerabilities are | |
| 3234 | + mitigated with the same mechanism so in order to | |
| 3235 | + disable this mitigation, you need to specify | |
| 3236 | + mds=off and tsx_async_abort=off too. | |
| 3237 | + | |
| 3238 | + Not specifying this option is equivalent to | |
| 3239 | + mmio_stale_data=full. | |
| 3240 | + | |
| 3241 | + For details see: | |
| 3242 | + Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst | |
| 3243 | + | |
| 3209 | 3244 | module.sig_enforce |
| 3210 | 3245 | [KNL] When CONFIG_MODULE_SIG is set, this means that |
| 3211 | 3246 | modules without (valid) signatures will fail to load. |
| @@ -40,9 +40,8 @@ properties: · 39 unmodified lines | ||
| 40 | 40 | value to be used for converting remote channel measurements to |
| 41 | 41 | temperature. |
| 42 | 42 | $ref: /schemas/types.yaml#/definitions/int32 |
| 43 | − items: | |
| 44 | − minimum: -128 | |
| 45 | − maximum: 127 | |
| 43 | + minimum: -128 | |
| 44 | + maximum: 127 | |
| 46 | 45 | |
| 47 | 46 | ti,beta-compensation: |
| 48 | 47 | description: |
| @@ -30,6 +30,7 @@ properties: · 29 unmodified lines | ||
| 30 | 30 | - socionext,uniphier-ld11-aidet |
| 31 | 31 | - socionext,uniphier-ld20-aidet |
| 32 | 32 | - socionext,uniphier-pxs3-aidet |
| 33 | + - socionext,uniphier-nx1-aidet | |
| 33 | 34 | |
| 34 | 35 | reg: |
| 35 | 36 | maxItems: 1 |
| @@ -47,6 +47,5 @@ examples: · 46 unmodified lines | ||
| 47 | 47 | clocks = <&clkcfg CLK_SPI0>; |
| 48 | 48 | interrupt-parent = <&plic>; |
| 49 | 49 | interrupts = <54>; |
| 50 | − spi-max-frequency = <25000000>; | |
| 51 | 50 | }; |
| 52 | 51 | ... |
| @@ -110,7 +110,6 @@ examples: · 109 unmodified lines | ||
| 110 | 110 | pinctrl-names = "default"; |
| 111 | 111 | pinctrl-0 = <&qup_spi1_default>; |
| 112 | 112 | interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; |
| 113 | − spi-max-frequency = <50000000>; | |
| 114 | 113 | #address-cells = <1>; |
| 115 | 114 | #size-cells = <0>; |
| 116 | 115 | }; |
| @@ -136,7 +136,8 @@ properties: · 135 unmodified lines | ||
| 136 | 136 | Phandle of a companion. |
| 137 | 137 | |
| 138 | 138 | phys: |
| 139 | − maxItems: 1 | |
| 139 | + minItems: 1 | |
| 140 | + maxItems: 3 | |
| 140 | 141 | |
| 141 | 142 | phy-names: |
| 142 | 143 | const: usb |
| @@ -103,7 +103,8 @@ properties: · 102 unmodified lines | ||
| 103 | 103 | Overrides the detected port count |
| 104 | 104 | |
| 105 | 105 | phys: |
| 106 | − maxItems: 1 | |
| 106 | + minItems: 1 | |
| 107 | + maxItems: 3 | |
| 107 | 108 | |
| 108 | 109 | phy-names: |
| 109 | 110 | const: usb |
| @@ -6,7 +6,7 @@ This document explains how GPIOs can be assigned to given devices and functions. · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | Note that it only applies to the new descriptor-based interface. For a |
| 8 | 8 | description of the deprecated integer-based GPIO interface please refer to |
| 9 | −gpio-legacy.txt (actually, there is no real mapping possible with the old | |
| 9 | +legacy.rst (actually, there is no real mapping possible with the old | |
| 10 | 10 | interface; you just fetch an integer from somewhere and request the |
| 11 | 11 | corresponding GPIO). |
| 12 | 12 | |
| @@ -4,7 +4,7 @@ GPIO Descriptor Consumer Interface · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | This document describes the consumer interface of the GPIO framework. Note that |
| 6 | 6 | it describes the new descriptor-based interface. For a description of the |
| 7 | −deprecated integer-based GPIO interface please refer to gpio-legacy.txt. | |
| 7 | +deprecated integer-based GPIO interface please refer to legacy.rst. | |
| 8 | 8 | |
| 9 | 9 | |
| 10 | 10 | Guidelines for GPIOs consumers |
| @@ -78,7 +78,7 @@ whether the line is configured active high or active low (see · 67 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | The two last flags are used for use cases where open drain is mandatory, such |
| 80 | 80 | as I2C: if the line is not already configured as open drain in the mappings |
| 81 | −(see board.txt), then open drain will be enforced anyway and a warning will be | |
| 81 | +(see board.rst), then open drain will be enforced anyway and a warning will be | |
| 82 | 82 | printed that the board configuration needs to be updated to match the use case. |
| 83 | 83 | |
| 84 | 84 | Both functions return either a valid GPIO descriptor, or an error code checkable |
| @@ -270,7 +270,7 @@ driven. · 185 unmodified lines | ||
| 270 | 270 | The same is applicable for open drain or open source output lines: those do not |
| 271 | 271 | actively drive their output high (open drain) or low (open source), they just |
| 272 | 272 | switch their output to a high impedance value. The consumer should not need to |
| 273 | −care. (For details read about open drain in driver.txt.) | |
| 273 | +care. (For details read about open drain in driver.rst.) | |
| 274 | 274 | |
| 275 | 275 | With this, all the gpiod_set_(array)_value_xxx() functions interpret the |
| 276 | 276 | parameter "value" as "asserted" ("1") or "de-asserted" ("0"). The physical line |
| @@ -14,12 +14,12 @@ Due to the history of GPIO interfaces in the kernel, there are two different · 13 unmodified lines | ||
| 14 | 14 | ways to obtain and use GPIOs: |
| 15 | 15 | |
| 16 | 16 | - The descriptor-based interface is the preferred way to manipulate GPIOs, |
| 17 | − and is described by all the files in this directory excepted gpio-legacy.txt. | |
| 17 | + and is described by all the files in this directory excepted legacy.rst. | |
| 18 | 18 | - The legacy integer-based interface which is considered deprecated (but still |
| 19 | − usable for compatibility reasons) is documented in gpio-legacy.txt. | |
| 19 | + usable for compatibility reasons) is documented in legacy.rst. | |
| 20 | 20 | |
| 21 | 21 | The remainder of this document applies to the new descriptor-based interface. |
| 22 | −gpio-legacy.txt contains the same information applied to the legacy | |
| 22 | +legacy.rst contains the same information applied to the legacy | |
| 23 | 23 | integer-based interface. |
| 24 | 24 | |
| 25 | 25 | |
| @@ -19,13 +19,23 @@ The main Btrfs features include: · 18 unmodified lines | ||
| 19 | 19 | * Subvolumes (separate internal filesystem roots) |
| 20 | 20 | * Object level mirroring and striping |
| 21 | 21 | * Checksums on data and metadata (multiple algorithms available) |
| 22 | − * Compression | |
| 22 | + * Compression (multiple algorithms available) | |
| 23 | + * Reflink, deduplication | |
| 24 | + * Scrub (on-line checksum verification) | |
| 25 | + * Hierarchical quota groups (subvolume and snapshot support) | |
| 23 | 26 | * Integrated multiple device support, with several raid algorithms |
| 24 | 27 | * Offline filesystem check |
| 25 | − * Efficient incremental backup and FS mirroring | |
| 28 | + * Efficient incremental backup and FS mirroring (send/receive) | |
| 29 | + * Trim/discard | |
| 26 | 30 | * Online filesystem defragmentation |
| 31 | + * Swapfile support | |
| 32 | + * Zoned mode | |
| 33 | + * Read/write metadata verification | |
| 34 | + * Online resize (shrink, grow) | |
| 27 | 35 | |
| 28 | −For more information please refer to the wiki | |
| 36 | +For more information please refer to the documentation site or wiki | |
| 37 | + | |
| 38 | + https://btrfs.readthedocs.io | |
| 29 | 39 | |
| 30 | 40 | https://btrfs.wiki.kernel.org |
| 31 | 41 | |
| @@ -13,8 +13,8 @@ disappeared as of Linux 3.0. · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | There are two places where extended attributes can be found. The first |
| 15 | 15 | place is between the end of each inode entry and the beginning of the |
| 16 | −next inode entry. For example, if inode.i\_extra\_isize = 28 and | |
| 17 | −sb.inode\_size = 256, then there are 256 - (128 + 28) = 100 bytes | |
| 16 | +next inode entry. For example, if inode.i_extra_isize = 28 and | |
| 17 | +sb.inode_size = 256, then there are 256 - (128 + 28) = 100 bytes | |
| 18 | 18 | available for in-inode extended attribute storage. The second place |
| 19 | 19 | where extended attributes can be found is in the block pointed to by |
| 20 | 20 | ``inode.i_file_acl``. As of Linux 3.11, it is not possible for this |
| @@ -38,8 +38,8 @@ Extended attributes, when stored after the inode, have a header · 17 unmodified lines | ||
| 38 | 38 | - Name |
| 39 | 39 | - Description |
| 40 | 40 | * - 0x0 |
| 41 | − - \_\_le32 | |
| 42 | − - h\_magic | |
| 41 | + - __le32 | |
| 42 | + - h_magic | |
| 43 | 43 | - Magic number for identification, 0xEA020000. This value is set by the |
| 44 | 44 | Linux driver, though e2fsprogs doesn't seem to check it(?) |
| 45 | 45 | |
| @@ -55,28 +55,28 @@ The beginning of an extended attribute block is in · 9 unmodified lines | ||
| 55 | 55 | - Name |
| 56 | 56 | - Description |
| 57 | 57 | * - 0x0 |
| 58 | − - \_\_le32 | |
| 59 | − - h\_magic | |
| 58 | + - __le32 | |
| 59 | + - h_magic | |
| 60 | 60 | - Magic number for identification, 0xEA020000. |
| 61 | 61 | * - 0x4 |
| 62 | − - \_\_le32 | |
| 63 | − - h\_refcount | |
| 62 | + - __le32 | |
| 63 | + - h_refcount | |
| 64 | 64 | - Reference count. |
| 65 | 65 | * - 0x8 |
| 66 | − - \_\_le32 | |
| 67 | − - h\_blocks | |
| 66 | + - __le32 | |
| 67 | + - h_blocks | |
| 68 | 68 | - Number of disk blocks used. |
| 69 | 69 | * - 0xC |
| 70 | − - \_\_le32 | |
| 71 | − - h\_hash | |
| 70 | + - __le32 | |
| 71 | + - h_hash | |
| 72 | 72 | - Hash value of all attributes. |
| 73 | 73 | * - 0x10 |
| 74 | − - \_\_le32 | |
| 75 | − - h\_checksum | |
| 74 | + - __le32 | |
| 75 | + - h_checksum | |
| 76 | 76 | - Checksum of the extended attribute block. |
| 77 | 77 | * - 0x14 |
| 78 | − - \_\_u32 | |
| 79 | − - h\_reserved[3] | |
| 78 | + - __u32 | |
| 79 | + - h_reserved[3] | |
| 80 | 80 | - Zero. |
| 81 | 81 | |
| 82 | 82 | The checksum is calculated against the FS UUID, the 64-bit block number |
| @@ -100,46 +100,46 @@ Attributes stored inside an inode do not need be stored in sorted order. · 17 unmodified lines | ||
| 100 | 100 | - Name |
| 101 | 101 | - Description |
| 102 | 102 | * - 0x0 |
| 103 | − - \_\_u8 | |
| 104 | − - e\_name\_len | |
| 103 | + - __u8 | |
| 104 | + - e_name_len | |
| 105 | 105 | - Length of name. |
| 106 | 106 | * - 0x1 |
| 107 | − - \_\_u8 | |
| 108 | − - e\_name\_index | |
| 107 | + - __u8 | |
| 108 | + - e_name_index | |
| 109 | 109 | - Attribute name index. There is a discussion of this below. |
| 110 | 110 | * - 0x2 |
| 111 | − - \_\_le16 | |
| 112 | − - e\_value\_offs | |
| 111 | + - __le16 | |
| 112 | + - e_value_offs | |
| 113 | 113 | - Location of this attribute's value on the disk block where it is stored. |
| 114 | 114 | Multiple attributes can share the same value. For an inode attribute |
| 115 | 115 | this value is relative to the start of the first entry; for a block this |
| 116 | 116 | value is relative to the start of the block (i.e. the header). |
| 117 | 117 | * - 0x4 |
| 118 | − - \_\_le32 | |
| 119 | − - e\_value\_inum | |
| 118 | + - __le32 | |
| 119 | + - e_value_inum | |
| 120 | 120 | - The inode where the value is stored. Zero indicates the value is in the |
| 121 | 121 | same block as this entry. This field is only used if the |
| 122 | − INCOMPAT\_EA\_INODE feature is enabled. | |
| 122 | + INCOMPAT_EA_INODE feature is enabled. | |
| 123 | 123 | * - 0x8 |
| 124 | − - \_\_le32 | |
| 125 | − - e\_value\_size | |
| 124 | + - __le32 | |
| 125 | + - e_value_size | |
| 126 | 126 | - Length of attribute value. |
| 127 | 127 | * - 0xC |
| 128 | − - \_\_le32 | |
| 129 | − - e\_hash | |
| 128 | + - __le32 | |
| 129 | + - e_hash | |
| 130 | 130 | - Hash value of attribute name and attribute value. The kernel doesn't |
| 131 | 131 | update the hash for in-inode attributes, so for that case this value |
| 132 | 132 | must be zero, because e2fsck validates any non-zero hash regardless of |
| 133 | 133 | where the xattr lives. |
| 134 | 134 | * - 0x10 |
| 135 | 135 | - char |
| 136 | − - e\_name[e\_name\_len] | |
| 136 | + - e_name[e_name_len] | |
| 137 | 137 | - Attribute name. Does not include trailing NULL. |
| 138 | 138 | |
| 139 | 139 | Attribute values can follow the end of the entry table. There appears to |
| 140 | 140 | be a requirement that they be aligned to 4-byte boundaries. The values |
| 141 | 141 | are stored starting at the end of the block and grow towards the |
| 142 | −xattr\_header/xattr\_entry table. When the two collide, the overflow is | |
| 142 | +xattr_header/xattr_entry table. When the two collide, the overflow is | |
| 143 | 143 | put into a separate disk block. If the disk block fills up, the |
| 144 | 144 | filesystem returns -ENOSPC. |
| 145 | 145 | |
| @@ -167,15 +167,15 @@ the key name. Here is a map of name index values to key prefixes: · 21 unmodified lines | ||
| 167 | 167 | * - 1 |
| 168 | 168 | - “user.” |
| 169 | 169 | * - 2 |
| 170 | − - “system.posix\_acl\_access” | |
| 170 | + - “system.posix_acl_access” | |
| 171 | 171 | * - 3 |
| 172 | − - “system.posix\_acl\_default” | |
| 172 | + - “system.posix_acl_default” | |
| 173 | 173 | * - 4 |
| 174 | 174 | - “trusted.” |
| 175 | 175 | * - 6 |
| 176 | 176 | - “security.” |
| 177 | 177 | * - 7 |
| 178 | − - “system.” (inline\_data only?) | |
| 178 | + - “system.” (inline_data only?) | |
| 179 | 179 | * - 8 |
| 180 | 180 | - “system.richacl” (SuSE kernels only?) |
| 181 | 181 | |
| @@ -23,7 +23,7 @@ means that a block group addresses 32 gigabytes instead of 128 megabytes, · 22 unmodified lines | ||
| 23 | 23 | also shrinking the amount of file system overhead for metadata. |
| 24 | 24 | |
| 25 | 25 | The administrator can set a block cluster size at mkfs time (which is |
| 26 | −stored in the s\_log\_cluster\_size field in the superblock); from then | |
| 26 | +stored in the s_log_cluster_size field in the superblock); from then | |
| 27 | 27 | on, the block bitmaps track clusters, not individual blocks. This means |
| 28 | 28 | that block groups can be several gigabytes in size (instead of just |
| 29 | 29 | 128MiB); however, the minimum allocation unit becomes a cluster, not a |
| @@ -9,15 +9,15 @@ group. · 8 unmodified lines | ||
| 9 | 9 | The inode bitmap records which entries in the inode table are in use. |
| 10 | 10 | |
| 11 | 11 | As with most bitmaps, one bit represents the usage status of one data |
| 12 | −block or inode table entry. This implies a block group size of 8 \* | |
| 13 | −number\_of\_bytes\_in\_a\_logical\_block. | |
| 12 | +block or inode table entry. This implies a block group size of 8 * | |
| 13 | +number_of_bytes_in_a_logical_block. | |
| 14 | 14 | |
| 15 | 15 | NOTE: If ``BLOCK_UNINIT`` is set for a given block group, various parts |
| 16 | 16 | of the kernel and e2fsprogs code pretends that the block bitmap contains |
| 17 | 17 | zeros (i.e. all blocks in the group are free). However, it is not |
| 18 | 18 | necessarily the case that no blocks are in use -- if ``meta_bg`` is set, |
| 19 | 19 | the bitmaps and group descriptor live inside the group. Unfortunately, |
| 20 | −ext2fs\_test\_block\_bitmap2() will return '0' for those locations, | |
| 20 | +ext2fs_test_block_bitmap2() will return '0' for those locations, | |
| 21 | 21 | which produces confusing debugfs output. |
| 22 | 22 | |
| 23 | 23 | Inode Table |
| @@ -56,39 +56,39 @@ established that the super block and the group descriptor table, if · 55 unmodified lines | ||
| 56 | 56 | present, will be at the beginning of the block group. The bitmaps and |
| 57 | 57 | the inode table can be anywhere, and it is quite possible for the |
| 58 | 58 | bitmaps to come after the inode table, or for both to be in different |
| 59 | −groups (flex\_bg). Leftover space is used for file data blocks, indirect | |
| 59 | +groups (flex_bg). Leftover space is used for file data blocks, indirect | |
| 60 | 60 | block maps, extent tree blocks, and extended attributes. |
| 61 | 61 | |
| 62 | 62 | Flexible Block Groups |
| 63 | 63 | --------------------- |
| 64 | 64 | |
| 65 | 65 | Starting in ext4, there is a new feature called flexible block groups |
| 66 | −(flex\_bg). In a flex\_bg, several block groups are tied together as one | |
| 66 | +(flex_bg). In a flex_bg, several block groups are tied together as one | |
| 67 | 67 | logical block group; the bitmap spaces and the inode table space in the |
| 68 | −first block group of the flex\_bg are expanded to include the bitmaps | |
| 69 | −and inode tables of all other block groups in the flex\_bg. For example, | |
| 70 | −if the flex\_bg size is 4, then group 0 will contain (in order) the | |
| 68 | +first block group of the flex_bg are expanded to include the bitmaps | |
| 69 | +and inode tables of all other block groups in the flex_bg. For example, | |
| 70 | +if the flex_bg size is 4, then group 0 will contain (in order) the | |
| 71 | 71 | superblock, group descriptors, data block bitmaps for groups 0-3, inode |
| 72 | 72 | bitmaps for groups 0-3, inode tables for groups 0-3, and the remaining |
| 73 | 73 | space in group 0 is for file data. The effect of this is to group the |
| 74 | 74 | block group metadata close together for faster loading, and to enable |
| 75 | 75 | large files to be continuous on disk. Backup copies of the superblock |
| 76 | 76 | and group descriptors are always at the beginning of block groups, even |
| 77 | −if flex\_bg is enabled. The number of block groups that make up a | |
| 78 | −flex\_bg is given by 2 ^ ``sb.s_log_groups_per_flex``. | |
| 77 | +if flex_bg is enabled. The number of block groups that make up a | |
| 78 | +flex_bg is given by 2 ^ ``sb.s_log_groups_per_flex``. | |
| 79 | 79 | |
| 80 | 80 | Meta Block Groups |
| 81 | 81 | ----------------- |
| 82 | 82 | |
| 83 | −Without the option META\_BG, for safety concerns, all block group | |
| 83 | +Without the option META_BG, for safety concerns, all block group | |
| 84 | 84 | descriptors copies are kept in the first block group. Given the default |
| 85 | 85 | 128MiB(2^27 bytes) block group size and 64-byte group descriptors, ext4 |
| 86 | 86 | can have at most 2^27/64 = 2^21 block groups. This limits the entire |
| 87 | 87 | filesystem size to 2^21 * 2^27 = 2^48bytes or 256TiB. |
| 88 | 88 | |
| 89 | 89 | The solution to this problem is to use the metablock group feature |
| 90 | −(META\_BG), which is already in ext3 for all 2.6 releases. With the | |
| 91 | −META\_BG feature, ext4 filesystems are partitioned into many metablock | |
| 90 | +(META_BG), which is already in ext3 for all 2.6 releases. With the | |
| 91 | +META_BG feature, ext4 filesystems are partitioned into many metablock | |
| 92 | 92 | groups. Each metablock group is a cluster of block groups whose group |
| 93 | 93 | descriptor structures can be stored in a single disk block. For ext4 |
| 94 | 94 | filesystems with 4 KB block size, a single metablock group partition |
| @@ -110,7 +110,7 @@ bytes, a meta-block group contains 32 block groups for filesystems with · 15 unmodified lines | ||
| 110 | 110 | a 1KB block size, and 128 block groups for filesystems with a 4KB |
| 111 | 111 | blocksize. Filesystems can either be created using this new block group |
| 112 | 112 | descriptor layout, or existing filesystems can be resized on-line, and |
| 113 | −the field s\_first\_meta\_bg in the superblock will indicate the first | |
| 113 | +the field s_first_meta_bg in the superblock will indicate the first | |
| 114 | 114 | block group using this new layout. |
| 115 | 115 | |
| 116 | 116 | Please see an important note about ``BLOCK_UNINIT`` in the section about |
| @@ -121,15 +121,15 @@ Lazy Block Group Initialization · 4 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | A new feature for ext4 are three block group descriptor flags that |
| 123 | 123 | enable mkfs to skip initializing other parts of the block group |
| 124 | −metadata. Specifically, the INODE\_UNINIT and BLOCK\_UNINIT flags mean | |
| 124 | +metadata. Specifically, the INODE_UNINIT and BLOCK_UNINIT flags mean | |
| 125 | 125 | that the inode and block bitmaps for that group can be calculated and |
| 126 | 126 | therefore the on-disk bitmap blocks are not initialized. This is |
| 127 | 127 | generally the case for an empty block group or a block group containing |
| 128 | −only fixed-location block group metadata. The INODE\_ZEROED flag means | |
| 128 | +only fixed-location block group metadata. The INODE_ZEROED flag means | |
| 129 | 129 | that the inode table has been initialized; mkfs will unset this flag and |
| 130 | 130 | rely on the kernel to initialize the inode tables in the background. |
| 131 | 131 | |
| 132 | 132 | By not writing zeroes to the bitmaps and inode table, mkfs time is |
| 133 | −reduced considerably. Note the feature flag is RO\_COMPAT\_GDT\_CSUM, | |
| 134 | −but the dumpe2fs output prints this as “uninit\_bg”. They are the same | |
| 133 | +reduced considerably. Note the feature flag is RO_COMPAT_GDT_CSUM, | |
| 134 | +but the dumpe2fs output prints this as “uninit_bg”. They are the same | |
| 135 | 135 | thing. |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | 3 | +---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| 4 | −| i.i\_block Offset | Where It Points | | |
| 4 | +| i.i_block Offset | Where It Points | | |
| 5 | 5 | +=====================+==============================================================================================================================================================================================================================+ |
| 6 | 6 | | 0 to 11 | Direct map to file blocks 0 to 11. | |
| 7 | 7 | +---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| @@ -4,7 +4,7 @@ Checksums · 3 unmodified lines | ||
| 4 | 4 | --------- |
| 5 | 5 | |
| 6 | 6 | Starting in early 2012, metadata checksums were added to all major ext4 |
| 7 | −and jbd2 data structures. The associated feature flag is metadata\_csum. | |
| 7 | +and jbd2 data structures. The associated feature flag is metadata_csum. | |
| 8 | 8 | The desired checksum algorithm is indicated in the superblock, though as |
| 9 | 9 | of October 2012 the only supported algorithm is crc32c. Some data |
| 10 | 10 | structures did not have space to fit a full 32-bit checksum, so only the |
| @@ -20,7 +20,7 @@ encounters directory blocks that lack sufficient empty space to add a · 9 unmodified lines | ||
| 20 | 20 | checksum, it will request that you run ``e2fsck -D`` to have the |
| 21 | 21 | directories rebuilt with checksums. This has the added benefit of |
| 22 | 22 | removing slack space from the directory files and rebalancing the htree |
| 23 | −indexes. If you \_ignore\_ this step, your directories will not be | |
| 23 | +indexes. If you _ignore_ this step, your directories will not be | |
| 24 | 24 | protected by a checksum! |
| 25 | 25 | |
| 26 | 26 | The following table describes the data elements that go into each type |
| @@ -35,39 +35,39 @@ of checksum. The checksum function is whatever the superblock describes · 8 unmodified lines | ||
| 35 | 35 | - Length |
| 36 | 36 | - Ingredients |
| 37 | 37 | * - Superblock |
| 38 | − - \_\_le32 | |
| 38 | + - __le32 | |
| 39 | 39 | - The entire superblock up to the checksum field. The UUID lives inside |
| 40 | 40 | the superblock. |
| 41 | 41 | * - MMP |
| 42 | − - \_\_le32 | |
| 42 | + - __le32 | |
| 43 | 43 | - UUID + the entire MMP block up to the checksum field. |
| 44 | 44 | * - Extended Attributes |
| 45 | − - \_\_le32 | |
| 45 | + - __le32 | |
| 46 | 46 | - UUID + the entire extended attribute block. The checksum field is set to |
| 47 | 47 | zero. |
| 48 | 48 | * - Directory Entries |
| 49 | − - \_\_le32 | |
| 49 | + - __le32 | |
| 50 | 50 | - UUID + inode number + inode generation + the directory block up to the |
| 51 | 51 | fake entry enclosing the checksum field. |
| 52 | 52 | * - HTREE Nodes |
| 53 | − - \_\_le32 | |
| 53 | + - __le32 | |
| 54 | 54 | - UUID + inode number + inode generation + all valid extents + HTREE tail. |
| 55 | 55 | The checksum field is set to zero. |
| 56 | 56 | * - Extents |
| 57 | − - \_\_le32 | |
| 57 | + - __le32 | |
| 58 | 58 | - UUID + inode number + inode generation + the entire extent block up to |
| 59 | 59 | the checksum field. |
| 60 | 60 | * - Bitmaps |
| 61 | − - \_\_le32 or \_\_le16 | |
| 61 | + - __le32 or __le16 | |
| 62 | 62 | - UUID + the entire bitmap. Checksums are stored in the group descriptor, |
| 63 | 63 | and truncated if the group descriptor size is 32 bytes (i.e. ^64bit) |
| 64 | 64 | * - Inodes |
| 65 | − - \_\_le32 | |
| 65 | + - __le32 | |
| 66 | 66 | - UUID + inode number + inode generation + the entire inode. The checksum |
| 67 | 67 | field is set to zero. Each inode has its own checksum. |
| 68 | 68 | * - Group Descriptors |
| 69 | − - \_\_le16 | |
| 70 | − - If metadata\_csum, then UUID + group number + the entire descriptor; | |
| 71 | − else if gdt\_csum, then crc16(UUID + group number + the entire | |
| 69 | + - __le16 | |
| 70 | + - If metadata_csum, then UUID + group number + the entire descriptor; | |
| 71 | + else if gdt_csum, then crc16(UUID + group number + the entire | |
| 72 | 72 | descriptor). In all cases, only the lower 16 bits are stored. |
| 73 | 73 | |
| @@ -42,24 +42,24 @@ is at most 263 bytes long, though on disk you'll need to reference · 41 unmodified lines | ||
| 42 | 42 | - Name |
| 43 | 43 | - Description |
| 44 | 44 | * - 0x0 |
| 45 | − - \_\_le32 | |
| 45 | + - __le32 | |
| 46 | 46 | - inode |
| 47 | 47 | - Number of the inode that this directory entry points to. |
| 48 | 48 | * - 0x4 |
| 49 | − - \_\_le16 | |
| 50 | − - rec\_len | |
| 49 | + - __le16 | |
| 50 | + - rec_len | |
| 51 | 51 | - Length of this directory entry. Must be a multiple of 4. |
| 52 | 52 | * - 0x6 |
| 53 | − - \_\_le16 | |
| 54 | − - name\_len | |
| 53 | + - __le16 | |
| 54 | + - name_len | |
| 55 | 55 | - Length of the file name. |
| 56 | 56 | * - 0x8 |
| 57 | 57 | - char |
| 58 | − - name[EXT4\_NAME\_LEN] | |
| 58 | + - name[EXT4_NAME_LEN] | |
| 59 | 59 | - File name. |
| 60 | 60 | |
| 61 | 61 | Since file names cannot be longer than 255 bytes, the new directory |
| 62 | −entry format shortens the name\_len field and uses the space for a file | |
| 62 | +entry format shortens the name_len field and uses the space for a file | |
| 63 | 63 | type flag, probably to avoid having to load every inode during directory |
| 64 | 64 | tree traversal. This format is ``ext4_dir_entry_2``, which is at most |
| 65 | 65 | 263 bytes long, though on disk you'll need to reference |
| @@ -74,24 +74,24 @@ tree traversal. This format is ``ext4_dir_entry_2``, which is at most · 8 unmodified lines | ||
| 74 | 74 | - Name |
| 75 | 75 | - Description |
| 76 | 76 | * - 0x0 |
| 77 | − - \_\_le32 | |
| 77 | + - __le32 | |
| 78 | 78 | - inode |
| 79 | 79 | - Number of the inode that this directory entry points to. |
| 80 | 80 | * - 0x4 |
| 81 | − - \_\_le16 | |
| 82 | − - rec\_len | |
| 81 | + - __le16 | |
| 82 | + - rec_len | |
| 83 | 83 | - Length of this directory entry. |
| 84 | 84 | * - 0x6 |
| 85 | − - \_\_u8 | |
| 86 | − - name\_len | |
| 85 | + - __u8 | |
| 86 | + - name_len | |
| 87 | 87 | - Length of the file name. |
| 88 | 88 | * - 0x7 |
| 89 | − - \_\_u8 | |
| 90 | − - file\_type | |
| 89 | + - __u8 | |
| 90 | + - file_type | |
| 91 | 91 | - File type code, see ftype_ table below. |
| 92 | 92 | * - 0x8 |
| 93 | 93 | - char |
| 94 | − - name[EXT4\_NAME\_LEN] | |
| 94 | + - name[EXT4_NAME_LEN] | |
| 95 | 95 | - File name. |
| 96 | 96 | |
| 97 | 97 | .. _ftype: |
| @@ -137,19 +137,19 @@ entry uses this extension, it may be up to 271 bytes. · 39 unmodified lines | ||
| 137 | 137 | - Name |
| 138 | 138 | - Description |
| 139 | 139 | * - 0x0 |
| 140 | − - \_\_le32 | |
| 140 | + - __le32 | |
| 141 | 141 | - hash |
| 142 | 142 | - The hash of the directory name |
| 143 | 143 | * - 0x4 |
| 144 | − - \_\_le32 | |
| 145 | − - minor\_hash | |
| 144 | + - __le32 | |
| 145 | + - minor_hash | |
| 146 | 146 | - The minor hash of the directory name |
| 147 | 147 | |
| 148 | 148 | |
| 149 | 149 | In order to add checksums to these classic directory blocks, a phony |
| 150 | 150 | ``struct ext4_dir_entry`` is placed at the end of each leaf block to |
| 151 | 151 | hold the checksum. The directory entry is 12 bytes long. The inode |
| 152 | −number and name\_len fields are set to zero to fool old software into | |
| 152 | +number and name_len fields are set to zero to fool old software into | |
| 153 | 153 | ignoring an apparently empty directory entry, and the checksum is stored |
| 154 | 154 | in the place where the name normally goes. The structure is |
| 155 | 155 | ``struct ext4_dir_entry_tail``: |
| @@ -163,24 +163,24 @@ in the place where the name normally goes. The structure is · 7 unmodified lines | ||
| 163 | 163 | - Name |
| 164 | 164 | - Description |
| 165 | 165 | * - 0x0 |
| 166 | − - \_\_le32 | |
| 167 | − - det\_reserved\_zero1 | |
| 166 | + - __le32 | |
| 167 | + - det_reserved_zero1 | |
| 168 | 168 | - Inode number, which must be zero. |
| 169 | 169 | * - 0x4 |
| 170 | − - \_\_le16 | |
| 171 | − - det\_rec\_len | |
| 170 | + - __le16 | |
| 171 | + - det_rec_len | |
| 172 | 172 | - Length of this directory entry, which must be 12. |
| 173 | 173 | * - 0x6 |
| 174 | − - \_\_u8 | |
| 175 | − - det\_reserved\_zero2 | |
| 174 | + - __u8 | |
| 175 | + - det_reserved_zero2 | |
| 176 | 176 | - Length of the file name, which must be zero. |
| 177 | 177 | * - 0x7 |
| 178 | − - \_\_u8 | |
| 179 | − - det\_reserved\_ft | |
| 178 | + - __u8 | |
| 179 | + - det_reserved_ft | |
| 180 | 180 | - File type, which must be 0xDE. |
| 181 | 181 | * - 0x8 |
| 182 | − - \_\_le32 | |
| 183 | − - det\_checksum | |
| 182 | + - __le32 | |
| 183 | + - det_checksum | |
| 184 | 184 | - Directory leaf block checksum. |
| 185 | 185 | |
| 186 | 186 | The leaf directory block checksum is calculated against the FS UUID, the |
| @@ -194,7 +194,7 @@ Hash Tree Directories · 7 unmodified lines | ||
| 194 | 194 | A linear array of directory entries isn't great for performance, so a |
| 195 | 195 | new feature was added to ext3 to provide a faster (but peculiar) |
| 196 | 196 | balanced tree keyed off a hash of the directory entry name. If the |
| 197 | −EXT4\_INDEX\_FL (0x1000) flag is set in the inode, this directory uses a | |
| 197 | +EXT4_INDEX_FL (0x1000) flag is set in the inode, this directory uses a | |
| 198 | 198 | hashed btree (htree) to organize and find directory entries. For |
| 199 | 199 | backwards read-only compatibility with ext2, this tree is actually |
| 200 | 200 | hidden inside the directory file, masquerading as “empty” directory data |
| @@ -206,14 +206,14 @@ rest of the directory block is empty so that it moves on. · 5 unmodified lines | ||
| 206 | 206 | The root of the tree always lives in the first data block of the |
| 207 | 207 | directory. By ext2 custom, the '.' and '..' entries must appear at the |
| 208 | 208 | beginning of this first block, so they are put here as two |
| 209 | −``struct ext4_dir_entry_2``\ s and not stored in the tree. The rest of | |
| 209 | +``struct ext4_dir_entry_2`` s and not stored in the tree. The rest of | |
| 210 | 210 | the root node contains metadata about the tree and finally a hash->block |
| 211 | 211 | map to find nodes that are lower in the htree. If |
| 212 | 212 | ``dx_root.info.indirect_levels`` is non-zero then the htree has two |
| 213 | 213 | levels; the data block pointed to by the root node's map is an interior |
| 214 | 214 | node, which is indexed by a minor hash. Interior nodes in this tree |
| 215 | 215 | contains a zeroed out ``struct ext4_dir_entry_2`` followed by a |
| 216 | −minor\_hash->block map to find leafe nodes. Leaf nodes contain a linear | |
| 216 | +minor_hash->block map to find leafe nodes. Leaf nodes contain a linear | |
| 217 | 217 | array of all ``struct ext4_dir_entry_2``; all of these entries |
| 218 | 218 | (presumably) hash to the same value. If there is an overflow, the |
| 219 | 219 | entries simply overflow into the next leaf node, and the |
| @@ -245,83 +245,83 @@ of a data block: · 25 unmodified lines | ||
| 245 | 245 | - Name |
| 246 | 246 | - Description |
| 247 | 247 | * - 0x0 |
| 248 | − - \_\_le32 | |
| 248 | + - __le32 | |
| 249 | 249 | - dot.inode |
| 250 | 250 | - inode number of this directory. |
| 251 | 251 | * - 0x4 |
| 252 | − - \_\_le16 | |
| 253 | − - dot.rec\_len | |
| 252 | + - __le16 | |
| 253 | + - dot.rec_len | |
| 254 | 254 | - Length of this record, 12. |
| 255 | 255 | * - 0x6 |
| 256 | 256 | - u8 |
| 257 | − - dot.name\_len | |
| 257 | + - dot.name_len | |
| 258 | 258 | - Length of the name, 1. |
| 259 | 259 | * - 0x7 |
| 260 | 260 | - u8 |
| 261 | − - dot.file\_type | |
| 261 | + - dot.file_type | |
| 262 | 262 | - File type of this entry, 0x2 (directory) (if the feature flag is set). |
| 263 | 263 | * - 0x8 |
| 264 | 264 | - char |
| 265 | 265 | - dot.name[4] |
| 266 | − - “.\\0\\0\\0” | |
| 266 | + - “.\0\0\0” | |
| 267 | 267 | * - 0xC |
| 268 | − - \_\_le32 | |
| 268 | + - __le32 | |
| 269 | 269 | - dotdot.inode |
| 270 | 270 | - inode number of parent directory. |
| 271 | 271 | * - 0x10 |
| 272 | − - \_\_le16 | |
| 273 | − - dotdot.rec\_len | |
| 274 | − - block\_size - 12. The record length is long enough to cover all htree | |
| 272 | + - __le16 | |
| 273 | + - dotdot.rec_len | |
| 274 | + - block_size - 12. The record length is long enough to cover all htree | |
| 275 | 275 | data. |
| 276 | 276 | * - 0x12 |
| 277 | 277 | - u8 |
| 278 | − - dotdot.name\_len | |
| 278 | + - dotdot.name_len | |
| 279 | 279 | - Length of the name, 2. |
| 280 | 280 | * - 0x13 |
| 281 | 281 | - u8 |
| 282 | − - dotdot.file\_type | |
| 282 | + - dotdot.file_type | |
| 283 | 283 | - File type of this entry, 0x2 (directory) (if the feature flag is set). |
| 284 | 284 | * - 0x14 |
| 285 | 285 | - char |
| 286 | − - dotdot\_name[4] | |
| 287 | − - “..\\0\\0” | |
| 286 | + - dotdot_name[4] | |
| 287 | + - “..\0\0” | |
| 288 | 288 | * - 0x18 |
| 289 | − - \_\_le32 | |
| 290 | − - struct dx\_root\_info.reserved\_zero | |
| 289 | + - __le32 | |
| 290 | + - struct dx_root_info.reserved_zero | |
| 291 | 291 | - Zero. |
| 292 | 292 | * - 0x1C |
| 293 | 293 | - u8 |
| 294 | − - struct dx\_root\_info.hash\_version | |
| 294 | + - struct dx_root_info.hash_version | |
| 295 | 295 | - Hash type, see dirhash_ table below. |
| 296 | 296 | * - 0x1D |
| 297 | 297 | - u8 |
| 298 | − - struct dx\_root\_info.info\_length | |
| 298 | + - struct dx_root_info.info_length | |
| 299 | 299 | - Length of the tree information, 0x8. |
| 300 | 300 | * - 0x1E |
| 301 | 301 | - u8 |
| 302 | − - struct dx\_root\_info.indirect\_levels | |
| 303 | − - Depth of the htree. Cannot be larger than 3 if the INCOMPAT\_LARGEDIR | |
| 302 | + - struct dx_root_info.indirect_levels | |
| 303 | + - Depth of the htree. Cannot be larger than 3 if the INCOMPAT_LARGEDIR | |
| 304 | 304 | feature is set; cannot be larger than 2 otherwise. |
| 305 | 305 | * - 0x1F |
| 306 | 306 | - u8 |
| 307 | − - struct dx\_root\_info.unused\_flags | |
| 307 | + - struct dx_root_info.unused_flags | |
| 308 | 308 | - |
| 309 | 309 | * - 0x20 |
| 310 | − - \_\_le16 | |
| 310 | + - __le16 | |
| 311 | 311 | - limit |
| 312 | − - Maximum number of dx\_entries that can follow this header, plus 1 for | |
| 312 | + - Maximum number of dx_entries that can follow this header, plus 1 for | |
| 313 | 313 | the header itself. |
| 314 | 314 | * - 0x22 |
| 315 | − - \_\_le16 | |
| 315 | + - __le16 | |
| 316 | 316 | - count |
| 317 | − - Actual number of dx\_entries that follow this header, plus 1 for the | |
| 317 | + - Actual number of dx_entries that follow this header, plus 1 for the | |
| 318 | 318 | header itself. |
| 319 | 319 | * - 0x24 |
| 320 | − - \_\_le32 | |
| 320 | + - __le32 | |
| 321 | 321 | - block |
| 322 | 322 | - The block number (within the directory file) that goes with hash=0. |
| 323 | 323 | * - 0x28 |
| 324 | − - struct dx\_entry | |
| 324 | + - struct dx_entry | |
| 325 | 325 | - entries[0] |
| 326 | 326 | - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block. |
| 327 | 327 | |
| @@ -362,38 +362,38 @@ also the full length of a data block: · 34 unmodified lines | ||
| 362 | 362 | - Name |
| 363 | 363 | - Description |
| 364 | 364 | * - 0x0 |
| 365 | − - \_\_le32 | |
| 365 | + - __le32 | |
| 366 | 366 | - fake.inode |
| 367 | 367 | - Zero, to make it look like this entry is not in use. |
| 368 | 368 | * - 0x4 |
| 369 | − - \_\_le16 | |
| 370 | − - fake.rec\_len | |
| 371 | − - The size of the block, in order to hide all of the dx\_node data. | |
| 369 | + - __le16 | |
| 370 | + - fake.rec_len | |
| 371 | + - The size of the block, in order to hide all of the dx_node data. | |
| 372 | 372 | * - 0x6 |
| 373 | 373 | - u8 |
| 374 | − - name\_len | |
| 374 | + - name_len | |
| 375 | 375 | - Zero. There is no name for this “unused” directory entry. |
| 376 | 376 | * - 0x7 |
| 377 | 377 | - u8 |
| 378 | − - file\_type | |
| 378 | + - file_type | |
| 379 | 379 | - Zero. There is no file type for this “unused” directory entry. |
| 380 | 380 | * - 0x8 |
| 381 | − - \_\_le16 | |
| 381 | + - __le16 | |
| 382 | 382 | - limit |
| 383 | − - Maximum number of dx\_entries that can follow this header, plus 1 for | |
| 383 | + - Maximum number of dx_entries that can follow this header, plus 1 for | |
| 384 | 384 | the header itself. |
| 385 | 385 | * - 0xA |
| 386 | − - \_\_le16 | |
| 386 | + - __le16 | |
| 387 | 387 | - count |
| 388 | − - Actual number of dx\_entries that follow this header, plus 1 for the | |
| 388 | + - Actual number of dx_entries that follow this header, plus 1 for the | |
| 389 | 389 | header itself. |
| 390 | 390 | * - 0xE |
| 391 | − - \_\_le32 | |
| 391 | + - __le32 | |
| 392 | 392 | - block |
| 393 | 393 | - The block number (within the directory file) that goes with the lowest |
| 394 | 394 | hash value of this block. This value is stored in the parent block. |
| 395 | 395 | * - 0x12 |
| 396 | − - struct dx\_entry | |
| 396 | + - struct dx_entry | |
| 397 | 397 | - entries[0] |
| 398 | 398 | - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block. |
| 399 | 399 | |
| @@ -410,11 +410,11 @@ long: · 10 unmodified lines | ||
| 410 | 410 | - Name |
| 411 | 411 | - Description |
| 412 | 412 | * - 0x0 |
| 413 | − - \_\_le32 | |
| 413 | + - __le32 | |
| 414 | 414 | - hash |
| 415 | 415 | - Hash code. |
| 416 | 416 | * - 0x4 |
| 417 | − - \_\_le32 | |
| 417 | + - __le32 | |
| 418 | 418 | - block |
| 419 | 419 | - Block number (within the directory file, not filesystem blocks) of the |
| 420 | 420 | next node in the htree. |
| @@ -423,13 +423,13 @@ long: · 2 unmodified lines | ||
| 423 | 423 | author.) |
| 424 | 424 | |
| 425 | 425 | If metadata checksums are enabled, the last 8 bytes of the directory |
| 426 | −block (precisely the length of one dx\_entry) are used to store a | |
| 426 | +block (precisely the length of one dx_entry) are used to store a | |
| 427 | 427 | ``struct dx_tail``, which contains the checksum. The ``limit`` and |
| 428 | −``count`` entries in the dx\_root/dx\_node structures are adjusted as | |
| 429 | −necessary to fit the dx\_tail into the block. If there is no space for | |
| 430 | −the dx\_tail, the user is notified to run e2fsck -D to rebuild the | |
| 428 | +``count`` entries in the dx_root/dx_node structures are adjusted as | |
| 429 | +necessary to fit the dx_tail into the block. If there is no space for | |
| 430 | +the dx_tail, the user is notified to run e2fsck -D to rebuild the | |
| 431 | 431 | directory index (which will ensure that there's space for the checksum. |
| 432 | −The dx\_tail structure is 8 bytes long and looks like this: | |
| 432 | +The dx_tail structure is 8 bytes long and looks like this: | |
| 433 | 433 | |
| 434 | 434 | .. list-table:: |
| 435 | 435 | :widths: 8 8 24 40 |
| @@ -441,13 +441,13 @@ The dx\_tail structure is 8 bytes long and looks like this: · 5 unmodified lines | ||
| 441 | 441 | - Description |
| 442 | 442 | * - 0x0 |
| 443 | 443 | - u32 |
| 444 | − - dt\_reserved | |
| 444 | + - dt_reserved | |
| 445 | 445 | - Zero. |
| 446 | 446 | * - 0x4 |
| 447 | − - \_\_le32 | |
| 448 | − - dt\_checksum | |
| 447 | + - __le32 | |
| 448 | + - dt_checksum | |
| 449 | 449 | - Checksum of the htree directory block. |
| 450 | 450 | |
| 451 | 451 | The checksum is calculated against the FS UUID, the htree index header |
| 452 | −(dx\_root or dx\_node), all of the htree indices (dx\_entry) that are in | |
| 453 | −use, and the tail block (dx\_tail). | |
| 452 | +(dx_root or dx_node), all of the htree indices (dx_entry) that are in | |
| 453 | +use, and the tail block (dx_tail). | |
| @@ -5,14 +5,14 @@ Large Extended Attribute Values · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | To enable ext4 to store extended attribute values that do not fit in the |
| 7 | 7 | inode or in the single extended attribute block attached to an inode, |
| 8 | −the EA\_INODE feature allows us to store the value in the data blocks of | |
| 8 | +the EA_INODE feature allows us to store the value in the data blocks of | |
| 9 | 9 | a regular file inode. This “EA inode” is linked only from the extended |
| 10 | 10 | attribute name index and must not appear in a directory entry. The |
| 11 | −inode's i\_atime field is used to store a checksum of the xattr value; | |
| 12 | −and i\_ctime/i\_version store a 64-bit reference count, which enables | |
| 11 | +inode's i_atime field is used to store a checksum of the xattr value; | |
| 12 | +and i_ctime/i_version store a 64-bit reference count, which enables | |
| 13 | 13 | sharing of large xattr values between multiple owning inodes. For |
| 14 | 14 | backward compatibility with older versions of this feature, the |
| 15 | −i\_mtime/i\_generation *may* store a back-reference to the inode number | |
| 16 | −and i\_generation of the **one** owning inode (in cases where the EA | |
| 15 | +i_mtime/i_generation *may* store a back-reference to the inode number | |
| 16 | +and i_generation of the **one** owning inode (in cases where the EA | |
| 17 | 17 | inode is not referenced by multiple inodes) to verify that the EA inode |
| 18 | 18 | is the correct one being accessed. |
| @@ -7,34 +7,34 @@ Each block group on the filesystem has one of these descriptors · 6 unmodified lines | ||
| 7 | 7 | associated with it. As noted in the Layout section above, the group |
| 8 | 8 | descriptors (if present) are the second item in the block group. The |
| 9 | 9 | standard configuration is for each block group to contain a full copy of |
| 10 | −the block group descriptor table unless the sparse\_super feature flag | |
| 10 | +the block group descriptor table unless the sparse_super feature flag | |
| 11 | 11 | is set. |
| 12 | 12 | |
| 13 | 13 | Notice how the group descriptor records the location of both bitmaps and |
| 14 | 14 | the inode table (i.e. they can float). This means that within a block |
| 15 | 15 | group, the only data structures with fixed locations are the superblock |
| 16 | −and the group descriptor table. The flex\_bg mechanism uses this | |
| 16 | +and the group descriptor table. The flex_bg mechanism uses this | |
| 17 | 17 | property to group several block groups into a flex group and lay out all |
| 18 | 18 | of the groups' bitmaps and inode tables into one long run in the first |
| 19 | 19 | group of the flex group. |
| 20 | 20 | |
| 21 | −If the meta\_bg feature flag is set, then several block groups are | |
| 22 | −grouped together into a meta group. Note that in the meta\_bg case, | |
| 21 | +If the meta_bg feature flag is set, then several block groups are | |
| 22 | +grouped together into a meta group. Note that in the meta_bg case, | |
| 23 | 23 | however, the first and last two block groups within the larger meta |
| 24 | 24 | group contain only group descriptors for the groups inside the meta |
| 25 | 25 | group. |
| 26 | 26 | |
| 27 | −flex\_bg and meta\_bg do not appear to be mutually exclusive features. | |
| 27 | +flex_bg and meta_bg do not appear to be mutually exclusive features. | |
| 28 | 28 | |
| 29 | 29 | In ext2, ext3, and ext4 (when the 64bit feature is not enabled), the |
| 30 | 30 | block group descriptor was only 32 bytes long and therefore ends at |
| 31 | −bg\_checksum. On an ext4 filesystem with the 64bit feature enabled, the | |
| 31 | +bg_checksum. On an ext4 filesystem with the 64bit feature enabled, the | |
| 32 | 32 | block group descriptor expands to at least the 64 bytes described below; |
| 33 | 33 | the size is stored in the superblock. |
| 34 | 34 | |
| 35 | −If gdt\_csum is set and metadata\_csum is not set, the block group | |
| 35 | +If gdt_csum is set and metadata_csum is not set, the block group | |
| 36 | 36 | checksum is the crc16 of the FS UUID, the group number, and the group |
| 37 | −descriptor structure. If metadata\_csum is set, then the block group | |
| 37 | +descriptor structure. If metadata_csum is set, then the block group | |
| 38 | 38 | checksum is the lower 16 bits of the checksum of the FS UUID, the group |
| 39 | 39 | number, and the group descriptor structure. Both block and inode bitmap |
| 40 | 40 | checksums are calculated against the FS UUID, the group number, and the |
| @@ -51,59 +51,59 @@ The block group descriptor is laid out in ``struct ext4_group_desc``. · 10 unmodified lines | ||
| 51 | 51 | - Name |
| 52 | 52 | - Description |
| 53 | 53 | * - 0x0 |
| 54 | − - \_\_le32 | |
| 55 | − - bg\_block\_bitmap\_lo | |
| 54 | + - __le32 | |
| 55 | + - bg_block_bitmap_lo | |
| 56 | 56 | - Lower 32-bits of location of block bitmap. |
| 57 | 57 | * - 0x4 |
| 58 | − - \_\_le32 | |
| 59 | − - bg\_inode\_bitmap\_lo | |
| 58 | + - __le32 | |
| 59 | + - bg_inode_bitmap_lo | |
| 60 | 60 | - Lower 32-bits of location of inode bitmap. |
| 61 | 61 | * - 0x8 |
| 62 | − - \_\_le32 | |
| 63 | − - bg\_inode\_table\_lo | |
| 62 | + - __le32 | |
| 63 | + - bg_inode_table_lo | |
| 64 | 64 | - Lower 32-bits of location of inode table. |
| 65 | 65 | * - 0xC |
| 66 | − - \_\_le16 | |
| 67 | − - bg\_free\_blocks\_count\_lo | |
| 66 | + - __le16 | |
| 67 | + - bg_free_blocks_count_lo | |
| 68 | 68 | - Lower 16-bits of free block count. |
| 69 | 69 | * - 0xE |
| 70 | − - \_\_le16 | |
| 71 | − - bg\_free\_inodes\_count\_lo | |
| 70 | + - __le16 | |
| 71 | + - bg_free_inodes_count_lo | |
| 72 | 72 | - Lower 16-bits of free inode count. |
| 73 | 73 | * - 0x10 |
| 74 | − - \_\_le16 | |
| 75 | − - bg\_used\_dirs\_count\_lo | |
| 74 | + - __le16 | |
| 75 | + - bg_used_dirs_count_lo | |
| 76 | 76 | - Lower 16-bits of directory count. |
| 77 | 77 | * - 0x12 |
| 78 | − - \_\_le16 | |
| 79 | − - bg\_flags | |
| 78 | + - __le16 | |
| 79 | + - bg_flags | |
| 80 | 80 | - Block group flags. See the bgflags_ table below. |
| 81 | 81 | * - 0x14 |
| 82 | − - \_\_le32 | |
| 83 | − - bg\_exclude\_bitmap\_lo | |
| 82 | + - __le32 | |
| 83 | + - bg_exclude_bitmap_lo | |
| 84 | 84 | - Lower 32-bits of location of snapshot exclusion bitmap. |
| 85 | 85 | * - 0x18 |
| 86 | − - \_\_le16 | |
| 87 | − - bg\_block\_bitmap\_csum\_lo | |
| 86 | + - __le16 | |
| 87 | + - bg_block_bitmap_csum_lo | |
| 88 | 88 | - Lower 16-bits of the block bitmap checksum. |
| 89 | 89 | * - 0x1A |
| 90 | − - \_\_le16 | |
| 91 | − - bg\_inode\_bitmap\_csum\_lo | |
| 90 | + - __le16 | |
| 91 | + - bg_inode_bitmap_csum_lo | |
| 92 | 92 | - Lower 16-bits of the inode bitmap checksum. |
| 93 | 93 | * - 0x1C |
| 94 | − - \_\_le16 | |
| 95 | − - bg\_itable\_unused\_lo | |
| 94 | + - __le16 | |
| 95 | + - bg_itable_unused_lo | |
| 96 | 96 | - Lower 16-bits of unused inode count. If set, we needn't scan past the |
| 97 | − ``(sb.s_inodes_per_group - gdt.bg_itable_unused)``\ th entry in the | |
| 97 | + ``(sb.s_inodes_per_group - gdt.bg_itable_unused)`` th entry in the | |
| 98 | 98 | inode table for this group. |
| 99 | 99 | * - 0x1E |
| 100 | − - \_\_le16 | |
| 101 | − - bg\_checksum | |
| 102 | − - Group descriptor checksum; crc16(sb\_uuid+group\_num+bg\_desc) if the | |
| 103 | − RO\_COMPAT\_GDT\_CSUM feature is set, or | |
| 104 | − crc32c(sb\_uuid+group\_num+bg\_desc) & 0xFFFF if the | |
| 105 | − RO\_COMPAT\_METADATA\_CSUM feature is set. The bg\_checksum | |
| 106 | − field in bg\_desc is skipped when calculating crc16 checksum, | |
| 100 | + - __le16 | |
| 101 | + - bg_checksum | |
| 102 | + - Group descriptor checksum; crc16(sb_uuid+group_num+bg_desc) if the | |
| 103 | + RO_COMPAT_GDT_CSUM feature is set, or | |
| 104 | + crc32c(sb_uuid+group_num+bg_desc) & 0xFFFF if the | |
| 105 | + RO_COMPAT_METADATA_CSUM feature is set. The bg_checksum | |
| 106 | + field in bg_desc is skipped when calculating crc16 checksum, | |
| 107 | 107 | and set to zero if crc32c checksum is used. |
| 108 | 108 | * - |
| 109 | 109 | - |
| @@ -111,48 +111,48 @@ The block group descriptor is laid out in ``struct ext4_group_desc``. · 1 unmodified line | ||
| 111 | 111 | - These fields only exist if the 64bit feature is enabled and s_desc_size |
| 112 | 112 | > 32. |
| 113 | 113 | * - 0x20 |
| 114 | − - \_\_le32 | |
| 115 | − - bg\_block\_bitmap\_hi | |
| 114 | + - __le32 | |
| 115 | + - bg_block_bitmap_hi | |
| 116 | 116 | - Upper 32-bits of location of block bitmap. |
| 117 | 117 | * - 0x24 |
| 118 | − - \_\_le32 | |
| 119 | − - bg\_inode\_bitmap\_hi | |
| 118 | + - __le32 | |
| 119 | + - bg_inode_bitmap_hi | |
| 120 | 120 | - Upper 32-bits of location of inodes bitmap. |
| 121 | 121 | * - 0x28 |
| 122 | − - \_\_le32 | |
| 123 | − - bg\_inode\_table\_hi | |
| 122 | + - __le32 | |
| 123 | + - bg_inode_table_hi | |
| 124 | 124 | - Upper 32-bits of location of inodes table. |
| 125 | 125 | * - 0x2C |
| 126 | − - \_\_le16 | |
| 127 | − - bg\_free\_blocks\_count\_hi | |
| 126 | + - __le16 | |
| 127 | + - bg_free_blocks_count_hi | |
| 128 | 128 | - Upper 16-bits of free block count. |
| 129 | 129 | * - 0x2E |
| 130 | − - \_\_le16 | |
| 131 | − - bg\_free\_inodes\_count\_hi | |
| 130 | + - __le16 | |
| 131 | + - bg_free_inodes_count_hi | |
| 132 | 132 | - Upper 16-bits of free inode count. |
| 133 | 133 | * - 0x30 |
| 134 | − - \_\_le16 | |
| 135 | − - bg\_used\_dirs\_count\_hi | |
| 134 | + - __le16 | |
| 135 | + - bg_used_dirs_count_hi | |
| 136 | 136 | - Upper 16-bits of directory count. |
| 137 | 137 | * - 0x32 |
| 138 | − - \_\_le16 | |
| 139 | − - bg\_itable\_unused\_hi | |
| 138 | + - __le16 | |
| 139 | + - bg_itable_unused_hi | |
| 140 | 140 | - Upper 16-bits of unused inode count. |
| 141 | 141 | * - 0x34 |
| 142 | − - \_\_le32 | |
| 143 | − - bg\_exclude\_bitmap\_hi | |
| 142 | + - __le32 | |
| 143 | + - bg_exclude_bitmap_hi | |
| 144 | 144 | - Upper 32-bits of location of snapshot exclusion bitmap. |
| 145 | 145 | * - 0x38 |
| 146 | − - \_\_le16 | |
| 147 | − - bg\_block\_bitmap\_csum\_hi | |
| 146 | + - __le16 | |
| 147 | + - bg_block_bitmap_csum_hi | |
| 148 | 148 | - Upper 16-bits of the block bitmap checksum. |
| 149 | 149 | * - 0x3A |
| 150 | − - \_\_le16 | |
| 151 | − - bg\_inode\_bitmap\_csum\_hi | |
| 150 | + - __le16 | |
| 151 | + - bg_inode_bitmap_csum_hi | |
| 152 | 152 | - Upper 16-bits of the inode bitmap checksum. |
| 153 | 153 | * - 0x3C |
| 154 | − - \_\_u32 | |
| 155 | − - bg\_reserved | |
| 154 | + - __u32 | |
| 155 | + - bg_reserved | |
| 156 | 156 | - Padding to 64 bytes. |
| 157 | 157 | |
| 158 | 158 | .. _bgflags: |
| @@ -166,8 +166,8 @@ Block group flags can be any combination of the following: · 7 unmodified lines | ||
| 166 | 166 | * - Value |
| 167 | 167 | - Description |
| 168 | 168 | * - 0x1 |
| 169 | − - inode table and bitmap are not initialized (EXT4\_BG\_INODE\_UNINIT). | |
| 169 | + - inode table and bitmap are not initialized (EXT4_BG_INODE_UNINIT). | |
| 170 | 170 | * - 0x2 |
| 171 | − - block bitmap is not initialized (EXT4\_BG\_BLOCK\_UNINIT). | |
| 171 | + - block bitmap is not initialized (EXT4_BG_BLOCK_UNINIT). | |
| 172 | 172 | * - 0x4 |
| 173 | − - inode table is zeroed (EXT4\_BG\_INODE\_ZEROED). | |
| 173 | + - inode table is zeroed (EXT4_BG_INODE_ZEROED). | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | −The Contents of inode.i\_block | |
| 3 | +The Contents of inode.i_block | |
| 4 | 4 | ------------------------------ |
| 5 | 5 | |
| 6 | 6 | Depending on the type of file an inode describes, the 60 bytes of |
| @@ -47,7 +47,7 @@ In ext4, the file to logical block map has been replaced with an extent · 40 unmodified lines | ||
| 47 | 47 | tree. Under the old scheme, allocating a contiguous run of 1,000 blocks |
| 48 | 48 | requires an indirect block to map all 1,000 entries; with extents, the |
| 49 | 49 | mapping is reduced to a single ``struct ext4_extent`` with |
| 50 | −``ee_len = 1000``. If flex\_bg is enabled, it is possible to allocate | |
| 50 | +``ee_len = 1000``. If flex_bg is enabled, it is possible to allocate | |
| 51 | 51 | very large files with a single extent, at a considerable reduction in |
| 52 | 52 | metadata block use, and some improvement in disk efficiency. The inode |
| 53 | 53 | must have the extents flag (0x80000) flag set for this feature to be in |
| @@ -76,28 +76,28 @@ which is 12 bytes long: · 22 unmodified lines | ||
| 76 | 76 | - Name |
| 77 | 77 | - Description |
| 78 | 78 | * - 0x0 |
| 79 | − - \_\_le16 | |
| 80 | − - eh\_magic | |
| 79 | + - __le16 | |
| 80 | + - eh_magic | |
| 81 | 81 | - Magic number, 0xF30A. |
| 82 | 82 | * - 0x2 |
| 83 | − - \_\_le16 | |
| 84 | − - eh\_entries | |
| 83 | + - __le16 | |
| 84 | + - eh_entries | |
| 85 | 85 | - Number of valid entries following the header. |
| 86 | 86 | * - 0x4 |
| 87 | − - \_\_le16 | |
| 88 | − - eh\_max | |
| 87 | + - __le16 | |
| 88 | + - eh_max | |
| 89 | 89 | - Maximum number of entries that could follow the header. |
| 90 | 90 | * - 0x6 |
| 91 | − - \_\_le16 | |
| 92 | − - eh\_depth | |
| 91 | + - __le16 | |
| 92 | + - eh_depth | |
| 93 | 93 | - Depth of this extent node in the extent tree. 0 = this extent node |
| 94 | 94 | points to data blocks; otherwise, this extent node points to other |
| 95 | 95 | extent nodes. The extent tree can be at most 5 levels deep: a logical |
| 96 | 96 | block number can be at most ``2^32``, and the smallest ``n`` that |
| 97 | 97 | satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5. |
| 98 | 98 | * - 0x8 |
| 99 | − - \_\_le32 | |
| 100 | − - eh\_generation | |
| 99 | + - __le32 | |
| 100 | + - eh_generation | |
| 101 | 101 | - Generation of the tree. (Used by Lustre, but not standard ext4). |
| 102 | 102 | |
| 103 | 103 | Internal nodes of the extent tree, also known as index nodes, are |
| @@ -112,22 +112,22 @@ recorded as ``struct ext4_extent_idx``, and are 12 bytes long: · 8 unmodified lines | ||
| 112 | 112 | - Name |
| 113 | 113 | - Description |
| 114 | 114 | * - 0x0 |
| 115 | − - \_\_le32 | |
| 116 | − - ei\_block | |
| 115 | + - __le32 | |
| 116 | + - ei_block | |
| 117 | 117 | - This index node covers file blocks from 'block' onward. |
| 118 | 118 | * - 0x4 |
| 119 | − - \_\_le32 | |
| 120 | − - ei\_leaf\_lo | |
| 119 | + - __le32 | |
| 120 | + - ei_leaf_lo | |
| 121 | 121 | - Lower 32-bits of the block number of the extent node that is the next |
| 122 | 122 | level lower in the tree. The tree node pointed to can be either another |
| 123 | 123 | internal node or a leaf node, described below. |
| 124 | 124 | * - 0x8 |
| 125 | − - \_\_le16 | |
| 126 | − - ei\_leaf\_hi | |
| 125 | + - __le16 | |
| 126 | + - ei_leaf_hi | |
| 127 | 127 | - Upper 16-bits of the previous field. |
| 128 | 128 | * - 0xA |
| 129 | − - \_\_u16 | |
| 130 | − - ei\_unused | |
| 129 | + - __u16 | |
| 130 | + - ei_unused | |
| 131 | 131 | - |
| 132 | 132 | |
| 133 | 133 | Leaf nodes of the extent tree are recorded as ``struct ext4_extent``, |
| @@ -142,24 +142,24 @@ and are also 12 bytes long: · 8 unmodified lines | ||
| 142 | 142 | - Name |
| 143 | 143 | - Description |
| 144 | 144 | * - 0x0 |
| 145 | − - \_\_le32 | |
| 146 | − - ee\_block | |
| 145 | + - __le32 | |
| 146 | + - ee_block | |
| 147 | 147 | - First file block number that this extent covers. |
| 148 | 148 | * - 0x4 |
| 149 | − - \_\_le16 | |
| 150 | − - ee\_len | |
| 149 | + - __le16 | |
| 150 | + - ee_len | |
| 151 | 151 | - Number of blocks covered by extent. If the value of this field is <= |
| 152 | 152 | 32768, the extent is initialized. If the value of the field is > 32768, |
| 153 | 153 | the extent is uninitialized and the actual extent length is ``ee_len`` - |
| 154 | 154 | 32768. Therefore, the maximum length of a initialized extent is 32768 |
| 155 | 155 | blocks, and the maximum length of an uninitialized extent is 32767. |
| 156 | 156 | * - 0x6 |
| 157 | − - \_\_le16 | |
| 158 | − - ee\_start\_hi | |
| 157 | + - __le16 | |
| 158 | + - ee_start_hi | |
| 159 | 159 | - Upper 16-bits of the block number to which this extent points. |
| 160 | 160 | * - 0x8 |
| 161 | − - \_\_le32 | |
| 162 | − - ee\_start\_lo | |
| 161 | + - __le32 | |
| 162 | + - ee_start_lo | |
| 163 | 163 | - Lower 32-bits of the block number to which this extent points. |
| 164 | 164 | |
| 165 | 165 | Prior to the introduction of metadata checksums, the extent header + |
| @@ -182,8 +182,8 @@ including) the checksum itself. · 16 unmodified lines | ||
| 182 | 182 | - Name |
| 183 | 183 | - Description |
| 184 | 184 | * - 0x0 |
| 185 | − - \_\_le32 | |
| 186 | − - eb\_checksum | |
| 185 | + - __le32 | |
| 186 | + - eb_checksum | |
| 187 | 187 | - Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock) |
| 188 | 188 | |
| 189 | 189 | Inline Data |
| @@ -11,12 +11,12 @@ file is smaller than 60 bytes, then the data are stored inline in · 10 unmodified lines | ||
| 11 | 11 | attribute space, then it might be found as an extended attribute |
| 12 | 12 | “system.data” within the inode body (“ibody EA”). This of course |
| 13 | 13 | constrains the amount of extended attributes one can attach to an inode. |
| 14 | −If the data size increases beyond i\_block + ibody EA, a regular block | |
| 14 | +If the data size increases beyond i_block + ibody EA, a regular block | |
| 15 | 15 | is allocated and the contents moved to that block. |
| 16 | 16 | |
| 17 | 17 | Pending a change to compact the extended attribute key used to store |
| 18 | 18 | inline data, one ought to be able to store 160 bytes of data in a |
| 19 | −256-byte inode (as of June 2015, when i\_extra\_isize is 28). Prior to | |
| 19 | +256-byte inode (as of June 2015, when i_extra_isize is 28). Prior to | |
| 20 | 20 | that, the limit was 156 bytes due to inefficient use of inode space. |
| 21 | 21 | |
| 22 | 22 | The inline data feature requires the presence of an extended attribute |
| @@ -25,12 +25,12 @@ for “system.data”, even if the attribute value is zero length. · 2 unmodified lines | ||
| 25 | 25 | Inline Directories |
| 26 | 26 | ~~~~~~~~~~~~~~~~~~ |
| 27 | 27 | |
| 28 | −The first four bytes of i\_block are the inode number of the parent | |
| 28 | +The first four bytes of i_block are the inode number of the parent | |
| 29 | 29 | directory. Following that is a 56-byte space for an array of directory |
| 30 | 30 | entries; see ``struct ext4_dir_entry``. If there is a “system.data” |
| 31 | 31 | attribute in the inode body, the EA value is an array of |
| 32 | 32 | ``struct ext4_dir_entry`` as well. Note that for inline directories, the |
| 33 | −i\_block and EA space are treated as separate dirent blocks; directory | |
| 33 | +i_block and EA space are treated as separate dirent blocks; directory | |
| 34 | 34 | entries cannot span the two. |
| 35 | 35 | |
| 36 | 36 | Inline directory entries are not checksummed, as the inode checksum |
| @@ -38,138 +38,138 @@ The inode table entry is laid out in ``struct ext4_inode``. · 37 unmodified lines | ||
| 38 | 38 | - Name |
| 39 | 39 | - Description |
| 40 | 40 | * - 0x0 |
| 41 | − - \_\_le16 | |
| 42 | − - i\_mode | |
| 41 | + - __le16 | |
| 42 | + - i_mode | |
| 43 | 43 | - File mode. See the table i_mode_ below. |
| 44 | 44 | * - 0x2 |
| 45 | − - \_\_le16 | |
| 46 | − - i\_uid | |
| 45 | + - __le16 | |
| 46 | + - i_uid | |
| 47 | 47 | - Lower 16-bits of Owner UID. |
| 48 | 48 | * - 0x4 |
| 49 | − - \_\_le32 | |
| 50 | − - i\_size\_lo | |
| 49 | + - __le32 | |
| 50 | + - i_size_lo | |
| 51 | 51 | - Lower 32-bits of size in bytes. |
| 52 | 52 | * - 0x8 |
| 53 | − - \_\_le32 | |
| 54 | − - i\_atime | |
| 55 | − - Last access time, in seconds since the epoch. However, if the EA\_INODE | |
| 53 | + - __le32 | |
| 54 | + - i_atime | |
| 55 | + - Last access time, in seconds since the epoch. However, if the EA_INODE | |
| 56 | 56 | inode flag is set, this inode stores an extended attribute value and |
| 57 | 57 | this field contains the checksum of the value. |
| 58 | 58 | * - 0xC |
| 59 | − - \_\_le32 | |
| 60 | − - i\_ctime | |
| 59 | + - __le32 | |
| 60 | + - i_ctime | |
| 61 | 61 | - Last inode change time, in seconds since the epoch. However, if the |
| 62 | − EA\_INODE inode flag is set, this inode stores an extended attribute | |
| 62 | + EA_INODE inode flag is set, this inode stores an extended attribute | |
| 63 | 63 | value and this field contains the lower 32 bits of the attribute value's |
| 64 | 64 | reference count. |
| 65 | 65 | * - 0x10 |
| 66 | − - \_\_le32 | |
| 67 | − - i\_mtime | |
| 66 | + - __le32 | |
| 67 | + - i_mtime | |
| 68 | 68 | - Last data modification time, in seconds since the epoch. However, if the |
| 69 | − EA\_INODE inode flag is set, this inode stores an extended attribute | |
| 69 | + EA_INODE inode flag is set, this inode stores an extended attribute | |
| 70 | 70 | value and this field contains the number of the inode that owns the |
| 71 | 71 | extended attribute. |
| 72 | 72 | * - 0x14 |
| 73 | − - \_\_le32 | |
| 74 | − - i\_dtime | |
| 73 | + - __le32 | |
| 74 | + - i_dtime | |
| 75 | 75 | - Deletion Time, in seconds since the epoch. |
| 76 | 76 | * - 0x18 |
| 77 | − - \_\_le16 | |
| 78 | − - i\_gid | |
| 77 | + - __le16 | |
| 78 | + - i_gid | |
| 79 | 79 | - Lower 16-bits of GID. |
| 80 | 80 | * - 0x1A |
| 81 | − - \_\_le16 | |
| 82 | − - i\_links\_count | |
| 81 | + - __le16 | |
| 82 | + - i_links_count | |
| 83 | 83 | - Hard link count. Normally, ext4 does not permit an inode to have more |
| 84 | 84 | than 65,000 hard links. This applies to files as well as directories, |
| 85 | 85 | which means that there cannot be more than 64,998 subdirectories in a |
| 86 | 86 | directory (each subdirectory's '..' entry counts as a hard link, as does |
| 87 | − the '.' entry in the directory itself). With the DIR\_NLINK feature | |
| 87 | + the '.' entry in the directory itself). With the DIR_NLINK feature | |
| 88 | 88 | enabled, ext4 supports more than 64,998 subdirectories by setting this |
| 89 | 89 | field to 1 to indicate that the number of hard links is not known. |
| 90 | 90 | * - 0x1C |
| 91 | − - \_\_le32 | |
| 92 | − - i\_blocks\_lo | |
| 93 | − - Lower 32-bits of “block” count. If the huge\_file feature flag is not | |
| 91 | + - __le32 | |
| 92 | + - i_blocks_lo | |
| 93 | + - Lower 32-bits of “block” count. If the huge_file feature flag is not | |
| 94 | 94 | set on the filesystem, the file consumes ``i_blocks_lo`` 512-byte blocks |
| 95 | − on disk. If huge\_file is set and EXT4\_HUGE\_FILE\_FL is NOT set in | |
| 95 | + on disk. If huge_file is set and EXT4_HUGE_FILE_FL is NOT set in | |
| 96 | 96 | ``inode.i_flags``, then the file consumes ``i_blocks_lo + (i_blocks_hi |
| 97 | − << 32)`` 512-byte blocks on disk. If huge\_file is set and | |
| 98 | − EXT4\_HUGE\_FILE\_FL IS set in ``inode.i_flags``, then this file | |
| 97 | + << 32)`` 512-byte blocks on disk. If huge_file is set and | |
| 98 | + EXT4_HUGE_FILE_FL IS set in ``inode.i_flags``, then this file | |
| 99 | 99 | consumes (``i_blocks_lo + i_blocks_hi`` << 32) filesystem blocks on |
| 100 | 100 | disk. |
| 101 | 101 | * - 0x20 |
| 102 | − - \_\_le32 | |
| 103 | − - i\_flags | |
| 102 | + - __le32 | |
| 103 | + - i_flags | |
| 104 | 104 | - Inode flags. See the table i_flags_ below. |
| 105 | 105 | * - 0x24 |
| 106 | 106 | - 4 bytes |
| 107 | − - i\_osd1 | |
| 107 | + - i_osd1 | |
| 108 | 108 | - See the table i_osd1_ for more details. |
| 109 | 109 | * - 0x28 |
| 110 | 110 | - 60 bytes |
| 111 | − - i\_block[EXT4\_N\_BLOCKS=15] | |
| 112 | − - Block map or extent tree. See the section “The Contents of inode.i\_block”. | |
| 111 | + - i_block[EXT4_N_BLOCKS=15] | |
| 112 | + - Block map or extent tree. See the section “The Contents of inode.i_block”. | |
| 113 | 113 | * - 0x64 |
| 114 | − - \_\_le32 | |
| 115 | − - i\_generation | |
| 114 | + - __le32 | |
| 115 | + - i_generation | |
| 116 | 116 | - File version (for NFS). |
| 117 | 117 | * - 0x68 |
| 118 | − - \_\_le32 | |
| 119 | − - i\_file\_acl\_lo | |
| 118 | + - __le32 | |
| 119 | + - i_file_acl_lo | |
| 120 | 120 | - Lower 32-bits of extended attribute block. ACLs are of course one of |
| 121 | 121 | many possible extended attributes; I think the name of this field is a |
| 122 | 122 | result of the first use of extended attributes being for ACLs. |
| 123 | 123 | * - 0x6C |
| 124 | − - \_\_le32 | |
| 125 | − - i\_size\_high / i\_dir\_acl | |
| 124 | + - __le32 | |
| 125 | + - i_size_high / i_dir_acl | |
| 126 | 126 | - Upper 32-bits of file/directory size. In ext2/3 this field was named |
| 127 | − i\_dir\_acl, though it was usually set to zero and never used. | |
| 127 | + i_dir_acl, though it was usually set to zero and never used. | |
| 128 | 128 | * - 0x70 |
| 129 | − - \_\_le32 | |
| 130 | − - i\_obso\_faddr | |
| 129 | + - __le32 | |
| 130 | + - i_obso_faddr | |
| 131 | 131 | - (Obsolete) fragment address. |
| 132 | 132 | * - 0x74 |
| 133 | 133 | - 12 bytes |
| 134 | − - i\_osd2 | |
| 134 | + - i_osd2 | |
| 135 | 135 | - See the table i_osd2_ for more details. |
| 136 | 136 | * - 0x80 |
| 137 | − - \_\_le16 | |
| 138 | − - i\_extra\_isize | |
| 137 | + - __le16 | |
| 138 | + - i_extra_isize | |
| 139 | 139 | - Size of this inode - 128. Alternately, the size of the extended inode |
| 140 | 140 | fields beyond the original ext2 inode, including this field. |
| 141 | 141 | * - 0x82 |
| 142 | − - \_\_le16 | |
| 143 | − - i\_checksum\_hi | |
| 142 | + - __le16 | |
| 143 | + - i_checksum_hi | |
| 144 | 144 | - Upper 16-bits of the inode checksum. |
| 145 | 145 | * - 0x84 |
| 146 | − - \_\_le32 | |
| 147 | − - i\_ctime\_extra | |
| 146 | + - __le32 | |
| 147 | + - i_ctime_extra | |
| 148 | 148 | - Extra change time bits. This provides sub-second precision. See Inode |
| 149 | 149 | Timestamps section. |
| 150 | 150 | * - 0x88 |
| 151 | − - \_\_le32 | |
| 152 | − - i\_mtime\_extra | |
| 151 | + - __le32 | |
| 152 | + - i_mtime_extra | |
| 153 | 153 | - Extra modification time bits. This provides sub-second precision. |
| 154 | 154 | * - 0x8C |
| 155 | − - \_\_le32 | |
| 156 | − - i\_atime\_extra | |
| 155 | + - __le32 | |
| 156 | + - i_atime_extra | |
| 157 | 157 | - Extra access time bits. This provides sub-second precision. |
| 158 | 158 | * - 0x90 |
| 159 | − - \_\_le32 | |
| 160 | − - i\_crtime | |
| 159 | + - __le32 | |
| 160 | + - i_crtime | |
| 161 | 161 | - File creation time, in seconds since the epoch. |
| 162 | 162 | * - 0x94 |
| 163 | − - \_\_le32 | |
| 164 | − - i\_crtime\_extra | |
| 163 | + - __le32 | |
| 164 | + - i_crtime_extra | |
| 165 | 165 | - Extra file creation time bits. This provides sub-second precision. |
| 166 | 166 | * - 0x98 |
| 167 | − - \_\_le32 | |
| 168 | − - i\_version\_hi | |
| 167 | + - __le32 | |
| 168 | + - i_version_hi | |
| 169 | 169 | - Upper 32-bits for version number. |
| 170 | 170 | * - 0x9C |
| 171 | − - \_\_le32 | |
| 172 | − - i\_projid | |
| 171 | + - __le32 | |
| 172 | + - i_projid | |
| 173 | 173 | - Project ID. |
| 174 | 174 | |
| 175 | 175 | .. _i_mode: |
| @@ -183,45 +183,45 @@ The ``i_mode`` value is a combination of the following flags: · 7 unmodified lines | ||
| 183 | 183 | * - Value |
| 184 | 184 | - Description |
| 185 | 185 | * - 0x1 |
| 186 | − - S\_IXOTH (Others may execute) | |
| 186 | + - S_IXOTH (Others may execute) | |
| 187 | 187 | * - 0x2 |
| 188 | − - S\_IWOTH (Others may write) | |
| 188 | + - S_IWOTH (Others may write) | |
| 189 | 189 | * - 0x4 |
| 190 | − - S\_IROTH (Others may read) | |
| 190 | + - S_IROTH (Others may read) | |
| 191 | 191 | * - 0x8 |
| 192 | − - S\_IXGRP (Group members may execute) | |
| 192 | + - S_IXGRP (Group members may execute) | |
| 193 | 193 | * - 0x10 |
| 194 | − - S\_IWGRP (Group members may write) | |
| 194 | + - S_IWGRP (Group members may write) | |
| 195 | 195 | * - 0x20 |
| 196 | − - S\_IRGRP (Group members may read) | |
| 196 | + - S_IRGRP (Group members may read) | |
| 197 | 197 | * - 0x40 |
| 198 | − - S\_IXUSR (Owner may execute) | |
| 198 | + - S_IXUSR (Owner may execute) | |
| 199 | 199 | * - 0x80 |
| 200 | − - S\_IWUSR (Owner may write) | |
| 200 | + - S_IWUSR (Owner may write) | |
| 201 | 201 | * - 0x100 |
| 202 | − - S\_IRUSR (Owner may read) | |
| 202 | + - S_IRUSR (Owner may read) | |
| 203 | 203 | * - 0x200 |
| 204 | − - S\_ISVTX (Sticky bit) | |
| 204 | + - S_ISVTX (Sticky bit) | |
| 205 | 205 | * - 0x400 |
| 206 | − - S\_ISGID (Set GID) | |
| 206 | + - S_ISGID (Set GID) | |
| 207 | 207 | * - 0x800 |
| 208 | − - S\_ISUID (Set UID) | |
| 208 | + - S_ISUID (Set UID) | |
| 209 | 209 | * - |
| 210 | 210 | - These are mutually-exclusive file types: |
| 211 | 211 | * - 0x1000 |
| 212 | − - S\_IFIFO (FIFO) | |
| 212 | + - S_IFIFO (FIFO) | |
| 213 | 213 | * - 0x2000 |
| 214 | − - S\_IFCHR (Character device) | |
| 214 | + - S_IFCHR (Character device) | |
| 215 | 215 | * - 0x4000 |
| 216 | − - S\_IFDIR (Directory) | |
| 216 | + - S_IFDIR (Directory) | |
| 217 | 217 | * - 0x6000 |
| 218 | − - S\_IFBLK (Block device) | |
| 218 | + - S_IFBLK (Block device) | |
| 219 | 219 | * - 0x8000 |
| 220 | − - S\_IFREG (Regular file) | |
| 220 | + - S_IFREG (Regular file) | |
| 221 | 221 | * - 0xA000 |
| 222 | − - S\_IFLNK (Symbolic link) | |
| 222 | + - S_IFLNK (Symbolic link) | |
| 223 | 223 | * - 0xC000 |
| 224 | − - S\_IFSOCK (Socket) | |
| 224 | + - S_IFSOCK (Socket) | |
| 225 | 225 | |
| 226 | 226 | .. _i_flags: |
| 227 | 227 | |
| @@ -234,56 +234,56 @@ The ``i_flags`` field is a combination of these values: · 6 unmodified lines | ||
| 234 | 234 | * - Value |
| 235 | 235 | - Description |
| 236 | 236 | * - 0x1 |
| 237 | − - This file requires secure deletion (EXT4\_SECRM\_FL). (not implemented) | |
| 237 | + - This file requires secure deletion (EXT4_SECRM_FL). (not implemented) | |
| 238 | 238 | * - 0x2 |
| 239 | 239 | - This file should be preserved, should undeletion be desired |
| 240 | − (EXT4\_UNRM\_FL). (not implemented) | |
| 240 | + (EXT4_UNRM_FL). (not implemented) | |
| 241 | 241 | * - 0x4 |
| 242 | − - File is compressed (EXT4\_COMPR\_FL). (not really implemented) | |
| 242 | + - File is compressed (EXT4_COMPR_FL). (not really implemented) | |
| 243 | 243 | * - 0x8 |
| 244 | − - All writes to the file must be synchronous (EXT4\_SYNC\_FL). | |
| 244 | + - All writes to the file must be synchronous (EXT4_SYNC_FL). | |
| 245 | 245 | * - 0x10 |
| 246 | − - File is immutable (EXT4\_IMMUTABLE\_FL). | |
| 246 | + - File is immutable (EXT4_IMMUTABLE_FL). | |
| 247 | 247 | * - 0x20 |
| 248 | − - File can only be appended (EXT4\_APPEND\_FL). | |
| 248 | + - File can only be appended (EXT4_APPEND_FL). | |
| 249 | 249 | * - 0x40 |
| 250 | − - The dump(1) utility should not dump this file (EXT4\_NODUMP\_FL). | |
| 250 | + - The dump(1) utility should not dump this file (EXT4_NODUMP_FL). | |
| 251 | 251 | * - 0x80 |
| 252 | − - Do not update access time (EXT4\_NOATIME\_FL). | |
| 252 | + - Do not update access time (EXT4_NOATIME_FL). | |
| 253 | 253 | * - 0x100 |
| 254 | − - Dirty compressed file (EXT4\_DIRTY\_FL). (not used) | |
| 254 | + - Dirty compressed file (EXT4_DIRTY_FL). (not used) | |
| 255 | 255 | * - 0x200 |
| 256 | − - File has one or more compressed clusters (EXT4\_COMPRBLK\_FL). (not used) | |
| 256 | + - File has one or more compressed clusters (EXT4_COMPRBLK_FL). (not used) | |
| 257 | 257 | * - 0x400 |
| 258 | − - Do not compress file (EXT4\_NOCOMPR\_FL). (not used) | |
| 258 | + - Do not compress file (EXT4_NOCOMPR_FL). (not used) | |
| 259 | 259 | * - 0x800 |
| 260 | − - Encrypted inode (EXT4\_ENCRYPT\_FL). This bit value previously was | |
| 261 | − EXT4\_ECOMPR\_FL (compression error), which was never used. | |
| 260 | + - Encrypted inode (EXT4_ENCRYPT_FL). This bit value previously was | |
| 261 | + EXT4_ECOMPR_FL (compression error), which was never used. | |
| 262 | 262 | * - 0x1000 |
| 263 | − - Directory has hashed indexes (EXT4\_INDEX\_FL). | |
| 263 | + - Directory has hashed indexes (EXT4_INDEX_FL). | |
| 264 | 264 | * - 0x2000 |
| 265 | − - AFS magic directory (EXT4\_IMAGIC\_FL). | |
| 265 | + - AFS magic directory (EXT4_IMAGIC_FL). | |
| 266 | 266 | * - 0x4000 |
| 267 | 267 | - File data must always be written through the journal |
| 268 | − (EXT4\_JOURNAL\_DATA\_FL). | |
| 268 | + (EXT4_JOURNAL_DATA_FL). | |
| 269 | 269 | * - 0x8000 |
| 270 | − - File tail should not be merged (EXT4\_NOTAIL\_FL). (not used by ext4) | |
| 270 | + - File tail should not be merged (EXT4_NOTAIL_FL). (not used by ext4) | |
| 271 | 271 | * - 0x10000 |
| 272 | 272 | - All directory entry data should be written synchronously (see |
| 273 | − ``dirsync``) (EXT4\_DIRSYNC\_FL). | |
| 273 | + ``dirsync``) (EXT4_DIRSYNC_FL). | |
| 274 | 274 | * - 0x20000 |
| 275 | − - Top of directory hierarchy (EXT4\_TOPDIR\_FL). | |
| 275 | + - Top of directory hierarchy (EXT4_TOPDIR_FL). | |
| 276 | 276 | * - 0x40000 |
| 277 | − - This is a huge file (EXT4\_HUGE\_FILE\_FL). | |
| 277 | + - This is a huge file (EXT4_HUGE_FILE_FL). | |
| 278 | 278 | * - 0x80000 |
| 279 | − - Inode uses extents (EXT4\_EXTENTS\_FL). | |
| 279 | + - Inode uses extents (EXT4_EXTENTS_FL). | |
| 280 | 280 | * - 0x100000 |
| 281 | − - Verity protected file (EXT4\_VERITY\_FL). | |
| 281 | + - Verity protected file (EXT4_VERITY_FL). | |
| 282 | 282 | * - 0x200000 |
| 283 | 283 | - Inode stores a large extended attribute value in its data blocks |
| 284 | − (EXT4\_EA\_INODE\_FL). | |
| 284 | + (EXT4_EA_INODE_FL). | |
| 285 | 285 | * - 0x400000 |
| 286 | − - This file has blocks allocated past EOF (EXT4\_EOFBLOCKS\_FL). | |
| 286 | + - This file has blocks allocated past EOF (EXT4_EOFBLOCKS_FL). | |
| 287 | 287 | (deprecated) |
| 288 | 288 | * - 0x01000000 |
| 289 | 289 | - Inode is a snapshot (``EXT4_SNAPFILE_FL``). (not in mainline) |
| @@ -294,21 +294,21 @@ The ``i_flags`` field is a combination of these values: · 4 unmodified lines | ||
| 294 | 294 | - Snapshot shrink has completed (``EXT4_SNAPFILE_SHRUNK_FL``). (not in |
| 295 | 295 | mainline) |
| 296 | 296 | * - 0x10000000 |
| 297 | − - Inode has inline data (EXT4\_INLINE\_DATA\_FL). | |
| 297 | + - Inode has inline data (EXT4_INLINE_DATA_FL). | |
| 298 | 298 | * - 0x20000000 |
| 299 | − - Create children with the same project ID (EXT4\_PROJINHERIT\_FL). | |
| 299 | + - Create children with the same project ID (EXT4_PROJINHERIT_FL). | |
| 300 | 300 | * - 0x80000000 |
| 301 | − - Reserved for ext4 library (EXT4\_RESERVED\_FL). | |
| 301 | + - Reserved for ext4 library (EXT4_RESERVED_FL). | |
| 302 | 302 | * - |
| 303 | 303 | - Aggregate flags: |
| 304 | 304 | * - 0x705BDFFF |
| 305 | 305 | - User-visible flags. |
| 306 | 306 | * - 0x604BC0FF |
| 307 | − - User-modifiable flags. Note that while EXT4\_JOURNAL\_DATA\_FL and | |
| 308 | − EXT4\_EXTENTS\_FL can be set with setattr, they are not in the kernel's | |
| 309 | − EXT4\_FL\_USER\_MODIFIABLE mask, since it needs to handle the setting of | |
| 307 | + - User-modifiable flags. Note that while EXT4_JOURNAL_DATA_FL and | |
| 308 | + EXT4_EXTENTS_FL can be set with setattr, they are not in the kernel's | |
| 309 | + EXT4_FL_USER_MODIFIABLE mask, since it needs to handle the setting of | |
| 310 | 310 | these flags in a special manner and they are masked out of the set of |
| 311 | − flags that are saved directly to i\_flags. | |
| 311 | + flags that are saved directly to i_flags. | |
| 312 | 312 | |
| 313 | 313 | .. _i_osd1: |
| 314 | 314 | |
| @@ -325,9 +325,9 @@ Linux: · 10 unmodified lines | ||
| 325 | 325 | - Name |
| 326 | 326 | - Description |
| 327 | 327 | * - 0x0 |
| 328 | − - \_\_le32 | |
| 329 | − - l\_i\_version | |
| 330 | − - Inode version. However, if the EA\_INODE inode flag is set, this inode | |
| 328 | + - __le32 | |
| 329 | + - l_i_version | |
| 330 | + - Inode version. However, if the EA_INODE inode flag is set, this inode | |
| 331 | 331 | stores an extended attribute value and this field contains the upper 32 |
| 332 | 332 | bits of the attribute value's reference count. |
| 333 | 333 | |
| @@ -342,8 +342,8 @@ Hurd: · 8 unmodified lines | ||
| 342 | 342 | - Name |
| 343 | 343 | - Description |
| 344 | 344 | * - 0x0 |
| 345 | − - \_\_le32 | |
| 346 | − - h\_i\_translator | |
| 345 | + - __le32 | |
| 346 | + - h_i_translator | |
| 347 | 347 | - ?? |
| 348 | 348 | |
| 349 | 349 | Masix: |
| @@ -357,8 +357,8 @@ Masix: · 7 unmodified lines | ||
| 357 | 357 | - Name |
| 358 | 358 | - Description |
| 359 | 359 | * - 0x0 |
| 360 | − - \_\_le32 | |
| 361 | − - m\_i\_reserved | |
| 360 | + - __le32 | |
| 361 | + - m_i_reserved | |
| 362 | 362 | - ?? |
| 363 | 363 | |
| 364 | 364 | .. _i_osd2: |
| @@ -376,30 +376,30 @@ Linux: · 11 unmodified lines | ||
| 376 | 376 | - Name |
| 377 | 377 | - Description |
| 378 | 378 | * - 0x0 |
| 379 | − - \_\_le16 | |
| 380 | − - l\_i\_blocks\_high | |
| 379 | + - __le16 | |
| 380 | + - l_i_blocks_high | |
| 381 | 381 | - Upper 16-bits of the block count. Please see the note attached to |
| 382 | − i\_blocks\_lo. | |
| 382 | + i_blocks_lo. | |
| 383 | 383 | * - 0x2 |
| 384 | − - \_\_le16 | |
| 385 | − - l\_i\_file\_acl\_high | |
| 384 | + - __le16 | |
| 385 | + - l_i_file_acl_high | |
| 386 | 386 | - Upper 16-bits of the extended attribute block (historically, the file |
| 387 | 387 | ACL location). See the Extended Attributes section below. |
| 388 | 388 | * - 0x4 |
| 389 | − - \_\_le16 | |
| 390 | − - l\_i\_uid\_high | |
| 389 | + - __le16 | |
| 390 | + - l_i_uid_high | |
| 391 | 391 | - Upper 16-bits of the Owner UID. |
| 392 | 392 | * - 0x6 |
| 393 | − - \_\_le16 | |
| 394 | − - l\_i\_gid\_high | |
| 393 | + - __le16 | |
| 394 | + - l_i_gid_high | |
| 395 | 395 | - Upper 16-bits of the GID. |
| 396 | 396 | * - 0x8 |
| 397 | − - \_\_le16 | |
| 398 | − - l\_i\_checksum\_lo | |
| 397 | + - __le16 | |
| 398 | + - l_i_checksum_lo | |
| 399 | 399 | - Lower 16-bits of the inode checksum. |
| 400 | 400 | * - 0xA |
| 401 | − - \_\_le16 | |
| 402 | − - l\_i\_reserved | |
| 401 | + - __le16 | |
| 402 | + - l_i_reserved | |
| 403 | 403 | - Unused. |
| 404 | 404 | |
| 405 | 405 | Hurd: |
| @@ -413,24 +413,24 @@ Hurd: · 7 unmodified lines | ||
| 413 | 413 | - Name |
| 414 | 414 | - Description |
| 415 | 415 | * - 0x0 |
| 416 | − - \_\_le16 | |
| 417 | − - h\_i\_reserved1 | |
| 416 | + - __le16 | |
| 417 | + - h_i_reserved1 | |
| 418 | 418 | - ?? |
| 419 | 419 | * - 0x2 |
| 420 | − - \_\_u16 | |
| 421 | − - h\_i\_mode\_high | |
| 420 | + - __u16 | |
| 421 | + - h_i_mode_high | |
| 422 | 422 | - Upper 16-bits of the file mode. |
| 423 | 423 | * - 0x4 |
| 424 | − - \_\_le16 | |
| 425 | − - h\_i\_uid\_high | |
| 424 | + - __le16 | |
| 425 | + - h_i_uid_high | |
| 426 | 426 | - Upper 16-bits of the Owner UID. |
| 427 | 427 | * - 0x6 |
| 428 | − - \_\_le16 | |
| 429 | − - h\_i\_gid\_high | |
| 428 | + - __le16 | |
| 429 | + - h_i_gid_high | |
| 430 | 430 | - Upper 16-bits of the GID. |
| 431 | 431 | * - 0x8 |
| 432 | − - \_\_u32 | |
| 433 | − - h\_i\_author | |
| 432 | + - __u32 | |
| 433 | + - h_i_author | |
| 434 | 434 | - Author code? |
| 435 | 435 | |
| 436 | 436 | Masix: |
| @@ -444,17 +444,17 @@ Masix: · 7 unmodified lines | ||
| 444 | 444 | - Name |
| 445 | 445 | - Description |
| 446 | 446 | * - 0x0 |
| 447 | − - \_\_le16 | |
| 448 | − - h\_i\_reserved1 | |
| 447 | + - __le16 | |
| 448 | + - h_i_reserved1 | |
| 449 | 449 | - ?? |
| 450 | 450 | * - 0x2 |
| 451 | − - \_\_u16 | |
| 452 | − - m\_i\_file\_acl\_high | |
| 451 | + - __u16 | |
| 452 | + - m_i_file_acl_high | |
| 453 | 453 | - Upper 16-bits of the extended attribute block (historically, the file |
| 454 | 454 | ACL location). |
| 455 | 455 | * - 0x4 |
| 456 | − - \_\_u32 | |
| 457 | − - m\_i\_reserved2[2] | |
| 456 | + - __u32 | |
| 457 | + - m_i_reserved2[2] | |
| 458 | 458 | - ?? |
| 459 | 459 | |
| 460 | 460 | Inode Size |
| @@ -466,11 +466,11 @@ In ext2 and ext3, the inode structure size was fixed at 128 bytes · 5 unmodified lines | ||
| 466 | 466 | on-disk inode at format time for all inodes in the filesystem to provide |
| 467 | 467 | space beyond the end of the original ext2 inode. The on-disk inode |
| 468 | 468 | record size is recorded in the superblock as ``s_inode_size``. The |
| 469 | −number of bytes actually used by struct ext4\_inode beyond the original | |
| 469 | +number of bytes actually used by struct ext4_inode beyond the original | |
| 470 | 470 | 128-byte ext2 inode is recorded in the ``i_extra_isize`` field for each |
| 471 | −inode, which allows struct ext4\_inode to grow for a new kernel without | |
| 471 | +inode, which allows struct ext4_inode to grow for a new kernel without | |
| 472 | 472 | having to upgrade all of the on-disk inodes. Access to fields beyond |
| 473 | −EXT2\_GOOD\_OLD\_INODE\_SIZE should be verified to be within | |
| 473 | +EXT2_GOOD_OLD_INODE_SIZE should be verified to be within | |
| 474 | 474 | ``i_extra_isize``. By default, ext4 inode records are 256 bytes, and (as |
| 475 | 475 | of August 2019) the inode structure is 160 bytes |
| 476 | 476 | (``i_extra_isize = 32``). The extra space between the end of the inode |
| @@ -516,7 +516,7 @@ creation time (crtime); this field is 64-bits wide and decoded in the · 39 unmodified lines | ||
| 516 | 516 | same manner as 64-bit [cma]time. Neither crtime nor dtime are accessible |
| 517 | 517 | through the regular stat() interface, though debugfs will report them. |
| 518 | 518 | |
| 519 | −We use the 32-bit signed time value plus (2^32 \* (extra epoch bits)). | |
| 519 | +We use the 32-bit signed time value plus (2^32 * (extra epoch bits)). | |
| 520 | 520 | In other words: |
| 521 | 521 | |
| 522 | 522 | .. list-table:: |
| @@ -525,8 +525,8 @@ In other words: · 2 unmodified lines | ||
| 525 | 525 | |
| 526 | 526 | * - Extra epoch bits |
| 527 | 527 | - MSB of 32-bit time |
| 528 | − - Adjustment for signed 32-bit to 64-bit tv\_sec | |
| 529 | − - Decoded 64-bit tv\_sec | |
| 528 | + - Adjustment for signed 32-bit to 64-bit tv_sec | |
| 529 | + - Decoded 64-bit tv_sec | |
| 530 | 530 | - valid time range |
| 531 | 531 | * - 0 0 |
| 532 | 532 | - 1 |
| @@ -63,8 +63,8 @@ Generally speaking, the journal has this format: · 62 unmodified lines | ||
| 63 | 63 | :header-rows: 1 |
| 64 | 64 | |
| 65 | 65 | * - Superblock |
| 66 | − - descriptor\_block (data\_blocks or revocation\_block) [more data or | |
| 67 | − revocations] commmit\_block | |
| 66 | + - descriptor_block (data_blocks or revocation_block) [more data or | |
| 67 | + revocations] commmit_block | |
| 68 | 68 | - [more transactions...] |
| 69 | 69 | * - |
| 70 | 70 | - One transaction |
| @@ -93,8 +93,8 @@ superblock. · 22 unmodified lines | ||
| 93 | 93 | * - 1024 bytes of padding |
| 94 | 94 | - ext4 Superblock |
| 95 | 95 | - Journal Superblock |
| 96 | − - descriptor\_block (data\_blocks or revocation\_block) [more data or | |
| 97 | − revocations] commmit\_block | |
| 96 | + - descriptor_block (data_blocks or revocation_block) [more data or | |
| 97 | + revocations] commmit_block | |
| 98 | 98 | - [more transactions...] |
| 99 | 99 | * - |
| 100 | 100 | - |
| @@ -117,17 +117,17 @@ Every block in the journal starts with a common 12-byte header · 16 unmodified lines | ||
| 117 | 117 | - Name |
| 118 | 118 | - Description |
| 119 | 119 | * - 0x0 |
| 120 | − - \_\_be32 | |
| 121 | − - h\_magic | |
| 120 | + - __be32 | |
| 121 | + - h_magic | |
| 122 | 122 | - jbd2 magic number, 0xC03B3998. |
| 123 | 123 | * - 0x4 |
| 124 | − - \_\_be32 | |
| 125 | − - h\_blocktype | |
| 124 | + - __be32 | |
| 125 | + - h_blocktype | |
| 126 | 126 | - Description of what this block contains. See the jbd2_blocktype_ table |
| 127 | 127 | below. |
| 128 | 128 | * - 0x8 |
| 129 | − - \_\_be32 | |
| 130 | − - h\_sequence | |
| 129 | + - __be32 | |
| 130 | + - h_sequence | |
| 131 | 131 | - The transaction ID that goes with this block. |
| 132 | 132 | |
| 133 | 133 | .. _jbd2_blocktype: |
| @@ -177,99 +177,99 @@ which is 1024 bytes long: · 43 unmodified lines | ||
| 177 | 177 | - |
| 178 | 178 | - Static information describing the journal. |
| 179 | 179 | * - 0x0 |
| 180 | − - journal\_header\_t (12 bytes) | |
| 181 | − - s\_header | |
| 180 | + - journal_header_t (12 bytes) | |
| 181 | + - s_header | |
| 182 | 182 | - Common header identifying this as a superblock. |
| 183 | 183 | * - 0xC |
| 184 | − - \_\_be32 | |
| 185 | − - s\_blocksize | |
| 184 | + - __be32 | |
| 185 | + - s_blocksize | |
| 186 | 186 | - Journal device block size. |
| 187 | 187 | * - 0x10 |
| 188 | − - \_\_be32 | |
| 189 | − - s\_maxlen | |
| 188 | + - __be32 | |
| 189 | + - s_maxlen | |
| 190 | 190 | - Total number of blocks in this journal. |
| 191 | 191 | * - 0x14 |
| 192 | − - \_\_be32 | |
| 193 | − - s\_first | |
| 192 | + - __be32 | |
| 193 | + - s_first | |
| 194 | 194 | - First block of log information. |
| 195 | 195 | * - |
| 196 | 196 | - |
| 197 | 197 | - |
| 198 | 198 | - Dynamic information describing the current state of the log. |
| 199 | 199 | * - 0x18 |
| 200 | − - \_\_be32 | |
| 201 | − - s\_sequence | |
| 200 | + - __be32 | |
| 201 | + - s_sequence | |
| 202 | 202 | - First commit ID expected in log. |
| 203 | 203 | * - 0x1C |
| 204 | − - \_\_be32 | |
| 205 | − - s\_start | |
| 204 | + - __be32 | |
| 205 | + - s_start | |
| 206 | 206 | - Block number of the start of log. Contrary to the comments, this field |
| 207 | 207 | being zero does not imply that the journal is clean! |
| 208 | 208 | * - 0x20 |
| 209 | − - \_\_be32 | |
| 210 | − - s\_errno | |
| 211 | − - Error value, as set by jbd2\_journal\_abort(). | |
| 209 | + - __be32 | |
| 210 | + - s_errno | |
| 211 | + - Error value, as set by jbd2_journal_abort(). | |
| 212 | 212 | * - |
| 213 | 213 | - |
| 214 | 214 | - |
| 215 | 215 | - The remaining fields are only valid in a v2 superblock. |
| 216 | 216 | * - 0x24 |
| 217 | − - \_\_be32 | |
| 218 | − - s\_feature\_compat; | |
| 217 | + - __be32 | |
| 218 | + - s_feature_compat; | |
| 219 | 219 | - Compatible feature set. See the table jbd2_compat_ below. |
| 220 | 220 | * - 0x28 |
| 221 | − - \_\_be32 | |
| 222 | − - s\_feature\_incompat | |
| 221 | + - __be32 | |
| 222 | + - s_feature_incompat | |
| 223 | 223 | - Incompatible feature set. See the table jbd2_incompat_ below. |
| 224 | 224 | * - 0x2C |
| 225 | − - \_\_be32 | |
| 226 | − - s\_feature\_ro\_compat | |
| 225 | + - __be32 | |
| 226 | + - s_feature_ro_compat | |
| 227 | 227 | - Read-only compatible feature set. There aren't any of these currently. |
| 228 | 228 | * - 0x30 |
| 229 | − - \_\_u8 | |
| 230 | − - s\_uuid[16] | |
| 229 | + - __u8 | |
| 230 | + - s_uuid[16] | |
| 231 | 231 | - 128-bit uuid for journal. This is compared against the copy in the ext4 |
| 232 | 232 | super block at mount time. |
| 233 | 233 | * - 0x40 |
| 234 | − - \_\_be32 | |
| 235 | − - s\_nr\_users | |
| 234 | + - __be32 | |
| 235 | + - s_nr_users | |
| 236 | 236 | - Number of file systems sharing this journal. |
| 237 | 237 | * - 0x44 |
| 238 | − - \_\_be32 | |
| 239 | − - s\_dynsuper | |
| 238 | + - __be32 | |
| 239 | + - s_dynsuper | |
| 240 | 240 | - Location of dynamic super block copy. (Not used?) |
| 241 | 241 | * - 0x48 |
| 242 | − - \_\_be32 | |
| 243 | − - s\_max\_transaction | |
| 242 | + - __be32 | |
| 243 | + - s_max_transaction | |
| 244 | 244 | - Limit of journal blocks per transaction. (Not used?) |
| 245 | 245 | * - 0x4C |
| 246 | − - \_\_be32 | |
| 247 | − - s\_max\_trans\_data | |
| 246 | + - __be32 | |
| 247 | + - s_max_trans_data | |
| 248 | 248 | - Limit of data blocks per transaction. (Not used?) |
| 249 | 249 | * - 0x50 |
| 250 | − - \_\_u8 | |
| 251 | − - s\_checksum\_type | |
| 250 | + - __u8 | |
| 251 | + - s_checksum_type | |
| 252 | 252 | - Checksum algorithm used for the journal. See jbd2_checksum_type_ for |
| 253 | 253 | more info. |
| 254 | 254 | * - 0x51 |
| 255 | − - \_\_u8[3] | |
| 256 | − - s\_padding2 | |
| 255 | + - __u8[3] | |
| 256 | + - s_padding2 | |
| 257 | 257 | - |
| 258 | 258 | * - 0x54 |
| 259 | − - \_\_be32 | |
| 260 | − - s\_num\_fc\_blocks | |
| 259 | + - __be32 | |
| 260 | + - s_num_fc_blocks | |
| 261 | 261 | - Number of fast commit blocks in the journal. |
| 262 | 262 | * - 0x58 |
| 263 | − - \_\_u32 | |
| 264 | − - s\_padding[42] | |
| 263 | + - __u32 | |
| 264 | + - s_padding[42] | |
| 265 | 265 | - |
| 266 | 266 | * - 0xFC |
| 267 | − - \_\_be32 | |
| 268 | − - s\_checksum | |
| 267 | + - __be32 | |
| 268 | + - s_checksum | |
| 269 | 269 | - Checksum of the entire superblock, with this field set to zero. |
| 270 | 270 | * - 0x100 |
| 271 | − - \_\_u8 | |
| 272 | − - s\_users[16\*48] | |
| 271 | + - __u8 | |
| 272 | + - s_users[16*48] | |
| 273 | 273 | - ids of all file systems sharing the log. e2fsprogs/Linux don't allow |
| 274 | 274 | shared external journals, but I imagine Lustre (or ocfs2?), which use |
| 275 | 275 | the jbd2 code, might. |
| @@ -286,7 +286,7 @@ The journal compat features are any combination of the following: · 10 unmodified lines | ||
| 286 | 286 | - Description |
| 287 | 287 | * - 0x1 |
| 288 | 288 | - Journal maintains checksums on the data blocks. |
| 289 | − (JBD2\_FEATURE\_COMPAT\_CHECKSUM) | |
| 289 | + (JBD2_FEATURE_COMPAT_CHECKSUM) | |
| 290 | 290 | |
| 291 | 291 | .. _jbd2_incompat: |
| 292 | 292 | |
| @@ -299,23 +299,23 @@ The journal incompat features are any combination of the following: · 6 unmodified lines | ||
| 299 | 299 | * - Value |
| 300 | 300 | - Description |
| 301 | 301 | * - 0x1 |
| 302 | − - Journal has block revocation records. (JBD2\_FEATURE\_INCOMPAT\_REVOKE) | |
| 302 | + - Journal has block revocation records. (JBD2_FEATURE_INCOMPAT_REVOKE) | |
| 303 | 303 | * - 0x2 |
| 304 | 304 | - Journal can deal with 64-bit block numbers. |
| 305 | − (JBD2\_FEATURE\_INCOMPAT\_64BIT) | |
| 305 | + (JBD2_FEATURE_INCOMPAT_64BIT) | |
| 306 | 306 | * - 0x4 |
| 307 | − - Journal commits asynchronously. (JBD2\_FEATURE\_INCOMPAT\_ASYNC\_COMMIT) | |
| 307 | + - Journal commits asynchronously. (JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) | |
| 308 | 308 | * - 0x8 |
| 309 | 309 | - This journal uses v2 of the checksum on-disk format. Each journal |
| 310 | 310 | metadata block gets its own checksum, and the block tags in the |
| 311 | 311 | descriptor table contain checksums for each of the data blocks in the |
| 312 | − journal. (JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2) | |
| 312 | + journal. (JBD2_FEATURE_INCOMPAT_CSUM_V2) | |
| 313 | 313 | * - 0x10 |
| 314 | 314 | - This journal uses v3 of the checksum on-disk format. This is the same as |
| 315 | 315 | v2, but the journal block tag size is fixed regardless of the size of |
| 316 | − block numbers. (JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3) | |
| 316 | + block numbers. (JBD2_FEATURE_INCOMPAT_CSUM_V3) | |
| 317 | 317 | * - 0x20 |
| 318 | − - Journal has fast commit blocks. (JBD2\_FEATURE\_INCOMPAT\_FAST\_COMMIT) | |
| 318 | + - Journal has fast commit blocks. (JBD2_FEATURE_INCOMPAT_FAST_COMMIT) | |
| 319 | 319 | |
| 320 | 320 | .. _jbd2_checksum_type: |
| 321 | 321 | |
| @@ -355,11 +355,11 @@ Descriptor blocks consume at least 36 bytes, but use a full block: · 33 unmodified lines | ||
| 355 | 355 | - Name |
| 356 | 356 | - Descriptor |
| 357 | 357 | * - 0x0 |
| 358 | − - journal\_header\_t | |
| 358 | + - journal_header_t | |
| 359 | 359 | - (open coded) |
| 360 | 360 | - Common block header. |
| 361 | 361 | * - 0xC |
| 362 | − - struct journal\_block\_tag\_s | |
| 362 | + - struct journal_block_tag_s | |
| 363 | 363 | - open coded array[] |
| 364 | 364 | - Enough tags either to fill up the block or to describe all the data |
| 365 | 365 | blocks that follow this descriptor block. |
| @@ -367,7 +367,7 @@ Descriptor blocks consume at least 36 bytes, but use a full block: · 1 unmodified line | ||
| 367 | 367 | Journal block tags have any of the following formats, depending on which |
| 368 | 368 | journal feature and block tag flags are set. |
| 369 | 369 | |
| 370 | −If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 is set, the journal block tag is | |
| 370 | +If JBD2_FEATURE_INCOMPAT_CSUM_V3 is set, the journal block tag is | |
| 371 | 371 | defined as ``struct journal_block_tag3_s``, which looks like the |
| 372 | 372 | following. The size is 16 or 32 bytes. |
| 373 | 373 | |
| @@ -380,24 +380,24 @@ following. The size is 16 or 32 bytes. · 6 unmodified lines | ||
| 380 | 380 | - Name |
| 381 | 381 | - Descriptor |
| 382 | 382 | * - 0x0 |
| 383 | − - \_\_be32 | |
| 384 | − - t\_blocknr | |
| 383 | + - __be32 | |
| 384 | + - t_blocknr | |
| 385 | 385 | - Lower 32-bits of the location of where the corresponding data block |
| 386 | 386 | should end up on disk. |
| 387 | 387 | * - 0x4 |
| 388 | − - \_\_be32 | |
| 389 | − - t\_flags | |
| 388 | + - __be32 | |
| 389 | + - t_flags | |
| 390 | 390 | - Flags that go with the descriptor. See the table jbd2_tag_flags_ for |
| 391 | 391 | more info. |
| 392 | 392 | * - 0x8 |
| 393 | − - \_\_be32 | |
| 394 | − - t\_blocknr\_high | |
| 393 | + - __be32 | |
| 394 | + - t_blocknr_high | |
| 395 | 395 | - Upper 32-bits of the location of where the corresponding data block |
| 396 | − should end up on disk. This is zero if JBD2\_FEATURE\_INCOMPAT\_64BIT is | |
| 396 | + should end up on disk. This is zero if JBD2_FEATURE_INCOMPAT_64BIT is | |
| 397 | 397 | not enabled. |
| 398 | 398 | * - 0xC |
| 399 | − - \_\_be32 | |
| 400 | − - t\_checksum | |
| 399 | + - __be32 | |
| 400 | + - t_checksum | |
| 401 | 401 | - Checksum of the journal UUID, the sequence number, and the data block. |
| 402 | 402 | * - |
| 403 | 403 | - |
| @@ -433,7 +433,7 @@ The journal tag flags are any combination of the following: · 29 unmodified lines | ||
| 433 | 433 | * - 0x8 |
| 434 | 434 | - This is the last tag in this descriptor block. |
| 435 | 435 | |
| 436 | −If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 is NOT set, the journal block tag | |
| 436 | +If JBD2_FEATURE_INCOMPAT_CSUM_V3 is NOT set, the journal block tag | |
| 437 | 437 | is defined as ``struct journal_block_tag_s``, which looks like the |
| 438 | 438 | following. The size is 8, 12, 24, or 28 bytes: |
| 439 | 439 | |
| @@ -446,18 +446,18 @@ following. The size is 8, 12, 24, or 28 bytes: · 6 unmodified lines | ||
| 446 | 446 | - Name |
| 447 | 447 | - Descriptor |
| 448 | 448 | * - 0x0 |
| 449 | − - \_\_be32 | |
| 450 | − - t\_blocknr | |
| 449 | + - __be32 | |
| 450 | + - t_blocknr | |
| 451 | 451 | - Lower 32-bits of the location of where the corresponding data block |
| 452 | 452 | should end up on disk. |
| 453 | 453 | * - 0x4 |
| 454 | − - \_\_be16 | |
| 455 | − - t\_checksum | |
| 454 | + - __be16 | |
| 455 | + - t_checksum | |
| 456 | 456 | - Checksum of the journal UUID, the sequence number, and the data block. |
| 457 | 457 | Note that only the lower 16 bits are stored. |
| 458 | 458 | * - 0x6 |
| 459 | − - \_\_be16 | |
| 460 | − - t\_flags | |
| 459 | + - __be16 | |
| 460 | + - t_flags | |
| 461 | 461 | - Flags that go with the descriptor. See the table jbd2_tag_flags_ for |
| 462 | 462 | more info. |
| 463 | 463 | * - |
| @@ -466,8 +466,8 @@ following. The size is 8, 12, 24, or 28 bytes: · 2 unmodified lines | ||
| 466 | 466 | - This next field is only present if the super block indicates support for |
| 467 | 467 | 64-bit block numbers. |
| 468 | 468 | * - 0x8 |
| 469 | − - \_\_be32 | |
| 470 | − - t\_blocknr\_high | |
| 469 | + - __be32 | |
| 470 | + - t_blocknr_high | |
| 471 | 471 | - Upper 32-bits of the location of where the corresponding data block |
| 472 | 472 | should end up on disk. |
| 473 | 473 | * - |
| @@ -483,8 +483,8 @@ following. The size is 8, 12, 24, or 28 bytes: · 9 unmodified lines | ||
| 483 | 483 | ``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that |
| 484 | 484 | field. |
| 485 | 485 | |
| 486 | −If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or | |
| 487 | −JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the block is a | |
| 486 | +If JBD2_FEATURE_INCOMPAT_CSUM_V2 or | |
| 487 | +JBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the block is a | |
| 488 | 488 | ``struct jbd2_journal_block_tail``, which looks like this: |
| 489 | 489 | |
| 490 | 490 | .. list-table:: |
| @@ -496,8 +496,8 @@ JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the block is a · 5 unmodified lines | ||
| 496 | 496 | - Name |
| 497 | 497 | - Descriptor |
| 498 | 498 | * - 0x0 |
| 499 | − - \_\_be32 | |
| 500 | − - t\_checksum | |
| 499 | + - __be32 | |
| 500 | + - t_checksum | |
| 501 | 501 | - Checksum of the journal UUID + the descriptor block, with this field set |
| 502 | 502 | to zero. |
| 503 | 503 | |
| @@ -538,25 +538,25 @@ length, but use a full block: · 34 unmodified lines | ||
| 538 | 538 | - Name |
| 539 | 539 | - Description |
| 540 | 540 | * - 0x0 |
| 541 | − - journal\_header\_t | |
| 542 | − - r\_header | |
| 541 | + - journal_header_t | |
| 542 | + - r_header | |
| 543 | 543 | - Common block header. |
| 544 | 544 | * - 0xC |
| 545 | − - \_\_be32 | |
| 546 | − - r\_count | |
| 545 | + - __be32 | |
| 546 | + - r_count | |
| 547 | 547 | - Number of bytes used in this block. |
| 548 | 548 | * - 0x10 |
| 549 | − - \_\_be32 or \_\_be64 | |
| 549 | + - __be32 or __be64 | |
| 550 | 550 | - blocks[0] |
| 551 | 551 | - Blocks to revoke. |
| 552 | 552 | |
| 553 | −After r\_count is a linear array of block numbers that are effectively | |
| 553 | +After r_count is a linear array of block numbers that are effectively | |
| 554 | 554 | revoked by this transaction. The size of each block number is 8 bytes if |
| 555 | 555 | the superblock advertises 64-bit block number support, or 4 bytes |
| 556 | 556 | otherwise. |
| 557 | 557 | |
| 558 | −If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or | |
| 559 | −JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the revocation | |
| 558 | +If JBD2_FEATURE_INCOMPAT_CSUM_V2 or | |
| 559 | +JBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the revocation | |
| 560 | 560 | block is a ``struct jbd2_journal_revoke_tail``, which has this format: |
| 561 | 561 | |
| 562 | 562 | .. list-table:: |
| @@ -568,8 +568,8 @@ block is a ``struct jbd2_journal_revoke_tail``, which has this format: · 5 unmodified lines | ||
| 568 | 568 | - Name |
| 569 | 569 | - Description |
| 570 | 570 | * - 0x0 |
| 571 | − - \_\_be32 | |
| 572 | − - r\_checksum | |
| 571 | + - __be32 | |
| 572 | + - r_checksum | |
| 573 | 573 | - Checksum of the journal UUID + revocation block |
| 574 | 574 | |
| 575 | 575 | Commit Block |
| @@ -592,38 +592,38 @@ bytes long (but uses a full block): · 16 unmodified lines | ||
| 592 | 592 | - Name |
| 593 | 593 | - Descriptor |
| 594 | 594 | * - 0x0 |
| 595 | − - journal\_header\_s | |
| 595 | + - journal_header_s | |
| 596 | 596 | - (open coded) |
| 597 | 597 | - Common block header. |
| 598 | 598 | * - 0xC |
| 599 | 599 | - unsigned char |
| 600 | − - h\_chksum\_type | |
| 600 | + - h_chksum_type | |
| 601 | 601 | - The type of checksum to use to verify the integrity of the data blocks |
| 602 | 602 | in the transaction. See jbd2_checksum_type_ for more info. |
| 603 | 603 | * - 0xD |
| 604 | 604 | - unsigned char |
| 605 | − - h\_chksum\_size | |
| 605 | + - h_chksum_size | |
| 606 | 606 | - The number of bytes used by the checksum. Most likely 4. |
| 607 | 607 | * - 0xE |
| 608 | 608 | - unsigned char |
| 609 | − - h\_padding[2] | |
| 609 | + - h_padding[2] | |
| 610 | 610 | - |
| 611 | 611 | * - 0x10 |
| 612 | − - \_\_be32 | |
| 613 | − - h\_chksum[JBD2\_CHECKSUM\_BYTES] | |
| 612 | + - __be32 | |
| 613 | + - h_chksum[JBD2_CHECKSUM_BYTES] | |
| 614 | 614 | - 32 bytes of space to store checksums. If |
| 615 | − JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 | |
| 615 | + JBD2_FEATURE_INCOMPAT_CSUM_V2 or JBD2_FEATURE_INCOMPAT_CSUM_V3 | |
| 616 | 616 | are set, the first ``__be32`` is the checksum of the journal UUID and |
| 617 | 617 | the entire commit block, with this field zeroed. If |
| 618 | − JBD2\_FEATURE\_COMPAT\_CHECKSUM is set, the first ``__be32`` is the | |
| 618 | + JBD2_FEATURE_COMPAT_CHECKSUM is set, the first ``__be32`` is the | |
| 619 | 619 | crc32 of all the blocks already written to the transaction. |
| 620 | 620 | * - 0x30 |
| 621 | − - \_\_be64 | |
| 622 | − - h\_commit\_sec | |
| 621 | + - __be64 | |
| 622 | + - h_commit_sec | |
| 623 | 623 | - The time that the transaction was committed, in seconds since the epoch. |
| 624 | 624 | * - 0x38 |
| 625 | − - \_\_be32 | |
| 626 | − - h\_commit\_nsec | |
| 625 | + - __be32 | |
| 626 | + - h_commit_nsec | |
| 627 | 627 | - Nanoseconds component of the above timestamp. |
| 628 | 628 | |
| 629 | 629 | Fast commits |
| @@ -7,8 +7,8 @@ Multiple mount protection (MMP) is a feature that protects the · 6 unmodified lines | ||
| 7 | 7 | filesystem against multiple hosts trying to use the filesystem |
| 8 | 8 | simultaneously. When a filesystem is opened (for mounting, or fsck, |
| 9 | 9 | etc.), the MMP code running on the node (call it node A) checks a |
| 10 | −sequence number. If the sequence number is EXT4\_MMP\_SEQ\_CLEAN, the | |
| 11 | −open continues. If the sequence number is EXT4\_MMP\_SEQ\_FSCK, then | |
| 10 | +sequence number. If the sequence number is EXT4_MMP_SEQ_CLEAN, the | |
| 11 | +open continues. If the sequence number is EXT4_MMP_SEQ_FSCK, then | |
| 12 | 12 | fsck is (hopefully) running, and open fails immediately. Otherwise, the |
| 13 | 13 | open code will wait for twice the specified MMP check interval and check |
| 14 | 14 | the sequence number again. If the sequence number has changed, then the |
| @@ -40,38 +40,38 @@ The MMP structure (``struct mmp_struct``) is as follows: · 25 unmodified lines | ||
| 40 | 40 | - Name |
| 41 | 41 | - Description |
| 42 | 42 | * - 0x0 |
| 43 | − - \_\_le32 | |
| 44 | − - mmp\_magic | |
| 43 | + - __le32 | |
| 44 | + - mmp_magic | |
| 45 | 45 | - Magic number for MMP, 0x004D4D50 (“MMP”). |
| 46 | 46 | * - 0x4 |
| 47 | − - \_\_le32 | |
| 48 | − - mmp\_seq | |
| 47 | + - __le32 | |
| 48 | + - mmp_seq | |
| 49 | 49 | - Sequence number, updated periodically. |
| 50 | 50 | * - 0x8 |
| 51 | − - \_\_le64 | |
| 52 | − - mmp\_time | |
| 51 | + - __le64 | |
| 52 | + - mmp_time | |
| 53 | 53 | - Time that the MMP block was last updated. |
| 54 | 54 | * - 0x10 |
| 55 | 55 | - char[64] |
| 56 | − - mmp\_nodename | |
| 56 | + - mmp_nodename | |
| 57 | 57 | - Hostname of the node that opened the filesystem. |
| 58 | 58 | * - 0x50 |
| 59 | 59 | - char[32] |
| 60 | − - mmp\_bdevname | |
| 60 | + - mmp_bdevname | |
| 61 | 61 | - Block device name of the filesystem. |
| 62 | 62 | * - 0x70 |
| 63 | − - \_\_le16 | |
| 64 | − - mmp\_check\_interval | |
| 63 | + - __le16 | |
| 64 | + - mmp_check_interval | |
| 65 | 65 | - The MMP re-check interval, in seconds. |
| 66 | 66 | * - 0x72 |
| 67 | − - \_\_le16 | |
| 68 | − - mmp\_pad1 | |
| 67 | + - __le16 | |
| 68 | + - mmp_pad1 | |
| 69 | 69 | - Zero. |
| 70 | 70 | * - 0x74 |
| 71 | − - \_\_le32[226] | |
| 72 | − - mmp\_pad2 | |
| 71 | + - __le32[226] | |
| 72 | + - mmp_pad2 | |
| 73 | 73 | - Zero. |
| 74 | 74 | * - 0x3FC |
| 75 | − - \_\_le32 | |
| 76 | − - mmp\_checksum | |
| 75 | + - __le32 | |
| 76 | + - mmp_checksum | |
| 77 | 77 | - Checksum of the MMP block. |
| @@ -7,7 +7,7 @@ An ext4 file system is split into a series of block groups. To reduce · 6 unmodified lines | ||
| 7 | 7 | performance difficulties due to fragmentation, the block allocator tries |
| 8 | 8 | very hard to keep each file's blocks within the same group, thereby |
| 9 | 9 | reducing seek times. The size of a block group is specified in |
| 10 | −``sb.s_blocks_per_group`` blocks, though it can also calculated as 8 \* | |
| 10 | +``sb.s_blocks_per_group`` blocks, though it can also calculated as 8 * | |
| 11 | 11 | ``block_size_in_bytes``. With the default block size of 4KiB, each group |
| 12 | 12 | will contain 32,768 blocks, for a length of 128MiB. The number of block |
| 13 | 13 | groups is the size of the device divided by the size of a block group. |
| @@ -34,7 +34,7 @@ ext4 reserves some inode for special features, as follows: · 33 unmodified lines | ||
| 34 | 34 | * - 10 |
| 35 | 35 | - Replica inode, used for some non-upstream feature? |
| 36 | 36 | * - 11 |
| 37 | − - Traditional first non-reserved inode. Usually this is the lost+found directory. See s\_first\_ino in the superblock. | |
| 37 | + - Traditional first non-reserved inode. Usually this is the lost+found directory. See s_first_ino in the superblock. | |
| 38 | 38 | |
| 39 | 39 | Note that there are also some inodes allocated from non-reserved inode numbers |
| 40 | 40 | for other filesystem features which are not referenced from standard directory |
| @@ -47,9 +47,9 @@ hierarchy. These are generally reference from the superblock. They are: · 6 unmodified lines | ||
| 47 | 47 | * - Superblock field |
| 48 | 48 | - Description |
| 49 | 49 | |
| 50 | − * - s\_lpf\_ino | |
| 50 | + * - s_lpf_ino | |
| 51 | 51 | - Inode number of lost+found directory. |
| 52 | − * - s\_prj\_quota\_inum | |
| 52 | + * - s_prj_quota_inum | |
| 53 | 53 | - Inode number of quota file tracking project quotas |
| 54 | − * - s\_orphan\_file\_inum | |
| 54 | + * - s_orphan_file_inum | |
| 55 | 55 | - Inode number of file tracking orphan inodes. |
| @@ -7,7 +7,7 @@ The superblock records various information about the enclosing · 6 unmodified lines | ||
| 7 | 7 | filesystem, such as block counts, inode counts, supported features, |
| 8 | 8 | maintenance information, and more. |
| 9 | 9 | |
| 10 | −If the sparse\_super feature flag is set, redundant copies of the | |
| 10 | +If the sparse_super feature flag is set, redundant copies of the | |
| 11 | 11 | superblock and group descriptors are kept only in the groups whose group |
| 12 | 12 | number is either 0 or a power of 3, 5, or 7. If the flag is not set, |
| 13 | 13 | redundant copies are kept in all groups. |
| @@ -27,107 +27,107 @@ The ext4 superblock is laid out as follows in · 13 unmodified lines | ||
| 27 | 27 | - Name |
| 28 | 28 | - Description |
| 29 | 29 | * - 0x0 |
| 30 | − - \_\_le32 | |
| 31 | − - s\_inodes\_count | |
| 30 | + - __le32 | |
| 31 | + - s_inodes_count | |
| 32 | 32 | - Total inode count. |
| 33 | 33 | * - 0x4 |
| 34 | − - \_\_le32 | |
| 35 | − - s\_blocks\_count\_lo | |
| 34 | + - __le32 | |
| 35 | + - s_blocks_count_lo | |
| 36 | 36 | - Total block count. |
| 37 | 37 | * - 0x8 |
| 38 | − - \_\_le32 | |
| 39 | − - s\_r\_blocks\_count\_lo | |
| 38 | + - __le32 | |
| 39 | + - s_r_blocks_count_lo | |
| 40 | 40 | - This number of blocks can only be allocated by the super-user. |
| 41 | 41 | * - 0xC |
| 42 | − - \_\_le32 | |
| 43 | − - s\_free\_blocks\_count\_lo | |
| 42 | + - __le32 | |
| 43 | + - s_free_blocks_count_lo | |
| 44 | 44 | - Free block count. |
| 45 | 45 | * - 0x10 |
| 46 | − - \_\_le32 | |
| 47 | − - s\_free\_inodes\_count | |
| 46 | + - __le32 | |
| 47 | + - s_free_inodes_count | |
| 48 | 48 | - Free inode count. |
| 49 | 49 | * - 0x14 |
| 50 | − - \_\_le32 | |
| 51 | − - s\_first\_data\_block | |
| 50 | + - __le32 | |
| 51 | + - s_first_data_block | |
| 52 | 52 | - First data block. This must be at least 1 for 1k-block filesystems and |
| 53 | 53 | is typically 0 for all other block sizes. |
| 54 | 54 | * - 0x18 |
| 55 | − - \_\_le32 | |
| 56 | − - s\_log\_block\_size | |
| 57 | − - Block size is 2 ^ (10 + s\_log\_block\_size). | |
| 55 | + - __le32 | |
| 56 | + - s_log_block_size | |
| 57 | + - Block size is 2 ^ (10 + s_log_block_size). | |
| 58 | 58 | * - 0x1C |
| 59 | − - \_\_le32 | |
| 60 | − - s\_log\_cluster\_size | |
| 61 | − - Cluster size is 2 ^ (10 + s\_log\_cluster\_size) blocks if bigalloc is | |
| 62 | − enabled. Otherwise s\_log\_cluster\_size must equal s\_log\_block\_size. | |
| 59 | + - __le32 | |
| 60 | + - s_log_cluster_size | |
| 61 | + - Cluster size is 2 ^ (10 + s_log_cluster_size) blocks if bigalloc is | |
| 62 | + enabled. Otherwise s_log_cluster_size must equal s_log_block_size. | |
| 63 | 63 | * - 0x20 |
| 64 | − - \_\_le32 | |
| 65 | − - s\_blocks\_per\_group | |
| 64 | + - __le32 | |
| 65 | + - s_blocks_per_group | |
| 66 | 66 | - Blocks per group. |
| 67 | 67 | * - 0x24 |
| 68 | − - \_\_le32 | |
| 69 | − - s\_clusters\_per\_group | |
| 68 | + - __le32 | |
| 69 | + - s_clusters_per_group | |
| 70 | 70 | - Clusters per group, if bigalloc is enabled. Otherwise |
| 71 | − s\_clusters\_per\_group must equal s\_blocks\_per\_group. | |
| 71 | + s_clusters_per_group must equal s_blocks_per_group. | |
| 72 | 72 | * - 0x28 |
| 73 | − - \_\_le32 | |
| 74 | − - s\_inodes\_per\_group | |
| 73 | + - __le32 | |
| 74 | + - s_inodes_per_group | |
| 75 | 75 | - Inodes per group. |
| 76 | 76 | * - 0x2C |
| 77 | − - \_\_le32 | |
| 78 | − - s\_mtime | |
| 77 | + - __le32 | |
| 78 | + - s_mtime | |
| 79 | 79 | - Mount time, in seconds since the epoch. |
| 80 | 80 | * - 0x30 |
| 81 | − - \_\_le32 | |
| 82 | − - s\_wtime | |
| 81 | + - __le32 | |
| 82 | + - s_wtime | |
| 83 | 83 | - Write time, in seconds since the epoch. |
| 84 | 84 | * - 0x34 |
| 85 | − - \_\_le16 | |
| 86 | − - s\_mnt\_count | |
| 85 | + - __le16 | |
| 86 | + - s_mnt_count | |
| 87 | 87 | - Number of mounts since the last fsck. |
| 88 | 88 | * - 0x36 |
| 89 | − - \_\_le16 | |
| 90 | − - s\_max\_mnt\_count | |
| 89 | + - __le16 | |
| 90 | + - s_max_mnt_count | |
| 91 | 91 | - Number of mounts beyond which a fsck is needed. |
| 92 | 92 | * - 0x38 |
| 93 | − - \_\_le16 | |
| 94 | − - s\_magic | |
| 93 | + - __le16 | |
| 94 | + - s_magic | |
| 95 | 95 | - Magic signature, 0xEF53 |
| 96 | 96 | * - 0x3A |
| 97 | − - \_\_le16 | |
| 98 | − - s\_state | |
| 97 | + - __le16 | |
| 98 | + - s_state | |
| 99 | 99 | - File system state. See super_state_ for more info. |
| 100 | 100 | * - 0x3C |
| 101 | − - \_\_le16 | |
| 102 | − - s\_errors | |
| 101 | + - __le16 | |
| 102 | + - s_errors | |
| 103 | 103 | - Behaviour when detecting errors. See super_errors_ for more info. |
| 104 | 104 | * - 0x3E |
| 105 | − - \_\_le16 | |
| 106 | − - s\_minor\_rev\_level | |
| 105 | + - __le16 | |
| 106 | + - s_minor_rev_level | |
| 107 | 107 | - Minor revision level. |
| 108 | 108 | * - 0x40 |
| 109 | − - \_\_le32 | |
| 110 | − - s\_lastcheck | |
| 109 | + - __le32 | |
| 110 | + - s_lastcheck | |
| 111 | 111 | - Time of last check, in seconds since the epoch. |
| 112 | 112 | * - 0x44 |
| 113 | − - \_\_le32 | |
| 114 | − - s\_checkinterval | |
| 113 | + - __le32 | |
| 114 | + - s_checkinterval | |
| 115 | 115 | - Maximum time between checks, in seconds. |
| 116 | 116 | * - 0x48 |
| 117 | − - \_\_le32 | |
| 118 | − - s\_creator\_os | |
| 117 | + - __le32 | |
| 118 | + - s_creator_os | |
| 119 | 119 | - Creator OS. See the table super_creator_ for more info. |
| 120 | 120 | * - 0x4C |
| 121 | − - \_\_le32 | |
| 122 | − - s\_rev\_level | |
| 121 | + - __le32 | |
| 122 | + - s_rev_level | |
| 123 | 123 | - Revision level. See the table super_revision_ for more info. |
| 124 | 124 | * - 0x50 |
| 125 | − - \_\_le16 | |
| 126 | − - s\_def\_resuid | |
| 125 | + - __le16 | |
| 126 | + - s_def_resuid | |
| 127 | 127 | - Default uid for reserved blocks. |
| 128 | 128 | * - 0x52 |
| 129 | − - \_\_le16 | |
| 130 | − - s\_def\_resgid | |
| 129 | + - __le16 | |
| 130 | + - s_def_resgid | |
| 131 | 131 | - Default gid for reserved blocks. |
| 132 | 132 | * - |
| 133 | 133 | - |
| @@ -143,50 +143,50 @@ The ext4 superblock is laid out as follows in · 9 unmodified lines | ||
| 143 | 143 | about a feature in either the compatible or incompatible feature set, it |
| 144 | 144 | must abort and not try to meddle with things it doesn't understand... |
| 145 | 145 | * - 0x54 |
| 146 | − - \_\_le32 | |
| 147 | − - s\_first\_ino | |
| 146 | + - __le32 | |
| 147 | + - s_first_ino | |
| 148 | 148 | - First non-reserved inode. |
| 149 | 149 | * - 0x58 |
| 150 | − - \_\_le16 | |
| 151 | − - s\_inode\_size | |
| 150 | + - __le16 | |
| 151 | + - s_inode_size | |
| 152 | 152 | - Size of inode structure, in bytes. |
| 153 | 153 | * - 0x5A |
| 154 | − - \_\_le16 | |
| 155 | − - s\_block\_group\_nr | |
| 154 | + - __le16 | |
| 155 | + - s_block_group_nr | |
| 156 | 156 | - Block group # of this superblock. |
| 157 | 157 | * - 0x5C |
| 158 | − - \_\_le32 | |
| 159 | − - s\_feature\_compat | |
| 158 | + - __le32 | |
| 159 | + - s_feature_compat | |
| 160 | 160 | - Compatible feature set flags. Kernel can still read/write this fs even |
| 161 | 161 | if it doesn't understand a flag; fsck should not do that. See the |
| 162 | 162 | super_compat_ table for more info. |
| 163 | 163 | * - 0x60 |
| 164 | − - \_\_le32 | |
| 165 | − - s\_feature\_incompat | |
| 164 | + - __le32 | |
| 165 | + - s_feature_incompat | |
| 166 | 166 | - Incompatible feature set. If the kernel or fsck doesn't understand one |
| 167 | 167 | of these bits, it should stop. See the super_incompat_ table for more |
| 168 | 168 | info. |
| 169 | 169 | * - 0x64 |
| 170 | − - \_\_le32 | |
| 171 | − - s\_feature\_ro\_compat | |
| 170 | + - __le32 | |
| 171 | + - s_feature_ro_compat | |
| 172 | 172 | - Readonly-compatible feature set. If the kernel doesn't understand one of |
| 173 | 173 | these bits, it can still mount read-only. See the super_rocompat_ table |
| 174 | 174 | for more info. |
| 175 | 175 | * - 0x68 |
| 176 | − - \_\_u8 | |
| 177 | − - s\_uuid[16] | |
| 176 | + - __u8 | |
| 177 | + - s_uuid[16] | |
| 178 | 178 | - 128-bit UUID for volume. |
| 179 | 179 | * - 0x78 |
| 180 | 180 | - char |
| 181 | − - s\_volume\_name[16] | |
| 181 | + - s_volume_name[16] | |
| 182 | 182 | - Volume label. |
| 183 | 183 | * - 0x88 |
| 184 | 184 | - char |
| 185 | − - s\_last\_mounted[64] | |
| 185 | + - s_last_mounted[64] | |
| 186 | 186 | - Directory where filesystem was last mounted. |
| 187 | 187 | * - 0xC8 |
| 188 | − - \_\_le32 | |
| 189 | − - s\_algorithm\_usage\_bitmap | |
| 188 | + - __le32 | |
| 189 | + - s_algorithm_usage_bitmap | |
| 190 | 190 | - For compression (Not used in e2fsprogs/Linux) |
| 191 | 191 | * - |
| 192 | 192 | - |
| @@ -194,18 +194,18 @@ The ext4 superblock is laid out as follows in · 1 unmodified line | ||
| 194 | 194 | - Performance hints. Directory preallocation should only happen if the |
| 195 | 195 | EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. |
| 196 | 196 | * - 0xCC |
| 197 | − - \_\_u8 | |
| 198 | − - s\_prealloc\_blocks | |
| 197 | + - __u8 | |
| 198 | + - s_prealloc_blocks | |
| 199 | 199 | - #. of blocks to try to preallocate for ... files? (Not used in |
| 200 | 200 | e2fsprogs/Linux) |
| 201 | 201 | * - 0xCD |
| 202 | − - \_\_u8 | |
| 203 | − - s\_prealloc\_dir\_blocks | |
| 202 | + - __u8 | |
| 203 | + - s_prealloc_dir_blocks | |
| 204 | 204 | - #. of blocks to preallocate for directories. (Not used in |
| 205 | 205 | e2fsprogs/Linux) |
| 206 | 206 | * - 0xCE |
| 207 | − - \_\_le16 | |
| 208 | − - s\_reserved\_gdt\_blocks | |
| 207 | + - __le16 | |
| 208 | + - s_reserved_gdt_blocks | |
| 209 | 209 | - Number of reserved GDT entries for future filesystem expansion. |
| 210 | 210 | * - |
| 211 | 211 | - |
| @@ -213,281 +213,281 @@ The ext4 superblock is laid out as follows in · 1 unmodified line | ||
| 213 | 213 | - Journalling support is valid only if EXT4_FEATURE_COMPAT_HAS_JOURNAL is |
| 214 | 214 | set. |
| 215 | 215 | * - 0xD0 |
| 216 | − - \_\_u8 | |
| 217 | − - s\_journal\_uuid[16] | |
| 216 | + - __u8 | |
| 217 | + - s_journal_uuid[16] | |
| 218 | 218 | - UUID of journal superblock |
| 219 | 219 | * - 0xE0 |
| 220 | − - \_\_le32 | |
| 221 | − - s\_journal\_inum | |
| 220 | + - __le32 | |
| 221 | + - s_journal_inum | |
| 222 | 222 | - inode number of journal file. |
| 223 | 223 | * - 0xE4 |
| 224 | − - \_\_le32 | |
| 225 | − - s\_journal\_dev | |
| 224 | + - __le32 | |
| 225 | + - s_journal_dev | |
| 226 | 226 | - Device number of journal file, if the external journal feature flag is |
| 227 | 227 | set. |
| 228 | 228 | * - 0xE8 |
| 229 | − - \_\_le32 | |
| 230 | − - s\_last\_orphan | |
| 229 | + - __le32 | |
| 230 | + - s_last_orphan | |
| 231 | 231 | - Start of list of orphaned inodes to delete. |
| 232 | 232 | * - 0xEC |
| 233 | − - \_\_le32 | |
| 234 | − - s\_hash\_seed[4] | |
| 233 | + - __le32 | |
| 234 | + - s_hash_seed[4] | |
| 235 | 235 | - HTREE hash seed. |
| 236 | 236 | * - 0xFC |
| 237 | − - \_\_u8 | |
| 238 | − - s\_def\_hash\_version | |
| 237 | + - __u8 | |
| 238 | + - s_def_hash_version | |
| 239 | 239 | - Default hash algorithm to use for directory hashes. See super_def_hash_ |
| 240 | 240 | for more info. |
| 241 | 241 | * - 0xFD |
| 242 | − - \_\_u8 | |
| 243 | − - s\_jnl\_backup\_type | |
| 244 | − - If this value is 0 or EXT3\_JNL\_BACKUP\_BLOCKS (1), then the | |
| 242 | + - __u8 | |
| 243 | + - s_jnl_backup_type | |
| 244 | + - If this value is 0 or EXT3_JNL_BACKUP_BLOCKS (1), then the | |
| 245 | 245 | ``s_jnl_blocks`` field contains a duplicate copy of the inode's |
| 246 | 246 | ``i_block[]`` array and ``i_size``. |
| 247 | 247 | * - 0xFE |
| 248 | − - \_\_le16 | |
| 249 | − - s\_desc\_size | |
| 248 | + - __le16 | |
| 249 | + - s_desc_size | |
| 250 | 250 | - Size of group descriptors, in bytes, if the 64bit incompat feature flag |
| 251 | 251 | is set. |
| 252 | 252 | * - 0x100 |
| 253 | − - \_\_le32 | |
| 254 | − - s\_default\_mount\_opts | |
| 253 | + - __le32 | |
| 254 | + - s_default_mount_opts | |
| 255 | 255 | - Default mount options. See the super_mountopts_ table for more info. |
| 256 | 256 | * - 0x104 |
| 257 | − - \_\_le32 | |
| 258 | − - s\_first\_meta\_bg | |
| 259 | − - First metablock block group, if the meta\_bg feature is enabled. | |
| 257 | + - __le32 | |
| 258 | + - s_first_meta_bg | |
| 259 | + - First metablock block group, if the meta_bg feature is enabled. | |
| 260 | 260 | * - 0x108 |
| 261 | − - \_\_le32 | |
| 262 | − - s\_mkfs\_time | |
| 261 | + - __le32 | |
| 262 | + - s_mkfs_time | |
| 263 | 263 | - When the filesystem was created, in seconds since the epoch. |
| 264 | 264 | * - 0x10C |
| 265 | − - \_\_le32 | |
| 266 | − - s\_jnl\_blocks[17] | |
| 265 | + - __le32 | |
| 266 | + - s_jnl_blocks[17] | |
| 267 | 267 | - Backup copy of the journal inode's ``i_block[]`` array in the first 15 |
| 268 | − elements and i\_size\_high and i\_size in the 16th and 17th elements, | |
| 268 | + elements and i_size_high and i_size in the 16th and 17th elements, | |
| 269 | 269 | respectively. |
| 270 | 270 | * - |
| 271 | 271 | - |
| 272 | 272 | - |
| 273 | 273 | - 64bit support is valid only if EXT4_FEATURE_COMPAT_64BIT is set. |
| 274 | 274 | * - 0x150 |
| 275 | − - \_\_le32 | |
| 276 | − - s\_blocks\_count\_hi | |
| 275 | + - __le32 | |
| 276 | + - s_blocks_count_hi | |
| 277 | 277 | - High 32-bits of the block count. |
| 278 | 278 | * - 0x154 |
| 279 | − - \_\_le32 | |
| 280 | − - s\_r\_blocks\_count\_hi | |
| 279 | + - __le32 | |
| 280 | + - s_r_blocks_count_hi | |
| 281 | 281 | - High 32-bits of the reserved block count. |
| 282 | 282 | * - 0x158 |
| 283 | − - \_\_le32 | |
| 284 | − - s\_free\_blocks\_count\_hi | |
| 283 | + - __le32 | |
| 284 | + - s_free_blocks_count_hi | |
| 285 | 285 | - High 32-bits of the free block count. |
| 286 | 286 | * - 0x15C |
| 287 | − - \_\_le16 | |
| 288 | − - s\_min\_extra\_isize | |
| 287 | + - __le16 | |
| 288 | + - s_min_extra_isize | |
| 289 | 289 | - All inodes have at least # bytes. |
| 290 | 290 | * - 0x15E |
| 291 | − - \_\_le16 | |
| 292 | − - s\_want\_extra\_isize | |
| 291 | + - __le16 | |
| 292 | + - s_want_extra_isize | |
| 293 | 293 | - New inodes should reserve # bytes. |
| 294 | 294 | * - 0x160 |
| 295 | − - \_\_le32 | |
| 296 | − - s\_flags | |
| 295 | + - __le32 | |
| 296 | + - s_flags | |
| 297 | 297 | - Miscellaneous flags. See the super_flags_ table for more info. |
| 298 | 298 | * - 0x164 |
| 299 | − - \_\_le16 | |
| 300 | − - s\_raid\_stride | |
| 299 | + - __le16 | |
| 300 | + - s_raid_stride | |
| 301 | 301 | - RAID stride. This is the number of logical blocks read from or written |
| 302 | 302 | to the disk before moving to the next disk. This affects the placement |
| 303 | 303 | of filesystem metadata, which will hopefully make RAID storage faster. |
| 304 | 304 | * - 0x166 |
| 305 | − - \_\_le16 | |
| 306 | − - s\_mmp\_interval | |
| 305 | + - __le16 | |
| 306 | + - s_mmp_interval | |
| 307 | 307 | - #. seconds to wait in multi-mount prevention (MMP) checking. In theory, |
| 308 | 308 | MMP is a mechanism to record in the superblock which host and device |
| 309 | 309 | have mounted the filesystem, in order to prevent multiple mounts. This |
| 310 | 310 | feature does not seem to be implemented... |
| 311 | 311 | * - 0x168 |
| 312 | − - \_\_le64 | |
| 313 | − - s\_mmp\_block | |
| 312 | + - __le64 | |
| 313 | + - s_mmp_block | |
| 314 | 314 | - Block # for multi-mount protection data. |
| 315 | 315 | * - 0x170 |
| 316 | − - \_\_le32 | |
| 317 | − - s\_raid\_stripe\_width | |
| 316 | + - __le32 | |
| 317 | + - s_raid_stripe_width | |
| 318 | 318 | - RAID stripe width. This is the number of logical blocks read from or |
| 319 | 319 | written to the disk before coming back to the current disk. This is used |
| 320 | 320 | by the block allocator to try to reduce the number of read-modify-write |
| 321 | 321 | operations in a RAID5/6. |
| 322 | 322 | * - 0x174 |
| 323 | − - \_\_u8 | |
| 324 | − - s\_log\_groups\_per\_flex | |
| 323 | + - __u8 | |
| 324 | + - s_log_groups_per_flex | |
| 325 | 325 | - Size of a flexible block group is 2 ^ ``s_log_groups_per_flex``. |
| 326 | 326 | * - 0x175 |
| 327 | − - \_\_u8 | |
| 328 | − - s\_checksum\_type | |
| 327 | + - __u8 | |
| 328 | + - s_checksum_type | |
| 329 | 329 | - Metadata checksum algorithm type. The only valid value is 1 (crc32c). |
| 330 | 330 | * - 0x176 |
| 331 | − - \_\_le16 | |
| 332 | − - s\_reserved\_pad | |
| 331 | + - __le16 | |
| 332 | + - s_reserved_pad | |
| 333 | 333 | - |
| 334 | 334 | * - 0x178 |
| 335 | − - \_\_le64 | |
| 336 | − - s\_kbytes\_written | |
| 335 | + - __le64 | |
| 336 | + - s_kbytes_written | |
| 337 | 337 | - Number of KiB written to this filesystem over its lifetime. |
| 338 | 338 | * - 0x180 |
| 339 | − - \_\_le32 | |
| 340 | − - s\_snapshot\_inum | |
| 339 | + - __le32 | |
| 340 | + - s_snapshot_inum | |
| 341 | 341 | - inode number of active snapshot. (Not used in e2fsprogs/Linux.) |
| 342 | 342 | * - 0x184 |
| 343 | − - \_\_le32 | |
| 344 | − - s\_snapshot\_id | |
| 343 | + - __le32 | |
| 344 | + - s_snapshot_id | |
| 345 | 345 | - Sequential ID of active snapshot. (Not used in e2fsprogs/Linux.) |
| 346 | 346 | * - 0x188 |
| 347 | − - \_\_le64 | |
| 348 | − - s\_snapshot\_r\_blocks\_count | |
| 347 | + - __le64 | |
| 348 | + - s_snapshot_r_blocks_count | |
| 349 | 349 | - Number of blocks reserved for active snapshot's future use. (Not used in |
| 350 | 350 | e2fsprogs/Linux.) |
| 351 | 351 | * - 0x190 |
| 352 | − - \_\_le32 | |
| 353 | − - s\_snapshot\_list | |
| 352 | + - __le32 | |
| 353 | + - s_snapshot_list | |
| 354 | 354 | - inode number of the head of the on-disk snapshot list. (Not used in |
| 355 | 355 | e2fsprogs/Linux.) |
| 356 | 356 | * - 0x194 |
| 357 | − - \_\_le32 | |
| 358 | − - s\_error\_count | |
| 357 | + - __le32 | |
| 358 | + - s_error_count | |
| 359 | 359 | - Number of errors seen. |
| 360 | 360 | * - 0x198 |
| 361 | − - \_\_le32 | |
| 362 | − - s\_first\_error\_time | |
| 361 | + - __le32 | |
| 362 | + - s_first_error_time | |
| 363 | 363 | - First time an error happened, in seconds since the epoch. |
| 364 | 364 | * - 0x19C |
| 365 | − - \_\_le32 | |
| 366 | − - s\_first\_error\_ino | |
| 365 | + - __le32 | |
| 366 | + - s_first_error_ino | |
| 367 | 367 | - inode involved in first error. |
| 368 | 368 | * - 0x1A0 |
| 369 | − - \_\_le64 | |
| 370 | − - s\_first\_error\_block | |
| 369 | + - __le64 | |
| 370 | + - s_first_error_block | |
| 371 | 371 | - Number of block involved of first error. |
| 372 | 372 | * - 0x1A8 |
| 373 | − - \_\_u8 | |
| 374 | − - s\_first\_error\_func[32] | |
| 373 | + - __u8 | |
| 374 | + - s_first_error_func[32] | |
| 375 | 375 | - Name of function where the error happened. |
| 376 | 376 | * - 0x1C8 |
| 377 | − - \_\_le32 | |
| 378 | − - s\_first\_error\_line | |
| 377 | + - __le32 | |
| 378 | + - s_first_error_line | |
| 379 | 379 | - Line number where error happened. |
| 380 | 380 | * - 0x1CC |
| 381 | − - \_\_le32 | |
| 382 | − - s\_last\_error\_time | |
| 381 | + - __le32 | |
| 382 | + - s_last_error_time | |
| 383 | 383 | - Time of most recent error, in seconds since the epoch. |
| 384 | 384 | * - 0x1D0 |
| 385 | − - \_\_le32 | |
| 386 | − - s\_last\_error\_ino | |
| 385 | + - __le32 | |
| 386 | + - s_last_error_ino | |
| 387 | 387 | - inode involved in most recent error. |
| 388 | 388 | * - 0x1D4 |
| 389 | − - \_\_le32 | |
| 390 | − - s\_last\_error\_line | |
| 389 | + - __le32 | |
| 390 | + - s_last_error_line | |
| 391 | 391 | - Line number where most recent error happened. |
| 392 | 392 | * - 0x1D8 |
| 393 | − - \_\_le64 | |
| 394 | − - s\_last\_error\_block | |
| 393 | + - __le64 | |
| 394 | + - s_last_error_block | |
| 395 | 395 | - Number of block involved in most recent error. |
| 396 | 396 | * - 0x1E0 |
| 397 | − - \_\_u8 | |
| 398 | − - s\_last\_error\_func[32] | |
| 397 | + - __u8 | |
| 398 | + - s_last_error_func[32] | |
| 399 | 399 | - Name of function where the most recent error happened. |
| 400 | 400 | * - 0x200 |
| 401 | − - \_\_u8 | |
| 402 | − - s\_mount\_opts[64] | |
| 401 | + - __u8 | |
| 402 | + - s_mount_opts[64] | |
| 403 | 403 | - ASCIIZ string of mount options. |
| 404 | 404 | * - 0x240 |
| 405 | − - \_\_le32 | |
| 406 | − - s\_usr\_quota\_inum | |
| 405 | + - __le32 | |
| 406 | + - s_usr_quota_inum | |
| 407 | 407 | - Inode number of user `quota <quota>`__ file. |
| 408 | 408 | * - 0x244 |
| 409 | − - \_\_le32 | |
| 410 | − - s\_grp\_quota\_inum | |
| 409 | + - __le32 | |
| 410 | + - s_grp_quota_inum | |
| 411 | 411 | - Inode number of group `quota <quota>`__ file. |
| 412 | 412 | * - 0x248 |
| 413 | − - \_\_le32 | |
| 414 | − - s\_overhead\_blocks | |
| 413 | + - __le32 | |
| 414 | + - s_overhead_blocks | |
| 415 | 415 | - Overhead blocks/clusters in fs. (Huh? This field is always zero, which |
| 416 | 416 | means that the kernel calculates it dynamically.) |
| 417 | 417 | * - 0x24C |
| 418 | − - \_\_le32 | |
| 419 | − - s\_backup\_bgs[2] | |
| 420 | − - Block groups containing superblock backups (if sparse\_super2) | |
| 418 | + - __le32 | |
| 419 | + - s_backup_bgs[2] | |
| 420 | + - Block groups containing superblock backups (if sparse_super2) | |
| 421 | 421 | * - 0x254 |
| 422 | − - \_\_u8 | |
| 423 | − - s\_encrypt\_algos[4] | |
| 422 | + - __u8 | |
| 423 | + - s_encrypt_algos[4] | |
| 424 | 424 | - Encryption algorithms in use. There can be up to four algorithms in use |
| 425 | 425 | at any time; valid algorithm codes are given in the super_encrypt_ table |
| 426 | 426 | below. |
| 427 | 427 | * - 0x258 |
| 428 | − - \_\_u8 | |
| 429 | − - s\_encrypt\_pw\_salt[16] | |
| 428 | + - __u8 | |
| 429 | + - s_encrypt_pw_salt[16] | |
| 430 | 430 | - Salt for the string2key algorithm for encryption. |
| 431 | 431 | * - 0x268 |
| 432 | − - \_\_le32 | |
| 433 | − - s\_lpf\_ino | |
| 432 | + - __le32 | |
| 433 | + - s_lpf_ino | |
| 434 | 434 | - Inode number of lost+found |
| 435 | 435 | * - 0x26C |
| 436 | − - \_\_le32 | |
| 437 | − - s\_prj\_quota\_inum | |
| 436 | + - __le32 | |
| 437 | + - s_prj_quota_inum | |
| 438 | 438 | - Inode that tracks project quotas. |
| 439 | 439 | * - 0x270 |
| 440 | − - \_\_le32 | |
| 441 | − - s\_checksum\_seed | |
| 442 | − - Checksum seed used for metadata\_csum calculations. This value is | |
| 443 | − crc32c(~0, $orig\_fs\_uuid). | |
| 440 | + - __le32 | |
| 441 | + - s_checksum_seed | |
| 442 | + - Checksum seed used for metadata_csum calculations. This value is | |
| 443 | + crc32c(~0, $orig_fs_uuid). | |
| 444 | 444 | * - 0x274 |
| 445 | − - \_\_u8 | |
| 446 | − - s\_wtime_hi | |
| 445 | + - __u8 | |
| 446 | + - s_wtime_hi | |
| 447 | 447 | - Upper 8 bits of the s_wtime field. |
| 448 | 448 | * - 0x275 |
| 449 | − - \_\_u8 | |
| 450 | − - s\_mtime_hi | |
| 449 | + - __u8 | |
| 450 | + - s_mtime_hi | |
| 451 | 451 | - Upper 8 bits of the s_mtime field. |
| 452 | 452 | * - 0x276 |
| 453 | − - \_\_u8 | |
| 454 | − - s\_mkfs_time_hi | |
| 453 | + - __u8 | |
| 454 | + - s_mkfs_time_hi | |
| 455 | 455 | - Upper 8 bits of the s_mkfs_time field. |
| 456 | 456 | * - 0x277 |
| 457 | − - \_\_u8 | |
| 458 | − - s\_lastcheck_hi | |
| 457 | + - __u8 | |
| 458 | + - s_lastcheck_hi | |
| 459 | 459 | - Upper 8 bits of the s_lastcheck_hi field. |
| 460 | 460 | * - 0x278 |
| 461 | − - \_\_u8 | |
| 462 | − - s\_first_error_time_hi | |
| 461 | + - __u8 | |
| 462 | + - s_first_error_time_hi | |
| 463 | 463 | - Upper 8 bits of the s_first_error_time_hi field. |
| 464 | 464 | * - 0x279 |
| 465 | − - \_\_u8 | |
| 466 | − - s\_last_error_time_hi | |
| 465 | + - __u8 | |
| 466 | + - s_last_error_time_hi | |
| 467 | 467 | - Upper 8 bits of the s_last_error_time_hi field. |
| 468 | 468 | * - 0x27A |
| 469 | − - \_\_u8 | |
| 470 | − - s\_pad[2] | |
| 469 | + - __u8 | |
| 470 | + - s_pad[2] | |
| 471 | 471 | - Zero padding. |
| 472 | 472 | * - 0x27C |
| 473 | − - \_\_le16 | |
| 474 | − - s\_encoding | |
| 473 | + - __le16 | |
| 474 | + - s_encoding | |
| 475 | 475 | - Filename charset encoding. |
| 476 | 476 | * - 0x27E |
| 477 | − - \_\_le16 | |
| 478 | − - s\_encoding_flags | |
| 477 | + - __le16 | |
| 478 | + - s_encoding_flags | |
| 479 | 479 | - Filename charset encoding flags. |
| 480 | 480 | * - 0x280 |
| 481 | − - \_\_le32 | |
| 482 | − - s\_orphan\_file\_inum | |
| 481 | + - __le32 | |
| 482 | + - s_orphan_file_inum | |
| 483 | 483 | - Orphan file inode number. |
| 484 | 484 | * - 0x284 |
| 485 | − - \_\_le32 | |
| 486 | − - s\_reserved[94] | |
| 485 | + - __le32 | |
| 486 | + - s_reserved[94] | |
| 487 | 487 | - Padding to the end of the block. |
| 488 | 488 | * - 0x3FC |
| 489 | − - \_\_le32 | |
| 490 | − - s\_checksum | |
| 489 | + - __le32 | |
| 490 | + - s_checksum | |
| 491 | 491 | - Superblock checksum. |
| 492 | 492 | |
| 493 | 493 | .. _super_state: |
| @@ -574,44 +574,44 @@ following: · 80 unmodified lines | ||
| 574 | 574 | * - Value |
| 575 | 575 | - Description |
| 576 | 576 | * - 0x1 |
| 577 | − - Directory preallocation (COMPAT\_DIR\_PREALLOC). | |
| 577 | + - Directory preallocation (COMPAT_DIR_PREALLOC). | |
| 578 | 578 | * - 0x2 |
| 579 | 579 | - “imagic inodes”. Not clear from the code what this does |
| 580 | − (COMPAT\_IMAGIC\_INODES). | |
| 580 | + (COMPAT_IMAGIC_INODES). | |
| 581 | 581 | * - 0x4 |
| 582 | − - Has a journal (COMPAT\_HAS\_JOURNAL). | |
| 582 | + - Has a journal (COMPAT_HAS_JOURNAL). | |
| 583 | 583 | * - 0x8 |
| 584 | − - Supports extended attributes (COMPAT\_EXT\_ATTR). | |
| 584 | + - Supports extended attributes (COMPAT_EXT_ATTR). | |
| 585 | 585 | * - 0x10 |
| 586 | 586 | - Has reserved GDT blocks for filesystem expansion |
| 587 | − (COMPAT\_RESIZE\_INODE). Requires RO\_COMPAT\_SPARSE\_SUPER. | |
| 587 | + (COMPAT_RESIZE_INODE). Requires RO_COMPAT_SPARSE_SUPER. | |
| 588 | 588 | * - 0x20 |
| 589 | − - Has directory indices (COMPAT\_DIR\_INDEX). | |
| 589 | + - Has directory indices (COMPAT_DIR_INDEX). | |
| 590 | 590 | * - 0x40 |
| 591 | 591 | - “Lazy BG”. Not in Linux kernel, seems to have been for uninitialized |
| 592 | − block groups? (COMPAT\_LAZY\_BG) | |
| 592 | + block groups? (COMPAT_LAZY_BG) | |
| 593 | 593 | * - 0x80 |
| 594 | − - “Exclude inode”. Not used. (COMPAT\_EXCLUDE\_INODE). | |
| 594 | + - “Exclude inode”. Not used. (COMPAT_EXCLUDE_INODE). | |
| 595 | 595 | * - 0x100 |
| 596 | 596 | - “Exclude bitmap”. Seems to be used to indicate the presence of |
| 597 | 597 | snapshot-related exclude bitmaps? Not defined in kernel or used in |
| 598 | − e2fsprogs (COMPAT\_EXCLUDE\_BITMAP). | |
| 598 | + e2fsprogs (COMPAT_EXCLUDE_BITMAP). | |
| 599 | 599 | * - 0x200 |
| 600 | − - Sparse Super Block, v2. If this flag is set, the SB field s\_backup\_bgs | |
| 600 | + - Sparse Super Block, v2. If this flag is set, the SB field s_backup_bgs | |
| 601 | 601 | points to the two block groups that contain backup superblocks |
| 602 | − (COMPAT\_SPARSE\_SUPER2). | |
| 602 | + (COMPAT_SPARSE_SUPER2). | |
| 603 | 603 | * - 0x400 |
| 604 | 604 | - Fast commits supported. Although fast commits blocks are |
| 605 | 605 | backward incompatible, fast commit blocks are not always |
| 606 | 606 | present in the journal. If fast commit blocks are present in |
| 607 | 607 | the journal, JBD2 incompat feature |
| 608 | − (JBD2\_FEATURE\_INCOMPAT\_FAST\_COMMIT) gets | |
| 609 | − set (COMPAT\_FAST\_COMMIT). | |
| 608 | + (JBD2_FEATURE_INCOMPAT_FAST_COMMIT) gets | |
| 609 | + set (COMPAT_FAST_COMMIT). | |
| 610 | 610 | * - 0x1000 |
| 611 | 611 | - Orphan file allocated. This is the special file for more efficient |
| 612 | 612 | tracking of unlinked but still open inodes. When there may be any |
| 613 | 613 | entries in the file, we additionally set proper rocompat feature |
| 614 | − (RO\_COMPAT\_ORPHAN\_PRESENT). | |
| 614 | + (RO_COMPAT_ORPHAN_PRESENT). | |
| 615 | 615 | |
| 616 | 616 | .. _super_incompat: |
| 617 | 617 | |
| @@ -625,45 +625,45 @@ following: · 7 unmodified lines | ||
| 625 | 625 | * - Value |
| 626 | 626 | - Description |
| 627 | 627 | * - 0x1 |
| 628 | − - Compression (INCOMPAT\_COMPRESSION). | |
| 628 | + - Compression (INCOMPAT_COMPRESSION). | |
| 629 | 629 | * - 0x2 |
| 630 | − - Directory entries record the file type. See ext4\_dir\_entry\_2 below | |
| 631 | − (INCOMPAT\_FILETYPE). | |
| 630 | + - Directory entries record the file type. See ext4_dir_entry_2 below | |
| 631 | + (INCOMPAT_FILETYPE). | |
| 632 | 632 | * - 0x4 |
| 633 | − - Filesystem needs recovery (INCOMPAT\_RECOVER). | |
| 633 | + - Filesystem needs recovery (INCOMPAT_RECOVER). | |
| 634 | 634 | * - 0x8 |
| 635 | − - Filesystem has a separate journal device (INCOMPAT\_JOURNAL\_DEV). | |
| 635 | + - Filesystem has a separate journal device (INCOMPAT_JOURNAL_DEV). | |
| 636 | 636 | * - 0x10 |
| 637 | 637 | - Meta block groups. See the earlier discussion of this feature |
| 638 | − (INCOMPAT\_META\_BG). | |
| 638 | + (INCOMPAT_META_BG). | |
| 639 | 639 | * - 0x40 |
| 640 | − - Files in this filesystem use extents (INCOMPAT\_EXTENTS). | |
| 640 | + - Files in this filesystem use extents (INCOMPAT_EXTENTS). | |
| 641 | 641 | * - 0x80 |
| 642 | − - Enable a filesystem size of 2^64 blocks (INCOMPAT\_64BIT). | |
| 642 | + - Enable a filesystem size of 2^64 blocks (INCOMPAT_64BIT). | |
| 643 | 643 | * - 0x100 |
| 644 | − - Multiple mount protection (INCOMPAT\_MMP). | |
| 644 | + - Multiple mount protection (INCOMPAT_MMP). | |
| 645 | 645 | * - 0x200 |
| 646 | 646 | - Flexible block groups. See the earlier discussion of this feature |
| 647 | − (INCOMPAT\_FLEX\_BG). | |
| 647 | + (INCOMPAT_FLEX_BG). | |
| 648 | 648 | * - 0x400 |
| 649 | 649 | - Inodes can be used to store large extended attribute values |
| 650 | − (INCOMPAT\_EA\_INODE). | |
| 650 | + (INCOMPAT_EA_INODE). | |
| 651 | 651 | * - 0x1000 |
| 652 | − - Data in directory entry (INCOMPAT\_DIRDATA). (Not implemented?) | |
| 652 | + - Data in directory entry (INCOMPAT_DIRDATA). (Not implemented?) | |
| 653 | 653 | * - 0x2000 |
| 654 | 654 | - Metadata checksum seed is stored in the superblock. This feature enables |
| 655 | − the administrator to change the UUID of a metadata\_csum filesystem | |
| 655 | + the administrator to change the UUID of a metadata_csum filesystem | |
| 656 | 656 | while the filesystem is mounted; without it, the checksum definition |
| 657 | − requires all metadata blocks to be rewritten (INCOMPAT\_CSUM\_SEED). | |
| 657 | + requires all metadata blocks to be rewritten (INCOMPAT_CSUM_SEED). | |
| 658 | 658 | * - 0x4000 |
| 659 | − - Large directory >2GB or 3-level htree (INCOMPAT\_LARGEDIR). Prior to | |
| 659 | + - Large directory >2GB or 3-level htree (INCOMPAT_LARGEDIR). Prior to | |
| 660 | 660 | this feature, directories could not be larger than 4GiB and could not |
| 661 | 661 | have an htree more than 2 levels deep. If this feature is enabled, |
| 662 | 662 | directories can be larger than 4GiB and have a maximum htree depth of 3. |
| 663 | 663 | * - 0x8000 |
| 664 | − - Data in inode (INCOMPAT\_INLINE\_DATA). | |
| 664 | + - Data in inode (INCOMPAT_INLINE_DATA). | |
| 665 | 665 | * - 0x10000 |
| 666 | − - Encrypted inodes are present on the filesystem. (INCOMPAT\_ENCRYPT). | |
| 666 | + - Encrypted inodes are present on the filesystem. (INCOMPAT_ENCRYPT). | |
| 667 | 667 | |
| 668 | 668 | .. _super_rocompat: |
| 669 | 669 | |
| @@ -678,54 +678,54 @@ the following: · 8 unmodified lines | ||
| 678 | 678 | - Description |
| 679 | 679 | * - 0x1 |
| 680 | 680 | - Sparse superblocks. See the earlier discussion of this feature |
| 681 | − (RO\_COMPAT\_SPARSE\_SUPER). | |
| 681 | + (RO_COMPAT_SPARSE_SUPER). | |
| 682 | 682 | * - 0x2 |
| 683 | 683 | - This filesystem has been used to store a file greater than 2GiB |
| 684 | − (RO\_COMPAT\_LARGE\_FILE). | |
| 684 | + (RO_COMPAT_LARGE_FILE). | |
| 685 | 685 | * - 0x4 |
| 686 | − - Not used in kernel or e2fsprogs (RO\_COMPAT\_BTREE\_DIR). | |
| 686 | + - Not used in kernel or e2fsprogs (RO_COMPAT_BTREE_DIR). | |
| 687 | 687 | * - 0x8 |
| 688 | 688 | - This filesystem has files whose sizes are represented in units of |
| 689 | 689 | logical blocks, not 512-byte sectors. This implies a very large file |
| 690 | − indeed! (RO\_COMPAT\_HUGE\_FILE) | |
| 690 | + indeed! (RO_COMPAT_HUGE_FILE) | |
| 691 | 691 | * - 0x10 |
| 692 | 692 | - Group descriptors have checksums. In addition to detecting corruption, |
| 693 | 693 | this is useful for lazy formatting with uninitialized groups |
| 694 | − (RO\_COMPAT\_GDT\_CSUM). | |
| 694 | + (RO_COMPAT_GDT_CSUM). | |
| 695 | 695 | * - 0x20 |
| 696 | 696 | - Indicates that the old ext3 32,000 subdirectory limit no longer applies |
| 697 | − (RO\_COMPAT\_DIR\_NLINK). A directory's i\_links\_count will be set to 1 | |
| 697 | + (RO_COMPAT_DIR_NLINK). A directory's i_links_count will be set to 1 | |
| 698 | 698 | if it is incremented past 64,999. |
| 699 | 699 | * - 0x40 |
| 700 | 700 | - Indicates that large inodes exist on this filesystem |
| 701 | − (RO\_COMPAT\_EXTRA\_ISIZE). | |
| 701 | + (RO_COMPAT_EXTRA_ISIZE). | |
| 702 | 702 | * - 0x80 |
| 703 | − - This filesystem has a snapshot (RO\_COMPAT\_HAS\_SNAPSHOT). | |
| 703 | + - This filesystem has a snapshot (RO_COMPAT_HAS_SNAPSHOT). | |
| 704 | 704 | * - 0x100 |
| 705 | − - `Quota <Quota>`__ (RO\_COMPAT\_QUOTA). | |
| 705 | + - `Quota <Quota>`__ (RO_COMPAT_QUOTA). | |
| 706 | 706 | * - 0x200 |
| 707 | 707 | - This filesystem supports “bigalloc”, which means that file extents are |
| 708 | 708 | tracked in units of clusters (of blocks) instead of blocks |
| 709 | − (RO\_COMPAT\_BIGALLOC). | |
| 709 | + (RO_COMPAT_BIGALLOC). | |
| 710 | 710 | * - 0x400 |
| 711 | 711 | - This filesystem supports metadata checksumming. |
| 712 | − (RO\_COMPAT\_METADATA\_CSUM; implies RO\_COMPAT\_GDT\_CSUM, though | |
| 713 | − GDT\_CSUM must not be set) | |
| 712 | + (RO_COMPAT_METADATA_CSUM; implies RO_COMPAT_GDT_CSUM, though | |
| 713 | + GDT_CSUM must not be set) | |
| 714 | 714 | * - 0x800 |
| 715 | 715 | - Filesystem supports replicas. This feature is neither in the kernel nor |
| 716 | − e2fsprogs. (RO\_COMPAT\_REPLICA) | |
| 716 | + e2fsprogs. (RO_COMPAT_REPLICA) | |
| 717 | 717 | * - 0x1000 |
| 718 | 718 | - Read-only filesystem image; the kernel will not mount this image |
| 719 | 719 | read-write and most tools will refuse to write to the image. |
| 720 | − (RO\_COMPAT\_READONLY) | |
| 720 | + (RO_COMPAT_READONLY) | |
| 721 | 721 | * - 0x2000 |
| 722 | − - Filesystem tracks project quotas. (RO\_COMPAT\_PROJECT) | |
| 722 | + - Filesystem tracks project quotas. (RO_COMPAT_PROJECT) | |
| 723 | 723 | * - 0x8000 |
| 724 | − - Verity inodes may be present on the filesystem. (RO\_COMPAT\_VERITY) | |
| 724 | + - Verity inodes may be present on the filesystem. (RO_COMPAT_VERITY) | |
| 725 | 725 | * - 0x10000 |
| 726 | 726 | - Indicates orphan file may have valid orphan entries and thus we need |
| 727 | 727 | to clean them up when mounting the filesystem |
| 728 | − (RO\_COMPAT\_ORPHAN\_PRESENT). | |
| 728 | + (RO_COMPAT_ORPHAN_PRESENT). | |
| 729 | 729 | |
| 730 | 730 | .. _super_def_hash: |
| 731 | 731 | |
| @@ -761,36 +761,36 @@ The ``s_default_mount_opts`` field is any combination of the following: · 29 unmodified lines | ||
| 761 | 761 | * - Value |
| 762 | 762 | - Description |
| 763 | 763 | * - 0x0001 |
| 764 | − - Print debugging info upon (re)mount. (EXT4\_DEFM\_DEBUG) | |
| 764 | + - Print debugging info upon (re)mount. (EXT4_DEFM_DEBUG) | |
| 765 | 765 | * - 0x0002 |
| 766 | 766 | - New files take the gid of the containing directory (instead of the fsgid |
| 767 | − of the current process). (EXT4\_DEFM\_BSDGROUPS) | |
| 767 | + of the current process). (EXT4_DEFM_BSDGROUPS) | |
| 768 | 768 | * - 0x0004 |
| 769 | − - Support userspace-provided extended attributes. (EXT4\_DEFM\_XATTR\_USER) | |
| 769 | + - Support userspace-provided extended attributes. (EXT4_DEFM_XATTR_USER) | |
| 770 | 770 | * - 0x0008 |
| 771 | − - Support POSIX access control lists (ACLs). (EXT4\_DEFM\_ACL) | |
| 771 | + - Support POSIX access control lists (ACLs). (EXT4_DEFM_ACL) | |
| 772 | 772 | * - 0x0010 |
| 773 | − - Do not support 32-bit UIDs. (EXT4\_DEFM\_UID16) | |
| 773 | + - Do not support 32-bit UIDs. (EXT4_DEFM_UID16) | |
| 774 | 774 | * - 0x0020 |
| 775 | 775 | - All data and metadata are commited to the journal. |
| 776 | − (EXT4\_DEFM\_JMODE\_DATA) | |
| 776 | + (EXT4_DEFM_JMODE_DATA) | |
| 777 | 777 | * - 0x0040 |
| 778 | 778 | - All data are flushed to the disk before metadata are committed to the |
| 779 | − journal. (EXT4\_DEFM\_JMODE\_ORDERED) | |
| 779 | + journal. (EXT4_DEFM_JMODE_ORDERED) | |
| 780 | 780 | * - 0x0060 |
| 781 | 781 | - Data ordering is not preserved; data may be written after the metadata |
| 782 | − has been written. (EXT4\_DEFM\_JMODE\_WBACK) | |
| 782 | + has been written. (EXT4_DEFM_JMODE_WBACK) | |
| 783 | 783 | * - 0x0100 |
| 784 | − - Disable write flushes. (EXT4\_DEFM\_NOBARRIER) | |
| 784 | + - Disable write flushes. (EXT4_DEFM_NOBARRIER) | |
| 785 | 785 | * - 0x0200 |
| 786 | 786 | - Track which blocks in a filesystem are metadata and therefore should not |
| 787 | 787 | be used as data blocks. This option will be enabled by default on 3.18, |
| 788 | − hopefully. (EXT4\_DEFM\_BLOCK\_VALIDITY) | |
| 788 | + hopefully. (EXT4_DEFM_BLOCK_VALIDITY) | |
| 789 | 789 | * - 0x0400 |
| 790 | 790 | - Enable DISCARD support, where the storage device is told about blocks |
| 791 | − becoming unused. (EXT4\_DEFM\_DISCARD) | |
| 791 | + becoming unused. (EXT4_DEFM_DISCARD) | |
| 792 | 792 | * - 0x0800 |
| 793 | − - Disable delayed allocation. (EXT4\_DEFM\_NODELALLOC) | |
| 793 | + - Disable delayed allocation. (EXT4_DEFM_NODELALLOC) | |
| 794 | 794 | |
| 795 | 795 | .. _super_flags: |
| 796 | 796 | |
| @@ -820,12 +820,12 @@ The ``s_encrypt_algos`` list can contain any of the following: · 23 unmodified lines | ||
| 820 | 820 | * - Value |
| 821 | 821 | - Description |
| 822 | 822 | * - 0 |
| 823 | − - Invalid algorithm (ENCRYPTION\_MODE\_INVALID). | |
| 823 | + - Invalid algorithm (ENCRYPTION_MODE_INVALID). | |
| 824 | 824 | * - 1 |
| 825 | − - 256-bit AES in XTS mode (ENCRYPTION\_MODE\_AES\_256\_XTS). | |
| 825 | + - 256-bit AES in XTS mode (ENCRYPTION_MODE_AES_256_XTS). | |
| 826 | 826 | * - 2 |
| 827 | − - 256-bit AES in GCM mode (ENCRYPTION\_MODE\_AES\_256\_GCM). | |
| 827 | + - 256-bit AES in GCM mode (ENCRYPTION_MODE_AES_256_GCM). | |
| 828 | 828 | * - 3 |
| 829 | − - 256-bit AES in CBC mode (ENCRYPTION\_MODE\_AES\_256\_CBC). | |
| 829 | + - 256-bit AES in CBC mode (ENCRYPTION_MODE_AES_256_CBC). | |
| 830 | 830 | |
| 831 | 831 | Total size of the superblock is 1024 bytes. |
| @@ -129,18 +129,24 @@ yet. Bug reports are always welcome at the issue tracker below! · 128 unmodified lines | ||
| 129 | 129 | * - arm64 |
| 130 | 130 | - Supported |
| 131 | 131 | - ``LLVM=1`` |
| 132 | + * - hexagon | |
| 133 | + - Maintained | |
| 134 | + - ``LLVM=1`` | |
| 132 | 135 | * - mips |
| 133 | 136 | - Maintained |
| 134 | − - ``CC=clang`` | |
| 137 | + - ``LLVM=1`` | |
| 135 | 138 | * - powerpc |
| 136 | 139 | - Maintained |
| 137 | 140 | - ``CC=clang`` |
| 138 | 141 | * - riscv |
| 139 | 142 | - Maintained |
| 140 | − - ``CC=clang`` | |
| 143 | + - ``LLVM=1`` | |
| 141 | 144 | * - s390 |
| 142 | 145 | - Maintained |
| 143 | 146 | - ``CC=clang`` |
| 147 | + * - um (User Mode) | |
| 148 | + - Maintained | |
| 149 | + - ``LLVM=1`` | |
| 144 | 150 | * - x86 |
| 145 | 151 | - Supported |
| 146 | 152 | - ``LLVM=1`` |
| @@ -45,10 +45,12 @@ Name Alias Usage Preserved · 44 unmodified lines | ||
| 45 | 45 | ``$r23``-``$r31`` ``$s0``-``$s8`` Static registers Yes |
| 46 | 46 | ================= =============== =================== ============ |
| 47 | 47 | |
| 48 | −Note: The register ``$r21`` is reserved in the ELF psABI, but used by the Linux | |
| 49 | −kernel for storing the percpu base address. It normally has no ABI name, but is | |
| 50 | −called ``$u0`` in the kernel. You may also see ``$v0`` or ``$v1`` in some old code, | |
| 51 | −however they are deprecated aliases of ``$a0`` and ``$a1`` respectively. | |
| 48 | +.. Note:: | |
| 49 | + The register ``$r21`` is reserved in the ELF psABI, but used by the Linux | |
| 50 | + kernel for storing the percpu base address. It normally has no ABI name, | |
| 51 | + but is called ``$u0`` in the kernel. You may also see ``$v0`` or ``$v1`` | |
| 52 | + in some old code,however they are deprecated aliases of ``$a0`` and ``$a1`` | |
| 53 | + respectively. | |
| 52 | 54 | |
| 53 | 55 | FPRs |
| 54 | 56 | ---- |
| @@ -69,8 +71,9 @@ Name Alias Usage Preserved · 14 unmodified lines | ||
| 69 | 71 | ``$f24``-``$f31`` ``$fs0``-``$fs7`` Static registers Yes |
| 70 | 72 | ================= ================== =================== ============ |
| 71 | 73 | |
| 72 | −Note: You may see ``$fv0`` or ``$fv1`` in some old code, however they are deprecated | |
| 73 | −aliases of ``$fa0`` and ``$fa1`` respectively. | |
| 74 | +.. Note:: | |
| 75 | + You may see ``$fv0`` or ``$fv1`` in some old code, however they are | |
| 76 | + deprecated aliases of ``$fa0`` and ``$fa1`` respectively. | |
| 74 | 77 | |
| 75 | 78 | VRs |
| 76 | 79 | ---- |
| @@ -145,12 +145,16 @@ Documentation of Loongson's LS7A chipset: · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (in English) |
| 147 | 147 | |
| 148 | −Note: CPUINTC is CSR.ECFG/CSR.ESTAT and its interrupt controller described | |
| 149 | −in Section 7.4 of "LoongArch Reference Manual, Vol 1"; LIOINTC is "Legacy I/O | |
| 150 | −Interrupts" described in Section 11.1 of "Loongson 3A5000 Processor Reference | |
| 151 | −Manual"; EIOINTC is "Extended I/O Interrupts" described in Section 11.2 of | |
| 152 | −"Loongson 3A5000 Processor Reference Manual"; HTVECINTC is "HyperTransport | |
| 153 | −Interrupts" described in Section 14.3 of "Loongson 3A5000 Processor Reference | |
| 154 | −Manual"; PCH-PIC/PCH-MSI is "Interrupt Controller" described in Section 5 of | |
| 155 | −"Loongson 7A1000 Bridge User Manual"; PCH-LPC is "LPC Interrupts" described in | |
| 156 | −Section 24.3 of "Loongson 7A1000 Bridge User Manual". | |
| 148 | +.. Note:: | |
| 149 | + - CPUINTC is CSR.ECFG/CSR.ESTAT and its interrupt controller described | |
| 150 | + in Section 7.4 of "LoongArch Reference Manual, Vol 1"; | |
| 151 | + - LIOINTC is "Legacy I/OInterrupts" described in Section 11.1 of | |
| 152 | + "Loongson 3A5000 Processor Reference Manual"; | |
| 153 | + - EIOINTC is "Extended I/O Interrupts" described in Section 11.2 of | |
| 154 | + "Loongson 3A5000 Processor Reference Manual"; | |
| 155 | + - HTVECINTC is "HyperTransport Interrupts" described in Section 14.3 of | |
| 156 | + "Loongson 3A5000 Processor Reference Manual"; | |
| 157 | + - PCH-PIC/PCH-MSI is "Interrupt Controller" described in Section 5 of | |
| 158 | + "Loongson 7A1000 Bridge User Manual"; | |
| 159 | + - PCH-LPC is "LPC Interrupts" described in Section 24.3 of | |
| 160 | + "Loongson 7A1000 Bridge User Manual". | |
| @@ -2925,6 +2925,43 @@ plpmtud_probe_interval - INTEGER · 2924 unmodified lines | ||
| 2925 | 2925 | |
| 2926 | 2926 | Default: 0 |
| 2927 | 2927 | |
| 2928 | +reconf_enable - BOOLEAN | |
| 2929 | + Enable or disable extension of Stream Reconfiguration functionality | |
| 2930 | + specified in RFC6525. This extension provides the ability to "reset" | |
| 2931 | + a stream, and it includes the Parameters of "Outgoing/Incoming SSN | |
| 2932 | + Reset", "SSN/TSN Reset" and "Add Outgoing/Incoming Streams". | |
| 2933 | + | |
| 2934 | + - 1: Enable extension. | |
| 2935 | + - 0: Disable extension. | |
| 2936 | + | |
| 2937 | + Default: 0 | |
| 2938 | + | |
| 2939 | +intl_enable - BOOLEAN | |
| 2940 | + Enable or disable extension of User Message Interleaving functionality | |
| 2941 | + specified in RFC8260. This extension allows the interleaving of user | |
| 2942 | + messages sent on different streams. With this feature enabled, I-DATA | |
| 2943 | + chunk will replace DATA chunk to carry user messages if also supported | |
| 2944 | + by the peer. Note that to use this feature, one needs to set this option | |
| 2945 | + to 1 and also needs to set socket options SCTP_FRAGMENT_INTERLEAVE to 2 | |
| 2946 | + and SCTP_INTERLEAVING_SUPPORTED to 1. | |
| 2947 | + | |
| 2948 | + - 1: Enable extension. | |
| 2949 | + - 0: Disable extension. | |
| 2950 | + | |
| 2951 | + Default: 0 | |
| 2952 | + | |
| 2953 | +ecn_enable - BOOLEAN | |
| 2954 | + Control use of Explicit Congestion Notification (ECN) by SCTP. | |
| 2955 | + Like in TCP, ECN is used only when both ends of the SCTP connection | |
| 2956 | + indicate support for it. This feature is useful in avoiding losses | |
| 2957 | + due to congestion by allowing supporting routers to signal congestion | |
| 2958 | + before having to drop packets. | |
| 2959 | + | |
| 2960 | + 1: Enable ecn. | |
| 2961 | + 0: Disable ecn. | |
| 2962 | + | |
| 2963 | + Default: 1 | |
| 2964 | + | |
| 2928 | 2965 | |
| 2929 | 2966 | ``/proc/sys/net/core/*`` |
| 2930 | 2967 | ======================== |
| @@ -104,7 +104,7 @@ Whenever possible, use the PHY side RGMII delay for these reasons: · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | * PHY device drivers in PHYLIB being reusable by nature, being able to |
| 106 | 106 | configure correctly a specified delay enables more designs with similar delay |
| 107 | − requirements to be operate correctly | |
| 107 | + requirements to be operated correctly | |
| 108 | 108 | |
| 109 | 109 | For cases where the PHY is not capable of providing this delay, but the |
| 110 | 110 | Ethernet MAC driver is capable of doing so, the correct phy_interface_t value |
| @@ -46,10 +46,11 @@ LA64中每个寄存器为64位宽。 ``$r0`` 的内容总是固定为0,而其 · 45 unmodified lines | ||
| 46 | 46 | ``$r23``-``$r31`` ``$s0``-``$s8`` 静态寄存器 是 |
| 47 | 47 | ================= =============== =================== ========== |
| 48 | 48 | |
| 49 | −注意:``$r21``寄存器在ELF psABI中保留未使用,但是在Linux内核用于保存每CPU | |
| 50 | −变量基地址。该寄存器没有ABI命名,不过在内核中称为``$u0``。在一些遗留代码 | |
| 51 | −中有时可能见到``$v0``和``$v1``,它们是``$a0``和``$a1``的别名,属于已经废弃 | |
| 52 | −的用法。 | |
| 49 | +.. note:: | |
| 50 | + 注意: ``$r21`` 寄存器在ELF psABI中保留未使用,但是在Linux内核用于保 | |
| 51 | + 存每CPU变量基地址。该寄存器没有ABI命名,不过在内核中称为 ``$u0`` 。在 | |
| 52 | + 一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 ``$a0`` 和 | |
| 53 | + ``$a1`` 的别名,属于已经废弃的用法。 | |
| 53 | 54 | |
| 54 | 55 | 浮点寄存器 |
| 55 | 56 | ---------- |
| @@ -68,8 +69,9 @@ LA64中每个寄存器为64位宽。 ``$r0`` 的内容总是固定为0,而其 · 12 unmodified lines | ||
| 68 | 69 | ``$f24``-``$f31`` ``$fs0``-``$fs7`` 静态寄存器 是 |
| 69 | 70 | ================= ================== =================== ========== |
| 70 | 71 | |
| 71 | −注意:在一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 ``$a0`` | |
| 72 | −和 ``$a1`` 的别名,属于已经废弃的用法。 | |
| 72 | +.. note:: | |
| 73 | + 注意:在一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 | |
| 74 | + ``$a0`` 和 ``$a1`` 的别名,属于已经废弃的用法。 | |
| 73 | 75 | |
| 74 | 76 | |
| 75 | 77 | 向量寄存器 |
| @@ -147,9 +147,11 @@ PCH-LPC:: · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (英文版) |
| 149 | 149 | |
| 150 | −注:CPUINTC即《龙芯架构参考手册卷一》第7.4节所描述的CSR.ECFG/CSR.ESTAT寄存器及其中断 | |
| 151 | −控制逻辑;LIOINTC即《龙芯3A5000处理器使用手册》第11.1节所描述的“传统I/O中断”;EIOINTC | |
| 152 | −即《龙芯3A5000处理器使用手册》第11.2节所描述的“扩展I/O中断”;HTVECINTC即《龙芯3A5000 | |
| 153 | −处理器使用手册》第14.3节所描述的“HyperTransport中断”;PCH-PIC/PCH-MSI即《龙芯7A1000桥 | |
| 154 | −片用户手册》第5章所描述的“中断控制器”;PCH-LPC即《龙芯7A1000桥片用户手册》第24.3节所 | |
| 155 | −描述的“LPC中断”。 | |
| 150 | +.. note:: | |
| 151 | + - CPUINTC:即《龙芯架构参考手册卷一》第7.4节所描述的CSR.ECFG/CSR.ESTAT寄存器及其 | |
| 152 | + 中断控制逻辑; | |
| 153 | + - LIOINTC:即《龙芯3A5000处理器使用手册》第11.1节所描述的“传统I/O中断”; | |
| 154 | + - EIOINTC:即《龙芯3A5000处理器使用手册》第11.2节所描述的“扩展I/O中断”; | |
| 155 | + - HTVECINTC:即《龙芯3A5000处理器使用手册》第14.3节所描述的“HyperTransport中断”; | |
| 156 | + - PCH-PIC/PCH-MSI:即《龙芯7A1000桥片用户手册》第5章所描述的“中断控制器”; | |
| 157 | + - PCH-LPC:即《龙芯7A1000桥片用户手册》第24.3节所描述的“LPC中断”。 | |
| @@ -120,7 +120,8 @@ Testing · 119 unmodified lines | ||
| 120 | 120 | unpoison-pfn |
| 121 | 121 | Software-unpoison page at PFN echoed into this file. This way |
| 122 | 122 | a page can be reused again. This only works for Linux |
| 123 | − injected failures, not for real memory failures. | |
| 123 | + injected failures, not for real memory failures. Once any hardware | |
| 124 | + memory failure happens, this feature is disabled. | |
| 124 | 125 | |
| 125 | 126 | Note these injection interfaces are not stable and might change between |
| 126 | 127 | kernel versions |
| @@ -427,6 +427,7 @@ ACPI VIOT DRIVER · 426 unmodified lines | ||
| 427 | 427 | M: Jean-Philippe Brucker <jean-philippe@linaro.org> |
| 428 | 428 | L: linux-acpi@vger.kernel.org |
| 429 | 429 | L: iommu@lists.linux-foundation.org |
| 430 | +L: iommu@lists.linux.dev | |
| 430 | 431 | S: Maintained |
| 431 | 432 | F: drivers/acpi/viot.c |
| 432 | 433 | F: include/linux/acpi_viot.h |
| @@ -960,6 +961,7 @@ AMD IOMMU (AMD-VI) · 527 unmodified lines | ||
| 960 | 961 | M: Joerg Roedel <joro@8bytes.org> |
| 961 | 962 | R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> |
| 962 | 963 | L: iommu@lists.linux-foundation.org |
| 964 | +L: iommu@lists.linux.dev | |
| 963 | 965 | S: Maintained |
| 964 | 966 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 965 | 967 | F: drivers/iommu/amd/ |
| @@ -2467,6 +2469,7 @@ ARM/NXP S32G ARCHITECTURE · 1501 unmodified lines | ||
| 2467 | 2469 | M: Chester Lin <clin@suse.com> |
| 2468 | 2470 | R: Andreas Färber <afaerber@suse.de> |
| 2469 | 2471 | R: Matthias Brugger <mbrugger@suse.com> |
| 2472 | +R: NXP S32 Linux Team <s32@nxp.com> | |
| 2470 | 2473 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2471 | 2474 | S: Maintained |
| 2472 | 2475 | F: arch/arm64/boot/dts/freescale/s32g*.dts* |
| @@ -3662,7 +3665,7 @@ BPF JIT for ARM · 1189 unmodified lines | ||
| 3662 | 3665 | M: Shubham Bansal <illusionist.neo@gmail.com> |
| 3663 | 3666 | L: netdev@vger.kernel.org |
| 3664 | 3667 | L: bpf@vger.kernel.org |
| 3665 | −S: Maintained | |
| 3668 | +S: Odd Fixes | |
| 3666 | 3669 | F: arch/arm/net/ |
| 3667 | 3670 | |
| 3668 | 3671 | BPF JIT for ARM64 |
| @@ -3686,14 +3689,15 @@ BPF JIT for NFP NICs · 17 unmodified lines | ||
| 3686 | 3689 | M: Jakub Kicinski <kuba@kernel.org> |
| 3687 | 3690 | L: netdev@vger.kernel.org |
| 3688 | 3691 | L: bpf@vger.kernel.org |
| 3689 | −S: Supported | |
| 3692 | +S: Odd Fixes | |
| 3690 | 3693 | F: drivers/net/ethernet/netronome/nfp/bpf/ |
| 3691 | 3694 | |
| 3692 | 3695 | BPF JIT for POWERPC (32-BIT AND 64-BIT) |
| 3693 | 3696 | M: Naveen N. Rao <naveen.n.rao@linux.ibm.com> |
| 3697 | +M: Michael Ellerman <mpe@ellerman.id.au> | |
| 3694 | 3698 | L: netdev@vger.kernel.org |
| 3695 | 3699 | L: bpf@vger.kernel.org |
| 3696 | −S: Maintained | |
| 3700 | +S: Supported | |
| 3697 | 3701 | F: arch/powerpc/net/ |
| 3698 | 3702 | |
| 3699 | 3703 | BPF JIT for RISC-V (32-bit) |
| @@ -3719,7 +3723,7 @@ M: Heiko Carstens <hca@linux.ibm.com> · 19 unmodified lines | ||
| 3719 | 3723 | M: Vasily Gorbik <gor@linux.ibm.com> |
| 3720 | 3724 | L: netdev@vger.kernel.org |
| 3721 | 3725 | L: bpf@vger.kernel.org |
| 3722 | −S: Maintained | |
| 3726 | +S: Supported | |
| 3723 | 3727 | F: arch/s390/net/ |
| 3724 | 3728 | X: arch/s390/net/pnet.c |
| 3725 | 3729 | |
| @@ -3727,14 +3731,14 @@ BPF JIT for SPARC (32-BIT AND 64-BIT) · 1 unmodified line | ||
| 3727 | 3731 | M: David S. Miller <davem@davemloft.net> |
| 3728 | 3732 | L: netdev@vger.kernel.org |
| 3729 | 3733 | L: bpf@vger.kernel.org |
| 3730 | −S: Maintained | |
| 3734 | +S: Odd Fixes | |
| 3731 | 3735 | F: arch/sparc/net/ |
| 3732 | 3736 | |
| 3733 | 3737 | BPF JIT for X86 32-BIT |
| 3734 | 3738 | M: Wang YanQing <udknight@gmail.com> |
| 3735 | 3739 | L: netdev@vger.kernel.org |
| 3736 | 3740 | L: bpf@vger.kernel.org |
| 3737 | −S: Maintained | |
| 3741 | +S: Odd Fixes | |
| 3738 | 3742 | F: arch/x86/net/bpf_jit_comp32.c |
| 3739 | 3743 | |
| 3740 | 3744 | BPF JIT for X86 64-BIT |
| @@ -3757,6 +3761,19 @@ F: include/linux/bpf_lsm.h · 16 unmodified lines | ||
| 3757 | 3761 | F: kernel/bpf/bpf_lsm.c |
| 3758 | 3762 | F: security/bpf/ |
| 3759 | 3763 | |
| 3764 | +BPF L7 FRAMEWORK | |
| 3765 | +M: John Fastabend <john.fastabend@gmail.com> | |
| 3766 | +M: Jakub Sitnicki <jakub@cloudflare.com> | |
| 3767 | +L: netdev@vger.kernel.org | |
| 3768 | +L: bpf@vger.kernel.org | |
| 3769 | +S: Maintained | |
| 3770 | +F: include/linux/skmsg.h | |
| 3771 | +F: net/core/skmsg.c | |
| 3772 | +F: net/core/sock_map.c | |
| 3773 | +F: net/ipv4/tcp_bpf.c | |
| 3774 | +F: net/ipv4/udp_bpf.c | |
| 3775 | +F: net/unix/unix_bpf.c | |
| 3776 | + | |
| 3760 | 3777 | BPFTOOL |
| 3761 | 3778 | M: Quentin Monnet <quentin@isovalent.com> |
| 3762 | 3779 | L: bpf@vger.kernel.org |
| @@ -3796,12 +3813,12 @@ N: bcmbca · 33 unmodified lines | ||
| 3796 | 3813 | N: bcm[9]?47622 |
| 3797 | 3814 | |
| 3798 | 3815 | BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE |
| 3799 | −M: Nicolas Saenz Julienne <nsaenz@kernel.org> | |
| 3816 | +M: Florian Fainelli <f.fainelli@gmail.com> | |
| 3800 | 3817 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 3801 | 3818 | L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) |
| 3802 | 3819 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 3803 | 3820 | S: Maintained |
| 3804 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/nsaenz/linux-rpi.git | |
| 3821 | +T: git git://github.com/broadcom/stblinux.git | |
| 3805 | 3822 | F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml |
| 3806 | 3823 | F: drivers/pci/controller/pcie-brcmstb.c |
| 3807 | 3824 | F: drivers/staging/vc04_services |
| @@ -5962,6 +5979,7 @@ M: Christoph Hellwig <hch@lst.de> · 2154 unmodified lines | ||
| 5962 | 5979 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
| 5963 | 5980 | R: Robin Murphy <robin.murphy@arm.com> |
| 5964 | 5981 | L: iommu@lists.linux-foundation.org |
| 5982 | +L: iommu@lists.linux.dev | |
| 5965 | 5983 | S: Supported |
| 5966 | 5984 | W: http://git.infradead.org/users/hch/dma-mapping.git |
| 5967 | 5985 | T: git git://git.infradead.org/users/hch/dma-mapping.git |
| @@ -5974,6 +5992,7 @@ F: kernel/dma/ · 6 unmodified lines | ||
| 5974 | 5992 | DMA MAPPING BENCHMARK |
| 5975 | 5993 | M: Xiang Chen <chenxiang66@hisilicon.com> |
| 5976 | 5994 | L: iommu@lists.linux-foundation.org |
| 5995 | +L: iommu@lists.linux.dev | |
| 5977 | 5996 | F: kernel/dma/map_benchmark.c |
| 5978 | 5997 | F: tools/testing/selftests/dma/ |
| 5979 | 5998 | |
| @@ -7558,6 +7577,7 @@ F: drivers/gpu/drm/exynos/exynos_dp* · 1578 unmodified lines | ||
| 7558 | 7577 | EXYNOS SYSMMU (IOMMU) driver |
| 7559 | 7578 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
| 7560 | 7579 | L: iommu@lists.linux-foundation.org |
| 7580 | +L: iommu@lists.linux.dev | |
| 7561 | 7581 | S: Maintained |
| 7562 | 7582 | F: drivers/iommu/exynos-iommu.c |
| 7563 | 7583 | |
| @@ -8479,6 +8499,7 @@ F: Documentation/devicetree/bindings/gpio/ · 915 unmodified lines | ||
| 8479 | 8499 | F: Documentation/driver-api/gpio/ |
| 8480 | 8500 | F: drivers/gpio/ |
| 8481 | 8501 | F: include/asm-generic/gpio.h |
| 8502 | +F: include/dt-bindings/gpio/ | |
| 8482 | 8503 | F: include/linux/gpio.h |
| 8483 | 8504 | F: include/linux/gpio/ |
| 8484 | 8505 | F: include/linux/of_gpio.h |
| @@ -9132,6 +9153,7 @@ F: drivers/media/platform/st/sti/hva · 647 unmodified lines | ||
| 9132 | 9153 | |
| 9133 | 9154 | HWPOISON MEMORY FAILURE HANDLING |
| 9134 | 9155 | M: Naoya Horiguchi <naoya.horiguchi@nec.com> |
| 9156 | +R: Miaohe Lin <linmiaohe@huawei.com> | |
| 9135 | 9157 | L: linux-mm@kvack.org |
| 9136 | 9158 | S: Maintained |
| 9137 | 9159 | F: mm/hwpoison-inject.c |
| @@ -9276,6 +9298,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git · 138 unmodified lines | ||
| 9276 | 9298 | F: Documentation/devicetree/bindings/i2c/i2c.txt |
| 9277 | 9299 | F: Documentation/i2c/ |
| 9278 | 9300 | F: drivers/i2c/* |
| 9301 | +F: include/dt-bindings/i2c/i2c.h | |
| 9279 | 9302 | F: include/linux/i2c-dev.h |
| 9280 | 9303 | F: include/linux/i2c-smbus.h |
| 9281 | 9304 | F: include/linux/i2c.h |
| @@ -9291,6 +9314,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git · 9 unmodified lines | ||
| 9291 | 9314 | F: Documentation/devicetree/bindings/i2c/ |
| 9292 | 9315 | F: drivers/i2c/algos/ |
| 9293 | 9316 | F: drivers/i2c/busses/ |
| 9317 | +F: include/dt-bindings/i2c/ | |
| 9294 | 9318 | |
| 9295 | 9319 | I2C-TAOS-EVM DRIVER |
| 9296 | 9320 | M: Jean Delvare <jdelvare@suse.com> |
| @@ -9975,6 +9999,7 @@ INTEL IOMMU (VT-d) · 678 unmodified lines | ||
| 9975 | 9999 | M: David Woodhouse <dwmw2@infradead.org> |
| 9976 | 10000 | M: Lu Baolu <baolu.lu@linux.intel.com> |
| 9977 | 10001 | L: iommu@lists.linux-foundation.org |
| 10002 | +L: iommu@lists.linux.dev | |
| 9978 | 10003 | S: Supported |
| 9979 | 10004 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 9980 | 10005 | F: drivers/iommu/intel/ |
| @@ -10354,6 +10379,7 @@ IOMMU DRIVERS · 373 unmodified lines | ||
| 10354 | 10379 | M: Joerg Roedel <joro@8bytes.org> |
| 10355 | 10380 | M: Will Deacon <will@kernel.org> |
| 10356 | 10381 | L: iommu@lists.linux-foundation.org |
| 10382 | +L: iommu@lists.linux.dev | |
| 10357 | 10383 | S: Maintained |
| 10358 | 10384 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 10359 | 10385 | F: Documentation/devicetree/bindings/iommu/ |
| @@ -10830,6 +10856,7 @@ M: Marc Zyngier <maz@kernel.org> · 470 unmodified lines | ||
| 10830 | 10856 | R: James Morse <james.morse@arm.com> |
| 10831 | 10857 | R: Alexandru Elisei <alexandru.elisei@arm.com> |
| 10832 | 10858 | R: Suzuki K Poulose <suzuki.poulose@arm.com> |
| 10859 | +R: Oliver Upton <oliver.upton@linux.dev> | |
| 10833 | 10860 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 10834 | 10861 | L: kvmarm@lists.cs.columbia.edu (moderated for non-subscribers) |
| 10835 | 10862 | S: Maintained |
| @@ -10872,7 +10899,6 @@ F: arch/riscv/include/asm/kvm* · 36 unmodified lines | ||
| 10872 | 10899 | F: arch/riscv/include/uapi/asm/kvm* |
| 10873 | 10900 | F: arch/riscv/kvm/ |
| 10874 | 10901 | F: tools/testing/selftests/kvm/*/riscv/ |
| 10875 | −F: tools/testing/selftests/kvm/riscv/ | |
| 10876 | 10902 | |
| 10877 | 10903 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) |
| 10878 | 10904 | M: Christian Borntraeger <borntraeger@linux.ibm.com> |
| @@ -10897,28 +10923,51 @@ F: tools/testing/selftests/kvm/*/s390x/ · 18 unmodified lines | ||
| 10897 | 10923 | F: tools/testing/selftests/kvm/s390x/ |
| 10898 | 10924 | |
| 10899 | 10925 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) |
| 10926 | +M: Sean Christopherson <seanjc@google.com> | |
| 10900 | 10927 | M: Paolo Bonzini <pbonzini@redhat.com> |
| 10901 | −R: Sean Christopherson <seanjc@google.com> | |
| 10902 | −R: Vitaly Kuznetsov <vkuznets@redhat.com> | |
| 10903 | −R: Wanpeng Li <wanpengli@tencent.com> | |
| 10904 | −R: Jim Mattson <jmattson@google.com> | |
| 10905 | −R: Joerg Roedel <joro@8bytes.org> | |
| 10906 | 10928 | L: kvm@vger.kernel.org |
| 10907 | 10929 | S: Supported |
| 10908 | −W: http://www.linux-kvm.org | |
| 10909 | 10930 | T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git |
| 10910 | 10931 | F: arch/x86/include/asm/kvm* |
| 10911 | −F: arch/x86/include/asm/pvclock-abi.h | |
| 10912 | 10932 | F: arch/x86/include/asm/svm.h |
| 10913 | 10933 | F: arch/x86/include/asm/vmx*.h |
| 10914 | 10934 | F: arch/x86/include/uapi/asm/kvm* |
| 10915 | 10935 | F: arch/x86/include/uapi/asm/svm.h |
| 10916 | 10936 | F: arch/x86/include/uapi/asm/vmx.h |
| 10917 | −F: arch/x86/kernel/kvm.c | |
| 10918 | −F: arch/x86/kernel/kvmclock.c | |
| 10919 | 10937 | F: arch/x86/kvm/ |
| 10920 | 10938 | F: arch/x86/kvm/*/ |
| 10921 | 10939 | |
| 10940 | +KVM PARAVIRT (KVM/paravirt) | |
| 10941 | +M: Paolo Bonzini <pbonzini@redhat.com> | |
| 10942 | +R: Wanpeng Li <wanpengli@tencent.com> | |
| 10943 | +R: Vitaly Kuznetsov <vkuznets@redhat.com> | |
| 10944 | +L: kvm@vger.kernel.org | |
| 10945 | +S: Supported | |
| 10946 | +T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git | |
| 10947 | +F: arch/x86/kernel/kvm.c | |
| 10948 | +F: arch/x86/kernel/kvmclock.c | |
| 10949 | +F: arch/x86/include/asm/pvclock-abi.h | |
| 10950 | +F: include/linux/kvm_para.h | |
| 10951 | +F: include/uapi/linux/kvm_para.h | |
| 10952 | +F: include/uapi/asm-generic/kvm_para.h | |
| 10953 | +F: include/asm-generic/kvm_para.h | |
| 10954 | +F: arch/um/include/asm/kvm_para.h | |
| 10955 | +F: arch/x86/include/asm/kvm_para.h | |
| 10956 | +F: arch/x86/include/uapi/asm/kvm_para.h | |
| 10957 | + | |
| 10958 | +KVM X86 HYPER-V (KVM/hyper-v) | |
| 10959 | +M: Vitaly Kuznetsov <vkuznets@redhat.com> | |
| 10960 | +M: Sean Christopherson <seanjc@google.com> | |
| 10961 | +M: Paolo Bonzini <pbonzini@redhat.com> | |
| 10962 | +L: kvm@vger.kernel.org | |
| 10963 | +S: Supported | |
| 10964 | +T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git | |
| 10965 | +F: arch/x86/kvm/hyperv.* | |
| 10966 | +F: arch/x86/kvm/kvm_onhyperv.* | |
| 10967 | +F: arch/x86/kvm/svm/hyperv.* | |
| 10968 | +F: arch/x86/kvm/svm/svm_onhyperv.* | |
| 10969 | +F: arch/x86/kvm/vmx/evmcs.* | |
| 10970 | + | |
| 10922 | 10971 | KERNFS |
| 10923 | 10972 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 10924 | 10973 | M: Tejun Heo <tj@kernel.org> |
| @@ -11097,20 +11146,6 @@ S: Maintained · 172 unmodified lines | ||
| 11097 | 11146 | F: include/net/l3mdev.h |
| 11098 | 11147 | F: net/l3mdev |
| 11099 | 11148 | |
| 11100 | −L7 BPF FRAMEWORK | |
| 11101 | −M: John Fastabend <john.fastabend@gmail.com> | |
| 11102 | −M: Daniel Borkmann <daniel@iogearbox.net> | |
| 11103 | −M: Jakub Sitnicki <jakub@cloudflare.com> | |
| 11104 | −L: netdev@vger.kernel.org | |
| 11105 | −L: bpf@vger.kernel.org | |
| 11106 | −S: Maintained | |
| 11107 | −F: include/linux/skmsg.h | |
| 11108 | −F: net/core/skmsg.c | |
| 11109 | −F: net/core/sock_map.c | |
| 11110 | −F: net/ipv4/tcp_bpf.c | |
| 11111 | −F: net/ipv4/udp_bpf.c | |
| 11112 | −F: net/unix/unix_bpf.c | |
| 11113 | − | |
| 11114 | 11149 | LANDLOCK SECURITY MODULE |
| 11115 | 11150 | M: Mickaël Salaün <mic@digikod.net> |
| 11116 | 11151 | L: linux-security-module@vger.kernel.org |
| @@ -11590,6 +11625,7 @@ F: drivers/gpu/drm/bridge/lontium-lt8912b.c · 473 unmodified lines | ||
| 11590 | 11625 | LOONGARCH |
| 11591 | 11626 | M: Huacai Chen <chenhuacai@kernel.org> |
| 11592 | 11627 | R: WANG Xuerui <kernel@xen0n.name> |
| 11628 | +L: loongarch@lists.linux.dev | |
| 11593 | 11629 | S: Maintained |
| 11594 | 11630 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git |
| 11595 | 11631 | F: arch/loongarch/ |
| @@ -12503,6 +12539,7 @@ F: drivers/i2c/busses/i2c-mt65xx.c · 907 unmodified lines | ||
| 12503 | 12539 | MEDIATEK IOMMU DRIVER |
| 12504 | 12540 | M: Yong Wu <yong.wu@mediatek.com> |
| 12505 | 12541 | L: iommu@lists.linux-foundation.org |
| 12542 | +L: iommu@lists.linux.dev | |
| 12506 | 12543 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) |
| 12507 | 12544 | S: Supported |
| 12508 | 12545 | F: Documentation/devicetree/bindings/iommu/mediatek* |
| @@ -12845,9 +12882,8 @@ M: Andrew Morton <akpm@linux-foundation.org> · 336 unmodified lines | ||
| 12845 | 12882 | L: linux-mm@kvack.org |
| 12846 | 12883 | S: Maintained |
| 12847 | 12884 | W: http://www.linux-mm.org |
| 12848 | −T: quilt https://ozlabs.org/~akpm/mmotm/ | |
| 12849 | −T: quilt https://ozlabs.org/~akpm/mmots/ | |
| 12850 | −T: git git://github.com/hnaz/linux-mm.git | |
| 12885 | +T: git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | |
| 12886 | +T: quilt git://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new | |
| 12851 | 12887 | F: include/linux/gfp.h |
| 12852 | 12888 | F: include/linux/memory_hotplug.h |
| 12853 | 12889 | F: include/linux/mm.h |
| @@ -12857,6 +12893,18 @@ F: include/linux/vmalloc.h · 3 unmodified lines | ||
| 12857 | 12893 | F: mm/ |
| 12858 | 12894 | F: tools/testing/selftests/vm/ |
| 12859 | 12895 | |
| 12896 | +MEMORY HOT(UN)PLUG | |
| 12897 | +M: David Hildenbrand <david@redhat.com> | |
| 12898 | +M: Oscar Salvador <osalvador@suse.de> | |
| 12899 | +L: linux-mm@kvack.org | |
| 12900 | +S: Maintained | |
| 12901 | +F: Documentation/admin-guide/mm/memory-hotplug.rst | |
| 12902 | +F: Documentation/core-api/memory-hotplug.rst | |
| 12903 | +F: drivers/base/memory.c | |
| 12904 | +F: include/linux/memory_hotplug.h | |
| 12905 | +F: mm/memory_hotplug.c | |
| 12906 | +F: tools/testing/selftests/memory-hotplug/ | |
| 12907 | + | |
| 12860 | 12908 | MEMORY TECHNOLOGY DEVICES (MTD) |
| 12861 | 12909 | M: Miquel Raynal <miquel.raynal@bootlin.com> |
| 12862 | 12910 | M: Richard Weinberger <richard@nod.at> |
| @@ -13801,6 +13849,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git · 938 unmodified lines | ||
| 13801 | 13849 | F: Documentation/devicetree/bindings/net/ |
| 13802 | 13850 | F: drivers/connector/ |
| 13803 | 13851 | F: drivers/net/ |
| 13852 | +F: include/dt-bindings/net/ | |
| 13804 | 13853 | F: include/linux/etherdevice.h |
| 13805 | 13854 | F: include/linux/fcdevice.h |
| 13806 | 13855 | F: include/linux/fddidevice.h |
| @@ -13952,7 +14001,6 @@ F: net/ipv6/tcp*.c · 145 unmodified lines | ||
| 13952 | 14001 | NETWORKING [TLS] |
| 13953 | 14002 | M: Boris Pismenny <borisp@nvidia.com> |
| 13954 | 14003 | M: John Fastabend <john.fastabend@gmail.com> |
| 13955 | −M: Daniel Borkmann <daniel@iogearbox.net> | |
| 13956 | 14004 | M: Jakub Kicinski <kuba@kernel.org> |
| 13957 | 14005 | L: netdev@vger.kernel.org |
| 13958 | 14006 | S: Maintained |
| @@ -14261,7 +14309,7 @@ F: drivers/iio/gyro/fxas21002c_i2c.c · 302 unmodified lines | ||
| 14261 | 14309 | F: drivers/iio/gyro/fxas21002c_spi.c |
| 14262 | 14310 | |
| 14263 | 14311 | NXP i.MX CLOCK DRIVERS |
| 14264 | −M: Abel Vesa <abel.vesa@nxp.com> | |
| 14312 | +M: Abel Vesa <abelvesa@kernel.org> | |
| 14265 | 14313 | L: linux-clk@vger.kernel.org |
| 14266 | 14314 | L: linux-imx@nxp.com |
| 14267 | 14315 | S: Maintained |
| @@ -14869,6 +14917,7 @@ F: include/dt-bindings/ · 601 unmodified lines | ||
| 14869 | 14917 | |
| 14870 | 14918 | OPENCOMPUTE PTP CLOCK DRIVER |
| 14871 | 14919 | M: Jonathan Lemon <jonathan.lemon@gmail.com> |
| 14920 | +M: Vadim Fedorenko <vadfed@fb.com> | |
| 14872 | 14921 | L: netdev@vger.kernel.org |
| 14873 | 14922 | S: Maintained |
| 14874 | 14923 | F: drivers/ptp/ptp_ocp.c |
| @@ -16488,7 +16537,7 @@ F: Documentation/devicetree/bindings/opp/opp-v2-kryo-cpu.yaml · 1613 unmodified lines | ||
| 16488 | 16537 | F: drivers/cpufreq/qcom-cpufreq-nvmem.c |
| 16489 | 16538 | |
| 16490 | 16539 | QUALCOMM CRYPTO DRIVERS |
| 16491 | −M: Thara Gopinath <thara.gopinath@linaro.org> | |
| 16540 | +M: Thara Gopinath <thara.gopinath@gmail.com> | |
| 16492 | 16541 | L: linux-crypto@vger.kernel.org |
| 16493 | 16542 | L: linux-arm-msm@vger.kernel.org |
| 16494 | 16543 | S: Maintained |
| @@ -16543,6 +16592,7 @@ F: drivers/i2c/busses/i2c-qcom-cci.c · 48 unmodified lines | ||
| 16543 | 16592 | QUALCOMM IOMMU |
| 16544 | 16593 | M: Rob Clark <robdclark@gmail.com> |
| 16545 | 16594 | L: iommu@lists.linux-foundation.org |
| 16595 | +L: iommu@lists.linux.dev | |
| 16546 | 16596 | L: linux-arm-msm@vger.kernel.org |
| 16547 | 16597 | S: Maintained |
| 16548 | 16598 | F: drivers/iommu/arm/arm-smmu/qcom_iommu.c |
| @@ -16598,7 +16648,7 @@ F: include/linux/if_rmnet.h · 49 unmodified lines | ||
| 16598 | 16648 | |
| 16599 | 16649 | QUALCOMM TSENS THERMAL DRIVER |
| 16600 | 16650 | M: Amit Kucheria <amitk@kernel.org> |
| 16601 | −M: Thara Gopinath <thara.gopinath@linaro.org> | |
| 16651 | +M: Thara Gopinath <thara.gopinath@gmail.com> | |
| 16602 | 16652 | L: linux-pm@vger.kernel.org |
| 16603 | 16653 | L: linux-arm-msm@vger.kernel.org |
| 16604 | 16654 | S: Maintained |
| @@ -19168,6 +19218,7 @@ F: arch/x86/boot/video* · 2563 unmodified lines | ||
| 19168 | 19218 | SWIOTLB SUBSYSTEM |
| 19169 | 19219 | M: Christoph Hellwig <hch@infradead.org> |
| 19170 | 19220 | L: iommu@lists.linux-foundation.org |
| 19221 | +L: iommu@lists.linux.dev | |
| 19171 | 19222 | S: Supported |
| 19172 | 19223 | W: http://git.infradead.org/users/hch/dma-mapping.git |
| 19173 | 19224 | T: git git://git.infradead.org/users/hch/dma-mapping.git |
| @@ -19305,7 +19356,7 @@ R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> · 131 unmodified lines | ||
| 19305 | 19356 | R: Mika Westerberg <mika.westerberg@linux.intel.com> |
| 19306 | 19357 | R: Jan Dabros <jsd@semihalf.com> |
| 19307 | 19358 | L: linux-i2c@vger.kernel.org |
| 19308 | −S: Maintained | |
| 19359 | +S: Supported | |
| 19309 | 19360 | F: drivers/i2c/busses/i2c-designware-* |
| 19310 | 19361 | |
| 19311 | 19362 | SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER |
| @@ -20712,6 +20763,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git · 1400 unmodified lines | ||
| 20712 | 20763 | F: Documentation/devicetree/bindings/usb/ |
| 20713 | 20764 | F: Documentation/usb/ |
| 20714 | 20765 | F: drivers/usb/ |
| 20766 | +F: include/dt-bindings/usb/ | |
| 20715 | 20767 | F: include/linux/usb.h |
| 20716 | 20768 | F: include/linux/usb/ |
| 20717 | 20769 | |
| @@ -21843,6 +21895,7 @@ M: Juergen Gross <jgross@suse.com> · 1125 unmodified lines | ||
| 21843 | 21895 | M: Stefano Stabellini <sstabellini@kernel.org> |
| 21844 | 21896 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) |
| 21845 | 21897 | L: iommu@lists.linux-foundation.org |
| 21898 | +L: iommu@lists.linux.dev | |
| 21846 | 21899 | S: Supported |
| 21847 | 21900 | F: arch/x86/xen/*swiotlb* |
| 21848 | 21901 | F: drivers/xen/*swiotlb* |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 19 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc2 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Superb Owl |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -1141,7 +1141,7 @@ KBUILD_MODULES := 1 · 1132 unmodified lines | ||
| 1141 | 1141 | |
| 1142 | 1142 | autoksyms_recursive: descend modules.order |
| 1143 | 1143 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ |
| 1144 | − "$(MAKE) -f $(srctree)/Makefile vmlinux" | |
| 1144 | + "$(MAKE) -f $(srctree)/Makefile autoksyms_recursive" | |
| 1145 | 1145 | endif |
| 1146 | 1146 | |
| 1147 | 1147 | autoksyms_h := $(if $(CONFIG_TRIM_UNUSED_KSYMS), include/generated/autoksyms.h) |
| @@ -1586,7 +1586,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ · 1585 unmodified lines | ||
| 1586 | 1586 | aspeed-bmc-lenovo-hr630.dtb \ |
| 1587 | 1587 | aspeed-bmc-lenovo-hr855xg2.dtb \ |
| 1588 | 1588 | aspeed-bmc-microsoft-olympus.dtb \ |
| 1589 | − aspeed-bmc-nuvia-dc-scm.dtb \ | |
| 1590 | 1589 | aspeed-bmc-opp-lanyang.dtb \ |
| 1591 | 1590 | aspeed-bmc-opp-mihawk.dtb \ |
| 1592 | 1591 | aspeed-bmc-opp-mowgli.dtb \ |
| @@ -1599,6 +1598,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ · 6 unmodified lines | ||
| 1599 | 1598 | aspeed-bmc-opp-witherspoon.dtb \ |
| 1600 | 1599 | aspeed-bmc-opp-zaius.dtb \ |
| 1601 | 1600 | aspeed-bmc-portwell-neptune.dtb \ |
| 1601 | + aspeed-bmc-qcom-dc-scm-v1.dtb \ | |
| 1602 | 1602 | aspeed-bmc-quanta-q71l.dtb \ |
| 1603 | 1603 | aspeed-bmc-quanta-s6q.dtb \ |
| 1604 | 1604 | aspeed-bmc-supermicro-x11spi.dtb \ |
| @@ -6,8 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "aspeed-g6.dtsi" |
| 7 | 7 | |
| 8 | 8 | / { |
| 9 | − model = "Nuvia DC-SCM BMC"; | |
| 10 | − compatible = "nuvia,dc-scm-bmc", "aspeed,ast2600"; | |
| 9 | + model = "Qualcomm DC-SCM V1 BMC"; | |
| 10 | + compatible = "qcom,dc-scm-v1-bmc", "aspeed,ast2600"; | |
| 11 | 11 | |
| 12 | 12 | aliases { |
| 13 | 13 | serial4 = &uart5; |
| @@ -120,26 +120,31 @@ · 119 unmodified lines | ||
| 120 | 120 | port@0 { |
| 121 | 121 | reg = <0>; |
| 122 | 122 | label = "lan1"; |
| 123 | + phy-mode = "internal"; | |
| 123 | 124 | }; |
| 124 | 125 | |
| 125 | 126 | port@1 { |
| 126 | 127 | reg = <1>; |
| 127 | 128 | label = "lan2"; |
| 129 | + phy-mode = "internal"; | |
| 128 | 130 | }; |
| 129 | 131 | |
| 130 | 132 | port@2 { |
| 131 | 133 | reg = <2>; |
| 132 | 134 | label = "lan3"; |
| 135 | + phy-mode = "internal"; | |
| 133 | 136 | }; |
| 134 | 137 | |
| 135 | 138 | port@3 { |
| 136 | 139 | reg = <3>; |
| 137 | 140 | label = "lan4"; |
| 141 | + phy-mode = "internal"; | |
| 138 | 142 | }; |
| 139 | 143 | |
| 140 | 144 | port@4 { |
| 141 | 145 | reg = <4>; |
| 142 | 146 | label = "lan5"; |
| 147 | + phy-mode = "internal"; | |
| 143 | 148 | }; |
| 144 | 149 | |
| 145 | 150 | port@5 { |
| @@ -28,12 +28,12 @@ · 27 unmodified lines | ||
| 28 | 28 | &expgpio { |
| 29 | 29 | gpio-line-names = "BT_ON", |
| 30 | 30 | "WL_ON", |
| 31 | − "", | |
| 31 | + "PWR_LED_OFF", | |
| 32 | 32 | "GLOBAL_RESET", |
| 33 | 33 | "VDD_SD_IO_SEL", |
| 34 | − "CAM_GPIO", | |
| 34 | + "GLOBAL_SHUTDOWN", | |
| 35 | 35 | "SD_PWR_ON", |
| 36 | − "SD_OC_N"; | |
| 36 | + "SHUTDOWN_REQUEST"; | |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | 39 | &genet_mdio { |
| @@ -593,7 +593,7 @@ · 592 unmodified lines | ||
| 593 | 593 | pinctrl-names = "default"; |
| 594 | 594 | pinctrl-0 = <&pinctrl_atmel_conn>; |
| 595 | 595 | reg = <0x4a>; |
| 596 | − reset-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; /* SODIMM 106 */ | |
| 596 | + reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* SODIMM 106 */ | |
| 597 | 597 | status = "disabled"; |
| 598 | 598 | }; |
| 599 | 599 | }; |
| @@ -762,7 +762,7 @@ · 761 unmodified lines | ||
| 762 | 762 | regulator-name = "vddpu"; |
| 763 | 763 | regulator-min-microvolt = <725000>; |
| 764 | 764 | regulator-max-microvolt = <1450000>; |
| 765 | − regulator-enable-ramp-delay = <150>; | |
| 765 | + regulator-enable-ramp-delay = <380>; | |
| 766 | 766 | anatop-reg-offset = <0x140>; |
| 767 | 767 | anatop-vol-bit-shift = <9>; |
| 768 | 768 | anatop-vol-bit-width = <5>; |
| @@ -120,6 +120,7 @@ · 119 unmodified lines | ||
| 120 | 120 | compatible = "usb-nop-xceiv"; |
| 121 | 121 | clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>; |
| 122 | 122 | clock-names = "main_clk"; |
| 123 | + power-domains = <&pgc_hsic_phy>; | |
| 123 | 124 | #phy-cells = <0>; |
| 124 | 125 | }; |
| 125 | 126 | |
| @@ -1153,7 +1154,6 @@ · 1027 unmodified lines | ||
| 1153 | 1154 | compatible = "fsl,imx7d-usb", "fsl,imx27-usb"; |
| 1154 | 1155 | reg = <0x30b30000 0x200>; |
| 1155 | 1156 | interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; |
| 1156 | − power-domains = <&pgc_hsic_phy>; | |
| 1157 | 1157 | clocks = <&clks IMX7D_USB_CTRL_CLK>; |
| 1158 | 1158 | fsl,usbphy = <&usbphynop3>; |
| 1159 | 1159 | fsl,usbmisc = <&usbmisc3 0>; |
| @@ -0,0 +1,47 @@ | ||
| 1 | +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) | |
| 2 | +/* | |
| 3 | + * Copyright (C) STMicroelectronics 2022 - All Rights Reserved | |
| 4 | + * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics. | |
| 5 | + */ | |
| 6 | + | |
| 7 | +/ { | |
| 8 | + firmware { | |
| 9 | + optee: optee { | |
| 10 | + compatible = "linaro,optee-tz"; | |
| 11 | + method = "smc"; | |
| 12 | + }; | |
| 13 | + | |
| 14 | + scmi: scmi { | |
| 15 | + compatible = "linaro,scmi-optee"; | |
| 16 | + #address-cells = <1>; | |
| 17 | + #size-cells = <0>; | |
| 18 | + linaro,optee-channel-id = <0>; | |
| 19 | + shmem = <&scmi_shm>; | |
| 20 | + | |
| 21 | + scmi_clk: protocol@14 { | |
| 22 | + reg = <0x14>; | |
| 23 | + #clock-cells = <1>; | |
| 24 | + }; | |
| 25 | + | |
| 26 | + scmi_reset: protocol@16 { | |
| 27 | + reg = <0x16>; | |
| 28 | + #reset-cells = <1>; | |
| 29 | + }; | |
| 30 | + }; | |
| 31 | + }; | |
| 32 | + | |
| 33 | + soc { | |
| 34 | + scmi_sram: sram@2ffff000 { | |
| 35 | + compatible = "mmio-sram"; | |
| 36 | + reg = <0x2ffff000 0x1000>; | |
| 37 | + #address-cells = <1>; | |
| 38 | + #size-cells = <1>; | |
| 39 | + ranges = <0 0x2ffff000 0x1000>; | |
| 40 | + | |
| 41 | + scmi_shm: scmi-sram@0 { | |
| 42 | + compatible = "arm,scmi-shmem"; | |
| 43 | + reg = <0 0x80>; | |
| 44 | + }; | |
| 45 | + }; | |
| 46 | + }; | |
| 47 | +}; | |
| @@ -115,33 +115,6 @@ · 114 unmodified lines | ||
| 115 | 115 | status = "disabled"; |
| 116 | 116 | }; |
| 117 | 117 | |
| 118 | − firmware { | |
| 119 | − optee: optee { | |
| 120 | − compatible = "linaro,optee-tz"; | |
| 121 | − method = "smc"; | |
| 122 | − status = "disabled"; | |
| 123 | − }; | |
| 124 | − | |
| 125 | − scmi: scmi { | |
| 126 | − compatible = "linaro,scmi-optee"; | |
| 127 | − #address-cells = <1>; | |
| 128 | − #size-cells = <0>; | |
| 129 | − linaro,optee-channel-id = <0>; | |
| 130 | − shmem = <&scmi_shm>; | |
| 131 | − status = "disabled"; | |
| 132 | − | |
| 133 | − scmi_clk: protocol@14 { | |
| 134 | − reg = <0x14>; | |
| 135 | − #clock-cells = <1>; | |
| 136 | − }; | |
| 137 | − | |
| 138 | − scmi_reset: protocol@16 { | |
| 139 | − reg = <0x16>; | |
| 140 | − #reset-cells = <1>; | |
| 141 | − }; | |
| 142 | − }; | |
| 143 | − }; | |
| 144 | − | |
| 145 | 118 | soc { |
| 146 | 119 | compatible = "simple-bus"; |
| 147 | 120 | #address-cells = <1>; |
| @@ -149,20 +122,6 @@ · 1 unmodified line | ||
| 149 | 122 | interrupt-parent = <&intc>; |
| 150 | 123 | ranges; |
| 151 | 124 | |
| 152 | − scmi_sram: sram@2ffff000 { | |
| 153 | − compatible = "mmio-sram"; | |
| 154 | − reg = <0x2ffff000 0x1000>; | |
| 155 | − #address-cells = <1>; | |
| 156 | − #size-cells = <1>; | |
| 157 | − ranges = <0 0x2ffff000 0x1000>; | |
| 158 | − | |
| 159 | − scmi_shm: scmi-sram@0 { | |
| 160 | − compatible = "arm,scmi-shmem"; | |
| 161 | − reg = <0 0x80>; | |
| 162 | − status = "disabled"; | |
| 163 | − }; | |
| 164 | − }; | |
| 165 | − | |
| 166 | 125 | timers2: timer@40000000 { |
| 167 | 126 | #address-cells = <1>; |
| 168 | 127 | #size-cells = <0>; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | /dts-v1/; |
| 8 | 8 | |
| 9 | 9 | #include "stm32mp157a-dk1.dts" |
| 10 | +#include "stm32mp15-scmi.dtsi" | |
| 10 | 11 | |
| 11 | 12 | / { |
| 12 | 13 | model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; |
| @@ -54,10 +55,6 @@ · 41 unmodified lines | ||
| 54 | 55 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 55 | 56 | }; |
| 56 | 57 | |
| 57 | −&optee { | |
| 58 | − status = "okay"; | |
| 59 | −}; | |
| 60 | − | |
| 61 | 58 | &rcc { |
| 62 | 59 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 63 | 60 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -76,11 +73,3 @@ · 12 unmodified lines | ||
| 76 | 73 | &rtc { |
| 77 | 74 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; |
| 78 | 75 | }; |
| 79 | − | |
| 80 | −&scmi { | |
| 81 | − status = "okay"; | |
| 82 | −}; | |
| 83 | − | |
| 84 | −&scmi_shm { | |
| 85 | − status = "okay"; | |
| 86 | −}; | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | /dts-v1/; |
| 8 | 8 | |
| 9 | 9 | #include "stm32mp157c-dk2.dts" |
| 10 | +#include "stm32mp15-scmi.dtsi" | |
| 10 | 11 | |
| 11 | 12 | / { |
| 12 | 13 | model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; |
| @@ -63,10 +64,6 @@ · 50 unmodified lines | ||
| 63 | 64 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 64 | 65 | }; |
| 65 | 66 | |
| 66 | −&optee { | |
| 67 | − status = "okay"; | |
| 68 | −}; | |
| 69 | − | |
| 70 | 67 | &rcc { |
| 71 | 68 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 72 | 69 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -85,11 +82,3 @@ · 12 unmodified lines | ||
| 85 | 82 | &rtc { |
| 86 | 83 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; |
| 87 | 84 | }; |
| 88 | − | |
| 89 | −&scmi { | |
| 90 | − status = "okay"; | |
| 91 | −}; | |
| 92 | − | |
| 93 | −&scmi_shm { | |
| 94 | − status = "okay"; | |
| 95 | −}; | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | /dts-v1/; |
| 8 | 8 | |
| 9 | 9 | #include "stm32mp157c-ed1.dts" |
| 10 | +#include "stm32mp15-scmi.dtsi" | |
| 10 | 11 | |
| 11 | 12 | / { |
| 12 | 13 | model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; |
| @@ -59,10 +60,6 @@ · 46 unmodified lines | ||
| 59 | 60 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 60 | 61 | }; |
| 61 | 62 | |
| 62 | −&optee { | |
| 63 | − status = "okay"; | |
| 64 | −}; | |
| 65 | − | |
| 66 | 63 | &rcc { |
| 67 | 64 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 68 | 65 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -81,11 +78,3 @@ · 12 unmodified lines | ||
| 81 | 78 | &rtc { |
| 82 | 79 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; |
| 83 | 80 | }; |
| 84 | − | |
| 85 | −&scmi { | |
| 86 | − status = "okay"; | |
| 87 | −}; | |
| 88 | − | |
| 89 | −&scmi_shm { | |
| 90 | − status = "okay"; | |
| 91 | −}; | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | /dts-v1/; |
| 8 | 8 | |
| 9 | 9 | #include "stm32mp157c-ev1.dts" |
| 10 | +#include "stm32mp15-scmi.dtsi" | |
| 10 | 11 | |
| 11 | 12 | / { |
| 12 | 13 | model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; |
| @@ -68,10 +69,6 @@ · 55 unmodified lines | ||
| 68 | 69 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 69 | 70 | }; |
| 70 | 71 | |
| 71 | −&optee { | |
| 72 | − status = "okay"; | |
| 73 | −}; | |
| 74 | − | |
| 75 | 72 | &rcc { |
| 76 | 73 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 77 | 74 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -90,11 +87,3 @@ · 12 unmodified lines | ||
| 90 | 87 | &rtc { |
| 91 | 88 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; |
| 92 | 89 | }; |
| 93 | − | |
| 94 | −&scmi { | |
| 95 | − status = "okay"; | |
| 96 | −}; | |
| 97 | − | |
| 98 | −&scmi_shm { | |
| 99 | − status = "okay"; | |
| 100 | −}; | |
| @@ -39,6 +39,7 @@ static int axxia_boot_secondary(unsigned int cpu, struct task_struct *idle) · 38 unmodified lines | ||
| 39 | 39 | return -ENOENT; |
| 40 | 40 | |
| 41 | 41 | syscon = of_iomap(syscon_np, 0); |
| 42 | + of_node_put(syscon_np); | |
| 42 | 43 | if (!syscon) |
| 43 | 44 | return -ENOMEM; |
| 44 | 45 | |
| @@ -372,6 +372,7 @@ static void __init cns3xxx_init(void) · 371 unmodified lines | ||
| 372 | 372 | /* De-Asscer SATA Reset */ |
| 373 | 373 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA)); |
| 374 | 374 | } |
| 375 | + of_node_put(dn); | |
| 375 | 376 | |
| 376 | 377 | dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-sdhci"); |
| 377 | 378 | if (of_device_is_available(dn)) { |
| @@ -385,6 +386,7 @@ static void __init cns3xxx_init(void) · 7 unmodified lines | ||
| 385 | 386 | cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO)); |
| 386 | 387 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO)); |
| 387 | 388 | } |
| 389 | + of_node_put(dn); | |
| 388 | 390 | |
| 389 | 391 | pm_power_off = cns3xxx_power_off; |
| 390 | 392 | |
| @@ -149,6 +149,7 @@ static void exynos_map_pmu(void) · 148 unmodified lines | ||
| 149 | 149 | np = of_find_matching_node(NULL, exynos_dt_pmu_match); |
| 150 | 150 | if (np) |
| 151 | 151 | pmu_base_addr = of_iomap(np, 0); |
| 152 | + of_node_put(np); | |
| 152 | 153 | } |
| 153 | 154 | |
| 154 | 155 | static void __init exynos_init_irq(void) |
| @@ -218,13 +218,13 @@ void __init spear_setup_of_timer(void) · 217 unmodified lines | ||
| 218 | 218 | irq = irq_of_parse_and_map(np, 0); |
| 219 | 219 | if (!irq) { |
| 220 | 220 | pr_err("%s: No irq passed for timer via DT\n", __func__); |
| 221 | − return; | |
| 221 | + goto err_put_np; | |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | 224 | gpt_base = of_iomap(np, 0); |
| 225 | 225 | if (!gpt_base) { |
| 226 | 226 | pr_err("%s: of iomap failed\n", __func__); |
| 227 | − return; | |
| 227 | + goto err_put_np; | |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | gpt_clk = clk_get_sys("gpt0", NULL); |
| @@ -239,6 +239,8 @@ void __init spear_setup_of_timer(void) · 8 unmodified lines | ||
| 239 | 239 | goto err_prepare_enable_clk; |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | + of_node_put(np); | |
| 243 | + | |
| 242 | 244 | spear_clockevent_init(irq); |
| 243 | 245 | spear_clocksource_init(); |
| 244 | 246 | |
| @@ -248,4 +250,6 @@ err_prepare_enable_clk: · 3 unmodified lines | ||
| 248 | 250 | clk_put(gpt_clk); |
| 249 | 251 | err_iomap: |
| 250 | 252 | iounmap(gpt_base); |
| 253 | +err_put_np: | |
| 254 | + of_node_put(np); | |
| 251 | 255 | } |
| @@ -280,8 +280,8 @@ · 279 unmodified lines | ||
| 280 | 280 | interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; |
| 281 | 281 | pinctrl-names = "default"; |
| 282 | 282 | pinctrl-0 = <&uart0_bus>; |
| 283 | − clocks = <&cmu_peri CLK_GOUT_UART0_EXT_UCLK>, | |
| 284 | − <&cmu_peri CLK_GOUT_UART0_PCLK>; | |
| 283 | + clocks = <&cmu_peri CLK_GOUT_UART0_PCLK>, | |
| 284 | + <&cmu_peri CLK_GOUT_UART0_EXT_UCLK>; | |
| 285 | 285 | clock-names = "uart", "clk_uart_baud0"; |
| 286 | 286 | samsung,uart-fifosize = <64>; |
| 287 | 287 | status = "disabled"; |
| @@ -293,8 +293,8 @@ · 5 unmodified lines | ||
| 293 | 293 | interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>; |
| 294 | 294 | pinctrl-names = "default"; |
| 295 | 295 | pinctrl-0 = <&uart1_bus>; |
| 296 | − clocks = <&cmu_peri CLK_GOUT_UART1_EXT_UCLK>, | |
| 297 | − <&cmu_peri CLK_GOUT_UART1_PCLK>; | |
| 296 | + clocks = <&cmu_peri CLK_GOUT_UART1_PCLK>, | |
| 297 | + <&cmu_peri CLK_GOUT_UART1_EXT_UCLK>; | |
| 298 | 298 | clock-names = "uart", "clk_uart_baud0"; |
| 299 | 299 | samsung,uart-fifosize = <256>; |
| 300 | 300 | status = "disabled"; |
| @@ -306,8 +306,8 @@ · 5 unmodified lines | ||
| 306 | 306 | interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>; |
| 307 | 307 | pinctrl-names = "default"; |
| 308 | 308 | pinctrl-0 = <&uart2_bus>; |
| 309 | − clocks = <&cmu_peri CLK_GOUT_UART2_EXT_UCLK>, | |
| 310 | − <&cmu_peri CLK_GOUT_UART2_PCLK>; | |
| 309 | + clocks = <&cmu_peri CLK_GOUT_UART2_PCLK>, | |
| 310 | + <&cmu_peri CLK_GOUT_UART2_EXT_UCLK>; | |
| 311 | 311 | clock-names = "uart", "clk_uart_baud0"; |
| 312 | 312 | samsung,uart-fifosize = <256>; |
| 313 | 313 | status = "disabled"; |
| @@ -79,7 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | }; |
| 80 | 80 | }; |
| 81 | 81 | |
| 82 | − soc { | |
| 82 | + soc@0 { | |
| 83 | 83 | compatible = "simple-bus"; |
| 84 | 84 | #address-cells = <1>; |
| 85 | 85 | #size-cells = <1>; |
| @@ -456,13 +456,11 @@ · 455 unmodified lines | ||
| 456 | 456 | clock-names = "clk_ahb", "clk_xin"; |
| 457 | 457 | mmc-ddr-1_8v; |
| 458 | 458 | mmc-hs200-1_8v; |
| 459 | − mmc-hs400-1_8v; | |
| 460 | 459 | ti,trm-icp = <0x2>; |
| 461 | 460 | ti,otap-del-sel-legacy = <0x0>; |
| 462 | 461 | ti,otap-del-sel-mmc-hs = <0x0>; |
| 463 | 462 | ti,otap-del-sel-ddr52 = <0x6>; |
| 464 | 463 | ti,otap-del-sel-hs200 = <0x7>; |
| 465 | − ti,otap-del-sel-hs400 = <0x4>; | |
| 466 | 464 | }; |
| 467 | 465 | |
| 468 | 466 | sdhci1: mmc@fa00000 { |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | ranges; |
| 34 | 34 | #interrupt-cells = <3>; |
| 35 | 35 | interrupt-controller; |
| 36 | − reg = <0x00 0x01800000 0x00 0x200000>, /* GICD */ | |
| 36 | + reg = <0x00 0x01800000 0x00 0x100000>, /* GICD */ | |
| 37 | 37 | <0x00 0x01900000 0x00 0x100000>, /* GICR */ |
| 38 | 38 | <0x00 0x6f000000 0x00 0x2000>, /* GICC */ |
| 39 | 39 | <0x00 0x6f010000 0x00 0x1000>, /* GICH */ |
| @@ -362,11 +362,6 @@ struct kvm_vcpu_arch { · 361 unmodified lines | ||
| 362 | 362 | struct arch_timer_cpu timer_cpu; |
| 363 | 363 | struct kvm_pmu pmu; |
| 364 | 364 | |
| 365 | − /* | |
| 366 | − * Anything that is not used directly from assembly code goes | |
| 367 | − * here. | |
| 368 | − */ | |
| 369 | − | |
| 370 | 365 | /* |
| 371 | 366 | * Guest registers we preserve during guest debugging. |
| 372 | 367 | * |
| @@ -113,6 +113,9 @@ static __always_inline bool has_vhe(void) · 112 unmodified lines | ||
| 113 | 113 | /* |
| 114 | 114 | * Code only run in VHE/NVHE hyp context can assume VHE is present or |
| 115 | 115 | * absent. Otherwise fall back to caps. |
| 116 | + * This allows the compiler to discard VHE-specific code from the | |
| 117 | + * nVHE object, reducing the number of external symbol references | |
| 118 | + * needed to link. | |
| 116 | 119 | */ |
| 117 | 120 | if (is_vhe_hyp_code()) |
| 118 | 121 | return true; |
| @@ -1974,15 +1974,7 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) · 1973 unmodified lines | ||
| 1974 | 1974 | #ifdef CONFIG_KVM |
| 1975 | 1975 | static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused) |
| 1976 | 1976 | { |
| 1977 | − if (kvm_get_mode() != KVM_MODE_PROTECTED) | |
| 1978 | − return false; | |
| 1979 | − | |
| 1980 | − if (is_kernel_in_hyp_mode()) { | |
| 1981 | − pr_warn("Protected KVM not available with VHE\n"); | |
| 1982 | − return false; | |
| 1983 | − } | |
| 1984 | − | |
| 1985 | − return true; | |
| 1977 | + return kvm_get_mode() == KVM_MODE_PROTECTED; | |
| 1986 | 1978 | } |
| 1987 | 1979 | #endif /* CONFIG_KVM */ |
| 1988 | 1980 | |
| @@ -3109,7 +3101,6 @@ void cpu_set_feature(unsigned int num) · 1120 unmodified lines | ||
| 3109 | 3101 | WARN_ON(num >= MAX_CPU_FEATURES); |
| 3110 | 3102 | elf_hwcap |= BIT(num); |
| 3111 | 3103 | } |
| 3112 | −EXPORT_SYMBOL_GPL(cpu_set_feature); | |
| 3113 | 3104 | |
| 3114 | 3105 | bool cpu_have_feature(unsigned int num) |
| 3115 | 3106 | { |
| @@ -102,7 +102,6 @@ SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) · 101 unmodified lines | ||
| 102 | 102 | * x19-x29 per the AAPCS, and we created frame records upon entry, so we need |
| 103 | 103 | * to restore x0-x8, x29, and x30. |
| 104 | 104 | */ |
| 105 | −ftrace_common_return: | |
| 106 | 105 | /* Restore function arguments */ |
| 107 | 106 | ldp x0, x1, [sp] |
| 108 | 107 | ldp x2, x3, [sp, #S_X2] |
| @@ -78,47 +78,76 @@ static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr) · 77 unmodified lines | ||
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | /* |
| 81 | − * Turn on the call to ftrace_caller() in instrumented function | |
| 81 | + * Find the address the callsite must branch to in order to reach '*addr'. | |
| 82 | + * | |
| 83 | + * Due to the limited range of 'BL' instructions, modules may be placed too far | |
| 84 | + * away to branch directly and must use a PLT. | |
| 85 | + * | |
| 86 | + * Returns true when '*addr' contains a reachable target address, or has been | |
| 87 | + * modified to contain a PLT address. Returns false otherwise. | |
| 82 | 88 | */ |
| 83 | −int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |
| 89 | +static bool ftrace_find_callable_addr(struct dyn_ftrace *rec, | |
| 90 | + struct module *mod, | |
| 91 | + unsigned long *addr) | |
| 84 | 92 | { |
| 85 | 93 | unsigned long pc = rec->ip; |
| 86 | − u32 old, new; | |
| 87 | − long offset = (long)pc - (long)addr; | |
| 94 | + long offset = (long)*addr - (long)pc; | |
| 95 | + struct plt_entry *plt; | |
| 88 | 96 | |
| 89 | − if (offset < -SZ_128M || offset >= SZ_128M) { | |
| 90 | − struct module *mod; | |
| 91 | − struct plt_entry *plt; | |
| 97 | + /* | |
| 98 | + * When the target is within range of the 'BL' instruction, use 'addr' | |
| 99 | + * as-is and branch to that directly. | |
| 100 | + */ | |
| 101 | + if (offset >= -SZ_128M && offset < SZ_128M) | |
| 102 | + return true; | |
| 92 | 103 | |
| 93 | − if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS)) | |
| 94 | − return -EINVAL; | |
| 104 | + /* | |
| 105 | + * When the target is outside of the range of a 'BL' instruction, we | |
| 106 | + * must use a PLT to reach it. We can only place PLTs for modules, and | |
| 107 | + * only when module PLT support is built-in. | |
| 108 | + */ | |
| 109 | + if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS)) | |
| 110 | + return false; | |
| 95 | 111 | |
| 96 | − /* | |
| 97 | − * On kernels that support module PLTs, the offset between the | |
| 98 | − * branch instruction and its target may legally exceed the | |
| 99 | − * range of an ordinary relative 'bl' opcode. In this case, we | |
| 100 | − * need to branch via a trampoline in the module. | |
| 101 | − * | |
| 102 | − * NOTE: __module_text_address() must be called with preemption | |
| 103 | − * disabled, but we can rely on ftrace_lock to ensure that 'mod' | |
| 104 | − * retains its validity throughout the remainder of this code. | |
| 105 | − */ | |
| 112 | + /* | |
| 113 | + * 'mod' is only set at module load time, but if we end up | |
| 114 | + * dealing with an out-of-range condition, we can assume it | |
| 115 | + * is due to a module being loaded far away from the kernel. | |
| 116 | + * | |
| 117 | + * NOTE: __module_text_address() must be called with preemption | |
| 118 | + * disabled, but we can rely on ftrace_lock to ensure that 'mod' | |
| 119 | + * retains its validity throughout the remainder of this code. | |
| 120 | + */ | |
| 121 | + if (!mod) { | |
| 106 | 122 | preempt_disable(); |
| 107 | 123 | mod = __module_text_address(pc); |
| 108 | 124 | preempt_enable(); |
| 125 | + } | |
| 109 | 126 | |
| 110 | − if (WARN_ON(!mod)) | |
| 111 | − return -EINVAL; | |
| 127 | + if (WARN_ON(!mod)) | |
| 128 | + return false; | |
| 112 | 129 | |
| 113 | − plt = get_ftrace_plt(mod, addr); | |
| 114 | − if (!plt) { | |
| 115 | − pr_err("ftrace: no module PLT for %ps\n", (void *)addr); | |
| 116 | − return -EINVAL; | |
| 117 | − } | |
| 118 | − | |
| 119 | − addr = (unsigned long)plt; | |
| 130 | + plt = get_ftrace_plt(mod, *addr); | |
| 131 | + if (!plt) { | |
| 132 | + pr_err("ftrace: no module PLT for %ps\n", (void *)*addr); | |
| 133 | + return false; | |
| 120 | 134 | } |
| 121 | 135 | |
| 136 | + *addr = (unsigned long)plt; | |
| 137 | + return true; | |
| 138 | +} | |
| 139 | + | |
| 140 | +/* | |
| 141 | + * Turn on the call to ftrace_caller() in instrumented function | |
| 142 | + */ | |
| 143 | +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |
| 144 | +{ | |
| 145 | + unsigned long pc = rec->ip; | |
| 146 | + u32 old, new; | |
| 147 | + | |
| 148 | + if (!ftrace_find_callable_addr(rec, NULL, &addr)) | |
| 149 | + return -EINVAL; | |
| 150 | + | |
| 122 | 151 | old = aarch64_insn_gen_nop(); |
| 123 | 152 | new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); |
| 124 | 153 | |
| @@ -132,6 +161,11 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, · 7 unmodified lines | ||
| 132 | 161 | unsigned long pc = rec->ip; |
| 133 | 162 | u32 old, new; |
| 134 | 163 | |
| 164 | + if (!ftrace_find_callable_addr(rec, NULL, &old_addr)) | |
| 165 | + return -EINVAL; | |
| 166 | + if (!ftrace_find_callable_addr(rec, NULL, &addr)) | |
| 167 | + return -EINVAL; | |
| 168 | + | |
| 135 | 169 | old = aarch64_insn_gen_branch_imm(pc, old_addr, |
| 136 | 170 | AARCH64_INSN_BRANCH_LINK); |
| 137 | 171 | new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); |
| @@ -181,54 +215,15 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, · 43 unmodified lines | ||
| 181 | 215 | unsigned long addr) |
| 182 | 216 | { |
| 183 | 217 | unsigned long pc = rec->ip; |
| 184 | − bool validate = true; | |
| 185 | 218 | u32 old = 0, new; |
| 186 | − long offset = (long)pc - (long)addr; | |
| 187 | 219 | |
| 188 | − if (offset < -SZ_128M || offset >= SZ_128M) { | |
| 189 | − u32 replaced; | |
| 190 | − | |
| 191 | − if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS)) | |
| 192 | − return -EINVAL; | |
| 193 | − | |
| 194 | − /* | |
| 195 | − * 'mod' is only set at module load time, but if we end up | |
| 196 | − * dealing with an out-of-range condition, we can assume it | |
| 197 | − * is due to a module being loaded far away from the kernel. | |
| 198 | − */ | |
| 199 | − if (!mod) { | |
| 200 | − preempt_disable(); | |
| 201 | − mod = __module_text_address(pc); | |
| 202 | − preempt_enable(); | |
| 203 | − | |
| 204 | − if (WARN_ON(!mod)) | |
| 205 | − return -EINVAL; | |
| 206 | − } | |
| 207 | − | |
| 208 | − /* | |
| 209 | − * The instruction we are about to patch may be a branch and | |
| 210 | − * link instruction that was redirected via a PLT entry. In | |
| 211 | − * this case, the normal validation will fail, but we can at | |
| 212 | − * least check that we are dealing with a branch and link | |
| 213 | − * instruction that points into the right module. | |
| 214 | − */ | |
| 215 | − if (aarch64_insn_read((void *)pc, &replaced)) | |
| 216 | − return -EFAULT; | |
| 217 | − | |
| 218 | − if (!aarch64_insn_is_bl(replaced) || | |
| 219 | − !within_module(pc + aarch64_get_branch_offset(replaced), | |
| 220 | − mod)) | |
| 221 | − return -EINVAL; | |
| 222 | − | |
| 223 | − validate = false; | |
| 224 | − } else { | |
| 225 | − old = aarch64_insn_gen_branch_imm(pc, addr, | |
| 226 | − AARCH64_INSN_BRANCH_LINK); | |
| 227 | − } | |
| 220 | + if (!ftrace_find_callable_addr(rec, mod, &addr)) | |
| 221 | + return -EINVAL; | |
| 228 | 222 | |
| 223 | + old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); | |
| 229 | 224 | new = aarch64_insn_gen_nop(); |
| 230 | 225 | |
| 231 | − return ftrace_modify_code(pc, old, new, validate); | |
| 226 | + return ftrace_modify_code(pc, old, new, true); | |
| 232 | 227 | } |
| 233 | 228 | |
| 234 | 229 | void arch_ftrace_update_code(int command) |
| @@ -303,14 +303,13 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) · 302 unmodified lines | ||
| 303 | 303 | early_fixmap_init(); |
| 304 | 304 | early_ioremap_init(); |
| 305 | 305 | |
| 306 | + setup_machine_fdt(__fdt_pointer); | |
| 307 | + | |
| 306 | 308 | /* |
| 307 | 309 | * Initialise the static keys early as they may be enabled by the |
| 308 | − * cpufeature code, early parameters, and DT setup. | |
| 310 | + * cpufeature code and early parameters. | |
| 309 | 311 | */ |
| 310 | 312 | jump_label_init(); |
| 311 | − | |
| 312 | − setup_machine_fdt(__fdt_pointer); | |
| 313 | − | |
| 314 | 313 | parse_early_param(); |
| 315 | 314 | |
| 316 | 315 | /* |
| @@ -1230,6 +1230,9 @@ bool kvm_arch_timer_get_input_level(int vintid) · 1229 unmodified lines | ||
| 1230 | 1230 | struct kvm_vcpu *vcpu = kvm_get_running_vcpu(); |
| 1231 | 1231 | struct arch_timer_context *timer; |
| 1232 | 1232 | |
| 1233 | + if (WARN(!vcpu, "No vcpu context!\n")) | |
| 1234 | + return false; | |
| 1235 | + | |
| 1233 | 1236 | if (vintid == vcpu_vtimer(vcpu)->irq.irq) |
| 1234 | 1237 | timer = vcpu_vtimer(vcpu); |
| 1235 | 1238 | else if (vintid == vcpu_ptimer(vcpu)->irq.irq) |
| @@ -150,8 +150,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 149 unmodified lines | ||
| 150 | 150 | if (ret) |
| 151 | 151 | goto out_free_stage2_pgd; |
| 152 | 152 | |
| 153 | − if (!zalloc_cpumask_var(&kvm->arch.supported_cpus, GFP_KERNEL)) | |
| 153 | + if (!zalloc_cpumask_var(&kvm->arch.supported_cpus, GFP_KERNEL)) { | |
| 154 | + ret = -ENOMEM; | |
| 154 | 155 | goto out_free_stage2_pgd; |
| 156 | + } | |
| 155 | 157 | cpumask_copy(kvm->arch.supported_cpus, cpu_possible_mask); |
| 156 | 158 | |
| 157 | 159 | kvm_vgic_early_init(kvm); |
| @@ -2110,11 +2112,11 @@ static int finalize_hyp_mode(void) · 1952 unmodified lines | ||
| 2110 | 2112 | return 0; |
| 2111 | 2113 | |
| 2112 | 2114 | /* |
| 2113 | − * Exclude HYP BSS from kmemleak so that it doesn't get peeked | |
| 2114 | − * at, which would end badly once the section is inaccessible. | |
| 2115 | − * None of other sections should ever be introspected. | |
| 2115 | + * Exclude HYP sections from kmemleak so that they don't get peeked | |
| 2116 | + * at, which would end badly once inaccessible. | |
| 2116 | 2117 | */ |
| 2117 | 2118 | kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); |
| 2119 | + kmemleak_free_part(__va(hyp_mem_base), hyp_mem_size); | |
| 2118 | 2120 | return pkvm_drop_host_privileges(); |
| 2119 | 2121 | } |
| 2120 | 2122 | |
| @@ -2271,7 +2273,11 @@ static int __init early_kvm_mode_cfg(char *arg) · 150 unmodified lines | ||
| 2271 | 2273 | return -EINVAL; |
| 2272 | 2274 | |
| 2273 | 2275 | if (strcmp(arg, "protected") == 0) { |
| 2274 | − kvm_mode = KVM_MODE_PROTECTED; | |
| 2276 | + if (!is_kernel_in_hyp_mode()) | |
| 2277 | + kvm_mode = KVM_MODE_PROTECTED; | |
| 2278 | + else | |
| 2279 | + pr_warn_once("Protected KVM not available with VHE\n"); | |
| 2280 | + | |
| 2275 | 2281 | return 0; |
| 2276 | 2282 | } |
| 2277 | 2283 | |
| @@ -80,6 +80,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu) · 79 unmodified lines | ||
| 80 | 80 | vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED; |
| 81 | 81 | vcpu->arch.flags |= KVM_ARM64_FP_HOST; |
| 82 | 82 | |
| 83 | + vcpu->arch.flags &= ~KVM_ARM64_HOST_SVE_ENABLED; | |
| 83 | 84 | if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN) |
| 84 | 85 | vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED; |
| 85 | 86 | |
| @@ -93,6 +94,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu) · 7 unmodified lines | ||
| 93 | 94 | * operations. Do this for ZA as well for now for simplicity. |
| 94 | 95 | */ |
| 95 | 96 | if (system_supports_sme()) { |
| 97 | + vcpu->arch.flags &= ~KVM_ARM64_HOST_SME_ENABLED; | |
| 96 | 98 | if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN) |
| 97 | 99 | vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED; |
| 98 | 100 | |
| @@ -314,15 +314,11 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) · 313 unmodified lines | ||
| 314 | 314 | int host_stage2_idmap_locked(phys_addr_t addr, u64 size, |
| 315 | 315 | enum kvm_pgtable_prot prot) |
| 316 | 316 | { |
| 317 | − hyp_assert_lock_held(&host_kvm.lock); | |
| 318 | − | |
| 319 | 317 | return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); |
| 320 | 318 | } |
| 321 | 319 | |
| 322 | 320 | int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) |
| 323 | 321 | { |
| 324 | − hyp_assert_lock_held(&host_kvm.lock); | |
| 325 | − | |
| 326 | 322 | return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, |
| 327 | 323 | addr, size, &host_s2_pool, owner_id); |
| 328 | 324 | } |
| @@ -243,15 +243,9 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id) · 242 unmodified lines | ||
| 243 | 243 | case SYS_ID_AA64MMFR2_EL1: |
| 244 | 244 | return get_pvm_id_aa64mmfr2(vcpu); |
| 245 | 245 | default: |
| 246 | − /* | |
| 247 | − * Should never happen because all cases are covered in | |
| 248 | − * pvm_sys_reg_descs[]. | |
| 249 | − */ | |
| 250 | − WARN_ON(1); | |
| 251 | − break; | |
| 246 | + /* Unhandled ID register, RAZ */ | |
| 247 | + return 0; | |
| 252 | 248 | } |
| 253 | − | |
| 254 | − return 0; | |
| 255 | 249 | } |
| 256 | 250 | |
| 257 | 251 | static u64 read_id_reg(const struct kvm_vcpu *vcpu, |
| @@ -332,6 +326,16 @@ static bool pvm_gic_read_sre(struct kvm_vcpu *vcpu, · 74 unmodified lines | ||
| 332 | 326 | /* Mark the specified system register as an AArch64 feature id register. */ |
| 333 | 327 | #define AARCH64(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch64 } |
| 334 | 328 | |
| 329 | +/* | |
| 330 | + * sys_reg_desc initialiser for architecturally unallocated cpufeature ID | |
| 331 | + * register with encoding Op0=3, Op1=0, CRn=0, CRm=crm, Op2=op2 | |
| 332 | + * (1 <= crm < 8, 0 <= Op2 < 8). | |
| 333 | + */ | |
| 334 | +#define ID_UNALLOCATED(crm, op2) { \ | |
| 335 | + Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2), \ | |
| 336 | + .access = pvm_access_id_aarch64, \ | |
| 337 | +} | |
| 338 | + | |
| 335 | 339 | /* Mark the specified system register as Read-As-Zero/Write-Ignored */ |
| 336 | 340 | #define RAZ_WI(REG) { SYS_DESC(REG), .access = pvm_access_raz_wi } |
| 337 | 341 | |
| @@ -375,24 +379,46 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = { · 37 unmodified lines | ||
| 375 | 379 | AARCH32(SYS_MVFR0_EL1), |
| 376 | 380 | AARCH32(SYS_MVFR1_EL1), |
| 377 | 381 | AARCH32(SYS_MVFR2_EL1), |
| 382 | + ID_UNALLOCATED(3,3), | |
| 378 | 383 | AARCH32(SYS_ID_PFR2_EL1), |
| 379 | 384 | AARCH32(SYS_ID_DFR1_EL1), |
| 380 | 385 | AARCH32(SYS_ID_MMFR5_EL1), |
| 386 | + ID_UNALLOCATED(3,7), | |
| 381 | 387 | |
| 382 | 388 | /* AArch64 ID registers */ |
| 383 | 389 | /* CRm=4 */ |
| 384 | 390 | AARCH64(SYS_ID_AA64PFR0_EL1), |
| 385 | 391 | AARCH64(SYS_ID_AA64PFR1_EL1), |
| 392 | + ID_UNALLOCATED(4,2), | |
| 393 | + ID_UNALLOCATED(4,3), | |
| 386 | 394 | AARCH64(SYS_ID_AA64ZFR0_EL1), |
| 395 | + ID_UNALLOCATED(4,5), | |
| 396 | + ID_UNALLOCATED(4,6), | |
| 397 | + ID_UNALLOCATED(4,7), | |
| 387 | 398 | AARCH64(SYS_ID_AA64DFR0_EL1), |
| 388 | 399 | AARCH64(SYS_ID_AA64DFR1_EL1), |
| 400 | + ID_UNALLOCATED(5,2), | |
| 401 | + ID_UNALLOCATED(5,3), | |
| 389 | 402 | AARCH64(SYS_ID_AA64AFR0_EL1), |
| 390 | 403 | AARCH64(SYS_ID_AA64AFR1_EL1), |
| 404 | + ID_UNALLOCATED(5,6), | |
| 405 | + ID_UNALLOCATED(5,7), | |
| 391 | 406 | AARCH64(SYS_ID_AA64ISAR0_EL1), |
| 392 | 407 | AARCH64(SYS_ID_AA64ISAR1_EL1), |
| 408 | + AARCH64(SYS_ID_AA64ISAR2_EL1), | |
| 409 | + ID_UNALLOCATED(6,3), | |
| 410 | + ID_UNALLOCATED(6,4), | |
| 411 | + ID_UNALLOCATED(6,5), | |
| 412 | + ID_UNALLOCATED(6,6), | |
| 413 | + ID_UNALLOCATED(6,7), | |
| 393 | 414 | AARCH64(SYS_ID_AA64MMFR0_EL1), |
| 394 | 415 | AARCH64(SYS_ID_AA64MMFR1_EL1), |
| 395 | 416 | AARCH64(SYS_ID_AA64MMFR2_EL1), |
| 417 | + ID_UNALLOCATED(7,3), | |
| 418 | + ID_UNALLOCATED(7,4), | |
| 419 | + ID_UNALLOCATED(7,5), | |
| 420 | + ID_UNALLOCATED(7,6), | |
| 421 | + ID_UNALLOCATED(7,7), | |
| 396 | 422 | |
| 397 | 423 | /* Scalable Vector Registers are restricted. */ |
| 398 | 424 | |
| @@ -429,11 +429,11 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = { · 428 unmodified lines | ||
| 429 | 429 | VGIC_ACCESS_32bit), |
| 430 | 430 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_SET, |
| 431 | 431 | vgic_mmio_read_pending, vgic_mmio_write_spending, |
| 432 | − NULL, vgic_uaccess_write_spending, 1, | |
| 432 | + vgic_uaccess_read_pending, vgic_uaccess_write_spending, 1, | |
| 433 | 433 | VGIC_ACCESS_32bit), |
| 434 | 434 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_CLEAR, |
| 435 | 435 | vgic_mmio_read_pending, vgic_mmio_write_cpending, |
| 436 | − NULL, vgic_uaccess_write_cpending, 1, | |
| 436 | + vgic_uaccess_read_pending, vgic_uaccess_write_cpending, 1, | |
| 437 | 437 | VGIC_ACCESS_32bit), |
| 438 | 438 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET, |
| 439 | 439 | vgic_mmio_read_active, vgic_mmio_write_sactive, |
| @@ -353,42 +353,6 @@ static unsigned long vgic_mmio_read_v3_idregs(struct kvm_vcpu *vcpu, · 352 unmodified lines | ||
| 353 | 353 | return 0; |
| 354 | 354 | } |
| 355 | 355 | |
| 356 | −static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu, | |
| 357 | − gpa_t addr, unsigned int len) | |
| 358 | −{ | |
| 359 | − u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | |
| 360 | − u32 value = 0; | |
| 361 | − int i; | |
| 362 | − | |
| 363 | − /* | |
| 364 | − * pending state of interrupt is latched in pending_latch variable. | |
| 365 | − * Userspace will save and restore pending state and line_level | |
| 366 | − * separately. | |
| 367 | − * Refer to Documentation/virt/kvm/devices/arm-vgic-v3.rst | |
| 368 | − * for handling of ISPENDR and ICPENDR. | |
| 369 | − */ | |
| 370 | − for (i = 0; i < len * 8; i++) { | |
| 371 | − struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); | |
| 372 | − bool state = irq->pending_latch; | |
| 373 | − | |
| 374 | − if (irq->hw && vgic_irq_is_sgi(irq->intid)) { | |
| 375 | − int err; | |
| 376 | − | |
| 377 | − err = irq_get_irqchip_state(irq->host_irq, | |
| 378 | − IRQCHIP_STATE_PENDING, | |
| 379 | − &state); | |
| 380 | − WARN_ON(err); | |
| 381 | − } | |
| 382 | − | |
| 383 | − if (state) | |
| 384 | − value |= (1U << i); | |
| 385 | − | |
| 386 | − vgic_put_irq(vcpu->kvm, irq); | |
| 387 | − } | |
| 388 | − | |
| 389 | − return value; | |
| 390 | −} | |
| 391 | − | |
| 392 | 356 | static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu, |
| 393 | 357 | gpa_t addr, unsigned int len, |
| 394 | 358 | unsigned long val) |
| @@ -666,7 +630,7 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = { · 271 unmodified lines | ||
| 666 | 630 | VGIC_ACCESS_32bit), |
| 667 | 631 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISPENDR, |
| 668 | 632 | vgic_mmio_read_pending, vgic_mmio_write_spending, |
| 669 | − vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 1, | |
| 633 | + vgic_uaccess_read_pending, vgic_v3_uaccess_write_pending, 1, | |
| 670 | 634 | VGIC_ACCESS_32bit), |
| 671 | 635 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICPENDR, |
| 672 | 636 | vgic_mmio_read_pending, vgic_mmio_write_cpending, |
| @@ -750,7 +714,7 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = { · 77 unmodified lines | ||
| 750 | 714 | VGIC_ACCESS_32bit), |
| 751 | 715 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISPENDR0, |
| 752 | 716 | vgic_mmio_read_pending, vgic_mmio_write_spending, |
| 753 | − vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4, | |
| 717 | + vgic_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4, | |
| 754 | 718 | VGIC_ACCESS_32bit), |
| 755 | 719 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICPENDR0, |
| 756 | 720 | vgic_mmio_read_pending, vgic_mmio_write_cpending, |
| @@ -226,8 +226,9 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, · 225 unmodified lines | ||
| 226 | 226 | return 0; |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | −unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, | |
| 230 | − gpa_t addr, unsigned int len) | |
| 229 | +static unsigned long __read_pending(struct kvm_vcpu *vcpu, | |
| 230 | + gpa_t addr, unsigned int len, | |
| 231 | + bool is_user) | |
| 231 | 232 | { |
| 232 | 233 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 233 | 234 | u32 value = 0; |
| @@ -239,6 +240,15 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 5 unmodified lines | ||
| 239 | 240 | unsigned long flags; |
| 240 | 241 | bool val; |
| 241 | 242 | |
| 243 | + /* | |
| 244 | + * When used from userspace with a GICv3 model: | |
| 245 | + * | |
| 246 | + * Pending state of interrupt is latched in pending_latch | |
| 247 | + * variable. Userspace will save and restore pending state | |
| 248 | + * and line_level separately. | |
| 249 | + * Refer to Documentation/virt/kvm/devices/arm-vgic-v3.rst | |
| 250 | + * for handling of ISPENDR and ICPENDR. | |
| 251 | + */ | |
| 242 | 252 | raw_spin_lock_irqsave(&irq->irq_lock, flags); |
| 243 | 253 | if (irq->hw && vgic_irq_is_sgi(irq->intid)) { |
| 244 | 254 | int err; |
| @@ -248,10 +258,20 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 3 unmodified lines | ||
| 248 | 258 | IRQCHIP_STATE_PENDING, |
| 249 | 259 | &val); |
| 250 | 260 | WARN_RATELIMIT(err, "IRQ %d", irq->host_irq); |
| 251 | − } else if (vgic_irq_is_mapped_level(irq)) { | |
| 261 | + } else if (!is_user && vgic_irq_is_mapped_level(irq)) { | |
| 252 | 262 | val = vgic_get_phys_line_level(irq); |
| 253 | 263 | } else { |
| 254 | − val = irq_is_pending(irq); | |
| 264 | + switch (vcpu->kvm->arch.vgic.vgic_model) { | |
| 265 | + case KVM_DEV_TYPE_ARM_VGIC_V3: | |
| 266 | + if (is_user) { | |
| 267 | + val = irq->pending_latch; | |
| 268 | + break; | |
| 269 | + } | |
| 270 | + fallthrough; | |
| 271 | + default: | |
| 272 | + val = irq_is_pending(irq); | |
| 273 | + break; | |
| 274 | + } | |
| 255 | 275 | } |
| 256 | 276 | |
| 257 | 277 | value |= ((u32)val << i); |
| @@ -263,6 +283,18 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 5 unmodified lines | ||
| 263 | 283 | return value; |
| 264 | 284 | } |
| 265 | 285 | |
| 286 | +unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, | |
| 287 | + gpa_t addr, unsigned int len) | |
| 288 | +{ | |
| 289 | + return __read_pending(vcpu, addr, len, false); | |
| 290 | +} | |
| 291 | + | |
| 292 | +unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu, | |
| 293 | + gpa_t addr, unsigned int len) | |
| 294 | +{ | |
| 295 | + return __read_pending(vcpu, addr, len, true); | |
| 296 | +} | |
| 297 | + | |
| 266 | 298 | static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq) |
| 267 | 299 | { |
| 268 | 300 | return (vgic_irq_is_sgi(irq->intid) && |
| @@ -149,6 +149,9 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, · 148 unmodified lines | ||
| 149 | 149 | unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, |
| 150 | 150 | gpa_t addr, unsigned int len); |
| 151 | 151 | |
| 152 | +unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu, | |
| 153 | + gpa_t addr, unsigned int len); | |
| 154 | + | |
| 152 | 155 | void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, |
| 153 | 156 | gpa_t addr, unsigned int len, |
| 154 | 157 | unsigned long val); |
| @@ -66,7 +66,7 @@ static void flush_context(void) · 65 unmodified lines | ||
| 66 | 66 | * the next context-switch, we broadcast TLB flush + I-cache |
| 67 | 67 | * invalidation over the inner shareable domain on rollover. |
| 68 | 68 | */ |
| 69 | − kvm_call_hyp(__kvm_flush_vm_context); | |
| 69 | + kvm_call_hyp(__kvm_flush_vm_context); | |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | static bool check_update_reserved_vmid(u64 vmid, u64 newvmid) |
| @@ -218,8 +218,6 @@ SYM_FUNC_ALIAS(__dma_flush_area, __pi___dma_flush_area) · 217 unmodified lines | ||
| 218 | 218 | */ |
| 219 | 219 | SYM_FUNC_START(__pi___dma_map_area) |
| 220 | 220 | add x1, x0, x1 |
| 221 | − cmp w2, #DMA_FROM_DEVICE | |
| 222 | − b.eq __pi_dcache_inval_poc | |
| 223 | 221 | b __pi_dcache_clean_poc |
| 224 | 222 | SYM_FUNC_END(__pi___dma_map_area) |
| 225 | 223 | SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area) |
| @@ -12,10 +12,9 @@ static inline unsigned long exception_era(struct pt_regs *regs) · 11 unmodified lines | ||
| 12 | 12 | return regs->csr_era; |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | −static inline int compute_return_era(struct pt_regs *regs) | |
| 15 | +static inline void compute_return_era(struct pt_regs *regs) | |
| 16 | 16 | { |
| 17 | 17 | regs->csr_era += 4; |
| 18 | − return 0; | |
| 19 | 18 | } |
| 20 | 19 | |
| 21 | 20 | #endif /* _ASM_BRANCH_H */ |
| @@ -426,6 +426,11 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, · 425 unmodified lines | ||
| 426 | 426 | |
| 427 | 427 | #define kern_addr_valid(addr) (1) |
| 428 | 428 | |
| 429 | +static inline unsigned long pmd_pfn(pmd_t pmd) | |
| 430 | +{ | |
| 431 | + return (pmd_val(pmd) & _PFN_MASK) >> _PFN_SHIFT; | |
| 432 | +} | |
| 433 | + | |
| 429 | 434 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 430 | 435 | |
| 431 | 436 | /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/ |
| @@ -497,11 +502,6 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) · 65 unmodified lines | ||
| 497 | 502 | return pmd; |
| 498 | 503 | } |
| 499 | 504 | |
| 500 | −static inline unsigned long pmd_pfn(pmd_t pmd) | |
| 501 | −{ | |
| 502 | − return (pmd_val(pmd) & _PFN_MASK) >> _PFN_SHIFT; | |
| 503 | −} | |
| 504 | − | |
| 505 | 505 | static inline struct page *pmd_page(pmd_t pmd) |
| 506 | 506 | { |
| 507 | 507 | if (pmd_trans_huge(pmd)) |
| @@ -263,7 +263,7 @@ void cpu_probe(void) · 262 unmodified lines | ||
| 263 | 263 | |
| 264 | 264 | c->cputype = CPU_UNKNOWN; |
| 265 | 265 | c->processor_id = read_cpucfg(LOONGARCH_CPUCFG0); |
| 266 | − c->fpu_vers = (read_cpucfg(LOONGARCH_CPUCFG2) >> 3) & 0x3; | |
| 266 | + c->fpu_vers = (read_cpucfg(LOONGARCH_CPUCFG2) & CPUCFG2_FPVERS) >> 3; | |
| 267 | 267 | |
| 268 | 268 | c->fpu_csr0 = FPU_CSR_RN; |
| 269 | 269 | c->fpu_mask = FPU_CSR_RSVD; |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | __REF |
| 16 | 16 | |
| 17 | −SYM_ENTRY(_stext, SYM_L_GLOBAL, SYM_A_NONE) | |
| 18 | − | |
| 19 | 17 | SYM_CODE_START(kernel_entry) # kernel entry point |
| 20 | 18 | |
| 21 | 19 | /* Config direct window and set PG */ |
| @@ -475,8 +475,7 @@ asmlinkage void noinstr do_ri(struct pt_regs *regs) · 474 unmodified lines | ||
| 475 | 475 | |
| 476 | 476 | die_if_kernel("Reserved instruction in kernel code", regs); |
| 477 | 477 | |
| 478 | − if (unlikely(compute_return_era(regs) < 0)) | |
| 479 | − goto out; | |
| 478 | + compute_return_era(regs); | |
| 480 | 479 | |
| 481 | 480 | if (unlikely(get_user(opcode, era) < 0)) { |
| 482 | 481 | status = SIGSEGV; |
| @@ -37,6 +37,7 @@ SECTIONS · 36 unmodified lines | ||
| 37 | 37 | HEAD_TEXT_SECTION |
| 38 | 38 | |
| 39 | 39 | . = ALIGN(PECOFF_SEGMENT_ALIGN); |
| 40 | + _stext = .; | |
| 40 | 41 | .text : { |
| 41 | 42 | TEXT_TEXT |
| 42 | 43 | SCHED_TEXT |
| @@ -101,6 +102,7 @@ SECTIONS · 58 unmodified lines | ||
| 101 | 102 | |
| 102 | 103 | STABS_DEBUG |
| 103 | 104 | DWARF_DEBUG |
| 105 | + ELF_DETAILS | |
| 104 | 106 | |
| 105 | 107 | .gptab.sdata : { |
| 106 | 108 | *(.gptab.data) |
| @@ -281,15 +281,16 @@ void setup_tlb_handler(int cpu) · 280 unmodified lines | ||
| 281 | 281 | if (pcpu_handlers[cpu]) |
| 282 | 282 | return; |
| 283 | 283 | |
| 284 | − page = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, get_order(vec_sz)); | |
| 284 | + page = alloc_pages_node(cpu_to_node(cpu), GFP_ATOMIC, get_order(vec_sz)); | |
| 285 | 285 | if (!page) |
| 286 | 286 | return; |
| 287 | 287 | |
| 288 | 288 | addr = page_address(page); |
| 289 | − pcpu_handlers[cpu] = virt_to_phys(addr); | |
| 289 | + pcpu_handlers[cpu] = (unsigned long)addr; | |
| 290 | 290 | memcpy((void *)addr, (void *)eentry, vec_sz); |
| 291 | 291 | local_flush_icache_range((unsigned long)addr, (unsigned long)addr + vec_sz); |
| 292 | − csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_TLBRENTRY); | |
| 292 | + csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY); | |
| 293 | + csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY); | |
| 293 | 294 | csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY); |
| 294 | 295 | } |
| 295 | 296 | #endif |
| @@ -111,8 +111,9 @@ · 110 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | clocks = <&cgu X1000_CLK_RTCLK>, |
| 113 | 113 | <&cgu X1000_CLK_EXCLK>, |
| 114 | − <&cgu X1000_CLK_PCLK>; | |
| 115 | − clock-names = "rtc", "ext", "pclk"; | |
| 114 | + <&cgu X1000_CLK_PCLK>, | |
| 115 | + <&cgu X1000_CLK_TCU>; | |
| 116 | + clock-names = "rtc", "ext", "pclk", "tcu"; | |
| 116 | 117 | |
| 117 | 118 | interrupt-controller; |
| 118 | 119 | #interrupt-cells = <1>; |
| @@ -104,8 +104,9 @@ · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | clocks = <&cgu X1830_CLK_RTCLK>, |
| 106 | 106 | <&cgu X1830_CLK_EXCLK>, |
| 107 | − <&cgu X1830_CLK_PCLK>; | |
| 108 | − clock-names = "rtc", "ext", "pclk"; | |
| 107 | + <&cgu X1830_CLK_PCLK>, | |
| 108 | + <&cgu X1830_CLK_TCU>; | |
| 109 | + clock-names = "rtc", "ext", "pclk", "tcu"; | |
| 109 | 110 | |
| 110 | 111 | interrupt-controller; |
| 111 | 112 | #interrupt-cells = <1>; |
| @@ -44,6 +44,7 @@ static __init unsigned int ranchu_measure_hpt_freq(void) · 43 unmodified lines | ||
| 44 | 44 | __func__); |
| 45 | 45 | |
| 46 | 46 | rtc_base = of_iomap(np, 0); |
| 47 | + of_node_put(np); | |
| 47 | 48 | if (!rtc_base) |
| 48 | 49 | panic("%s(): Failed to ioremap Goldfish RTC base!", __func__); |
| 49 | 50 | |
| @@ -208,6 +208,12 @@ void __init ltq_soc_init(void) · 207 unmodified lines | ||
| 208 | 208 | of_address_to_resource(np_sysgpe, 0, &res_sys[2])) |
| 209 | 209 | panic("Failed to get core resources"); |
| 210 | 210 | |
| 211 | + of_node_put(np_status); | |
| 212 | + of_node_put(np_ebu); | |
| 213 | + of_node_put(np_sys1); | |
| 214 | + of_node_put(np_syseth); | |
| 215 | + of_node_put(np_sysgpe); | |
| 216 | + | |
| 211 | 217 | if ((request_mem_region(res_status.start, resource_size(&res_status), |
| 212 | 218 | res_status.name) < 0) || |
| 213 | 219 | (request_mem_region(res_ebu.start, resource_size(&res_ebu), |
| @@ -408,6 +408,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) · 407 unmodified lines | ||
| 408 | 408 | if (!ltq_eiu_membase) |
| 409 | 409 | panic("Failed to remap eiu memory"); |
| 410 | 410 | } |
| 411 | + of_node_put(eiu_node); | |
| 411 | 412 | |
| 412 | 413 | return 0; |
| 413 | 414 | } |
| @@ -441,6 +441,10 @@ void __init ltq_soc_init(void) · 440 unmodified lines | ||
| 441 | 441 | of_address_to_resource(np_ebu, 0, &res_ebu)) |
| 442 | 442 | panic("Failed to get core resources"); |
| 443 | 443 | |
| 444 | + of_node_put(np_pmu); | |
| 445 | + of_node_put(np_cgu); | |
| 446 | + of_node_put(np_ebu); | |
| 447 | + | |
| 444 | 448 | if (!request_mem_region(res_pmu.start, resource_size(&res_pmu), |
| 445 | 449 | res_pmu.name) || |
| 446 | 450 | !request_mem_region(res_cgu.start, resource_size(&res_cgu), |
| @@ -214,6 +214,8 @@ static void update_gic_frequency_dt(void) · 213 unmodified lines | ||
| 214 | 214 | |
| 215 | 215 | if (of_update_property(node, &gic_frequency_prop) < 0) |
| 216 | 216 | pr_err("error updating gic frequency property\n"); |
| 217 | + | |
| 218 | + of_node_put(node); | |
| 217 | 219 | } |
| 218 | 220 | |
| 219 | 221 | #endif |
| @@ -98,13 +98,18 @@ static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup) · 97 unmodified lines | ||
| 98 | 98 | np = of_find_compatible_node(NULL, NULL, lookup->compatible); |
| 99 | 99 | if (np) { |
| 100 | 100 | lookup->name = (char *)np->name; |
| 101 | − if (lookup->phys_addr) | |
| 101 | + if (lookup->phys_addr) { | |
| 102 | + of_node_put(np); | |
| 102 | 103 | continue; |
| 104 | + } | |
| 103 | 105 | if (!of_address_to_resource(np, 0, &res)) |
| 104 | 106 | lookup->phys_addr = res.start; |
| 107 | + of_node_put(np); | |
| 105 | 108 | } |
| 106 | 109 | } |
| 107 | 110 | |
| 111 | + of_node_put(root); | |
| 112 | + | |
| 108 | 113 | return 0; |
| 109 | 114 | } |
| 110 | 115 | |
| @@ -32,6 +32,9 @@ static unsigned int pic32_xlate_core_timer_irq(void) · 31 unmodified lines | ||
| 32 | 32 | goto default_map; |
| 33 | 33 | |
| 34 | 34 | irq = irq_of_parse_and_map(node, 0); |
| 35 | + | |
| 36 | + of_node_put(node); | |
| 37 | + | |
| 35 | 38 | if (!irq) |
| 36 | 39 | goto default_map; |
| 37 | 40 | |
| @@ -40,6 +40,8 @@ __iomem void *plat_of_remap_node(const char *node) · 39 unmodified lines | ||
| 40 | 40 | if (of_address_to_resource(np, 0, &res)) |
| 41 | 41 | panic("Failed to get resource for %s", node); |
| 42 | 42 | |
| 43 | + of_node_put(np); | |
| 44 | + | |
| 43 | 45 | if (!request_mem_region(res.start, |
| 44 | 46 | resource_size(&res), |
| 45 | 47 | res.name)) |
| @@ -640,8 +640,6 @@ static int icu_get_irq(unsigned int irq) · 639 unmodified lines | ||
| 640 | 640 | |
| 641 | 641 | printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); |
| 642 | 642 | |
| 643 | − atomic_inc(&irq_err_count); | |
| 644 | − | |
| 645 | 643 | return -1; |
| 646 | 644 | } |
| 647 | 645 | |
| @@ -10,6 +10,7 @@ config PARISC · 9 unmodified lines | ||
| 10 | 10 | select ARCH_WANT_FRAME_POINTERS |
| 11 | 11 | select ARCH_HAS_ELF_RANDOMIZE |
| 12 | 12 | select ARCH_HAS_STRICT_KERNEL_RWX |
| 13 | + select ARCH_HAS_STRICT_MODULE_RWX | |
| 13 | 14 | select ARCH_HAS_UBSAN_SANITIZE_ALL |
| 14 | 15 | select ARCH_HAS_PTE_SPECIAL |
| 15 | 16 | select ARCH_NO_SG_CHAIN |
| @@ -12,7 +12,7 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, · 11 unmodified lines | ||
| 12 | 12 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | −#if defined(CONFIG_STI_CONSOLE) || defined(CONFIG_FB_STI) | |
| 15 | +#if defined(CONFIG_FB_STI) | |
| 16 | 16 | int fb_is_primary_device(struct fb_info *info); |
| 17 | 17 | #else |
| 18 | 18 | static inline int fb_is_primary_device(struct fb_info *info) |
| @@ -722,7 +722,10 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned lon · 721 unmodified lines | ||
| 722 | 722 | return; |
| 723 | 723 | |
| 724 | 724 | if (parisc_requires_coherency()) { |
| 725 | − flush_user_cache_page(vma, vmaddr); | |
| 725 | + if (vma->vm_flags & VM_SHARED) | |
| 726 | + flush_data_cache(); | |
| 727 | + else | |
| 728 | + flush_user_cache_page(vma, vmaddr); | |
| 726 | 729 | return; |
| 727 | 730 | } |
| 728 | 731 | |
| @@ -102,7 +102,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[]) · 101 unmodified lines | ||
| 102 | 102 | * that happen. Want to keep this overhead low, but still provide |
| 103 | 103 | * some information to the customer. All exits from this routine |
| 104 | 104 | * need to restore Fpu_register[0] |
| 105 | − */ | |
| 105 | + */ | |
| 106 | 106 | |
| 107 | 107 | bflags=(Fpu_register[0] & 0xf8000000); |
| 108 | 108 | Fpu_register[0] &= 0x07ffffff; |
| @@ -1855,7 +1855,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) · 1854 unmodified lines | ||
| 1855 | 1855 | tm_reclaim_current(0); |
| 1856 | 1856 | #endif |
| 1857 | 1857 | |
| 1858 | − memset(regs->gpr, 0, sizeof(regs->gpr)); | |
| 1858 | + memset(®s->gpr[1], 0, sizeof(regs->gpr) - sizeof(regs->gpr[0])); | |
| 1859 | 1859 | regs->ctr = 0; |
| 1860 | 1860 | regs->link = 0; |
| 1861 | 1861 | regs->xer = 0; |
| @@ -2302,7 +2302,7 @@ static void __init prom_init_stdout(void) · 2301 unmodified lines | ||
| 2302 | 2302 | |
| 2303 | 2303 | static int __init prom_find_machine_type(void) |
| 2304 | 2304 | { |
| 2305 | − char compat[256]; | |
| 2305 | + static char compat[256] __prombss; | |
| 2306 | 2306 | int len, i = 0; |
| 2307 | 2307 | #ifdef CONFIG_PPC64 |
| 2308 | 2308 | phandle rtas; |
| @@ -1071,7 +1071,7 @@ static struct rtas_filter rtas_filters[] __ro_after_init = { · 1070 unmodified lines | ||
| 1071 | 1071 | { "get-time-of-day", -1, -1, -1, -1, -1 }, |
| 1072 | 1072 | { "ibm,get-vpd", -1, 0, -1, 1, 2 }, |
| 1073 | 1073 | { "ibm,lpar-perftools", -1, 2, 3, -1, -1 }, |
| 1074 | − { "ibm,platform-dump", -1, 4, 5, -1, -1 }, | |
| 1074 | + { "ibm,platform-dump", -1, 4, 5, -1, -1 }, /* Special cased */ | |
| 1075 | 1075 | { "ibm,read-slot-reset-state", -1, -1, -1, -1, -1 }, |
| 1076 | 1076 | { "ibm,scan-log-dump", -1, 0, 1, -1, -1 }, |
| 1077 | 1077 | { "ibm,set-dynamic-indicator", -1, 2, -1, -1, -1 }, |
| @@ -1120,6 +1120,15 @@ static bool block_rtas_call(int token, int nargs, · 42 unmodified lines | ||
| 1120 | 1120 | size = 1; |
| 1121 | 1121 | |
| 1122 | 1122 | end = base + size - 1; |
| 1123 | + | |
| 1124 | + /* | |
| 1125 | + * Special case for ibm,platform-dump - NULL buffer | |
| 1126 | + * address is used to indicate end of dump processing | |
| 1127 | + */ | |
| 1128 | + if (!strcmp(f->name, "ibm,platform-dump") && | |
| 1129 | + base == 0) | |
| 1130 | + return false; | |
| 1131 | + | |
| 1123 | 1132 | if (!in_rmo_buf(base, end)) |
| 1124 | 1133 | goto err; |
| 1125 | 1134 | } |
| @@ -935,12 +935,6 @@ void __init setup_arch(char **cmdline_p) · 934 unmodified lines | ||
| 935 | 935 | /* Print various info about the machine that has been gathered so far. */ |
| 936 | 936 | print_system_info(); |
| 937 | 937 | |
| 938 | − /* Reserve large chunks of memory for use by CMA for KVM. */ | |
| 939 | − kvm_cma_reserve(); | |
| 940 | − | |
| 941 | − /* Reserve large chunks of memory for us by CMA for hugetlb */ | |
| 942 | − gigantic_hugetlb_cma_reserve(); | |
| 943 | − | |
| 944 | 938 | klp_init_thread_info(&init_task); |
| 945 | 939 | |
| 946 | 940 | setup_initial_init_mm(_stext, _etext, _edata, _end); |
| @@ -955,6 +949,13 @@ void __init setup_arch(char **cmdline_p) · 8 unmodified lines | ||
| 955 | 949 | |
| 956 | 950 | initmem_init(); |
| 957 | 951 | |
| 952 | + /* | |
| 953 | + * Reserve large chunks of memory for use by CMA for KVM and hugetlb. These must | |
| 954 | + * be called after initmem_init(), so that pageblock_order is initialised. | |
| 955 | + */ | |
| 956 | + kvm_cma_reserve(); | |
| 957 | + gigantic_hugetlb_cma_reserve(); | |
| 958 | + | |
| 958 | 959 | early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); |
| 959 | 960 | |
| 960 | 961 | if (ppc_md.setup_arch) |
| @@ -0,0 +1,7 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef _MICROWATT_H | |
| 3 | +#define _MICROWATT_H | |
| 4 | + | |
| 5 | +void microwatt_rng_init(void); | |
| 6 | + | |
| 7 | +#endif /* _MICROWATT_H */ | |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <asm/archrandom.h> |
| 12 | 12 | #include <asm/cputable.h> |
| 13 | 13 | #include <asm/machdep.h> |
| 14 | +#include "microwatt.h" | |
| 14 | 15 | |
| 15 | 16 | #define DARN_ERR 0xFFFFFFFFFFFFFFFFul |
| 16 | 17 | |
| @@ -29,7 +30,7 @@ static int microwatt_get_random_darn(unsigned long *v) · 12 unmodified lines | ||
| 29 | 30 | return 1; |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | −static __init int rng_init(void) | |
| 33 | +void __init microwatt_rng_init(void) | |
| 33 | 34 | { |
| 34 | 35 | unsigned long val; |
| 35 | 36 | int i; |
| @@ -37,12 +38,7 @@ static __init int rng_init(void) · 1 unmodified line | ||
| 37 | 38 | for (i = 0; i < 10; i++) { |
| 38 | 39 | if (microwatt_get_random_darn(&val)) { |
| 39 | 40 | ppc_md.get_random_seed = microwatt_get_random_darn; |
| 40 | − return 0; | |
| 41 | + return; | |
| 41 | 42 | } |
| 42 | 43 | } |
| 43 | − | |
| 44 | − pr_warn("Unable to use DARN for get_random_seed()\n"); | |
| 45 | − | |
| 46 | − return -EIO; | |
| 47 | 44 | } |
| 48 | −machine_subsys_initcall(, rng_init); | |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/xics.h> |
| 17 | 17 | #include <asm/udbg.h> |
| 18 | 18 | |
| 19 | +#include "microwatt.h" | |
| 20 | + | |
| 19 | 21 | static void __init microwatt_init_IRQ(void) |
| 20 | 22 | { |
| 21 | 23 | xics_init(); |
| @@ -32,10 +34,16 @@ static int __init microwatt_populate(void) · 10 unmodified lines | ||
| 32 | 34 | } |
| 33 | 35 | machine_arch_initcall(microwatt, microwatt_populate); |
| 34 | 36 | |
| 37 | +static void __init microwatt_setup_arch(void) | |
| 38 | +{ | |
| 39 | + microwatt_rng_init(); | |
| 40 | +} | |
| 41 | + | |
| 35 | 42 | define_machine(microwatt) { |
| 36 | 43 | .name = "microwatt", |
| 37 | 44 | .probe = microwatt_probe, |
| 38 | 45 | .init_IRQ = microwatt_init_IRQ, |
| 46 | + .setup_arch = microwatt_setup_arch, | |
| 39 | 47 | .progress = udbg_progress, |
| 40 | 48 | .calibrate_decr = generic_calibrate_decr, |
| 41 | 49 | }; |
| @@ -42,4 +42,6 @@ ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos, size_t count); · 41 unmodified lines | ||
| 42 | 42 | u32 __init memcons_get_size(struct memcons *mc); |
| 43 | 43 | struct memcons *__init memcons_init(struct device_node *node, const char *mc_prop_name); |
| 44 | 44 | |
| 45 | +void pnv_rng_init(void); | |
| 46 | + | |
| 45 | 47 | #endif /* _POWERNV_H */ |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <asm/prom.h> |
| 18 | 18 | #include <asm/machdep.h> |
| 19 | 19 | #include <asm/smp.h> |
| 20 | +#include "powernv.h" | |
| 20 | 21 | |
| 21 | 22 | #define DARN_ERR 0xFFFFFFFFFFFFFFFFul |
| 22 | 23 | |
| @@ -28,7 +29,6 @@ struct powernv_rng { · 5 unmodified lines | ||
| 28 | 29 | |
| 29 | 30 | static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); |
| 30 | 31 | |
| 31 | − | |
| 32 | 32 | int powernv_hwrng_present(void) |
| 33 | 33 | { |
| 34 | 34 | struct powernv_rng *rng; |
| @@ -98,9 +98,6 @@ static int __init initialise_darn(void) · 63 unmodified lines | ||
| 98 | 98 | return 0; |
| 99 | 99 | } |
| 100 | 100 | } |
| 101 | − | |
| 102 | − pr_warn("Unable to use DARN for get_random_seed()\n"); | |
| 103 | − | |
| 104 | 101 | return -EIO; |
| 105 | 102 | } |
| 106 | 103 | |
| @@ -163,32 +160,55 @@ static __init int rng_create(struct device_node *dn) · 56 unmodified lines | ||
| 163 | 160 | |
| 164 | 161 | rng_init_per_cpu(rng, dn); |
| 165 | 162 | |
| 166 | − pr_info_once("Registering arch random hook.\n"); | |
| 167 | − | |
| 168 | 163 | ppc_md.get_random_seed = powernv_get_random_long; |
| 169 | 164 | |
| 170 | 165 | return 0; |
| 171 | 166 | } |
| 172 | 167 | |
| 173 | −static __init int rng_init(void) | |
| 168 | +static int __init pnv_get_random_long_early(unsigned long *v) | |
| 174 | 169 | { |
| 175 | 170 | struct device_node *dn; |
| 176 | − int rc; | |
| 171 | + | |
| 172 | + if (!slab_is_available()) | |
| 173 | + return 0; | |
| 174 | + | |
| 175 | + if (cmpxchg(&ppc_md.get_random_seed, pnv_get_random_long_early, | |
| 176 | + NULL) != pnv_get_random_long_early) | |
| 177 | + return 0; | |
| 177 | 178 | |
| 178 | 179 | for_each_compatible_node(dn, NULL, "ibm,power-rng") { |
| 179 | − rc = rng_create(dn); | |
| 180 | − if (rc) { | |
| 181 | − pr_err("Failed creating rng for %pOF (%d).\n", | |
| 182 | − dn, rc); | |
| 180 | + if (rng_create(dn)) | |
| 183 | 181 | continue; |
| 184 | − } | |
| 185 | − | |
| 186 | 182 | /* Create devices for hwrng driver */ |
| 187 | 183 | of_platform_device_create(dn, NULL, NULL); |
| 188 | 184 | } |
| 189 | 185 | |
| 190 | − initialise_darn(); | |
| 186 | + if (!ppc_md.get_random_seed) | |
| 187 | + return 0; | |
| 188 | + return ppc_md.get_random_seed(v); | |
| 189 | +} | |
| 190 | + | |
| 191 | +void __init pnv_rng_init(void) | |
| 192 | +{ | |
| 193 | + struct device_node *dn; | |
| 191 | 194 | |
| 195 | + /* Prefer darn over the rest. */ | |
| 196 | + if (!initialise_darn()) | |
| 197 | + return; | |
| 198 | + | |
| 199 | + dn = of_find_compatible_node(NULL, NULL, "ibm,power-rng"); | |
| 200 | + if (dn) | |
| 201 | + ppc_md.get_random_seed = pnv_get_random_long_early; | |
| 202 | + | |
| 203 | + of_node_put(dn); | |
| 204 | +} | |
| 205 | + | |
| 206 | +static int __init pnv_rng_late_init(void) | |
| 207 | +{ | |
| 208 | + unsigned long v; | |
| 209 | + /* In case it wasn't called during init for some other reason. */ | |
| 210 | + if (ppc_md.get_random_seed == pnv_get_random_long_early) | |
| 211 | + pnv_get_random_long_early(&v); | |
| 192 | 212 | return 0; |
| 193 | 213 | } |
| 194 | −machine_subsys_initcall(powernv, rng_init); | |
| 214 | +machine_subsys_initcall(powernv, pnv_rng_late_init); | |
| @@ -203,6 +203,8 @@ static void __init pnv_setup_arch(void) · 202 unmodified lines | ||
| 203 | 203 | pnv_check_guarded_cores(); |
| 204 | 204 | |
| 205 | 205 | /* XXX PMCS */ |
| 206 | + | |
| 207 | + pnv_rng_init(); | |
| 206 | 208 | } |
| 207 | 209 | |
| 208 | 210 | static void __init pnv_init(void) |
| @@ -122,4 +122,6 @@ void pseries_lpar_read_hblkrm_characteristics(void); · 121 unmodified lines | ||
| 122 | 122 | static inline void pseries_lpar_read_hblkrm_characteristics(void) { } |
| 123 | 123 | #endif |
| 124 | 124 | |
| 125 | +void pseries_rng_init(void); | |
| 126 | + | |
| 125 | 127 | #endif /* _PSERIES_PSERIES_H */ |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/archrandom.h> |
| 11 | 11 | #include <asm/machdep.h> |
| 12 | 12 | #include <asm/plpar_wrappers.h> |
| 13 | +#include "pseries.h" | |
| 13 | 14 | |
| 14 | 15 | |
| 15 | 16 | static int pseries_get_random_long(unsigned long *v) |
| @@ -24,19 +25,13 @@ static int pseries_get_random_long(unsigned long *v) · 8 unmodified lines | ||
| 24 | 25 | return 0; |
| 25 | 26 | } |
| 26 | 27 | |
| 27 | −static __init int rng_init(void) | |
| 28 | +void __init pseries_rng_init(void) | |
| 28 | 29 | { |
| 29 | 30 | struct device_node *dn; |
| 30 | 31 | |
| 31 | 32 | dn = of_find_compatible_node(NULL, NULL, "ibm,random"); |
| 32 | 33 | if (!dn) |
| 33 | − return -ENODEV; | |
| 34 | − | |
| 35 | − pr_info("Registering arch random hook.\n"); | |
| 36 | − | |
| 34 | + return; | |
| 37 | 35 | ppc_md.get_random_seed = pseries_get_random_long; |
| 38 | − | |
| 39 | 36 | of_node_put(dn); |
| 40 | − return 0; | |
| 41 | 37 | } |
| 42 | −machine_subsys_initcall(pseries, rng_init); | |
| @@ -839,6 +839,7 @@ static void __init pSeries_setup_arch(void) · 838 unmodified lines | ||
| 839 | 839 | } |
| 840 | 840 | |
| 841 | 841 | ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; |
| 842 | + pseries_rng_init(); | |
| 842 | 843 | } |
| 843 | 844 | |
| 844 | 845 | static void pseries_panic(char *str) |
| @@ -364,8 +364,13 @@ config RISCV_ISA_SVPBMT · 363 unmodified lines | ||
| 364 | 364 | select RISCV_ALTERNATIVE |
| 365 | 365 | default y |
| 366 | 366 | help |
| 367 | − Adds support to dynamically detect the presence of the SVPBMT extension | |
| 368 | − (Supervisor-mode: page-based memory types) and enable its usage. | |
| 367 | + Adds support to dynamically detect the presence of the SVPBMT | |
| 368 | + ISA-extension (Supervisor-mode: page-based memory types) and | |
| 369 | + enable its usage. | |
| 370 | + | |
| 371 | + The memory type for a page contains a combination of attributes | |
| 372 | + that indicate the cacheability, idempotency, and ordering | |
| 373 | + properties for access to that page. | |
| 369 | 374 | |
| 370 | 375 | The SVPBMT extension is only available on 64Bit cpus. |
| 371 | 376 | |
| @@ -35,6 +35,7 @@ config ERRATA_SIFIVE_CIP_1200 · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | config ERRATA_THEAD |
| 37 | 37 | bool "T-HEAD errata" |
| 38 | + depends on !XIP_KERNEL | |
| 38 | 39 | select RISCV_ALTERNATIVE |
| 39 | 40 | help |
| 40 | 41 | All T-HEAD errata Kconfig depend on this Kconfig. Disabling |
| @@ -192,6 +192,15 @@ · 191 unmodified lines | ||
| 192 | 192 | riscv,ndev = <186>; |
| 193 | 193 | }; |
| 194 | 194 | |
| 195 | + pdma: dma-controller@3000000 { | |
| 196 | + compatible = "sifive,fu540-c000-pdma", "sifive,pdma0"; | |
| 197 | + reg = <0x0 0x3000000 0x0 0x8000>; | |
| 198 | + interrupt-parent = <&plic>; | |
| 199 | + interrupts = <5 6>, <7 8>, <9 10>, <11 12>; | |
| 200 | + dma-channels = <4>; | |
| 201 | + #dma-cells = <1>; | |
| 202 | + }; | |
| 203 | + | |
| 195 | 204 | clkcfg: clkcfg@20002000 { |
| 196 | 205 | compatible = "microchip,mpfs-clkcfg"; |
| 197 | 206 | reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; |
| @@ -75,20 +75,20 @@ asm volatile(ALTERNATIVE( \ · 74 unmodified lines | ||
| 75 | 75 | "nop\n\t" \ |
| 76 | 76 | "nop\n\t" \ |
| 77 | 77 | "nop", \ |
| 78 | − "li t3, %2\n\t" \ | |
| 79 | − "slli t3, t3, %4\n\t" \ | |
| 78 | + "li t3, %1\n\t" \ | |
| 79 | + "slli t3, t3, %3\n\t" \ | |
| 80 | 80 | "and t3, %0, t3\n\t" \ |
| 81 | 81 | "bne t3, zero, 2f\n\t" \ |
| 82 | − "li t3, %3\n\t" \ | |
| 83 | − "slli t3, t3, %4\n\t" \ | |
| 82 | + "li t3, %2\n\t" \ | |
| 83 | + "slli t3, t3, %3\n\t" \ | |
| 84 | 84 | "or %0, %0, t3\n\t" \ |
| 85 | 85 | "2:", THEAD_VENDOR_ID, \ |
| 86 | 86 | ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \ |
| 87 | 87 | : "+r"(_val) \ |
| 88 | − : "0"(_val), \ | |
| 89 | − "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \ | |
| 88 | + : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \ | |
| 90 | 89 | "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT), \ |
| 91 | − "I"(ALT_THEAD_PBMT_SHIFT)) | |
| 90 | + "I"(ALT_THEAD_PBMT_SHIFT) \ | |
| 91 | + : "t3") | |
| 92 | 92 | #else |
| 93 | 93 | #define ALT_THEAD_PMA(_val) |
| 94 | 94 | #endif |
| @@ -293,7 +293,6 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin, · 292 unmodified lines | ||
| 293 | 293 | unsigned int stage) |
| 294 | 294 | { |
| 295 | 295 | u32 cpu_req_feature = cpufeature_probe(stage); |
| 296 | − u32 cpu_apply_feature = 0; | |
| 297 | 296 | struct alt_entry *alt; |
| 298 | 297 | u32 tmp; |
| 299 | 298 | |
| @@ -307,10 +306,8 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin, · 7 unmodified lines | ||
| 307 | 306 | } |
| 308 | 307 | |
| 309 | 308 | tmp = (1U << alt->errata_id); |
| 310 | − if (cpu_req_feature & tmp) { | |
| 309 | + if (cpu_req_feature & tmp) | |
| 311 | 310 | patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); |
| 312 | − cpu_apply_feature |= tmp; | |
| 313 | − } | |
| 314 | 311 | } |
| 315 | 312 | } |
| 316 | 313 | #endif |
| @@ -97,7 +97,7 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu) · 96 unmodified lines | ||
| 97 | 97 | * We ran out of VMIDs so we increment vmid_version and |
| 98 | 98 | * start assigning VMIDs from 1. |
| 99 | 99 | * |
| 100 | − * This also means existing VMIDs assignement to all Guest | |
| 100 | + * This also means existing VMIDs assignment to all Guest | |
| 101 | 101 | * instances is invalid and we have force VMID re-assignement |
| 102 | 102 | * for all Guest instances. The Guest instances that were not |
| 103 | 103 | * running will automatically pick-up new VMIDs because will |
| @@ -219,6 +219,11 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize, · 218 unmodified lines | ||
| 219 | 219 | unsigned long src; |
| 220 | 220 | int rc; |
| 221 | 221 | |
| 222 | + if (!(iter_is_iovec(iter) || iov_iter_is_kvec(iter))) | |
| 223 | + return -EINVAL; | |
| 224 | + /* Multi-segment iterators are not supported */ | |
| 225 | + if (iter->nr_segs > 1) | |
| 226 | + return -EINVAL; | |
| 222 | 227 | if (!csize) |
| 223 | 228 | return 0; |
| 224 | 229 | src = pfn_to_phys(pfn) + offset; |
| @@ -228,7 +233,10 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize, · 3 unmodified lines | ||
| 228 | 233 | rc = copy_oldmem_user(iter->iov->iov_base, src, csize); |
| 229 | 234 | else |
| 230 | 235 | rc = copy_oldmem_kernel(iter->kvec->iov_base, src, csize); |
| 231 | − return rc; | |
| 236 | + if (rc < 0) | |
| 237 | + return rc; | |
| 238 | + iov_iter_advance(iter, csize); | |
| 239 | + return csize; | |
| 232 | 240 | } |
| 233 | 241 | |
| 234 | 242 | /* |
| @@ -516,6 +516,26 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type) · 515 unmodified lines | ||
| 516 | 516 | return err; |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | +/* Events CPU_CYLCES and INSTRUCTIONS can be submitted with two different | |
| 520 | + * attribute::type values: | |
| 521 | + * - PERF_TYPE_HARDWARE: | |
| 522 | + * - pmu->type: | |
| 523 | + * Handle both type of invocations identical. They address the same hardware. | |
| 524 | + * The result is different when event modifiers exclude_kernel and/or | |
| 525 | + * exclude_user are also set. | |
| 526 | + */ | |
| 527 | +static int cpumf_pmu_event_type(struct perf_event *event) | |
| 528 | +{ | |
| 529 | + u64 ev = event->attr.config; | |
| 530 | + | |
| 531 | + if (cpumf_generic_events_basic[PERF_COUNT_HW_CPU_CYCLES] == ev || | |
| 532 | + cpumf_generic_events_basic[PERF_COUNT_HW_INSTRUCTIONS] == ev || | |
| 533 | + cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev || | |
| 534 | + cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev) | |
| 535 | + return PERF_TYPE_HARDWARE; | |
| 536 | + return PERF_TYPE_RAW; | |
| 537 | +} | |
| 538 | + | |
| 519 | 539 | static int cpumf_pmu_event_init(struct perf_event *event) |
| 520 | 540 | { |
| 521 | 541 | unsigned int type = event->attr.type; |
| @@ -525,7 +545,7 @@ static int cpumf_pmu_event_init(struct perf_event *event) · 3 unmodified lines | ||
| 525 | 545 | err = __hw_perf_event_init(event, type); |
| 526 | 546 | else if (event->pmu->type == type) |
| 527 | 547 | /* Registered as unknown PMU */ |
| 528 | − err = __hw_perf_event_init(event, PERF_TYPE_RAW); | |
| 548 | + err = __hw_perf_event_init(event, cpumf_pmu_event_type(event)); | |
| 529 | 549 | else |
| 530 | 550 | return -ENOENT; |
| 531 | 551 | |
| @@ -193,8 +193,9 @@ static int paicrypt_event_init(struct perf_event *event) · 192 unmodified lines | ||
| 193 | 193 | /* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */ |
| 194 | 194 | if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type) |
| 195 | 195 | return -ENOENT; |
| 196 | − /* PAI crypto event must be valid */ | |
| 197 | − if (a->config > PAI_CRYPTO_BASE + paicrypt_cnt) | |
| 196 | + /* PAI crypto event must be in valid range */ | |
| 197 | + if (a->config < PAI_CRYPTO_BASE || | |
| 198 | + a->config > PAI_CRYPTO_BASE + paicrypt_cnt) | |
| 198 | 199 | return -EINVAL; |
| 199 | 200 | /* Allow only CPU wide operation, no process context for now. */ |
| 200 | 201 | if (event->hw.target || event->cpu == -1) |
| @@ -208,6 +209,12 @@ static int paicrypt_event_init(struct perf_event *event) · 7 unmodified lines | ||
| 208 | 209 | if (rc) |
| 209 | 210 | return rc; |
| 210 | 211 | |
| 212 | + /* Event initialization sets last_tag to 0. When later on the events | |
| 213 | + * are deleted and re-added, do not reset the event count value to zero. | |
| 214 | + * Events are added, deleted and re-added when 2 or more events | |
| 215 | + * are active at the same time. | |
| 216 | + */ | |
| 217 | + event->hw.last_tag = 0; | |
| 211 | 218 | cpump->event = event; |
| 212 | 219 | event->destroy = paicrypt_event_destroy; |
| 213 | 220 | |
| @@ -242,9 +249,12 @@ static void paicrypt_start(struct perf_event *event, int flags) · 28 unmodified lines | ||
| 242 | 249 | { |
| 243 | 250 | u64 sum; |
| 244 | 251 | |
| 245 | − sum = paicrypt_getall(event); /* Get current value */ | |
| 246 | − local64_set(&event->hw.prev_count, sum); | |
| 247 | − local64_set(&event->count, 0); | |
| 252 | + if (!event->hw.last_tag) { | |
| 253 | + event->hw.last_tag = 1; | |
| 254 | + sum = paicrypt_getall(event); /* Get current value */ | |
| 255 | + local64_set(&event->count, 0); | |
| 256 | + local64_set(&event->hw.prev_count, sum); | |
| 257 | + } | |
| 248 | 258 | } |
| 249 | 259 | |
| 250 | 260 | static int paicrypt_add(struct perf_event *event, int flags) |
| @@ -124,6 +124,51 @@ static u64 get_cc_mask(void) · 123 unmodified lines | ||
| 124 | 124 | return BIT_ULL(gpa_width - 1); |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | +/* | |
| 128 | + * The TDX module spec states that #VE may be injected for a limited set of | |
| 129 | + * reasons: | |
| 130 | + * | |
| 131 | + * - Emulation of the architectural #VE injection on EPT violation; | |
| 132 | + * | |
| 133 | + * - As a result of guest TD execution of a disallowed instruction, | |
| 134 | + * a disallowed MSR access, or CPUID virtualization; | |
| 135 | + * | |
| 136 | + * - A notification to the guest TD about anomalous behavior; | |
| 137 | + * | |
| 138 | + * The last one is opt-in and is not used by the kernel. | |
| 139 | + * | |
| 140 | + * The Intel Software Developer's Manual describes cases when instruction | |
| 141 | + * length field can be used in section "Information for VM Exits Due to | |
| 142 | + * Instruction Execution". | |
| 143 | + * | |
| 144 | + * For TDX, it ultimately means GET_VEINFO provides reliable instruction length | |
| 145 | + * information if #VE occurred due to instruction execution, but not for EPT | |
| 146 | + * violations. | |
| 147 | + */ | |
| 148 | +static int ve_instr_len(struct ve_info *ve) | |
| 149 | +{ | |
| 150 | + switch (ve->exit_reason) { | |
| 151 | + case EXIT_REASON_HLT: | |
| 152 | + case EXIT_REASON_MSR_READ: | |
| 153 | + case EXIT_REASON_MSR_WRITE: | |
| 154 | + case EXIT_REASON_CPUID: | |
| 155 | + case EXIT_REASON_IO_INSTRUCTION: | |
| 156 | + /* It is safe to use ve->instr_len for #VE due instructions */ | |
| 157 | + return ve->instr_len; | |
| 158 | + case EXIT_REASON_EPT_VIOLATION: | |
| 159 | + /* | |
| 160 | + * For EPT violations, ve->insn_len is not defined. For those, | |
| 161 | + * the kernel must decode instructions manually and should not | |
| 162 | + * be using this function. | |
| 163 | + */ | |
| 164 | + WARN_ONCE(1, "ve->instr_len is not defined for EPT violations"); | |
| 165 | + return 0; | |
| 166 | + default: | |
| 167 | + WARN_ONCE(1, "Unexpected #VE-type: %lld\n", ve->exit_reason); | |
| 168 | + return ve->instr_len; | |
| 169 | + } | |
| 170 | +} | |
| 171 | + | |
| 127 | 172 | static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti) |
| 128 | 173 | { |
| 129 | 174 | struct tdx_hypercall_args args = { |
| @@ -147,7 +192,7 @@ static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti) · 17 unmodified lines | ||
| 147 | 192 | return __tdx_hypercall(&args, do_sti ? TDX_HCALL_ISSUE_STI : 0); |
| 148 | 193 | } |
| 149 | 194 | |
| 150 | −static bool handle_halt(void) | |
| 195 | +static int handle_halt(struct ve_info *ve) | |
| 151 | 196 | { |
| 152 | 197 | /* |
| 153 | 198 | * Since non safe halt is mainly used in CPU offlining |
| @@ -158,9 +203,9 @@ static bool handle_halt(void) · 4 unmodified lines | ||
| 158 | 203 | const bool do_sti = false; |
| 159 | 204 | |
| 160 | 205 | if (__halt(irq_disabled, do_sti)) |
| 161 | − return false; | |
| 206 | + return -EIO; | |
| 162 | 207 | |
| 163 | − return true; | |
| 208 | + return ve_instr_len(ve); | |
| 164 | 209 | } |
| 165 | 210 | |
| 166 | 211 | void __cpuidle tdx_safe_halt(void) |
| @@ -180,7 +225,7 @@ void __cpuidle tdx_safe_halt(void) · 13 unmodified lines | ||
| 180 | 225 | WARN_ONCE(1, "HLT instruction emulation failed\n"); |
| 181 | 226 | } |
| 182 | 227 | |
| 183 | −static bool read_msr(struct pt_regs *regs) | |
| 228 | +static int read_msr(struct pt_regs *regs, struct ve_info *ve) | |
| 184 | 229 | { |
| 185 | 230 | struct tdx_hypercall_args args = { |
| 186 | 231 | .r10 = TDX_HYPERCALL_STANDARD, |
| @@ -194,14 +239,14 @@ static bool read_msr(struct pt_regs *regs) · 7 unmodified lines | ||
| 194 | 239 | * (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>". |
| 195 | 240 | */ |
| 196 | 241 | if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) |
| 197 | − return false; | |
| 242 | + return -EIO; | |
| 198 | 243 | |
| 199 | 244 | regs->ax = lower_32_bits(args.r11); |
| 200 | 245 | regs->dx = upper_32_bits(args.r11); |
| 201 | − return true; | |
| 246 | + return ve_instr_len(ve); | |
| 202 | 247 | } |
| 203 | 248 | |
| 204 | −static bool write_msr(struct pt_regs *regs) | |
| 249 | +static int write_msr(struct pt_regs *regs, struct ve_info *ve) | |
| 205 | 250 | { |
| 206 | 251 | struct tdx_hypercall_args args = { |
| 207 | 252 | .r10 = TDX_HYPERCALL_STANDARD, |
| @@ -215,10 +260,13 @@ static bool write_msr(struct pt_regs *regs) · 7 unmodified lines | ||
| 215 | 260 | * can be found in TDX Guest-Host-Communication Interface |
| 216 | 261 | * (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>". |
| 217 | 262 | */ |
| 218 | − return !__tdx_hypercall(&args, 0); | |
| 263 | + if (__tdx_hypercall(&args, 0)) | |
| 264 | + return -EIO; | |
| 265 | + | |
| 266 | + return ve_instr_len(ve); | |
| 219 | 267 | } |
| 220 | 268 | |
| 221 | −static bool handle_cpuid(struct pt_regs *regs) | |
| 269 | +static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve) | |
| 222 | 270 | { |
| 223 | 271 | struct tdx_hypercall_args args = { |
| 224 | 272 | .r10 = TDX_HYPERCALL_STANDARD, |
| @@ -236,7 +284,7 @@ static bool handle_cpuid(struct pt_regs *regs) · 11 unmodified lines | ||
| 236 | 284 | */ |
| 237 | 285 | if (regs->ax < 0x40000000 || regs->ax > 0x4FFFFFFF) { |
| 238 | 286 | regs->ax = regs->bx = regs->cx = regs->dx = 0; |
| 239 | − return true; | |
| 287 | + return ve_instr_len(ve); | |
| 240 | 288 | } |
| 241 | 289 | |
| 242 | 290 | /* |
| @@ -245,7 +293,7 @@ static bool handle_cpuid(struct pt_regs *regs) · 2 unmodified lines | ||
| 245 | 293 | * (GHCI), section titled "VP.VMCALL<Instruction.CPUID>". |
| 246 | 294 | */ |
| 247 | 295 | if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) |
| 248 | − return false; | |
| 296 | + return -EIO; | |
| 249 | 297 | |
| 250 | 298 | /* |
| 251 | 299 | * As per TDX GHCI CPUID ABI, r12-r15 registers contain contents of |
| @@ -257,7 +305,7 @@ static bool handle_cpuid(struct pt_regs *regs) · 5 unmodified lines | ||
| 257 | 305 | regs->cx = args.r14; |
| 258 | 306 | regs->dx = args.r15; |
| 259 | 307 | |
| 260 | − return true; | |
| 308 | + return ve_instr_len(ve); | |
| 261 | 309 | } |
| 262 | 310 | |
| 263 | 311 | static bool mmio_read(int size, unsigned long addr, unsigned long *val) |
| @@ -283,10 +331,10 @@ static bool mmio_write(int size, unsigned long addr, unsigned long val) · 19 unmodified lines | ||
| 283 | 331 | EPT_WRITE, addr, val); |
| 284 | 332 | } |
| 285 | 333 | |
| 286 | −static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve) | |
| 334 | +static int handle_mmio(struct pt_regs *regs, struct ve_info *ve) | |
| 287 | 335 | { |
| 336 | + unsigned long *reg, val, vaddr; | |
| 288 | 337 | char buffer[MAX_INSN_SIZE]; |
| 289 | − unsigned long *reg, val; | |
| 290 | 338 | struct insn insn = {}; |
| 291 | 339 | enum mmio_type mmio; |
| 292 | 340 | int size, extend_size; |
| @@ -294,34 +342,49 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve) · 1 unmodified line | ||
| 294 | 342 | |
| 295 | 343 | /* Only in-kernel MMIO is supported */ |
| 296 | 344 | if (WARN_ON_ONCE(user_mode(regs))) |
| 297 | − return false; | |
| 345 | + return -EFAULT; | |
| 298 | 346 | |
| 299 | 347 | if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) |
| 300 | − return false; | |
| 348 | + return -EFAULT; | |
| 301 | 349 | |
| 302 | 350 | if (insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) |
| 303 | − return false; | |
| 351 | + return -EINVAL; | |
| 304 | 352 | |
| 305 | 353 | mmio = insn_decode_mmio(&insn, &size); |
| 306 | 354 | if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED)) |
| 307 | − return false; | |
| 355 | + return -EINVAL; | |
| 308 | 356 | |
| 309 | 357 | if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) { |
| 310 | 358 | reg = insn_get_modrm_reg_ptr(&insn, regs); |
| 311 | 359 | if (!reg) |
| 312 | − return false; | |
| 360 | + return -EINVAL; | |
| 313 | 361 | } |
| 314 | 362 | |
| 315 | − ve->instr_len = insn.length; | |
| 363 | + /* | |
| 364 | + * Reject EPT violation #VEs that split pages. | |
| 365 | + * | |
| 366 | + * MMIO accesses are supposed to be naturally aligned and therefore | |
| 367 | + * never cross page boundaries. Seeing split page accesses indicates | |
| 368 | + * a bug or a load_unaligned_zeropad() that stepped into an MMIO page. | |
| 369 | + * | |
| 370 | + * load_unaligned_zeropad() will recover using exception fixups. | |
| 371 | + */ | |
| 372 | + vaddr = (unsigned long)insn_get_addr_ref(&insn, regs); | |
| 373 | + if (vaddr / PAGE_SIZE != (vaddr + size - 1) / PAGE_SIZE) | |
| 374 | + return -EFAULT; | |
| 316 | 375 | |
| 317 | 376 | /* Handle writes first */ |
| 318 | 377 | switch (mmio) { |
| 319 | 378 | case MMIO_WRITE: |
| 320 | 379 | memcpy(&val, reg, size); |
| 321 | − return mmio_write(size, ve->gpa, val); | |
| 380 | + if (!mmio_write(size, ve->gpa, val)) | |
| 381 | + return -EIO; | |
| 382 | + return insn.length; | |
| 322 | 383 | case MMIO_WRITE_IMM: |
| 323 | 384 | val = insn.immediate.value; |
| 324 | − return mmio_write(size, ve->gpa, val); | |
| 385 | + if (!mmio_write(size, ve->gpa, val)) | |
| 386 | + return -EIO; | |
| 387 | + return insn.length; | |
| 325 | 388 | case MMIO_READ: |
| 326 | 389 | case MMIO_READ_ZERO_EXTEND: |
| 327 | 390 | case MMIO_READ_SIGN_EXTEND: |
| @@ -334,15 +397,15 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve) · 6 unmodified lines | ||
| 334 | 397 | * decoded or handled properly. It was likely not using io.h |
| 335 | 398 | * helpers or accessed MMIO accidentally. |
| 336 | 399 | */ |
| 337 | − return false; | |
| 400 | + return -EINVAL; | |
| 338 | 401 | default: |
| 339 | 402 | WARN_ONCE(1, "Unknown insn_decode_mmio() decode value?"); |
| 340 | − return false; | |
| 403 | + return -EINVAL; | |
| 341 | 404 | } |
| 342 | 405 | |
| 343 | 406 | /* Handle reads */ |
| 344 | 407 | if (!mmio_read(size, ve->gpa, &val)) |
| 345 | − return false; | |
| 408 | + return -EIO; | |
| 346 | 409 | |
| 347 | 410 | switch (mmio) { |
| 348 | 411 | case MMIO_READ: |
| @@ -364,13 +427,13 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve) · 15 unmodified lines | ||
| 364 | 427 | default: |
| 365 | 428 | /* All other cases has to be covered with the first switch() */ |
| 366 | 429 | WARN_ON_ONCE(1); |
| 367 | − return false; | |
| 430 | + return -EINVAL; | |
| 368 | 431 | } |
| 369 | 432 | |
| 370 | 433 | if (extend_size) |
| 371 | 434 | memset(reg, extend_val, extend_size); |
| 372 | 435 | memcpy(reg, &val, size); |
| 373 | − return true; | |
| 436 | + return insn.length; | |
| 374 | 437 | } |
| 375 | 438 | |
| 376 | 439 | static bool handle_in(struct pt_regs *regs, int size, int port) |
| @@ -421,13 +484,14 @@ static bool handle_out(struct pt_regs *regs, int size, int port) · 44 unmodified lines | ||
| 421 | 484 | * |
| 422 | 485 | * Return True on success or False on failure. |
| 423 | 486 | */ |
| 424 | −static bool handle_io(struct pt_regs *regs, u32 exit_qual) | |
| 487 | +static int handle_io(struct pt_regs *regs, struct ve_info *ve) | |
| 425 | 488 | { |
| 489 | + u32 exit_qual = ve->exit_qual; | |
| 426 | 490 | int size, port; |
| 427 | − bool in; | |
| 491 | + bool in, ret; | |
| 428 | 492 | |
| 429 | 493 | if (VE_IS_IO_STRING(exit_qual)) |
| 430 | − return false; | |
| 494 | + return -EIO; | |
| 431 | 495 | |
| 432 | 496 | in = VE_IS_IO_IN(exit_qual); |
| 433 | 497 | size = VE_GET_IO_SIZE(exit_qual); |
| @@ -435,9 +499,13 @@ static bool handle_io(struct pt_regs *regs, u32 exit_qual) · 1 unmodified line | ||
| 435 | 499 | |
| 436 | 500 | |
| 437 | 501 | if (in) |
| 438 | − return handle_in(regs, size, port); | |
| 502 | + ret = handle_in(regs, size, port); | |
| 439 | 503 | else |
| 440 | − return handle_out(regs, size, port); | |
| 504 | + ret = handle_out(regs, size, port); | |
| 505 | + if (!ret) | |
| 506 | + return -EIO; | |
| 507 | + | |
| 508 | + return ve_instr_len(ve); | |
| 441 | 509 | } |
| 442 | 510 | |
| 443 | 511 | /* |
| @@ -447,13 +515,19 @@ static bool handle_io(struct pt_regs *regs, u32 exit_qual) · 3 unmodified lines | ||
| 447 | 515 | __init bool tdx_early_handle_ve(struct pt_regs *regs) |
| 448 | 516 | { |
| 449 | 517 | struct ve_info ve; |
| 518 | + int insn_len; | |
| 450 | 519 | |
| 451 | 520 | tdx_get_ve_info(&ve); |
| 452 | 521 | |
| 453 | 522 | if (ve.exit_reason != EXIT_REASON_IO_INSTRUCTION) |
| 454 | 523 | return false; |
| 455 | 524 | |
| 456 | − return handle_io(regs, ve.exit_qual); | |
| 525 | + insn_len = handle_io(regs, &ve); | |
| 526 | + if (insn_len < 0) | |
| 527 | + return false; | |
| 528 | + | |
| 529 | + regs->ip += insn_len; | |
| 530 | + return true; | |
| 457 | 531 | } |
| 458 | 532 | |
| 459 | 533 | void tdx_get_ve_info(struct ve_info *ve) |
| @@ -486,54 +560,65 @@ void tdx_get_ve_info(struct ve_info *ve) · 26 unmodified lines | ||
| 486 | 560 | ve->instr_info = upper_32_bits(out.r10); |
| 487 | 561 | } |
| 488 | 562 | |
| 489 | −/* Handle the user initiated #VE */ | |
| 490 | −static bool virt_exception_user(struct pt_regs *regs, struct ve_info *ve) | |
| 563 | +/* | |
| 564 | + * Handle the user initiated #VE. | |
| 565 | + * | |
| 566 | + * On success, returns the number of bytes RIP should be incremented (>=0) | |
| 567 | + * or -errno on error. | |
| 568 | + */ | |
| 569 | +static int virt_exception_user(struct pt_regs *regs, struct ve_info *ve) | |
| 491 | 570 | { |
| 492 | 571 | switch (ve->exit_reason) { |
| 493 | 572 | case EXIT_REASON_CPUID: |
| 494 | − return handle_cpuid(regs); | |
| 573 | + return handle_cpuid(regs, ve); | |
| 495 | 574 | default: |
| 496 | 575 | pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); |
| 497 | − return false; | |
| 576 | + return -EIO; | |
| 498 | 577 | } |
| 499 | 578 | } |
| 500 | 579 | |
| 501 | −/* Handle the kernel #VE */ | |
| 502 | −static bool virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve) | |
| 580 | +/* | |
| 581 | + * Handle the kernel #VE. | |
| 582 | + * | |
| 583 | + * On success, returns the number of bytes RIP should be incremented (>=0) | |
| 584 | + * or -errno on error. | |
| 585 | + */ | |
| 586 | +static int virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve) | |
| 503 | 587 | { |
| 504 | 588 | switch (ve->exit_reason) { |
| 505 | 589 | case EXIT_REASON_HLT: |
| 506 | − return handle_halt(); | |
| 590 | + return handle_halt(ve); | |
| 507 | 591 | case EXIT_REASON_MSR_READ: |
| 508 | − return read_msr(regs); | |
| 592 | + return read_msr(regs, ve); | |
| 509 | 593 | case EXIT_REASON_MSR_WRITE: |
| 510 | − return write_msr(regs); | |
| 594 | + return write_msr(regs, ve); | |
| 511 | 595 | case EXIT_REASON_CPUID: |
| 512 | − return handle_cpuid(regs); | |
| 596 | + return handle_cpuid(regs, ve); | |
| 513 | 597 | case EXIT_REASON_EPT_VIOLATION: |
| 514 | 598 | return handle_mmio(regs, ve); |
| 515 | 599 | case EXIT_REASON_IO_INSTRUCTION: |
| 516 | − return handle_io(regs, ve->exit_qual); | |
| 600 | + return handle_io(regs, ve); | |
| 517 | 601 | default: |
| 518 | 602 | pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); |
| 519 | − return false; | |
| 603 | + return -EIO; | |
| 520 | 604 | } |
| 521 | 605 | } |
| 522 | 606 | |
| 523 | 607 | bool tdx_handle_virt_exception(struct pt_regs *regs, struct ve_info *ve) |
| 524 | 608 | { |
| 525 | − bool ret; | |
| 609 | + int insn_len; | |
| 526 | 610 | |
| 527 | 611 | if (user_mode(regs)) |
| 528 | − ret = virt_exception_user(regs, ve); | |
| 612 | + insn_len = virt_exception_user(regs, ve); | |
| 529 | 613 | else |
| 530 | − ret = virt_exception_kernel(regs, ve); | |
| 614 | + insn_len = virt_exception_kernel(regs, ve); | |
| 615 | + if (insn_len < 0) | |
| 616 | + return false; | |
| 531 | 617 | |
| 532 | 618 | /* After successful #VE handling, move the IP */ |
| 533 | − if (ret) | |
| 534 | − regs->ip += ve->instr_len; | |
| 619 | + regs->ip += insn_len; | |
| 535 | 620 | |
| 536 | − return ret; | |
| 621 | + return true; | |
| 537 | 622 | } |
| 538 | 623 | |
| 539 | 624 | static bool tdx_tlb_flush_required(bool private) |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/io.h> |
| 14 | 14 | #include <asm/apic.h> |
| 15 | 15 | #include <asm/desc.h> |
| 16 | +#include <asm/sev.h> | |
| 16 | 17 | #include <asm/hypervisor.h> |
| 17 | 18 | #include <asm/hyperv-tlfs.h> |
| 18 | 19 | #include <asm/mshyperv.h> |
| @@ -405,6 +406,11 @@ void __init hyperv_init(void) · 386 unmodified lines | ||
| 405 | 406 | } |
| 406 | 407 | |
| 407 | 408 | if (hv_isolation_type_snp()) { |
| 409 | + /* Negotiate GHCB Version. */ | |
| 410 | + if (!hv_ghcb_negotiate_protocol()) | |
| 411 | + hv_ghcb_terminate(SEV_TERM_SET_GEN, | |
| 412 | + GHCB_SEV_ES_PROT_UNSUPPORTED); | |
| 413 | + | |
| 408 | 414 | hv_ghcb_pg = alloc_percpu(union hv_ghcb *); |
| 409 | 415 | if (!hv_ghcb_pg) |
| 410 | 416 | goto free_vp_assist_page; |
| @@ -53,6 +53,8 @@ union hv_ghcb { · 52 unmodified lines | ||
| 53 | 53 | } hypercall; |
| 54 | 54 | } __packed __aligned(HV_HYP_PAGE_SIZE); |
| 55 | 55 | |
| 56 | +static u16 hv_ghcb_version __ro_after_init; | |
| 57 | + | |
| 56 | 58 | u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size) |
| 57 | 59 | { |
| 58 | 60 | union hv_ghcb *hv_ghcb; |
| @@ -96,12 +98,85 @@ u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size) · 37 unmodified lines | ||
| 96 | 98 | return status; |
| 97 | 99 | } |
| 98 | 100 | |
| 101 | +static inline u64 rd_ghcb_msr(void) | |
| 102 | +{ | |
| 103 | + return __rdmsr(MSR_AMD64_SEV_ES_GHCB); | |
| 104 | +} | |
| 105 | + | |
| 106 | +static inline void wr_ghcb_msr(u64 val) | |
| 107 | +{ | |
| 108 | + native_wrmsrl(MSR_AMD64_SEV_ES_GHCB, val); | |
| 109 | +} | |
| 110 | + | |
| 111 | +static enum es_result hv_ghcb_hv_call(struct ghcb *ghcb, u64 exit_code, | |
| 112 | + u64 exit_info_1, u64 exit_info_2) | |
| 113 | +{ | |
| 114 | + /* Fill in protocol and format specifiers */ | |
| 115 | + ghcb->protocol_version = hv_ghcb_version; | |
| 116 | + ghcb->ghcb_usage = GHCB_DEFAULT_USAGE; | |
| 117 | + | |
| 118 | + ghcb_set_sw_exit_code(ghcb, exit_code); | |
| 119 | + ghcb_set_sw_exit_info_1(ghcb, exit_info_1); | |
| 120 | + ghcb_set_sw_exit_info_2(ghcb, exit_info_2); | |
| 121 | + | |
| 122 | + VMGEXIT(); | |
| 123 | + | |
| 124 | + if (ghcb->save.sw_exit_info_1 & GENMASK_ULL(31, 0)) | |
| 125 | + return ES_VMM_ERROR; | |
| 126 | + else | |
| 127 | + return ES_OK; | |
| 128 | +} | |
| 129 | + | |
| 130 | +void hv_ghcb_terminate(unsigned int set, unsigned int reason) | |
| 131 | +{ | |
| 132 | + u64 val = GHCB_MSR_TERM_REQ; | |
| 133 | + | |
| 134 | + /* Tell the hypervisor what went wrong. */ | |
| 135 | + val |= GHCB_SEV_TERM_REASON(set, reason); | |
| 136 | + | |
| 137 | + /* Request Guest Termination from Hypvervisor */ | |
| 138 | + wr_ghcb_msr(val); | |
| 139 | + VMGEXIT(); | |
| 140 | + | |
| 141 | + while (true) | |
| 142 | + asm volatile("hlt\n" : : : "memory"); | |
| 143 | +} | |
| 144 | + | |
| 145 | +bool hv_ghcb_negotiate_protocol(void) | |
| 146 | +{ | |
| 147 | + u64 ghcb_gpa; | |
| 148 | + u64 val; | |
| 149 | + | |
| 150 | + /* Save ghcb page gpa. */ | |
| 151 | + ghcb_gpa = rd_ghcb_msr(); | |
| 152 | + | |
| 153 | + /* Do the GHCB protocol version negotiation */ | |
| 154 | + wr_ghcb_msr(GHCB_MSR_SEV_INFO_REQ); | |
| 155 | + VMGEXIT(); | |
| 156 | + val = rd_ghcb_msr(); | |
| 157 | + | |
| 158 | + if (GHCB_MSR_INFO(val) != GHCB_MSR_SEV_INFO_RESP) | |
| 159 | + return false; | |
| 160 | + | |
| 161 | + if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTOCOL_MIN || | |
| 162 | + GHCB_MSR_PROTO_MIN(val) > GHCB_PROTOCOL_MAX) | |
| 163 | + return false; | |
| 164 | + | |
| 165 | + hv_ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val), | |
| 166 | + GHCB_PROTOCOL_MAX); | |
| 167 | + | |
| 168 | + /* Write ghcb page back after negotiating protocol. */ | |
| 169 | + wr_ghcb_msr(ghcb_gpa); | |
| 170 | + VMGEXIT(); | |
| 171 | + | |
| 172 | + return true; | |
| 173 | +} | |
| 174 | + | |
| 99 | 175 | void hv_ghcb_msr_write(u64 msr, u64 value) |
| 100 | 176 | { |
| 101 | 177 | union hv_ghcb *hv_ghcb; |
| 102 | 178 | void **ghcb_base; |
| 103 | 179 | unsigned long flags; |
| 104 | − struct es_em_ctxt ctxt; | |
| 105 | 180 | |
| 106 | 181 | if (!hv_ghcb_pg) |
| 107 | 182 | return; |
| @@ -120,8 +195,7 @@ void hv_ghcb_msr_write(u64 msr, u64 value) · 12 unmodified lines | ||
| 120 | 195 | ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value)); |
| 121 | 196 | ghcb_set_rdx(&hv_ghcb->ghcb, upper_32_bits(value)); |
| 122 | 197 | |
| 123 | − if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt, | |
| 124 | − SVM_EXIT_MSR, 1, 0)) | |
| 198 | + if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 1, 0)) | |
| 125 | 199 | pr_warn("Fail to write msr via ghcb %llx.\n", msr); |
| 126 | 200 | |
| 127 | 201 | local_irq_restore(flags); |
| @@ -133,7 +207,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value) · 5 unmodified lines | ||
| 133 | 207 | union hv_ghcb *hv_ghcb; |
| 134 | 208 | void **ghcb_base; |
| 135 | 209 | unsigned long flags; |
| 136 | − struct es_em_ctxt ctxt; | |
| 137 | 210 | |
| 138 | 211 | /* Check size of union hv_ghcb here. */ |
| 139 | 212 | BUILD_BUG_ON(sizeof(union hv_ghcb) != HV_HYP_PAGE_SIZE); |
| @@ -152,8 +225,7 @@ void hv_ghcb_msr_read(u64 msr, u64 *value) · 12 unmodified lines | ||
| 152 | 225 | } |
| 153 | 226 | |
| 154 | 227 | ghcb_set_rcx(&hv_ghcb->ghcb, msr); |
| 155 | − if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt, | |
| 156 | − SVM_EXIT_MSR, 0, 0)) | |
| 228 | + if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 0, 0)) | |
| 157 | 229 | pr_warn("Fail to read msr via ghcb %llx.\n", msr); |
| 158 | 230 | else |
| 159 | 231 | *value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax) |
| @@ -446,5 +446,6 @@ · 445 unmodified lines | ||
| 446 | 446 | #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ |
| 447 | 447 | #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ |
| 448 | 448 | #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ |
| 449 | +#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ | |
| 449 | 450 | |
| 450 | 451 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -4,9 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <asm/e820/types.h> |
| 6 | 6 | |
| 7 | −struct device; | |
| 8 | −struct resource; | |
| 9 | − | |
| 10 | 7 | extern struct e820_table *e820_table; |
| 11 | 8 | extern struct e820_table *e820_table_kexec; |
| 12 | 9 | extern struct e820_table *e820_table_firmware; |
| @@ -46,8 +43,6 @@ extern void e820__register_nosave_regions(unsigned long limit_pfn); · 33 unmodified lines | ||
| 46 | 43 | |
| 47 | 44 | extern int e820__get_entry_type(u64 start, u64 end); |
| 48 | 45 | |
| 49 | −extern void remove_e820_regions(struct device *dev, struct resource *avail); | |
| 50 | − | |
| 51 | 46 | /* |
| 52 | 47 | * Returns true iff the specified range [start,end) is completely contained inside |
| 53 | 48 | * the ISA region. |
| @@ -323,7 +323,7 @@ static inline u32 efi64_convert_status(efi_status_t status) · 322 unmodified lines | ||
| 323 | 323 | #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ |
| 324 | 324 | (__efi64_split(phys), (desc)) |
| 325 | 325 | |
| 326 | −#define __efi64_argmap_set_memory_space_descriptor(phys, size, flags) \ | |
| 326 | +#define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ | |
| 327 | 327 | (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) |
| 328 | 328 | |
| 329 | 329 | /* |
| @@ -1047,14 +1047,77 @@ struct kvm_x86_msr_filter { · 1046 unmodified lines | ||
| 1047 | 1047 | }; |
| 1048 | 1048 | |
| 1049 | 1049 | enum kvm_apicv_inhibit { |
| 1050 | + | |
| 1051 | + /********************************************************************/ | |
| 1052 | + /* INHIBITs that are relevant to both Intel's APICv and AMD's AVIC. */ | |
| 1053 | + /********************************************************************/ | |
| 1054 | + | |
| 1055 | + /* | |
| 1056 | + * APIC acceleration is disabled by a module parameter | |
| 1057 | + * and/or not supported in hardware. | |
| 1058 | + */ | |
| 1050 | 1059 | APICV_INHIBIT_REASON_DISABLE, |
| 1060 | + | |
| 1061 | + /* | |
| 1062 | + * APIC acceleration is inhibited because AutoEOI feature is | |
| 1063 | + * being used by a HyperV guest. | |
| 1064 | + */ | |
| 1051 | 1065 | APICV_INHIBIT_REASON_HYPERV, |
| 1066 | + | |
| 1067 | + /* | |
| 1068 | + * APIC acceleration is inhibited because the userspace didn't yet | |
| 1069 | + * enable the kernel/split irqchip. | |
| 1070 | + */ | |
| 1071 | + APICV_INHIBIT_REASON_ABSENT, | |
| 1072 | + | |
| 1073 | + /* APIC acceleration is inhibited because KVM_GUESTDBG_BLOCKIRQ | |
| 1074 | + * (out of band, debug measure of blocking all interrupts on this vCPU) | |
| 1075 | + * was enabled, to avoid AVIC/APICv bypassing it. | |
| 1076 | + */ | |
| 1077 | + APICV_INHIBIT_REASON_BLOCKIRQ, | |
| 1078 | + | |
| 1079 | + /* | |
| 1080 | + * For simplicity, the APIC acceleration is inhibited | |
| 1081 | + * first time either APIC ID or APIC base are changed by the guest | |
| 1082 | + * from their reset values. | |
| 1083 | + */ | |
| 1084 | + APICV_INHIBIT_REASON_APIC_ID_MODIFIED, | |
| 1085 | + APICV_INHIBIT_REASON_APIC_BASE_MODIFIED, | |
| 1086 | + | |
| 1087 | + /******************************************************/ | |
| 1088 | + /* INHIBITs that are relevant only to the AMD's AVIC. */ | |
| 1089 | + /******************************************************/ | |
| 1090 | + | |
| 1091 | + /* | |
| 1092 | + * AVIC is inhibited on a vCPU because it runs a nested guest. | |
| 1093 | + * | |
| 1094 | + * This is needed because unlike APICv, the peers of this vCPU | |
| 1095 | + * cannot use the doorbell mechanism to signal interrupts via AVIC when | |
| 1096 | + * a vCPU runs nested. | |
| 1097 | + */ | |
| 1052 | 1098 | APICV_INHIBIT_REASON_NESTED, |
| 1099 | + | |
| 1100 | + /* | |
| 1101 | + * On SVM, the wait for the IRQ window is implemented with pending vIRQ, | |
| 1102 | + * which cannot be injected when the AVIC is enabled, thus AVIC | |
| 1103 | + * is inhibited while KVM waits for IRQ window. | |
| 1104 | + */ | |
| 1053 | 1105 | APICV_INHIBIT_REASON_IRQWIN, |
| 1106 | + | |
| 1107 | + /* | |
| 1108 | + * PIT (i8254) 're-inject' mode, relies on EOI intercept, | |
| 1109 | + * which AVIC doesn't support for edge triggered interrupts. | |
| 1110 | + */ | |
| 1054 | 1111 | APICV_INHIBIT_REASON_PIT_REINJ, |
| 1112 | + | |
| 1113 | + /* | |
| 1114 | + * AVIC is inhibited because the guest has x2apic in its CPUID. | |
| 1115 | + */ | |
| 1055 | 1116 | APICV_INHIBIT_REASON_X2APIC, |
| 1056 | − APICV_INHIBIT_REASON_BLOCKIRQ, | |
| 1057 | − APICV_INHIBIT_REASON_ABSENT, | |
| 1117 | + | |
| 1118 | + /* | |
| 1119 | + * AVIC is disabled because SEV doesn't support it. | |
| 1120 | + */ | |
| 1058 | 1121 | APICV_INHIBIT_REASON_SEV, |
| 1059 | 1122 | }; |
| 1060 | 1123 | |
| @@ -179,9 +179,13 @@ int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible); · 178 unmodified lines | ||
| 179 | 179 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 180 | 180 | void hv_ghcb_msr_write(u64 msr, u64 value); |
| 181 | 181 | void hv_ghcb_msr_read(u64 msr, u64 *value); |
| 182 | +bool hv_ghcb_negotiate_protocol(void); | |
| 183 | +void hv_ghcb_terminate(unsigned int set, unsigned int reason); | |
| 182 | 184 | #else |
| 183 | 185 | static inline void hv_ghcb_msr_write(u64 msr, u64 value) {} |
| 184 | 186 | static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {} |
| 187 | +static inline bool hv_ghcb_negotiate_protocol(void) { return false; } | |
| 188 | +static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {} | |
| 185 | 189 | #endif |
| 186 | 190 | |
| 187 | 191 | extern bool hv_isolation_type_snp(void); |
| @@ -116,6 +116,30 @@ · 115 unmodified lines | ||
| 116 | 116 | * Not susceptible to |
| 117 | 117 | * TSX Async Abort (TAA) vulnerabilities. |
| 118 | 118 | */ |
| 119 | +#define ARCH_CAP_SBDR_SSDP_NO BIT(13) /* | |
| 120 | + * Not susceptible to SBDR and SSDP | |
| 121 | + * variants of Processor MMIO stale data | |
| 122 | + * vulnerabilities. | |
| 123 | + */ | |
| 124 | +#define ARCH_CAP_FBSDP_NO BIT(14) /* | |
| 125 | + * Not susceptible to FBSDP variant of | |
| 126 | + * Processor MMIO stale data | |
| 127 | + * vulnerabilities. | |
| 128 | + */ | |
| 129 | +#define ARCH_CAP_PSDP_NO BIT(15) /* | |
| 130 | + * Not susceptible to PSDP variant of | |
| 131 | + * Processor MMIO stale data | |
| 132 | + * vulnerabilities. | |
| 133 | + */ | |
| 134 | +#define ARCH_CAP_FB_CLEAR BIT(17) /* | |
| 135 | + * VERW clears CPU fill buffer | |
| 136 | + * even on MDS_NO CPUs. | |
| 137 | + */ | |
| 138 | +#define ARCH_CAP_FB_CLEAR_CTRL BIT(18) /* | |
| 139 | + * MSR_IA32_MCU_OPT_CTRL[FB_CLEAR_DIS] | |
| 140 | + * bit available to control VERW | |
| 141 | + * behavior. | |
| 142 | + */ | |
| 119 | 143 | |
| 120 | 144 | #define MSR_IA32_FLUSH_CMD 0x0000010b |
| 121 | 145 | #define L1D_FLUSH BIT(0) /* |
| @@ -133,6 +157,7 @@ · 11 unmodified lines | ||
| 133 | 157 | #define MSR_IA32_MCU_OPT_CTRL 0x00000123 |
| 134 | 158 | #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ |
| 135 | 159 | #define RTM_ALLOW BIT(1) /* TSX development mode */ |
| 160 | +#define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ | |
| 136 | 161 | |
| 137 | 162 | #define MSR_IA32_SYSENTER_CS 0x00000174 |
| 138 | 163 | #define MSR_IA32_SYSENTER_ESP 0x00000175 |
| @@ -269,6 +269,8 @@ DECLARE_STATIC_KEY_FALSE(mds_idle_clear); · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); |
| 271 | 271 | |
| 272 | +DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear); | |
| 273 | + | |
| 272 | 274 | #include <asm/segment.h> |
| 273 | 275 | |
| 274 | 276 | /** |
| @@ -69,6 +69,8 @@ void pcibios_scan_specific_bus(int busn); · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | /* pci-irq.c */ |
| 71 | 71 | |
| 72 | +struct pci_dev; | |
| 73 | + | |
| 72 | 74 | struct irq_info { |
| 73 | 75 | u8 bus, devfn; /* Bus, device and function */ |
| 74 | 76 | struct { |
| @@ -246,3 +248,9 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val) · 171 unmodified lines | ||
| 246 | 248 | # define x86_default_pci_init_irq NULL |
| 247 | 249 | # define x86_default_pci_fixup_irqs NULL |
| 248 | 250 | #endif |
| 251 | + | |
| 252 | +#if defined(CONFIG_PCI) && defined(CONFIG_ACPI) | |
| 253 | +extern bool pci_use_e820; | |
| 254 | +#else | |
| 255 | +#define pci_use_e820 false | |
| 256 | +#endif | |
| @@ -108,19 +108,16 @@ extern unsigned long _brk_end; · 107 unmodified lines | ||
| 108 | 108 | void *extend_brk(size_t size, size_t align); |
| 109 | 109 | |
| 110 | 110 | /* |
| 111 | − * Reserve space in the brk section. The name must be unique within the file, | |
| 112 | − * and somewhat descriptive. The size is in bytes. | |
| 111 | + * Reserve space in the .brk section, which is a block of memory from which the | |
| 112 | + * caller is allowed to allocate very early (before even memblock is available) | |
| 113 | + * by calling extend_brk(). All allocated memory will be eventually converted | |
| 114 | + * to memblock. Any leftover unallocated memory will be freed. | |
| 113 | 115 | * |
| 114 | − * The allocation is done using inline asm (rather than using a section | |
| 115 | − * attribute on a normal variable) in order to allow the use of @nobits, so | |
| 116 | − * that it doesn't take up any space in the vmlinux file. | |
| 116 | + * The size is in bytes. | |
| 117 | 117 | */ |
| 118 | −#define RESERVE_BRK(name, size) \ | |
| 119 | − asm(".pushsection .brk_reservation,\"aw\",@nobits\n\t" \ | |
| 120 | − ".brk." #name ":\n\t" \ | |
| 121 | − ".skip " __stringify(size) "\n\t" \ | |
| 122 | − ".size .brk." #name ", " __stringify(size) "\n\t" \ | |
| 123 | − ".popsection\n\t") | |
| 118 | +#define RESERVE_BRK(name, size) \ | |
| 119 | + __section(".bss..brk") __aligned(1) __used \ | |
| 120 | + static char __brk_##name[size] | |
| 124 | 121 | |
| 125 | 122 | extern void probe_roms(void); |
| 126 | 123 | #ifdef __i386__ |
| @@ -133,12 +130,19 @@ asmlinkage void __init x86_64_start_reservations(char *real_mode_data); · 6 unmodified lines | ||
| 133 | 130 | |
| 134 | 131 | #endif /* __i386__ */ |
| 135 | 132 | #endif /* _SETUP */ |
| 136 | −#else | |
| 137 | −#define RESERVE_BRK(name,sz) \ | |
| 138 | − .pushsection .brk_reservation,"aw",@nobits; \ | |
| 139 | −.brk.name: \ | |
| 140 | −1: .skip sz; \ | |
| 141 | − .size .brk.name,.-1b; \ | |
| 133 | + | |
| 134 | +#else /* __ASSEMBLY */ | |
| 135 | + | |
| 136 | +.macro __RESERVE_BRK name, size | |
| 137 | + .pushsection .bss..brk, "aw" | |
| 138 | +SYM_DATA_START(__brk_\name) | |
| 139 | + .skip \size | |
| 140 | +SYM_DATA_END(__brk_\name) | |
| 142 | 141 | .popsection |
| 142 | +.endm | |
| 143 | + | |
| 144 | +#define RESERVE_BRK(name, size) __RESERVE_BRK name, size | |
| 145 | + | |
| 143 | 146 | #endif /* __ASSEMBLY__ */ |
| 147 | + | |
| 144 | 148 | #endif /* _ASM_X86_SETUP_H */ |
| @@ -36,10 +36,6 @@ KCSAN_SANITIZE := n · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | OBJECT_FILES_NON_STANDARD_test_nx.o := y |
| 38 | 38 | |
| 39 | −ifdef CONFIG_FRAME_POINTER | |
| 40 | −OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y | |
| 41 | −endif | |
| 42 | − | |
| 43 | 39 | # If instrumentation of this dir is enabled, boot hangs during first second. |
| 44 | 40 | # Probably could be more selective here, but note that files related to irqs, |
| 45 | 41 | # boot, dumpstack/stacktrace, etc are either non-interesting or can lead to |
| @@ -41,8 +41,10 @@ static void __init spectre_v2_select_mitigation(void); · 40 unmodified lines | ||
| 41 | 41 | static void __init ssb_select_mitigation(void); |
| 42 | 42 | static void __init l1tf_select_mitigation(void); |
| 43 | 43 | static void __init mds_select_mitigation(void); |
| 44 | −static void __init mds_print_mitigation(void); | |
| 44 | +static void __init md_clear_update_mitigation(void); | |
| 45 | +static void __init md_clear_select_mitigation(void); | |
| 45 | 46 | static void __init taa_select_mitigation(void); |
| 47 | +static void __init mmio_select_mitigation(void); | |
| 46 | 48 | static void __init srbds_select_mitigation(void); |
| 47 | 49 | static void __init l1d_flush_select_mitigation(void); |
| 48 | 50 | |
| @@ -85,6 +87,10 @@ EXPORT_SYMBOL_GPL(mds_idle_clear); · 36 unmodified lines | ||
| 85 | 87 | */ |
| 86 | 88 | DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); |
| 87 | 89 | |
| 90 | +/* Controls CPU Fill buffer clear before KVM guest MMIO accesses */ | |
| 91 | +DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear); | |
| 92 | +EXPORT_SYMBOL_GPL(mmio_stale_data_clear); | |
| 93 | + | |
| 88 | 94 | void __init check_bugs(void) |
| 89 | 95 | { |
| 90 | 96 | identify_boot_cpu(); |
| @@ -117,17 +123,10 @@ void __init check_bugs(void) · 26 unmodified lines | ||
| 117 | 123 | spectre_v2_select_mitigation(); |
| 118 | 124 | ssb_select_mitigation(); |
| 119 | 125 | l1tf_select_mitigation(); |
| 120 | − mds_select_mitigation(); | |
| 121 | − taa_select_mitigation(); | |
| 126 | + md_clear_select_mitigation(); | |
| 122 | 127 | srbds_select_mitigation(); |
| 123 | 128 | l1d_flush_select_mitigation(); |
| 124 | 129 | |
| 125 | − /* | |
| 126 | − * As MDS and TAA mitigations are inter-related, print MDS | |
| 127 | − * mitigation until after TAA mitigation selection is done. | |
| 128 | − */ | |
| 129 | − mds_print_mitigation(); | |
| 130 | − | |
| 131 | 130 | arch_smt_update(); |
| 132 | 131 | |
| 133 | 132 | #ifdef CONFIG_X86_32 |
| @@ -267,14 +266,6 @@ static void __init mds_select_mitigation(void) · 133 unmodified lines | ||
| 267 | 266 | } |
| 268 | 267 | } |
| 269 | 268 | |
| 270 | −static void __init mds_print_mitigation(void) | |
| 271 | −{ | |
| 272 | − if (!boot_cpu_has_bug(X86_BUG_MDS) || cpu_mitigations_off()) | |
| 273 | − return; | |
| 274 | − | |
| 275 | − pr_info("%s\n", mds_strings[mds_mitigation]); | |
| 276 | −} | |
| 277 | − | |
| 278 | 269 | static int __init mds_cmdline(char *str) |
| 279 | 270 | { |
| 280 | 271 | if (!boot_cpu_has_bug(X86_BUG_MDS)) |
| @@ -329,7 +320,7 @@ static void __init taa_select_mitigation(void) · 48 unmodified lines | ||
| 329 | 320 | /* TSX previously disabled by tsx=off */ |
| 330 | 321 | if (!boot_cpu_has(X86_FEATURE_RTM)) { |
| 331 | 322 | taa_mitigation = TAA_MITIGATION_TSX_DISABLED; |
| 332 | − goto out; | |
| 323 | + return; | |
| 333 | 324 | } |
| 334 | 325 | |
| 335 | 326 | if (cpu_mitigations_off()) { |
| @@ -343,7 +334,7 @@ static void __init taa_select_mitigation(void) · 7 unmodified lines | ||
| 343 | 334 | */ |
| 344 | 335 | if (taa_mitigation == TAA_MITIGATION_OFF && |
| 345 | 336 | mds_mitigation == MDS_MITIGATION_OFF) |
| 346 | − goto out; | |
| 337 | + return; | |
| 347 | 338 | |
| 348 | 339 | if (boot_cpu_has(X86_FEATURE_MD_CLEAR)) |
| 349 | 340 | taa_mitigation = TAA_MITIGATION_VERW; |
| @@ -375,18 +366,6 @@ static void __init taa_select_mitigation(void) · 25 unmodified lines | ||
| 375 | 366 | |
| 376 | 367 | if (taa_nosmt || cpu_mitigations_auto_nosmt()) |
| 377 | 368 | cpu_smt_disable(false); |
| 378 | − | |
| 379 | − /* | |
| 380 | − * Update MDS mitigation, if necessary, as the mds_user_clear is | |
| 381 | − * now enabled for TAA mitigation. | |
| 382 | − */ | |
| 383 | − if (mds_mitigation == MDS_MITIGATION_OFF && | |
| 384 | − boot_cpu_has_bug(X86_BUG_MDS)) { | |
| 385 | − mds_mitigation = MDS_MITIGATION_FULL; | |
| 386 | − mds_select_mitigation(); | |
| 387 | − } | |
| 388 | −out: | |
| 389 | − pr_info("%s\n", taa_strings[taa_mitigation]); | |
| 390 | 369 | } |
| 391 | 370 | |
| 392 | 371 | static int __init tsx_async_abort_parse_cmdline(char *str) |
| @@ -410,6 +389,151 @@ static int __init tsx_async_abort_parse_cmdline(char *str) · 17 unmodified lines | ||
| 410 | 389 | } |
| 411 | 390 | early_param("tsx_async_abort", tsx_async_abort_parse_cmdline); |
| 412 | 391 | |
| 392 | +#undef pr_fmt | |
| 393 | +#define pr_fmt(fmt) "MMIO Stale Data: " fmt | |
| 394 | + | |
| 395 | +enum mmio_mitigations { | |
| 396 | + MMIO_MITIGATION_OFF, | |
| 397 | + MMIO_MITIGATION_UCODE_NEEDED, | |
| 398 | + MMIO_MITIGATION_VERW, | |
| 399 | +}; | |
| 400 | + | |
| 401 | +/* Default mitigation for Processor MMIO Stale Data vulnerabilities */ | |
| 402 | +static enum mmio_mitigations mmio_mitigation __ro_after_init = MMIO_MITIGATION_VERW; | |
| 403 | +static bool mmio_nosmt __ro_after_init = false; | |
| 404 | + | |
| 405 | +static const char * const mmio_strings[] = { | |
| 406 | + [MMIO_MITIGATION_OFF] = "Vulnerable", | |
| 407 | + [MMIO_MITIGATION_UCODE_NEEDED] = "Vulnerable: Clear CPU buffers attempted, no microcode", | |
| 408 | + [MMIO_MITIGATION_VERW] = "Mitigation: Clear CPU buffers", | |
| 409 | +}; | |
| 410 | + | |
| 411 | +static void __init mmio_select_mitigation(void) | |
| 412 | +{ | |
| 413 | + u64 ia32_cap; | |
| 414 | + | |
| 415 | + if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) || | |
| 416 | + cpu_mitigations_off()) { | |
| 417 | + mmio_mitigation = MMIO_MITIGATION_OFF; | |
| 418 | + return; | |
| 419 | + } | |
| 420 | + | |
| 421 | + if (mmio_mitigation == MMIO_MITIGATION_OFF) | |
| 422 | + return; | |
| 423 | + | |
| 424 | + ia32_cap = x86_read_arch_cap_msr(); | |
| 425 | + | |
| 426 | + /* | |
| 427 | + * Enable CPU buffer clear mitigation for host and VMM, if also affected | |
| 428 | + * by MDS or TAA. Otherwise, enable mitigation for VMM only. | |
| 429 | + */ | |
| 430 | + if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) && | |
| 431 | + boot_cpu_has(X86_FEATURE_RTM))) | |
| 432 | + static_branch_enable(&mds_user_clear); | |
| 433 | + else | |
| 434 | + static_branch_enable(&mmio_stale_data_clear); | |
| 435 | + | |
| 436 | + /* | |
| 437 | + * If Processor-MMIO-Stale-Data bug is present and Fill Buffer data can | |
| 438 | + * be propagated to uncore buffers, clearing the Fill buffers on idle | |
| 439 | + * is required irrespective of SMT state. | |
| 440 | + */ | |
| 441 | + if (!(ia32_cap & ARCH_CAP_FBSDP_NO)) | |
| 442 | + static_branch_enable(&mds_idle_clear); | |
| 443 | + | |
| 444 | + /* | |
| 445 | + * Check if the system has the right microcode. | |
| 446 | + * | |
| 447 | + * CPU Fill buffer clear mitigation is enumerated by either an explicit | |
| 448 | + * FB_CLEAR or by the presence of both MD_CLEAR and L1D_FLUSH on MDS | |
| 449 | + * affected systems. | |
| 450 | + */ | |
| 451 | + if ((ia32_cap & ARCH_CAP_FB_CLEAR) || | |
| 452 | + (boot_cpu_has(X86_FEATURE_MD_CLEAR) && | |
| 453 | + boot_cpu_has(X86_FEATURE_FLUSH_L1D) && | |
| 454 | + !(ia32_cap & ARCH_CAP_MDS_NO))) | |
| 455 | + mmio_mitigation = MMIO_MITIGATION_VERW; | |
| 456 | + else | |
| 457 | + mmio_mitigation = MMIO_MITIGATION_UCODE_NEEDED; | |
| 458 | + | |
| 459 | + if (mmio_nosmt || cpu_mitigations_auto_nosmt()) | |
| 460 | + cpu_smt_disable(false); | |
| 461 | +} | |
| 462 | + | |
| 463 | +static int __init mmio_stale_data_parse_cmdline(char *str) | |
| 464 | +{ | |
| 465 | + if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) | |
| 466 | + return 0; | |
| 467 | + | |
| 468 | + if (!str) | |
| 469 | + return -EINVAL; | |
| 470 | + | |
| 471 | + if (!strcmp(str, "off")) { | |
| 472 | + mmio_mitigation = MMIO_MITIGATION_OFF; | |
| 473 | + } else if (!strcmp(str, "full")) { | |
| 474 | + mmio_mitigation = MMIO_MITIGATION_VERW; | |
| 475 | + } else if (!strcmp(str, "full,nosmt")) { | |
| 476 | + mmio_mitigation = MMIO_MITIGATION_VERW; | |
| 477 | + mmio_nosmt = true; | |
| 478 | + } | |
| 479 | + | |
| 480 | + return 0; | |
| 481 | +} | |
| 482 | +early_param("mmio_stale_data", mmio_stale_data_parse_cmdline); | |
| 483 | + | |
| 484 | +#undef pr_fmt | |
| 485 | +#define pr_fmt(fmt) "" fmt | |
| 486 | + | |
| 487 | +static void __init md_clear_update_mitigation(void) | |
| 488 | +{ | |
| 489 | + if (cpu_mitigations_off()) | |
| 490 | + return; | |
| 491 | + | |
| 492 | + if (!static_key_enabled(&mds_user_clear)) | |
| 493 | + goto out; | |
| 494 | + | |
| 495 | + /* | |
| 496 | + * mds_user_clear is now enabled. Update MDS, TAA and MMIO Stale Data | |
| 497 | + * mitigation, if necessary. | |
| 498 | + */ | |
| 499 | + if (mds_mitigation == MDS_MITIGATION_OFF && | |
| 500 | + boot_cpu_has_bug(X86_BUG_MDS)) { | |
| 501 | + mds_mitigation = MDS_MITIGATION_FULL; | |
| 502 | + mds_select_mitigation(); | |
| 503 | + } | |
| 504 | + if (taa_mitigation == TAA_MITIGATION_OFF && | |
| 505 | + boot_cpu_has_bug(X86_BUG_TAA)) { | |
| 506 | + taa_mitigation = TAA_MITIGATION_VERW; | |
| 507 | + taa_select_mitigation(); | |
| 508 | + } | |
| 509 | + if (mmio_mitigation == MMIO_MITIGATION_OFF && | |
| 510 | + boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { | |
| 511 | + mmio_mitigation = MMIO_MITIGATION_VERW; | |
| 512 | + mmio_select_mitigation(); | |
| 513 | + } | |
| 514 | +out: | |
| 515 | + if (boot_cpu_has_bug(X86_BUG_MDS)) | |
| 516 | + pr_info("MDS: %s\n", mds_strings[mds_mitigation]); | |
| 517 | + if (boot_cpu_has_bug(X86_BUG_TAA)) | |
| 518 | + pr_info("TAA: %s\n", taa_strings[taa_mitigation]); | |
| 519 | + if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) | |
| 520 | + pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]); | |
| 521 | +} | |
| 522 | + | |
| 523 | +static void __init md_clear_select_mitigation(void) | |
| 524 | +{ | |
| 525 | + mds_select_mitigation(); | |
| 526 | + taa_select_mitigation(); | |
| 527 | + mmio_select_mitigation(); | |
| 528 | + | |
| 529 | + /* | |
| 530 | + * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update | |
| 531 | + * and print their mitigation after MDS, TAA and MMIO Stale Data | |
| 532 | + * mitigation selection is done. | |
| 533 | + */ | |
| 534 | + md_clear_update_mitigation(); | |
| 535 | +} | |
| 536 | + | |
| 413 | 537 | #undef pr_fmt |
| 414 | 538 | #define pr_fmt(fmt) "SRBDS: " fmt |
| 415 | 539 | |
| @@ -478,11 +602,13 @@ static void __init srbds_select_mitigation(void) · 62 unmodified lines | ||
| 478 | 602 | return; |
| 479 | 603 | |
| 480 | 604 | /* |
| 481 | − * Check to see if this is one of the MDS_NO systems supporting | |
| 482 | − * TSX that are only exposed to SRBDS when TSX is enabled. | |
| 605 | + * Check to see if this is one of the MDS_NO systems supporting TSX that | |
| 606 | + * are only exposed to SRBDS when TSX is enabled or when CPU is affected | |
| 607 | + * by Processor MMIO Stale Data vulnerability. | |
| 483 | 608 | */ |
| 484 | 609 | ia32_cap = x86_read_arch_cap_msr(); |
| 485 | − if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM)) | |
| 610 | + if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) && | |
| 611 | + !boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) | |
| 486 | 612 | srbds_mitigation = SRBDS_MITIGATION_TSX_OFF; |
| 487 | 613 | else if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
| 488 | 614 | srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR; |
| @@ -1116,6 +1242,8 @@ static void update_indir_branch_cond(void) · 627 unmodified lines | ||
| 1116 | 1242 | /* Update the static key controlling the MDS CPU buffer clear in idle */ |
| 1117 | 1243 | static void update_mds_branch_idle(void) |
| 1118 | 1244 | { |
| 1245 | + u64 ia32_cap = x86_read_arch_cap_msr(); | |
| 1246 | + | |
| 1119 | 1247 | /* |
| 1120 | 1248 | * Enable the idle clearing if SMT is active on CPUs which are |
| 1121 | 1249 | * affected only by MSBDS and not any other MDS variant. |
| @@ -1127,14 +1255,17 @@ static void update_mds_branch_idle(void) · 5 unmodified lines | ||
| 1127 | 1255 | if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY)) |
| 1128 | 1256 | return; |
| 1129 | 1257 | |
| 1130 | − if (sched_smt_active()) | |
| 1258 | + if (sched_smt_active()) { | |
| 1131 | 1259 | static_branch_enable(&mds_idle_clear); |
| 1132 | − else | |
| 1260 | + } else if (mmio_mitigation == MMIO_MITIGATION_OFF || | |
| 1261 | + (ia32_cap & ARCH_CAP_FBSDP_NO)) { | |
| 1133 | 1262 | static_branch_disable(&mds_idle_clear); |
| 1263 | + } | |
| 1134 | 1264 | } |
| 1135 | 1265 | |
| 1136 | 1266 | #define MDS_MSG_SMT "MDS CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for more details.\n" |
| 1137 | 1267 | #define TAA_MSG_SMT "TAA CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html for more details.\n" |
| 1268 | +#define MMIO_MSG_SMT "MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.\n" | |
| 1138 | 1269 | |
| 1139 | 1270 | void cpu_bugs_smt_update(void) |
| 1140 | 1271 | { |
| @@ -1179,6 +1310,16 @@ void cpu_bugs_smt_update(void) · 38 unmodified lines | ||
| 1179 | 1310 | break; |
| 1180 | 1311 | } |
| 1181 | 1312 | |
| 1313 | + switch (mmio_mitigation) { | |
| 1314 | + case MMIO_MITIGATION_VERW: | |
| 1315 | + case MMIO_MITIGATION_UCODE_NEEDED: | |
| 1316 | + if (sched_smt_active()) | |
| 1317 | + pr_warn_once(MMIO_MSG_SMT); | |
| 1318 | + break; | |
| 1319 | + case MMIO_MITIGATION_OFF: | |
| 1320 | + break; | |
| 1321 | + } | |
| 1322 | + | |
| 1182 | 1323 | mutex_unlock(&spec_ctrl_mutex); |
| 1183 | 1324 | } |
| 1184 | 1325 | |
| @@ -1781,6 +1922,20 @@ static ssize_t tsx_async_abort_show_state(char *buf) · 596 unmodified lines | ||
| 1781 | 1922 | sched_smt_active() ? "vulnerable" : "disabled"); |
| 1782 | 1923 | } |
| 1783 | 1924 | |
| 1925 | +static ssize_t mmio_stale_data_show_state(char *buf) | |
| 1926 | +{ | |
| 1927 | + if (mmio_mitigation == MMIO_MITIGATION_OFF) | |
| 1928 | + return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]); | |
| 1929 | + | |
| 1930 | + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { | |
| 1931 | + return sysfs_emit(buf, "%s; SMT Host state unknown\n", | |
| 1932 | + mmio_strings[mmio_mitigation]); | |
| 1933 | + } | |
| 1934 | + | |
| 1935 | + return sysfs_emit(buf, "%s; SMT %s\n", mmio_strings[mmio_mitigation], | |
| 1936 | + sched_smt_active() ? "vulnerable" : "disabled"); | |
| 1937 | +} | |
| 1938 | + | |
| 1784 | 1939 | static char *stibp_state(void) |
| 1785 | 1940 | { |
| 1786 | 1941 | if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) |
| @@ -1881,6 +2036,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr · 94 unmodified lines | ||
| 1881 | 2036 | case X86_BUG_SRBDS: |
| 1882 | 2037 | return srbds_show_state(buf); |
| 1883 | 2038 | |
| 2039 | + case X86_BUG_MMIO_STALE_DATA: | |
| 2040 | + return mmio_stale_data_show_state(buf); | |
| 2041 | + | |
| 1884 | 2042 | default: |
| 1885 | 2043 | break; |
| 1886 | 2044 | } |
| @@ -1932,4 +2090,9 @@ ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char * · 45 unmodified lines | ||
| 1932 | 2090 | { |
| 1933 | 2091 | return cpu_show_common(dev, attr, buf, X86_BUG_SRBDS); |
| 1934 | 2092 | } |
| 2093 | + | |
| 2094 | +ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf) | |
| 2095 | +{ | |
| 2096 | + return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA); | |
| 2097 | +} | |
| 1935 | 2098 | #endif |
| @@ -1211,18 +1211,42 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { · 1210 unmodified lines | ||
| 1211 | 1211 | X86_FEATURE_ANY, issues) |
| 1212 | 1212 | |
| 1213 | 1213 | #define SRBDS BIT(0) |
| 1214 | +/* CPU is affected by X86_BUG_MMIO_STALE_DATA */ | |
| 1215 | +#define MMIO BIT(1) | |
| 1216 | +/* CPU is affected by Shared Buffers Data Sampling (SBDS), a variant of X86_BUG_MMIO_STALE_DATA */ | |
| 1217 | +#define MMIO_SBDS BIT(2) | |
| 1214 | 1218 | |
| 1215 | 1219 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { |
| 1216 | 1220 | VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), |
| 1217 | 1221 | VULNBL_INTEL_STEPPINGS(HASWELL, X86_STEPPING_ANY, SRBDS), |
| 1218 | 1222 | VULNBL_INTEL_STEPPINGS(HASWELL_L, X86_STEPPING_ANY, SRBDS), |
| 1219 | 1223 | VULNBL_INTEL_STEPPINGS(HASWELL_G, X86_STEPPING_ANY, SRBDS), |
| 1224 | + VULNBL_INTEL_STEPPINGS(HASWELL_X, BIT(2) | BIT(4), MMIO), | |
| 1225 | + VULNBL_INTEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x3, 0x5), MMIO), | |
| 1220 | 1226 | VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), |
| 1227 | + VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), | |
| 1221 | 1228 | VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), |
| 1229 | + VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO), | |
| 1222 | 1230 | VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS), |
| 1231 | + VULNBL_INTEL_STEPPINGS(SKYLAKE_X, BIT(3) | BIT(4) | BIT(6) | | |
| 1232 | + BIT(7) | BIT(0xB), MMIO), | |
| 1233 | + VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO), | |
| 1223 | 1234 | VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS), |
| 1224 | − VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0xC), SRBDS), | |
| 1225 | − VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0xD), SRBDS), | |
| 1235 | + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x9, 0xC), SRBDS | MMIO), | |
| 1236 | + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0x8), SRBDS), | |
| 1237 | + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x9, 0xD), SRBDS | MMIO), | |
| 1238 | + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0x8), SRBDS), | |
| 1239 | + VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPINGS(0x5, 0x5), MMIO | MMIO_SBDS), | |
| 1240 | + VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x1, 0x1), MMIO), | |
| 1241 | + VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0x6), MMIO), | |
| 1242 | + VULNBL_INTEL_STEPPINGS(COMETLAKE, BIT(2) | BIT(3) | BIT(5), MMIO | MMIO_SBDS), | |
| 1243 | + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS), | |
| 1244 | + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO), | |
| 1245 | + VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS), | |
| 1246 | + VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPINGS(0x1, 0x1), MMIO), | |
| 1247 | + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS), | |
| 1248 | + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), | |
| 1249 | + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPINGS(0x0, 0x0), MMIO | MMIO_SBDS), | |
| 1226 | 1250 | {} |
| 1227 | 1251 | }; |
| 1228 | 1252 | |
| @@ -1243,6 +1267,13 @@ u64 x86_read_arch_cap_msr(void) · 14 unmodified lines | ||
| 1243 | 1267 | return ia32_cap; |
| 1244 | 1268 | } |
| 1245 | 1269 | |
| 1270 | +static bool arch_cap_mmio_immune(u64 ia32_cap) | |
| 1271 | +{ | |
| 1272 | + return (ia32_cap & ARCH_CAP_FBSDP_NO && | |
| 1273 | + ia32_cap & ARCH_CAP_PSDP_NO && | |
| 1274 | + ia32_cap & ARCH_CAP_SBDR_SSDP_NO); | |
| 1275 | +} | |
| 1276 | + | |
| 1246 | 1277 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
| 1247 | 1278 | { |
| 1248 | 1279 | u64 ia32_cap = x86_read_arch_cap_msr(); |
| @@ -1296,12 +1327,27 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) · 47 unmodified lines | ||
| 1296 | 1327 | /* |
| 1297 | 1328 | * SRBDS affects CPUs which support RDRAND or RDSEED and are listed |
| 1298 | 1329 | * in the vulnerability blacklist. |
| 1330 | + * | |
| 1331 | + * Some of the implications and mitigation of Shared Buffers Data | |
| 1332 | + * Sampling (SBDS) are similar to SRBDS. Give SBDS same treatment as | |
| 1333 | + * SRBDS. | |
| 1299 | 1334 | */ |
| 1300 | 1335 | if ((cpu_has(c, X86_FEATURE_RDRAND) || |
| 1301 | 1336 | cpu_has(c, X86_FEATURE_RDSEED)) && |
| 1302 | − cpu_matches(cpu_vuln_blacklist, SRBDS)) | |
| 1337 | + cpu_matches(cpu_vuln_blacklist, SRBDS | MMIO_SBDS)) | |
| 1303 | 1338 | setup_force_cpu_bug(X86_BUG_SRBDS); |
| 1304 | 1339 | |
| 1340 | + /* | |
| 1341 | + * Processor MMIO Stale Data bug enumeration | |
| 1342 | + * | |
| 1343 | + * Affected CPU list is generally enough to enumerate the vulnerability, | |
| 1344 | + * but for virtualization case check for ARCH_CAP MSR bits also, VMM may | |
| 1345 | + * not want the guest to enumerate the bug. | |
| 1346 | + */ | |
| 1347 | + if (cpu_matches(cpu_vuln_blacklist, MMIO) && | |
| 1348 | + !arch_cap_mmio_immune(ia32_cap)) | |
| 1349 | + setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); | |
| 1350 | + | |
| 1305 | 1351 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1306 | 1352 | return; |
| 1307 | 1353 | |
| @@ -175,6 +175,7 @@ SYM_INNER_LABEL(ftrace_caller_end, SYM_L_GLOBAL) · 174 unmodified lines | ||
| 175 | 175 | |
| 176 | 176 | jmp ftrace_epilogue |
| 177 | 177 | SYM_FUNC_END(ftrace_caller); |
| 178 | +STACK_FRAME_NON_STANDARD_FP(ftrace_caller) | |
| 178 | 179 | |
| 179 | 180 | SYM_FUNC_START(ftrace_epilogue) |
| 180 | 181 | /* |
| @@ -282,6 +283,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL) · 101 unmodified lines | ||
| 282 | 283 | jmp ftrace_epilogue |
| 283 | 284 | |
| 284 | 285 | SYM_FUNC_END(ftrace_regs_caller) |
| 286 | +STACK_FRAME_NON_STANDARD_FP(ftrace_regs_caller) | |
| 285 | 287 | |
| 286 | 288 | |
| 287 | 289 | #else /* ! CONFIG_DYNAMIC_FTRACE */ |
| @@ -311,10 +313,14 @@ trace: · 23 unmodified lines | ||
| 311 | 313 | jmp ftrace_stub |
| 312 | 314 | SYM_FUNC_END(__fentry__) |
| 313 | 315 | EXPORT_SYMBOL(__fentry__) |
| 316 | +STACK_FRAME_NON_STANDARD_FP(__fentry__) | |
| 317 | + | |
| 314 | 318 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 315 | 319 | |
| 316 | 320 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 317 | −SYM_FUNC_START(return_to_handler) | |
| 321 | +SYM_CODE_START(return_to_handler) | |
| 322 | + UNWIND_HINT_EMPTY | |
| 323 | + ANNOTATE_NOENDBR | |
| 318 | 324 | subq $16, %rsp |
| 319 | 325 | |
| 320 | 326 | /* Save the return values */ |
| @@ -339,7 +345,6 @@ SYM_FUNC_START(return_to_handler) · 18 unmodified lines | ||
| 339 | 345 | int3 |
| 340 | 346 | .Ldo_rop: |
| 341 | 347 | mov %rdi, (%rsp) |
| 342 | − UNWIND_HINT_FUNC | |
| 343 | 348 | RET |
| 344 | −SYM_FUNC_END(return_to_handler) | |
| 349 | +SYM_CODE_END(return_to_handler) | |
| 345 | 350 | #endif |
| @@ -1,7 +1,8 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | −#include <linux/dev_printk.h> | |
| 3 | 2 | #include <linux/ioport.h> |
| 3 | +#include <linux/printk.h> | |
| 4 | 4 | #include <asm/e820/api.h> |
| 5 | +#include <asm/pci_x86.h> | |
| 5 | 6 | |
| 6 | 7 | static void resource_clip(struct resource *res, resource_size_t start, |
| 7 | 8 | resource_size_t end) |
| @@ -24,14 +25,14 @@ static void resource_clip(struct resource *res, resource_size_t start, · 16 unmodified lines | ||
| 24 | 25 | res->start = end + 1; |
| 25 | 26 | } |
| 26 | 27 | |
| 27 | −void remove_e820_regions(struct device *dev, struct resource *avail) | |
| 28 | +static void remove_e820_regions(struct resource *avail) | |
| 28 | 29 | { |
| 29 | 30 | int i; |
| 30 | 31 | struct e820_entry *entry; |
| 31 | 32 | u64 e820_start, e820_end; |
| 32 | 33 | struct resource orig = *avail; |
| 33 | 34 | |
| 34 | − if (!(avail->flags & IORESOURCE_MEM)) | |
| 35 | + if (!pci_use_e820) | |
| 35 | 36 | return; |
| 36 | 37 | |
| 37 | 38 | for (i = 0; i < e820_table->nr_entries; i++) { |
| @@ -41,7 +42,7 @@ void remove_e820_regions(struct device *dev, struct resource *avail) · 3 unmodified lines | ||
| 41 | 42 | |
| 42 | 43 | resource_clip(avail, e820_start, e820_end); |
| 43 | 44 | if (orig.start != avail->start || orig.end != avail->end) { |
| 44 | − dev_info(dev, "clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", | |
| 45 | + pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", | |
| 45 | 46 | &orig, avail, e820_start, e820_end); |
| 46 | 47 | orig = *avail; |
| 47 | 48 | } |
| @@ -55,6 +56,9 @@ void arch_remove_reservations(struct resource *avail) · 7 unmodified lines | ||
| 55 | 56 | * the low 1MB unconditionally, as this area is needed for some ISA |
| 56 | 57 | * cards requiring a memory range, e.g. the i82365 PCMCIA controller. |
| 57 | 58 | */ |
| 58 | − if (avail->flags & IORESOURCE_MEM) | |
| 59 | + if (avail->flags & IORESOURCE_MEM) { | |
| 59 | 60 | resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); |
| 61 | + | |
| 62 | + remove_e820_regions(avail); | |
| 63 | + } | |
| 60 | 64 | } |
| @@ -67,11 +67,6 @@ RESERVE_BRK(dmi_alloc, 65536); · 66 unmodified lines | ||
| 67 | 67 | #endif |
| 68 | 68 | |
| 69 | 69 | |
| 70 | −/* | |
| 71 | − * Range of the BSS area. The size of the BSS area is determined | |
| 72 | − * at link time, with RESERVE_BRK() facility reserving additional | |
| 73 | − * chunks. | |
| 74 | − */ | |
| 75 | 70 | unsigned long _brk_start = (unsigned long)__brk_base; |
| 76 | 71 | unsigned long _brk_end = (unsigned long)__brk_base; |
| 77 | 72 | |
| @@ -385,10 +385,10 @@ SECTIONS · 384 unmodified lines | ||
| 385 | 385 | __end_of_kernel_reserve = .; |
| 386 | 386 | |
| 387 | 387 | . = ALIGN(PAGE_SIZE); |
| 388 | − .brk : AT(ADDR(.brk) - LOAD_OFFSET) { | |
| 388 | + .brk (NOLOAD) : AT(ADDR(.brk) - LOAD_OFFSET) { | |
| 389 | 389 | __brk_base = .; |
| 390 | 390 | . += 64 * 1024; /* 64k alignment slop space */ |
| 391 | − *(.brk_reservation) /* areas brk users have reserved */ | |
| 391 | + *(.bss..brk) /* areas brk users have reserved */ | |
| 392 | 392 | __brk_limit = .; |
| 393 | 393 | } |
| 394 | 394 | |
| @@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) · 2038 unmodified lines | ||
| 2039 | 2039 | } |
| 2040 | 2040 | } |
| 2041 | 2041 | |
| 2042 | +static void kvm_lapic_xapic_id_updated(struct kvm_lapic *apic) | |
| 2043 | +{ | |
| 2044 | + struct kvm *kvm = apic->vcpu->kvm; | |
| 2045 | + | |
| 2046 | + if (KVM_BUG_ON(apic_x2apic_mode(apic), kvm)) | |
| 2047 | + return; | |
| 2048 | + | |
| 2049 | + if (kvm_xapic_id(apic) == apic->vcpu->vcpu_id) | |
| 2050 | + return; | |
| 2051 | + | |
| 2052 | + kvm_set_apicv_inhibit(apic->vcpu->kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); | |
| 2053 | +} | |
| 2054 | + | |
| 2042 | 2055 | static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) |
| 2043 | 2056 | { |
| 2044 | 2057 | int ret = 0; |
| @@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) · 2 unmodified lines | ||
| 2047 | 2060 | |
| 2048 | 2061 | switch (reg) { |
| 2049 | 2062 | case APIC_ID: /* Local APIC ID */ |
| 2050 | − if (!apic_x2apic_mode(apic)) | |
| 2063 | + if (!apic_x2apic_mode(apic)) { | |
| 2051 | 2064 | kvm_apic_set_xapic_id(apic, val >> 24); |
| 2052 | − else | |
| 2065 | + kvm_lapic_xapic_id_updated(apic); | |
| 2066 | + } else { | |
| 2053 | 2067 | ret = 1; |
| 2068 | + } | |
| 2054 | 2069 | break; |
| 2055 | 2070 | |
| 2056 | 2071 | case APIC_TASKPRI: |
| @@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) · 279 unmodified lines | ||
| 2336 | 2351 | MSR_IA32_APICBASE_BASE; |
| 2337 | 2352 | |
| 2338 | 2353 | if ((value & MSR_IA32_APICBASE_ENABLE) && |
| 2339 | − apic->base_address != APIC_DEFAULT_PHYS_BASE) | |
| 2340 | − pr_warn_once("APIC base relocation is unsupported by KVM"); | |
| 2354 | + apic->base_address != APIC_DEFAULT_PHYS_BASE) { | |
| 2355 | + kvm_set_apicv_inhibit(apic->vcpu->kvm, | |
| 2356 | + APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); | |
| 2357 | + } | |
| 2341 | 2358 | } |
| 2342 | 2359 | |
| 2343 | 2360 | void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) |
| @@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu, · 304 unmodified lines | ||
| 2648 | 2665 | icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); |
| 2649 | 2666 | __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32); |
| 2650 | 2667 | } |
| 2668 | + } else { | |
| 2669 | + kvm_lapic_xapic_id_updated(vcpu->arch.apic); | |
| 2651 | 2670 | } |
| 2652 | 2671 | |
| 2653 | 2672 | return 0; |
| @@ -3411,7 +3411,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) · 3410 unmodified lines | ||
| 3411 | 3411 | root = mmu_alloc_root(vcpu, i << (30 - PAGE_SHIFT), |
| 3412 | 3412 | i << 30, PT32_ROOT_LEVEL, true); |
| 3413 | 3413 | mmu->pae_root[i] = root | PT_PRESENT_MASK | |
| 3414 | − shadow_me_mask; | |
| 3414 | + shadow_me_value; | |
| 3415 | 3415 | } |
| 3416 | 3416 | mmu->root.hpa = __pa(mmu->pae_root); |
| 3417 | 3417 | } else { |
| @@ -291,58 +291,91 @@ void avic_ring_doorbell(struct kvm_vcpu *vcpu) · 290 unmodified lines | ||
| 291 | 291 | static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source, |
| 292 | 292 | u32 icrl, u32 icrh, u32 index) |
| 293 | 293 | { |
| 294 | − u32 dest, apic_id; | |
| 295 | − struct kvm_vcpu *vcpu; | |
| 294 | + u32 l1_physical_id, dest; | |
| 295 | + struct kvm_vcpu *target_vcpu; | |
| 296 | 296 | int dest_mode = icrl & APIC_DEST_MASK; |
| 297 | 297 | int shorthand = icrl & APIC_SHORT_MASK; |
| 298 | 298 | struct kvm_svm *kvm_svm = to_kvm_svm(kvm); |
| 299 | − u32 *avic_logical_id_table = page_address(kvm_svm->avic_logical_id_table_page); | |
| 300 | 299 | |
| 301 | 300 | if (shorthand != APIC_DEST_NOSHORT) |
| 302 | 301 | return -EINVAL; |
| 303 | 302 | |
| 304 | − /* | |
| 305 | − * The AVIC incomplete IPI #vmexit info provides index into | |
| 306 | − * the physical APIC ID table, which can be used to derive | |
| 307 | − * guest physical APIC ID. | |
| 308 | − */ | |
| 303 | + if (apic_x2apic_mode(source)) | |
| 304 | + dest = icrh; | |
| 305 | + else | |
| 306 | + dest = GET_APIC_DEST_FIELD(icrh); | |
| 307 | + | |
| 309 | 308 | if (dest_mode == APIC_DEST_PHYSICAL) { |
| 310 | − apic_id = index; | |
| 309 | + /* broadcast destination, use slow path */ | |
| 310 | + if (apic_x2apic_mode(source) && dest == X2APIC_BROADCAST) | |
| 311 | + return -EINVAL; | |
| 312 | + if (!apic_x2apic_mode(source) && dest == APIC_BROADCAST) | |
| 313 | + return -EINVAL; | |
| 314 | + | |
| 315 | + l1_physical_id = dest; | |
| 316 | + | |
| 317 | + if (WARN_ON_ONCE(l1_physical_id != index)) | |
| 318 | + return -EINVAL; | |
| 319 | + | |
| 311 | 320 | } else { |
| 312 | − if (!apic_x2apic_mode(source)) { | |
| 313 | − /* For xAPIC logical mode, the index is for logical APIC table. */ | |
| 314 | − apic_id = avic_logical_id_table[index] & 0x1ff; | |
| 321 | + u32 bitmap, cluster; | |
| 322 | + int logid_index; | |
| 323 | + | |
| 324 | + if (apic_x2apic_mode(source)) { | |
| 325 | + /* 16 bit dest mask, 16 bit cluster id */ | |
| 326 | + bitmap = dest & 0xFFFF0000; | |
| 327 | + cluster = (dest >> 16) << 4; | |
| 328 | + } else if (kvm_lapic_get_reg(source, APIC_DFR) == APIC_DFR_FLAT) { | |
| 329 | + /* 8 bit dest mask*/ | |
| 330 | + bitmap = dest; | |
| 331 | + cluster = 0; | |
| 315 | 332 | } else { |
| 316 | − return -EINVAL; | |
| 333 | + /* 4 bit desk mask, 4 bit cluster id */ | |
| 334 | + bitmap = dest & 0xF; | |
| 335 | + cluster = (dest >> 4) << 2; | |
| 317 | 336 | } |
| 318 | − } | |
| 319 | 337 | |
| 320 | − /* | |
| 321 | − * Assuming vcpu ID is the same as physical apic ID, | |
| 322 | − * and use it to retrieve the target vCPU. | |
| 323 | − */ | |
| 324 | − vcpu = kvm_get_vcpu_by_id(kvm, apic_id); | |
| 325 | − if (!vcpu) | |
| 326 | − return -EINVAL; | |
| 338 | + if (unlikely(!bitmap)) | |
| 339 | + /* guest bug: nobody to send the logical interrupt to */ | |
| 340 | + return 0; | |
| 327 | 341 | |
| 328 | − if (apic_x2apic_mode(vcpu->arch.apic)) | |
| 329 | − dest = icrh; | |
| 330 | − else | |
| 331 | − dest = GET_APIC_DEST_FIELD(icrh); | |
| 342 | + if (!is_power_of_2(bitmap)) | |
| 343 | + /* multiple logical destinations, use slow path */ | |
| 344 | + return -EINVAL; | |
| 332 | 345 | |
| 333 | − /* | |
| 334 | − * Try matching the destination APIC ID with the vCPU. | |
| 335 | − */ | |
| 336 | − if (kvm_apic_match_dest(vcpu, source, shorthand, dest, dest_mode)) { | |
| 337 | − vcpu->arch.apic->irr_pending = true; | |
| 338 | − svm_complete_interrupt_delivery(vcpu, | |
| 339 | − icrl & APIC_MODE_MASK, | |
| 340 | − icrl & APIC_INT_LEVELTRIG, | |
| 341 | − icrl & APIC_VECTOR_MASK); | |
| 342 | − return 0; | |
| 346 | + logid_index = cluster + __ffs(bitmap); | |
| 347 | + | |
| 348 | + if (apic_x2apic_mode(source)) { | |
| 349 | + l1_physical_id = logid_index; | |
| 350 | + } else { | |
| 351 | + u32 *avic_logical_id_table = | |
| 352 | + page_address(kvm_svm->avic_logical_id_table_page); | |
| 353 | + | |
| 354 | + u32 logid_entry = avic_logical_id_table[logid_index]; | |
| 355 | + | |
| 356 | + if (WARN_ON_ONCE(index != logid_index)) | |
| 357 | + return -EINVAL; | |
| 358 | + | |
| 359 | + /* guest bug: non existing/reserved logical destination */ | |
| 360 | + if (unlikely(!(logid_entry & AVIC_LOGICAL_ID_ENTRY_VALID_MASK))) | |
| 361 | + return 0; | |
| 362 | + | |
| 363 | + l1_physical_id = logid_entry & | |
| 364 | + AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK; | |
| 365 | + } | |
| 343 | 366 | } |
| 344 | 367 | |
| 345 | − return -EINVAL; | |
| 368 | + target_vcpu = kvm_get_vcpu_by_id(kvm, l1_physical_id); | |
| 369 | + if (unlikely(!target_vcpu)) | |
| 370 | + /* guest bug: non existing vCPU is a target of this IPI*/ | |
| 371 | + return 0; | |
| 372 | + | |
| 373 | + target_vcpu->arch.apic->irr_pending = true; | |
| 374 | + svm_complete_interrupt_delivery(target_vcpu, | |
| 375 | + icrl & APIC_MODE_MASK, | |
| 376 | + icrl & APIC_INT_LEVELTRIG, | |
| 377 | + icrl & APIC_VECTOR_MASK); | |
| 378 | + return 0; | |
| 346 | 379 | } |
| 347 | 380 | |
| 348 | 381 | static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source, |
| @@ -508,35 +541,6 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu) · 159 unmodified lines | ||
| 508 | 541 | return ret; |
| 509 | 542 | } |
| 510 | 543 | |
| 511 | −static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu) | |
| 512 | −{ | |
| 513 | − u64 *old, *new; | |
| 514 | − struct vcpu_svm *svm = to_svm(vcpu); | |
| 515 | − u32 id = kvm_xapic_id(vcpu->arch.apic); | |
| 516 | − | |
| 517 | − if (vcpu->vcpu_id == id) | |
| 518 | − return 0; | |
| 519 | − | |
| 520 | − old = avic_get_physical_id_entry(vcpu, vcpu->vcpu_id); | |
| 521 | − new = avic_get_physical_id_entry(vcpu, id); | |
| 522 | − if (!new || !old) | |
| 523 | − return 1; | |
| 524 | − | |
| 525 | − /* We need to move physical_id_entry to new offset */ | |
| 526 | − *new = *old; | |
| 527 | − *old = 0ULL; | |
| 528 | − to_svm(vcpu)->avic_physical_id_cache = new; | |
| 529 | − | |
| 530 | − /* | |
| 531 | − * Also update the guest physical APIC ID in the logical | |
| 532 | − * APIC ID table entry if already setup the LDR. | |
| 533 | − */ | |
| 534 | − if (svm->ldr_reg) | |
| 535 | − avic_handle_ldr_update(vcpu); | |
| 536 | − | |
| 537 | − return 0; | |
| 538 | −} | |
| 539 | − | |
| 540 | 544 | static void avic_handle_dfr_update(struct kvm_vcpu *vcpu) |
| 541 | 545 | { |
| 542 | 546 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -555,10 +559,6 @@ static int avic_unaccel_trap_write(struct kvm_vcpu *vcpu) · 12 unmodified lines | ||
| 555 | 559 | AVIC_UNACCEL_ACCESS_OFFSET_MASK; |
| 556 | 560 | |
| 557 | 561 | switch (offset) { |
| 558 | − case APIC_ID: | |
| 559 | − if (avic_handle_apic_id_update(vcpu)) | |
| 560 | − return 0; | |
| 561 | − break; | |
| 562 | 562 | case APIC_LDR: |
| 563 | 563 | if (avic_handle_ldr_update(vcpu)) |
| 564 | 564 | return 0; |
| @@ -650,8 +650,6 @@ int avic_init_vcpu(struct vcpu_svm *svm) · 85 unmodified lines | ||
| 650 | 650 | |
| 651 | 651 | void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu) |
| 652 | 652 | { |
| 653 | − if (avic_handle_apic_id_update(vcpu) != 0) | |
| 654 | − return; | |
| 655 | 653 | avic_handle_dfr_update(vcpu); |
| 656 | 654 | avic_handle_ldr_update(vcpu); |
| 657 | 655 | } |
| @@ -910,7 +908,9 @@ bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason) · 252 unmodified lines | ||
| 910 | 908 | BIT(APICV_INHIBIT_REASON_PIT_REINJ) | |
| 911 | 909 | BIT(APICV_INHIBIT_REASON_X2APIC) | |
| 912 | 910 | BIT(APICV_INHIBIT_REASON_BLOCKIRQ) | |
| 913 | − BIT(APICV_INHIBIT_REASON_SEV); | |
| 911 | + BIT(APICV_INHIBIT_REASON_SEV) | | |
| 912 | + BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) | | |
| 913 | + BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); | |
| 914 | 914 | |
| 915 | 915 | return supported & BIT(reason); |
| 916 | 916 | } |
| @@ -946,7 +946,7 @@ out: · 29 unmodified lines | ||
| 946 | 946 | return ret; |
| 947 | 947 | } |
| 948 | 948 | |
| 949 | −void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |
| 949 | +void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |
| 950 | 950 | { |
| 951 | 951 | u64 entry; |
| 952 | 952 | int h_physical_id = kvm_cpu_get_apicid(cpu); |
| @@ -978,7 +978,7 @@ void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 25 unmodified lines | ||
| 978 | 978 | avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true); |
| 979 | 979 | } |
| 980 | 980 | |
| 981 | −void __avic_vcpu_put(struct kvm_vcpu *vcpu) | |
| 981 | +void avic_vcpu_put(struct kvm_vcpu *vcpu) | |
| 982 | 982 | { |
| 983 | 983 | u64 entry; |
| 984 | 984 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -997,25 +997,6 @@ void __avic_vcpu_put(struct kvm_vcpu *vcpu) · 12 unmodified lines | ||
| 997 | 997 | WRITE_ONCE(*(svm->avic_physical_id_cache), entry); |
| 998 | 998 | } |
| 999 | 999 | |
| 1000 | −static void avic_vcpu_load(struct kvm_vcpu *vcpu) | |
| 1001 | −{ | |
| 1002 | − int cpu = get_cpu(); | |
| 1003 | − | |
| 1004 | − WARN_ON(cpu != vcpu->cpu); | |
| 1005 | − | |
| 1006 | − __avic_vcpu_load(vcpu, cpu); | |
| 1007 | − | |
| 1008 | − put_cpu(); | |
| 1009 | −} | |
| 1010 | − | |
| 1011 | −static void avic_vcpu_put(struct kvm_vcpu *vcpu) | |
| 1012 | −{ | |
| 1013 | − preempt_disable(); | |
| 1014 | − | |
| 1015 | − __avic_vcpu_put(vcpu); | |
| 1016 | − | |
| 1017 | − preempt_enable(); | |
| 1018 | −} | |
| 1019 | 1000 | |
| 1020 | 1001 | void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) |
| 1021 | 1002 | { |
| @@ -1042,7 +1023,7 @@ void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) · 20 unmodified lines | ||
| 1042 | 1023 | vmcb_mark_dirty(vmcb, VMCB_AVIC); |
| 1043 | 1024 | |
| 1044 | 1025 | if (activated) |
| 1045 | − avic_vcpu_load(vcpu); | |
| 1026 | + avic_vcpu_load(vcpu, vcpu->cpu); | |
| 1046 | 1027 | else |
| 1047 | 1028 | avic_vcpu_put(vcpu); |
| 1048 | 1029 | |
| @@ -1075,5 +1056,5 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu) · 26 unmodified lines | ||
| 1075 | 1056 | if (!kvm_vcpu_apicv_active(vcpu)) |
| 1076 | 1057 | return; |
| 1077 | 1058 | |
| 1078 | − avic_vcpu_load(vcpu); | |
| 1059 | + avic_vcpu_load(vcpu, vcpu->cpu); | |
| 1079 | 1060 | } |
| @@ -616,6 +616,8 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm) · 615 unmodified lines | ||
| 616 | 616 | struct kvm_vcpu *vcpu = &svm->vcpu; |
| 617 | 617 | struct vmcb *vmcb01 = svm->vmcb01.ptr; |
| 618 | 618 | struct vmcb *vmcb02 = svm->nested.vmcb02.ptr; |
| 619 | + u32 pause_count12; | |
| 620 | + u32 pause_thresh12; | |
| 619 | 621 | |
| 620 | 622 | /* |
| 621 | 623 | * Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2, |
| @@ -671,27 +673,25 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm) · 49 unmodified lines | ||
| 671 | 673 | if (!nested_vmcb_needs_vls_intercept(svm)) |
| 672 | 674 | vmcb02->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK; |
| 673 | 675 | |
| 676 | + pause_count12 = svm->pause_filter_enabled ? svm->nested.ctl.pause_filter_count : 0; | |
| 677 | + pause_thresh12 = svm->pause_threshold_enabled ? svm->nested.ctl.pause_filter_thresh : 0; | |
| 674 | 678 | if (kvm_pause_in_guest(svm->vcpu.kvm)) { |
| 675 | − /* use guest values since host doesn't use them */ | |
| 676 | − vmcb02->control.pause_filter_count = | |
| 677 | − svm->pause_filter_enabled ? | |
| 678 | − svm->nested.ctl.pause_filter_count : 0; | |
| 679 | + /* use guest values since host doesn't intercept PAUSE */ | |
| 680 | + vmcb02->control.pause_filter_count = pause_count12; | |
| 681 | + vmcb02->control.pause_filter_thresh = pause_thresh12; | |
| 679 | 682 | |
| 680 | − vmcb02->control.pause_filter_thresh = | |
| 681 | − svm->pause_threshold_enabled ? | |
| 682 | − svm->nested.ctl.pause_filter_thresh : 0; | |
| 683 | − | |
| 684 | − } else if (!vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_PAUSE)) { | |
| 685 | − /* use host values when guest doesn't use them */ | |
| 683 | + } else { | |
| 684 | + /* start from host values otherwise */ | |
| 686 | 685 | vmcb02->control.pause_filter_count = vmcb01->control.pause_filter_count; |
| 687 | 686 | vmcb02->control.pause_filter_thresh = vmcb01->control.pause_filter_thresh; |
| 688 | − } else { | |
| 689 | − /* | |
| 690 | − * Intercept every PAUSE otherwise and | |
| 691 | − * ignore both host and guest values | |
| 692 | − */ | |
| 693 | − vmcb02->control.pause_filter_count = 0; | |
| 694 | − vmcb02->control.pause_filter_thresh = 0; | |
| 687 | + | |
| 688 | + /* ... but ensure filtering is disabled if so requested. */ | |
| 689 | + if (vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_PAUSE)) { | |
| 690 | + if (!pause_count12) | |
| 691 | + vmcb02->control.pause_filter_count = 0; | |
| 692 | + if (!pause_thresh12) | |
| 693 | + vmcb02->control.pause_filter_thresh = 0; | |
| 694 | + } | |
| 695 | 695 | } |
| 696 | 696 | |
| 697 | 697 | nested_svm_transition_tlb_flush(vcpu); |
| @@ -951,8 +951,11 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 253 unmodified lines | ||
| 951 | 951 | vmcb12->control.event_inj = svm->nested.ctl.event_inj; |
| 952 | 952 | vmcb12->control.event_inj_err = svm->nested.ctl.event_inj_err; |
| 953 | 953 | |
| 954 | − if (!kvm_pause_in_guest(vcpu->kvm) && vmcb02->control.pause_filter_count) | |
| 954 | + if (!kvm_pause_in_guest(vcpu->kvm)) { | |
| 955 | 955 | vmcb01->control.pause_filter_count = vmcb02->control.pause_filter_count; |
| 956 | + vmcb_mark_dirty(vmcb01, VMCB_INTERCEPTS); | |
| 957 | + | |
| 958 | + } | |
| 956 | 959 | |
| 957 | 960 | nested_svm_copy_common_state(svm->nested.vmcb02.ptr, svm->vmcb01.ptr); |
| 958 | 961 | |
| @@ -844,7 +844,7 @@ static int __sev_dbg_encrypt_user(struct kvm *kvm, unsigned long paddr, · 843 unmodified lines | ||
| 844 | 844 | |
| 845 | 845 | /* If source buffer is not aligned then use an intermediate buffer */ |
| 846 | 846 | if (!IS_ALIGNED((unsigned long)vaddr, 16)) { |
| 847 | − src_tpage = alloc_page(GFP_KERNEL); | |
| 847 | + src_tpage = alloc_page(GFP_KERNEL_ACCOUNT); | |
| 848 | 848 | if (!src_tpage) |
| 849 | 849 | return -ENOMEM; |
| 850 | 850 | |
| @@ -865,7 +865,7 @@ static int __sev_dbg_encrypt_user(struct kvm *kvm, unsigned long paddr, · 14 unmodified lines | ||
| 865 | 865 | if (!IS_ALIGNED((unsigned long)dst_vaddr, 16) || !IS_ALIGNED(size, 16)) { |
| 866 | 866 | int dst_offset; |
| 867 | 867 | |
| 868 | − dst_tpage = alloc_page(GFP_KERNEL); | |
| 868 | + dst_tpage = alloc_page(GFP_KERNEL_ACCOUNT); | |
| 869 | 869 | if (!dst_tpage) { |
| 870 | 870 | ret = -ENOMEM; |
| 871 | 871 | goto e_free; |
| @@ -1665,19 +1665,24 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm) · 793 unmodified lines | ||
| 1665 | 1665 | { |
| 1666 | 1666 | struct kvm_sev_info *dst = &to_kvm_svm(dst_kvm)->sev_info; |
| 1667 | 1667 | struct kvm_sev_info *src = &to_kvm_svm(src_kvm)->sev_info; |
| 1668 | + struct kvm_vcpu *dst_vcpu, *src_vcpu; | |
| 1669 | + struct vcpu_svm *dst_svm, *src_svm; | |
| 1668 | 1670 | struct kvm_sev_info *mirror; |
| 1671 | + unsigned long i; | |
| 1669 | 1672 | |
| 1670 | 1673 | dst->active = true; |
| 1671 | 1674 | dst->asid = src->asid; |
| 1672 | 1675 | dst->handle = src->handle; |
| 1673 | 1676 | dst->pages_locked = src->pages_locked; |
| 1674 | 1677 | dst->enc_context_owner = src->enc_context_owner; |
| 1678 | + dst->es_active = src->es_active; | |
| 1675 | 1679 | |
| 1676 | 1680 | src->asid = 0; |
| 1677 | 1681 | src->active = false; |
| 1678 | 1682 | src->handle = 0; |
| 1679 | 1683 | src->pages_locked = 0; |
| 1680 | 1684 | src->enc_context_owner = NULL; |
| 1685 | + src->es_active = false; | |
| 1681 | 1686 | |
| 1682 | 1687 | list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list); |
| 1683 | 1688 | |
| @@ -1704,26 +1709,21 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm) · 20 unmodified lines | ||
| 1704 | 1709 | list_del(&src->mirror_entry); |
| 1705 | 1710 | list_add_tail(&dst->mirror_entry, &owner_sev_info->mirror_vms); |
| 1706 | 1711 | } |
| 1707 | −} | |
| 1708 | 1712 | |
| 1709 | −static int sev_es_migrate_from(struct kvm *dst, struct kvm *src) | |
| 1710 | −{ | |
| 1711 | − unsigned long i; | |
| 1712 | − struct kvm_vcpu *dst_vcpu, *src_vcpu; | |
| 1713 | − struct vcpu_svm *dst_svm, *src_svm; | |
| 1713 | + kvm_for_each_vcpu(i, dst_vcpu, dst_kvm) { | |
| 1714 | + dst_svm = to_svm(dst_vcpu); | |
| 1714 | 1715 | |
| 1715 | − if (atomic_read(&src->online_vcpus) != atomic_read(&dst->online_vcpus)) | |
| 1716 | − return -EINVAL; | |
| 1716 | + sev_init_vmcb(dst_svm); | |
| 1717 | 1717 | |
| 1718 | − kvm_for_each_vcpu(i, src_vcpu, src) { | |
| 1719 | − if (!src_vcpu->arch.guest_state_protected) | |
| 1720 | − return -EINVAL; | |
| 1721 | − } | |
| 1718 | + if (!dst->es_active) | |
| 1719 | + continue; | |
| 1722 | 1720 | |
| 1723 | − kvm_for_each_vcpu(i, src_vcpu, src) { | |
| 1721 | + /* | |
| 1722 | + * Note, the source is not required to have the same number of | |
| 1723 | + * vCPUs as the destination when migrating a vanilla SEV VM. | |
| 1724 | + */ | |
| 1725 | + src_vcpu = kvm_get_vcpu(dst_kvm, i); | |
| 1724 | 1726 | src_svm = to_svm(src_vcpu); |
| 1725 | − dst_vcpu = kvm_get_vcpu(dst, i); | |
| 1726 | − dst_svm = to_svm(dst_vcpu); | |
| 1727 | 1727 | |
| 1728 | 1728 | /* |
| 1729 | 1729 | * Transfer VMSA and GHCB state to the destination. Nullify and |
| @@ -1740,8 +1740,23 @@ static int sev_es_migrate_from(struct kvm *dst, struct kvm *src) · 10 unmodified lines | ||
| 1740 | 1740 | src_svm->vmcb->control.vmsa_pa = INVALID_PAGE; |
| 1741 | 1741 | src_vcpu->arch.guest_state_protected = false; |
| 1742 | 1742 | } |
| 1743 | − to_kvm_svm(src)->sev_info.es_active = false; | |
| 1744 | − to_kvm_svm(dst)->sev_info.es_active = true; | |
| 1743 | +} | |
| 1744 | + | |
| 1745 | +static int sev_check_source_vcpus(struct kvm *dst, struct kvm *src) | |
| 1746 | +{ | |
| 1747 | + struct kvm_vcpu *src_vcpu; | |
| 1748 | + unsigned long i; | |
| 1749 | + | |
| 1750 | + if (!sev_es_guest(src)) | |
| 1751 | + return 0; | |
| 1752 | + | |
| 1753 | + if (atomic_read(&src->online_vcpus) != atomic_read(&dst->online_vcpus)) | |
| 1754 | + return -EINVAL; | |
| 1755 | + | |
| 1756 | + kvm_for_each_vcpu(i, src_vcpu, src) { | |
| 1757 | + if (!src_vcpu->arch.guest_state_protected) | |
| 1758 | + return -EINVAL; | |
| 1759 | + } | |
| 1745 | 1760 | |
| 1746 | 1761 | return 0; |
| 1747 | 1762 | } |
| @@ -1789,11 +1804,9 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd) · 41 unmodified lines | ||
| 1789 | 1804 | if (ret) |
| 1790 | 1805 | goto out_dst_vcpu; |
| 1791 | 1806 | |
| 1792 | − if (sev_es_guest(source_kvm)) { | |
| 1793 | − ret = sev_es_migrate_from(kvm, source_kvm); | |
| 1794 | − if (ret) | |
| 1795 | − goto out_source_vcpu; | |
| 1796 | − } | |
| 1807 | + ret = sev_check_source_vcpus(kvm, source_kvm); | |
| 1808 | + if (ret) | |
| 1809 | + goto out_source_vcpu; | |
| 1797 | 1810 | |
| 1798 | 1811 | sev_migrate_from(kvm, source_kvm); |
| 1799 | 1812 | kvm_vm_dead(source_kvm); |
| @@ -2914,7 +2927,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) · 1114 unmodified lines | ||
| 2914 | 2927 | count, in); |
| 2915 | 2928 | } |
| 2916 | 2929 | |
| 2917 | −void sev_es_init_vmcb(struct vcpu_svm *svm) | |
| 2930 | +static void sev_es_init_vmcb(struct vcpu_svm *svm) | |
| 2918 | 2931 | { |
| 2919 | 2932 | struct kvm_vcpu *vcpu = &svm->vcpu; |
| 2920 | 2933 | |
| @@ -2967,6 +2980,15 @@ void sev_es_init_vmcb(struct vcpu_svm *svm) · 46 unmodified lines | ||
| 2967 | 2980 | } |
| 2968 | 2981 | } |
| 2969 | 2982 | |
| 2983 | +void sev_init_vmcb(struct vcpu_svm *svm) | |
| 2984 | +{ | |
| 2985 | + svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; | |
| 2986 | + clr_exception_intercept(svm, UD_VECTOR); | |
| 2987 | + | |
| 2988 | + if (sev_es_guest(svm->vcpu.kvm)) | |
| 2989 | + sev_es_init_vmcb(svm); | |
| 2990 | +} | |
| 2991 | + | |
| 2970 | 2992 | void sev_es_vcpu_reset(struct vcpu_svm *svm) |
| 2971 | 2993 | { |
| 2972 | 2994 | /* |
| @@ -921,7 +921,7 @@ static void grow_ple_window(struct kvm_vcpu *vcpu) · 920 unmodified lines | ||
| 921 | 921 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 922 | 922 | int old = control->pause_filter_count; |
| 923 | 923 | |
| 924 | − if (kvm_pause_in_guest(vcpu->kvm) || !old) | |
| 924 | + if (kvm_pause_in_guest(vcpu->kvm)) | |
| 925 | 925 | return; |
| 926 | 926 | |
| 927 | 927 | control->pause_filter_count = __grow_ple_window(old, |
| @@ -942,7 +942,7 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu) · 14 unmodified lines | ||
| 942 | 942 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 943 | 943 | int old = control->pause_filter_count; |
| 944 | 944 | |
| 945 | − if (kvm_pause_in_guest(vcpu->kvm) || !old) | |
| 945 | + if (kvm_pause_in_guest(vcpu->kvm)) | |
| 946 | 946 | return; |
| 947 | 947 | |
| 948 | 948 | control->pause_filter_count = |
| @@ -1212,15 +1212,8 @@ static void init_vmcb(struct kvm_vcpu *vcpu) · 263 unmodified lines | ||
| 1212 | 1212 | svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK; |
| 1213 | 1213 | } |
| 1214 | 1214 | |
| 1215 | − if (sev_guest(vcpu->kvm)) { | |
| 1216 | − svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; | |
| 1217 | − clr_exception_intercept(svm, UD_VECTOR); | |
| 1218 | − | |
| 1219 | − if (sev_es_guest(vcpu->kvm)) { | |
| 1220 | − /* Perform SEV-ES specific VMCB updates */ | |
| 1221 | − sev_es_init_vmcb(svm); | |
| 1222 | − } | |
| 1223 | − } | |
| 1215 | + if (sev_guest(vcpu->kvm)) | |
| 1216 | + sev_init_vmcb(svm); | |
| 1224 | 1217 | |
| 1225 | 1218 | svm_hv_init_vmcb(vmcb); |
| 1226 | 1219 | init_vmcb_after_set_cpuid(vcpu); |
| @@ -1400,13 +1393,13 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 173 unmodified lines | ||
| 1400 | 1393 | indirect_branch_prediction_barrier(); |
| 1401 | 1394 | } |
| 1402 | 1395 | if (kvm_vcpu_apicv_active(vcpu)) |
| 1403 | − __avic_vcpu_load(vcpu, cpu); | |
| 1396 | + avic_vcpu_load(vcpu, cpu); | |
| 1404 | 1397 | } |
| 1405 | 1398 | |
| 1406 | 1399 | static void svm_vcpu_put(struct kvm_vcpu *vcpu) |
| 1407 | 1400 | { |
| 1408 | 1401 | if (kvm_vcpu_apicv_active(vcpu)) |
| 1409 | − __avic_vcpu_put(vcpu); | |
| 1402 | + avic_vcpu_put(vcpu); | |
| 1410 | 1403 | |
| 1411 | 1404 | svm_prepare_host_switch(vcpu); |
| 1412 | 1405 | |
| @@ -610,8 +610,8 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb); · 609 unmodified lines | ||
| 610 | 610 | int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu); |
| 611 | 611 | int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu); |
| 612 | 612 | int avic_init_vcpu(struct vcpu_svm *svm); |
| 613 | −void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu); | |
| 614 | −void __avic_vcpu_put(struct kvm_vcpu *vcpu); | |
| 613 | +void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu); | |
| 614 | +void avic_vcpu_put(struct kvm_vcpu *vcpu); | |
| 615 | 615 | void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu); |
| 616 | 616 | void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu); |
| 617 | 617 | void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu); |
| @@ -649,10 +649,10 @@ void __init sev_set_cpu_caps(void); · 31 unmodified lines | ||
| 649 | 649 | void __init sev_hardware_setup(void); |
| 650 | 650 | void sev_hardware_unsetup(void); |
| 651 | 651 | int sev_cpu_init(struct svm_cpu_data *sd); |
| 652 | +void sev_init_vmcb(struct vcpu_svm *svm); | |
| 652 | 653 | void sev_free_vcpu(struct kvm_vcpu *vcpu); |
| 653 | 654 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); |
| 654 | 655 | int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); |
| 655 | −void sev_es_init_vmcb(struct vcpu_svm *svm); | |
| 656 | 656 | void sev_es_vcpu_reset(struct vcpu_svm *svm); |
| 657 | 657 | void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); |
| 658 | 658 | void sev_es_prepare_switch_to_guest(struct sev_es_save_area *hostsa); |
| @@ -229,6 +229,9 @@ static const struct { · 228 unmodified lines | ||
| 229 | 229 | #define L1D_CACHE_ORDER 4 |
| 230 | 230 | static void *vmx_l1d_flush_pages; |
| 231 | 231 | |
| 232 | +/* Control for disabling CPU Fill buffer clear */ | |
| 233 | +static bool __read_mostly vmx_fb_clear_ctrl_available; | |
| 234 | + | |
| 232 | 235 | static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) |
| 233 | 236 | { |
| 234 | 237 | struct page *page; |
| @@ -360,6 +363,60 @@ static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp) · 125 unmodified lines | ||
| 360 | 363 | return sprintf(s, "%s\n", vmentry_l1d_param[l1tf_vmx_mitigation].option); |
| 361 | 364 | } |
| 362 | 365 | |
| 366 | +static void vmx_setup_fb_clear_ctrl(void) | |
| 367 | +{ | |
| 368 | + u64 msr; | |
| 369 | + | |
| 370 | + if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES) && | |
| 371 | + !boot_cpu_has_bug(X86_BUG_MDS) && | |
| 372 | + !boot_cpu_has_bug(X86_BUG_TAA)) { | |
| 373 | + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, msr); | |
| 374 | + if (msr & ARCH_CAP_FB_CLEAR_CTRL) | |
| 375 | + vmx_fb_clear_ctrl_available = true; | |
| 376 | + } | |
| 377 | +} | |
| 378 | + | |
| 379 | +static __always_inline void vmx_disable_fb_clear(struct vcpu_vmx *vmx) | |
| 380 | +{ | |
| 381 | + u64 msr; | |
| 382 | + | |
| 383 | + if (!vmx->disable_fb_clear) | |
| 384 | + return; | |
| 385 | + | |
| 386 | + rdmsrl(MSR_IA32_MCU_OPT_CTRL, msr); | |
| 387 | + msr |= FB_CLEAR_DIS; | |
| 388 | + wrmsrl(MSR_IA32_MCU_OPT_CTRL, msr); | |
| 389 | + /* Cache the MSR value to avoid reading it later */ | |
| 390 | + vmx->msr_ia32_mcu_opt_ctrl = msr; | |
| 391 | +} | |
| 392 | + | |
| 393 | +static __always_inline void vmx_enable_fb_clear(struct vcpu_vmx *vmx) | |
| 394 | +{ | |
| 395 | + if (!vmx->disable_fb_clear) | |
| 396 | + return; | |
| 397 | + | |
| 398 | + vmx->msr_ia32_mcu_opt_ctrl &= ~FB_CLEAR_DIS; | |
| 399 | + wrmsrl(MSR_IA32_MCU_OPT_CTRL, vmx->msr_ia32_mcu_opt_ctrl); | |
| 400 | +} | |
| 401 | + | |
| 402 | +static void vmx_update_fb_clear_dis(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx) | |
| 403 | +{ | |
| 404 | + vmx->disable_fb_clear = vmx_fb_clear_ctrl_available; | |
| 405 | + | |
| 406 | + /* | |
| 407 | + * If guest will not execute VERW, there is no need to set FB_CLEAR_DIS | |
| 408 | + * at VMEntry. Skip the MSR read/write when a guest has no use case to | |
| 409 | + * execute VERW. | |
| 410 | + */ | |
| 411 | + if ((vcpu->arch.arch_capabilities & ARCH_CAP_FB_CLEAR) || | |
| 412 | + ((vcpu->arch.arch_capabilities & ARCH_CAP_MDS_NO) && | |
| 413 | + (vcpu->arch.arch_capabilities & ARCH_CAP_TAA_NO) && | |
| 414 | + (vcpu->arch.arch_capabilities & ARCH_CAP_PSDP_NO) && | |
| 415 | + (vcpu->arch.arch_capabilities & ARCH_CAP_FBSDP_NO) && | |
| 416 | + (vcpu->arch.arch_capabilities & ARCH_CAP_SBDR_SSDP_NO))) | |
| 417 | + vmx->disable_fb_clear = false; | |
| 418 | +} | |
| 419 | + | |
| 363 | 420 | static const struct kernel_param_ops vmentry_l1d_flush_ops = { |
| 364 | 421 | .set = vmentry_l1d_flush_set, |
| 365 | 422 | .get = vmentry_l1d_flush_get, |
| @@ -2252,6 +2309,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 1886 unmodified lines | ||
| 2252 | 2309 | ret = kvm_set_msr_common(vcpu, msr_info); |
| 2253 | 2310 | } |
| 2254 | 2311 | |
| 2312 | + /* FB_CLEAR may have changed, also update the FB_CLEAR_DIS behavior */ | |
| 2313 | + if (msr_index == MSR_IA32_ARCH_CAPABILITIES) | |
| 2314 | + vmx_update_fb_clear_dis(vcpu, vmx); | |
| 2315 | + | |
| 2255 | 2316 | return ret; |
| 2256 | 2317 | } |
| 2257 | 2318 | |
| @@ -4553,6 +4614,8 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 2295 unmodified lines | ||
| 4553 | 4614 | kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); |
| 4554 | 4615 | |
| 4555 | 4616 | vpid_sync_context(vmx->vpid); |
| 4617 | + | |
| 4618 | + vmx_update_fb_clear_dis(vcpu, vmx); | |
| 4556 | 4619 | } |
| 4557 | 4620 | |
| 4558 | 4621 | static void vmx_enable_irq_window(struct kvm_vcpu *vcpu) |
| @@ -6772,6 +6835,11 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, · 2213 unmodified lines | ||
| 6772 | 6835 | vmx_l1d_flush(vcpu); |
| 6773 | 6836 | else if (static_branch_unlikely(&mds_user_clear)) |
| 6774 | 6837 | mds_clear_cpu_buffers(); |
| 6838 | + else if (static_branch_unlikely(&mmio_stale_data_clear) && | |
| 6839 | + kvm_arch_has_assigned_device(vcpu->kvm)) | |
| 6840 | + mds_clear_cpu_buffers(); | |
| 6841 | + | |
| 6842 | + vmx_disable_fb_clear(vmx); | |
| 6775 | 6843 | |
| 6776 | 6844 | if (vcpu->arch.cr2 != native_read_cr2()) |
| 6777 | 6845 | native_write_cr2(vcpu->arch.cr2); |
| @@ -6781,6 +6849,8 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, · 3 unmodified lines | ||
| 6781 | 6849 | |
| 6782 | 6850 | vcpu->arch.cr2 = native_read_cr2(); |
| 6783 | 6851 | |
| 6852 | + vmx_enable_fb_clear(vmx); | |
| 6853 | + | |
| 6784 | 6854 | guest_state_exit_irqoff(); |
| 6785 | 6855 | } |
| 6786 | 6856 | |
| @@ -7709,7 +7779,9 @@ static bool vmx_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason) · 922 unmodified lines | ||
| 7709 | 7779 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | |
| 7710 | 7780 | BIT(APICV_INHIBIT_REASON_ABSENT) | |
| 7711 | 7781 | BIT(APICV_INHIBIT_REASON_HYPERV) | |
| 7712 | − BIT(APICV_INHIBIT_REASON_BLOCKIRQ); | |
| 7782 | + BIT(APICV_INHIBIT_REASON_BLOCKIRQ) | | |
| 7783 | + BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) | | |
| 7784 | + BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); | |
| 7713 | 7785 | |
| 7714 | 7786 | return supported & BIT(reason); |
| 7715 | 7787 | } |
| @@ -8212,6 +8284,8 @@ static int __init vmx_init(void) · 496 unmodified lines | ||
| 8212 | 8284 | return r; |
| 8213 | 8285 | } |
| 8214 | 8286 | |
| 8287 | + vmx_setup_fb_clear_ctrl(); | |
| 8288 | + | |
| 8215 | 8289 | for_each_possible_cpu(cpu) { |
| 8216 | 8290 | INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); |
| 8217 | 8291 | |
| @@ -348,6 +348,8 @@ struct vcpu_vmx { · 347 unmodified lines | ||
| 348 | 348 | u64 msr_ia32_feature_control_valid_bits; |
| 349 | 349 | /* SGX Launch Control public key hash */ |
| 350 | 350 | u64 msr_ia32_sgxlepubkeyhash[4]; |
| 351 | + u64 msr_ia32_mcu_opt_ctrl; | |
| 352 | + bool disable_fb_clear; | |
| 351 | 353 | |
| 352 | 354 | struct pt_desc pt_desc; |
| 353 | 355 | struct lbr_desc lbr_desc; |
| @@ -1617,6 +1617,9 @@ static u64 kvm_get_arch_capabilities(void) · 1616 unmodified lines | ||
| 1617 | 1617 | */ |
| 1618 | 1618 | } |
| 1619 | 1619 | |
| 1620 | + /* Guests don't need to know "Fill buffer clear control" exists */ | |
| 1621 | + data &= ~ARCH_CAP_FB_CLEAR_CTRL; | |
| 1622 | + | |
| 1620 | 1623 | return data; |
| 1621 | 1624 | } |
| 1622 | 1625 | |
| @@ -9850,6 +9853,7 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu) · 8227 unmodified lines | ||
| 9850 | 9853 | return; |
| 9851 | 9854 | |
| 9852 | 9855 | down_read(&vcpu->kvm->arch.apicv_update_lock); |
| 9856 | + preempt_disable(); | |
| 9853 | 9857 | |
| 9854 | 9858 | activate = kvm_vcpu_apicv_activated(vcpu); |
| 9855 | 9859 | |
| @@ -9870,6 +9874,7 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu) · 14 unmodified lines | ||
| 9870 | 9874 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
| 9871 | 9875 | |
| 9872 | 9876 | out: |
| 9877 | + preempt_enable(); | |
| 9873 | 9878 | up_read(&vcpu->kvm->arch.apicv_update_lock); |
| 9874 | 9879 | } |
| 9875 | 9880 | EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv); |
| @@ -1420,8 +1420,9 @@ st: if (is_imm8(insn->off)) · 1419 unmodified lines | ||
| 1420 | 1420 | case BPF_JMP | BPF_CALL: |
| 1421 | 1421 | func = (u8 *) __bpf_call_base + imm32; |
| 1422 | 1422 | if (tail_call_reachable) { |
| 1423 | + /* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */ | |
| 1423 | 1424 | EMIT3_off32(0x48, 0x8B, 0x85, |
| 1424 | − -(bpf_prog->aux->stack_depth + 8)); | |
| 1425 | + -round_up(bpf_prog->aux->stack_depth, 8) - 8); | |
| 1425 | 1426 | if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7)) |
| 1426 | 1427 | return -EINVAL; |
| 1427 | 1428 | } else { |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/pci-acpi.h> |
| 9 | 9 | #include <asm/numa.h> |
| 10 | 10 | #include <asm/pci_x86.h> |
| 11 | −#include <asm/e820/api.h> | |
| 12 | 11 | |
| 13 | 12 | struct pci_root_info { |
| 14 | 13 | struct acpi_pci_root_info common; |
| @@ -20,7 +19,7 @@ struct pci_root_info { · 5 unmodified lines | ||
| 20 | 19 | #endif |
| 21 | 20 | }; |
| 22 | 21 | |
| 23 | −static bool pci_use_e820 = true; | |
| 22 | +bool pci_use_e820 = true; | |
| 24 | 23 | static bool pci_use_crs = true; |
| 25 | 24 | static bool pci_ignore_seg; |
| 26 | 25 | |
| @@ -387,11 +386,6 @@ static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci) · 360 unmodified lines | ||
| 387 | 386 | |
| 388 | 387 | status = acpi_pci_probe_root_resources(ci); |
| 389 | 388 | |
| 390 | − if (pci_use_e820) { | |
| 391 | − resource_list_for_each_entry(entry, &ci->resources) | |
| 392 | − remove_e820_regions(&device->dev, entry->res); | |
| 393 | − } | |
| 394 | − | |
| 395 | 389 | if (pci_use_crs) { |
| 396 | 390 | resource_list_for_each_entry_safe(entry, tmp, &ci->resources) |
| 397 | 391 | if (resource_is_pcicfg_ioport(entry->res)) |
| @@ -2173,7 +2173,7 @@ ENDPROC(ret_from_kernel_thread) · 2172 unmodified lines | ||
| 2173 | 2173 | |
| 2174 | 2174 | #ifdef CONFIG_HIBERNATION |
| 2175 | 2175 | |
| 2176 | − .bss | |
| 2176 | + .section .bss, "aw" | |
| 2177 | 2177 | .align 4 |
| 2178 | 2178 | .Lsaved_regs: |
| 2179 | 2179 | #if defined(__XTENSA_WINDOWED_ABI__) |
| @@ -154,6 +154,7 @@ static void __init calibrate_ccount(void) · 153 unmodified lines | ||
| 154 | 154 | cpu = of_find_compatible_node(NULL, NULL, "cdns,xtensa-cpu"); |
| 155 | 155 | if (cpu) { |
| 156 | 156 | clk = of_clk_get(cpu, 0); |
| 157 | + of_node_put(cpu); | |
| 157 | 158 | if (!IS_ERR(clk)) { |
| 158 | 159 | ccount_freq = clk_get_rate(clk); |
| 159 | 160 | return; |
| @@ -133,6 +133,7 @@ static int __init machine_setup(void) · 132 unmodified lines | ||
| 133 | 133 | |
| 134 | 134 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) |
| 135 | 135 | update_local_mac(eth); |
| 136 | + of_node_put(eth); | |
| 136 | 137 | return 0; |
| 137 | 138 | } |
| 138 | 139 | arch_initcall(machine_setup); |
| @@ -7046,6 +7046,7 @@ static void bfq_exit_queue(struct elevator_queue *e) · 7045 unmodified lines | ||
| 7046 | 7046 | spin_unlock_irq(&bfqd->lock); |
| 7047 | 7047 | #endif |
| 7048 | 7048 | |
| 7049 | + blk_stat_disable_accounting(bfqd->queue); | |
| 7049 | 7050 | wbt_enable_default(bfqd->queue); |
| 7050 | 7051 | |
| 7051 | 7052 | kfree(bfqd); |
| @@ -7188,7 +7189,12 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) · 136 unmodified lines | ||
| 7188 | 7189 | bfq_init_root_group(bfqd->root_group, bfqd); |
| 7189 | 7190 | bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); |
| 7190 | 7191 | |
| 7192 | + /* We dispatch from request queue wide instead of hw queue */ | |
| 7193 | + blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q); | |
| 7194 | + | |
| 7191 | 7195 | wbt_disable_default(q); |
| 7196 | + blk_stat_enable_accounting(q); | |
| 7197 | + | |
| 7192 | 7198 | return 0; |
| 7193 | 7199 | |
| 7194 | 7200 | out_free: |
| @@ -322,19 +322,6 @@ void blk_cleanup_queue(struct request_queue *q) · 321 unmodified lines | ||
| 322 | 322 | blk_mq_exit_queue(q); |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | − /* | |
| 326 | − * In theory, request pool of sched_tags belongs to request queue. | |
| 327 | − * However, the current implementation requires tag_set for freeing | |
| 328 | − * requests, so free the pool now. | |
| 329 | − * | |
| 330 | − * Queue has become frozen, there can't be any in-queue requests, so | |
| 331 | − * it is safe to free requests now. | |
| 332 | − */ | |
| 333 | − mutex_lock(&q->sysfs_lock); | |
| 334 | − if (q->elevator) | |
| 335 | − blk_mq_sched_free_rqs(q); | |
| 336 | − mutex_unlock(&q->sysfs_lock); | |
| 337 | − | |
| 338 | 325 | /* @q is and will stay empty, shutdown and put */ |
| 339 | 326 | blk_put_queue(q); |
| 340 | 327 | } |
| @@ -144,7 +144,6 @@ int disk_register_independent_access_ranges(struct gendisk *disk, · 143 unmodified lines | ||
| 144 | 144 | } |
| 145 | 145 | |
| 146 | 146 | for (i = 0; i < iars->nr_ia_ranges; i++) { |
| 147 | − iars->ia_range[i].queue = q; | |
| 148 | 147 | ret = kobject_init_and_add(&iars->ia_range[i].kobj, |
| 149 | 148 | &blk_ia_range_ktype, &iars->kobj, |
| 150 | 149 | "%d", i); |
| @@ -711,11 +711,6 @@ void blk_mq_debugfs_register(struct request_queue *q) · 710 unmodified lines | ||
| 711 | 711 | } |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | −void blk_mq_debugfs_unregister(struct request_queue *q) | |
| 715 | −{ | |
| 716 | − q->sched_debugfs_dir = NULL; | |
| 717 | −} | |
| 718 | − | |
| 719 | 714 | static void blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx, |
| 720 | 715 | struct blk_mq_ctx *ctx) |
| 721 | 716 | { |
| @@ -746,6 +741,8 @@ void blk_mq_debugfs_register_hctx(struct request_queue *q, · 24 unmodified lines | ||
| 746 | 741 | |
| 747 | 742 | void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx) |
| 748 | 743 | { |
| 744 | + if (!hctx->queue->debugfs_dir) | |
| 745 | + return; | |
| 749 | 746 | debugfs_remove_recursive(hctx->debugfs_dir); |
| 750 | 747 | hctx->sched_debugfs_dir = NULL; |
| 751 | 748 | hctx->debugfs_dir = NULL; |
| @@ -773,6 +770,8 @@ void blk_mq_debugfs_register_sched(struct request_queue *q) · 21 unmodified lines | ||
| 773 | 770 | { |
| 774 | 771 | struct elevator_type *e = q->elevator->type; |
| 775 | 772 | |
| 773 | + lockdep_assert_held(&q->debugfs_mutex); | |
| 774 | + | |
| 776 | 775 | /* |
| 777 | 776 | * If the parent directory has not been created yet, return, we will be |
| 778 | 777 | * called again later on and the directory/files will be created then. |
| @@ -790,6 +789,8 @@ void blk_mq_debugfs_register_sched(struct request_queue *q) · 11 unmodified lines | ||
| 790 | 789 | |
| 791 | 790 | void blk_mq_debugfs_unregister_sched(struct request_queue *q) |
| 792 | 791 | { |
| 792 | + lockdep_assert_held(&q->debugfs_mutex); | |
| 793 | + | |
| 793 | 794 | debugfs_remove_recursive(q->sched_debugfs_dir); |
| 794 | 795 | q->sched_debugfs_dir = NULL; |
| 795 | 796 | } |
| @@ -811,6 +812,10 @@ static const char *rq_qos_id_to_name(enum rq_qos_id id) · 15 unmodified lines | ||
| 811 | 812 | |
| 812 | 813 | void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos) |
| 813 | 814 | { |
| 815 | + lockdep_assert_held(&rqos->q->debugfs_mutex); | |
| 816 | + | |
| 817 | + if (!rqos->q->debugfs_dir) | |
| 818 | + return; | |
| 814 | 819 | debugfs_remove_recursive(rqos->debugfs_dir); |
| 815 | 820 | rqos->debugfs_dir = NULL; |
| 816 | 821 | } |
| @@ -820,6 +825,8 @@ void blk_mq_debugfs_register_rqos(struct rq_qos *rqos) · 3 unmodified lines | ||
| 820 | 825 | struct request_queue *q = rqos->q; |
| 821 | 826 | const char *dir_name = rq_qos_id_to_name(rqos->id); |
| 822 | 827 | |
| 828 | + lockdep_assert_held(&q->debugfs_mutex); | |
| 829 | + | |
| 823 | 830 | if (rqos->debugfs_dir || !rqos->ops->debugfs_attrs) |
| 824 | 831 | return; |
| 825 | 832 | |
| @@ -833,17 +840,13 @@ void blk_mq_debugfs_register_rqos(struct rq_qos *rqos) · 7 unmodified lines | ||
| 833 | 840 | debugfs_create_files(rqos->debugfs_dir, rqos, rqos->ops->debugfs_attrs); |
| 834 | 841 | } |
| 835 | 842 | |
| 836 | −void blk_mq_debugfs_unregister_queue_rqos(struct request_queue *q) | |
| 837 | −{ | |
| 838 | − debugfs_remove_recursive(q->rqos_debugfs_dir); | |
| 839 | − q->rqos_debugfs_dir = NULL; | |
| 840 | −} | |
| 841 | − | |
| 842 | 843 | void blk_mq_debugfs_register_sched_hctx(struct request_queue *q, |
| 843 | 844 | struct blk_mq_hw_ctx *hctx) |
| 844 | 845 | { |
| 845 | 846 | struct elevator_type *e = q->elevator->type; |
| 846 | 847 | |
| 848 | + lockdep_assert_held(&q->debugfs_mutex); | |
| 849 | + | |
| 847 | 850 | /* |
| 848 | 851 | * If the parent debugfs directory has not been created yet, return; |
| 849 | 852 | * We will be called again later on with appropriate parent debugfs |
| @@ -863,6 +866,10 @@ void blk_mq_debugfs_register_sched_hctx(struct request_queue *q, · 13 unmodified lines | ||
| 863 | 866 | |
| 864 | 867 | void blk_mq_debugfs_unregister_sched_hctx(struct blk_mq_hw_ctx *hctx) |
| 865 | 868 | { |
| 869 | + lockdep_assert_held(&hctx->queue->debugfs_mutex); | |
| 870 | + | |
| 871 | + if (!hctx->queue->debugfs_dir) | |
| 872 | + return; | |
| 866 | 873 | debugfs_remove_recursive(hctx->sched_debugfs_dir); |
| 867 | 874 | hctx->sched_debugfs_dir = NULL; |
| 868 | 875 | } |
| @@ -21,7 +21,6 @@ int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq); · 20 unmodified lines | ||
| 21 | 21 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v); |
| 22 | 22 | |
| 23 | 23 | void blk_mq_debugfs_register(struct request_queue *q); |
| 24 | −void blk_mq_debugfs_unregister(struct request_queue *q); | |
| 25 | 24 | void blk_mq_debugfs_register_hctx(struct request_queue *q, |
| 26 | 25 | struct blk_mq_hw_ctx *hctx); |
| 27 | 26 | void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx); |
| @@ -36,16 +35,11 @@ void blk_mq_debugfs_unregister_sched_hctx(struct blk_mq_hw_ctx *hctx); · 8 unmodified lines | ||
| 36 | 35 | |
| 37 | 36 | void blk_mq_debugfs_register_rqos(struct rq_qos *rqos); |
| 38 | 37 | void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos); |
| 39 | −void blk_mq_debugfs_unregister_queue_rqos(struct request_queue *q); | |
| 40 | 38 | #else |
| 41 | 39 | static inline void blk_mq_debugfs_register(struct request_queue *q) |
| 42 | 40 | { |
| 43 | 41 | } |
| 44 | 42 | |
| 45 | −static inline void blk_mq_debugfs_unregister(struct request_queue *q) | |
| 46 | −{ | |
| 47 | −} | |
| 48 | − | |
| 49 | 43 | static inline void blk_mq_debugfs_register_hctx(struct request_queue *q, |
| 50 | 44 | struct blk_mq_hw_ctx *hctx) |
| 51 | 45 | { |
| @@ -87,10 +81,6 @@ static inline void blk_mq_debugfs_register_rqos(struct rq_qos *rqos) · 35 unmodified lines | ||
| 87 | 81 | static inline void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos) |
| 88 | 82 | { |
| 89 | 83 | } |
| 90 | − | |
| 91 | −static inline void blk_mq_debugfs_unregister_queue_rqos(struct request_queue *q) | |
| 92 | −{ | |
| 93 | −} | |
| 94 | 84 | #endif |
| 95 | 85 | |
| 96 | 86 | #ifdef CONFIG_BLK_DEBUG_FS_ZONED |
| @@ -564,6 +564,7 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) · 563 unmodified lines | ||
| 564 | 564 | int ret; |
| 565 | 565 | |
| 566 | 566 | if (!e) { |
| 567 | + blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q); | |
| 567 | 568 | q->elevator = NULL; |
| 568 | 569 | q->nr_requests = q->tag_set->queue_depth; |
| 569 | 570 | return 0; |
| @@ -593,7 +594,9 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) · 23 unmodified lines | ||
| 593 | 594 | if (ret) |
| 594 | 595 | goto err_free_map_and_rqs; |
| 595 | 596 | |
| 597 | + mutex_lock(&q->debugfs_mutex); | |
| 596 | 598 | blk_mq_debugfs_register_sched(q); |
| 599 | + mutex_unlock(&q->debugfs_mutex); | |
| 597 | 600 | |
| 598 | 601 | queue_for_each_hw_ctx(q, hctx, i) { |
| 599 | 602 | if (e->ops.init_hctx) { |
| @@ -606,7 +609,9 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) · 6 unmodified lines | ||
| 606 | 609 | return ret; |
| 607 | 610 | } |
| 608 | 611 | } |
| 612 | + mutex_lock(&q->debugfs_mutex); | |
| 609 | 613 | blk_mq_debugfs_register_sched_hctx(q, hctx); |
| 614 | + mutex_unlock(&q->debugfs_mutex); | |
| 610 | 615 | } |
| 611 | 616 | |
| 612 | 617 | return 0; |
| @@ -647,14 +652,21 @@ void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e) · 34 unmodified lines | ||
| 647 | 652 | unsigned int flags = 0; |
| 648 | 653 | |
| 649 | 654 | queue_for_each_hw_ctx(q, hctx, i) { |
| 655 | + mutex_lock(&q->debugfs_mutex); | |
| 650 | 656 | blk_mq_debugfs_unregister_sched_hctx(hctx); |
| 657 | + mutex_unlock(&q->debugfs_mutex); | |
| 658 | + | |
| 651 | 659 | if (e->type->ops.exit_hctx && hctx->sched_data) { |
| 652 | 660 | e->type->ops.exit_hctx(hctx, i); |
| 653 | 661 | hctx->sched_data = NULL; |
| 654 | 662 | } |
| 655 | 663 | flags = hctx->flags; |
| 656 | 664 | } |
| 665 | + | |
| 666 | + mutex_lock(&q->debugfs_mutex); | |
| 657 | 667 | blk_mq_debugfs_unregister_sched(q); |
| 668 | + mutex_unlock(&q->debugfs_mutex); | |
| 669 | + | |
| 658 | 670 | if (e->type->ops.exit_sched) |
| 659 | 671 | e->type->ops.exit_sched(e); |
| 660 | 672 | blk_mq_sched_tags_teardown(q, flags); |
| @@ -579,6 +579,8 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, · 578 unmodified lines | ||
| 579 | 579 | if (!blk_mq_hw_queue_mapped(data.hctx)) |
| 580 | 580 | goto out_queue_exit; |
| 581 | 581 | cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask); |
| 582 | + if (cpu >= nr_cpu_ids) | |
| 583 | + goto out_queue_exit; | |
| 582 | 584 | data.ctx = __blk_mq_get_ctx(q, cpu); |
| 583 | 585 | |
| 584 | 586 | if (!q->elevator) |
| @@ -2140,20 +2142,6 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) · 1555 unmodified lines | ||
| 2140 | 2142 | } |
| 2141 | 2143 | EXPORT_SYMBOL(blk_mq_run_hw_queue); |
| 2142 | 2144 | |
| 2143 | −/* | |
| 2144 | − * Is the request queue handled by an IO scheduler that does not respect | |
| 2145 | − * hardware queues when dispatching? | |
| 2146 | − */ | |
| 2147 | −static bool blk_mq_has_sqsched(struct request_queue *q) | |
| 2148 | −{ | |
| 2149 | − struct elevator_queue *e = q->elevator; | |
| 2150 | − | |
| 2151 | − if (e && e->type->ops.dispatch_request && | |
| 2152 | − !(e->type->elevator_features & ELEVATOR_F_MQ_AWARE)) | |
| 2153 | − return true; | |
| 2154 | − return false; | |
| 2155 | −} | |
| 2156 | − | |
| 2157 | 2145 | /* |
| 2158 | 2146 | * Return prefered queue to dispatch from (if any) for non-mq aware IO |
| 2159 | 2147 | * scheduler. |
| @@ -2186,7 +2174,7 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async) · 26 unmodified lines | ||
| 2186 | 2174 | unsigned long i; |
| 2187 | 2175 | |
| 2188 | 2176 | sq_hctx = NULL; |
| 2189 | − if (blk_mq_has_sqsched(q)) | |
| 2177 | + if (blk_queue_sq_sched(q)) | |
| 2190 | 2178 | sq_hctx = blk_mq_get_sq_hctx(q); |
| 2191 | 2179 | queue_for_each_hw_ctx(q, hctx, i) { |
| 2192 | 2180 | if (blk_mq_hctx_stopped(hctx)) |
| @@ -2214,7 +2202,7 @@ void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs) · 21 unmodified lines | ||
| 2214 | 2202 | unsigned long i; |
| 2215 | 2203 | |
| 2216 | 2204 | sq_hctx = NULL; |
| 2217 | − if (blk_mq_has_sqsched(q)) | |
| 2205 | + if (blk_queue_sq_sched(q)) | |
| 2218 | 2206 | sq_hctx = blk_mq_get_sq_hctx(q); |
| 2219 | 2207 | queue_for_each_hw_ctx(q, hctx, i) { |
| 2220 | 2208 | if (blk_mq_hctx_stopped(hctx)) |
| @@ -2777,15 +2765,20 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, · 556 unmodified lines | ||
| 2777 | 2765 | return NULL; |
| 2778 | 2766 | } |
| 2779 | 2767 | |
| 2780 | − rq_qos_throttle(q, *bio); | |
| 2781 | − | |
| 2782 | 2768 | if (blk_mq_get_hctx_type((*bio)->bi_opf) != rq->mq_hctx->type) |
| 2783 | 2769 | return NULL; |
| 2784 | 2770 | if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) |
| 2785 | 2771 | return NULL; |
| 2786 | 2772 | |
| 2787 | − rq->cmd_flags = (*bio)->bi_opf; | |
| 2773 | + /* | |
| 2774 | + * If any qos ->throttle() end up blocking, we will have flushed the | |
| 2775 | + * plug and hence killed the cached_rq list as well. Pop this entry | |
| 2776 | + * before we throttle. | |
| 2777 | + */ | |
| 2788 | 2778 | plug->cached_rq = rq_list_next(rq); |
| 2779 | + rq_qos_throttle(q, *bio); | |
| 2780 | + | |
| 2781 | + rq->cmd_flags = (*bio)->bi_opf; | |
| 2789 | 2782 | INIT_LIST_HEAD(&rq->queuelist); |
| 2790 | 2783 | return rq; |
| 2791 | 2784 | } |
| @@ -3443,8 +3436,9 @@ static void blk_mq_exit_hctx(struct request_queue *q, · 651 unmodified lines | ||
| 3443 | 3436 | if (blk_mq_hw_queue_mapped(hctx)) |
| 3444 | 3437 | blk_mq_tag_idle(hctx); |
| 3445 | 3438 | |
| 3446 | − blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx], | |
| 3447 | − set->queue_depth, flush_rq); | |
| 3439 | + if (blk_queue_init_done(q)) | |
| 3440 | + blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx], | |
| 3441 | + set->queue_depth, flush_rq); | |
| 3448 | 3442 | if (set->ops->exit_request) |
| 3449 | 3443 | set->ops->exit_request(set, flush_rq, hctx_idx); |
| 3450 | 3444 | |
| @@ -4438,12 +4432,14 @@ static bool blk_mq_elv_switch_none(struct list_head *head, · 987 unmodified lines | ||
| 4438 | 4432 | if (!qe) |
| 4439 | 4433 | return false; |
| 4440 | 4434 | |
| 4435 | + /* q->elevator needs protection from ->sysfs_lock */ | |
| 4436 | + mutex_lock(&q->sysfs_lock); | |
| 4437 | + | |
| 4441 | 4438 | INIT_LIST_HEAD(&qe->node); |
| 4442 | 4439 | qe->q = q; |
| 4443 | 4440 | qe->type = q->elevator->type; |
| 4444 | 4441 | list_add(&qe->node, head); |
| 4445 | 4442 | |
| 4446 | − mutex_lock(&q->sysfs_lock); | |
| 4447 | 4443 | /* |
| 4448 | 4444 | * After elevator_switch_mq, the previous elevator_queue will be |
| 4449 | 4445 | * released by elevator_release. The reference of the io scheduler |
| @@ -294,8 +294,6 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data, · 293 unmodified lines | ||
| 294 | 294 | |
| 295 | 295 | void rq_qos_exit(struct request_queue *q) |
| 296 | 296 | { |
| 297 | − blk_mq_debugfs_unregister_queue_rqos(q); | |
| 298 | − | |
| 299 | 297 | while (q->rq_qos) { |
| 300 | 298 | struct rq_qos *rqos = q->rq_qos; |
| 301 | 299 | q->rq_qos = rqos->next; |
| @@ -104,8 +104,11 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos) · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | blk_mq_unfreeze_queue(q); |
| 106 | 106 | |
| 107 | − if (rqos->ops->debugfs_attrs) | |
| 107 | + if (rqos->ops->debugfs_attrs) { | |
| 108 | + mutex_lock(&q->debugfs_mutex); | |
| 108 | 109 | blk_mq_debugfs_register_rqos(rqos); |
| 110 | + mutex_unlock(&q->debugfs_mutex); | |
| 111 | + } | |
| 109 | 112 | } |
| 110 | 113 | |
| 111 | 114 | static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) |
| @@ -129,7 +132,9 @@ static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) · 17 unmodified lines | ||
| 129 | 132 | |
| 130 | 133 | blk_mq_unfreeze_queue(q); |
| 131 | 134 | |
| 135 | + mutex_lock(&q->debugfs_mutex); | |
| 132 | 136 | blk_mq_debugfs_unregister_rqos(rqos); |
| 137 | + mutex_unlock(&q->debugfs_mutex); | |
| 133 | 138 | } |
| 134 | 139 | |
| 135 | 140 | typedef bool (acquire_inflight_cb_t)(struct rq_wait *rqw, void *private_data); |
| @@ -779,14 +779,6 @@ static void blk_release_queue(struct kobject *kobj) · 778 unmodified lines | ||
| 779 | 779 | if (queue_is_mq(q)) |
| 780 | 780 | blk_mq_release(q); |
| 781 | 781 | |
| 782 | − blk_trace_shutdown(q); | |
| 783 | − mutex_lock(&q->debugfs_mutex); | |
| 784 | − debugfs_remove_recursive(q->debugfs_dir); | |
| 785 | − mutex_unlock(&q->debugfs_mutex); | |
| 786 | − | |
| 787 | − if (queue_is_mq(q)) | |
| 788 | − blk_mq_debugfs_unregister(q); | |
| 789 | − | |
| 790 | 782 | bioset_exit(&q->bio_split); |
| 791 | 783 | |
| 792 | 784 | if (blk_queue_has_srcu(q)) |
| @@ -836,17 +828,16 @@ int blk_register_queue(struct gendisk *disk) · 43 unmodified lines | ||
| 836 | 828 | goto unlock; |
| 837 | 829 | } |
| 838 | 830 | |
| 831 | + if (queue_is_mq(q)) | |
| 832 | + __blk_mq_register_dev(dev, q); | |
| 833 | + mutex_lock(&q->sysfs_lock); | |
| 834 | + | |
| 839 | 835 | mutex_lock(&q->debugfs_mutex); |
| 840 | 836 | q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), |
| 841 | 837 | blk_debugfs_root); |
| 842 | − mutex_unlock(&q->debugfs_mutex); | |
| 843 | − | |
| 844 | − if (queue_is_mq(q)) { | |
| 845 | − __blk_mq_register_dev(dev, q); | |
| 838 | + if (queue_is_mq(q)) | |
| 846 | 839 | blk_mq_debugfs_register(q); |
| 847 | − } | |
| 848 | − | |
| 849 | − mutex_lock(&q->sysfs_lock); | |
| 840 | + mutex_unlock(&q->debugfs_mutex); | |
| 850 | 841 | |
| 851 | 842 | ret = disk_register_independent_access_ranges(disk, NULL); |
| 852 | 843 | if (ret) |
| @@ -948,8 +939,15 @@ void blk_unregister_queue(struct gendisk *disk) · 95 unmodified lines | ||
| 948 | 939 | /* Now that we've deleted all child objects, we can delete the queue. */ |
| 949 | 940 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
| 950 | 941 | kobject_del(&q->kobj); |
| 951 | − | |
| 952 | 942 | mutex_unlock(&q->sysfs_dir_lock); |
| 953 | 943 | |
| 944 | + mutex_lock(&q->debugfs_mutex); | |
| 945 | + blk_trace_shutdown(q); | |
| 946 | + debugfs_remove_recursive(q->debugfs_dir); | |
| 947 | + q->debugfs_dir = NULL; | |
| 948 | + q->sched_debugfs_dir = NULL; | |
| 949 | + q->rqos_debugfs_dir = NULL; | |
| 950 | + mutex_unlock(&q->debugfs_mutex); | |
| 951 | + | |
| 954 | 952 | kobject_put(&disk_to_dev(disk)->kobj); |
| 955 | 953 | } |
| @@ -623,6 +623,7 @@ void del_gendisk(struct gendisk *disk) · 622 unmodified lines | ||
| 623 | 623 | * Prevent new I/O from crossing bio_queue_enter(). |
| 624 | 624 | */ |
| 625 | 625 | blk_queue_start_drain(q); |
| 626 | + blk_mq_freeze_queue_wait(q); | |
| 626 | 627 | |
| 627 | 628 | if (!(disk->flags & GENHD_FL_HIDDEN)) { |
| 628 | 629 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); |
| @@ -646,12 +647,21 @@ void del_gendisk(struct gendisk *disk) · 17 unmodified lines | ||
| 646 | 647 | pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); |
| 647 | 648 | device_del(disk_to_dev(disk)); |
| 648 | 649 | |
| 649 | − blk_mq_freeze_queue_wait(q); | |
| 650 | − | |
| 651 | 650 | blk_throtl_cancel_bios(disk->queue); |
| 652 | 651 | |
| 653 | 652 | blk_sync_queue(q); |
| 654 | 653 | blk_flush_integrity(); |
| 654 | + blk_mq_cancel_work_sync(q); | |
| 655 | + | |
| 656 | + blk_mq_quiesce_queue(q); | |
| 657 | + if (q->elevator) { | |
| 658 | + mutex_lock(&q->sysfs_lock); | |
| 659 | + elevator_exit(q); | |
| 660 | + mutex_unlock(&q->sysfs_lock); | |
| 661 | + } | |
| 662 | + rq_qos_exit(q); | |
| 663 | + blk_mq_unquiesce_queue(q); | |
| 664 | + | |
| 655 | 665 | /* |
| 656 | 666 | * Allow using passthrough request again after the queue is torn down. |
| 657 | 667 | */ |
| @@ -1120,31 +1130,6 @@ static const struct attribute_group *disk_attr_groups[] = { · 462 unmodified lines | ||
| 1120 | 1130 | NULL |
| 1121 | 1131 | }; |
| 1122 | 1132 | |
| 1123 | −static void disk_release_mq(struct request_queue *q) | |
| 1124 | −{ | |
| 1125 | − blk_mq_cancel_work_sync(q); | |
| 1126 | − | |
| 1127 | − /* | |
| 1128 | − * There can't be any non non-passthrough bios in flight here, but | |
| 1129 | − * requests stay around longer, including passthrough ones so we | |
| 1130 | − * still need to freeze the queue here. | |
| 1131 | − */ | |
| 1132 | − blk_mq_freeze_queue(q); | |
| 1133 | − | |
| 1134 | − /* | |
| 1135 | − * Since the I/O scheduler exit code may access cgroup information, | |
| 1136 | − * perform I/O scheduler exit before disassociating from the block | |
| 1137 | − * cgroup controller. | |
| 1138 | − */ | |
| 1139 | − if (q->elevator) { | |
| 1140 | − mutex_lock(&q->sysfs_lock); | |
| 1141 | − elevator_exit(q); | |
| 1142 | − mutex_unlock(&q->sysfs_lock); | |
| 1143 | − } | |
| 1144 | − rq_qos_exit(q); | |
| 1145 | − __blk_mq_unfreeze_queue(q, true); | |
| 1146 | −} | |
| 1147 | − | |
| 1148 | 1133 | /** |
| 1149 | 1134 | * disk_release - releases all allocated resources of the gendisk |
| 1150 | 1135 | * @dev: the device representing this disk |
| @@ -1166,9 +1151,6 @@ static void disk_release(struct device *dev) · 15 unmodified lines | ||
| 1166 | 1151 | might_sleep(); |
| 1167 | 1152 | WARN_ON_ONCE(disk_live(disk)); |
| 1168 | 1153 | |
| 1169 | − if (queue_is_mq(disk->queue)) | |
| 1170 | − disk_release_mq(disk->queue); | |
| 1171 | − | |
| 1172 | 1154 | blkcg_exit_queue(disk->queue); |
| 1173 | 1155 | |
| 1174 | 1156 | disk_release_events(disk); |
| @@ -79,10 +79,6 @@ int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk) · 78 unmodified lines | ||
| 79 | 79 | |
| 80 | 80 | WARN_ON_ONCE(!bdev->bd_holder); |
| 81 | 81 | |
| 82 | − /* FIXME: remove the following once add_disk() handles errors */ | |
| 83 | − if (WARN_ON(!bdev->bd_holder_dir)) | |
| 84 | − goto out_unlock; | |
| 85 | − | |
| 86 | 82 | holder = bd_find_holder_disk(bdev, disk); |
| 87 | 83 | if (holder) { |
| 88 | 84 | holder->refcnt++; |
| @@ -421,6 +421,8 @@ static int kyber_init_sched(struct request_queue *q, struct elevator_type *e) · 420 unmodified lines | ||
| 421 | 421 | |
| 422 | 422 | blk_stat_enable_accounting(q); |
| 423 | 423 | |
| 424 | + blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q); | |
| 425 | + | |
| 424 | 426 | eq->elevator_data = kqd; |
| 425 | 427 | q->elevator = eq; |
| 426 | 428 | |
| @@ -1033,7 +1035,6 @@ static struct elevator_type kyber_sched = { · 606 unmodified lines | ||
| 1033 | 1035 | #endif |
| 1034 | 1036 | .elevator_attrs = kyber_sched_attrs, |
| 1035 | 1037 | .elevator_name = "kyber", |
| 1036 | − .elevator_features = ELEVATOR_F_MQ_AWARE, | |
| 1037 | 1038 | .elevator_owner = THIS_MODULE, |
| 1038 | 1039 | }; |
| 1039 | 1040 | |
| @@ -642,6 +642,9 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e) · 641 unmodified lines | ||
| 642 | 642 | spin_lock_init(&dd->lock); |
| 643 | 643 | spin_lock_init(&dd->zone_lock); |
| 644 | 644 | |
| 645 | + /* We dispatch from request queue wide instead of hw queue */ | |
| 646 | + blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q); | |
| 647 | + | |
| 645 | 648 | q->elevator = eq; |
| 646 | 649 | return 0; |
| 647 | 650 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | −/blacklist_hashes_checked | |
| 2 | +/blacklist_hash_list | |
| 3 | 3 | /extract-cert |
| 4 | 4 | /x509_certificate_list |
| 5 | 5 | /x509_revocation_list |
| @@ -3,26 +3,26 @@ · 2 unmodified lines | ||
| 3 | 3 | # Makefile for the linux kernel signature checking certificates. |
| 4 | 4 | # |
| 5 | 5 | |
| 6 | −obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o | |
| 7 | −obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o | |
| 6 | +obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o | |
| 7 | +obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o | |
| 8 | 8 | obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o |
| 9 | 9 | ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),) |
| 10 | −quiet_cmd_check_blacklist_hashes = CHECK $(patsubst "%",%,$(2)) | |
| 11 | − cmd_check_blacklist_hashes = $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(2); touch $@ | |
| 12 | 10 | |
| 13 | −$(eval $(call config_filename,SYSTEM_BLACKLIST_HASH_LIST)) | |
| 11 | +$(obj)/blacklist_hashes.o: $(obj)/blacklist_hash_list | |
| 12 | +CFLAGS_blacklist_hashes.o := -I $(obj) | |
| 14 | 13 | |
| 15 | −$(obj)/blacklist_hashes.o: $(obj)/blacklist_hashes_checked | |
| 14 | +quiet_cmd_check_and_copy_blacklist_hash_list = GEN $@ | |
| 15 | + cmd_check_and_copy_blacklist_hash_list = \ | |
| 16 | + $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) >&2; \ | |
| 17 | + cat $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) > $@ | |
| 16 | 18 | |
| 17 | −CFLAGS_blacklist_hashes.o += -I$(srctree) | |
| 18 | − | |
| 19 | −targets += blacklist_hashes_checked | |
| 20 | −$(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE | |
| 21 | − $(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST)) | |
| 19 | +$(obj)/blacklist_hash_list: $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) FORCE | |
| 20 | + $(call if_changed,check_and_copy_blacklist_hash_list) | |
| 22 | 21 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o |
| 23 | 22 | else |
| 24 | 23 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o |
| 25 | 24 | endif |
| 25 | +targets += blacklist_hash_list | |
| 26 | 26 | |
| 27 | 27 | quiet_cmd_extract_certs = CERT $@ |
| 28 | 28 | cmd_extract_certs = $(obj)/extract-cert $(extract-cert-in) $@ |
| @@ -33,7 +33,7 @@ $(obj)/system_certificates.o: $(obj)/x509_certificate_list · 4 unmodified lines | ||
| 33 | 33 | $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE |
| 34 | 34 | $(call if_changed,extract_certs) |
| 35 | 35 | |
| 36 | −targets += x509_certificate_list blacklist_hashes_checked | |
| 36 | +targets += x509_certificate_list | |
| 37 | 37 | |
| 38 | 38 | # If module signing is requested, say by allyesconfig, but a key has not been |
| 39 | 39 | # supplied, then one will need to be generated to make sure the build does not |
| @@ -15,10 +15,9 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/err.h> |
| 16 | 16 | #include <linux/seq_file.h> |
| 17 | 17 | #include <linux/uidgid.h> |
| 18 | −#include <linux/verification.h> | |
| 18 | +#include <keys/asymmetric-type.h> | |
| 19 | 19 | #include <keys/system_keyring.h> |
| 20 | 20 | #include "blacklist.h" |
| 21 | −#include "common.h" | |
| 22 | 21 | |
| 23 | 22 | /* |
| 24 | 23 | * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), |
| @@ -365,8 +364,9 @@ static __init int load_revocation_certificate_list(void) · 340 unmodified lines | ||
| 365 | 364 | if (revocation_certificate_list_size) |
| 366 | 365 | pr_notice("Loading compiled-in revocation X.509 certificates\n"); |
| 367 | 366 | |
| 368 | − return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, | |
| 369 | − blacklist_keyring); | |
| 367 | + return x509_load_certificate_list(revocation_certificate_list, | |
| 368 | + revocation_certificate_list_size, | |
| 369 | + blacklist_keyring); | |
| 370 | 370 | } |
| 371 | 371 | late_initcall(load_revocation_certificate_list); |
| 372 | 372 | #endif |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include "blacklist.h" |
| 3 | 3 | |
| 4 | −const char __initdata *const blacklist_hashes[] = { | |
| 5 | −#include CONFIG_SYSTEM_BLACKLIST_HASH_LIST | |
| 4 | +const char __initconst *const blacklist_hashes[] = { | |
| 5 | +#include "blacklist_hash_list" | |
| 6 | 6 | , NULL |
| 7 | 7 | }; |
| @@ -1,9 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| 2 | − | |
| 3 | −#ifndef _CERT_COMMON_H | |
| 4 | −#define _CERT_COMMON_H | |
| 5 | − | |
| 6 | −int load_certificate_list(const u8 cert_list[], const unsigned long list_size, | |
| 7 | − const struct key *keyring); | |
| 8 | − | |
| 9 | −#endif | |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <keys/asymmetric-type.h> |
| 17 | 17 | #include <keys/system_keyring.h> |
| 18 | 18 | #include <crypto/pkcs7.h> |
| 19 | −#include "common.h" | |
| 20 | 19 | |
| 21 | 20 | static struct key *builtin_trusted_keys; |
| 22 | 21 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING |
| @@ -183,7 +182,8 @@ __init int load_module_cert(struct key *keyring) · 160 unmodified lines | ||
| 183 | 182 | |
| 184 | 183 | pr_notice("Loading compiled-in module X.509 certificates\n"); |
| 185 | 184 | |
| 186 | − return load_certificate_list(system_certificate_list, module_cert_size, keyring); | |
| 185 | + return x509_load_certificate_list(system_certificate_list, | |
| 186 | + module_cert_size, keyring); | |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | /* |
| @@ -204,7 +204,7 @@ static __init int load_system_certificate_list(void) · 14 unmodified lines | ||
| 204 | 204 | size = system_certificate_list_size - module_cert_size; |
| 205 | 205 | #endif |
| 206 | 206 | |
| 207 | − return load_certificate_list(p, size, builtin_trusted_keys); | |
| 207 | + return x509_load_certificate_list(p, size, builtin_trusted_keys); | |
| 208 | 208 | } |
| 209 | 209 | late_initcall(load_system_certificate_list); |
| 210 | 210 | |
| @@ -15,6 +15,7 @@ source "crypto/async_tx/Kconfig" · 14 unmodified lines | ||
| 15 | 15 | # |
| 16 | 16 | menuconfig CRYPTO |
| 17 | 17 | tristate "Cryptographic API" |
| 18 | + select LIB_MEMNEQ | |
| 18 | 19 | help |
| 19 | 20 | This option provides the core Cryptographic API. |
| 20 | 21 | |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | # |
| 5 | 5 | |
| 6 | 6 | obj-$(CONFIG_CRYPTO) += crypto.o |
| 7 | −crypto-y := api.o cipher.o compress.o memneq.o | |
| 7 | +crypto-y := api.o cipher.o compress.o | |
| 8 | 8 | |
| 9 | 9 | obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o |
| 10 | 10 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o |
| @@ -75,4 +75,14 @@ config SIGNED_PE_FILE_VERIFICATION · 74 unmodified lines | ||
| 75 | 75 | This option provides support for verifying the signature(s) on a |
| 76 | 76 | signed PE binary. |
| 77 | 77 | |
| 78 | +config FIPS_SIGNATURE_SELFTEST | |
| 79 | + bool "Run FIPS selftests on the X.509+PKCS7 signature verification" | |
| 80 | + help | |
| 81 | + This option causes some selftests to be run on the signature | |
| 82 | + verification code, using some built in data. This is required | |
| 83 | + for FIPS. | |
| 84 | + depends on KEYS | |
| 85 | + depends on ASYMMETRIC_KEY_TYPE | |
| 86 | + depends on PKCS7_MESSAGE_PARSER | |
| 87 | + | |
| 78 | 88 | endif # ASYMMETRIC_KEY_TYPE |
| @@ -20,7 +20,9 @@ x509_key_parser-y := \ · 19 unmodified lines | ||
| 20 | 20 | x509.asn1.o \ |
| 21 | 21 | x509_akid.asn1.o \ |
| 22 | 22 | x509_cert_parser.o \ |
| 23 | + x509_loader.o \ | |
| 23 | 24 | x509_public_key.o |
| 25 | +x509_key_parser-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += selftest.o | |
| 24 | 26 | |
| 25 | 27 | $(obj)/x509_cert_parser.o: \ |
| 26 | 28 | $(obj)/x509.asn1.h \ |
| @@ -0,0 +1,224 @@ | ||
| 1 | +/* Self-testing for signature checking. | |
| 2 | + * | |
| 3 | + * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved. | |
| 4 | + * Written by David Howells (dhowells@redhat.com) | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#include <linux/kernel.h> | |
| 8 | +#include <linux/cred.h> | |
| 9 | +#include <linux/key.h> | |
| 10 | +#include <crypto/pkcs7.h> | |
| 11 | +#include "x509_parser.h" | |
| 12 | + | |
| 13 | +struct certs_test { | |
| 14 | + const u8 *data; | |
| 15 | + size_t data_len; | |
| 16 | + const u8 *pkcs7; | |
| 17 | + size_t pkcs7_len; | |
| 18 | +}; | |
| 19 | + | |
| 20 | +/* | |
| 21 | + * Set of X.509 certificates to provide public keys for the tests. These will | |
| 22 | + * be loaded into a temporary keyring for the duration of the testing. | |
| 23 | + */ | |
| 24 | +static const __initconst u8 certs_selftest_keys[] = { | |
| 25 | + "\x30\x82\x05\x55\x30\x82\x03\x3d\xa0\x03\x02\x01\x02\x02\x14\x73" | |
| 26 | + "\x98\xea\x98\x2d\xd0\x2e\xa8\xb1\xcf\x57\xc7\xf2\x97\xb3\xe6\x1a" | |
| 27 | + "\xfc\x8c\x0a\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b" | |
| 28 | + "\x05\x00\x30\x34\x31\x32\x30\x30\x06\x03\x55\x04\x03\x0c\x29\x43" | |
| 29 | + "\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69\x66" | |
| 30 | + "\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x6c\x66\x2d\x74\x65\x73" | |
| 31 | + "\x74\x69\x6e\x67\x20\x6b\x65\x79\x30\x20\x17\x0d\x32\x32\x30\x35" | |
| 32 | + "\x31\x38\x32\x32\x33\x32\x34\x31\x5a\x18\x0f\x32\x31\x32\x32\x30" | |
| 33 | + "\x34\x32\x34\x32\x32\x33\x32\x34\x31\x5a\x30\x34\x31\x32\x30\x30" | |
| 34 | + "\x06\x03\x55\x04\x03\x0c\x29\x43\x65\x72\x74\x69\x66\x69\x63\x61" | |
| 35 | + "\x74\x65\x20\x76\x65\x72\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x20" | |
| 36 | + "\x73\x65\x6c\x66\x2d\x74\x65\x73\x74\x69\x6e\x67\x20\x6b\x65\x79" | |
| 37 | + "\x30\x82\x02\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01" | |
| 38 | + "\x01\x05\x00\x03\x82\x02\x0f\x00\x30\x82\x02\x0a\x02\x82\x02\x01" | |
| 39 | + "\x00\xcc\xac\x49\xdd\x3b\xca\xb0\x15\x7e\x84\x6a\xb2\x0a\x69\x5f" | |
| 40 | + "\x1c\x0a\x61\x82\x3b\x4f\x2c\xa3\x95\x2c\x08\x58\x4b\xb1\x5d\x99" | |
| 41 | + "\xe0\xc3\xc1\x79\xc2\xb3\xeb\xc0\x1e\x6d\x3e\x54\x1d\xbd\xb7\x92" | |
| 42 | + "\x7b\x4d\xb5\x95\x58\xb2\x52\x2e\xc6\x24\x4b\x71\x63\x80\x32\x77" | |
| 43 | + "\xa7\x38\x5e\xdb\x72\xae\x6e\x0d\xec\xfb\xb6\x6d\x01\x7f\xe9\x55" | |
| 44 | + "\x66\xdf\xbf\x1d\x76\x78\x02\x31\xe8\xe5\x07\xf8\xb7\x82\x5c\x0d" | |
| 45 | + "\xd4\xbb\xfb\xa2\x59\x0d\x2e\x3a\x78\x95\x3a\x8b\x46\x06\x47\x44" | |
| 46 | + "\x46\xd7\xcd\x06\x6a\x41\x13\xe3\x19\xf6\xbb\x6e\x38\xf4\x83\x01" | |
| 47 | + "\xa3\xbf\x4a\x39\x4f\xd7\x0a\xe9\x38\xb3\xf5\x94\x14\x4e\xdd\xf7" | |
| 48 | + "\x43\xfd\x24\xb2\x49\x3c\xa5\xf7\x7a\x7c\xd4\x45\x3d\x97\x75\x68" | |
| 49 | + "\xf1\xed\x4c\x42\x0b\x70\xca\x85\xf3\xde\xe5\x88\x2c\xc5\xbe\xb6" | |
| 50 | + "\x97\x34\xba\x24\x02\xcd\x8b\x86\x9f\xa9\x73\xca\x73\xcf\x92\x81" | |
| 51 | + "\xee\x75\x55\xbb\x18\x67\x5c\xff\x3f\xb5\xdd\x33\x1b\x0c\xe9\x78" | |
| 52 | + "\xdb\x5c\xcf\xaa\x5c\x43\x42\xdf\x5e\xa9\x6d\xec\xd7\xd7\xff\xe6" | |
| 53 | + "\xa1\x3a\x92\x1a\xda\xae\xf6\x8c\x6f\x7b\xd5\xb4\x6e\x06\xe9\x8f" | |
| 54 | + "\xe8\xde\x09\x31\x89\xed\x0e\x11\xa1\xfa\x8a\xe9\xe9\x64\x59\x62" | |
| 55 | + "\x53\xda\xd1\x70\xbe\x11\xd4\x99\x97\x11\xcf\x99\xde\x0b\x9d\x94" | |
| 56 | + "\x7e\xaa\xb8\x52\xea\x37\xdb\x90\x7e\x35\xbd\xd9\xfe\x6d\x0a\x48" | |
| 57 | + "\x70\x28\xdd\xd5\x0d\x7f\x03\x80\x93\x14\x23\x8f\xb9\x22\xcd\x7c" | |
| 58 | + "\x29\xfe\xf1\x72\xb5\x5c\x0b\x12\xcf\x9c\x15\xf6\x11\x4c\x7a\x45" | |
| 59 | + "\x25\x8c\x45\x0a\x34\xac\x2d\x9a\x81\xca\x0b\x13\x22\xcd\xeb\x1a" | |
| 60 | + "\x38\x88\x18\x97\x96\x08\x81\xaa\xcc\x8f\x0f\x8a\x32\x7b\x76\x68" | |
| 61 | + "\x03\x68\x43\xbf\x11\xba\x55\x60\xfd\x80\x1c\x0d\x9b\x69\xb6\x09" | |
| 62 | + "\x72\xbc\x0f\x41\x2f\x07\x82\xc6\xe3\xb2\x13\x91\xc4\x6d\x14\x95" | |
| 63 | + "\x31\xbe\x19\xbd\xbc\xed\xe1\x4c\x74\xa2\xe0\x78\x0b\xbb\x94\xec" | |
| 64 | + "\x4c\x53\x3a\xa2\xb5\x84\x1d\x4b\x65\x7e\xdc\xf7\xdb\x36\x7d\xbe" | |
| 65 | + "\x9e\x3b\x36\x66\x42\x66\x76\x35\xbf\xbe\xf0\xc1\x3c\x7c\xe9\x42" | |
| 66 | + "\x5c\x24\x53\x03\x05\xa8\x67\x24\x50\x02\x75\xff\x24\x46\x3b\x35" | |
| 67 | + "\x89\x76\xe6\x70\xda\xc5\x51\x8c\x9a\xe5\x05\xb0\x0b\xd0\x2d\xd4" | |
| 68 | + "\x7d\x57\x75\x94\x6b\xf9\x0a\xad\x0e\x41\x00\x15\xd0\x4f\xc0\x7f" | |
| 69 | + "\x90\x2d\x18\x48\x8f\x28\xfe\x5d\xa7\xcd\x99\x9e\xbd\x02\x6c\x8a" | |
| 70 | + "\x31\xf3\x1c\xc7\x4b\xe6\x93\xcd\x42\xa2\xe4\x68\x10\x47\x9d\xfc" | |
| 71 | + "\x21\x02\x03\x01\x00\x01\xa3\x5d\x30\x5b\x30\x0c\x06\x03\x55\x1d" | |
| 72 | + "\x13\x01\x01\xff\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04" | |
| 73 | + "\x04\x03\x02\x07\x80\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14" | |
| 74 | + "\xf5\x87\x03\xbb\x33\xce\x1b\x73\xee\x02\xec\xcd\xee\x5b\x88\x17" | |
| 75 | + "\x51\x8f\xe3\xdb\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80" | |
| 76 | + "\x14\xf5\x87\x03\xbb\x33\xce\x1b\x73\xee\x02\xec\xcd\xee\x5b\x88" | |
| 77 | + "\x17\x51\x8f\xe3\xdb\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01" | |
| 78 | + "\x01\x0b\x05\x00\x03\x82\x02\x01\x00\xc0\x2e\x12\x41\x7b\x73\x85" | |
| 79 | + "\x16\xc8\xdb\x86\x79\xe8\xf5\xcd\x44\xf4\xc6\xe2\x81\x23\x5e\x47" | |
| 80 | + "\xcb\xab\x25\xf1\x1e\x58\x3e\x31\x7f\x78\xad\x85\xeb\xfe\x14\x88" | |
| 81 | + "\x60\xf7\x7f\xd2\x26\xa2\xf4\x98\x2a\xfd\xba\x05\x0c\x20\x33\x12" | |
| 82 | + "\xcc\x4d\x14\x61\x64\x81\x93\xd3\x33\xed\xc8\xff\xf1\x78\xcc\x5f" | |
| 83 | + "\x51\x9f\x09\xd7\xbe\x0d\x5c\x74\xfd\x9b\xdf\x52\x4a\xc9\xa8\x71" | |
| 84 | + "\x25\x33\x04\x10\x67\x36\xd0\xb3\x0b\xc9\xa1\x40\x72\xae\x41\x7b" | |
| 85 | + "\x68\xe6\xe4\x7b\xd0\x28\xf7\x6d\xe7\x3f\x50\xfc\x91\x7c\x91\x56" | |
| 86 | + "\xd4\xdf\xa6\xbb\xe8\x4d\x1b\x58\xaa\x28\xfa\xc1\x19\xeb\x11\x2f" | |
| 87 | + "\x24\x8b\x7c\xc5\xa9\x86\x26\xaa\x6e\xb7\x9b\xd5\xf8\x06\xfb\x02" | |
| 88 | + "\x52\x7b\x9c\x9e\xa1\xe0\x07\x8b\x5e\xe4\xb8\x55\x29\xf6\x48\x52" | |
| 89 | + "\x1c\x1b\x54\x2d\x46\xd8\xe5\x71\xb9\x60\xd1\x45\xb5\x92\x89\x8a" | |
| 90 | + "\x63\x58\x2a\xb3\xc6\xb2\x76\xe2\x3c\x82\x59\x04\xae\x5a\xc4\x99" | |
| 91 | + "\x7b\x2e\x4b\x46\x57\xb8\x29\x24\xb2\xfd\xee\x2c\x0d\xa4\x83\xfa" | |
| 92 | + "\x65\x2a\x07\x35\x8b\x97\xcf\xbd\x96\x2e\xd1\x7e\x6c\xc2\x1e\x87" | |
| 93 | + "\xb6\x6c\x76\x65\xb5\xb2\x62\xda\x8b\xe9\x73\xe3\xdb\x33\xdd\x13" | |
| 94 | + "\x3a\x17\x63\x6a\x76\xde\x8d\x8f\xe0\x47\x61\x28\x3a\x83\xff\x8f" | |
| 95 | + "\xe7\xc7\xe0\x4a\xa3\xe5\x07\xcf\xe9\x8c\x35\x35\x2e\xe7\x80\x66" | |
| 96 | + "\x31\xbf\x91\x58\x0a\xe1\x25\x3d\x38\xd3\xa4\xf0\x59\x34\x47\x07" | |
| 97 | + "\x62\x0f\xbe\x30\xdd\x81\x88\x58\xf0\x28\xb0\x96\xe5\x82\xf8\x05" | |
| 98 | + "\xb7\x13\x01\xbc\xfa\xc6\x1f\x86\x72\xcc\xf9\xee\x8e\xd9\xd6\x04" | |
| 99 | + "\x8c\x24\x6c\xbf\x0f\x5d\x37\x39\xcf\x45\xc1\x93\x3a\xd2\xed\x5c" | |
| 100 | + "\x58\x79\x74\x86\x62\x30\x7e\x8e\xbb\xdd\x7a\xa9\xed\xca\x40\xcb" | |
| 101 | + "\x62\x47\xf4\xb4\x9f\x52\x7f\x72\x63\xa8\xf0\x2b\xaf\x45\x2a\x48" | |
| 102 | + "\x19\x6d\xe3\xfb\xf9\x19\x66\x69\xc8\xcc\x62\x87\x6c\x53\x2b\x2d" | |
| 103 | + "\x6e\x90\x6c\x54\x3a\x82\x25\x41\xcb\x18\x6a\xa4\x22\xa8\xa1\xc4" | |
| 104 | + "\x47\xd7\x81\x00\x1c\x15\x51\x0f\x1a\xaf\xef\x9f\xa6\x61\x8c\xbd" | |
| 105 | + "\x6b\x8b\xed\xe6\xac\x0e\xb6\x3a\x4c\x92\xe6\x0f\x91\x0a\x0f\x71" | |
| 106 | + "\xc7\xa0\xb9\x0d\x3a\x17\x5a\x6f\x35\xc8\xe7\x50\x4f\x46\xe8\x70" | |
| 107 | + "\x60\x48\x06\x82\x8b\x66\x58\xe6\x73\x91\x9c\x12\x3d\x35\x8e\x46" | |
| 108 | + "\xad\x5a\xf5\xb3\xdb\x69\x21\x04\xfd\xd3\x1c\xdf\x94\x9d\x56\xb0" | |
| 109 | + "\x0a\xd1\x95\x76\x8d\xec\x9e\xdd\x0b\x15\x97\x64\xad\xe5\xf2\x62" | |
| 110 | + "\x02\xfc\x9e\x5f\x56\x42\x39\x05\xb3" | |
| 111 | +}; | |
| 112 | + | |
| 113 | +/* | |
| 114 | + * Signed data and detached signature blobs that form the verification tests. | |
| 115 | + */ | |
| 116 | +static const __initconst u8 certs_selftest_1_data[] = { | |
| 117 | + "\x54\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x74\x65\x73" | |
| 118 | + "\x74\x20\x64\x61\x74\x61\x20\x75\x73\x65\x64\x20\x66\x6f\x72\x20" | |
| 119 | + "\x73\x65\x6c\x66\x2d\x74\x65\x73\x74\x69\x6e\x67\x20\x63\x65\x72" | |
| 120 | + "\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69\x66\x69\x63" | |
| 121 | + "\x61\x74\x69\x6f\x6e\x2e\x0a" | |
| 122 | +}; | |
| 123 | + | |
| 124 | +static const __initconst u8 certs_selftest_1_pkcs7[] = { | |
| 125 | + "\x30\x82\x02\xab\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02\xa0" | |
| 126 | + "\x82\x02\x9c\x30\x82\x02\x98\x02\x01\x01\x31\x0d\x30\x0b\x06\x09" | |
| 127 | + "\x60\x86\x48\x01\x65\x03\x04\x02\x01\x30\x0b\x06\x09\x2a\x86\x48" | |
| 128 | + "\x86\xf7\x0d\x01\x07\x01\x31\x82\x02\x75\x30\x82\x02\x71\x02\x01" | |
| 129 | + "\x01\x30\x4c\x30\x34\x31\x32\x30\x30\x06\x03\x55\x04\x03\x0c\x29" | |
| 130 | + "\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69" | |
| 131 | + "\x66\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x6c\x66\x2d\x74\x65" | |
| 132 | + "\x73\x74\x69\x6e\x67\x20\x6b\x65\x79\x02\x14\x73\x98\xea\x98\x2d" | |
| 133 | + "\xd0\x2e\xa8\xb1\xcf\x57\xc7\xf2\x97\xb3\xe6\x1a\xfc\x8c\x0a\x30" | |
| 134 | + "\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x30\x0d\x06\x09" | |
| 135 | + "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x04\x82\x02\x00\xac" | |
| 136 | + "\xb0\xf2\x07\xd6\x99\x6d\xc0\xc0\xd9\x8d\x31\x0d\x7e\x04\xeb\xc3" | |
| 137 | + "\x88\x90\xc4\x58\x46\xd4\xe2\xa0\xa3\x25\xe3\x04\x50\x37\x85\x8c" | |
| 138 | + "\x91\xc6\xfc\xc5\xd4\x92\xfd\x05\xd8\xb8\xa3\xb8\xba\x89\x13\x00" | |
| 139 | + "\x88\x79\x99\x51\x6b\x5b\x28\x31\xc0\xb3\x1b\x7a\x68\x2c\x00\xdb" | |
| 140 | + "\x4b\x46\x11\xf3\xfa\x50\x8e\x19\x89\xa2\x4c\xda\x4c\x89\x01\x11" | |
| 141 | + "\x89\xee\xd3\xc8\xc1\xe7\xa7\xf6\xb2\xa2\xf8\x65\xb8\x35\x20\x33" | |
| 142 | + "\xba\x12\x62\xd5\xbd\xaa\x71\xe5\x5b\xc0\x6a\x32\xff\x6a\x2e\x23" | |
| 143 | + "\xef\x2b\xb6\x58\xb1\xfb\x5f\x82\x34\x40\x6d\x9f\xbc\x27\xac\x37" | |
| 144 | + "\x23\x99\xcf\x7d\x20\xb2\x39\x01\xc0\x12\xce\xd7\x5d\x2f\xb6\xab" | |
| 145 | + "\xb5\x56\x4f\xef\xf4\x72\x07\x58\x65\xa9\xeb\x1f\x75\x1c\x5f\x0c" | |
| 146 | + "\x88\xe0\xa4\xe2\xcd\x73\x2b\x9e\xb2\x05\x7e\x12\xf8\xd0\x66\x41" | |
| 147 | + "\xcc\x12\x63\xd4\xd6\xac\x9b\x1d\x14\x77\x8d\x1c\x57\xd5\x27\xc6" | |
| 148 | + "\x49\xa2\x41\x43\xf3\x59\x29\xe5\xcb\xd1\x75\xbc\x3a\x97\x2a\x72" | |
| 149 | + "\x22\x66\xc5\x3b\xc1\xba\xfc\x53\x18\x98\xe2\x21\x64\xc6\x52\x87" | |
| 150 | + "\x13\xd5\x7c\x42\xe8\xfb\x9c\x9a\x45\x32\xd5\xa5\x22\x62\x9d\xd4" | |
| 151 | + "\xcb\xa4\xfa\x77\xbb\x50\x24\x0b\x8b\x88\x99\x15\x56\xa9\x1e\x92" | |
| 152 | + "\xbf\x5d\x94\x77\xb6\xf1\x67\x01\x60\x06\x58\x5c\xdf\x18\x52\x79" | |
| 153 | + "\x37\x30\x93\x7d\x87\x04\xf1\xe0\x55\x59\x52\xf3\xc2\xb1\x1c\x5b" | |
| 154 | + "\x12\x7c\x49\x87\xfb\xf7\xed\xdd\x95\x71\xec\x4b\x1a\x85\x08\xb0" | |
| 155 | + "\xa0\x36\xc4\x7b\xab\x40\xe0\xf1\x98\xcc\xaf\x19\x40\x8f\x47\x6f" | |
| 156 | + "\xf0\x6c\x84\x29\x7f\x7f\x04\x46\xcb\x08\x0f\xe0\xc1\xc9\x70\x6e" | |
| 157 | + "\x95\x3b\xa4\xbc\x29\x2b\x53\x67\x45\x1b\x0d\xbc\x13\xa5\x76\x31" | |
| 158 | + "\xaf\xb9\xd0\xe0\x60\x12\xd2\xf4\xb7\x7c\x58\x7e\xf6\x2d\xbb\x24" | |
| 159 | + "\x14\x5a\x20\x24\xa8\x12\xdf\x25\xbd\x42\xce\x96\x7c\x2e\xba\x14" | |
| 160 | + "\x1b\x81\x9f\x18\x45\xa4\xc6\x70\x3e\x0e\xf0\xd3\x7b\x9c\x10\xbe" | |
| 161 | + "\xb8\x7a\x89\xc5\x9e\xd9\x97\xdf\xd7\xe7\xc6\x1d\xc0\x20\x6c\xb8" | |
| 162 | + "\x1e\x3a\x63\xb8\x39\x8e\x8e\x62\xd5\xd2\xb4\xcd\xff\x46\xfc\x8e" | |
| 163 | + "\xec\x07\x35\x0c\xff\xb0\x05\xe6\xf4\xe5\xfe\xa2\xe3\x0a\xe6\x36" | |
| 164 | + "\xa7\x4a\x7e\x62\x1d\xc4\x50\x39\x35\x4e\x28\xcb\x4a\xfb\x9d\xdb" | |
| 165 | + "\xdd\x23\xd6\x53\xb1\x74\x77\x12\xf7\x9c\xf0\x9a\x6b\xf7\xa9\x64" | |
| 166 | + "\x2d\x86\x21\x2a\xcf\xc6\x54\xf5\xc9\xad\xfa\xb5\x12\xb4\xf3\x51" | |
| 167 | + "\x77\x55\x3c\x6f\x0c\x32\xd3\x8c\x44\x39\x71\x25\xfe\x96\xd2" | |
| 168 | +}; | |
| 169 | + | |
| 170 | +/* | |
| 171 | + * List of tests to be run. | |
| 172 | + */ | |
| 173 | +#define TEST(data, pkcs7) { data, sizeof(data) - 1, pkcs7, sizeof(pkcs7) - 1 } | |
| 174 | +static const struct certs_test certs_tests[] __initconst = { | |
| 175 | + TEST(certs_selftest_1_data, certs_selftest_1_pkcs7), | |
| 176 | +}; | |
| 177 | + | |
| 178 | +int __init fips_signature_selftest(void) | |
| 179 | +{ | |
| 180 | + struct key *keyring; | |
| 181 | + int ret, i; | |
| 182 | + | |
| 183 | + pr_notice("Running certificate verification selftests\n"); | |
| 184 | + | |
| 185 | + keyring = keyring_alloc(".certs_selftest", | |
| 186 | + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(), | |
| 187 | + (KEY_POS_ALL & ~KEY_POS_SETATTR) | | |
| 188 | + KEY_USR_VIEW | KEY_USR_READ | | |
| 189 | + KEY_USR_SEARCH, | |
| 190 | + KEY_ALLOC_NOT_IN_QUOTA, | |
| 191 | + NULL, NULL); | |
| 192 | + if (IS_ERR(keyring)) | |
| 193 | + panic("Can't allocate certs selftest keyring: %ld\n", | |
| 194 | + PTR_ERR(keyring)); | |
| 195 | + | |
| 196 | + ret = x509_load_certificate_list(certs_selftest_keys, | |
| 197 | + sizeof(certs_selftest_keys) - 1, keyring); | |
| 198 | + if (ret < 0) | |
| 199 | + panic("Can't allocate certs selftest keyring: %d\n", ret); | |
| 200 | + | |
| 201 | + for (i = 0; i < ARRAY_SIZE(certs_tests); i++) { | |
| 202 | + const struct certs_test *test = &certs_tests[i]; | |
| 203 | + struct pkcs7_message *pkcs7; | |
| 204 | + | |
| 205 | + pkcs7 = pkcs7_parse_message(test->pkcs7, test->pkcs7_len); | |
| 206 | + if (IS_ERR(pkcs7)) | |
| 207 | + panic("Certs selftest %d: pkcs7_parse_message() = %d\n", i, ret); | |
| 208 | + | |
| 209 | + pkcs7_supply_detached_data(pkcs7, test->data, test->data_len); | |
| 210 | + | |
| 211 | + ret = pkcs7_verify(pkcs7, VERIFYING_MODULE_SIGNATURE); | |
| 212 | + if (ret < 0) | |
| 213 | + panic("Certs selftest %d: pkcs7_verify() = %d\n", i, ret); | |
| 214 | + | |
| 215 | + ret = pkcs7_validate_trust(pkcs7, keyring); | |
| 216 | + if (ret < 0) | |
| 217 | + panic("Certs selftest %d: pkcs7_validate_trust() = %d\n", i, ret); | |
| 218 | + | |
| 219 | + pkcs7_free_message(pkcs7); | |
| 220 | + } | |
| 221 | + | |
| 222 | + key_put(keyring); | |
| 223 | + return 0; | |
| 224 | +} | |
| @@ -2,11 +2,11 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | #include <linux/kernel.h> |
| 4 | 4 | #include <linux/key.h> |
| 5 | −#include "common.h" | |
| 5 | +#include <keys/asymmetric-type.h> | |
| 6 | 6 | |
| 7 | −int load_certificate_list(const u8 cert_list[], | |
| 8 | − const unsigned long list_size, | |
| 9 | − const struct key *keyring) | |
| 7 | +int x509_load_certificate_list(const u8 cert_list[], | |
| 8 | + const unsigned long list_size, | |
| 9 | + const struct key *keyring) | |
| 10 | 10 | { |
| 11 | 11 | key_ref_t key; |
| 12 | 12 | const u8 *p, *end; |
| @@ -40,6 +40,15 @@ struct x509_certificate { · 39 unmodified lines | ||
| 40 | 40 | bool blacklisted; |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | +/* | |
| 44 | + * selftest.c | |
| 45 | + */ | |
| 46 | +#ifdef CONFIG_FIPS_SIGNATURE_SELFTEST | |
| 47 | +extern int __init fips_signature_selftest(void); | |
| 48 | +#else | |
| 49 | +static inline int fips_signature_selftest(void) { return 0; } | |
| 50 | +#endif | |
| 51 | + | |
| 43 | 52 | /* |
| 44 | 53 | * x509_cert_parser.c |
| 45 | 54 | */ |
| @@ -244,9 +244,15 @@ static struct asymmetric_key_parser x509_key_parser = { · 243 unmodified lines | ||
| 244 | 244 | /* |
| 245 | 245 | * Module stuff |
| 246 | 246 | */ |
| 247 | +extern int __init certs_selftest(void); | |
| 247 | 248 | static int __init x509_key_init(void) |
| 248 | 249 | { |
| 249 | − return register_asymmetric_key_parser(&x509_key_parser); | |
| 250 | + int ret; | |
| 251 | + | |
| 252 | + ret = register_asymmetric_key_parser(&x509_key_parser); | |
| 253 | + if (ret < 0) | |
| 254 | + return ret; | |
| 255 | + return fips_signature_selftest(); | |
| 250 | 256 | } |
| 251 | 257 | |
| 252 | 258 | static void __exit x509_key_exit(void) |
| @@ -564,6 +564,12 @@ ssize_t __weak cpu_show_srbds(struct device *dev, · 563 unmodified lines | ||
| 564 | 564 | return sysfs_emit(buf, "Not affected\n"); |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | +ssize_t __weak cpu_show_mmio_stale_data(struct device *dev, | |
| 568 | + struct device_attribute *attr, char *buf) | |
| 569 | +{ | |
| 570 | + return sysfs_emit(buf, "Not affected\n"); | |
| 571 | +} | |
| 572 | + | |
| 567 | 573 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
| 568 | 574 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); |
| 569 | 575 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); |
| @@ -573,6 +579,7 @@ static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); · 3 unmodified lines | ||
| 573 | 579 | static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); |
| 574 | 580 | static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); |
| 575 | 581 | static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); |
| 582 | +static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL); | |
| 576 | 583 | |
| 577 | 584 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
| 578 | 585 | &dev_attr_meltdown.attr, |
| @@ -584,6 +591,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { · 5 unmodified lines | ||
| 584 | 591 | &dev_attr_tsx_async_abort.attr, |
| 585 | 592 | &dev_attr_itlb_multihit.attr, |
| 586 | 593 | &dev_attr_srbds.attr, |
| 594 | + &dev_attr_mmio_stale_data.attr, | |
| 587 | 595 | NULL |
| 588 | 596 | }; |
| 589 | 597 | |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/init.h> |
| 9 | 9 | #include <linux/memory.h> |
| 10 | 10 | #include <linux/of.h> |
| 11 | +#include <linux/backing-dev.h> | |
| 11 | 12 | |
| 12 | 13 | #include "base.h" |
| 13 | 14 | |
| @@ -20,6 +21,7 @@ · 6 unmodified lines | ||
| 20 | 21 | void __init driver_init(void) |
| 21 | 22 | { |
| 22 | 23 | /* These are the core pieces */ |
| 24 | + bdi_init(&noop_backing_dev_info); | |
| 23 | 25 | devtmpfs_init(); |
| 24 | 26 | devices_init(); |
| 25 | 27 | buses_init(); |
| @@ -558,7 +558,7 @@ static ssize_t hard_offline_page_store(struct device *dev, · 557 unmodified lines | ||
| 558 | 558 | if (kstrtoull(buf, 0, &pfn) < 0) |
| 559 | 559 | return -EINVAL; |
| 560 | 560 | pfn >>= PAGE_SHIFT; |
| 561 | − ret = memory_failure(pfn, 0); | |
| 561 | + ret = memory_failure(pfn, MF_SW_SIMULATED); | |
| 562 | 562 | if (ret == -EOPNOTSUPP) |
| 563 | 563 | ret = 0; |
| 564 | 564 | return ret ? ret : count; |
| @@ -252,6 +252,7 @@ static void regmap_irq_enable(struct irq_data *data) · 251 unmodified lines | ||
| 252 | 252 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); |
| 253 | 253 | struct regmap *map = d->map; |
| 254 | 254 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); |
| 255 | + unsigned int reg = irq_data->reg_offset / map->reg_stride; | |
| 255 | 256 | unsigned int mask, type; |
| 256 | 257 | |
| 257 | 258 | type = irq_data->type.type_falling_val | irq_data->type.type_rising_val; |
| @@ -268,14 +269,14 @@ static void regmap_irq_enable(struct irq_data *data) · 10 unmodified lines | ||
| 268 | 269 | * at the corresponding offset in regmap_irq_set_type(). |
| 269 | 270 | */ |
| 270 | 271 | if (d->chip->type_in_mask && type) |
| 271 | − mask = d->type_buf[irq_data->reg_offset / map->reg_stride]; | |
| 272 | + mask = d->type_buf[reg] & irq_data->mask; | |
| 272 | 273 | else |
| 273 | 274 | mask = irq_data->mask; |
| 274 | 275 | |
| 275 | 276 | if (d->chip->clear_on_unmask) |
| 276 | 277 | d->clear_status = true; |
| 277 | 278 | |
| 278 | − d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~mask; | |
| 279 | + d->mask_buf[reg] &= ~mask; | |
| 279 | 280 | } |
| 280 | 281 | |
| 281 | 282 | static void regmap_irq_disable(struct irq_data *data) |
| @@ -386,6 +387,7 @@ static inline int read_sub_irq_data(struct regmap_irq_chip_data *data, · 104 unmodified lines | ||
| 386 | 387 | subreg = &chip->sub_reg_offsets[b]; |
| 387 | 388 | for (i = 0; i < subreg->num_regs; i++) { |
| 388 | 389 | unsigned int offset = subreg->offset[i]; |
| 390 | + unsigned int index = offset / map->reg_stride; | |
| 389 | 391 | |
| 390 | 392 | if (chip->not_fixed_stride) |
| 391 | 393 | ret = regmap_read(map, |
| @@ -394,7 +396,7 @@ static inline int read_sub_irq_data(struct regmap_irq_chip_data *data, · 2 unmodified lines | ||
| 394 | 396 | else |
| 395 | 397 | ret = regmap_read(map, |
| 396 | 398 | chip->status_base + offset, |
| 397 | − &data->status_buf[offset]); | |
| 399 | + &data->status_buf[index]); | |
| 398 | 400 | |
| 399 | 401 | if (ret) |
| 400 | 402 | break; |
| @@ -1880,8 +1880,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, · 1879 unmodified lines | ||
| 1880 | 1880 | */ |
| 1881 | 1881 | bool regmap_can_raw_write(struct regmap *map) |
| 1882 | 1882 | { |
| 1883 | − return map->bus && map->bus->write && map->format.format_val && | |
| 1884 | − map->format.format_reg; | |
| 1883 | + return map->write && map->format.format_val && map->format.format_reg; | |
| 1885 | 1884 | } |
| 1886 | 1885 | EXPORT_SYMBOL_GPL(regmap_can_raw_write); |
| 1887 | 1886 | |
| @@ -2155,10 +2154,9 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg, · 267 unmodified lines | ||
| 2155 | 2154 | size_t write_len; |
| 2156 | 2155 | int ret; |
| 2157 | 2156 | |
| 2158 | − if (!map->bus) | |
| 2159 | − return -EINVAL; | |
| 2160 | − if (!map->bus->write) | |
| 2157 | + if (!map->write) | |
| 2161 | 2158 | return -ENOTSUPP; |
| 2159 | + | |
| 2162 | 2160 | if (val_len % map->format.val_bytes) |
| 2163 | 2161 | return -EINVAL; |
| 2164 | 2162 | if (!IS_ALIGNED(reg, map->reg_stride)) |
| @@ -2278,7 +2276,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, · 113 unmodified lines | ||
| 2278 | 2276 | * Some devices don't support bulk write, for them we have a series of |
| 2279 | 2277 | * single write operations. |
| 2280 | 2278 | */ |
| 2281 | − if (!map->bus || !map->format.parse_inplace) { | |
| 2279 | + if (!map->write || !map->format.parse_inplace) { | |
| 2282 | 2280 | map->lock(map->lock_arg); |
| 2283 | 2281 | for (i = 0; i < val_count; i++) { |
| 2284 | 2282 | unsigned int ival; |
| @@ -2904,6 +2902,9 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, · 619 unmodified lines | ||
| 2904 | 2902 | size_t read_len; |
| 2905 | 2903 | int ret; |
| 2906 | 2904 | |
| 2905 | + if (!map->read) | |
| 2906 | + return -ENOTSUPP; | |
| 2907 | + | |
| 2907 | 2908 | if (val_len % map->format.val_bytes) |
| 2908 | 2909 | return -EINVAL; |
| 2909 | 2910 | if (!IS_ALIGNED(reg, map->reg_stride)) |
| @@ -3017,7 +3018,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, · 107 unmodified lines | ||
| 3017 | 3018 | if (val_count == 0) |
| 3018 | 3019 | return -EINVAL; |
| 3019 | 3020 | |
| 3020 | − if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { | |
| 3021 | + if (map->read && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { | |
| 3021 | 3022 | ret = regmap_raw_read(map, reg, val, val_bytes * val_count); |
| 3022 | 3023 | if (ret != 0) |
| 3023 | 3024 | return ret; |
| @@ -2114,9 +2114,11 @@ static void blkfront_closing(struct blkfront_info *info) · 2113 unmodified lines | ||
| 2114 | 2114 | return; |
| 2115 | 2115 | |
| 2116 | 2116 | /* No more blkif_request(). */ |
| 2117 | − blk_mq_stop_hw_queues(info->rq); | |
| 2118 | − blk_mark_disk_dead(info->gd); | |
| 2119 | − set_capacity(info->gd, 0); | |
| 2117 | + if (info->rq && info->gd) { | |
| 2118 | + blk_mq_stop_hw_queues(info->rq); | |
| 2119 | + blk_mark_disk_dead(info->gd); | |
| 2120 | + set_capacity(info->gd, 0); | |
| 2121 | + } | |
| 2120 | 2122 | |
| 2121 | 2123 | for_each_rinfo(info, rinfo, i) { |
| 2122 | 2124 | /* No more gnttab callback work. */ |
| @@ -2457,16 +2459,19 @@ static int blkfront_remove(struct xenbus_device *xbdev) · 334 unmodified lines | ||
| 2457 | 2459 | |
| 2458 | 2460 | dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename); |
| 2459 | 2461 | |
| 2460 | − del_gendisk(info->gd); | |
| 2462 | + if (info->gd) | |
| 2463 | + del_gendisk(info->gd); | |
| 2461 | 2464 | |
| 2462 | 2465 | mutex_lock(&blkfront_mutex); |
| 2463 | 2466 | list_del(&info->info_list); |
| 2464 | 2467 | mutex_unlock(&blkfront_mutex); |
| 2465 | 2468 | |
| 2466 | 2469 | blkif_free(info, 0); |
| 2467 | − xlbd_release_minors(info->gd->first_minor, info->gd->minors); | |
| 2468 | − blk_cleanup_disk(info->gd); | |
| 2469 | − blk_mq_free_tag_set(&info->tag_set); | |
| 2470 | + if (info->gd) { | |
| 2471 | + xlbd_release_minors(info->gd->first_minor, info->gd->minors); | |
| 2472 | + blk_cleanup_disk(info->gd); | |
| 2473 | + blk_mq_free_tag_set(&info->tag_set); | |
| 2474 | + } | |
| 2470 | 2475 | |
| 2471 | 2476 | kfree(info); |
| 2472 | 2477 | return 0; |
| @@ -175,10 +175,9 @@ static int bt1_apb_request_rst(struct bt1_apb *apb) · 174 unmodified lines | ||
| 175 | 175 | int ret; |
| 176 | 176 | |
| 177 | 177 | apb->prst = devm_reset_control_get_optional_exclusive(apb->dev, "prst"); |
| 178 | − if (IS_ERR(apb->prst)) { | |
| 179 | − dev_warn(apb->dev, "Couldn't get reset control line\n"); | |
| 180 | − return PTR_ERR(apb->prst); | |
| 181 | − } | |
| 178 | + if (IS_ERR(apb->prst)) | |
| 179 | + return dev_err_probe(apb->dev, PTR_ERR(apb->prst), | |
| 180 | + "Couldn't get reset control line\n"); | |
| 182 | 181 | |
| 183 | 182 | ret = reset_control_deassert(apb->prst); |
| 184 | 183 | if (ret) |
| @@ -199,10 +198,9 @@ static int bt1_apb_request_clk(struct bt1_apb *apb) · 14 unmodified lines | ||
| 199 | 198 | int ret; |
| 200 | 199 | |
| 201 | 200 | apb->pclk = devm_clk_get(apb->dev, "pclk"); |
| 202 | − if (IS_ERR(apb->pclk)) { | |
| 203 | − dev_err(apb->dev, "Couldn't get APB clock descriptor\n"); | |
| 204 | − return PTR_ERR(apb->pclk); | |
| 205 | − } | |
| 201 | + if (IS_ERR(apb->pclk)) | |
| 202 | + return dev_err_probe(apb->dev, PTR_ERR(apb->pclk), | |
| 203 | + "Couldn't get APB clock descriptor\n"); | |
| 206 | 204 | |
| 207 | 205 | ret = clk_prepare_enable(apb->pclk); |
| 208 | 206 | if (ret) { |
| @@ -135,10 +135,9 @@ static int bt1_axi_request_rst(struct bt1_axi *axi) · 134 unmodified lines | ||
| 135 | 135 | int ret; |
| 136 | 136 | |
| 137 | 137 | axi->arst = devm_reset_control_get_optional_exclusive(axi->dev, "arst"); |
| 138 | − if (IS_ERR(axi->arst)) { | |
| 139 | − dev_warn(axi->dev, "Couldn't get reset control line\n"); | |
| 140 | − return PTR_ERR(axi->arst); | |
| 141 | − } | |
| 138 | + if (IS_ERR(axi->arst)) | |
| 139 | + return dev_err_probe(axi->dev, PTR_ERR(axi->arst), | |
| 140 | + "Couldn't get reset control line\n"); | |
| 142 | 141 | |
| 143 | 142 | ret = reset_control_deassert(axi->arst); |
| 144 | 143 | if (ret) |
| @@ -159,10 +158,9 @@ static int bt1_axi_request_clk(struct bt1_axi *axi) · 14 unmodified lines | ||
| 159 | 158 | int ret; |
| 160 | 159 | |
| 161 | 160 | axi->aclk = devm_clk_get(axi->dev, "aclk"); |
| 162 | − if (IS_ERR(axi->aclk)) { | |
| 163 | − dev_err(axi->dev, "Couldn't get AXI Interconnect clock\n"); | |
| 164 | − return PTR_ERR(axi->aclk); | |
| 165 | − } | |
| 161 | + if (IS_ERR(axi->aclk)) | |
| 162 | + return dev_err_probe(axi->dev, PTR_ERR(axi->aclk), | |
| 163 | + "Couldn't get AXI Interconnect clock\n"); | |
| 166 | 164 | |
| 167 | 165 | ret = clk_prepare_enable(axi->aclk); |
| 168 | 166 | if (ret) { |
| @@ -1239,14 +1239,14 @@ error_cleanup_mc_io: · 1238 unmodified lines | ||
| 1239 | 1239 | static int fsl_mc_bus_remove(struct platform_device *pdev) |
| 1240 | 1240 | { |
| 1241 | 1241 | struct fsl_mc *mc = platform_get_drvdata(pdev); |
| 1242 | + struct fsl_mc_io *mc_io; | |
| 1242 | 1243 | |
| 1243 | 1244 | if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev)) |
| 1244 | 1245 | return -EINVAL; |
| 1245 | 1246 | |
| 1247 | + mc_io = mc->root_mc_bus_dev->mc_io; | |
| 1246 | 1248 | fsl_mc_device_remove(mc->root_mc_bus_dev); |
| 1247 | − | |
| 1248 | − fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io); | |
| 1249 | − mc->root_mc_bus_dev->mc_io = NULL; | |
| 1249 | + fsl_destroy_mc_io(mc_io); | |
| 1250 | 1250 | |
| 1251 | 1251 | bus_unregister_notifier(&fsl_mc_bus_type, &fsl_mc_nb); |
| 1252 | 1252 | |
| @@ -1019,7 +1019,7 @@ static struct parport_driver lp_driver = { · 1018 unmodified lines | ||
| 1019 | 1019 | |
| 1020 | 1020 | static int __init lp_init(void) |
| 1021 | 1021 | { |
| 1022 | − int i, err = 0; | |
| 1022 | + int i, err; | |
| 1023 | 1023 | |
| 1024 | 1024 | if (parport_nr[0] == LP_PARPORT_OFF) |
| 1025 | 1025 | return 0; |
| @@ -87,7 +87,7 @@ static struct fasync_struct *fasync; · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | /* Control how we warn userspace. */ |
| 89 | 89 | static struct ratelimit_state urandom_warning = |
| 90 | − RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3); | |
| 90 | + RATELIMIT_STATE_INIT_FLAGS("urandom_warning", HZ, 3, RATELIMIT_MSG_ON_RELEASE); | |
| 91 | 91 | static int ratelimit_disable __read_mostly = |
| 92 | 92 | IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM); |
| 93 | 93 | module_param_named(ratelimit_disable, ratelimit_disable, int, 0644); |
| @@ -408,7 +408,7 @@ static ssize_t get_random_bytes_user(struct iov_iter *iter) · 314 unmodified lines | ||
| 408 | 408 | |
| 409 | 409 | /* |
| 410 | 410 | * Immediately overwrite the ChaCha key at index 4 with random |
| 411 | − * bytes, in case userspace causes copy_to_user() below to sleep | |
| 411 | + * bytes, in case userspace causes copy_to_iter() below to sleep | |
| 412 | 412 | * forever, so that we still retain forward secrecy in that case. |
| 413 | 413 | */ |
| 414 | 414 | crng_make_state(chacha_state, (u8 *)&chacha_state[4], CHACHA_KEY_SIZE); |
| @@ -1009,7 +1009,7 @@ void add_interrupt_randomness(int irq) · 594 unmodified lines | ||
| 1009 | 1009 | if (new_count & MIX_INFLIGHT) |
| 1010 | 1010 | return; |
| 1011 | 1011 | |
| 1012 | − if (new_count < 64 && !time_is_before_jiffies(fast_pool->last + HZ)) | |
| 1012 | + if (new_count < 1024 && !time_is_before_jiffies(fast_pool->last + HZ)) | |
| 1013 | 1013 | return; |
| 1014 | 1014 | |
| 1015 | 1015 | if (unlikely(!fast_pool->mix.func)) |
| @@ -565,4 +565,3 @@ void __init hv_init_clocksource(void) · 564 unmodified lines | ||
| 565 | 565 | hv_sched_clock_offset = hv_read_reference_counter(); |
| 566 | 566 | hv_setup_sched_clock(read_hv_sched_clock_msr); |
| 567 | 567 | } |
| 568 | −EXPORT_SYMBOL_GPL(hv_init_clocksource); | |
| @@ -684,7 +684,7 @@ static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev) · 683 unmodified lines | ||
| 684 | 684 | if (!devpriv->usb_rx_buf) |
| 685 | 685 | return -ENOMEM; |
| 686 | 686 | |
| 687 | − size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE); | |
| 687 | + size = max(usb_endpoint_maxp(devpriv->ep_tx), MIN_BUF_SIZE); | |
| 688 | 688 | devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); |
| 689 | 689 | if (!devpriv->usb_tx_buf) |
| 690 | 690 | return -ENOMEM; |
| @@ -32,8 +32,11 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) · 31 unmodified lines | ||
| 32 | 32 | { |
| 33 | 33 | struct vm_area_struct *vma = vmf->vma; |
| 34 | 34 | struct udmabuf *ubuf = vma->vm_private_data; |
| 35 | + pgoff_t pgoff = vmf->pgoff; | |
| 35 | 36 | |
| 36 | − vmf->page = ubuf->pages[vmf->pgoff]; | |
| 37 | + if (pgoff >= ubuf->pagecount) | |
| 38 | + return VM_FAULT_SIGBUS; | |
| 39 | + vmf->page = ubuf->pages[pgoff]; | |
| 37 | 40 | get_page(vmf->page); |
| 38 | 41 | return 0; |
| 39 | 42 | } |
| @@ -1211,7 +1211,7 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg) · 1210 unmodified lines | ||
| 1211 | 1211 | struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2; |
| 1212 | 1212 | struct fw_card *card = client->device->card; |
| 1213 | 1213 | struct timespec64 ts = {0, 0}; |
| 1214 | − u32 cycle_time; | |
| 1214 | + u32 cycle_time = 0; | |
| 1215 | 1215 | int ret = 0; |
| 1216 | 1216 | |
| 1217 | 1217 | local_irq_disable(); |
| @@ -372,8 +372,7 @@ static ssize_t rom_index_show(struct device *dev, · 371 unmodified lines | ||
| 372 | 372 | struct fw_device *device = fw_device(dev->parent); |
| 373 | 373 | struct fw_unit *unit = fw_unit(dev); |
| 374 | 374 | |
| 375 | − return snprintf(buf, PAGE_SIZE, "%d\n", | |
| 376 | − (int)(unit->directory - device->config_rom)); | |
| 375 | + return sysfs_emit(buf, "%td\n", unit->directory - device->config_rom); | |
| 377 | 376 | } |
| 378 | 377 | |
| 379 | 378 | static struct device_attribute fw_unit_attributes[] = { |
| @@ -403,8 +402,7 @@ static ssize_t guid_show(struct device *dev, · 23 unmodified lines | ||
| 403 | 402 | int ret; |
| 404 | 403 | |
| 405 | 404 | down_read(&fw_device_rwsem); |
| 406 | − ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", | |
| 407 | − device->config_rom[3], device->config_rom[4]); | |
| 405 | + ret = sysfs_emit(buf, "0x%08x%08x\n", device->config_rom[3], device->config_rom[4]); | |
| 408 | 406 | up_read(&fw_device_rwsem); |
| 409 | 407 | |
| 410 | 408 | return ret; |
| @@ -36,7 +36,7 @@ struct scmi_msg_resp_base_attributes { · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | struct scmi_msg_resp_base_discover_agent { |
| 38 | 38 | __le32 agent_id; |
| 39 | − u8 name[SCMI_MAX_STR_SIZE]; | |
| 39 | + u8 name[SCMI_SHORT_NAME_MAX_SIZE]; | |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | 42 | |
| @@ -119,7 +119,7 @@ scmi_base_vendor_id_get(const struct scmi_protocol_handle *ph, bool sub_vendor) · 76 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | ret = ph->xops->do_xfer(ph, t); |
| 121 | 121 | if (!ret) |
| 122 | − memcpy(vendor_id, t->rx.buf, size); | |
| 122 | + strscpy(vendor_id, t->rx.buf, size); | |
| 123 | 123 | |
| 124 | 124 | ph->xops->xfer_put(ph, t); |
| 125 | 125 | |
| @@ -221,11 +221,17 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph, · 95 unmodified lines | ||
| 221 | 221 | calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) * |
| 222 | 222 | sizeof(u32); |
| 223 | 223 | if (calc_list_sz != real_list_sz) { |
| 224 | − dev_err(dev, | |
| 225 | − "Malformed reply - real_sz:%zd calc_sz:%u\n", | |
| 226 | − real_list_sz, calc_list_sz); | |
| 227 | − ret = -EPROTO; | |
| 228 | − break; | |
| 224 | + dev_warn(dev, | |
| 225 | + "Malformed reply - real_sz:%zd calc_sz:%u (loop_num_ret:%d)\n", | |
| 226 | + real_list_sz, calc_list_sz, loop_num_ret); | |
| 227 | + /* | |
| 228 | + * Bail out if the expected list size is bigger than the | |
| 229 | + * total payload size of the received reply. | |
| 230 | + */ | |
| 231 | + if (calc_list_sz > real_list_sz) { | |
| 232 | + ret = -EPROTO; | |
| 233 | + break; | |
| 234 | + } | |
| 229 | 235 | } |
| 230 | 236 | |
| 231 | 237 | for (loop = 0; loop < loop_num_ret; loop++) |
| @@ -270,7 +276,7 @@ static int scmi_base_discover_agent_get(const struct scmi_protocol_handle *ph, · 38 unmodified lines | ||
| 270 | 276 | ret = ph->xops->do_xfer(ph, t); |
| 271 | 277 | if (!ret) { |
| 272 | 278 | agent_info = t->rx.buf; |
| 273 | − strlcpy(name, agent_info->name, SCMI_MAX_STR_SIZE); | |
| 279 | + strscpy(name, agent_info->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 274 | 280 | } |
| 275 | 281 | |
| 276 | 282 | ph->xops->xfer_put(ph, t); |
| @@ -369,7 +375,7 @@ static int scmi_base_protocol_init(const struct scmi_protocol_handle *ph) · 92 unmodified lines | ||
| 369 | 375 | int id, ret; |
| 370 | 376 | u8 *prot_imp; |
| 371 | 377 | u32 version; |
| 372 | − char name[SCMI_MAX_STR_SIZE]; | |
| 378 | + char name[SCMI_SHORT_NAME_MAX_SIZE]; | |
| 373 | 379 | struct device *dev = ph->dev; |
| 374 | 380 | struct scmi_revision_info *rev = scmi_revision_area_get(ph); |
| 375 | 381 | |
| @@ -153,7 +153,7 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph, · 152 unmodified lines | ||
| 153 | 153 | if (!ret) { |
| 154 | 154 | u32 latency = 0; |
| 155 | 155 | attributes = le32_to_cpu(attr->attributes); |
| 156 | − strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE); | |
| 156 | + strscpy(clk->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 157 | 157 | /* clock_enable_latency field is present only since SCMI v3.1 */ |
| 158 | 158 | if (PROTOCOL_REV_MAJOR(version) >= 0x2) |
| 159 | 159 | latency = le32_to_cpu(attr->clock_enable_latency); |
| @@ -266,9 +266,7 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id, · 106 unmodified lines | ||
| 266 | 266 | struct scmi_clock_info *clk) |
| 267 | 267 | { |
| 268 | 268 | int ret; |
| 269 | − | |
| 270 | 269 | void *iter; |
| 271 | − struct scmi_msg_clock_describe_rates *msg; | |
| 272 | 270 | struct scmi_iterator_ops ops = { |
| 273 | 271 | .prepare_message = iter_clk_describe_prepare_message, |
| 274 | 272 | .update_state = iter_clk_describe_update_state, |
| @@ -281,7 +279,8 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id, · 6 unmodified lines | ||
| 281 | 279 | |
| 282 | 280 | iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES, |
| 283 | 281 | CLOCK_DESCRIBE_RATES, |
| 284 | − sizeof(*msg), &cpriv); | |
| 282 | + sizeof(struct scmi_msg_clock_describe_rates), | |
| 283 | + &cpriv); | |
| 285 | 284 | if (IS_ERR(iter)) |
| 286 | 285 | return PTR_ERR(iter); |
| 287 | 286 | |
| @@ -252,7 +252,7 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph, · 251 unmodified lines | ||
| 252 | 252 | dom_info->mult_factor = |
| 253 | 253 | (dom_info->sustained_freq_khz * 1000) / |
| 254 | 254 | dom_info->sustained_perf_level; |
| 255 | − strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); | |
| 255 | + strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | ph->xops->xfer_put(ph, t); |
| @@ -332,7 +332,6 @@ scmi_perf_describe_levels_get(const struct scmi_protocol_handle *ph, u32 domain, · 73 unmodified lines | ||
| 332 | 332 | { |
| 333 | 333 | int ret; |
| 334 | 334 | void *iter; |
| 335 | − struct scmi_msg_perf_describe_levels *msg; | |
| 336 | 335 | struct scmi_iterator_ops ops = { |
| 337 | 336 | .prepare_message = iter_perf_levels_prepare_message, |
| 338 | 337 | .update_state = iter_perf_levels_update_state, |
| @@ -345,7 +344,8 @@ scmi_perf_describe_levels_get(const struct scmi_protocol_handle *ph, u32 domain, · 6 unmodified lines | ||
| 345 | 344 | |
| 346 | 345 | iter = ph->hops->iter_response_init(ph, &ops, MAX_OPPS, |
| 347 | 346 | PERF_DESCRIBE_LEVELS, |
| 348 | − sizeof(*msg), &ppriv); | |
| 347 | + sizeof(struct scmi_msg_perf_describe_levels), | |
| 348 | + &ppriv); | |
| 349 | 349 | if (IS_ERR(iter)) |
| 350 | 350 | return PTR_ERR(iter); |
| 351 | 351 | |
| @@ -122,7 +122,7 @@ scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph, · 121 unmodified lines | ||
| 122 | 122 | dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); |
| 123 | 123 | dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); |
| 124 | 124 | dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags); |
| 125 | − strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); | |
| 125 | + strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 126 | 126 | } |
| 127 | 127 | ph->xops->xfer_put(ph, t); |
| 128 | 128 | |
| @@ -24,8 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include <asm/unaligned.h> |
| 26 | 26 | |
| 27 | −#define SCMI_SHORT_NAME_MAX_SIZE 16 | |
| 28 | − | |
| 29 | 27 | #define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0) |
| 30 | 28 | #define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16) |
| 31 | 29 | #define PROTOCOL_REV_MAJOR(x) ((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))) |
| @@ -116,7 +116,7 @@ scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph, · 115 unmodified lines | ||
| 116 | 116 | dom_info->latency_us = le32_to_cpu(attr->latency); |
| 117 | 117 | if (dom_info->latency_us == U32_MAX) |
| 118 | 118 | dom_info->latency_us = 0; |
| 119 | − strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); | |
| 119 | + strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | ph->xops->xfer_put(ph, t); |
| @@ -338,7 +338,6 @@ static int scmi_sensor_update_intervals(const struct scmi_protocol_handle *ph, · 337 unmodified lines | ||
| 338 | 338 | struct scmi_sensor_info *s) |
| 339 | 339 | { |
| 340 | 340 | void *iter; |
| 341 | − struct scmi_msg_sensor_list_update_intervals *msg; | |
| 342 | 341 | struct scmi_iterator_ops ops = { |
| 343 | 342 | .prepare_message = iter_intervals_prepare_message, |
| 344 | 343 | .update_state = iter_intervals_update_state, |
| @@ -351,22 +350,28 @@ static int scmi_sensor_update_intervals(const struct scmi_protocol_handle *ph, · 6 unmodified lines | ||
| 351 | 350 | |
| 352 | 351 | iter = ph->hops->iter_response_init(ph, &ops, s->intervals.count, |
| 353 | 352 | SENSOR_LIST_UPDATE_INTERVALS, |
| 354 | − sizeof(*msg), &upriv); | |
| 353 | + sizeof(struct scmi_msg_sensor_list_update_intervals), | |
| 354 | + &upriv); | |
| 355 | 355 | if (IS_ERR(iter)) |
| 356 | 356 | return PTR_ERR(iter); |
| 357 | 357 | |
| 358 | 358 | return ph->hops->iter_response_run(iter); |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | +struct scmi_apriv { | |
| 362 | + bool any_axes_support_extended_names; | |
| 363 | + struct scmi_sensor_info *s; | |
| 364 | +}; | |
| 365 | + | |
| 361 | 366 | static void iter_axes_desc_prepare_message(void *message, |
| 362 | 367 | const unsigned int desc_index, |
| 363 | 368 | const void *priv) |
| 364 | 369 | { |
| 365 | 370 | struct scmi_msg_sensor_axis_description_get *msg = message; |
| 366 | − const struct scmi_sensor_info *s = priv; | |
| 371 | + const struct scmi_apriv *apriv = priv; | |
| 367 | 372 | |
| 368 | 373 | /* Set the number of sensors to be skipped/already read */ |
| 369 | − msg->id = cpu_to_le32(s->id); | |
| 374 | + msg->id = cpu_to_le32(apriv->s->id); | |
| 370 | 375 | msg->axis_desc_index = cpu_to_le32(desc_index); |
| 371 | 376 | } |
| 372 | 377 | |
| @@ -393,19 +398,21 @@ iter_axes_desc_process_response(const struct scmi_protocol_handle *ph, · 20 unmodified lines | ||
| 393 | 398 | u32 attrh, attrl; |
| 394 | 399 | struct scmi_sensor_axis_info *a; |
| 395 | 400 | size_t dsize = SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ; |
| 396 | − struct scmi_sensor_info *s = priv; | |
| 401 | + struct scmi_apriv *apriv = priv; | |
| 397 | 402 | const struct scmi_axis_descriptor *adesc = st->priv; |
| 398 | 403 | |
| 399 | 404 | attrl = le32_to_cpu(adesc->attributes_low); |
| 405 | + if (SUPPORTS_EXTENDED_AXIS_NAMES(attrl)) | |
| 406 | + apriv->any_axes_support_extended_names = true; | |
| 400 | 407 | |
| 401 | − a = &s->axis[st->desc_index + st->loop_idx]; | |
| 408 | + a = &apriv->s->axis[st->desc_index + st->loop_idx]; | |
| 402 | 409 | a->id = le32_to_cpu(adesc->id); |
| 403 | 410 | a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl); |
| 404 | 411 | |
| 405 | 412 | attrh = le32_to_cpu(adesc->attributes_high); |
| 406 | 413 | a->scale = S32_EXT(SENSOR_SCALE(attrh)); |
| 407 | 414 | a->type = SENSOR_TYPE(attrh); |
| 408 | − strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE); | |
| 415 | + strscpy(a->name, adesc->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 409 | 416 | |
| 410 | 417 | if (a->extended_attrs) { |
| 411 | 418 | unsigned int ares = le32_to_cpu(adesc->resolution); |
| @@ -444,10 +451,19 @@ iter_axes_extended_name_process_response(const struct scmi_protocol_handle *ph, · 32 unmodified lines | ||
| 444 | 451 | void *priv) |
| 445 | 452 | { |
| 446 | 453 | struct scmi_sensor_axis_info *a; |
| 447 | − const struct scmi_sensor_info *s = priv; | |
| 454 | + const struct scmi_apriv *apriv = priv; | |
| 448 | 455 | struct scmi_sensor_axis_name_descriptor *adesc = st->priv; |
| 456 | + u32 axis_id = le32_to_cpu(adesc->axis_id); | |
| 449 | 457 | |
| 450 | − a = &s->axis[st->desc_index + st->loop_idx]; | |
| 458 | + if (axis_id >= st->max_resources) | |
| 459 | + return -EPROTO; | |
| 460 | + | |
| 461 | + /* | |
| 462 | + * Pick the corresponding descriptor based on the axis_id embedded | |
| 463 | + * in the reply since the list of axes supporting extended names | |
| 464 | + * can be a subset of all the axes. | |
| 465 | + */ | |
| 466 | + a = &apriv->s->axis[axis_id]; | |
| 451 | 467 | strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE); |
| 452 | 468 | st->priv = ++adesc; |
| 453 | 469 | |
| @@ -458,21 +474,36 @@ static int · 4 unmodified lines | ||
| 458 | 474 | scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph, |
| 459 | 475 | struct scmi_sensor_info *s) |
| 460 | 476 | { |
| 477 | + int ret; | |
| 461 | 478 | void *iter; |
| 462 | − struct scmi_msg_sensor_axis_description_get *msg; | |
| 463 | 479 | struct scmi_iterator_ops ops = { |
| 464 | 480 | .prepare_message = iter_axes_desc_prepare_message, |
| 465 | 481 | .update_state = iter_axes_extended_name_update_state, |
| 466 | 482 | .process_response = iter_axes_extended_name_process_response, |
| 467 | 483 | }; |
| 484 | + struct scmi_apriv apriv = { | |
| 485 | + .any_axes_support_extended_names = false, | |
| 486 | + .s = s, | |
| 487 | + }; | |
| 468 | 488 | |
| 469 | 489 | iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, |
| 470 | 490 | SENSOR_AXIS_NAME_GET, |
| 471 | − sizeof(*msg), s); | |
| 491 | + sizeof(struct scmi_msg_sensor_axis_description_get), | |
| 492 | + &apriv); | |
| 472 | 493 | if (IS_ERR(iter)) |
| 473 | 494 | return PTR_ERR(iter); |
| 474 | 495 | |
| 475 | − return ph->hops->iter_response_run(iter); | |
| 496 | + /* | |
| 497 | + * Do not cause whole protocol initialization failure when failing to | |
| 498 | + * get extended names for axes. | |
| 499 | + */ | |
| 500 | + ret = ph->hops->iter_response_run(iter); | |
| 501 | + if (ret) | |
| 502 | + dev_warn(ph->dev, | |
| 503 | + "Failed to get axes extended names for %s (ret:%d).\n", | |
| 504 | + s->name, ret); | |
| 505 | + | |
| 506 | + return 0; | |
| 476 | 507 | } |
| 477 | 508 | |
| 478 | 509 | static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, |
| @@ -481,12 +512,15 @@ static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, · 2 unmodified lines | ||
| 481 | 512 | { |
| 482 | 513 | int ret; |
| 483 | 514 | void *iter; |
| 484 | − struct scmi_msg_sensor_axis_description_get *msg; | |
| 485 | 515 | struct scmi_iterator_ops ops = { |
| 486 | 516 | .prepare_message = iter_axes_desc_prepare_message, |
| 487 | 517 | .update_state = iter_axes_desc_update_state, |
| 488 | 518 | .process_response = iter_axes_desc_process_response, |
| 489 | 519 | }; |
| 520 | + struct scmi_apriv apriv = { | |
| 521 | + .any_axes_support_extended_names = false, | |
| 522 | + .s = s, | |
| 523 | + }; | |
| 490 | 524 | |
| 491 | 525 | s->axis = devm_kcalloc(ph->dev, s->num_axis, |
| 492 | 526 | sizeof(*s->axis), GFP_KERNEL); |
| @@ -495,7 +529,8 @@ static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, · 2 unmodified lines | ||
| 495 | 529 | |
| 496 | 530 | iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, |
| 497 | 531 | SENSOR_AXIS_DESCRIPTION_GET, |
| 498 | − sizeof(*msg), s); | |
| 532 | + sizeof(struct scmi_msg_sensor_axis_description_get), | |
| 533 | + &apriv); | |
| 499 | 534 | if (IS_ERR(iter)) |
| 500 | 535 | return PTR_ERR(iter); |
| 501 | 536 | |
| @@ -503,7 +538,8 @@ static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, · 1 unmodified line | ||
| 503 | 538 | if (ret) |
| 504 | 539 | return ret; |
| 505 | 540 | |
| 506 | − if (PROTOCOL_REV_MAJOR(version) >= 0x3) | |
| 541 | + if (PROTOCOL_REV_MAJOR(version) >= 0x3 && | |
| 542 | + apriv.any_axes_support_extended_names) | |
| 507 | 543 | ret = scmi_sensor_axis_extended_names_get(ph, s); |
| 508 | 544 | |
| 509 | 545 | return ret; |
| @@ -598,7 +634,7 @@ iter_sens_descr_process_response(const struct scmi_protocol_handle *ph, · 88 unmodified lines | ||
| 598 | 634 | SUPPORTS_AXIS(attrh) ? |
| 599 | 635 | SENSOR_AXIS_NUMBER(attrh) : 0, |
| 600 | 636 | SCMI_MAX_NUM_SENSOR_AXIS); |
| 601 | − strscpy(s->name, sdesc->name, SCMI_MAX_STR_SIZE); | |
| 637 | + strscpy(s->name, sdesc->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 602 | 638 | |
| 603 | 639 | /* |
| 604 | 640 | * If supported overwrite short name with the extended |
| @@ -180,7 +180,6 @@ static int scmi_voltage_levels_get(const struct scmi_protocol_handle *ph, · 179 unmodified lines | ||
| 180 | 180 | { |
| 181 | 181 | int ret; |
| 182 | 182 | void *iter; |
| 183 | − struct scmi_msg_cmd_describe_levels *msg; | |
| 184 | 183 | struct scmi_iterator_ops ops = { |
| 185 | 184 | .prepare_message = iter_volt_levels_prepare_message, |
| 186 | 185 | .update_state = iter_volt_levels_update_state, |
| @@ -193,7 +192,8 @@ static int scmi_voltage_levels_get(const struct scmi_protocol_handle *ph, · 6 unmodified lines | ||
| 193 | 192 | |
| 194 | 193 | iter = ph->hops->iter_response_init(ph, &ops, v->num_levels, |
| 195 | 194 | VOLTAGE_DESCRIBE_LEVELS, |
| 196 | − sizeof(*msg), &vpriv); | |
| 195 | + sizeof(struct scmi_msg_cmd_describe_levels), | |
| 196 | + &vpriv); | |
| 197 | 197 | if (IS_ERR(iter)) |
| 198 | 198 | return PTR_ERR(iter); |
| 199 | 199 | |
| @@ -225,15 +225,14 @@ static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph, · 25 unmodified lines | ||
| 225 | 225 | |
| 226 | 226 | /* Retrieve domain attributes at first ... */ |
| 227 | 227 | put_unaligned_le32(dom, td->tx.buf); |
| 228 | − ret = ph->xops->do_xfer(ph, td); | |
| 229 | 228 | /* Skip domain on comms error */ |
| 230 | − if (ret) | |
| 229 | + if (ph->xops->do_xfer(ph, td)) | |
| 231 | 230 | continue; |
| 232 | 231 | |
| 233 | 232 | v = vinfo->domains + dom; |
| 234 | 233 | v->id = dom; |
| 235 | 234 | attributes = le32_to_cpu(resp_dom->attr); |
| 236 | − strlcpy(v->name, resp_dom->name, SCMI_MAX_STR_SIZE); | |
| 235 | + strscpy(v->name, resp_dom->name, SCMI_SHORT_NAME_MAX_SIZE); | |
| 237 | 236 | |
| 238 | 237 | /* |
| 239 | 238 | * If supported overwrite short name with the extended one; |
| @@ -249,12 +248,8 @@ static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph, · 9 unmodified lines | ||
| 249 | 248 | v->async_level_set = true; |
| 250 | 249 | } |
| 251 | 250 | |
| 252 | − ret = scmi_voltage_levels_get(ph, v); | |
| 253 | 251 | /* Skip invalid voltage descriptors */ |
| 254 | − if (ret) | |
| 255 | − continue; | |
| 256 | − | |
| 257 | − ph->xops->reset_rx_to_maxsz(ph, td); | |
| 252 | + scmi_voltage_levels_get(ph, v); | |
| 258 | 253 | } |
| 259 | 254 | |
| 260 | 255 | ph->xops->xfer_put(ph, td); |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/sysfb.h> |
| 27 | 27 | #include <video/vga.h> |
| 28 | 28 | |
| 29 | −#include <asm/efi.h> | |
| 30 | − | |
| 31 | 29 | enum { |
| 32 | 30 | OVERRIDE_NONE = 0x0, |
| 33 | 31 | OVERRIDE_BASE = 0x1, |
| @@ -434,25 +434,13 @@ static int grgpio_probe(struct platform_device *ofdev) · 433 unmodified lines | ||
| 434 | 434 | static int grgpio_remove(struct platform_device *ofdev) |
| 435 | 435 | { |
| 436 | 436 | struct grgpio_priv *priv = platform_get_drvdata(ofdev); |
| 437 | − int i; | |
| 438 | − int ret = 0; | |
| 439 | − | |
| 440 | − if (priv->domain) { | |
| 441 | − for (i = 0; i < GRGPIO_MAX_NGPIO; i++) { | |
| 442 | − if (priv->uirqs[i].refcnt != 0) { | |
| 443 | − ret = -EBUSY; | |
| 444 | − goto out; | |
| 445 | − } | |
| 446 | − } | |
| 447 | − } | |
| 448 | 437 | |
| 449 | 438 | gpiochip_remove(&priv->gc); |
| 450 | 439 | |
| 451 | 440 | if (priv->domain) |
| 452 | 441 | irq_domain_remove(priv->domain); |
| 453 | 442 | |
| 454 | −out: | |
| 455 | − return ret; | |
| 443 | + return 0; | |
| 456 | 444 | } |
| 457 | 445 | |
| 458 | 446 | static const struct of_device_id grgpio_match[] = { |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | 2 | // |
| 3 | −// MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | |
| 3 | +// MXS GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | |
| 4 | 4 | // Copyright 2008 Juergen Beisert, kernel@pengutronix.de |
| 5 | 5 | // |
| 6 | 6 | // Based on code from Freescale, |
| @@ -172,6 +172,8 @@ static void realtek_gpio_irq_unmask(struct irq_data *data) · 171 unmodified lines | ||
| 172 | 172 | unsigned long flags; |
| 173 | 173 | u16 m; |
| 174 | 174 | |
| 175 | + gpiochip_enable_irq(&ctrl->gc, line); | |
| 176 | + | |
| 175 | 177 | raw_spin_lock_irqsave(&ctrl->lock, flags); |
| 176 | 178 | m = ctrl->intr_mask[port]; |
| 177 | 179 | m |= realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK); |
| @@ -195,6 +197,8 @@ static void realtek_gpio_irq_mask(struct irq_data *data) · 17 unmodified lines | ||
| 195 | 197 | ctrl->intr_mask[port] = m; |
| 196 | 198 | realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m); |
| 197 | 199 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
| 200 | + | |
| 201 | + gpiochip_disable_irq(&ctrl->gc, line); | |
| 198 | 202 | } |
| 199 | 203 | |
| 200 | 204 | static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) |
| @@ -315,13 +319,15 @@ static int realtek_gpio_irq_init(struct gpio_chip *gc) · 114 unmodified lines | ||
| 315 | 319 | return 0; |
| 316 | 320 | } |
| 317 | 321 | |
| 318 | −static struct irq_chip realtek_gpio_irq_chip = { | |
| 322 | +static const struct irq_chip realtek_gpio_irq_chip = { | |
| 319 | 323 | .name = "realtek-otto-gpio", |
| 320 | 324 | .irq_ack = realtek_gpio_irq_ack, |
| 321 | 325 | .irq_mask = realtek_gpio_irq_mask, |
| 322 | 326 | .irq_unmask = realtek_gpio_irq_unmask, |
| 323 | 327 | .irq_set_type = realtek_gpio_irq_set_type, |
| 324 | 328 | .irq_set_affinity = realtek_gpio_irq_set_affinity, |
| 329 | + .flags = IRQCHIP_IMMUTABLE, | |
| 330 | + GPIOCHIP_IRQ_RESOURCE_HELPERS, | |
| 325 | 331 | }; |
| 326 | 332 | |
| 327 | 333 | static const struct of_device_id realtek_gpio_of_match[] = { |
| @@ -404,7 +410,7 @@ static int realtek_gpio_probe(struct platform_device *pdev) · 76 unmodified lines | ||
| 404 | 410 | irq = platform_get_irq_optional(pdev, 0); |
| 405 | 411 | if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) { |
| 406 | 412 | girq = &ctrl->gc.irq; |
| 407 | − girq->chip = &realtek_gpio_irq_chip; | |
| 413 | + gpio_irq_chip_set_chip(girq, &realtek_gpio_irq_chip); | |
| 408 | 414 | girq->default_type = IRQ_TYPE_NONE; |
| 409 | 415 | girq->handler = handle_bad_irq; |
| 410 | 416 | girq->parent_handler = realtek_gpio_irq_handler; |
| @@ -217,8 +217,6 @@ static int giu_get_irq(unsigned int irq) · 216 unmodified lines | ||
| 217 | 217 | printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", |
| 218 | 218 | maskl, pendl, maskh, pendh); |
| 219 | 219 | |
| 220 | − atomic_inc(&irq_err_count); | |
| 221 | − | |
| 222 | 220 | return -EINVAL; |
| 223 | 221 | } |
| 224 | 222 | |
| @@ -385,12 +385,13 @@ static int winbond_gpio_get(struct gpio_chip *gc, unsigned int offset) · 384 unmodified lines | ||
| 385 | 385 | unsigned long *base = gpiochip_get_data(gc); |
| 386 | 386 | const struct winbond_gpio_info *info; |
| 387 | 387 | bool val; |
| 388 | + int ret; | |
| 388 | 389 | |
| 389 | 390 | winbond_gpio_get_info(&offset, &info); |
| 390 | 391 | |
| 391 | − val = winbond_sio_enter(*base); | |
| 392 | − if (val) | |
| 393 | − return val; | |
| 392 | + ret = winbond_sio_enter(*base); | |
| 393 | + if (ret) | |
| 394 | + return ret; | |
| 394 | 395 | |
| 395 | 396 | winbond_sio_select_logical(*base, info->dev); |
| 396 | 397 | |
| @@ -642,7 +642,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 641 unmodified lines | ||
| 642 | 642 | atomic64_read(&adev->visible_pin_size), |
| 643 | 643 | vram_gtt.vram_size); |
| 644 | 644 | vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size; |
| 645 | − vram_gtt.gtt_size *= PAGE_SIZE; | |
| 646 | 645 | vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); |
| 647 | 646 | return copy_to_user(out, &vram_gtt, |
| 648 | 647 | min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0; |
| @@ -675,7 +674,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 26 unmodified lines | ||
| 675 | 674 | mem.cpu_accessible_vram.usable_heap_size * 3 / 4; |
| 676 | 675 | |
| 677 | 676 | mem.gtt.total_heap_size = gtt_man->size; |
| 678 | − mem.gtt.total_heap_size *= PAGE_SIZE; | |
| 679 | 677 | mem.gtt.usable_heap_size = mem.gtt.total_heap_size - |
| 680 | 678 | atomic64_read(&adev->gart_pin_size); |
| 681 | 679 | mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man); |
| @@ -1798,18 +1798,26 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 1797 unmodified lines | ||
| 1798 | 1798 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", |
| 1799 | 1799 | (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); |
| 1800 | 1800 | |
| 1801 | − /* Compute GTT size, either bsaed on 3/4th the size of RAM size | |
| 1801 | + /* Compute GTT size, either based on 1/2 the size of RAM size | |
| 1802 | 1802 | * or whatever the user passed on module init */ |
| 1803 | 1803 | if (amdgpu_gtt_size == -1) { |
| 1804 | 1804 | struct sysinfo si; |
| 1805 | 1805 | |
| 1806 | 1806 | si_meminfo(&si); |
| 1807 | − gtt_size = min(max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20), | |
| 1808 | − adev->gmc.mc_vram_size), | |
| 1809 | − ((uint64_t)si.totalram * si.mem_unit * 3/4)); | |
| 1810 | − } | |
| 1811 | − else | |
| 1807 | + /* Certain GL unit tests for large textures can cause problems | |
| 1808 | + * with the OOM killer since there is no way to link this memory | |
| 1809 | + * to a process. This was originally mitigated (but not necessarily | |
| 1810 | + * eliminated) by limiting the GTT size. The problem is this limit | |
| 1811 | + * is often too low for many modern games so just make the limit 1/2 | |
| 1812 | + * of system memory which aligns with TTM. The OOM accounting needs | |
| 1813 | + * to be addressed, but we shouldn't prevent common 3D applications | |
| 1814 | + * from being usable just to potentially mitigate that corner case. | |
| 1815 | + */ | |
| 1816 | + gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20), | |
| 1817 | + (u64)si.totalram * si.mem_unit / 2); | |
| 1818 | + } else { | |
| 1812 | 1819 | gtt_size = (uint64_t)amdgpu_gtt_size << 20; |
| 1820 | + } | |
| 1813 | 1821 | |
| 1814 | 1822 | /* Initialize GTT memory pool */ |
| 1815 | 1823 | r = amdgpu_gtt_mgr_init(adev, gtt_size); |
| @@ -2812,7 +2812,7 @@ static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = { · 2811 unmodified lines | ||
| 2812 | 2812 | |
| 2813 | 2813 | static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) |
| 2814 | 2814 | { |
| 2815 | − u32 max_cll, min_cll, max, min, q, r; | |
| 2815 | + u32 max_avg, min_cll, max, min, q, r; | |
| 2816 | 2816 | struct amdgpu_dm_backlight_caps *caps; |
| 2817 | 2817 | struct amdgpu_display_manager *dm; |
| 2818 | 2818 | struct drm_connector *conn_base; |
| @@ -2842,7 +2842,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) · 23 unmodified lines | ||
| 2842 | 2842 | caps = &dm->backlight_caps[i]; |
| 2843 | 2843 | caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; |
| 2844 | 2844 | caps->aux_support = false; |
| 2845 | − max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll; | |
| 2845 | + max_avg = conn_base->hdr_sink_metadata.hdmi_type1.max_fall; | |
| 2846 | 2846 | min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; |
| 2847 | 2847 | |
| 2848 | 2848 | if (caps->ext_caps->bits.oled == 1 /*|| |
| @@ -2870,8 +2870,8 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) · 21 unmodified lines | ||
| 2870 | 2870 | * The results of the above expressions can be verified at |
| 2871 | 2871 | * pre_computed_values. |
| 2872 | 2872 | */ |
| 2873 | − q = max_cll >> 5; | |
| 2874 | − r = max_cll % 32; | |
| 2873 | + q = max_avg >> 5; | |
| 2874 | + r = max_avg % 32; | |
| 2875 | 2875 | max = (1 << q) * pre_computed_values[r]; |
| 2876 | 2876 | |
| 2877 | 2877 | // min luminance: maxLum * (CV/255)^2 / 100 |
| @@ -550,7 +550,7 @@ static void dcn315_clk_mgr_helper_populate_bw_params( · 549 unmodified lines | ||
| 550 | 550 | if (!bw_params->clk_table.entries[i].dtbclk_mhz) |
| 551 | 551 | bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz; |
| 552 | 552 | } |
| 553 | − ASSERT(bw_params->clk_table.entries[i].dcfclk_mhz); | |
| 553 | + ASSERT(bw_params->clk_table.entries[i-1].dcfclk_mhz); | |
| 554 | 554 | bw_params->vram_type = bios_info->memory_type; |
| 555 | 555 | bw_params->num_channels = bios_info->ma_channel_number; |
| 556 | 556 | if (!bw_params->num_channels) |
| @@ -944,7 +944,7 @@ static void override_lane_settings(const struct link_training_settings *lt_setti · 943 unmodified lines | ||
| 944 | 944 | |
| 945 | 945 | return; |
| 946 | 946 | |
| 947 | − for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) { | |
| 947 | + for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { | |
| 948 | 948 | if (lt_settings->voltage_swing) |
| 949 | 949 | lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing; |
| 950 | 950 | if (lt_settings->pre_emphasis) |
| @@ -1766,29 +1766,9 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) · 1765 unmodified lines | ||
| 1766 | 1766 | break; |
| 1767 | 1767 | } |
| 1768 | 1768 | } |
| 1769 | − | |
| 1770 | − /* | |
| 1771 | − * TO-DO: So far the code logic below only addresses single eDP case. | |
| 1772 | − * For dual eDP case, there are a few things that need to be | |
| 1773 | − * implemented first: | |
| 1774 | − * | |
| 1775 | − * 1. Change the fastboot logic above, so eDP link[0 or 1]'s | |
| 1776 | − * stream[0 or 1] will all be checked. | |
| 1777 | − * | |
| 1778 | − * 2. Change keep_edp_vdd_on to an array, and maintain keep_edp_vdd_on | |
| 1779 | − * for each eDP. | |
| 1780 | − * | |
| 1781 | − * Once above 2 things are completed, we can then change the logic below | |
| 1782 | − * correspondingly, so dual eDP case will be fully covered. | |
| 1783 | − */ | |
| 1784 | − | |
| 1785 | − // We are trying to enable eDP, don't power down VDD if eDP stream is existing | |
| 1786 | − if ((edp_stream_num == 1 && edp_streams[0] != NULL) || can_apply_edp_fast_boot) { | |
| 1769 | + // We are trying to enable eDP, don't power down VDD | |
| 1770 | + if (can_apply_edp_fast_boot) | |
| 1787 | 1771 | keep_edp_vdd_on = true; |
| 1788 | − DC_LOG_EVENT_LINK_TRAINING("Keep eDP Vdd on\n"); | |
| 1789 | − } else { | |
| 1790 | − DC_LOG_EVENT_LINK_TRAINING("No eDP stream enabled, turn eDP Vdd off\n"); | |
| 1791 | − } | |
| 1792 | 1772 | } |
| 1793 | 1773 | |
| 1794 | 1774 | // Check seamless boot support |
| @@ -212,6 +212,9 @@ static void dpp2_cnv_setup ( · 211 unmodified lines | ||
| 212 | 212 | break; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | + /* Set default color space based on format if none is given. */ | |
| 216 | + color_space = input_color_space ? input_color_space : color_space; | |
| 217 | + | |
| 215 | 218 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { |
| 216 | 219 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); |
| 217 | 220 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); |
| @@ -153,6 +153,9 @@ static void dpp201_cnv_setup( · 152 unmodified lines | ||
| 153 | 153 | break; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | + /* Set default color space based on format if none is given. */ | |
| 157 | + color_space = input_color_space ? input_color_space : color_space; | |
| 158 | + | |
| 156 | 159 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { |
| 157 | 160 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); |
| 158 | 161 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); |
| @@ -294,6 +294,9 @@ static void dpp3_cnv_setup ( · 293 unmodified lines | ||
| 294 | 294 | break; |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | + /* Set default color space based on format if none is given. */ | |
| 298 | + color_space = input_color_space ? input_color_space : color_space; | |
| 299 | + | |
| 297 | 300 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { |
| 298 | 301 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); |
| 299 | 302 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); |
| @@ -152,6 +152,12 @@ static const struct dmi_system_id orientation_data[] = { · 151 unmodified lines | ||
| 152 | 152 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"), |
| 153 | 153 | }, |
| 154 | 154 | .driver_data = (void *)&lcd800x1280_rightside_up, |
| 155 | + }, { /* AYA NEO NEXT */ | |
| 156 | + .matches = { | |
| 157 | + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), | |
| 158 | + DMI_MATCH(DMI_BOARD_NAME, "NEXT"), | |
| 159 | + }, | |
| 160 | + .driver_data = (void *)&lcd800x1280_rightside_up, | |
| 155 | 161 | }, { /* Chuwi HiBook (CWI514) */ |
| 156 | 162 | .matches = { |
| 157 | 163 | DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), |
| @@ -176,15 +176,15 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = { · 175 unmodified lines | ||
| 176 | 176 | }, { |
| 177 | 177 | DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), |
| 178 | 178 | DRM_COMPONENT_DRIVER |
| 179 | − }, { | |
| 180 | − DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), | |
| 181 | − DRM_COMPONENT_DRIVER | |
| 182 | 179 | }, { |
| 183 | 180 | DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP), |
| 184 | 181 | DRM_COMPONENT_DRIVER |
| 185 | 182 | }, { |
| 186 | 183 | DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI), |
| 187 | 184 | DRM_COMPONENT_DRIVER |
| 185 | + }, { | |
| 186 | + DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), | |
| 187 | + DRM_COMPONENT_DRIVER | |
| 188 | 188 | }, { |
| 189 | 189 | DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI), |
| 190 | 190 | DRM_COMPONENT_DRIVER |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <drm/drm_print.h> |
| 27 | 27 | |
| 28 | 28 | #include "exynos_drm_drv.h" |
| 29 | +#include "exynos_drm_crtc.h" | |
| 29 | 30 | |
| 30 | 31 | /* Sysreg registers for MIC */ |
| 31 | 32 | #define DSD_CFG_MUX 0x1004 |
| @@ -100,9 +101,7 @@ struct exynos_mic { · 68 unmodified lines | ||
| 100 | 101 | |
| 101 | 102 | bool i80_mode; |
| 102 | 103 | struct videomode vm; |
| 103 | − struct drm_encoder *encoder; | |
| 104 | 104 | struct drm_bridge bridge; |
| 105 | − struct drm_bridge *next_bridge; | |
| 106 | 105 | |
| 107 | 106 | bool enabled; |
| 108 | 107 | }; |
| @@ -229,8 +228,6 @@ static void mic_set_reg_on(struct exynos_mic *mic, bool enable) · 120 unmodified lines | ||
| 229 | 228 | writel(reg, mic->reg + MIC_OP); |
| 230 | 229 | } |
| 231 | 230 | |
| 232 | −static void mic_disable(struct drm_bridge *bridge) { } | |
| 233 | − | |
| 234 | 231 | static void mic_post_disable(struct drm_bridge *bridge) |
| 235 | 232 | { |
| 236 | 233 | struct exynos_mic *mic = bridge->driver_private; |
| @@ -297,34 +294,30 @@ unlock: · 60 unmodified lines | ||
| 297 | 294 | mutex_unlock(&mic_mutex); |
| 298 | 295 | } |
| 299 | 296 | |
| 300 | −static void mic_enable(struct drm_bridge *bridge) { } | |
| 301 | − | |
| 302 | −static int mic_attach(struct drm_bridge *bridge, | |
| 303 | − enum drm_bridge_attach_flags flags) | |
| 304 | −{ | |
| 305 | − struct exynos_mic *mic = bridge->driver_private; | |
| 306 | − | |
| 307 | − return drm_bridge_attach(bridge->encoder, mic->next_bridge, | |
| 308 | − &mic->bridge, flags); | |
| 309 | −} | |
| 310 | − | |
| 311 | 297 | static const struct drm_bridge_funcs mic_bridge_funcs = { |
| 312 | − .disable = mic_disable, | |
| 313 | 298 | .post_disable = mic_post_disable, |
| 314 | 299 | .mode_set = mic_mode_set, |
| 315 | 300 | .pre_enable = mic_pre_enable, |
| 316 | − .enable = mic_enable, | |
| 317 | − .attach = mic_attach, | |
| 318 | 301 | }; |
| 319 | 302 | |
| 320 | 303 | static int exynos_mic_bind(struct device *dev, struct device *master, |
| 321 | 304 | void *data) |
| 322 | 305 | { |
| 323 | 306 | struct exynos_mic *mic = dev_get_drvdata(dev); |
| 307 | + struct drm_device *drm_dev = data; | |
| 308 | + struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev, | |
| 309 | + EXYNOS_DISPLAY_TYPE_LCD); | |
| 310 | + struct drm_encoder *e, *encoder = NULL; | |
| 311 | + | |
| 312 | + drm_for_each_encoder(e, drm_dev) | |
| 313 | + if (e->possible_crtcs == drm_crtc_mask(&crtc->base)) | |
| 314 | + encoder = e; | |
| 315 | + if (!encoder) | |
| 316 | + return -ENODEV; | |
| 324 | 317 | |
| 325 | 318 | mic->bridge.driver_private = mic; |
| 326 | 319 | |
| 327 | − return 0; | |
| 320 | + return drm_bridge_attach(encoder, &mic->bridge, NULL, 0); | |
| 328 | 321 | } |
| 329 | 322 | |
| 330 | 323 | static void exynos_mic_unbind(struct device *dev, struct device *master, |
| @@ -388,7 +381,6 @@ static int exynos_mic_probe(struct platform_device *pdev) · 57 unmodified lines | ||
| 388 | 381 | { |
| 389 | 382 | struct device *dev = &pdev->dev; |
| 390 | 383 | struct exynos_mic *mic; |
| 391 | − struct device_node *remote; | |
| 392 | 384 | struct resource res; |
| 393 | 385 | int ret, i; |
| 394 | 386 | |
| @@ -432,16 +424,6 @@ static int exynos_mic_probe(struct platform_device *pdev) · 37 unmodified lines | ||
| 432 | 424 | } |
| 433 | 425 | } |
| 434 | 426 | |
| 435 | − remote = of_graph_get_remote_node(dev->of_node, 1, 0); | |
| 436 | − mic->next_bridge = of_drm_find_bridge(remote); | |
| 437 | − if (IS_ERR(mic->next_bridge)) { | |
| 438 | − DRM_DEV_ERROR(dev, "mic: Failed to find next bridge\n"); | |
| 439 | − ret = PTR_ERR(mic->next_bridge); | |
| 440 | − goto err; | |
| 441 | − } | |
| 442 | − | |
| 443 | − of_node_put(remote); | |
| 444 | − | |
| 445 | 427 | platform_set_drvdata(pdev, mic); |
| 446 | 428 | |
| 447 | 429 | mic->bridge.funcs = &mic_bridge_funcs; |
| @@ -388,13 +388,23 @@ static int dg2_max_source_rate(struct intel_dp *intel_dp) · 387 unmodified lines | ||
| 388 | 388 | return intel_dp_is_edp(intel_dp) ? 810000 : 1350000; |
| 389 | 389 | } |
| 390 | 390 | |
| 391 | +static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy) | |
| 392 | +{ | |
| 393 | + u32 voltage; | |
| 394 | + | |
| 395 | + voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & VOLTAGE_INFO_MASK; | |
| 396 | + | |
| 397 | + return voltage == VOLTAGE_INFO_0_85V; | |
| 398 | +} | |
| 399 | + | |
| 391 | 400 | static int icl_max_source_rate(struct intel_dp *intel_dp) |
| 392 | 401 | { |
| 393 | 402 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 394 | 403 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
| 395 | 404 | enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); |
| 396 | 405 | |
| 397 | − if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp)) | |
| 406 | + if (intel_phy_is_combo(dev_priv, phy) && | |
| 407 | + (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp))) | |
| 398 | 408 | return 540000; |
| 399 | 409 | |
| 400 | 410 | return 810000; |
| @@ -402,7 +412,23 @@ static int icl_max_source_rate(struct intel_dp *intel_dp) · 1 unmodified line | ||
| 402 | 412 | |
| 403 | 413 | static int ehl_max_source_rate(struct intel_dp *intel_dp) |
| 404 | 414 | { |
| 405 | − if (intel_dp_is_edp(intel_dp)) | |
| 415 | + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 416 | + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 417 | + enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); | |
| 418 | + | |
| 419 | + if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy)) | |
| 420 | + return 540000; | |
| 421 | + | |
| 422 | + return 810000; | |
| 423 | +} | |
| 424 | + | |
| 425 | +static int dg1_max_source_rate(struct intel_dp *intel_dp) | |
| 426 | +{ | |
| 427 | + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 428 | + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); | |
| 429 | + enum phy phy = intel_port_to_phy(i915, dig_port->base.port); | |
| 430 | + | |
| 431 | + if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy)) | |
| 406 | 432 | return 540000; |
| 407 | 433 | |
| 408 | 434 | return 810000; |
| @@ -445,7 +471,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) · 36 unmodified lines | ||
| 445 | 471 | max_rate = dg2_max_source_rate(intel_dp); |
| 446 | 472 | else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) || |
| 447 | 473 | IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) |
| 448 | − max_rate = 810000; | |
| 474 | + max_rate = dg1_max_source_rate(intel_dp); | |
| 449 | 475 | else if (IS_JSL_EHL(dev_priv)) |
| 450 | 476 | max_rate = ehl_max_source_rate(intel_dp); |
| 451 | 477 | else |
| @@ -2396,7 +2396,7 @@ static void icl_wrpll_params_populate(struct skl_wrpll_params *params, · 2395 unmodified lines | ||
| 2396 | 2396 | } |
| 2397 | 2397 | |
| 2398 | 2398 | /* |
| 2399 | − * Display WA #22010492432: ehl, tgl, adl-p | |
| 2399 | + * Display WA #22010492432: ehl, tgl, adl-s, adl-p | |
| 2400 | 2400 | * Program half of the nominal DCO divider fraction value. |
| 2401 | 2401 | */ |
| 2402 | 2402 | static bool |
| @@ -2404,7 +2404,7 @@ ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915) · 1 unmodified line | ||
| 2404 | 2404 | { |
| 2405 | 2405 | return ((IS_PLATFORM(i915, INTEL_ELKHARTLAKE) && |
| 2406 | 2406 | IS_JSL_EHL_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) || |
| 2407 | − IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) && | |
| 2407 | + IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) && | |
| 2408 | 2408 | i915->dpll.ref_clks.nssc == 38400; |
| 2409 | 2409 | } |
| 2410 | 2410 | |
| @@ -999,7 +999,8 @@ static int eb_validate_vmas(struct i915_execbuffer *eb) · 998 unmodified lines | ||
| 999 | 999 | } |
| 1000 | 1000 | } |
| 1001 | 1001 | |
| 1002 | − err = dma_resv_reserve_fences(vma->obj->base.resv, 1); | |
| 1002 | + /* Reserve enough slots to accommodate composite fences */ | |
| 1003 | + err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches); | |
| 1003 | 1004 | if (err) |
| 1004 | 1005 | return err; |
| 1005 | 1006 | |
| @@ -785,6 +785,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt) · 784 unmodified lines | ||
| 785 | 785 | { |
| 786 | 786 | intel_wakeref_t wakeref; |
| 787 | 787 | |
| 788 | + intel_gt_sysfs_unregister(gt); | |
| 788 | 789 | intel_rps_driver_unregister(>->rps); |
| 789 | 790 | intel_gsc_fini(>->gsc); |
| 790 | 791 | |
| @@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj) · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | static struct intel_gt *kobj_to_gt(struct kobject *kobj) |
| 26 | 26 | { |
| 27 | − return container_of(kobj, struct kobj_gt, base)->gt; | |
| 27 | + return container_of(kobj, struct intel_gt, sysfs_gt); | |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | 30 | struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, |
| @@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = { · 41 unmodified lines | ||
| 72 | 72 | }; |
| 73 | 73 | ATTRIBUTE_GROUPS(id); |
| 74 | 74 | |
| 75 | +/* A kobject needs a release() method even if it does nothing */ | |
| 75 | 76 | static void kobj_gt_release(struct kobject *kobj) |
| 76 | 77 | { |
| 77 | − kfree(kobj); | |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | static struct kobj_type kobj_gt_type = { |
| @@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = { · 4 unmodified lines | ||
| 85 | 85 | |
| 86 | 86 | void intel_gt_sysfs_register(struct intel_gt *gt) |
| 87 | 87 | { |
| 88 | − struct kobj_gt *kg; | |
| 89 | − | |
| 90 | 88 | /* |
| 91 | 89 | * We need to make things right with the |
| 92 | 90 | * ABI compatibility. The files were originally |
| @@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt) · 5 unmodified lines | ||
| 98 | 96 | if (gt_is_root(gt)) |
| 99 | 97 | intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt)); |
| 100 | 98 | |
| 101 | − kg = kzalloc(sizeof(*kg), GFP_KERNEL); | |
| 102 | − if (!kg) | |
| 99 | + /* init and xfer ownership to sysfs tree */ | |
| 100 | + if (kobject_init_and_add(>->sysfs_gt, &kobj_gt_type, | |
| 101 | + gt->i915->sysfs_gt, "gt%d", gt->info.id)) | |
| 103 | 102 | goto exit_fail; |
| 104 | 103 | |
| 105 | − kobject_init(&kg->base, &kobj_gt_type); | |
| 106 | − kg->gt = gt; | |
| 107 | − | |
| 108 | − /* xfer ownership to sysfs tree */ | |
| 109 | − if (kobject_add(&kg->base, gt->i915->sysfs_gt, "gt%d", gt->info.id)) | |
| 110 | − goto exit_kobj_put; | |
| 111 | − | |
| 112 | − intel_gt_sysfs_pm_init(gt, &kg->base); | |
| 104 | + intel_gt_sysfs_pm_init(gt, >->sysfs_gt); | |
| 113 | 105 | |
| 114 | 106 | return; |
| 115 | 107 | |
| 116 | −exit_kobj_put: | |
| 117 | − kobject_put(&kg->base); | |
| 118 | − | |
| 119 | 108 | exit_fail: |
| 109 | + kobject_put(>->sysfs_gt); | |
| 120 | 110 | drm_warn(>->i915->drm, |
| 121 | 111 | "failed to initialize gt%d sysfs root\n", gt->info.id); |
| 122 | 112 | } |
| 113 | + | |
| 114 | +void intel_gt_sysfs_unregister(struct intel_gt *gt) | |
| 115 | +{ | |
| 116 | + kobject_put(>->sysfs_gt); | |
| 117 | +} | |
| @@ -13,11 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | struct intel_gt; |
| 15 | 15 | |
| 16 | −struct kobj_gt { | |
| 17 | − struct kobject base; | |
| 18 | − struct intel_gt *gt; | |
| 19 | −}; | |
| 20 | − | |
| 21 | 16 | bool is_object_gt(struct kobject *kobj); |
| 22 | 17 | |
| 23 | 18 | struct drm_i915_private *kobj_to_i915(struct kobject *kobj); |
| @@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt, · 4 unmodified lines | ||
| 28 | 23 | const char *name); |
| 29 | 24 | |
| 30 | 25 | void intel_gt_sysfs_register(struct intel_gt *gt); |
| 26 | +void intel_gt_sysfs_unregister(struct intel_gt *gt); | |
| 31 | 27 | struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, |
| 32 | 28 | const char *name); |
| 33 | 29 | |
| @@ -224,6 +224,9 @@ struct intel_gt { · 223 unmodified lines | ||
| 224 | 224 | } mocs; |
| 225 | 225 | |
| 226 | 226 | struct intel_pxp pxp; |
| 227 | + | |
| 228 | + /* gt/gtN sysfs */ | |
| 229 | + struct kobject sysfs_gt; | |
| 227 | 230 | }; |
| 228 | 231 | |
| 229 | 232 | enum intel_gt_scratch_field { |
| @@ -156,7 +156,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw) · 155 unmodified lines | ||
| 156 | 156 | [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) }, |
| 157 | 157 | [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) }, |
| 158 | 158 | }; |
| 159 | − static const struct uc_fw_platform_requirement *fw_blobs; | |
| 159 | + const struct uc_fw_platform_requirement *fw_blobs; | |
| 160 | 160 | enum intel_platform p = INTEL_INFO(i915)->platform; |
| 161 | 161 | u32 fw_count; |
| 162 | 162 | u8 rev = INTEL_REVID(i915); |
| @@ -116,8 +116,9 @@ show_client_class(struct seq_file *m, · 115 unmodified lines | ||
| 116 | 116 | total += busy_add(ctx, class); |
| 117 | 117 | rcu_read_unlock(); |
| 118 | 118 | |
| 119 | − seq_printf(m, "drm-engine-%s:\t%llu ns\n", | |
| 120 | − uabi_class_names[class], total); | |
| 119 | + if (capacity) | |
| 120 | + seq_printf(m, "drm-engine-%s:\t%llu ns\n", | |
| 121 | + uabi_class_names[class], total); | |
| 121 | 122 | |
| 122 | 123 | if (capacity > 1) |
| 123 | 124 | seq_printf(m, "drm-engine-capacity-%s:\t%u\n", |
| @@ -166,7 +166,14 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj, · 165 unmodified lines | ||
| 166 | 166 | struct device *kdev = kobj_to_dev(kobj); |
| 167 | 167 | struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); |
| 168 | 168 | struct i915_gpu_coredump *gpu; |
| 169 | − ssize_t ret; | |
| 169 | + ssize_t ret = 0; | |
| 170 | + | |
| 171 | + /* | |
| 172 | + * FIXME: Concurrent clients triggering resets and reading + clearing | |
| 173 | + * dumps can cause inconsistent sysfs reads when a user calls in with a | |
| 174 | + * non-zero offset to complete a prior partial read but the | |
| 175 | + * gpu_coredump has been cleared or replaced. | |
| 176 | + */ | |
| 170 | 177 | |
| 171 | 178 | gpu = i915_first_error_state(i915); |
| 172 | 179 | if (IS_ERR(gpu)) { |
| @@ -178,8 +185,10 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj, · 5 unmodified lines | ||
| 178 | 185 | const char *str = "No error state collected\n"; |
| 179 | 186 | size_t len = strlen(str); |
| 180 | 187 | |
| 181 | − ret = min_t(size_t, count, len - off); | |
| 182 | − memcpy(buf, str + off, ret); | |
| 188 | + if (off < len) { | |
| 189 | + ret = min_t(size_t, count, len - off); | |
| 190 | + memcpy(buf, str + off, ret); | |
| 191 | + } | |
| 183 | 192 | } |
| 184 | 193 | |
| 185 | 194 | return ret; |
| @@ -259,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv) · 73 unmodified lines | ||
| 259 | 268 | |
| 260 | 269 | device_remove_bin_file(kdev, &dpf_attrs_1); |
| 261 | 270 | device_remove_bin_file(kdev, &dpf_attrs); |
| 271 | + | |
| 272 | + kobject_put(dev_priv->sysfs_gt); | |
| 262 | 273 | } |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | 25 | #include <linux/sched/mm.h> |
| 26 | +#include <linux/dma-fence-array.h> | |
| 26 | 27 | #include <drm/drm_gem.h> |
| 27 | 28 | |
| 28 | 29 | #include "display/intel_frontbuffer.h" |
| @@ -1823,6 +1824,21 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 1794 unmodified lines | ||
| 1823 | 1824 | if (unlikely(err)) |
| 1824 | 1825 | return err; |
| 1825 | 1826 | |
| 1827 | + /* | |
| 1828 | + * Reserve fences slot early to prevent an allocation after preparing | |
| 1829 | + * the workload and associating fences with dma_resv. | |
| 1830 | + */ | |
| 1831 | + if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) { | |
| 1832 | + struct dma_fence *curr; | |
| 1833 | + int idx; | |
| 1834 | + | |
| 1835 | + dma_fence_array_for_each(curr, idx, fence) | |
| 1836 | + ; | |
| 1837 | + err = dma_resv_reserve_fences(vma->obj->base.resv, idx); | |
| 1838 | + if (unlikely(err)) | |
| 1839 | + return err; | |
| 1840 | + } | |
| 1841 | + | |
| 1826 | 1842 | if (flags & EXEC_OBJECT_WRITE) { |
| 1827 | 1843 | struct intel_frontbuffer *front; |
| 1828 | 1844 | |
| @@ -1832,31 +1848,23 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 3 unmodified lines | ||
| 1832 | 1848 | i915_active_add_request(&front->write, rq); |
| 1833 | 1849 | intel_frontbuffer_put(front); |
| 1834 | 1850 | } |
| 1851 | + } | |
| 1835 | 1852 | |
| 1836 | − if (!(flags & __EXEC_OBJECT_NO_RESERVE)) { | |
| 1837 | − err = dma_resv_reserve_fences(vma->obj->base.resv, 1); | |
| 1838 | − if (unlikely(err)) | |
| 1839 | − return err; | |
| 1840 | − } | |
| 1853 | + if (fence) { | |
| 1854 | + struct dma_fence *curr; | |
| 1855 | + enum dma_resv_usage usage; | |
| 1856 | + int idx; | |
| 1841 | 1857 | |
| 1842 | − if (fence) { | |
| 1843 | − dma_resv_add_fence(vma->obj->base.resv, fence, | |
| 1844 | − DMA_RESV_USAGE_WRITE); | |
| 1858 | + obj->read_domains = 0; | |
| 1859 | + if (flags & EXEC_OBJECT_WRITE) { | |
| 1860 | + usage = DMA_RESV_USAGE_WRITE; | |
| 1845 | 1861 | obj->write_domain = I915_GEM_DOMAIN_RENDER; |
| 1846 | − obj->read_domains = 0; | |
| 1847 | − } | |
| 1848 | − } else { | |
| 1849 | − if (!(flags & __EXEC_OBJECT_NO_RESERVE)) { | |
| 1850 | − err = dma_resv_reserve_fences(vma->obj->base.resv, 1); | |
| 1851 | − if (unlikely(err)) | |
| 1852 | − return err; | |
| 1862 | + } else { | |
| 1863 | + usage = DMA_RESV_USAGE_READ; | |
| 1853 | 1864 | } |
| 1854 | 1865 | |
| 1855 | − if (fence) { | |
| 1856 | − dma_resv_add_fence(vma->obj->base.resv, fence, | |
| 1857 | − DMA_RESV_USAGE_READ); | |
| 1858 | − obj->write_domain = 0; | |
| 1859 | − } | |
| 1866 | + dma_fence_array_for_each(curr, idx, fence) | |
| 1867 | + dma_resv_add_fence(vma->obj->base.resv, curr, usage); | |
| 1860 | 1868 | } |
| 1861 | 1869 | |
| 1862 | 1870 | if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence) |
| @@ -498,10 +498,15 @@ int adreno_hw_init(struct msm_gpu *gpu) · 497 unmodified lines | ||
| 498 | 498 | |
| 499 | 499 | ring->cur = ring->start; |
| 500 | 500 | ring->next = ring->start; |
| 501 | − | |
| 502 | − /* reset completed fence seqno: */ | |
| 503 | − ring->memptrs->fence = ring->fctx->completed_fence; | |
| 504 | 501 | ring->memptrs->rptr = 0; |
| 502 | + | |
| 503 | + /* Detect and clean up an impossible fence, ie. if GPU managed | |
| 504 | + * to scribble something invalid, we don't want that to confuse | |
| 505 | + * us into mistakingly believing that submits have completed. | |
| 506 | + */ | |
| 507 | + if (fence_before(ring->fctx->last_fence, ring->memptrs->fence)) { | |
| 508 | + ring->memptrs->fence = ring->fctx->last_fence; | |
| 509 | + } | |
| 505 | 510 | } |
| 506 | 511 | |
| 507 | 512 | return 0; |
| @@ -1057,7 +1062,8 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) · 549 unmodified lines | ||
| 1057 | 1062 | for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) |
| 1058 | 1063 | release_firmware(adreno_gpu->fw[i]); |
| 1059 | 1064 | |
| 1060 | − pm_runtime_disable(&priv->gpu_pdev->dev); | |
| 1065 | + if (pm_runtime_enabled(&priv->gpu_pdev->dev)) | |
| 1066 | + pm_runtime_disable(&priv->gpu_pdev->dev); | |
| 1061 | 1067 | |
| 1062 | 1068 | msm_gpu_cleanup(&adreno_gpu->base); |
| 1063 | 1069 | } |
| @@ -11,7 +11,14 @@ static int dpu_wb_conn_get_modes(struct drm_connector *connector) · 10 unmodified lines | ||
| 11 | 11 | struct msm_drm_private *priv = dev->dev_private; |
| 12 | 12 | struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); |
| 13 | 13 | |
| 14 | − return drm_add_modes_noedid(connector, dpu_kms->catalog->caps->max_linewidth, | |
| 14 | + /* | |
| 15 | + * We should ideally be limiting the modes only to the maxlinewidth but | |
| 16 | + * on some chipsets this will allow even 4k modes to be added which will | |
| 17 | + * fail the per SSPP bandwidth checks. So, till we have dual-SSPP support | |
| 18 | + * and source split support added lets limit the modes based on max_mixer_width | |
| 19 | + * as 4K modes can then be supported. | |
| 20 | + */ | |
| 21 | + return drm_add_modes_noedid(connector, dpu_kms->catalog->caps->max_mixer_width, | |
| 15 | 22 | dev->mode_config.max_height); |
| 16 | 23 | } |
| 17 | 24 | |
| @@ -216,6 +216,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, · 215 unmodified lines | ||
| 216 | 216 | encoder = mdp4_lcdc_encoder_init(dev, panel_node); |
| 217 | 217 | if (IS_ERR(encoder)) { |
| 218 | 218 | DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); |
| 219 | + of_node_put(panel_node); | |
| 219 | 220 | return PTR_ERR(encoder); |
| 220 | 221 | } |
| 221 | 222 | |
| @@ -225,6 +226,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, · 3 unmodified lines | ||
| 225 | 226 | connector = mdp4_lvds_connector_init(dev, panel_node, encoder); |
| 226 | 227 | if (IS_ERR(connector)) { |
| 227 | 228 | DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); |
| 229 | + of_node_put(panel_node); | |
| 228 | 230 | return PTR_ERR(connector); |
| 229 | 231 | } |
| 230 | 232 | |
| @@ -1534,6 +1534,8 @@ end: · 1533 unmodified lines | ||
| 1534 | 1534 | return ret; |
| 1535 | 1535 | } |
| 1536 | 1536 | |
| 1537 | +static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl); | |
| 1538 | + | |
| 1537 | 1539 | static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) |
| 1538 | 1540 | { |
| 1539 | 1541 | int ret = 0; |
| @@ -1557,7 +1559,7 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) · 17 unmodified lines | ||
| 1557 | 1559 | |
| 1558 | 1560 | ret = dp_ctrl_on_link(&ctrl->dp_ctrl); |
| 1559 | 1561 | if (!ret) |
| 1560 | − ret = dp_ctrl_on_stream(&ctrl->dp_ctrl); | |
| 1562 | + ret = dp_ctrl_on_stream_phy_test_report(&ctrl->dp_ctrl); | |
| 1561 | 1563 | else |
| 1562 | 1564 | DRM_ERROR("failed to enable DP link controller\n"); |
| 1563 | 1565 | |
| @@ -1813,7 +1815,27 @@ static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl) · 249 unmodified lines | ||
| 1813 | 1815 | return dp_ctrl_setup_main_link(ctrl, &training_step); |
| 1814 | 1816 | } |
| 1815 | 1817 | |
| 1816 | −int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) | |
| 1818 | +static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) | |
| 1819 | +{ | |
| 1820 | + int ret; | |
| 1821 | + struct dp_ctrl_private *ctrl; | |
| 1822 | + | |
| 1823 | + ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); | |
| 1824 | + | |
| 1825 | + ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; | |
| 1826 | + | |
| 1827 | + ret = dp_ctrl_enable_stream_clocks(ctrl); | |
| 1828 | + if (ret) { | |
| 1829 | + DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); | |
| 1830 | + return ret; | |
| 1831 | + } | |
| 1832 | + | |
| 1833 | + dp_ctrl_send_phy_test_pattern(ctrl); | |
| 1834 | + | |
| 1835 | + return 0; | |
| 1836 | +} | |
| 1837 | + | |
| 1838 | +int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train) | |
| 1817 | 1839 | { |
| 1818 | 1840 | int ret = 0; |
| 1819 | 1841 | bool mainlink_ready = false; |
| @@ -1849,12 +1871,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) · 29 unmodified lines | ||
| 1849 | 1871 | goto end; |
| 1850 | 1872 | } |
| 1851 | 1873 | |
| 1852 | − if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { | |
| 1853 | − dp_ctrl_send_phy_test_pattern(ctrl); | |
| 1854 | − return 0; | |
| 1855 | − } | |
| 1856 | − | |
| 1857 | − if (!dp_ctrl_channel_eq_ok(ctrl)) | |
| 1874 | + if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl)) | |
| 1858 | 1875 | dp_ctrl_link_retrain(ctrl); |
| 1859 | 1876 | |
| 1860 | 1877 | /* stop txing train pattern to end link training */ |
| @@ -21,7 +21,7 @@ struct dp_ctrl { · 20 unmodified lines | ||
| 21 | 21 | }; |
| 22 | 22 | |
| 23 | 23 | int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); |
| 24 | −int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl); | |
| 24 | +int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train); | |
| 25 | 25 | int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); |
| 26 | 26 | int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl); |
| 27 | 27 | int dp_ctrl_off(struct dp_ctrl *dp_ctrl); |
| @@ -309,7 +309,8 @@ static void dp_display_unbind(struct device *dev, struct device *master, · 308 unmodified lines | ||
| 309 | 309 | struct msm_drm_private *priv = dev_get_drvdata(master); |
| 310 | 310 | |
| 311 | 311 | /* disable all HPD interrupts */ |
| 312 | − dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); | |
| 312 | + if (dp->core_initialized) | |
| 313 | + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); | |
| 313 | 314 | |
| 314 | 315 | kthread_stop(dp->ev_tsk); |
| 315 | 316 | |
| @@ -872,7 +873,7 @@ static int dp_display_enable(struct dp_display_private *dp, u32 data) · 556 unmodified lines | ||
| 872 | 873 | return 0; |
| 873 | 874 | } |
| 874 | 875 | |
| 875 | − rc = dp_ctrl_on_stream(dp->ctrl); | |
| 876 | + rc = dp_ctrl_on_stream(dp->ctrl, data); | |
| 876 | 877 | if (!rc) |
| 877 | 878 | dp_display->power_on = true; |
| 878 | 879 | |
| @@ -1659,6 +1660,7 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) · 780 unmodified lines | ||
| 1659 | 1660 | int rc = 0; |
| 1660 | 1661 | struct dp_display_private *dp_display; |
| 1661 | 1662 | u32 state; |
| 1663 | + bool force_link_train = false; | |
| 1662 | 1664 | |
| 1663 | 1665 | dp_display = container_of(dp, struct dp_display_private, dp_display); |
| 1664 | 1666 | if (!dp_display->dp_mode.drm_mode.clock) { |
| @@ -1693,10 +1695,12 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) · 28 unmodified lines | ||
| 1693 | 1695 | |
| 1694 | 1696 | state = dp_display->hpd_state; |
| 1695 | 1697 | |
| 1696 | − if (state == ST_DISPLAY_OFF) | |
| 1698 | + if (state == ST_DISPLAY_OFF) { | |
| 1697 | 1699 | dp_display_host_phy_init(dp_display); |
| 1700 | + force_link_train = true; | |
| 1701 | + } | |
| 1698 | 1702 | |
| 1699 | − dp_display_enable(dp_display, 0); | |
| 1703 | + dp_display_enable(dp_display, force_link_train); | |
| 1700 | 1704 | |
| 1701 | 1705 | rc = dp_display_post_enable(dp); |
| 1702 | 1706 | if (rc) { |
| @@ -1705,10 +1709,6 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) · 2 unmodified lines | ||
| 1705 | 1709 | dp_display_unprepare(dp); |
| 1706 | 1710 | } |
| 1707 | 1711 | |
| 1708 | − /* manual kick off plug event to train link */ | |
| 1709 | − if (state == ST_DISPLAY_OFF) | |
| 1710 | − dp_add_event(dp_display, EV_IRQ_HPD_INT, 0, 0); | |
| 1711 | − | |
| 1712 | 1712 | /* completed connection */ |
| 1713 | 1713 | dp_display->hpd_state = ST_CONNECTED; |
| 1714 | 1714 | |
| @@ -964,7 +964,7 @@ static const struct drm_driver msm_driver = { · 963 unmodified lines | ||
| 964 | 964 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
| 965 | 965 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, |
| 966 | 966 | .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, |
| 967 | − .gem_prime_mmap = drm_gem_prime_mmap, | |
| 967 | + .gem_prime_mmap = msm_gem_prime_mmap, | |
| 968 | 968 | #ifdef CONFIG_DEBUG_FS |
| 969 | 969 | .debugfs_init = msm_debugfs_init, |
| 970 | 970 | #endif |
| @@ -246,6 +246,7 @@ unsigned long msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_t · 245 unmodified lines | ||
| 246 | 246 | void msm_gem_shrinker_init(struct drm_device *dev); |
| 247 | 247 | void msm_gem_shrinker_cleanup(struct drm_device *dev); |
| 248 | 248 | |
| 249 | +int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); | |
| 249 | 250 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj); |
| 250 | 251 | int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map); |
| 251 | 252 | void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map); |
| @@ -46,12 +46,14 @@ bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence) · 45 unmodified lines | ||
| 46 | 46 | (int32_t)(*fctx->fenceptr - fence) >= 0; |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | −/* called from workqueue */ | |
| 49 | +/* called from irq handler and workqueue (in recover path) */ | |
| 50 | 50 | void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence) |
| 51 | 51 | { |
| 52 | − spin_lock(&fctx->spinlock); | |
| 52 | + unsigned long flags; | |
| 53 | + | |
| 54 | + spin_lock_irqsave(&fctx->spinlock, flags); | |
| 53 | 55 | fctx->completed_fence = max(fence, fctx->completed_fence); |
| 54 | − spin_unlock(&fctx->spinlock); | |
| 56 | + spin_unlock_irqrestore(&fctx->spinlock, flags); | |
| 55 | 57 | } |
| 56 | 58 | |
| 57 | 59 | struct msm_fence { |
| @@ -439,14 +439,12 @@ int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma) · 438 unmodified lines | ||
| 439 | 439 | return ret; |
| 440 | 440 | } |
| 441 | 441 | |
| 442 | −void msm_gem_unpin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma) | |
| 442 | +void msm_gem_unpin_locked(struct drm_gem_object *obj) | |
| 443 | 443 | { |
| 444 | 444 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 445 | 445 | |
| 446 | 446 | GEM_WARN_ON(!msm_gem_is_locked(obj)); |
| 447 | 447 | |
| 448 | − msm_gem_unpin_vma(vma); | |
| 449 | − | |
| 450 | 448 | msm_obj->pin_count--; |
| 451 | 449 | GEM_WARN_ON(msm_obj->pin_count < 0); |
| 452 | 450 | |
| @@ -586,7 +584,8 @@ void msm_gem_unpin_iova(struct drm_gem_object *obj, · 133 unmodified lines | ||
| 586 | 584 | msm_gem_lock(obj); |
| 587 | 585 | vma = lookup_vma(obj, aspace); |
| 588 | 586 | if (!GEM_WARN_ON(!vma)) { |
| 589 | − msm_gem_unpin_vma_locked(obj, vma); | |
| 587 | + msm_gem_unpin_vma(vma); | |
| 588 | + msm_gem_unpin_locked(obj); | |
| 590 | 589 | } |
| 591 | 590 | msm_gem_unlock(obj); |
| 592 | 591 | } |
| @@ -145,7 +145,7 @@ struct msm_gem_object { · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); |
| 147 | 147 | int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma); |
| 148 | −void msm_gem_unpin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma); | |
| 148 | +void msm_gem_unpin_locked(struct drm_gem_object *obj); | |
| 149 | 149 | struct msm_gem_vma *msm_gem_get_vma_locked(struct drm_gem_object *obj, |
| 150 | 150 | struct msm_gem_address_space *aspace); |
| 151 | 151 | int msm_gem_get_iova(struct drm_gem_object *obj, |
| @@ -377,10 +377,11 @@ struct msm_gem_submit { · 225 unmodified lines | ||
| 377 | 377 | } *cmd; /* array of size nr_cmds */ |
| 378 | 378 | struct { |
| 379 | 379 | /* make sure these don't conflict w/ MSM_SUBMIT_BO_x */ |
| 380 | −#define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */ | |
| 381 | −#define BO_LOCKED 0x4000 /* obj lock is held */ | |
| 382 | −#define BO_ACTIVE 0x2000 /* active refcnt is held */ | |
| 383 | −#define BO_PINNED 0x1000 /* obj is pinned and on active list */ | |
| 380 | +#define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */ | |
| 381 | +#define BO_LOCKED 0x4000 /* obj lock is held */ | |
| 382 | +#define BO_ACTIVE 0x2000 /* active refcnt is held */ | |
| 383 | +#define BO_OBJ_PINNED 0x1000 /* obj (pages) is pinned and on active list */ | |
| 384 | +#define BO_VMA_PINNED 0x0800 /* vma (virtual address) is pinned */ | |
| 384 | 385 | uint32_t flags; |
| 385 | 386 | union { |
| 386 | 387 | struct msm_gem_object *obj; |
| @@ -11,6 +11,21 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "msm_drv.h" |
| 12 | 12 | #include "msm_gem.h" |
| 13 | 13 | |
| 14 | +int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) | |
| 15 | +{ | |
| 16 | + int ret; | |
| 17 | + | |
| 18 | + /* Ensure the mmap offset is initialized. We lazily initialize it, | |
| 19 | + * so if it has not been first mmap'd directly as a GEM object, the | |
| 20 | + * mmap offset will not be already initialized. | |
| 21 | + */ | |
| 22 | + ret = drm_gem_create_mmap_offset(obj); | |
| 23 | + if (ret) | |
| 24 | + return ret; | |
| 25 | + | |
| 26 | + return drm_gem_prime_mmap(obj, vma); | |
| 27 | +} | |
| 28 | + | |
| 14 | 29 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) |
| 15 | 30 | { |
| 16 | 31 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| @@ -232,8 +232,11 @@ static void submit_cleanup_bo(struct msm_gem_submit *submit, int i, · 231 unmodified lines | ||
| 232 | 232 | */ |
| 233 | 233 | submit->bos[i].flags &= ~cleanup_flags; |
| 234 | 234 | |
| 235 | − if (flags & BO_PINNED) | |
| 236 | − msm_gem_unpin_vma_locked(obj, submit->bos[i].vma); | |
| 235 | + if (flags & BO_VMA_PINNED) | |
| 236 | + msm_gem_unpin_vma(submit->bos[i].vma); | |
| 237 | + | |
| 238 | + if (flags & BO_OBJ_PINNED) | |
| 239 | + msm_gem_unpin_locked(obj); | |
| 237 | 240 | |
| 238 | 241 | if (flags & BO_ACTIVE) |
| 239 | 242 | msm_gem_active_put(obj); |
| @@ -244,7 +247,9 @@ static void submit_cleanup_bo(struct msm_gem_submit *submit, int i, · 4 unmodified lines | ||
| 244 | 247 | |
| 245 | 248 | static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) |
| 246 | 249 | { |
| 247 | − submit_cleanup_bo(submit, i, BO_PINNED | BO_ACTIVE | BO_LOCKED); | |
| 250 | + unsigned cleanup_flags = BO_VMA_PINNED | BO_OBJ_PINNED | | |
| 251 | + BO_ACTIVE | BO_LOCKED; | |
| 252 | + submit_cleanup_bo(submit, i, cleanup_flags); | |
| 248 | 253 | |
| 249 | 254 | if (!(submit->bos[i].flags & BO_VALID)) |
| 250 | 255 | submit->bos[i].iova = 0; |
| @@ -375,7 +380,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 124 unmodified lines | ||
| 375 | 380 | if (ret) |
| 376 | 381 | break; |
| 377 | 382 | |
| 378 | − submit->bos[i].flags |= BO_PINNED; | |
| 383 | + submit->bos[i].flags |= BO_OBJ_PINNED | BO_VMA_PINNED; | |
| 379 | 384 | submit->bos[i].vma = vma; |
| 380 | 385 | |
| 381 | 386 | if (vma->iova == submit->bos[i].iova) { |
| @@ -511,7 +516,7 @@ static void submit_cleanup(struct msm_gem_submit *submit, bool error) · 129 unmodified lines | ||
| 511 | 516 | unsigned i; |
| 512 | 517 | |
| 513 | 518 | if (error) |
| 514 | − cleanup_flags |= BO_PINNED | BO_ACTIVE; | |
| 519 | + cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED | BO_ACTIVE; | |
| 515 | 520 | |
| 516 | 521 | for (i = 0; i < submit->nr_bos; i++) { |
| 517 | 522 | struct msm_gem_object *msm_obj = submit->bos[i].obj; |
| @@ -529,7 +534,8 @@ void msm_submit_retire(struct msm_gem_submit *submit) · 11 unmodified lines | ||
| 529 | 534 | struct drm_gem_object *obj = &submit->bos[i].obj->base; |
| 530 | 535 | |
| 531 | 536 | msm_gem_lock(obj); |
| 532 | − submit_cleanup_bo(submit, i, BO_PINNED | BO_ACTIVE); | |
| 537 | + /* Note, VMA already fence-unpinned before submit: */ | |
| 538 | + submit_cleanup_bo(submit, i, BO_OBJ_PINNED | BO_ACTIVE); | |
| 533 | 539 | msm_gem_unlock(obj); |
| 534 | 540 | drm_gem_object_put(obj); |
| 535 | 541 | } |
| @@ -62,8 +62,7 @@ void msm_gem_purge_vma(struct msm_gem_address_space *aspace, · 61 unmodified lines | ||
| 62 | 62 | unsigned size = vma->node.size; |
| 63 | 63 | |
| 64 | 64 | /* Print a message if we try to purge a vma in use */ |
| 65 | − if (GEM_WARN_ON(msm_gem_vma_inuse(vma))) | |
| 66 | − return; | |
| 65 | + GEM_WARN_ON(msm_gem_vma_inuse(vma)); | |
| 67 | 66 | |
| 68 | 67 | /* Don't do anything if the memory isn't mapped */ |
| 69 | 68 | if (!vma->mapped) |
| @@ -128,8 +127,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, · 58 unmodified lines | ||
| 128 | 127 | void msm_gem_close_vma(struct msm_gem_address_space *aspace, |
| 129 | 128 | struct msm_gem_vma *vma) |
| 130 | 129 | { |
| 131 | − if (GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped)) | |
| 132 | − return; | |
| 130 | + GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped); | |
| 133 | 131 | |
| 134 | 132 | spin_lock(&aspace->lock); |
| 135 | 133 | if (vma->iova) |
| @@ -164,24 +164,6 @@ int msm_gpu_hw_init(struct msm_gpu *gpu) · 163 unmodified lines | ||
| 164 | 164 | return ret; |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | −static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, | |
| 168 | − uint32_t fence) | |
| 169 | −{ | |
| 170 | − struct msm_gem_submit *submit; | |
| 171 | − unsigned long flags; | |
| 172 | − | |
| 173 | − spin_lock_irqsave(&ring->submit_lock, flags); | |
| 174 | − list_for_each_entry(submit, &ring->submits, node) { | |
| 175 | − if (fence_after(submit->seqno, fence)) | |
| 176 | − break; | |
| 177 | − | |
| 178 | − msm_update_fence(submit->ring->fctx, | |
| 179 | − submit->hw_fence->seqno); | |
| 180 | − dma_fence_signal(submit->hw_fence); | |
| 181 | − } | |
| 182 | − spin_unlock_irqrestore(&ring->submit_lock, flags); | |
| 183 | −} | |
| 184 | − | |
| 185 | 167 | #ifdef CONFIG_DEV_COREDUMP |
| 186 | 168 | static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset, |
| 187 | 169 | size_t count, void *data, size_t datalen) |
| @@ -436,9 +418,9 @@ static void recover_worker(struct kthread_work *work) · 248 unmodified lines | ||
| 436 | 418 | * one more to clear the faulting submit |
| 437 | 419 | */ |
| 438 | 420 | if (ring == cur_ring) |
| 439 | − fence++; | |
| 421 | + ring->memptrs->fence = ++fence; | |
| 440 | 422 | |
| 441 | − update_fences(gpu, ring, fence); | |
| 423 | + msm_update_fence(ring->fctx, fence); | |
| 442 | 424 | } |
| 443 | 425 | |
| 444 | 426 | if (msm_gpu_active(gpu)) { |
| @@ -672,7 +654,6 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, · 227 unmodified lines | ||
| 672 | 654 | msm_submit_retire(submit); |
| 673 | 655 | |
| 674 | 656 | pm_runtime_mark_last_busy(&gpu->pdev->dev); |
| 675 | − pm_runtime_put_autosuspend(&gpu->pdev->dev); | |
| 676 | 657 | |
| 677 | 658 | spin_lock_irqsave(&ring->submit_lock, flags); |
| 678 | 659 | list_del(&submit->node); |
| @@ -686,6 +667,8 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, · 7 unmodified lines | ||
| 686 | 667 | msm_devfreq_idle(gpu); |
| 687 | 668 | mutex_unlock(&gpu->active_lock); |
| 688 | 669 | |
| 670 | + pm_runtime_put_autosuspend(&gpu->pdev->dev); | |
| 671 | + | |
| 689 | 672 | msm_gem_submit_put(submit); |
| 690 | 673 | } |
| 691 | 674 | |
| @@ -735,7 +718,7 @@ void msm_gpu_retire(struct msm_gpu *gpu) · 43 unmodified lines | ||
| 735 | 718 | int i; |
| 736 | 719 | |
| 737 | 720 | for (i = 0; i < gpu->nr_rings; i++) |
| 738 | − update_fences(gpu, gpu->rb[i], gpu->rb[i]->memptrs->fence); | |
| 721 | + msm_update_fence(gpu->rb[i]->fctx, gpu->rb[i]->memptrs->fence); | |
| 739 | 722 | |
| 740 | 723 | kthread_queue_work(gpu->worker, &gpu->retire_work); |
| 741 | 724 | update_sw_cntrs(gpu); |
| @@ -58,7 +58,7 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova, · 57 unmodified lines | ||
| 58 | 58 | u64 addr = iova; |
| 59 | 59 | unsigned int i; |
| 60 | 60 | |
| 61 | − for_each_sg(sgt->sgl, sg, sgt->nents, i) { | |
| 61 | + for_each_sgtable_sg(sgt, sg, i) { | |
| 62 | 62 | size_t size = sg->length; |
| 63 | 63 | phys_addr_t phys = sg_phys(sg); |
| 64 | 64 | |
| @@ -25,7 +25,7 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job) · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | msm_gem_lock(obj); |
| 27 | 27 | msm_gem_unpin_vma_fenced(submit->bos[i].vma, fctx); |
| 28 | − submit->bos[i].flags &= ~BO_PINNED; | |
| 28 | + submit->bos[i].flags &= ~BO_VMA_PINNED; | |
| 29 | 29 | msm_gem_unlock(obj); |
| 30 | 30 | } |
| 31 | 31 | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/component.h> |
| 10 | +#include <linux/dma-mapping.h> | |
| 10 | 11 | #include <linux/kfifo.h> |
| 11 | 12 | #include <linux/module.h> |
| 12 | 13 | #include <linux/of_graph.h> |
| @@ -73,7 +74,6 @@ static int sun4i_drv_bind(struct device *dev) · 60 unmodified lines | ||
| 73 | 74 | goto free_drm; |
| 74 | 75 | } |
| 75 | 76 | |
| 76 | − dev_set_drvdata(dev, drm); | |
| 77 | 77 | drm->dev_private = drv; |
| 78 | 78 | INIT_LIST_HEAD(&drv->frontend_list); |
| 79 | 79 | INIT_LIST_HEAD(&drv->engine_list); |
| @@ -114,6 +114,8 @@ static int sun4i_drv_bind(struct device *dev) · 34 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | drm_fbdev_generic_setup(drm, 32); |
| 116 | 116 | |
| 117 | + dev_set_drvdata(dev, drm); | |
| 118 | + | |
| 117 | 119 | return 0; |
| 118 | 120 | |
| 119 | 121 | finish_poll: |
| @@ -130,6 +132,7 @@ static void sun4i_drv_unbind(struct device *dev) · 10 unmodified lines | ||
| 130 | 132 | { |
| 131 | 133 | struct drm_device *drm = dev_get_drvdata(dev); |
| 132 | 134 | |
| 135 | + dev_set_drvdata(dev, NULL); | |
| 133 | 136 | drm_dev_unregister(drm); |
| 134 | 137 | drm_kms_helper_poll_fini(drm); |
| 135 | 138 | drm_atomic_helper_shutdown(drm); |
| @@ -367,6 +370,13 @@ static int sun4i_drv_probe(struct platform_device *pdev) · 231 unmodified lines | ||
| 367 | 370 | |
| 368 | 371 | INIT_KFIFO(list.fifo); |
| 369 | 372 | |
| 373 | + /* | |
| 374 | + * DE2 and DE3 cores actually supports 40-bit addresses, but | |
| 375 | + * driver does not. | |
| 376 | + */ | |
| 377 | + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
| 378 | + dma_set_max_seg_size(&pdev->dev, UINT_MAX); | |
| 379 | + | |
| 370 | 380 | for (i = 0;; i++) { |
| 371 | 381 | struct device_node *pipeline = of_parse_phandle(np, |
| 372 | 382 | "allwinner,pipelines", |
| @@ -117,7 +117,7 @@ static bool sun4i_layer_format_mod_supported(struct drm_plane *plane, · 116 unmodified lines | ||
| 117 | 117 | struct sun4i_layer *layer = plane_to_sun4i_layer(plane); |
| 118 | 118 | |
| 119 | 119 | if (IS_ERR_OR_NULL(layer->backend->frontend)) |
| 120 | − sun4i_backend_format_is_supported(format, modifier); | |
| 120 | + return sun4i_backend_format_is_supported(format, modifier); | |
| 121 | 121 | |
| 122 | 122 | return sun4i_backend_format_is_supported(format, modifier) || |
| 123 | 123 | sun4i_frontend_format_is_supported(format, modifier); |
| @@ -93,34 +93,10 @@ crtcs_exit: · 92 unmodified lines | ||
| 93 | 93 | return crtcs; |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | −static int sun8i_dw_hdmi_find_connector_pdev(struct device *dev, | |
| 97 | − struct platform_device **pdev_out) | |
| 98 | −{ | |
| 99 | − struct platform_device *pdev; | |
| 100 | − struct device_node *remote; | |
| 101 | − | |
| 102 | − remote = of_graph_get_remote_node(dev->of_node, 1, -1); | |
| 103 | − if (!remote) | |
| 104 | − return -ENODEV; | |
| 105 | − | |
| 106 | − if (!of_device_is_compatible(remote, "hdmi-connector")) { | |
| 107 | − of_node_put(remote); | |
| 108 | − return -ENODEV; | |
| 109 | − } | |
| 110 | − | |
| 111 | − pdev = of_find_device_by_node(remote); | |
| 112 | − of_node_put(remote); | |
| 113 | − if (!pdev) | |
| 114 | − return -ENODEV; | |
| 115 | − | |
| 116 | − *pdev_out = pdev; | |
| 117 | − return 0; | |
| 118 | −} | |
| 119 | − | |
| 120 | 96 | static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, |
| 121 | 97 | void *data) |
| 122 | 98 | { |
| 123 | − struct platform_device *pdev = to_platform_device(dev), *connector_pdev; | |
| 99 | + struct platform_device *pdev = to_platform_device(dev); | |
| 124 | 100 | struct dw_hdmi_plat_data *plat_data; |
| 125 | 101 | struct drm_device *drm = data; |
| 126 | 102 | struct device_node *phy_node; |
| @@ -167,30 +143,16 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, · 40 unmodified lines | ||
| 167 | 143 | return dev_err_probe(dev, PTR_ERR(hdmi->regulator), |
| 168 | 144 | "Couldn't get regulator\n"); |
| 169 | 145 | |
| 170 | − ret = sun8i_dw_hdmi_find_connector_pdev(dev, &connector_pdev); | |
| 171 | − if (!ret) { | |
| 172 | − hdmi->ddc_en = gpiod_get_optional(&connector_pdev->dev, | |
| 173 | − "ddc-en", GPIOD_OUT_HIGH); | |
| 174 | − platform_device_put(connector_pdev); | |
| 175 | − | |
| 176 | − if (IS_ERR(hdmi->ddc_en)) { | |
| 177 | − dev_err(dev, "Couldn't get ddc-en gpio\n"); | |
| 178 | − return PTR_ERR(hdmi->ddc_en); | |
| 179 | − } | |
| 180 | − } | |
| 181 | − | |
| 182 | 146 | ret = regulator_enable(hdmi->regulator); |
| 183 | 147 | if (ret) { |
| 184 | 148 | dev_err(dev, "Failed to enable regulator\n"); |
| 185 | − goto err_unref_ddc_en; | |
| 149 | + return ret; | |
| 186 | 150 | } |
| 187 | 151 | |
| 188 | − gpiod_set_value(hdmi->ddc_en, 1); | |
| 189 | − | |
| 190 | 152 | ret = reset_control_deassert(hdmi->rst_ctrl); |
| 191 | 153 | if (ret) { |
| 192 | 154 | dev_err(dev, "Could not deassert ctrl reset control\n"); |
| 193 | − goto err_disable_ddc_en; | |
| 155 | + goto err_disable_regulator; | |
| 194 | 156 | } |
| 195 | 157 | |
| 196 | 158 | ret = clk_prepare_enable(hdmi->clk_tmds); |
| @@ -245,12 +207,8 @@ err_disable_clk_tmds: · 48 unmodified lines | ||
| 245 | 207 | clk_disable_unprepare(hdmi->clk_tmds); |
| 246 | 208 | err_assert_ctrl_reset: |
| 247 | 209 | reset_control_assert(hdmi->rst_ctrl); |
| 248 | −err_disable_ddc_en: | |
| 249 | − gpiod_set_value(hdmi->ddc_en, 0); | |
| 210 | +err_disable_regulator: | |
| 250 | 211 | regulator_disable(hdmi->regulator); |
| 251 | −err_unref_ddc_en: | |
| 252 | − if (hdmi->ddc_en) | |
| 253 | − gpiod_put(hdmi->ddc_en); | |
| 254 | 212 | |
| 255 | 213 | return ret; |
| 256 | 214 | } |
| @@ -264,11 +222,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, · 7 unmodified lines | ||
| 264 | 222 | sun8i_hdmi_phy_deinit(hdmi->phy); |
| 265 | 223 | clk_disable_unprepare(hdmi->clk_tmds); |
| 266 | 224 | reset_control_assert(hdmi->rst_ctrl); |
| 267 | − gpiod_set_value(hdmi->ddc_en, 0); | |
| 268 | 225 | regulator_disable(hdmi->regulator); |
| 269 | − | |
| 270 | − if (hdmi->ddc_en) | |
| 271 | − gpiod_put(hdmi->ddc_en); | |
| 272 | 226 | } |
| 273 | 227 | |
| 274 | 228 | static const struct component_ops sun8i_dw_hdmi_ops = { |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <drm/bridge/dw_hdmi.h> |
| 10 | 10 | #include <drm/drm_encoder.h> |
| 11 | 11 | #include <linux/clk.h> |
| 12 | −#include <linux/gpio/consumer.h> | |
| 13 | 12 | #include <linux/regmap.h> |
| 14 | 13 | #include <linux/regulator/consumer.h> |
| 15 | 14 | #include <linux/reset.h> |
| @@ -193,7 +192,6 @@ struct sun8i_dw_hdmi { · 177 unmodified lines | ||
| 193 | 192 | struct regulator *regulator; |
| 194 | 193 | const struct sun8i_dw_hdmi_quirks *quirks; |
| 195 | 194 | struct reset_control *rst_ctrl; |
| 196 | − struct gpio_desc *ddc_en; | |
| 197 | 195 | }; |
| 198 | 196 | |
| 199 | 197 | extern struct platform_driver sun8i_hdmi_phy_driver; |
| @@ -109,11 +109,11 @@ void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo, · 108 unmodified lines | ||
| 109 | 109 | return; |
| 110 | 110 | |
| 111 | 111 | spin_lock(&bo->bdev->lru_lock); |
| 112 | − if (bo->bulk_move && bo->resource) | |
| 113 | − ttm_lru_bulk_move_del(bo->bulk_move, bo->resource); | |
| 112 | + if (bo->resource) | |
| 113 | + ttm_resource_del_bulk_move(bo->resource, bo); | |
| 114 | 114 | bo->bulk_move = bulk; |
| 115 | − if (bo->bulk_move && bo->resource) | |
| 116 | − ttm_lru_bulk_move_add(bo->bulk_move, bo->resource); | |
| 115 | + if (bo->resource) | |
| 116 | + ttm_resource_add_bulk_move(bo->resource, bo); | |
| 117 | 117 | spin_unlock(&bo->bdev->lru_lock); |
| 118 | 118 | } |
| 119 | 119 | EXPORT_SYMBOL(ttm_bo_set_bulk_move); |
| @@ -689,8 +689,11 @@ void ttm_bo_pin(struct ttm_buffer_object *bo) · 569 unmodified lines | ||
| 689 | 689 | { |
| 690 | 690 | dma_resv_assert_held(bo->base.resv); |
| 691 | 691 | WARN_ON_ONCE(!kref_read(&bo->kref)); |
| 692 | − if (!(bo->pin_count++) && bo->bulk_move && bo->resource) | |
| 693 | − ttm_lru_bulk_move_del(bo->bulk_move, bo->resource); | |
| 692 | + spin_lock(&bo->bdev->lru_lock); | |
| 693 | + if (bo->resource) | |
| 694 | + ttm_resource_del_bulk_move(bo->resource, bo); | |
| 695 | + ++bo->pin_count; | |
| 696 | + spin_unlock(&bo->bdev->lru_lock); | |
| 694 | 697 | } |
| 695 | 698 | EXPORT_SYMBOL(ttm_bo_pin); |
| 696 | 699 | |
| @@ -707,8 +710,11 @@ void ttm_bo_unpin(struct ttm_buffer_object *bo) · 10 unmodified lines | ||
| 707 | 710 | if (WARN_ON_ONCE(!bo->pin_count)) |
| 708 | 711 | return; |
| 709 | 712 | |
| 710 | − if (!(--bo->pin_count) && bo->bulk_move && bo->resource) | |
| 711 | − ttm_lru_bulk_move_add(bo->bulk_move, bo->resource); | |
| 713 | + spin_lock(&bo->bdev->lru_lock); | |
| 714 | + --bo->pin_count; | |
| 715 | + if (bo->resource) | |
| 716 | + ttm_resource_add_bulk_move(bo->resource, bo); | |
| 717 | + spin_unlock(&bo->bdev->lru_lock); | |
| 712 | 718 | } |
| 713 | 719 | EXPORT_SYMBOL(ttm_bo_unpin); |
| 714 | 720 | |
| @@ -156,8 +156,12 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx, · 155 unmodified lines | ||
| 156 | 156 | |
| 157 | 157 | ttm_resource_manager_for_each_res(man, &cursor, res) { |
| 158 | 158 | struct ttm_buffer_object *bo = res->bo; |
| 159 | − uint32_t num_pages = PFN_UP(bo->base.size); | |
| 159 | + uint32_t num_pages; | |
| 160 | 160 | |
| 161 | + if (!bo) | |
| 162 | + continue; | |
| 163 | + | |
| 164 | + num_pages = PFN_UP(bo->base.size); | |
| 161 | 165 | ret = ttm_bo_swapout(bo, ctx, gfp_flags); |
| 162 | 166 | /* ttm_bo_swapout has dropped the lru_lock */ |
| 163 | 167 | if (!ret) |
| @@ -91,8 +91,8 @@ static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos, · 90 unmodified lines | ||
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | /* Add the resource to a bulk_move cursor */ |
| 94 | −void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk, | |
| 95 | − struct ttm_resource *res) | |
| 94 | +static void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk, | |
| 95 | + struct ttm_resource *res) | |
| 96 | 96 | { |
| 97 | 97 | struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); |
| 98 | 98 | |
| @@ -105,8 +105,8 @@ void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk, · 6 unmodified lines | ||
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | /* Remove the resource from a bulk_move range */ |
| 108 | −void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, | |
| 109 | − struct ttm_resource *res) | |
| 108 | +static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, | |
| 109 | + struct ttm_resource *res) | |
| 110 | 110 | { |
| 111 | 111 | struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); |
| 112 | 112 | |
| @@ -122,6 +122,22 @@ void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, · 9 unmodified lines | ||
| 122 | 122 | } |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | +/* Add the resource to a bulk move if the BO is configured for it */ | |
| 126 | +void ttm_resource_add_bulk_move(struct ttm_resource *res, | |
| 127 | + struct ttm_buffer_object *bo) | |
| 128 | +{ | |
| 129 | + if (bo->bulk_move && !bo->pin_count) | |
| 130 | + ttm_lru_bulk_move_add(bo->bulk_move, res); | |
| 131 | +} | |
| 132 | + | |
| 133 | +/* Remove the resource from a bulk move if the BO is configured for it */ | |
| 134 | +void ttm_resource_del_bulk_move(struct ttm_resource *res, | |
| 135 | + struct ttm_buffer_object *bo) | |
| 136 | +{ | |
| 137 | + if (bo->bulk_move && !bo->pin_count) | |
| 138 | + ttm_lru_bulk_move_del(bo->bulk_move, res); | |
| 139 | +} | |
| 140 | + | |
| 125 | 141 | /* Move a resource to the LRU or bulk tail */ |
| 126 | 142 | void ttm_resource_move_to_lru_tail(struct ttm_resource *res) |
| 127 | 143 | { |
| @@ -169,15 +185,14 @@ void ttm_resource_init(struct ttm_buffer_object *bo, · 41 unmodified lines | ||
| 169 | 185 | res->bus.is_iomem = false; |
| 170 | 186 | res->bus.caching = ttm_cached; |
| 171 | 187 | res->bo = bo; |
| 172 | − INIT_LIST_HEAD(&res->lru); | |
| 173 | 188 | |
| 174 | 189 | man = ttm_manager_type(bo->bdev, place->mem_type); |
| 175 | 190 | spin_lock(&bo->bdev->lru_lock); |
| 176 | − man->usage += res->num_pages << PAGE_SHIFT; | |
| 177 | − if (bo->bulk_move) | |
| 178 | − ttm_lru_bulk_move_add(bo->bulk_move, res); | |
| 191 | + if (bo->pin_count) | |
| 192 | + list_add_tail(&res->lru, &bo->bdev->pinned); | |
| 179 | 193 | else |
| 180 | − ttm_resource_move_to_lru_tail(res); | |
| 194 | + list_add_tail(&res->lru, &man->lru[bo->priority]); | |
| 195 | + man->usage += res->num_pages << PAGE_SHIFT; | |
| 181 | 196 | spin_unlock(&bo->bdev->lru_lock); |
| 182 | 197 | } |
| 183 | 198 | EXPORT_SYMBOL(ttm_resource_init); |
| @@ -210,8 +225,16 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo, · 26 unmodified lines | ||
| 210 | 225 | { |
| 211 | 226 | struct ttm_resource_manager *man = |
| 212 | 227 | ttm_manager_type(bo->bdev, place->mem_type); |
| 228 | + int ret; | |
| 229 | + | |
| 230 | + ret = man->func->alloc(man, bo, place, res_ptr); | |
| 231 | + if (ret) | |
| 232 | + return ret; | |
| 213 | 233 | |
| 214 | − return man->func->alloc(man, bo, place, res_ptr); | |
| 234 | + spin_lock(&bo->bdev->lru_lock); | |
| 235 | + ttm_resource_add_bulk_move(*res_ptr, bo); | |
| 236 | + spin_unlock(&bo->bdev->lru_lock); | |
| 237 | + return 0; | |
| 215 | 238 | } |
| 216 | 239 | |
| 217 | 240 | void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res) |
| @@ -221,12 +244,9 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res) · 3 unmodified lines | ||
| 221 | 244 | if (!*res) |
| 222 | 245 | return; |
| 223 | 246 | |
| 224 | − if (bo->bulk_move) { | |
| 225 | − spin_lock(&bo->bdev->lru_lock); | |
| 226 | − ttm_lru_bulk_move_del(bo->bulk_move, *res); | |
| 227 | − spin_unlock(&bo->bdev->lru_lock); | |
| 228 | − } | |
| 229 | − | |
| 247 | + spin_lock(&bo->bdev->lru_lock); | |
| 248 | + ttm_resource_del_bulk_move(*res, bo); | |
| 249 | + spin_unlock(&bo->bdev->lru_lock); | |
| 230 | 250 | man = ttm_manager_type(bo->bdev, (*res)->mem_type); |
| 231 | 251 | man->func->free(man, *res); |
| 232 | 252 | *res = NULL; |
| @@ -248,6 +248,9 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo) · 247 unmodified lines | ||
| 248 | 248 | { |
| 249 | 249 | struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); |
| 250 | 250 | |
| 251 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 252 | + return; | |
| 253 | + | |
| 251 | 254 | mutex_lock(&vc4->purgeable.lock); |
| 252 | 255 | list_add_tail(&bo->size_head, &vc4->purgeable.list); |
| 253 | 256 | vc4->purgeable.num++; |
| @@ -259,6 +262,9 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct vc4_bo *bo) · 5 unmodified lines | ||
| 259 | 262 | { |
| 260 | 263 | struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); |
| 261 | 264 | |
| 265 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 266 | + return; | |
| 267 | + | |
| 262 | 268 | /* list_del_init() is used here because the caller might release |
| 263 | 269 | * the purgeable lock in order to acquire the madv one and update the |
| 264 | 270 | * madv status. |
| @@ -387,6 +393,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) · 122 unmodified lines | ||
| 387 | 393 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 388 | 394 | struct vc4_bo *bo; |
| 389 | 395 | |
| 396 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 397 | + return ERR_PTR(-ENODEV); | |
| 398 | + | |
| 390 | 399 | bo = kzalloc(sizeof(*bo), GFP_KERNEL); |
| 391 | 400 | if (!bo) |
| 392 | 401 | return ERR_PTR(-ENOMEM); |
| @@ -413,6 +422,9 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, · 20 unmodified lines | ||
| 413 | 422 | struct drm_gem_cma_object *cma_obj; |
| 414 | 423 | struct vc4_bo *bo; |
| 415 | 424 | |
| 425 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 426 | + return ERR_PTR(-ENODEV); | |
| 427 | + | |
| 416 | 428 | if (size == 0) |
| 417 | 429 | return ERR_PTR(-EINVAL); |
| 418 | 430 | |
| @@ -471,19 +483,20 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, · 52 unmodified lines | ||
| 471 | 483 | return bo; |
| 472 | 484 | } |
| 473 | 485 | |
| 474 | −int vc4_dumb_create(struct drm_file *file_priv, | |
| 475 | − struct drm_device *dev, | |
| 476 | − struct drm_mode_create_dumb *args) | |
| 486 | +int vc4_bo_dumb_create(struct drm_file *file_priv, | |
| 487 | + struct drm_device *dev, | |
| 488 | + struct drm_mode_create_dumb *args) | |
| 477 | 489 | { |
| 478 | − int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); | |
| 490 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 479 | 491 | struct vc4_bo *bo = NULL; |
| 480 | 492 | int ret; |
| 481 | 493 | |
| 482 | − if (args->pitch < min_pitch) | |
| 483 | − args->pitch = min_pitch; | |
| 494 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 495 | + return -ENODEV; | |
| 484 | 496 | |
| 485 | − if (args->size < args->pitch * args->height) | |
| 486 | − args->size = args->pitch * args->height; | |
| 497 | + ret = vc4_dumb_fixup_args(args); | |
| 498 | + if (ret) | |
| 499 | + return ret; | |
| 487 | 500 | |
| 488 | 501 | bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB); |
| 489 | 502 | if (IS_ERR(bo)) |
| @@ -601,8 +614,12 @@ static void vc4_bo_cache_time_work(struct work_struct *work) · 111 unmodified lines | ||
| 601 | 614 | |
| 602 | 615 | int vc4_bo_inc_usecnt(struct vc4_bo *bo) |
| 603 | 616 | { |
| 617 | + struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); | |
| 604 | 618 | int ret; |
| 605 | 619 | |
| 620 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 621 | + return -ENODEV; | |
| 622 | + | |
| 606 | 623 | /* Fast path: if the BO is already retained by someone, no need to |
| 607 | 624 | * check the madv status. |
| 608 | 625 | */ |
| @@ -637,6 +654,11 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo) · 28 unmodified lines | ||
| 637 | 654 | |
| 638 | 655 | void vc4_bo_dec_usecnt(struct vc4_bo *bo) |
| 639 | 656 | { |
| 657 | + struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); | |
| 658 | + | |
| 659 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 660 | + return; | |
| 661 | + | |
| 640 | 662 | /* Fast path: if the BO is still retained by someone, no need to test |
| 641 | 663 | * the madv value. |
| 642 | 664 | */ |
| @@ -756,6 +778,9 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, · 113 unmodified lines | ||
| 756 | 778 | struct vc4_bo *bo = NULL; |
| 757 | 779 | int ret; |
| 758 | 780 | |
| 781 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 782 | + return -ENODEV; | |
| 783 | + | |
| 759 | 784 | ret = vc4_grab_bin_bo(vc4, vc4file); |
| 760 | 785 | if (ret) |
| 761 | 786 | return ret; |
| @@ -779,9 +804,13 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, · 17 unmodified lines | ||
| 779 | 804 | int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, |
| 780 | 805 | struct drm_file *file_priv) |
| 781 | 806 | { |
| 807 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 782 | 808 | struct drm_vc4_mmap_bo *args = data; |
| 783 | 809 | struct drm_gem_object *gem_obj; |
| 784 | 810 | |
| 811 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 812 | + return -ENODEV; | |
| 813 | + | |
| 785 | 814 | gem_obj = drm_gem_object_lookup(file_priv, args->handle); |
| 786 | 815 | if (!gem_obj) { |
| 787 | 816 | DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); |
| @@ -805,6 +834,9 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, · 17 unmodified lines | ||
| 805 | 834 | struct vc4_bo *bo = NULL; |
| 806 | 835 | int ret; |
| 807 | 836 | |
| 837 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 838 | + return -ENODEV; | |
| 839 | + | |
| 808 | 840 | if (args->size == 0) |
| 809 | 841 | return -EINVAL; |
| 810 | 842 | |
| @@ -875,11 +907,15 @@ fail: · 64 unmodified lines | ||
| 875 | 907 | int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, |
| 876 | 908 | struct drm_file *file_priv) |
| 877 | 909 | { |
| 910 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 878 | 911 | struct drm_vc4_set_tiling *args = data; |
| 879 | 912 | struct drm_gem_object *gem_obj; |
| 880 | 913 | struct vc4_bo *bo; |
| 881 | 914 | bool t_format; |
| 882 | 915 | |
| 916 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 917 | + return -ENODEV; | |
| 918 | + | |
| 883 | 919 | if (args->flags != 0) |
| 884 | 920 | return -EINVAL; |
| 885 | 921 | |
| @@ -918,10 +954,14 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, · 32 unmodified lines | ||
| 918 | 954 | int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, |
| 919 | 955 | struct drm_file *file_priv) |
| 920 | 956 | { |
| 957 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 921 | 958 | struct drm_vc4_get_tiling *args = data; |
| 922 | 959 | struct drm_gem_object *gem_obj; |
| 923 | 960 | struct vc4_bo *bo; |
| 924 | 961 | |
| 962 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 963 | + return -ENODEV; | |
| 964 | + | |
| 925 | 965 | if (args->flags != 0 || args->modifier != 0) |
| 926 | 966 | return -EINVAL; |
| 927 | 967 | |
| @@ -948,6 +988,9 @@ int vc4_bo_cache_init(struct drm_device *dev) · 20 unmodified lines | ||
| 948 | 988 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 949 | 989 | int i; |
| 950 | 990 | |
| 991 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 992 | + return -ENODEV; | |
| 993 | + | |
| 951 | 994 | /* Create the initial set of BO labels that the kernel will |
| 952 | 995 | * use. This lets us avoid a bunch of string reallocation in |
| 953 | 996 | * the kernel's draw and BO allocation paths. |
| @@ -1007,6 +1050,9 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data, · 53 unmodified lines | ||
| 1007 | 1050 | struct drm_gem_object *gem_obj; |
| 1008 | 1051 | int ret = 0, label; |
| 1009 | 1052 | |
| 1053 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1054 | + return -ENODEV; | |
| 1055 | + | |
| 1010 | 1056 | if (!args->len) |
| 1011 | 1057 | return -EINVAL; |
| 1012 | 1058 | |
| @@ -256,7 +256,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format) · 255 unmodified lines | ||
| 256 | 256 | * Removing 1 from the FIFO full level however |
| 257 | 257 | * seems to completely remove that issue. |
| 258 | 258 | */ |
| 259 | − if (!vc4->hvs->hvs5) | |
| 259 | + if (!vc4->is_vc5) | |
| 260 | 260 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1; |
| 261 | 261 | |
| 262 | 262 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX; |
| @@ -389,7 +389,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode · 126 unmodified lines | ||
| 389 | 389 | if (is_dsi) |
| 390 | 390 | CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); |
| 391 | 391 | |
| 392 | − if (vc4->hvs->hvs5) | |
| 392 | + if (vc4->is_vc5) | |
| 393 | 393 | CRTC_WRITE(PV_MUX_CFG, |
| 394 | 394 | VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP, |
| 395 | 395 | PV_MUX_CFG_RGB_PIXEL_MUX_MODE)); |
| @@ -775,17 +775,18 @@ struct vc4_async_flip_state { · 379 unmodified lines | ||
| 775 | 775 | struct drm_framebuffer *old_fb; |
| 776 | 776 | struct drm_pending_vblank_event *event; |
| 777 | 777 | |
| 778 | − struct vc4_seqno_cb cb; | |
| 778 | + union { | |
| 779 | + struct dma_fence_cb fence; | |
| 780 | + struct vc4_seqno_cb seqno; | |
| 781 | + } cb; | |
| 779 | 782 | }; |
| 780 | 783 | |
| 781 | 784 | /* Called when the V3D execution for the BO being flipped to is done, so that |
| 782 | 785 | * we can actually update the plane's address to point to it. |
| 783 | 786 | */ |
| 784 | 787 | static void |
| 785 | −vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) | |
| 788 | +vc4_async_page_flip_complete(struct vc4_async_flip_state *flip_state) | |
| 786 | 789 | { |
| 787 | − struct vc4_async_flip_state *flip_state = | |
| 788 | − container_of(cb, struct vc4_async_flip_state, cb); | |
| 789 | 790 | struct drm_crtc *crtc = flip_state->crtc; |
| 790 | 791 | struct drm_device *dev = crtc->dev; |
| 791 | 792 | struct drm_plane *plane = crtc->primary; |
| @@ -802,59 +803,96 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) · 10 unmodified lines | ||
| 802 | 803 | drm_crtc_vblank_put(crtc); |
| 803 | 804 | drm_framebuffer_put(flip_state->fb); |
| 804 | 805 | |
| 805 | − /* Decrement the BO usecnt in order to keep the inc/dec calls balanced | |
| 806 | − * when the planes are updated through the async update path. | |
| 807 | − * FIXME: we should move to generic async-page-flip when it's | |
| 808 | − * available, so that we can get rid of this hand-made cleanup_fb() | |
| 809 | − * logic. | |
| 810 | − */ | |
| 811 | − if (flip_state->old_fb) { | |
| 812 | − struct drm_gem_cma_object *cma_bo; | |
| 813 | − struct vc4_bo *bo; | |
| 806 | + if (flip_state->old_fb) | |
| 807 | + drm_framebuffer_put(flip_state->old_fb); | |
| 808 | + | |
| 809 | + kfree(flip_state); | |
| 810 | +} | |
| 811 | + | |
| 812 | +static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb) | |
| 813 | +{ | |
| 814 | + struct vc4_async_flip_state *flip_state = | |
| 815 | + container_of(cb, struct vc4_async_flip_state, cb.seqno); | |
| 816 | + struct vc4_bo *bo = NULL; | |
| 814 | 817 | |
| 815 | − cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0); | |
| 818 | + if (flip_state->old_fb) { | |
| 819 | + struct drm_gem_cma_object *cma_bo = | |
| 820 | + drm_fb_cma_get_gem_obj(flip_state->old_fb, 0); | |
| 816 | 821 | bo = to_vc4_bo(&cma_bo->base); |
| 817 | − vc4_bo_dec_usecnt(bo); | |
| 818 | − drm_framebuffer_put(flip_state->old_fb); | |
| 819 | 822 | } |
| 820 | 823 | |
| 821 | − kfree(flip_state); | |
| 824 | + vc4_async_page_flip_complete(flip_state); | |
| 825 | + | |
| 826 | + /* | |
| 827 | + * Decrement the BO usecnt in order to keep the inc/dec | |
| 828 | + * calls balanced when the planes are updated through | |
| 829 | + * the async update path. | |
| 830 | + * | |
| 831 | + * FIXME: we should move to generic async-page-flip when | |
| 832 | + * it's available, so that we can get rid of this | |
| 833 | + * hand-made cleanup_fb() logic. | |
| 834 | + */ | |
| 835 | + if (bo) | |
| 836 | + vc4_bo_dec_usecnt(bo); | |
| 822 | 837 | } |
| 823 | 838 | |
| 824 | −/* Implements async (non-vblank-synced) page flips. | |
| 825 | − * | |
| 826 | − * The page flip ioctl needs to return immediately, so we grab the | |
| 827 | − * modeset semaphore on the pipe, and queue the address update for | |
| 828 | − * when V3D is done with the BO being flipped to. | |
| 829 | − */ | |
| 830 | −static int vc4_async_page_flip(struct drm_crtc *crtc, | |
| 831 | − struct drm_framebuffer *fb, | |
| 832 | − struct drm_pending_vblank_event *event, | |
| 833 | − uint32_t flags) | |
| 839 | +static void vc4_async_page_flip_fence_complete(struct dma_fence *fence, | |
| 840 | + struct dma_fence_cb *cb) | |
| 834 | 841 | { |
| 835 | − struct drm_device *dev = crtc->dev; | |
| 836 | − struct drm_plane *plane = crtc->primary; | |
| 837 | − int ret = 0; | |
| 838 | − struct vc4_async_flip_state *flip_state; | |
| 842 | + struct vc4_async_flip_state *flip_state = | |
| 843 | + container_of(cb, struct vc4_async_flip_state, cb.fence); | |
| 844 | + | |
| 845 | + vc4_async_page_flip_complete(flip_state); | |
| 846 | + dma_fence_put(fence); | |
| 847 | +} | |
| 848 | + | |
| 849 | +static int vc4_async_set_fence_cb(struct drm_device *dev, | |
| 850 | + struct vc4_async_flip_state *flip_state) | |
| 851 | +{ | |
| 852 | + struct drm_framebuffer *fb = flip_state->fb; | |
| 839 | 853 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); |
| 840 | − struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); | |
| 854 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 855 | + struct dma_fence *fence; | |
| 856 | + int ret; | |
| 841 | 857 | |
| 842 | − /* Increment the BO usecnt here, so that we never end up with an | |
| 843 | − * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the | |
| 844 | − * plane is later updated through the non-async path. | |
| 845 | − * FIXME: we should move to generic async-page-flip when it's | |
| 846 | − * available, so that we can get rid of this hand-made prepare_fb() | |
| 847 | − * logic. | |
| 848 | − */ | |
| 849 | − ret = vc4_bo_inc_usecnt(bo); | |
| 858 | + if (!vc4->is_vc5) { | |
| 859 | + struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); | |
| 860 | + | |
| 861 | + return vc4_queue_seqno_cb(dev, &flip_state->cb.seqno, bo->seqno, | |
| 862 | + vc4_async_page_flip_seqno_complete); | |
| 863 | + } | |
| 864 | + | |
| 865 | + ret = dma_resv_get_singleton(cma_bo->base.resv, DMA_RESV_USAGE_READ, &fence); | |
| 850 | 866 | if (ret) |
| 851 | 867 | return ret; |
| 852 | 868 | |
| 869 | + /* If there's no fence, complete the page flip immediately */ | |
| 870 | + if (!fence) { | |
| 871 | + vc4_async_page_flip_fence_complete(fence, &flip_state->cb.fence); | |
| 872 | + return 0; | |
| 873 | + } | |
| 874 | + | |
| 875 | + /* If the fence has already been completed, complete the page flip */ | |
| 876 | + if (dma_fence_add_callback(fence, &flip_state->cb.fence, | |
| 877 | + vc4_async_page_flip_fence_complete)) | |
| 878 | + vc4_async_page_flip_fence_complete(fence, &flip_state->cb.fence); | |
| 879 | + | |
| 880 | + return 0; | |
| 881 | +} | |
| 882 | + | |
| 883 | +static int | |
| 884 | +vc4_async_page_flip_common(struct drm_crtc *crtc, | |
| 885 | + struct drm_framebuffer *fb, | |
| 886 | + struct drm_pending_vblank_event *event, | |
| 887 | + uint32_t flags) | |
| 888 | +{ | |
| 889 | + struct drm_device *dev = crtc->dev; | |
| 890 | + struct drm_plane *plane = crtc->primary; | |
| 891 | + struct vc4_async_flip_state *flip_state; | |
| 892 | + | |
| 853 | 893 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); |
| 854 | − if (!flip_state) { | |
| 855 | − vc4_bo_dec_usecnt(bo); | |
| 894 | + if (!flip_state) | |
| 856 | 895 | return -ENOMEM; |
| 857 | − } | |
| 858 | 896 | |
| 859 | 897 | drm_framebuffer_get(fb); |
| 860 | 898 | flip_state->fb = fb; |
| @@ -881,23 +919,79 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, · 20 unmodified lines | ||
| 881 | 919 | */ |
| 882 | 920 | drm_atomic_set_fb_for_plane(plane->state, fb); |
| 883 | 921 | |
| 884 | − vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno, | |
| 885 | − vc4_async_page_flip_complete); | |
| 922 | + vc4_async_set_fence_cb(dev, flip_state); | |
| 886 | 923 | |
| 887 | 924 | /* Driver takes ownership of state on successful async commit. */ |
| 888 | 925 | return 0; |
| 889 | 926 | } |
| 890 | 927 | |
| 928 | +/* Implements async (non-vblank-synced) page flips. | |
| 929 | + * | |
| 930 | + * The page flip ioctl needs to return immediately, so we grab the | |
| 931 | + * modeset semaphore on the pipe, and queue the address update for | |
| 932 | + * when V3D is done with the BO being flipped to. | |
| 933 | + */ | |
| 934 | +static int vc4_async_page_flip(struct drm_crtc *crtc, | |
| 935 | + struct drm_framebuffer *fb, | |
| 936 | + struct drm_pending_vblank_event *event, | |
| 937 | + uint32_t flags) | |
| 938 | +{ | |
| 939 | + struct drm_device *dev = crtc->dev; | |
| 940 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 941 | + struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); | |
| 942 | + struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); | |
| 943 | + int ret; | |
| 944 | + | |
| 945 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 946 | + return -ENODEV; | |
| 947 | + | |
| 948 | + /* | |
| 949 | + * Increment the BO usecnt here, so that we never end up with an | |
| 950 | + * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the | |
| 951 | + * plane is later updated through the non-async path. | |
| 952 | + * | |
| 953 | + * FIXME: we should move to generic async-page-flip when | |
| 954 | + * it's available, so that we can get rid of this | |
| 955 | + * hand-made prepare_fb() logic. | |
| 956 | + */ | |
| 957 | + ret = vc4_bo_inc_usecnt(bo); | |
| 958 | + if (ret) | |
| 959 | + return ret; | |
| 960 | + | |
| 961 | + ret = vc4_async_page_flip_common(crtc, fb, event, flags); | |
| 962 | + if (ret) { | |
| 963 | + vc4_bo_dec_usecnt(bo); | |
| 964 | + return ret; | |
| 965 | + } | |
| 966 | + | |
| 967 | + return 0; | |
| 968 | +} | |
| 969 | + | |
| 970 | +static int vc5_async_page_flip(struct drm_crtc *crtc, | |
| 971 | + struct drm_framebuffer *fb, | |
| 972 | + struct drm_pending_vblank_event *event, | |
| 973 | + uint32_t flags) | |
| 974 | +{ | |
| 975 | + return vc4_async_page_flip_common(crtc, fb, event, flags); | |
| 976 | +} | |
| 977 | + | |
| 891 | 978 | int vc4_page_flip(struct drm_crtc *crtc, |
| 892 | 979 | struct drm_framebuffer *fb, |
| 893 | 980 | struct drm_pending_vblank_event *event, |
| 894 | 981 | uint32_t flags, |
| 895 | 982 | struct drm_modeset_acquire_ctx *ctx) |
| 896 | 983 | { |
| 897 | − if (flags & DRM_MODE_PAGE_FLIP_ASYNC) | |
| 898 | − return vc4_async_page_flip(crtc, fb, event, flags); | |
| 899 | − else | |
| 984 | + if (flags & DRM_MODE_PAGE_FLIP_ASYNC) { | |
| 985 | + struct drm_device *dev = crtc->dev; | |
| 986 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 987 | + | |
| 988 | + if (vc4->is_vc5) | |
| 989 | + return vc5_async_page_flip(crtc, fb, event, flags); | |
| 990 | + else | |
| 991 | + return vc4_async_page_flip(crtc, fb, event, flags); | |
| 992 | + } else { | |
| 900 | 993 | return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); |
| 994 | + } | |
| 901 | 995 | } |
| 902 | 996 | |
| 903 | 997 | struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) |
| @@ -1149,7 +1243,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc, · 245 unmodified lines | ||
| 1149 | 1243 | crtc_funcs, NULL); |
| 1150 | 1244 | drm_crtc_helper_add(crtc, crtc_helper_funcs); |
| 1151 | 1245 | |
| 1152 | − if (!vc4->hvs->hvs5) { | |
| 1246 | + if (!vc4->is_vc5) { | |
| 1153 | 1247 | drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); |
| 1154 | 1248 | |
| 1155 | 1249 | drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size); |
| @@ -63,6 +63,32 @@ void __iomem *vc4_ioremap_regs(struct platform_device *pdev, int index) · 62 unmodified lines | ||
| 63 | 63 | return map; |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | +int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args) | |
| 67 | +{ | |
| 68 | + int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); | |
| 69 | + | |
| 70 | + if (args->pitch < min_pitch) | |
| 71 | + args->pitch = min_pitch; | |
| 72 | + | |
| 73 | + if (args->size < args->pitch * args->height) | |
| 74 | + args->size = args->pitch * args->height; | |
| 75 | + | |
| 76 | + return 0; | |
| 77 | +} | |
| 78 | + | |
| 79 | +static int vc5_dumb_create(struct drm_file *file_priv, | |
| 80 | + struct drm_device *dev, | |
| 81 | + struct drm_mode_create_dumb *args) | |
| 82 | +{ | |
| 83 | + int ret; | |
| 84 | + | |
| 85 | + ret = vc4_dumb_fixup_args(args); | |
| 86 | + if (ret) | |
| 87 | + return ret; | |
| 88 | + | |
| 89 | + return drm_gem_cma_dumb_create_internal(file_priv, dev, args); | |
| 90 | +} | |
| 91 | + | |
| 66 | 92 | static int vc4_get_param_ioctl(struct drm_device *dev, void *data, |
| 67 | 93 | struct drm_file *file_priv) |
| 68 | 94 | { |
| @@ -73,6 +99,9 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, · 4 unmodified lines | ||
| 73 | 99 | if (args->pad != 0) |
| 74 | 100 | return -EINVAL; |
| 75 | 101 | |
| 102 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 103 | + return -ENODEV; | |
| 104 | + | |
| 76 | 105 | if (!vc4->v3d) |
| 77 | 106 | return -ENODEV; |
| 78 | 107 | |
| @@ -116,11 +145,16 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, · 37 unmodified lines | ||
| 116 | 145 | |
| 117 | 146 | static int vc4_open(struct drm_device *dev, struct drm_file *file) |
| 118 | 147 | { |
| 148 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 119 | 149 | struct vc4_file *vc4file; |
| 120 | 150 | |
| 151 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 152 | + return -ENODEV; | |
| 153 | + | |
| 121 | 154 | vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL); |
| 122 | 155 | if (!vc4file) |
| 123 | 156 | return -ENOMEM; |
| 157 | + vc4file->dev = vc4; | |
| 124 | 158 | |
| 125 | 159 | vc4_perfmon_open_file(vc4file); |
| 126 | 160 | file->driver_priv = vc4file; |
| @@ -132,6 +166,9 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) · 5 unmodified lines | ||
| 132 | 166 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 133 | 167 | struct vc4_file *vc4file = file->driver_priv; |
| 134 | 168 | |
| 169 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 170 | + return; | |
| 171 | + | |
| 135 | 172 | if (vc4file->bin_bo_used) |
| 136 | 173 | vc4_v3d_bin_bo_put(vc4); |
| 137 | 174 | |
| @@ -160,7 +197,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { · 22 unmodified lines | ||
| 160 | 197 | DRM_IOCTL_DEF_DRV(VC4_PERFMON_GET_VALUES, vc4_perfmon_get_values_ioctl, DRM_RENDER_ALLOW), |
| 161 | 198 | }; |
| 162 | 199 | |
| 163 | −static struct drm_driver vc4_drm_driver = { | |
| 200 | +static const struct drm_driver vc4_drm_driver = { | |
| 164 | 201 | .driver_features = (DRIVER_MODESET | |
| 165 | 202 | DRIVER_ATOMIC | |
| 166 | 203 | DRIVER_GEM | |
| @@ -175,7 +212,7 @@ static struct drm_driver vc4_drm_driver = { · 8 unmodified lines | ||
| 175 | 212 | |
| 176 | 213 | .gem_create_object = vc4_create_object, |
| 177 | 214 | |
| 178 | − DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_dumb_create), | |
| 215 | + DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create), | |
| 179 | 216 | |
| 180 | 217 | .ioctls = vc4_drm_ioctls, |
| 181 | 218 | .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), |
| @@ -189,6 +226,27 @@ static struct drm_driver vc4_drm_driver = { · 7 unmodified lines | ||
| 189 | 226 | .patchlevel = DRIVER_PATCHLEVEL, |
| 190 | 227 | }; |
| 191 | 228 | |
| 229 | +static const struct drm_driver vc5_drm_driver = { | |
| 230 | + .driver_features = (DRIVER_MODESET | | |
| 231 | + DRIVER_ATOMIC | | |
| 232 | + DRIVER_GEM), | |
| 233 | + | |
| 234 | +#if defined(CONFIG_DEBUG_FS) | |
| 235 | + .debugfs_init = vc4_debugfs_init, | |
| 236 | +#endif | |
| 237 | + | |
| 238 | + DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create), | |
| 239 | + | |
| 240 | + .fops = &vc4_drm_fops, | |
| 241 | + | |
| 242 | + .name = DRIVER_NAME, | |
| 243 | + .desc = DRIVER_DESC, | |
| 244 | + .date = DRIVER_DATE, | |
| 245 | + .major = DRIVER_MAJOR, | |
| 246 | + .minor = DRIVER_MINOR, | |
| 247 | + .patchlevel = DRIVER_PATCHLEVEL, | |
| 248 | +}; | |
| 249 | + | |
| 192 | 250 | static void vc4_match_add_drivers(struct device *dev, |
| 193 | 251 | struct component_match **match, |
| 194 | 252 | struct platform_driver *const *drivers, |
| @@ -212,42 +270,49 @@ static void vc4_match_add_drivers(struct device *dev, · 17 unmodified lines | ||
| 212 | 270 | static int vc4_drm_bind(struct device *dev) |
| 213 | 271 | { |
| 214 | 272 | struct platform_device *pdev = to_platform_device(dev); |
| 273 | + const struct drm_driver *driver; | |
| 215 | 274 | struct rpi_firmware *firmware = NULL; |
| 216 | 275 | struct drm_device *drm; |
| 217 | 276 | struct vc4_dev *vc4; |
| 218 | 277 | struct device_node *node; |
| 219 | 278 | struct drm_crtc *crtc; |
| 279 | + bool is_vc5; | |
| 220 | 280 | int ret = 0; |
| 221 | 281 | |
| 222 | 282 | dev->coherent_dma_mask = DMA_BIT_MASK(32); |
| 223 | 283 | |
| 224 | − /* If VC4 V3D is missing, don't advertise render nodes. */ | |
| 225 | − node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL); | |
| 226 | − if (!node || !of_device_is_available(node)) | |
| 227 | − vc4_drm_driver.driver_features &= ~DRIVER_RENDER; | |
| 228 | − of_node_put(node); | |
| 284 | + is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5"); | |
| 285 | + if (is_vc5) | |
| 286 | + driver = &vc5_drm_driver; | |
| 287 | + else | |
| 288 | + driver = &vc4_drm_driver; | |
| 229 | 289 | |
| 230 | − vc4 = devm_drm_dev_alloc(dev, &vc4_drm_driver, struct vc4_dev, base); | |
| 290 | + vc4 = devm_drm_dev_alloc(dev, driver, struct vc4_dev, base); | |
| 231 | 291 | if (IS_ERR(vc4)) |
| 232 | 292 | return PTR_ERR(vc4); |
| 293 | + vc4->is_vc5 = is_vc5; | |
| 233 | 294 | |
| 234 | 295 | drm = &vc4->base; |
| 235 | 296 | platform_set_drvdata(pdev, drm); |
| 236 | 297 | INIT_LIST_HEAD(&vc4->debugfs_list); |
| 237 | 298 | |
| 238 | − mutex_init(&vc4->bin_bo_lock); | |
| 299 | + if (!is_vc5) { | |
| 300 | + mutex_init(&vc4->bin_bo_lock); | |
| 239 | 301 | |
| 240 | − ret = vc4_bo_cache_init(drm); | |
| 241 | − if (ret) | |
| 242 | − return ret; | |
| 302 | + ret = vc4_bo_cache_init(drm); | |
| 303 | + if (ret) | |
| 304 | + return ret; | |
| 305 | + } | |
| 243 | 306 | |
| 244 | 307 | ret = drmm_mode_config_init(drm); |
| 245 | 308 | if (ret) |
| 246 | 309 | return ret; |
| 247 | 310 | |
| 248 | − ret = vc4_gem_init(drm); | |
| 249 | − if (ret) | |
| 250 | − return ret; | |
| 311 | + if (!is_vc5) { | |
| 312 | + ret = vc4_gem_init(drm); | |
| 313 | + if (ret) | |
| 314 | + return ret; | |
| 315 | + } | |
| 251 | 316 | |
| 252 | 317 | node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); |
| 253 | 318 | if (node) { |
| @@ -258,7 +323,7 @@ static int vc4_drm_bind(struct device *dev) · 4 unmodified lines | ||
| 258 | 323 | return -EPROBE_DEFER; |
| 259 | 324 | } |
| 260 | 325 | |
| 261 | − ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver); | |
| 326 | + ret = drm_aperture_remove_framebuffers(false, driver); | |
| 262 | 327 | if (ret) |
| 263 | 328 | return ret; |
| 264 | 329 | |
| @@ -48,6 +48,8 @@ enum vc4_kernel_bo_type { · 47 unmodified lines | ||
| 48 | 48 | * done. This way, only events related to a specific job will be counted. |
| 49 | 49 | */ |
| 50 | 50 | struct vc4_perfmon { |
| 51 | + struct vc4_dev *dev; | |
| 52 | + | |
| 51 | 53 | /* Tracks the number of users of the perfmon, when this counter reaches |
| 52 | 54 | * zero the perfmon is destroyed. |
| 53 | 55 | */ |
| @@ -74,6 +76,8 @@ struct vc4_perfmon { · 20 unmodified lines | ||
| 74 | 76 | struct vc4_dev { |
| 75 | 77 | struct drm_device base; |
| 76 | 78 | |
| 79 | + bool is_vc5; | |
| 80 | + | |
| 77 | 81 | unsigned int irq; |
| 78 | 82 | |
| 79 | 83 | struct vc4_hvs *hvs; |
| @@ -316,6 +320,7 @@ struct vc4_v3d { · 236 unmodified lines | ||
| 316 | 320 | }; |
| 317 | 321 | |
| 318 | 322 | struct vc4_hvs { |
| 323 | + struct vc4_dev *vc4; | |
| 319 | 324 | struct platform_device *pdev; |
| 320 | 325 | void __iomem *regs; |
| 321 | 326 | u32 __iomem *dlist; |
| @@ -333,9 +338,6 @@ struct vc4_hvs { · 11 unmodified lines | ||
| 333 | 338 | struct drm_mm_node mitchell_netravali_filter; |
| 334 | 339 | |
| 335 | 340 | struct debugfs_regset32 regset; |
| 336 | − | |
| 337 | − /* HVS version 5 flag, therefore requires updated dlist structures */ | |
| 338 | − bool hvs5; | |
| 339 | 341 | }; |
| 340 | 342 | |
| 341 | 343 | struct vc4_plane { |
| @@ -580,6 +582,8 @@ to_vc4_crtc_state(struct drm_crtc_state *crtc_state) · 238 unmodified lines | ||
| 580 | 582 | #define VC4_REG32(reg) { .name = #reg, .offset = reg } |
| 581 | 583 | |
| 582 | 584 | struct vc4_exec_info { |
| 585 | + struct vc4_dev *dev; | |
| 586 | + | |
| 583 | 587 | /* Sequence number for this bin/render job. */ |
| 584 | 588 | uint64_t seqno; |
| 585 | 589 | |
| @@ -701,6 +705,8 @@ struct vc4_exec_info { · 115 unmodified lines | ||
| 701 | 705 | * released when the DRM file is closed should be placed here. |
| 702 | 706 | */ |
| 703 | 707 | struct vc4_file { |
| 708 | + struct vc4_dev *dev; | |
| 709 | + | |
| 704 | 710 | struct { |
| 705 | 711 | struct idr idr; |
| 706 | 712 | struct mutex lock; |
| @@ -814,9 +820,9 @@ struct vc4_validated_shader_info { · 107 unmodified lines | ||
| 814 | 820 | struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); |
| 815 | 821 | struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, |
| 816 | 822 | bool from_cache, enum vc4_kernel_bo_type type); |
| 817 | −int vc4_dumb_create(struct drm_file *file_priv, | |
| 818 | − struct drm_device *dev, | |
| 819 | − struct drm_mode_create_dumb *args); | |
| 823 | +int vc4_bo_dumb_create(struct drm_file *file_priv, | |
| 824 | + struct drm_device *dev, | |
| 825 | + struct drm_mode_create_dumb *args); | |
| 820 | 826 | int vc4_create_bo_ioctl(struct drm_device *dev, void *data, |
| 821 | 827 | struct drm_file *file_priv); |
| 822 | 828 | int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, |
| @@ -885,6 +891,7 @@ static inline void vc4_debugfs_add_regset32(struct drm_device *drm, · 62 unmodified lines | ||
| 885 | 891 | |
| 886 | 892 | /* vc4_drv.c */ |
| 887 | 893 | void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); |
| 894 | +int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args); | |
| 888 | 895 | |
| 889 | 896 | /* vc4_dpi.c */ |
| 890 | 897 | extern struct platform_driver vc4_dpi_driver; |
| @@ -76,6 +76,9 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, · 75 unmodified lines | ||
| 76 | 76 | u32 i; |
| 77 | 77 | int ret = 0; |
| 78 | 78 | |
| 79 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 80 | + return -ENODEV; | |
| 81 | + | |
| 79 | 82 | if (!vc4->v3d) { |
| 80 | 83 | DRM_DEBUG("VC4_GET_HANG_STATE with no VC4 V3D probed\n"); |
| 81 | 84 | return -ENODEV; |
| @@ -386,6 +389,9 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, · 304 unmodified lines | ||
| 386 | 389 | unsigned long timeout_expire; |
| 387 | 390 | DEFINE_WAIT(wait); |
| 388 | 391 | |
| 392 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 393 | + return -ENODEV; | |
| 394 | + | |
| 389 | 395 | if (vc4->finished_seqno >= seqno) |
| 390 | 396 | return 0; |
| 391 | 397 | |
| @@ -468,6 +474,9 @@ vc4_submit_next_bin_job(struct drm_device *dev) · 76 unmodified lines | ||
| 468 | 474 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 469 | 475 | struct vc4_exec_info *exec; |
| 470 | 476 | |
| 477 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 478 | + return; | |
| 479 | + | |
| 471 | 480 | again: |
| 472 | 481 | exec = vc4_first_bin_job(vc4); |
| 473 | 482 | if (!exec) |
| @@ -513,6 +522,9 @@ vc4_submit_next_render_job(struct drm_device *dev) · 39 unmodified lines | ||
| 513 | 522 | if (!exec) |
| 514 | 523 | return; |
| 515 | 524 | |
| 525 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 526 | + return; | |
| 527 | + | |
| 516 | 528 | /* A previous RCL may have written to one of our textures, and |
| 517 | 529 | * our full cache flush at bin time may have occurred before |
| 518 | 530 | * that RCL completed. Flush the texture cache now, but not |
| @@ -531,6 +543,9 @@ vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec) · 12 unmodified lines | ||
| 531 | 543 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 532 | 544 | bool was_empty = list_empty(&vc4->render_job_list); |
| 533 | 545 | |
| 546 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 547 | + return; | |
| 548 | + | |
| 534 | 549 | list_move_tail(&exec->head, &vc4->render_job_list); |
| 535 | 550 | if (was_empty) |
| 536 | 551 | vc4_submit_next_render_job(dev); |
| @@ -997,6 +1012,9 @@ vc4_job_handle_completed(struct vc4_dev *vc4) · 460 unmodified lines | ||
| 997 | 1012 | unsigned long irqflags; |
| 998 | 1013 | struct vc4_seqno_cb *cb, *cb_temp; |
| 999 | 1014 | |
| 1015 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1016 | + return; | |
| 1017 | + | |
| 1000 | 1018 | spin_lock_irqsave(&vc4->job_lock, irqflags); |
| 1001 | 1019 | while (!list_empty(&vc4->job_done_list)) { |
| 1002 | 1020 | struct vc4_exec_info *exec = |
| @@ -1033,6 +1051,9 @@ int vc4_queue_seqno_cb(struct drm_device *dev, · 30 unmodified lines | ||
| 1033 | 1051 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 1034 | 1052 | unsigned long irqflags; |
| 1035 | 1053 | |
| 1054 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1055 | + return -ENODEV; | |
| 1056 | + | |
| 1036 | 1057 | cb->func = func; |
| 1037 | 1058 | INIT_WORK(&cb->work, vc4_seqno_cb_work); |
| 1038 | 1059 | |
| @@ -1083,8 +1104,12 @@ int · 44 unmodified lines | ||
| 1083 | 1104 | vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, |
| 1084 | 1105 | struct drm_file *file_priv) |
| 1085 | 1106 | { |
| 1107 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 1086 | 1108 | struct drm_vc4_wait_seqno *args = data; |
| 1087 | 1109 | |
| 1110 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1111 | + return -ENODEV; | |
| 1112 | + | |
| 1088 | 1113 | return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, |
| 1089 | 1114 | &args->timeout_ns); |
| 1090 | 1115 | } |
| @@ -1093,11 +1118,15 @@ int · 2 unmodified lines | ||
| 1093 | 1118 | vc4_wait_bo_ioctl(struct drm_device *dev, void *data, |
| 1094 | 1119 | struct drm_file *file_priv) |
| 1095 | 1120 | { |
| 1121 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 1096 | 1122 | int ret; |
| 1097 | 1123 | struct drm_vc4_wait_bo *args = data; |
| 1098 | 1124 | struct drm_gem_object *gem_obj; |
| 1099 | 1125 | struct vc4_bo *bo; |
| 1100 | 1126 | |
| 1127 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1128 | + return -ENODEV; | |
| 1129 | + | |
| 1101 | 1130 | if (args->pad != 0) |
| 1102 | 1131 | return -EINVAL; |
| 1103 | 1132 | |
| @@ -1144,6 +1173,9 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, · 40 unmodified lines | ||
| 1144 | 1173 | args->shader_rec_size, |
| 1145 | 1174 | args->bo_handle_count); |
| 1146 | 1175 | |
| 1176 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1177 | + return -ENODEV; | |
| 1178 | + | |
| 1147 | 1179 | if (!vc4->v3d) { |
| 1148 | 1180 | DRM_DEBUG("VC4_SUBMIT_CL with no VC4 V3D probed\n"); |
| 1149 | 1181 | return -ENODEV; |
| @@ -1167,6 +1199,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, · 17 unmodified lines | ||
| 1167 | 1199 | DRM_ERROR("malloc failure on exec struct\n"); |
| 1168 | 1200 | return -ENOMEM; |
| 1169 | 1201 | } |
| 1202 | + exec->dev = vc4; | |
| 1170 | 1203 | |
| 1171 | 1204 | ret = vc4_v3d_pm_get(vc4); |
| 1172 | 1205 | if (ret) { |
| @@ -1276,6 +1309,9 @@ int vc4_gem_init(struct drm_device *dev) · 103 unmodified lines | ||
| 1276 | 1309 | { |
| 1277 | 1310 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 1278 | 1311 | |
| 1312 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1313 | + return -ENODEV; | |
| 1314 | + | |
| 1279 | 1315 | vc4->dma_fence_context = dma_fence_context_alloc(1); |
| 1280 | 1316 | |
| 1281 | 1317 | INIT_LIST_HEAD(&vc4->bin_job_list); |
| @@ -1321,11 +1357,15 @@ static void vc4_gem_destroy(struct drm_device *dev, void *unused) · 39 unmodified lines | ||
| 1321 | 1357 | int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data, |
| 1322 | 1358 | struct drm_file *file_priv) |
| 1323 | 1359 | { |
| 1360 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 1324 | 1361 | struct drm_vc4_gem_madvise *args = data; |
| 1325 | 1362 | struct drm_gem_object *gem_obj; |
| 1326 | 1363 | struct vc4_bo *bo; |
| 1327 | 1364 | int ret; |
| 1328 | 1365 | |
| 1366 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 1367 | + return -ENODEV; | |
| 1368 | + | |
| 1329 | 1369 | switch (args->madv) { |
| 1330 | 1370 | case VC4_MADV_DONTNEED: |
| 1331 | 1371 | case VC4_MADV_WILLNEED: |
| @@ -1481,7 +1481,7 @@ vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, · 1480 unmodified lines | ||
| 1481 | 1481 | unsigned int bpc, |
| 1482 | 1482 | enum vc4_hdmi_output_format fmt) |
| 1483 | 1483 | { |
| 1484 | − unsigned long long clock = mode->clock * 1000; | |
| 1484 | + unsigned long long clock = mode->clock * 1000ULL; | |
| 1485 | 1485 | |
| 1486 | 1486 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) |
| 1487 | 1487 | clock = clock * 2; |
| @@ -220,10 +220,11 @@ u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo) · 219 unmodified lines | ||
| 220 | 220 | |
| 221 | 221 | int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output) |
| 222 | 222 | { |
| 223 | + struct vc4_dev *vc4 = hvs->vc4; | |
| 223 | 224 | u32 reg; |
| 224 | 225 | int ret; |
| 225 | 226 | |
| 226 | − if (!hvs->hvs5) | |
| 227 | + if (!vc4->is_vc5) | |
| 227 | 228 | return output; |
| 228 | 229 | |
| 229 | 230 | switch (output) { |
| @@ -273,6 +274,7 @@ int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output) · 43 unmodified lines | ||
| 273 | 274 | static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, |
| 274 | 275 | struct drm_display_mode *mode, bool oneshot) |
| 275 | 276 | { |
| 277 | + struct vc4_dev *vc4 = hvs->vc4; | |
| 276 | 278 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
| 277 | 279 | struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); |
| 278 | 280 | unsigned int chan = vc4_crtc_state->assigned_channel; |
| @@ -291,7 +293,7 @@ static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, · 12 unmodified lines | ||
| 291 | 293 | */ |
| 292 | 294 | dispctrl = SCALER_DISPCTRLX_ENABLE; |
| 293 | 295 | |
| 294 | − if (!hvs->hvs5) | |
| 296 | + if (!vc4->is_vc5) | |
| 295 | 297 | dispctrl |= VC4_SET_FIELD(mode->hdisplay, |
| 296 | 298 | SCALER_DISPCTRLX_WIDTH) | |
| 297 | 299 | VC4_SET_FIELD(mode->vdisplay, |
| @@ -312,7 +314,7 @@ static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, · 14 unmodified lines | ||
| 312 | 314 | |
| 313 | 315 | HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx | |
| 314 | 316 | SCALER_DISPBKGND_AUTOHS | |
| 315 | − ((!hvs->hvs5) ? SCALER_DISPBKGND_GAMMA : 0) | | |
| 317 | + ((!vc4->is_vc5) ? SCALER_DISPBKGND_GAMMA : 0) | | |
| 316 | 318 | (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); |
| 317 | 319 | |
| 318 | 320 | /* Reload the LUT, since the SRAMs would have been disabled if |
| @@ -617,11 +619,9 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) · 298 unmodified lines | ||
| 617 | 619 | if (!hvs) |
| 618 | 620 | return -ENOMEM; |
| 619 | 621 | |
| 622 | + hvs->vc4 = vc4; | |
| 620 | 623 | hvs->pdev = pdev; |
| 621 | 624 | |
| 622 | − if (of_device_is_compatible(pdev->dev.of_node, "brcm,bcm2711-hvs")) | |
| 623 | − hvs->hvs5 = true; | |
| 624 | − | |
| 625 | 625 | hvs->regs = vc4_ioremap_regs(pdev, 0); |
| 626 | 626 | if (IS_ERR(hvs->regs)) |
| 627 | 627 | return PTR_ERR(hvs->regs); |
| @@ -630,7 +630,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) · 2 unmodified lines | ||
| 630 | 630 | hvs->regset.regs = hvs_regs; |
| 631 | 631 | hvs->regset.nregs = ARRAY_SIZE(hvs_regs); |
| 632 | 632 | |
| 633 | − if (hvs->hvs5) { | |
| 633 | + if (vc4->is_vc5) { | |
| 634 | 634 | hvs->core_clk = devm_clk_get(&pdev->dev, NULL); |
| 635 | 635 | if (IS_ERR(hvs->core_clk)) { |
| 636 | 636 | dev_err(&pdev->dev, "Couldn't get core clock\n"); |
| @@ -644,7 +644,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) · 7 unmodified lines | ||
| 644 | 644 | } |
| 645 | 645 | } |
| 646 | 646 | |
| 647 | − if (!hvs->hvs5) | |
| 647 | + if (!vc4->is_vc5) | |
| 648 | 648 | hvs->dlist = hvs->regs + SCALER_DLIST_START; |
| 649 | 649 | else |
| 650 | 650 | hvs->dlist = hvs->regs + SCALER5_DLIST_START; |
| @@ -665,7 +665,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) · 14 unmodified lines | ||
| 665 | 665 | * between planes when they don't overlap on the screen, but |
| 666 | 666 | * for now we just allocate globally. |
| 667 | 667 | */ |
| 668 | − if (!hvs->hvs5) | |
| 668 | + if (!vc4->is_vc5) | |
| 669 | 669 | /* 48k words of 2x12-bit pixels */ |
| 670 | 670 | drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024); |
| 671 | 671 | else |
| @@ -265,6 +265,9 @@ vc4_irq_enable(struct drm_device *dev) · 264 unmodified lines | ||
| 265 | 265 | { |
| 266 | 266 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 267 | 267 | |
| 268 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 269 | + return; | |
| 270 | + | |
| 268 | 271 | if (!vc4->v3d) |
| 269 | 272 | return; |
| 270 | 273 | |
| @@ -279,6 +282,9 @@ vc4_irq_disable(struct drm_device *dev) · 8 unmodified lines | ||
| 279 | 282 | { |
| 280 | 283 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 281 | 284 | |
| 285 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 286 | + return; | |
| 287 | + | |
| 282 | 288 | if (!vc4->v3d) |
| 283 | 289 | return; |
| 284 | 290 | |
| @@ -296,8 +302,12 @@ vc4_irq_disable(struct drm_device *dev) · 11 unmodified lines | ||
| 296 | 302 | |
| 297 | 303 | int vc4_irq_install(struct drm_device *dev, int irq) |
| 298 | 304 | { |
| 305 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 299 | 306 | int ret; |
| 300 | 307 | |
| 308 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 309 | + return -ENODEV; | |
| 310 | + | |
| 301 | 311 | if (irq == IRQ_NOTCONNECTED) |
| 302 | 312 | return -ENOTCONN; |
| 303 | 313 | |
| @@ -316,6 +326,9 @@ void vc4_irq_uninstall(struct drm_device *dev) · 12 unmodified lines | ||
| 316 | 326 | { |
| 317 | 327 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 318 | 328 | |
| 329 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 330 | + return; | |
| 331 | + | |
| 319 | 332 | vc4_irq_disable(dev); |
| 320 | 333 | free_irq(vc4->irq, dev); |
| 321 | 334 | } |
| @@ -326,6 +339,9 @@ void vc4_irq_reset(struct drm_device *dev) · 4 unmodified lines | ||
| 326 | 339 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 327 | 340 | unsigned long irqflags; |
| 328 | 341 | |
| 342 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 343 | + return; | |
| 344 | + | |
| 329 | 345 | /* Acknowledge any stale IRQs. */ |
| 330 | 346 | V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); |
| 331 | 347 | |
| @@ -393,7 +393,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) · 392 unmodified lines | ||
| 393 | 393 | old_hvs_state->fifo_state[channel].pending_commit = NULL; |
| 394 | 394 | } |
| 395 | 395 | |
| 396 | − if (vc4->hvs->hvs5) { | |
| 396 | + if (vc4->is_vc5) { | |
| 397 | 397 | unsigned long state_rate = max(old_hvs_state->core_clock_rate, |
| 398 | 398 | new_hvs_state->core_clock_rate); |
| 399 | 399 | unsigned long core_rate = max_t(unsigned long, |
| @@ -412,7 +412,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) · 12 unmodified lines | ||
| 412 | 412 | |
| 413 | 413 | vc4_ctm_commit(vc4, state); |
| 414 | 414 | |
| 415 | − if (vc4->hvs->hvs5) | |
| 415 | + if (vc4->is_vc5) | |
| 416 | 416 | vc5_hvs_pv_muxing_commit(vc4, state); |
| 417 | 417 | else |
| 418 | 418 | vc4_hvs_pv_muxing_commit(vc4, state); |
| @@ -430,7 +430,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) · 11 unmodified lines | ||
| 430 | 430 | |
| 431 | 431 | drm_atomic_helper_cleanup_planes(dev, state); |
| 432 | 432 | |
| 433 | − if (vc4->hvs->hvs5) { | |
| 433 | + if (vc4->is_vc5) { | |
| 434 | 434 | drm_dbg(dev, "Running the core clock at %lu Hz\n", |
| 435 | 435 | new_hvs_state->core_clock_rate); |
| 436 | 436 | |
| @@ -479,8 +479,12 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, · 42 unmodified lines | ||
| 479 | 479 | struct drm_file *file_priv, |
| 480 | 480 | const struct drm_mode_fb_cmd2 *mode_cmd) |
| 481 | 481 | { |
| 482 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 482 | 483 | struct drm_mode_fb_cmd2 mode_cmd_local; |
| 483 | 484 | |
| 485 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 486 | + return ERR_PTR(-ENODEV); | |
| 487 | + | |
| 484 | 488 | /* If the user didn't specify a modifier, use the |
| 485 | 489 | * vc4_set_tiling_ioctl() state for the BO. |
| 486 | 490 | */ |
| @@ -997,11 +1001,15 @@ static const struct drm_mode_config_funcs vc4_mode_funcs = { · 510 unmodified lines | ||
| 997 | 1001 | .fb_create = vc4_fb_create, |
| 998 | 1002 | }; |
| 999 | 1003 | |
| 1004 | +static const struct drm_mode_config_funcs vc5_mode_funcs = { | |
| 1005 | + .atomic_check = vc4_atomic_check, | |
| 1006 | + .atomic_commit = drm_atomic_helper_commit, | |
| 1007 | + .fb_create = drm_gem_fb_create, | |
| 1008 | +}; | |
| 1009 | + | |
| 1000 | 1010 | int vc4_kms_load(struct drm_device *dev) |
| 1001 | 1011 | { |
| 1002 | 1012 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 1003 | − bool is_vc5 = of_device_is_compatible(dev->dev->of_node, | |
| 1004 | − "brcm,bcm2711-vc5"); | |
| 1005 | 1013 | int ret; |
| 1006 | 1014 | |
| 1007 | 1015 | /* |
| @@ -1009,7 +1017,7 @@ int vc4_kms_load(struct drm_device *dev) · 1 unmodified line | ||
| 1009 | 1017 | * the BCM2711, but the load tracker computations are used for |
| 1010 | 1018 | * the core clock rate calculation. |
| 1011 | 1019 | */ |
| 1012 | − if (!is_vc5) { | |
| 1020 | + if (!vc4->is_vc5) { | |
| 1013 | 1021 | /* Start with the load tracker enabled. Can be |
| 1014 | 1022 | * disabled through the debugfs load_tracker file. |
| 1015 | 1023 | */ |
| @@ -1025,7 +1033,7 @@ int vc4_kms_load(struct drm_device *dev) · 9 unmodified lines | ||
| 1025 | 1033 | return ret; |
| 1026 | 1034 | } |
| 1027 | 1035 | |
| 1028 | − if (is_vc5) { | |
| 1036 | + if (vc4->is_vc5) { | |
| 1029 | 1037 | dev->mode_config.max_width = 7680; |
| 1030 | 1038 | dev->mode_config.max_height = 7680; |
| 1031 | 1039 | } else { |
| @@ -1033,7 +1041,7 @@ int vc4_kms_load(struct drm_device *dev) · 1 unmodified line | ||
| 1033 | 1041 | dev->mode_config.max_height = 2048; |
| 1034 | 1042 | } |
| 1035 | 1043 | |
| 1036 | − dev->mode_config.funcs = &vc4_mode_funcs; | |
| 1044 | + dev->mode_config.funcs = vc4->is_vc5 ? &vc5_mode_funcs : &vc4_mode_funcs; | |
| 1037 | 1045 | dev->mode_config.helper_private = &vc4_mode_config_helpers; |
| 1038 | 1046 | dev->mode_config.preferred_depth = 24; |
| 1039 | 1047 | dev->mode_config.async_page_flip = true; |
| @@ -17,13 +17,27 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | void vc4_perfmon_get(struct vc4_perfmon *perfmon) |
| 19 | 19 | { |
| 20 | + struct vc4_dev *vc4 = perfmon->dev; | |
| 21 | + | |
| 22 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 23 | + return; | |
| 24 | + | |
| 20 | 25 | if (perfmon) |
| 21 | 26 | refcount_inc(&perfmon->refcnt); |
| 22 | 27 | } |
| 23 | 28 | |
| 24 | 29 | void vc4_perfmon_put(struct vc4_perfmon *perfmon) |
| 25 | 30 | { |
| 26 | − if (perfmon && refcount_dec_and_test(&perfmon->refcnt)) | |
| 31 | + struct vc4_dev *vc4; | |
| 32 | + | |
| 33 | + if (!perfmon) | |
| 34 | + return; | |
| 35 | + | |
| 36 | + vc4 = perfmon->dev; | |
| 37 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 38 | + return; | |
| 39 | + | |
| 40 | + if (refcount_dec_and_test(&perfmon->refcnt)) | |
| 27 | 41 | kfree(perfmon); |
| 28 | 42 | } |
| 29 | 43 | |
| @@ -32,6 +46,9 @@ void vc4_perfmon_start(struct vc4_dev *vc4, struct vc4_perfmon *perfmon) · 2 unmodified lines | ||
| 32 | 46 | unsigned int i; |
| 33 | 47 | u32 mask; |
| 34 | 48 | |
| 49 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 50 | + return; | |
| 51 | + | |
| 35 | 52 | if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon)) |
| 36 | 53 | return; |
| 37 | 54 | |
| @@ -49,6 +66,9 @@ void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon, · 11 unmodified lines | ||
| 49 | 66 | { |
| 50 | 67 | unsigned int i; |
| 51 | 68 | |
| 69 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 70 | + return; | |
| 71 | + | |
| 52 | 72 | if (WARN_ON_ONCE(!vc4->active_perfmon || |
| 53 | 73 | perfmon != vc4->active_perfmon)) |
| 54 | 74 | return; |
| @@ -64,8 +84,12 @@ void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon, · 9 unmodified lines | ||
| 64 | 84 | |
| 65 | 85 | struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) |
| 66 | 86 | { |
| 87 | + struct vc4_dev *vc4 = vc4file->dev; | |
| 67 | 88 | struct vc4_perfmon *perfmon; |
| 68 | 89 | |
| 90 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 91 | + return NULL; | |
| 92 | + | |
| 69 | 93 | mutex_lock(&vc4file->perfmon.lock); |
| 70 | 94 | perfmon = idr_find(&vc4file->perfmon.idr, id); |
| 71 | 95 | vc4_perfmon_get(perfmon); |
| @@ -76,8 +100,14 @@ struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) · 4 unmodified lines | ||
| 76 | 100 | |
| 77 | 101 | void vc4_perfmon_open_file(struct vc4_file *vc4file) |
| 78 | 102 | { |
| 103 | + struct vc4_dev *vc4 = vc4file->dev; | |
| 104 | + | |
| 105 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 106 | + return; | |
| 107 | + | |
| 79 | 108 | mutex_init(&vc4file->perfmon.lock); |
| 80 | 109 | idr_init_base(&vc4file->perfmon.idr, VC4_PERFMONID_MIN); |
| 110 | + vc4file->dev = vc4; | |
| 81 | 111 | } |
| 82 | 112 | |
| 83 | 113 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) |
| @@ -91,6 +121,11 @@ static int vc4_perfmon_idr_del(int id, void *elem, void *data) · 7 unmodified lines | ||
| 91 | 121 | |
| 92 | 122 | void vc4_perfmon_close_file(struct vc4_file *vc4file) |
| 93 | 123 | { |
| 124 | + struct vc4_dev *vc4 = vc4file->dev; | |
| 125 | + | |
| 126 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 127 | + return; | |
| 128 | + | |
| 94 | 129 | mutex_lock(&vc4file->perfmon.lock); |
| 95 | 130 | idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL); |
| 96 | 131 | idr_destroy(&vc4file->perfmon.idr); |
| @@ -107,6 +142,9 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, · 10 unmodified lines | ||
| 107 | 142 | unsigned int i; |
| 108 | 143 | int ret; |
| 109 | 144 | |
| 145 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 146 | + return -ENODEV; | |
| 147 | + | |
| 110 | 148 | if (!vc4->v3d) { |
| 111 | 149 | DRM_DEBUG("Creating perfmon no VC4 V3D probed\n"); |
| 112 | 150 | return -ENODEV; |
| @@ -127,6 +165,7 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, · 14 unmodified lines | ||
| 127 | 165 | GFP_KERNEL); |
| 128 | 166 | if (!perfmon) |
| 129 | 167 | return -ENOMEM; |
| 168 | + perfmon->dev = vc4; | |
| 130 | 169 | |
| 131 | 170 | for (i = 0; i < req->ncounters; i++) |
| 132 | 171 | perfmon->events[i] = req->events[i]; |
| @@ -157,6 +196,9 @@ int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data, · 24 unmodified lines | ||
| 157 | 196 | struct drm_vc4_perfmon_destroy *req = data; |
| 158 | 197 | struct vc4_perfmon *perfmon; |
| 159 | 198 | |
| 199 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 200 | + return -ENODEV; | |
| 201 | + | |
| 160 | 202 | if (!vc4->v3d) { |
| 161 | 203 | DRM_DEBUG("Destroying perfmon no VC4 V3D probed\n"); |
| 162 | 204 | return -ENODEV; |
| @@ -182,6 +224,9 @@ int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, · 19 unmodified lines | ||
| 182 | 224 | struct vc4_perfmon *perfmon; |
| 183 | 225 | int ret; |
| 184 | 226 | |
| 227 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 228 | + return -ENODEV; | |
| 229 | + | |
| 185 | 230 | if (!vc4->v3d) { |
| 186 | 231 | DRM_DEBUG("Getting perfmon no VC4 V3D probed\n"); |
| 187 | 232 | return -ENODEV; |
| @@ -489,10 +489,10 @@ static u32 vc4_lbm_size(struct drm_plane_state *state) · 488 unmodified lines | ||
| 489 | 489 | } |
| 490 | 490 | |
| 491 | 491 | /* Align it to 64 or 128 (hvs5) bytes */ |
| 492 | − lbm = roundup(lbm, vc4->hvs->hvs5 ? 128 : 64); | |
| 492 | + lbm = roundup(lbm, vc4->is_vc5 ? 128 : 64); | |
| 493 | 493 | |
| 494 | 494 | /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */ |
| 495 | − lbm /= vc4->hvs->hvs5 ? 4 : 2; | |
| 495 | + lbm /= vc4->is_vc5 ? 4 : 2; | |
| 496 | 496 | |
| 497 | 497 | return lbm; |
| 498 | 498 | } |
| @@ -608,7 +608,7 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) · 109 unmodified lines | ||
| 608 | 608 | ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, |
| 609 | 609 | &vc4_state->lbm, |
| 610 | 610 | lbm_size, |
| 611 | − vc4->hvs->hvs5 ? 64 : 32, | |
| 611 | + vc4->is_vc5 ? 64 : 32, | |
| 612 | 612 | 0, 0); |
| 613 | 613 | spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); |
| 614 | 614 | |
| @@ -917,7 +917,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, · 302 unmodified lines | ||
| 917 | 917 | mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && |
| 918 | 918 | fb->format->has_alpha; |
| 919 | 919 | |
| 920 | − if (!vc4->hvs->hvs5) { | |
| 920 | + if (!vc4->is_vc5) { | |
| 921 | 921 | /* Control word */ |
| 922 | 922 | vc4_dlist_write(vc4_state, |
| 923 | 923 | SCALER_CTL0_VALID | |
| @@ -1321,6 +1321,10 @@ static int vc4_plane_atomic_async_check(struct drm_plane *plane, · 397 unmodified lines | ||
| 1321 | 1321 | |
| 1322 | 1322 | old_vc4_state = to_vc4_plane_state(plane->state); |
| 1323 | 1323 | new_vc4_state = to_vc4_plane_state(new_plane_state); |
| 1324 | + | |
| 1325 | + if (!new_vc4_state->hw_dlist) | |
| 1326 | + return -EINVAL; | |
| 1327 | + | |
| 1324 | 1328 | if (old_vc4_state->dlist_count != new_vc4_state->dlist_count || |
| 1325 | 1329 | old_vc4_state->pos0_offset != new_vc4_state->pos0_offset || |
| 1326 | 1330 | old_vc4_state->pos2_offset != new_vc4_state->pos2_offset || |
| @@ -1385,6 +1389,13 @@ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = { · 58 unmodified lines | ||
| 1385 | 1389 | .atomic_async_update = vc4_plane_atomic_async_update, |
| 1386 | 1390 | }; |
| 1387 | 1391 | |
| 1392 | +static const struct drm_plane_helper_funcs vc5_plane_helper_funcs = { | |
| 1393 | + .atomic_check = vc4_plane_atomic_check, | |
| 1394 | + .atomic_update = vc4_plane_atomic_update, | |
| 1395 | + .atomic_async_check = vc4_plane_atomic_async_check, | |
| 1396 | + .atomic_async_update = vc4_plane_atomic_async_update, | |
| 1397 | +}; | |
| 1398 | + | |
| 1388 | 1399 | static bool vc4_format_mod_supported(struct drm_plane *plane, |
| 1389 | 1400 | uint32_t format, |
| 1390 | 1401 | uint64_t modifier) |
| @@ -1453,14 +1464,13 @@ static const struct drm_plane_funcs vc4_plane_funcs = { · 62 unmodified lines | ||
| 1453 | 1464 | struct drm_plane *vc4_plane_init(struct drm_device *dev, |
| 1454 | 1465 | enum drm_plane_type type) |
| 1455 | 1466 | { |
| 1467 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 1456 | 1468 | struct drm_plane *plane = NULL; |
| 1457 | 1469 | struct vc4_plane *vc4_plane; |
| 1458 | 1470 | u32 formats[ARRAY_SIZE(hvs_formats)]; |
| 1459 | 1471 | int num_formats = 0; |
| 1460 | 1472 | int ret = 0; |
| 1461 | 1473 | unsigned i; |
| 1462 | − bool hvs5 = of_device_is_compatible(dev->dev->of_node, | |
| 1463 | − "brcm,bcm2711-vc5"); | |
| 1464 | 1474 | static const uint64_t modifiers[] = { |
| 1465 | 1475 | DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, |
| 1466 | 1476 | DRM_FORMAT_MOD_BROADCOM_SAND128, |
| @@ -1476,7 +1486,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, · 9 unmodified lines | ||
| 1476 | 1486 | return ERR_PTR(-ENOMEM); |
| 1477 | 1487 | |
| 1478 | 1488 | for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { |
| 1479 | − if (!hvs_formats[i].hvs5_only || hvs5) { | |
| 1489 | + if (!hvs_formats[i].hvs5_only || vc4->is_vc5) { | |
| 1480 | 1490 | formats[num_formats] = hvs_formats[i].drm; |
| 1481 | 1491 | num_formats++; |
| 1482 | 1492 | } |
| @@ -1490,7 +1500,10 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, · 7 unmodified lines | ||
| 1490 | 1500 | if (ret) |
| 1491 | 1501 | return ERR_PTR(ret); |
| 1492 | 1502 | |
| 1493 | − drm_plane_helper_add(plane, &vc4_plane_helper_funcs); | |
| 1503 | + if (vc4->is_vc5) | |
| 1504 | + drm_plane_helper_add(plane, &vc5_plane_helper_funcs); | |
| 1505 | + else | |
| 1506 | + drm_plane_helper_add(plane, &vc4_plane_helper_funcs); | |
| 1494 | 1507 | |
| 1495 | 1508 | drm_plane_create_alpha_property(plane); |
| 1496 | 1509 | drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, |
| @@ -593,11 +593,15 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, · 592 unmodified lines | ||
| 593 | 593 | |
| 594 | 594 | int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) |
| 595 | 595 | { |
| 596 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 596 | 597 | struct vc4_rcl_setup setup = {0}; |
| 597 | 598 | struct drm_vc4_submit_cl *args = exec->args; |
| 598 | 599 | bool has_bin = args->bin_cl_size != 0; |
| 599 | 600 | int ret; |
| 600 | 601 | |
| 602 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 603 | + return -ENODEV; | |
| 604 | + | |
| 601 | 605 | if (args->min_x_tile > args->max_x_tile || |
| 602 | 606 | args->min_y_tile > args->max_y_tile) { |
| 603 | 607 | DRM_DEBUG("Bad render tile set (%d,%d)-(%d,%d)\n", |
| @@ -127,6 +127,9 @@ static int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) · 126 unmodified lines | ||
| 127 | 127 | int |
| 128 | 128 | vc4_v3d_pm_get(struct vc4_dev *vc4) |
| 129 | 129 | { |
| 130 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 131 | + return -ENODEV; | |
| 132 | + | |
| 130 | 133 | mutex_lock(&vc4->power_lock); |
| 131 | 134 | if (vc4->power_refcount++ == 0) { |
| 132 | 135 | int ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); |
| @@ -145,6 +148,9 @@ vc4_v3d_pm_get(struct vc4_dev *vc4) · 12 unmodified lines | ||
| 145 | 148 | void |
| 146 | 149 | vc4_v3d_pm_put(struct vc4_dev *vc4) |
| 147 | 150 | { |
| 151 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 152 | + return; | |
| 153 | + | |
| 148 | 154 | mutex_lock(&vc4->power_lock); |
| 149 | 155 | if (--vc4->power_refcount == 0) { |
| 150 | 156 | pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev); |
| @@ -172,6 +178,9 @@ int vc4_v3d_get_bin_slot(struct vc4_dev *vc4) · 21 unmodified lines | ||
| 172 | 178 | uint64_t seqno = 0; |
| 173 | 179 | struct vc4_exec_info *exec; |
| 174 | 180 | |
| 181 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 182 | + return -ENODEV; | |
| 183 | + | |
| 175 | 184 | try_again: |
| 176 | 185 | spin_lock_irqsave(&vc4->job_lock, irqflags); |
| 177 | 186 | slot = ffs(~vc4->bin_alloc_used); |
| @@ -316,6 +325,9 @@ int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used) · 138 unmodified lines | ||
| 316 | 325 | { |
| 317 | 326 | int ret = 0; |
| 318 | 327 | |
| 328 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 329 | + return -ENODEV; | |
| 330 | + | |
| 319 | 331 | mutex_lock(&vc4->bin_bo_lock); |
| 320 | 332 | |
| 321 | 333 | if (used && *used) |
| @@ -348,6 +360,9 @@ static void bin_bo_release(struct kref *ref) · 26 unmodified lines | ||
| 348 | 360 | |
| 349 | 361 | void vc4_v3d_bin_bo_put(struct vc4_dev *vc4) |
| 350 | 362 | { |
| 363 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 364 | + return; | |
| 365 | + | |
| 351 | 366 | mutex_lock(&vc4->bin_bo_lock); |
| 352 | 367 | kref_put(&vc4->bin_bo_kref, bin_bo_release); |
| 353 | 368 | mutex_unlock(&vc4->bin_bo_lock); |
| @@ -105,9 +105,13 @@ size_is_lt(uint32_t width, uint32_t height, int cpp) · 104 unmodified lines | ||
| 105 | 105 | struct drm_gem_cma_object * |
| 106 | 106 | vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) |
| 107 | 107 | { |
| 108 | + struct vc4_dev *vc4 = exec->dev; | |
| 108 | 109 | struct drm_gem_cma_object *obj; |
| 109 | 110 | struct vc4_bo *bo; |
| 110 | 111 | |
| 112 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 113 | + return NULL; | |
| 114 | + | |
| 111 | 115 | if (hindex >= exec->bo_count) { |
| 112 | 116 | DRM_DEBUG("BO index %d greater than BO count %d\n", |
| 113 | 117 | hindex, exec->bo_count); |
| @@ -160,10 +164,14 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, · 46 unmodified lines | ||
| 160 | 164 | uint32_t offset, uint8_t tiling_format, |
| 161 | 165 | uint32_t width, uint32_t height, uint8_t cpp) |
| 162 | 166 | { |
| 167 | + struct vc4_dev *vc4 = exec->dev; | |
| 163 | 168 | uint32_t aligned_width, aligned_height, stride, size; |
| 164 | 169 | uint32_t utile_w = utile_width(cpp); |
| 165 | 170 | uint32_t utile_h = utile_height(cpp); |
| 166 | 171 | |
| 172 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 173 | + return false; | |
| 174 | + | |
| 167 | 175 | /* The shaded vertex format stores signed 12.4 fixed point |
| 168 | 176 | * (-2048,2047) offsets from the viewport center, so we should |
| 169 | 177 | * never have a render target larger than 4096. The texture |
| @@ -482,10 +490,14 @@ vc4_validate_bin_cl(struct drm_device *dev, · 312 unmodified lines | ||
| 482 | 490 | void *unvalidated, |
| 483 | 491 | struct vc4_exec_info *exec) |
| 484 | 492 | { |
| 493 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 485 | 494 | uint32_t len = exec->args->bin_cl_size; |
| 486 | 495 | uint32_t dst_offset = 0; |
| 487 | 496 | uint32_t src_offset = 0; |
| 488 | 497 | |
| 498 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 499 | + return -ENODEV; | |
| 500 | + | |
| 489 | 501 | while (src_offset < len) { |
| 490 | 502 | void *dst_pkt = validated + dst_offset; |
| 491 | 503 | void *src_pkt = unvalidated + src_offset; |
| @@ -926,9 +938,13 @@ int · 434 unmodified lines | ||
| 926 | 938 | vc4_validate_shader_recs(struct drm_device *dev, |
| 927 | 939 | struct vc4_exec_info *exec) |
| 928 | 940 | { |
| 941 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 929 | 942 | uint32_t i; |
| 930 | 943 | int ret = 0; |
| 931 | 944 | |
| 945 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 946 | + return -ENODEV; | |
| 947 | + | |
| 932 | 948 | for (i = 0; i < exec->shader_state_count; i++) { |
| 933 | 949 | ret = validate_gl_shader_rec(dev, exec, &exec->shader_state[i]); |
| 934 | 950 | if (ret) |
| @@ -778,6 +778,7 @@ vc4_handle_branch_target(struct vc4_shader_validation_state *validation_state) · 777 unmodified lines | ||
| 778 | 778 | struct vc4_validated_shader_info * |
| 779 | 779 | vc4_validate_shader(struct drm_gem_cma_object *shader_obj) |
| 780 | 780 | { |
| 781 | + struct vc4_dev *vc4 = to_vc4_dev(shader_obj->base.dev); | |
| 781 | 782 | bool found_shader_end = false; |
| 782 | 783 | int shader_end_ip = 0; |
| 783 | 784 | uint32_t last_thread_switch_ip = -3; |
| @@ -785,6 +786,9 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) · 1 unmodified line | ||
| 785 | 786 | struct vc4_validated_shader_info *validated_shader = NULL; |
| 786 | 787 | struct vc4_shader_validation_state validation_state; |
| 787 | 788 | |
| 789 | + if (WARN_ON_ONCE(vc4->is_vc5)) | |
| 790 | + return NULL; | |
| 791 | + | |
| 788 | 792 | memset(&validation_state, 0, sizeof(validation_state)); |
| 789 | 793 | validation_state.shader = shader_obj->vaddr; |
| 790 | 794 | validation_state.max_ip = shader_obj->base.size / sizeof(uint64_t); |
| @@ -71,7 +71,7 @@ static int xen_drm_front_gem_object_mmap(struct drm_gem_object *gem_obj, · 70 unmodified lines | ||
| 71 | 71 | * the whole buffer. |
| 72 | 72 | */ |
| 73 | 73 | vma->vm_flags &= ~VM_PFNMAP; |
| 74 | − vma->vm_flags |= VM_MIXEDMAP; | |
| 74 | + vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; | |
| 75 | 75 | vma->vm_pgoff = 0; |
| 76 | 76 | |
| 77 | 77 | /* |
| @@ -199,7 +199,8 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, · 198 unmodified lines | ||
| 199 | 199 | if (!input_device->hid_desc) |
| 200 | 200 | goto cleanup; |
| 201 | 201 | |
| 202 | − input_device->report_desc_size = desc->desc[0].wDescriptorLength; | |
| 202 | + input_device->report_desc_size = le16_to_cpu( | |
| 203 | + desc->desc[0].wDescriptorLength); | |
| 203 | 204 | if (input_device->report_desc_size == 0) { |
| 204 | 205 | input_device->dev_info_status = -EINVAL; |
| 205 | 206 | goto cleanup; |
| @@ -217,7 +218,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, · 11 unmodified lines | ||
| 217 | 218 | |
| 218 | 219 | memcpy(input_device->report_desc, |
| 219 | 220 | ((unsigned char *)desc) + desc->bLength, |
| 220 | − desc->desc[0].wDescriptorLength); | |
| 221 | + le16_to_cpu(desc->desc[0].wDescriptorLength)); | |
| 221 | 222 | |
| 222 | 223 | /* Send the ack */ |
| 223 | 224 | memset(&ack, 0, sizeof(struct mousevsc_prt_msg)); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/cpu.h> |
| 22 | 22 | #include <linux/hyperv.h> |
| 23 | 23 | #include <asm/mshyperv.h> |
| 24 | +#include <linux/sched/isolation.h> | |
| 24 | 25 | |
| 25 | 26 | #include "hyperv_vmbus.h" |
| 26 | 27 | |
| @@ -638,6 +639,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 611 unmodified lines | ||
| 638 | 639 | */ |
| 639 | 640 | if (newchannel->offermsg.offer.sub_channel_index == 0) { |
| 640 | 641 | mutex_unlock(&vmbus_connection.channel_mutex); |
| 642 | + cpus_read_unlock(); | |
| 641 | 643 | /* |
| 642 | 644 | * Don't call free_channel(), because newchannel->kobj |
| 643 | 645 | * is not initialized yet. |
| @@ -728,16 +730,20 @@ static void init_vp_index(struct vmbus_channel *channel) · 84 unmodified lines | ||
| 728 | 730 | u32 i, ncpu = num_online_cpus(); |
| 729 | 731 | cpumask_var_t available_mask; |
| 730 | 732 | struct cpumask *allocated_mask; |
| 733 | + const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ); | |
| 731 | 734 | u32 target_cpu; |
| 732 | 735 | int numa_node; |
| 733 | 736 | |
| 734 | 737 | if (!perf_chn || |
| 735 | − !alloc_cpumask_var(&available_mask, GFP_KERNEL)) { | |
| 738 | + !alloc_cpumask_var(&available_mask, GFP_KERNEL) || | |
| 739 | + cpumask_empty(hk_mask)) { | |
| 736 | 740 | /* |
| 737 | 741 | * If the channel is not a performance critical |
| 738 | 742 | * channel, bind it to VMBUS_CONNECT_CPU. |
| 739 | 743 | * In case alloc_cpumask_var() fails, bind it to |
| 740 | 744 | * VMBUS_CONNECT_CPU. |
| 745 | + * If all the cpus are isolated, bind it to | |
| 746 | + * VMBUS_CONNECT_CPU. | |
| 741 | 747 | */ |
| 742 | 748 | channel->target_cpu = VMBUS_CONNECT_CPU; |
| 743 | 749 | if (perf_chn) |
| @@ -758,17 +764,19 @@ static void init_vp_index(struct vmbus_channel *channel) · 14 unmodified lines | ||
| 758 | 764 | } |
| 759 | 765 | allocated_mask = &hv_context.hv_numa_map[numa_node]; |
| 760 | 766 | |
| 761 | − if (cpumask_equal(allocated_mask, cpumask_of_node(numa_node))) { | |
| 767 | +retry: | |
| 768 | + cpumask_xor(available_mask, allocated_mask, cpumask_of_node(numa_node)); | |
| 769 | + cpumask_and(available_mask, available_mask, hk_mask); | |
| 770 | + | |
| 771 | + if (cpumask_empty(available_mask)) { | |
| 762 | 772 | /* |
| 763 | 773 | * We have cycled through all the CPUs in the node; |
| 764 | 774 | * reset the allocated map. |
| 765 | 775 | */ |
| 766 | 776 | cpumask_clear(allocated_mask); |
| 777 | + goto retry; | |
| 767 | 778 | } |
| 768 | 779 | |
| 769 | − cpumask_xor(available_mask, allocated_mask, | |
| 770 | − cpumask_of_node(numa_node)); | |
| 771 | − | |
| 772 | 780 | target_cpu = cpumask_first(available_mask); |
| 773 | 781 | cpumask_set_cpu(target_cpu, allocated_mask); |
| 774 | 782 | |
| @@ -394,7 +394,7 @@ kvp_send_key(struct work_struct *dummy) · 393 unmodified lines | ||
| 394 | 394 | in_msg = kvp_transaction.kvp_msg; |
| 395 | 395 | |
| 396 | 396 | /* |
| 397 | − * The key/value strings sent from the host are encoded in | |
| 397 | + * The key/value strings sent from the host are encoded | |
| 398 | 398 | * in utf16; convert it to utf8 strings. |
| 399 | 399 | * The host assures us that the utf16 strings will not exceed |
| 400 | 400 | * the max lengths specified. We will however, reserve room |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/kernel_stat.h> |
| 22 | 22 | #include <linux/clockchips.h> |
| 23 | 23 | #include <linux/cpu.h> |
| 24 | +#include <linux/sched/isolation.h> | |
| 24 | 25 | #include <linux/sched/task_stack.h> |
| 25 | 26 | |
| 26 | 27 | #include <linux/delay.h> |
| @@ -1770,6 +1771,9 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel, · 1743 unmodified lines | ||
| 1770 | 1771 | if (target_cpu >= nr_cpumask_bits) |
| 1771 | 1772 | return -EINVAL; |
| 1772 | 1773 | |
| 1774 | + if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ))) | |
| 1775 | + return -EINVAL; | |
| 1776 | + | |
| 1773 | 1777 | /* No CPUs should come up or down during this. */ |
| 1774 | 1778 | cpus_read_lock(); |
| 1775 | 1779 | |
| @@ -259,7 +259,7 @@ static const struct ec_board_info board_info[] = { · 258 unmodified lines | ||
| 259 | 259 | }, |
| 260 | 260 | { |
| 261 | 261 | .board_names = { |
| 262 | − "ROG CROSSHAIR VIII FORMULA" | |
| 262 | + "ROG CROSSHAIR VIII FORMULA", | |
| 263 | 263 | "ROG CROSSHAIR VIII HERO", |
| 264 | 264 | "ROG CROSSHAIR VIII HERO (WI-FI)", |
| 265 | 265 | }, |
| @@ -1228,10 +1228,15 @@ EXPORT_SYMBOL_GPL(occ_setup); · 1227 unmodified lines | ||
| 1228 | 1228 | |
| 1229 | 1229 | void occ_shutdown(struct occ *occ) |
| 1230 | 1230 | { |
| 1231 | + mutex_lock(&occ->lock); | |
| 1232 | + | |
| 1231 | 1233 | occ_shutdown_sysfs(occ); |
| 1232 | 1234 | |
| 1233 | 1235 | if (occ->hwmon) |
| 1234 | 1236 | hwmon_device_unregister(occ->hwmon); |
| 1237 | + occ->hwmon = NULL; | |
| 1238 | + | |
| 1239 | + mutex_unlock(&occ->lock); | |
| 1235 | 1240 | } |
| 1236 | 1241 | EXPORT_SYMBOL_GPL(occ_shutdown); |
| 1237 | 1242 | |
| @@ -477,9 +477,6 @@ int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare) · 476 unmodified lines | ||
| 477 | 477 | { |
| 478 | 478 | int ret; |
| 479 | 479 | |
| 480 | − if (IS_ERR(dev->clk)) | |
| 481 | − return PTR_ERR(dev->clk); | |
| 482 | − | |
| 483 | 480 | if (prepare) { |
| 484 | 481 | /* Optional interface clock */ |
| 485 | 482 | ret = clk_prepare_enable(dev->pclk); |
| @@ -320,8 +320,17 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) · 319 unmodified lines | ||
| 320 | 320 | goto exit_reset; |
| 321 | 321 | } |
| 322 | 322 | |
| 323 | − dev->clk = devm_clk_get(&pdev->dev, NULL); | |
| 324 | − if (!i2c_dw_prepare_clk(dev, true)) { | |
| 323 | + dev->clk = devm_clk_get_optional(&pdev->dev, NULL); | |
| 324 | + if (IS_ERR(dev->clk)) { | |
| 325 | + ret = PTR_ERR(dev->clk); | |
| 326 | + goto exit_reset; | |
| 327 | + } | |
| 328 | + | |
| 329 | + ret = i2c_dw_prepare_clk(dev, true); | |
| 330 | + if (ret) | |
| 331 | + goto exit_reset; | |
| 332 | + | |
| 333 | + if (dev->clk) { | |
| 325 | 334 | u64 clk_khz; |
| 326 | 335 | |
| 327 | 336 | dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; |
| @@ -1420,17 +1420,22 @@ static int mtk_i2c_probe(struct platform_device *pdev) · 1419 unmodified lines | ||
| 1420 | 1420 | if (ret < 0) { |
| 1421 | 1421 | dev_err(&pdev->dev, |
| 1422 | 1422 | "Request I2C IRQ %d fail\n", irq); |
| 1423 | − return ret; | |
| 1423 | + goto err_bulk_unprepare; | |
| 1424 | 1424 | } |
| 1425 | 1425 | |
| 1426 | 1426 | i2c_set_adapdata(&i2c->adap, i2c); |
| 1427 | 1427 | ret = i2c_add_adapter(&i2c->adap); |
| 1428 | 1428 | if (ret) |
| 1429 | − return ret; | |
| 1429 | + goto err_bulk_unprepare; | |
| 1430 | 1430 | |
| 1431 | 1431 | platform_set_drvdata(pdev, i2c); |
| 1432 | 1432 | |
| 1433 | 1433 | return 0; |
| 1434 | + | |
| 1435 | +err_bulk_unprepare: | |
| 1436 | + clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); | |
| 1437 | + | |
| 1438 | + return ret; | |
| 1434 | 1439 | } |
| 1435 | 1440 | |
| 1436 | 1441 | static int mtk_i2c_remove(struct platform_device *pdev) |
| @@ -2372,8 +2372,7 @@ static struct platform_driver npcm_i2c_bus_driver = { · 2371 unmodified lines | ||
| 2372 | 2372 | static int __init npcm_i2c_init(void) |
| 2373 | 2373 | { |
| 2374 | 2374 | npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL); |
| 2375 | − platform_driver_register(&npcm_i2c_bus_driver); | |
| 2376 | − return 0; | |
| 2375 | + return platform_driver_register(&npcm_i2c_bus_driver); | |
| 2377 | 2376 | } |
| 2378 | 2377 | module_init(npcm_i2c_init); |
| 2379 | 2378 | |
| @@ -1006,11 +1006,12 @@ static int bma180_probe(struct i2c_client *client, · 1005 unmodified lines | ||
| 1006 | 1006 | |
| 1007 | 1007 | data->trig->ops = &bma180_trigger_ops; |
| 1008 | 1008 | iio_trigger_set_drvdata(data->trig, indio_dev); |
| 1009 | − indio_dev->trig = iio_trigger_get(data->trig); | |
| 1010 | 1009 | |
| 1011 | 1010 | ret = iio_trigger_register(data->trig); |
| 1012 | 1011 | if (ret) |
| 1013 | 1012 | goto err_trigger_free; |
| 1013 | + | |
| 1014 | + indio_dev->trig = iio_trigger_get(data->trig); | |
| 1014 | 1015 | } |
| 1015 | 1016 | |
| 1016 | 1017 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
| @@ -1554,12 +1554,12 @@ static int kxcjk1013_probe(struct i2c_client *client, · 1553 unmodified lines | ||
| 1554 | 1554 | |
| 1555 | 1555 | data->dready_trig->ops = &kxcjk1013_trigger_ops; |
| 1556 | 1556 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); |
| 1557 | − indio_dev->trig = data->dready_trig; | |
| 1558 | − iio_trigger_get(indio_dev->trig); | |
| 1559 | 1557 | ret = iio_trigger_register(data->dready_trig); |
| 1560 | 1558 | if (ret) |
| 1561 | 1559 | goto err_poweroff; |
| 1562 | 1560 | |
| 1561 | + indio_dev->trig = iio_trigger_get(data->dready_trig); | |
| 1562 | + | |
| 1563 | 1563 | data->motion_trig->ops = &kxcjk1013_trigger_ops; |
| 1564 | 1564 | iio_trigger_set_drvdata(data->motion_trig, indio_dev); |
| 1565 | 1565 | ret = iio_trigger_register(data->motion_trig); |
| @@ -1511,10 +1511,14 @@ static int mma8452_reset(struct i2c_client *client) · 1510 unmodified lines | ||
| 1511 | 1511 | int i; |
| 1512 | 1512 | int ret; |
| 1513 | 1513 | |
| 1514 | − ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2, | |
| 1514 | + /* | |
| 1515 | + * Find on fxls8471, after config reset bit, it reset immediately, | |
| 1516 | + * and will not give ACK, so here do not check the return value. | |
| 1517 | + * The following code will read the reset register, and check whether | |
| 1518 | + * this reset works. | |
| 1519 | + */ | |
| 1520 | + i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2, | |
| 1515 | 1521 | MMA8452_CTRL_REG2_RST); |
| 1516 | − if (ret < 0) | |
| 1517 | − return ret; | |
| 1518 | 1522 | |
| 1519 | 1523 | for (i = 0; i < 10; i++) { |
| 1520 | 1524 | usleep_range(100, 200); |
| @@ -1557,11 +1561,13 @@ static int mma8452_probe(struct i2c_client *client, · 36 unmodified lines | ||
| 1557 | 1561 | mutex_init(&data->lock); |
| 1558 | 1562 | |
| 1559 | 1563 | data->chip_info = device_get_match_data(&client->dev); |
| 1560 | − if (!data->chip_info && id) { | |
| 1561 | − data->chip_info = &mma_chip_info_table[id->driver_data]; | |
| 1562 | − } else { | |
| 1563 | − dev_err(&client->dev, "unknown device model\n"); | |
| 1564 | − return -ENODEV; | |
| 1564 | + if (!data->chip_info) { | |
| 1565 | + if (id) { | |
| 1566 | + data->chip_info = &mma_chip_info_table[id->driver_data]; | |
| 1567 | + } else { | |
| 1568 | + dev_err(&client->dev, "unknown device model\n"); | |
| 1569 | + return -ENODEV; | |
| 1570 | + } | |
| 1565 | 1571 | } |
| 1566 | 1572 | |
| 1567 | 1573 | ret = iio_read_mount_matrix(&client->dev, &data->orientation); |
| @@ -456,8 +456,6 @@ static int mxc4005_probe(struct i2c_client *client, · 455 unmodified lines | ||
| 456 | 456 | |
| 457 | 457 | data->dready_trig->ops = &mxc4005_trigger_ops; |
| 458 | 458 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); |
| 459 | − indio_dev->trig = data->dready_trig; | |
| 460 | − iio_trigger_get(indio_dev->trig); | |
| 461 | 459 | ret = devm_iio_trigger_register(&client->dev, |
| 462 | 460 | data->dready_trig); |
| 463 | 461 | if (ret) { |
| @@ -465,6 +463,8 @@ static int mxc4005_probe(struct i2c_client *client, · 1 unmodified line | ||
| 465 | 463 | "failed to register trigger\n"); |
| 466 | 464 | return ret; |
| 467 | 465 | } |
| 466 | + | |
| 467 | + indio_dev->trig = iio_trigger_get(data->dready_trig); | |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | 470 | return devm_iio_device_register(&client->dev, indio_dev); |
| @@ -322,16 +322,19 @@ static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev) · 321 unmodified lines | ||
| 322 | 322 | |
| 323 | 323 | if (!try_module_get(cl->dev->driver->owner)) { |
| 324 | 324 | mutex_unlock(®istered_clients_lock); |
| 325 | + of_node_put(cln); | |
| 325 | 326 | return ERR_PTR(-ENODEV); |
| 326 | 327 | } |
| 327 | 328 | |
| 328 | 329 | get_device(cl->dev); |
| 329 | 330 | cl->info = info; |
| 330 | 331 | mutex_unlock(®istered_clients_lock); |
| 332 | + of_node_put(cln); | |
| 331 | 333 | return cl; |
| 332 | 334 | } |
| 333 | 335 | |
| 334 | 336 | mutex_unlock(®istered_clients_lock); |
| 337 | + of_node_put(cln); | |
| 335 | 338 | |
| 336 | 339 | return ERR_PTR(-EPROBE_DEFER); |
| 337 | 340 | } |
| @@ -186,6 +186,7 @@ static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev) · 185 unmodified lines | ||
| 186 | 186 | return -EOPNOTSUPP; |
| 187 | 187 | } |
| 188 | 188 | scu = syscon_node_to_regmap(syscon); |
| 189 | + of_node_put(syscon); | |
| 189 | 190 | if (IS_ERR(scu)) { |
| 190 | 191 | dev_warn(data->dev, "Failed to get syscon regmap\n"); |
| 191 | 192 | return -EOPNOTSUPP; |
| @@ -196,6 +196,14 @@ static const struct dmi_system_id axp288_adc_ts_bias_override[] = { · 195 unmodified lines | ||
| 196 | 196 | }, |
| 197 | 197 | .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA, |
| 198 | 198 | }, |
| 199 | + { | |
| 200 | + /* Nuvision Solo 10 Draw */ | |
| 201 | + .matches = { | |
| 202 | + DMI_MATCH(DMI_SYS_VENDOR, "TMAX"), | |
| 203 | + DMI_MATCH(DMI_PRODUCT_NAME, "TM101W610L"), | |
| 204 | + }, | |
| 205 | + .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA, | |
| 206 | + }, | |
| 199 | 207 | {} |
| 200 | 208 | }; |
| 201 | 209 | |
| @@ -334,11 +334,15 @@ static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l · 333 unmodified lines | ||
| 334 | 334 | i = 0; |
| 335 | 335 | device_for_each_child_node(&pdev->dev, fwnode) { |
| 336 | 336 | ret = fwnode_property_read_u32(fwnode, "reg", &channel); |
| 337 | − if (ret) | |
| 337 | + if (ret) { | |
| 338 | + fwnode_handle_put(fwnode); | |
| 338 | 339 | return ret; |
| 340 | + } | |
| 339 | 341 | |
| 340 | − if (channel >= RZG2L_ADC_MAX_CHANNELS) | |
| 342 | + if (channel >= RZG2L_ADC_MAX_CHANNELS) { | |
| 343 | + fwnode_handle_put(fwnode); | |
| 341 | 344 | return -EINVAL; |
| 345 | + } | |
| 342 | 346 | |
| 343 | 347 | chan_array[i].type = IIO_VOLTAGE; |
| 344 | 348 | chan_array[i].indexed = 1; |
| @@ -64,6 +64,7 @@ struct stm32_adc_priv; · 63 unmodified lines | ||
| 64 | 64 | * @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet) |
| 65 | 65 | * @has_syscfg: SYSCFG capability flags |
| 66 | 66 | * @num_irqs: number of interrupt lines |
| 67 | + * @num_adcs: maximum number of ADC instances in the common registers | |
| 67 | 68 | */ |
| 68 | 69 | struct stm32_adc_priv_cfg { |
| 69 | 70 | const struct stm32_adc_common_regs *regs; |
| @@ -71,6 +72,7 @@ struct stm32_adc_priv_cfg { · 1 unmodified line | ||
| 71 | 72 | u32 max_clk_rate_hz; |
| 72 | 73 | unsigned int has_syscfg; |
| 73 | 74 | unsigned int num_irqs; |
| 75 | + unsigned int num_adcs; | |
| 74 | 76 | }; |
| 75 | 77 | |
| 76 | 78 | /** |
| @@ -352,7 +354,7 @@ static void stm32_adc_irq_handler(struct irq_desc *desc) · 275 unmodified lines | ||
| 352 | 354 | * before invoking the interrupt handler (e.g. call ISR only for |
| 353 | 355 | * IRQ-enabled ADCs). |
| 354 | 356 | */ |
| 355 | − for (i = 0; i < priv->cfg->num_irqs; i++) { | |
| 357 | + for (i = 0; i < priv->cfg->num_adcs; i++) { | |
| 356 | 358 | if ((status & priv->cfg->regs->eoc_msk[i] && |
| 357 | 359 | stm32_adc_eoc_enabled(priv, i)) || |
| 358 | 360 | (status & priv->cfg->regs->ovr_msk[i])) |
| @@ -792,6 +794,7 @@ static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = { · 433 unmodified lines | ||
| 792 | 794 | .clk_sel = stm32f4_adc_clk_sel, |
| 793 | 795 | .max_clk_rate_hz = 36000000, |
| 794 | 796 | .num_irqs = 1, |
| 797 | + .num_adcs = 3, | |
| 795 | 798 | }; |
| 796 | 799 | |
| 797 | 800 | static const struct stm32_adc_priv_cfg stm32h7_adc_priv_cfg = { |
| @@ -800,14 +803,16 @@ static const struct stm32_adc_priv_cfg stm32h7_adc_priv_cfg = { · 2 unmodified lines | ||
| 800 | 803 | .max_clk_rate_hz = 36000000, |
| 801 | 804 | .has_syscfg = HAS_VBOOSTER, |
| 802 | 805 | .num_irqs = 1, |
| 806 | + .num_adcs = 2, | |
| 803 | 807 | }; |
| 804 | 808 | |
| 805 | 809 | static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = { |
| 806 | 810 | .regs = &stm32h7_adc_common_regs, |
| 807 | 811 | .clk_sel = stm32h7_adc_clk_sel, |
| 808 | − .max_clk_rate_hz = 40000000, | |
| 812 | + .max_clk_rate_hz = 36000000, | |
| 809 | 813 | .has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD, |
| 810 | 814 | .num_irqs = 2, |
| 815 | + .num_adcs = 2, | |
| 811 | 816 | }; |
| 812 | 817 | |
| 813 | 818 | static const struct of_device_id stm32_adc_of_match[] = { |
| @@ -1365,7 +1365,7 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev, · 1364 unmodified lines | ||
| 1365 | 1365 | else |
| 1366 | 1366 | ret = -EINVAL; |
| 1367 | 1367 | |
| 1368 | − if (mask == IIO_CHAN_INFO_PROCESSED && adc->vrefint.vrefint_cal) | |
| 1368 | + if (mask == IIO_CHAN_INFO_PROCESSED) | |
| 1369 | 1369 | *val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val; |
| 1370 | 1370 | |
| 1371 | 1371 | iio_device_release_direct_mode(indio_dev); |
| @@ -1407,7 +1407,6 @@ static irqreturn_t stm32_adc_threaded_isr(int irq, void *data) · 35 unmodified lines | ||
| 1407 | 1407 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1408 | 1408 | const struct stm32_adc_regspec *regs = adc->cfg->regs; |
| 1409 | 1409 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); |
| 1410 | − u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg); | |
| 1411 | 1410 | |
| 1412 | 1411 | /* Check ovr status right now, as ovr mask should be already disabled */ |
| 1413 | 1412 | if (status & regs->isr_ovr.mask) { |
| @@ -1422,11 +1421,6 @@ static irqreturn_t stm32_adc_threaded_isr(int irq, void *data) · 8 unmodified lines | ||
| 1422 | 1421 | return IRQ_HANDLED; |
| 1423 | 1422 | } |
| 1424 | 1423 | |
| 1425 | − if (!(status & mask)) | |
| 1426 | − dev_err_ratelimited(&indio_dev->dev, | |
| 1427 | − "Unexpected IRQ: IER=0x%08x, ISR=0x%08x\n", | |
| 1428 | − mask, status); | |
| 1429 | − | |
| 1430 | 1424 | return IRQ_NONE; |
| 1431 | 1425 | } |
| 1432 | 1426 | |
| @@ -1436,10 +1430,6 @@ static irqreturn_t stm32_adc_isr(int irq, void *data) · 3 unmodified lines | ||
| 1436 | 1430 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1437 | 1431 | const struct stm32_adc_regspec *regs = adc->cfg->regs; |
| 1438 | 1432 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); |
| 1439 | − u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg); | |
| 1440 | − | |
| 1441 | − if (!(status & mask)) | |
| 1442 | − return IRQ_WAKE_THREAD; | |
| 1443 | 1433 | |
| 1444 | 1434 | if (status & regs->isr_ovr.mask) { |
| 1445 | 1435 | /* |
| @@ -1979,10 +1969,10 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n · 533 unmodified lines | ||
| 1979 | 1969 | |
| 1980 | 1970 | for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { |
| 1981 | 1971 | if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) { |
| 1982 | − adc->int_ch[i] = chan; | |
| 1983 | − | |
| 1984 | − if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) | |
| 1985 | − continue; | |
| 1972 | + if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) { | |
| 1973 | + adc->int_ch[i] = chan; | |
| 1974 | + break; | |
| 1975 | + } | |
| 1986 | 1976 | |
| 1987 | 1977 | /* Get calibration data for vrefint channel */ |
| 1988 | 1978 | ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint); |
| @@ -1990,10 +1980,15 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n · 1 unmodified line | ||
| 1990 | 1980 | return dev_err_probe(indio_dev->dev.parent, ret, |
| 1991 | 1981 | "nvmem access error\n"); |
| 1992 | 1982 | } |
| 1993 | − if (ret == -ENOENT) | |
| 1994 | − dev_dbg(&indio_dev->dev, "vrefint calibration not found\n"); | |
| 1995 | − else | |
| 1996 | − adc->vrefint.vrefint_cal = vrefint; | |
| 1983 | + if (ret == -ENOENT) { | |
| 1984 | + dev_dbg(&indio_dev->dev, "vrefint calibration not found. Skip vrefint channel\n"); | |
| 1985 | + return ret; | |
| 1986 | + } else if (!vrefint) { | |
| 1987 | + dev_dbg(&indio_dev->dev, "Null vrefint calibration value. Skip vrefint channel\n"); | |
| 1988 | + return -ENOENT; | |
| 1989 | + } | |
| 1990 | + adc->int_ch[i] = chan; | |
| 1991 | + adc->vrefint.vrefint_cal = vrefint; | |
| 1997 | 1992 | } |
| 1998 | 1993 | } |
| 1999 | 1994 | |
| @@ -2030,7 +2025,9 @@ static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev, · 30 unmodified lines | ||
| 2030 | 2025 | } |
| 2031 | 2026 | strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ); |
| 2032 | 2027 | ret = stm32_adc_populate_int_ch(indio_dev, name, val); |
| 2033 | − if (ret) | |
| 2028 | + if (ret == -ENOENT) | |
| 2029 | + continue; | |
| 2030 | + else if (ret) | |
| 2034 | 2031 | goto err; |
| 2035 | 2032 | } else if (ret != -EINVAL) { |
| 2036 | 2033 | dev_err(&indio_dev->dev, "Invalid label %d\n", ret); |
| @@ -739,7 +739,7 @@ static int ads131e08_alloc_channels(struct iio_dev *indio_dev) · 738 unmodified lines | ||
| 739 | 739 | device_for_each_child_node(dev, node) { |
| 740 | 740 | ret = fwnode_property_read_u32(node, "reg", &channel); |
| 741 | 741 | if (ret) |
| 742 | − return ret; | |
| 742 | + goto err_child_out; | |
| 743 | 743 | |
| 744 | 744 | ret = fwnode_property_read_u32(node, "ti,gain", &tmp); |
| 745 | 745 | if (ret) { |
| @@ -747,7 +747,7 @@ static int ads131e08_alloc_channels(struct iio_dev *indio_dev) · 1 unmodified line | ||
| 747 | 747 | } else { |
| 748 | 748 | ret = ads131e08_pga_gain_to_field_value(st, tmp); |
| 749 | 749 | if (ret < 0) |
| 750 | − return ret; | |
| 750 | + goto err_child_out; | |
| 751 | 751 | |
| 752 | 752 | channel_config[i].pga_gain = tmp; |
| 753 | 753 | } |
| @@ -758,7 +758,7 @@ static int ads131e08_alloc_channels(struct iio_dev *indio_dev) · 4 unmodified lines | ||
| 758 | 758 | } else { |
| 759 | 759 | ret = ads131e08_validate_channel_mux(st, tmp); |
| 760 | 760 | if (ret) |
| 761 | − return ret; | |
| 761 | + goto err_child_out; | |
| 762 | 762 | |
| 763 | 763 | channel_config[i].mux = tmp; |
| 764 | 764 | } |
| @@ -784,6 +784,10 @@ static int ads131e08_alloc_channels(struct iio_dev *indio_dev) · 19 unmodified lines | ||
| 784 | 784 | st->channel_config = channel_config; |
| 785 | 785 | |
| 786 | 786 | return 0; |
| 787 | + | |
| 788 | +err_child_out: | |
| 789 | + fwnode_handle_put(node); | |
| 790 | + return ret; | |
| 787 | 791 | } |
| 788 | 792 | |
| 789 | 793 | static void ads131e08_regulator_disable(void *data) |
| @@ -1409,7 +1409,7 @@ static int ams_probe(struct platform_device *pdev) · 1408 unmodified lines | ||
| 1409 | 1409 | |
| 1410 | 1410 | irq = platform_get_irq(pdev, 0); |
| 1411 | 1411 | if (irq < 0) |
| 1412 | − return ret; | |
| 1412 | + return irq; | |
| 1413 | 1413 | |
| 1414 | 1414 | ret = devm_request_irq(&pdev->dev, irq, &ams_irq, 0, "ams-irq", |
| 1415 | 1415 | indio_dev); |
| @@ -277,7 +277,7 @@ static int rescale_configure_channel(struct device *dev, · 276 unmodified lines | ||
| 277 | 277 | chan->ext_info = rescale->ext_info; |
| 278 | 278 | chan->type = rescale->cfg->type; |
| 279 | 279 | |
| 280 | − if (iio_channel_has_info(schan, IIO_CHAN_INFO_RAW) || | |
| 280 | + if (iio_channel_has_info(schan, IIO_CHAN_INFO_RAW) && | |
| 281 | 281 | iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) { |
| 282 | 282 | dev_info(dev, "using raw+scale source channel\n"); |
| 283 | 283 | } else if (iio_channel_has_info(schan, IIO_CHAN_INFO_PROCESSED)) { |
| @@ -499,11 +499,11 @@ static int ccs811_probe(struct i2c_client *client, · 498 unmodified lines | ||
| 499 | 499 | |
| 500 | 500 | data->drdy_trig->ops = &ccs811_trigger_ops; |
| 501 | 501 | iio_trigger_set_drvdata(data->drdy_trig, indio_dev); |
| 502 | − indio_dev->trig = data->drdy_trig; | |
| 503 | − iio_trigger_get(indio_dev->trig); | |
| 504 | 502 | ret = iio_trigger_register(data->drdy_trig); |
| 505 | 503 | if (ret) |
| 506 | 504 | goto err_poweroff; |
| 505 | + | |
| 506 | + indio_dev->trig = iio_trigger_get(data->drdy_trig); | |
| 507 | 507 | } |
| 508 | 508 | |
| 509 | 509 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
| @@ -700,8 +700,10 @@ static int admv1014_init(struct admv1014_state *st) · 699 unmodified lines | ||
| 700 | 700 | ADMV1014_DET_EN_MSK; |
| 701 | 701 | |
| 702 | 702 | enable_reg = FIELD_PREP(ADMV1014_P1DB_COMPENSATION_MSK, st->p1db_comp ? 3 : 0) | |
| 703 | − FIELD_PREP(ADMV1014_IF_AMP_PD_MSK, !(st->input_mode)) | | |
| 704 | − FIELD_PREP(ADMV1014_BB_AMP_PD_MSK, st->input_mode) | | |
| 703 | + FIELD_PREP(ADMV1014_IF_AMP_PD_MSK, | |
| 704 | + (st->input_mode == ADMV1014_IF_MODE) ? 0 : 1) | | |
| 705 | + FIELD_PREP(ADMV1014_BB_AMP_PD_MSK, | |
| 706 | + (st->input_mode == ADMV1014_IF_MODE) ? 1 : 0) | | |
| 705 | 707 | FIELD_PREP(ADMV1014_DET_EN_MSK, st->det_en); |
| 706 | 708 | |
| 707 | 709 | return __admv1014_spi_update_bits(st, ADMV1014_REG_ENABLE, enable_reg_msk, enable_reg); |
| @@ -875,6 +875,7 @@ static int mpu3050_power_up(struct mpu3050 *mpu3050) · 874 unmodified lines | ||
| 875 | 875 | ret = regmap_update_bits(mpu3050->map, MPU3050_PWR_MGM, |
| 876 | 876 | MPU3050_PWR_MGM_SLEEP, 0); |
| 877 | 877 | if (ret) { |
| 878 | + regulator_bulk_disable(ARRAY_SIZE(mpu3050->regs), mpu3050->regs); | |
| 878 | 879 | dev_err(mpu3050->dev, "error setting power mode\n"); |
| 879 | 880 | return ret; |
| 880 | 881 | } |
| @@ -135,9 +135,12 @@ int hts221_allocate_trigger(struct iio_dev *iio_dev) · 134 unmodified lines | ||
| 135 | 135 | |
| 136 | 136 | iio_trigger_set_drvdata(hw->trig, iio_dev); |
| 137 | 137 | hw->trig->ops = &hts221_trigger_ops; |
| 138 | + | |
| 139 | + err = devm_iio_trigger_register(hw->dev, hw->trig); | |
| 140 | + | |
| 138 | 141 | iio_dev->trig = iio_trigger_get(hw->trig); |
| 139 | 142 | |
| 140 | − return devm_iio_trigger_register(hw->dev, hw->trig); | |
| 143 | + return err; | |
| 141 | 144 | } |
| 142 | 145 | |
| 143 | 146 | static int hts221_buffer_preenable(struct iio_dev *iio_dev) |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include "inv_icm42600_buffer.h" |
| 18 | 18 | |
| 19 | 19 | enum inv_icm42600_chip { |
| 20 | + INV_CHIP_INVALID, | |
| 20 | 21 | INV_CHIP_ICM42600, |
| 21 | 22 | INV_CHIP_ICM42602, |
| 22 | 23 | INV_CHIP_ICM42605, |
| @@ -565,7 +565,7 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, · 564 unmodified lines | ||
| 565 | 565 | bool open_drain; |
| 566 | 566 | int ret; |
| 567 | 567 | |
| 568 | − if (chip < 0 || chip >= INV_CHIP_NB) { | |
| 568 | + if (chip <= INV_CHIP_INVALID || chip >= INV_CHIP_NB) { | |
| 569 | 569 | dev_err(dev, "invalid chip = %d\n", chip); |
| 570 | 570 | return -ENODEV; |
| 571 | 571 | } |
| @@ -639,7 +639,7 @@ static int yas532_get_calibration_data(struct yas5xx *yas5xx) · 638 unmodified lines | ||
| 639 | 639 | dev_dbg(yas5xx->dev, "calibration data: %*ph\n", 14, data); |
| 640 | 640 | |
| 641 | 641 | /* Sanity check, is this all zeroes? */ |
| 642 | − if (memchr_inv(data, 0x00, 13)) { | |
| 642 | + if (memchr_inv(data, 0x00, 13) == NULL) { | |
| 643 | 643 | if (!(data[13] & BIT(7))) |
| 644 | 644 | dev_warn(yas5xx->dev, "calibration is blank!\n"); |
| 645 | 645 | } |
| @@ -885,6 +885,9 @@ sx9324_get_default_reg(struct device *dev, int idx, · 884 unmodified lines | ||
| 885 | 885 | break; |
| 886 | 886 | ret = device_property_read_u32_array(dev, prop, pin_defs, |
| 887 | 887 | ARRAY_SIZE(pin_defs)); |
| 888 | + if (ret) | |
| 889 | + break; | |
| 890 | + | |
| 888 | 891 | for (pin = 0; pin < SX9324_NUM_PINS; pin++) |
| 889 | 892 | raw |= (pin_defs[pin] << (2 * pin)) & |
| 890 | 893 | SX9324_REG_AFE_PH0_PIN_MASK(pin); |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | # Keep in alphabetical order |
| 7 | 7 | config IIO_RESCALE_KUNIT_TEST |
| 8 | 8 | bool "Test IIO rescale conversion functions" |
| 9 | − depends on KUNIT=y && !IIO_RESCALE | |
| 9 | + depends on KUNIT=y && IIO_RESCALE=y | |
| 10 | 10 | default KUNIT_ALL_TESTS |
| 11 | 11 | help |
| 12 | 12 | If you want to run tests on the iio-rescale code say Y here. |
| @@ -4,6 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | # |
| 5 | 5 | |
| 6 | 6 | # Keep in alphabetical order |
| 7 | −obj-$(CONFIG_IIO_RESCALE_KUNIT_TEST) += iio-test-rescale.o ../afe/iio-rescale.o | |
| 7 | +obj-$(CONFIG_IIO_RESCALE_KUNIT_TEST) += iio-test-rescale.o | |
| 8 | 8 | obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o |
| 9 | 9 | CFLAGS_iio-test-format.o += $(DISABLE_STRUCTLEAK_PLUGIN) |
| @@ -190,6 +190,7 @@ static int iio_sysfs_trigger_remove(int id) · 189 unmodified lines | ||
| 190 | 190 | } |
| 191 | 191 | |
| 192 | 192 | iio_trigger_unregister(t->trig); |
| 193 | + irq_work_sync(&t->work); | |
| 193 | 194 | iio_trigger_free(t->trig); |
| 194 | 195 | |
| 195 | 196 | list_del(&t->l); |
| @@ -987,7 +987,7 @@ static const struct of_device_id ipmmu_of_ids[] = { · 986 unmodified lines | ||
| 987 | 987 | .compatible = "renesas,ipmmu-r8a779a0", |
| 988 | 988 | .data = &ipmmu_features_rcar_gen4, |
| 989 | 989 | }, { |
| 990 | − .compatible = "renesas,rcar-gen4-ipmmu", | |
| 990 | + .compatible = "renesas,rcar-gen4-ipmmu-vmsa", | |
| 991 | 991 | .data = &ipmmu_features_rcar_gen4, |
| 992 | 992 | }, { |
| 993 | 993 | /* Terminator */ |
| @@ -298,7 +298,7 @@ config XTENSA_MX · 297 unmodified lines | ||
| 298 | 298 | |
| 299 | 299 | config XILINX_INTC |
| 300 | 300 | bool "Xilinx Interrupt Controller IP" |
| 301 | − depends on MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP | |
| 301 | + depends on OF | |
| 302 | 302 | select IRQ_DOMAIN |
| 303 | 303 | help |
| 304 | 304 | Support for the Xilinx Interrupt Controller IP core. |
| @@ -1035,6 +1035,7 @@ static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff) · 1034 unmodified lines | ||
| 1035 | 1035 | continue; |
| 1036 | 1036 | |
| 1037 | 1037 | cpu = of_cpu_node_to_id(cpu_node); |
| 1038 | + of_node_put(cpu_node); | |
| 1038 | 1039 | if (WARN_ON(cpu < 0)) |
| 1039 | 1040 | continue; |
| 1040 | 1041 | |
| @@ -1143,6 +1144,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p · 102 unmodified lines | ||
| 1143 | 1144 | for_each_child_of_node(affs, chld) |
| 1144 | 1145 | build_fiq_affinity(irqc, chld); |
| 1145 | 1146 | } |
| 1147 | + of_node_put(affs); | |
| 1146 | 1148 | |
| 1147 | 1149 | set_handle_irq(aic_handle_irq); |
| 1148 | 1150 | set_handle_fiq(aic_handle_fiq); |
| @@ -57,6 +57,7 @@ realview_gic_of_init(struct device_node *node, struct device_node *parent) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | /* The PB11MPCore GIC needs to be configured in the syscon */ |
| 59 | 59 | map = syscon_node_to_regmap(np); |
| 60 | + of_node_put(np); | |
| 60 | 61 | if (!IS_ERR(map)) { |
| 61 | 62 | /* new irq mode with no DCC */ |
| 62 | 63 | regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, |
| @@ -1932,7 +1932,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) · 1931 unmodified lines | ||
| 1932 | 1932 | |
| 1933 | 1933 | gic_data.ppi_descs = kcalloc(gic_data.ppi_nr, sizeof(*gic_data.ppi_descs), GFP_KERNEL); |
| 1934 | 1934 | if (!gic_data.ppi_descs) |
| 1935 | − return; | |
| 1935 | + goto out_put_node; | |
| 1936 | 1936 | |
| 1937 | 1937 | nr_parts = of_get_child_count(parts_node); |
| 1938 | 1938 | |
| @@ -1973,12 +1973,15 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) · 34 unmodified lines | ||
| 1973 | 1973 | continue; |
| 1974 | 1974 | |
| 1975 | 1975 | cpu = of_cpu_node_to_id(cpu_node); |
| 1976 | − if (WARN_ON(cpu < 0)) | |
| 1976 | + if (WARN_ON(cpu < 0)) { | |
| 1977 | + of_node_put(cpu_node); | |
| 1977 | 1978 | continue; |
| 1979 | + } | |
| 1978 | 1980 | |
| 1979 | 1981 | pr_cont("%pOF[%d] ", cpu_node, cpu); |
| 1980 | 1982 | |
| 1981 | 1983 | cpumask_set_cpu(cpu, &part->mask); |
| 1984 | + of_node_put(cpu_node); | |
| 1982 | 1985 | } |
| 1983 | 1986 | |
| 1984 | 1987 | pr_cont("}\n"); |
| @@ -39,6 +39,12 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define LIOINTC_ERRATA_IRQ 10 |
| 41 | 41 | |
| 42 | +#if defined(CONFIG_MIPS) | |
| 43 | +#define liointc_core_id get_ebase_cpunum() | |
| 44 | +#else | |
| 45 | +#define liointc_core_id get_csr_cpuid() | |
| 46 | +#endif | |
| 47 | + | |
| 42 | 48 | struct liointc_handler_data { |
| 43 | 49 | struct liointc_priv *priv; |
| 44 | 50 | u32 parent_int_map; |
| @@ -57,7 +63,7 @@ static void liointc_chained_handle_irq(struct irq_desc *desc) · 12 unmodified lines | ||
| 57 | 63 | struct liointc_handler_data *handler = irq_desc_get_handler_data(desc); |
| 58 | 64 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 59 | 65 | struct irq_chip_generic *gc = handler->priv->gc; |
| 60 | − int core = cpu_logical_map(smp_processor_id()) % LIOINTC_NUM_CORES; | |
| 66 | + int core = liointc_core_id % LIOINTC_NUM_CORES; | |
| 61 | 67 | u32 pending; |
| 62 | 68 | |
| 63 | 69 | chained_irq_enter(chip, desc); |
| @@ -134,9 +134,9 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do · 133 unmodified lines | ||
| 134 | 134 | if (!cpu_ictl) |
| 135 | 135 | return -EINVAL; |
| 136 | 136 | ret = of_property_read_u32(cpu_ictl, "#interrupt-cells", &tmp); |
| 137 | + of_node_put(cpu_ictl); | |
| 137 | 138 | if (ret || tmp != 1) |
| 138 | 139 | return -EINVAL; |
| 139 | − of_node_put(cpu_ictl); | |
| 140 | 140 | |
| 141 | 141 | cpu_int = be32_to_cpup(imap + 2); |
| 142 | 142 | if (cpu_int > 7 || cpu_int < 2) |
| @@ -237,6 +237,7 @@ static const struct of_device_id uniphier_aidet_match[] = { · 236 unmodified lines | ||
| 237 | 237 | { .compatible = "socionext,uniphier-ld11-aidet" }, |
| 238 | 238 | { .compatible = "socionext,uniphier-ld20-aidet" }, |
| 239 | 239 | { .compatible = "socionext,uniphier-pxs3-aidet" }, |
| 240 | + { .compatible = "socionext,uniphier-nx1-aidet" }, | |
| 240 | 241 | { /* sentinel */ } |
| 241 | 242 | }; |
| 242 | 243 | |
| @@ -272,6 +272,7 @@ struct dm_io { · 271 unmodified lines | ||
| 272 | 272 | atomic_t io_count; |
| 273 | 273 | struct mapped_device *md; |
| 274 | 274 | |
| 275 | + struct bio *split_bio; | |
| 275 | 276 | /* The three fields represent mapped part of original bio */ |
| 276 | 277 | struct bio *orig_bio; |
| 277 | 278 | unsigned int sector_offset; /* offset to end of orig_bio */ |
| @@ -1400,7 +1400,7 @@ static void start_worker(struct era *era) · 1399 unmodified lines | ||
| 1400 | 1400 | static void stop_worker(struct era *era) |
| 1401 | 1401 | { |
| 1402 | 1402 | atomic_set(&era->suspended, 1); |
| 1403 | − flush_workqueue(era->wq); | |
| 1403 | + drain_workqueue(era->wq); | |
| 1404 | 1404 | } |
| 1405 | 1405 | |
| 1406 | 1406 | /*---------------------------------------------------------------- |
| @@ -1570,6 +1570,12 @@ static void era_postsuspend(struct dm_target *ti) · 163 unmodified lines | ||
| 1570 | 1570 | } |
| 1571 | 1571 | |
| 1572 | 1572 | stop_worker(era); |
| 1573 | + | |
| 1574 | + r = metadata_commit(era->md); | |
| 1575 | + if (r) { | |
| 1576 | + DMERR("%s: metadata_commit failed", __func__); | |
| 1577 | + /* FIXME: fail mode */ | |
| 1578 | + } | |
| 1573 | 1579 | } |
| 1574 | 1580 | |
| 1575 | 1581 | static int era_preresume(struct dm_target *ti) |
| @@ -415,8 +415,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, · 414 unmodified lines | ||
| 415 | 415 | /* |
| 416 | 416 | * Work out how many "unsigned long"s we need to hold the bitset. |
| 417 | 417 | */ |
| 418 | − bitset_size = dm_round_up(region_count, | |
| 419 | − sizeof(*lc->clean_bits) << BYTE_SHIFT); | |
| 418 | + bitset_size = dm_round_up(region_count, BITS_PER_LONG); | |
| 420 | 419 | bitset_size >>= BYTE_SHIFT; |
| 421 | 420 | |
| 422 | 421 | lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits); |
| @@ -616,7 +615,7 @@ static int disk_resume(struct dm_dirty_log *log) · 193 unmodified lines | ||
| 616 | 615 | log_clear_bit(lc, lc->clean_bits, i); |
| 617 | 616 | |
| 618 | 617 | /* clear any old bits -- device has shrunk */ |
| 619 | − for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++) | |
| 618 | + for (i = lc->region_count; i % BITS_PER_LONG; i++) | |
| 620 | 619 | log_clear_bit(lc, lc->clean_bits, i); |
| 621 | 620 | |
| 622 | 621 | /* copy clean across to sync */ |
| @@ -3725,7 +3725,7 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv, · 3724 unmodified lines | ||
| 3725 | 3725 | if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) { |
| 3726 | 3726 | if (mddev->sync_thread) { |
| 3727 | 3727 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 3728 | − md_reap_sync_thread(mddev, false); | |
| 3728 | + md_reap_sync_thread(mddev); | |
| 3729 | 3729 | } |
| 3730 | 3730 | } else if (decipher_sync_action(mddev, mddev->recovery) != st_idle) |
| 3731 | 3731 | return -EBUSY; |
| @@ -555,6 +555,10 @@ static void dm_start_io_acct(struct dm_io *io, struct bio *clone) · 554 unmodified lines | ||
| 555 | 555 | unsigned long flags; |
| 556 | 556 | /* Can afford locking given DM_TIO_IS_DUPLICATE_BIO */ |
| 557 | 557 | spin_lock_irqsave(&io->lock, flags); |
| 558 | + if (dm_io_flagged(io, DM_IO_ACCOUNTED)) { | |
| 559 | + spin_unlock_irqrestore(&io->lock, flags); | |
| 560 | + return; | |
| 561 | + } | |
| 558 | 562 | dm_io_set_flag(io, DM_IO_ACCOUNTED); |
| 559 | 563 | spin_unlock_irqrestore(&io->lock, flags); |
| 560 | 564 | } |
| @@ -590,6 +594,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio) · 29 unmodified lines | ||
| 590 | 594 | atomic_set(&io->io_count, 2); |
| 591 | 595 | this_cpu_inc(*md->pending_io); |
| 592 | 596 | io->orig_bio = bio; |
| 597 | + io->split_bio = NULL; | |
| 593 | 598 | io->md = md; |
| 594 | 599 | spin_lock_init(&io->lock); |
| 595 | 600 | io->start_time = jiffies; |
| @@ -711,18 +716,18 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU) · 115 unmodified lines | ||
| 711 | 716 | } |
| 712 | 717 | |
| 713 | 718 | static inline struct dm_table *dm_get_live_table_bio(struct mapped_device *md, |
| 714 | − int *srcu_idx, struct bio *bio) | |
| 719 | + int *srcu_idx, unsigned bio_opf) | |
| 715 | 720 | { |
| 716 | − if (bio->bi_opf & REQ_NOWAIT) | |
| 721 | + if (bio_opf & REQ_NOWAIT) | |
| 717 | 722 | return dm_get_live_table_fast(md); |
| 718 | 723 | else |
| 719 | 724 | return dm_get_live_table(md, srcu_idx); |
| 720 | 725 | } |
| 721 | 726 | |
| 722 | 727 | static inline void dm_put_live_table_bio(struct mapped_device *md, int srcu_idx, |
| 723 | − struct bio *bio) | |
| 728 | + unsigned bio_opf) | |
| 724 | 729 | { |
| 725 | − if (bio->bi_opf & REQ_NOWAIT) | |
| 730 | + if (bio_opf & REQ_NOWAIT) | |
| 726 | 731 | dm_put_live_table_fast(md); |
| 727 | 732 | else |
| 728 | 733 | dm_put_live_table(md, srcu_idx); |
| @@ -883,7 +888,7 @@ static void dm_io_complete(struct dm_io *io) · 154 unmodified lines | ||
| 883 | 888 | { |
| 884 | 889 | blk_status_t io_error; |
| 885 | 890 | struct mapped_device *md = io->md; |
| 886 | − struct bio *bio = io->orig_bio; | |
| 891 | + struct bio *bio = io->split_bio ? io->split_bio : io->orig_bio; | |
| 887 | 892 | |
| 888 | 893 | if (io->status == BLK_STS_DM_REQUEUE) { |
| 889 | 894 | unsigned long flags; |
| @@ -935,9 +940,11 @@ static void dm_io_complete(struct dm_io *io) · 45 unmodified lines | ||
| 935 | 940 | if (io_error == BLK_STS_AGAIN) { |
| 936 | 941 | /* io_uring doesn't handle BLK_STS_AGAIN (yet) */ |
| 937 | 942 | queue_io(md, bio); |
| 943 | + return; | |
| 938 | 944 | } |
| 939 | 945 | } |
| 940 | − return; | |
| 946 | + if (io_error == BLK_STS_DM_REQUEUE) | |
| 947 | + return; | |
| 941 | 948 | } |
| 942 | 949 | |
| 943 | 950 | if (bio_is_flush_with_data(bio)) { |
| @@ -1609,7 +1616,12 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci) · 665 unmodified lines | ||
| 1609 | 1616 | ti = dm_table_find_target(ci->map, ci->sector); |
| 1610 | 1617 | if (unlikely(!ti)) |
| 1611 | 1618 | return BLK_STS_IOERR; |
| 1612 | − else if (unlikely(ci->is_abnormal_io)) | |
| 1619 | + | |
| 1620 | + if (unlikely((ci->bio->bi_opf & REQ_NOWAIT) != 0) && | |
| 1621 | + unlikely(!dm_target_supports_nowait(ti->type))) | |
| 1622 | + return BLK_STS_NOTSUPP; | |
| 1623 | + | |
| 1624 | + if (unlikely(ci->is_abnormal_io)) | |
| 1613 | 1625 | return __process_abnormal_io(ci, ti); |
| 1614 | 1626 | |
| 1615 | 1627 | /* |
| @@ -1682,9 +1694,11 @@ static void dm_split_and_process_bio(struct mapped_device *md, · 66 unmodified lines | ||
| 1682 | 1694 | * Remainder must be passed to submit_bio_noacct() so it gets handled |
| 1683 | 1695 | * *after* bios already submitted have been completely processed. |
| 1684 | 1696 | */ |
| 1685 | − bio_trim(bio, io->sectors, ci.sector_count); | |
| 1686 | − trace_block_split(bio, bio->bi_iter.bi_sector); | |
| 1687 | − bio_inc_remaining(bio); | |
| 1697 | + WARN_ON_ONCE(!dm_io_flagged(io, DM_IO_WAS_SPLIT)); | |
| 1698 | + io->split_bio = bio_split(bio, io->sectors, GFP_NOIO, | |
| 1699 | + &md->queue->bio_split); | |
| 1700 | + bio_chain(io->split_bio, bio); | |
| 1701 | + trace_block_split(io->split_bio, bio->bi_iter.bi_sector); | |
| 1688 | 1702 | submit_bio_noacct(bio); |
| 1689 | 1703 | out: |
| 1690 | 1704 | /* |
| @@ -1711,8 +1725,9 @@ static void dm_submit_bio(struct bio *bio) · 20 unmodified lines | ||
| 1711 | 1725 | struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; |
| 1712 | 1726 | int srcu_idx; |
| 1713 | 1727 | struct dm_table *map; |
| 1728 | + unsigned bio_opf = bio->bi_opf; | |
| 1714 | 1729 | |
| 1715 | − map = dm_get_live_table_bio(md, &srcu_idx, bio); | |
| 1730 | + map = dm_get_live_table_bio(md, &srcu_idx, bio_opf); | |
| 1716 | 1731 | |
| 1717 | 1732 | /* If suspended, or map not yet available, queue this IO for later */ |
| 1718 | 1733 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || |
| @@ -1728,7 +1743,7 @@ static void dm_submit_bio(struct bio *bio) · 9 unmodified lines | ||
| 1728 | 1743 | |
| 1729 | 1744 | dm_split_and_process_bio(md, map, bio); |
| 1730 | 1745 | out: |
| 1731 | − dm_put_live_table_bio(md, srcu_idx, bio); | |
| 1746 | + dm_put_live_table_bio(md, srcu_idx, bio_opf); | |
| 1732 | 1747 | } |
| 1733 | 1748 | |
| 1734 | 1749 | static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob, |
| @@ -4831,7 +4831,7 @@ action_store(struct mddev *mddev, const char *page, size_t len) · 4830 unmodified lines | ||
| 4831 | 4831 | flush_workqueue(md_misc_wq); |
| 4832 | 4832 | if (mddev->sync_thread) { |
| 4833 | 4833 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 4834 | − md_reap_sync_thread(mddev, true); | |
| 4834 | + md_reap_sync_thread(mddev); | |
| 4835 | 4835 | } |
| 4836 | 4836 | mddev_unlock(mddev); |
| 4837 | 4837 | } |
| @@ -6197,7 +6197,7 @@ static void __md_stop_writes(struct mddev *mddev) · 1359 unmodified lines | ||
| 6197 | 6197 | flush_workqueue(md_misc_wq); |
| 6198 | 6198 | if (mddev->sync_thread) { |
| 6199 | 6199 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 6200 | − md_reap_sync_thread(mddev, true); | |
| 6200 | + md_reap_sync_thread(mddev); | |
| 6201 | 6201 | } |
| 6202 | 6202 | |
| 6203 | 6203 | del_timer_sync(&mddev->safemode_timer); |
| @@ -9303,7 +9303,7 @@ void md_check_recovery(struct mddev *mddev) · 3099 unmodified lines | ||
| 9303 | 9303 | * ->spare_active and clear saved_raid_disk |
| 9304 | 9304 | */ |
| 9305 | 9305 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 9306 | − md_reap_sync_thread(mddev, true); | |
| 9306 | + md_reap_sync_thread(mddev); | |
| 9307 | 9307 | clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); |
| 9308 | 9308 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 9309 | 9309 | clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags); |
| @@ -9338,7 +9338,7 @@ void md_check_recovery(struct mddev *mddev) · 28 unmodified lines | ||
| 9338 | 9338 | goto unlock; |
| 9339 | 9339 | } |
| 9340 | 9340 | if (mddev->sync_thread) { |
| 9341 | − md_reap_sync_thread(mddev, true); | |
| 9341 | + md_reap_sync_thread(mddev); | |
| 9342 | 9342 | goto unlock; |
| 9343 | 9343 | } |
| 9344 | 9344 | /* Set RUNNING before clearing NEEDED to avoid |
| @@ -9411,18 +9411,14 @@ void md_check_recovery(struct mddev *mddev) · 66 unmodified lines | ||
| 9411 | 9411 | } |
| 9412 | 9412 | EXPORT_SYMBOL(md_check_recovery); |
| 9413 | 9413 | |
| 9414 | −void md_reap_sync_thread(struct mddev *mddev, bool reconfig_mutex_held) | |
| 9414 | +void md_reap_sync_thread(struct mddev *mddev) | |
| 9415 | 9415 | { |
| 9416 | 9416 | struct md_rdev *rdev; |
| 9417 | 9417 | sector_t old_dev_sectors = mddev->dev_sectors; |
| 9418 | 9418 | bool is_reshaped = false; |
| 9419 | 9419 | |
| 9420 | − if (reconfig_mutex_held) | |
| 9421 | − mddev_unlock(mddev); | |
| 9422 | 9420 | /* resync has finished, collect result */ |
| 9423 | 9421 | md_unregister_thread(&mddev->sync_thread); |
| 9424 | − if (reconfig_mutex_held) | |
| 9425 | − mddev_lock_nointr(mddev); | |
| 9426 | 9422 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
| 9427 | 9423 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && |
| 9428 | 9424 | mddev->degraded != mddev->raid_disks) { |
| @@ -719,7 +719,7 @@ extern struct md_thread *md_register_thread( · 718 unmodified lines | ||
| 719 | 719 | extern void md_unregister_thread(struct md_thread **threadp); |
| 720 | 720 | extern void md_wakeup_thread(struct md_thread *thread); |
| 721 | 721 | extern void md_check_recovery(struct mddev *mddev); |
| 722 | −extern void md_reap_sync_thread(struct mddev *mddev, bool reconfig_mutex_held); | |
| 722 | +extern void md_reap_sync_thread(struct mddev *mddev); | |
| 723 | 723 | extern int mddev_init_writes_pending(struct mddev *mddev); |
| 724 | 724 | extern bool md_write_start(struct mddev *mddev, struct bio *bi); |
| 725 | 725 | extern void md_write_inc(struct mddev *mddev, struct bio *bi); |
| @@ -629,9 +629,9 @@ static void ppl_do_flush(struct ppl_io_unit *io) · 628 unmodified lines | ||
| 629 | 629 | if (bdev) { |
| 630 | 630 | struct bio *bio; |
| 631 | 631 | |
| 632 | − bio = bio_alloc_bioset(bdev, 0, GFP_NOIO, | |
| 632 | + bio = bio_alloc_bioset(bdev, 0, | |
| 633 | 633 | REQ_OP_WRITE | REQ_PREFLUSH, |
| 634 | − &ppl_conf->flush_bs); | |
| 634 | + GFP_NOIO, &ppl_conf->flush_bs); | |
| 635 | 635 | bio->bi_private = io; |
| 636 | 636 | bio->bi_end_io = ppl_flush_endio; |
| 637 | 637 | |
| @@ -105,6 +105,7 @@ config TI_EMIF · 104 unmodified lines | ||
| 105 | 105 | config OMAP_GPMC |
| 106 | 106 | tristate "Texas Instruments OMAP SoC GPMC driver" |
| 107 | 107 | depends on OF_ADDRESS |
| 108 | + depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST | |
| 108 | 109 | select GPIOLIB |
| 109 | 110 | help |
| 110 | 111 | This driver is for the General Purpose Memory Controller (GPMC) |
| @@ -404,13 +404,16 @@ static int mtk_smi_device_link_common(struct device *dev, struct device **com_de · 403 unmodified lines | ||
| 404 | 404 | of_node_put(smi_com_node); |
| 405 | 405 | if (smi_com_pdev) { |
| 406 | 406 | /* smi common is the supplier, Make sure it is ready before */ |
| 407 | − if (!platform_get_drvdata(smi_com_pdev)) | |
| 407 | + if (!platform_get_drvdata(smi_com_pdev)) { | |
| 408 | + put_device(&smi_com_pdev->dev); | |
| 408 | 409 | return -EPROBE_DEFER; |
| 410 | + } | |
| 409 | 411 | smi_com_dev = &smi_com_pdev->dev; |
| 410 | 412 | link = device_link_add(dev, smi_com_dev, |
| 411 | 413 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); |
| 412 | 414 | if (!link) { |
| 413 | 415 | dev_err(dev, "Unable to link smi-common dev\n"); |
| 416 | + put_device(&smi_com_pdev->dev); | |
| 414 | 417 | return -ENODEV; |
| 415 | 418 | } |
| 416 | 419 | *com_dev = smi_com_dev; |
| @@ -1187,33 +1187,39 @@ static int of_get_dram_timings(struct exynos5_dmc *dmc) · 1186 unmodified lines | ||
| 1187 | 1187 | |
| 1188 | 1188 | dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT, |
| 1189 | 1189 | sizeof(u32), GFP_KERNEL); |
| 1190 | − if (!dmc->timing_row) | |
| 1191 | − return -ENOMEM; | |
| 1190 | + if (!dmc->timing_row) { | |
| 1191 | + ret = -ENOMEM; | |
| 1192 | + goto put_node; | |
| 1193 | + } | |
| 1192 | 1194 | |
| 1193 | 1195 | dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT, |
| 1194 | 1196 | sizeof(u32), GFP_KERNEL); |
| 1195 | − if (!dmc->timing_data) | |
| 1196 | − return -ENOMEM; | |
| 1197 | + if (!dmc->timing_data) { | |
| 1198 | + ret = -ENOMEM; | |
| 1199 | + goto put_node; | |
| 1200 | + } | |
| 1197 | 1201 | |
| 1198 | 1202 | dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT, |
| 1199 | 1203 | sizeof(u32), GFP_KERNEL); |
| 1200 | − if (!dmc->timing_power) | |
| 1201 | − return -ENOMEM; | |
| 1204 | + if (!dmc->timing_power) { | |
| 1205 | + ret = -ENOMEM; | |
| 1206 | + goto put_node; | |
| 1207 | + } | |
| 1202 | 1208 | |
| 1203 | 1209 | dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev, |
| 1204 | 1210 | DDR_TYPE_LPDDR3, |
| 1205 | 1211 | &dmc->timings_arr_size); |
| 1206 | 1212 | if (!dmc->timings) { |
| 1207 | − of_node_put(np_ddr); | |
| 1208 | 1213 | dev_warn(dmc->dev, "could not get timings from DT\n"); |
| 1209 | − return -EINVAL; | |
| 1214 | + ret = -EINVAL; | |
| 1215 | + goto put_node; | |
| 1210 | 1216 | } |
| 1211 | 1217 | |
| 1212 | 1218 | dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev); |
| 1213 | 1219 | if (!dmc->min_tck) { |
| 1214 | − of_node_put(np_ddr); | |
| 1215 | 1220 | dev_warn(dmc->dev, "could not get tck from DT\n"); |
| 1216 | − return -EINVAL; | |
| 1221 | + ret = -EINVAL; | |
| 1222 | + goto put_node; | |
| 1217 | 1223 | } |
| 1218 | 1224 | |
| 1219 | 1225 | /* Sorted array of OPPs with frequency ascending */ |
| @@ -1227,13 +1233,14 @@ static int of_get_dram_timings(struct exynos5_dmc *dmc) · 7 unmodified lines | ||
| 1227 | 1233 | clk_period_ps); |
| 1228 | 1234 | } |
| 1229 | 1235 | |
| 1230 | − of_node_put(np_ddr); | |
| 1231 | 1236 | |
| 1232 | 1237 | /* Take the highest frequency's timings as 'bypass' */ |
| 1233 | 1238 | dmc->bypass_timing_row = dmc->timing_row[idx - 1]; |
| 1234 | 1239 | dmc->bypass_timing_data = dmc->timing_data[idx - 1]; |
| 1235 | 1240 | dmc->bypass_timing_power = dmc->timing_power[idx - 1]; |
| 1236 | 1241 | |
| 1242 | +put_node: | |
| 1243 | + of_node_put(np_ddr); | |
| 1237 | 1244 | return ret; |
| 1238 | 1245 | } |
| 1239 | 1246 | |
| @@ -232,9 +232,9 @@ static int ssc_probe(struct platform_device *pdev) · 231 unmodified lines | ||
| 232 | 232 | clk_disable_unprepare(ssc->clk); |
| 233 | 233 | |
| 234 | 234 | ssc->irq = platform_get_irq(pdev, 0); |
| 235 | − if (!ssc->irq) { | |
| 235 | + if (ssc->irq < 0) { | |
| 236 | 236 | dev_dbg(&pdev->dev, "could not get irq\n"); |
| 237 | − return -ENXIO; | |
| 237 | + return ssc->irq; | |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | 240 | mutex_lock(&user_lock); |
| @@ -407,6 +407,8 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr) · 406 unmodified lines | ||
| 407 | 407 | // default |
| 408 | 408 | setting_reg1 = PCR_SETTING_REG1; |
| 409 | 409 | setting_reg2 = PCR_SETTING_REG2; |
| 410 | + } else { | |
| 411 | + return; | |
| 410 | 412 | } |
| 411 | 413 | |
| 412 | 414 | pci_read_config_dword(pdev, setting_reg2, &lval2); |
| @@ -79,6 +79,11 @@ static int at25_ee_read(void *priv, unsigned int offset, · 78 unmodified lines | ||
| 79 | 79 | { |
| 80 | 80 | struct at25_data *at25 = priv; |
| 81 | 81 | char *buf = val; |
| 82 | + size_t max_chunk = spi_max_transfer_size(at25->spi); | |
| 83 | + size_t num_msgs = DIV_ROUND_UP(count, max_chunk); | |
| 84 | + size_t nr_bytes = 0; | |
| 85 | + unsigned int msg_offset; | |
| 86 | + size_t msg_count; | |
| 82 | 87 | u8 *cp; |
| 83 | 88 | ssize_t status; |
| 84 | 89 | struct spi_transfer t[2]; |
| @@ -92,54 +97,59 @@ static int at25_ee_read(void *priv, unsigned int offset, · 7 unmodified lines | ||
| 92 | 97 | if (unlikely(!count)) |
| 93 | 98 | return -EINVAL; |
| 94 | 99 | |
| 95 | − cp = at25->command; | |
| 100 | + msg_offset = (unsigned int)offset; | |
| 101 | + msg_count = min(count, max_chunk); | |
| 102 | + while (num_msgs) { | |
| 103 | + cp = at25->command; | |
| 96 | 104 | |
| 97 | − instr = AT25_READ; | |
| 98 | − if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) | |
| 99 | − if (offset >= BIT(at25->addrlen * 8)) | |
| 100 | − instr |= AT25_INSTR_BIT3; | |
| 105 | + instr = AT25_READ; | |
| 106 | + if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) | |
| 107 | + if (msg_offset >= BIT(at25->addrlen * 8)) | |
| 108 | + instr |= AT25_INSTR_BIT3; | |
| 101 | 109 | |
| 102 | − mutex_lock(&at25->lock); | |
| 110 | + mutex_lock(&at25->lock); | |
| 103 | 111 | |
| 104 | − *cp++ = instr; | |
| 105 | − | |
| 106 | − /* 8/16/24-bit address is written MSB first */ | |
| 107 | − switch (at25->addrlen) { | |
| 108 | − default: /* case 3 */ | |
| 109 | − *cp++ = offset >> 16; | |
| 110 | − fallthrough; | |
| 111 | − case 2: | |
| 112 | − *cp++ = offset >> 8; | |
| 113 | − fallthrough; | |
| 114 | − case 1: | |
| 115 | − case 0: /* can't happen: for better code generation */ | |
| 116 | − *cp++ = offset >> 0; | |
| 117 | − } | |
| 112 | + *cp++ = instr; | |
| 118 | 113 | |
| 119 | − spi_message_init(&m); | |
| 120 | − memset(t, 0, sizeof(t)); | |
| 114 | + /* 8/16/24-bit address is written MSB first */ | |
| 115 | + switch (at25->addrlen) { | |
| 116 | + default: /* case 3 */ | |
| 117 | + *cp++ = msg_offset >> 16; | |
| 118 | + fallthrough; | |
| 119 | + case 2: | |
| 120 | + *cp++ = msg_offset >> 8; | |
| 121 | + fallthrough; | |
| 122 | + case 1: | |
| 123 | + case 0: /* can't happen: for better code generation */ | |
| 124 | + *cp++ = msg_offset >> 0; | |
| 125 | + } | |
| 121 | 126 | |
| 122 | − t[0].tx_buf = at25->command; | |
| 123 | − t[0].len = at25->addrlen + 1; | |
| 124 | − spi_message_add_tail(&t[0], &m); | |
| 127 | + spi_message_init(&m); | |
| 128 | + memset(t, 0, sizeof(t)); | |
| 125 | 129 | |
| 126 | − t[1].rx_buf = buf; | |
| 127 | − t[1].len = count; | |
| 128 | − spi_message_add_tail(&t[1], &m); | |
| 130 | + t[0].tx_buf = at25->command; | |
| 131 | + t[0].len = at25->addrlen + 1; | |
| 132 | + spi_message_add_tail(&t[0], &m); | |
| 129 | 133 | |
| 130 | − /* | |
| 131 | − * Read it all at once. | |
| 132 | − * | |
| 133 | − * REVISIT that's potentially a problem with large chips, if | |
| 134 | − * other devices on the bus need to be accessed regularly or | |
| 135 | − * this chip is clocked very slowly. | |
| 136 | − */ | |
| 137 | − status = spi_sync(at25->spi, &m); | |
| 138 | − dev_dbg(&at25->spi->dev, "read %zu bytes at %d --> %zd\n", | |
| 139 | − count, offset, status); | |
| 134 | + t[1].rx_buf = buf + nr_bytes; | |
| 135 | + t[1].len = msg_count; | |
| 136 | + spi_message_add_tail(&t[1], &m); | |
| 140 | 137 | |
| 141 | − mutex_unlock(&at25->lock); | |
| 142 | − return status; | |
| 138 | + status = spi_sync(at25->spi, &m); | |
| 139 | + | |
| 140 | + mutex_unlock(&at25->lock); | |
| 141 | + | |
| 142 | + if (status) | |
| 143 | + return status; | |
| 144 | + | |
| 145 | + --num_msgs; | |
| 146 | + msg_offset += msg_count; | |
| 147 | + nr_bytes += msg_count; | |
| 148 | + } | |
| 149 | + | |
| 150 | + dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n", | |
| 151 | + count, offset); | |
| 152 | + return 0; | |
| 143 | 153 | } |
| 144 | 154 | |
| 145 | 155 | /* Read extra registers as ID or serial number */ |
| @@ -190,6 +200,7 @@ ATTRIBUTE_GROUPS(sernum); · 44 unmodified lines | ||
| 190 | 200 | static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) |
| 191 | 201 | { |
| 192 | 202 | struct at25_data *at25 = priv; |
| 203 | + size_t maxsz = spi_max_transfer_size(at25->spi); | |
| 193 | 204 | const char *buf = val; |
| 194 | 205 | int status = 0; |
| 195 | 206 | unsigned buf_size; |
| @@ -253,6 +264,8 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) · 57 unmodified lines | ||
| 253 | 264 | segment = buf_size - (offset % buf_size); |
| 254 | 265 | if (segment > count) |
| 255 | 266 | segment = count; |
| 267 | + if (segment > maxsz) | |
| 268 | + segment = maxsz; | |
| 256 | 269 | memcpy(cp, buf, segment); |
| 257 | 270 | status = spi_write(at25->spi, bounce, |
| 258 | 271 | segment + at25->addrlen + 1); |
| @@ -1351,7 +1351,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) · 1350 unmodified lines | ||
| 1351 | 1351 | |
| 1352 | 1352 | if (dev->dev_state != MEI_DEV_INIT_CLIENTS || |
| 1353 | 1353 | dev->hbm_state != MEI_HBM_CAP_SETUP) { |
| 1354 | − if (dev->dev_state == MEI_DEV_POWER_DOWN) { | |
| 1354 | + if (dev->dev_state == MEI_DEV_POWER_DOWN || | |
| 1355 | + dev->dev_state == MEI_DEV_POWERING_DOWN) { | |
| 1355 | 1356 | dev_dbg(dev->dev, "hbm: capabilities response: on shutdown, ignoring\n"); |
| 1356 | 1357 | return 0; |
| 1357 | 1358 | } |
| @@ -109,6 +109,8 @@ · 108 unmodified lines | ||
| 109 | 109 | #define MEI_DEV_ID_ADP_P 0x51E0 /* Alder Lake Point P */ |
| 110 | 110 | #define MEI_DEV_ID_ADP_N 0x54E0 /* Alder Lake Point N */ |
| 111 | 111 | |
| 112 | +#define MEI_DEV_ID_RPL_S 0x7A68 /* Raptor Lake Point S */ | |
| 113 | + | |
| 112 | 114 | /* |
| 113 | 115 | * MEI HW Section |
| 114 | 116 | */ |
| @@ -1154,6 +1154,8 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) · 1153 unmodified lines | ||
| 1154 | 1154 | ret = mei_me_d0i3_exit_sync(dev); |
| 1155 | 1155 | if (ret) |
| 1156 | 1156 | return ret; |
| 1157 | + } else { | |
| 1158 | + hw->pg_state = MEI_PG_OFF; | |
| 1157 | 1159 | } |
| 1158 | 1160 | } |
| 1159 | 1161 | |
| @@ -116,6 +116,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 115 unmodified lines | ||
| 116 | 116 | {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)}, |
| 117 | 117 | {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)}, |
| 118 | 118 | |
| 119 | + {MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)}, | |
| 120 | + | |
| 119 | 121 | /* required last entry */ |
| 120 | 122 | {0, } |
| 121 | 123 | }; |
| @@ -1356,7 +1356,7 @@ static void msdc_data_xfer_next(struct msdc_host *host, struct mmc_request *mrq) · 1355 unmodified lines | ||
| 1356 | 1356 | msdc_request_done(host, mrq); |
| 1357 | 1357 | } |
| 1358 | 1358 | |
| 1359 | −static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, | |
| 1359 | +static void msdc_data_xfer_done(struct msdc_host *host, u32 events, | |
| 1360 | 1360 | struct mmc_request *mrq, struct mmc_data *data) |
| 1361 | 1361 | { |
| 1362 | 1362 | struct mmc_command *stop; |
| @@ -1376,7 +1376,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, · 13 unmodified lines | ||
| 1376 | 1376 | spin_unlock_irqrestore(&host->lock, flags); |
| 1377 | 1377 | |
| 1378 | 1378 | if (done) |
| 1379 | − return true; | |
| 1379 | + return; | |
| 1380 | 1380 | stop = data->stop; |
| 1381 | 1381 | |
| 1382 | 1382 | if (check_data || (stop && stop->error)) { |
| @@ -1385,12 +1385,15 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, · 2 unmodified lines | ||
| 1385 | 1385 | sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, |
| 1386 | 1386 | 1); |
| 1387 | 1387 | |
| 1388 | + ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CTRL, val, | |
| 1389 | + !(val & MSDC_DMA_CTRL_STOP), 1, 20000); | |
| 1390 | + if (ret) | |
| 1391 | + dev_dbg(host->dev, "DMA stop timed out\n"); | |
| 1392 | + | |
| 1388 | 1393 | ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val, |
| 1389 | 1394 | !(val & MSDC_DMA_CFG_STS), 1, 20000); |
| 1390 | − if (ret) { | |
| 1391 | − dev_dbg(host->dev, "DMA stop timed out\n"); | |
| 1392 | − return false; | |
| 1393 | − } | |
| 1395 | + if (ret) | |
| 1396 | + dev_dbg(host->dev, "DMA inactive timed out\n"); | |
| 1394 | 1397 | |
| 1395 | 1398 | sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask); |
| 1396 | 1399 | dev_dbg(host->dev, "DMA stop\n"); |
| @@ -1415,9 +1418,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, · 18 unmodified lines | ||
| 1415 | 1418 | } |
| 1416 | 1419 | |
| 1417 | 1420 | msdc_data_xfer_next(host, mrq); |
| 1418 | − done = true; | |
| 1419 | 1421 | } |
| 1420 | − return done; | |
| 1421 | 1422 | } |
| 1422 | 1423 | |
| 1423 | 1424 | static void msdc_set_buswidth(struct msdc_host *host, u32 width) |
| @@ -2416,6 +2417,9 @@ static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery) · 992 unmodified lines | ||
| 2416 | 2417 | if (recovery) { |
| 2417 | 2418 | sdr_set_field(host->base + MSDC_DMA_CTRL, |
| 2418 | 2419 | MSDC_DMA_CTRL_STOP, 1); |
| 2420 | + if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CTRL, val, | |
| 2421 | + !(val & MSDC_DMA_CTRL_STOP), 1, 3000))) | |
| 2422 | + return; | |
| 2419 | 2423 | if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CFG, val, |
| 2420 | 2424 | !(val & MSDC_DMA_CFG_STS), 1, 3000))) |
| 2421 | 2425 | return; |
| @@ -152,6 +152,8 @@ static int sdhci_o2_get_cd(struct mmc_host *mmc) · 151 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS)) |
| 154 | 154 | sdhci_o2_enable_internal_clock(host); |
| 155 | + else | |
| 156 | + sdhci_o2_wait_card_detect_stable(host); | |
| 155 | 157 | |
| 156 | 158 | return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); |
| 157 | 159 | } |
| @@ -890,7 +890,7 @@ static int gpmi_nfc_compute_timings(struct gpmi_nand_data *this, · 889 unmodified lines | ||
| 890 | 890 | hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) | |
| 891 | 891 | BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) | |
| 892 | 892 | BF_GPMI_TIMING0_DATA_SETUP(data_setup_cycles); |
| 893 | − hw->timing1 = BF_GPMI_TIMING1_BUSY_TIMEOUT(busy_timeout_cycles * 4096); | |
| 893 | + hw->timing1 = BF_GPMI_TIMING1_BUSY_TIMEOUT(DIV_ROUND_UP(busy_timeout_cycles, 4096)); | |
| 894 | 894 | |
| 895 | 895 | /* |
| 896 | 896 | * Derive NFC ideal delay from {3}: |
| @@ -29,9 +29,6 @@ struct nand_flash_dev nand_flash_ids[] = { · 28 unmodified lines | ||
| 29 | 29 | {"TC58NVG0S3E 1G 3.3V 8-bit", |
| 30 | 30 | { .id = {0x98, 0xd1, 0x90, 0x15, 0x76, 0x14, 0x01, 0x00} }, |
| 31 | 31 | SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512), }, |
| 32 | − {"TC58NVG0S3HTA00 1G 3.3V 8-bit", | |
| 33 | − { .id = {0x98, 0xf1, 0x80, 0x15} }, | |
| 34 | − SZ_2K, SZ_128, SZ_128K, 0, 4, 128, NAND_ECC_INFO(8, SZ_512), }, | |
| 35 | 32 | {"TC58NVG2S0F 4G 3.3V 8-bit", |
| 36 | 33 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, |
| 37 | 34 | SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, |
| @@ -3684,9 +3684,11 @@ re_arm: · 3683 unmodified lines | ||
| 3684 | 3684 | if (!rtnl_trylock()) |
| 3685 | 3685 | return; |
| 3686 | 3686 | |
| 3687 | − if (should_notify_peers) | |
| 3687 | + if (should_notify_peers) { | |
| 3688 | + bond->send_peer_notif--; | |
| 3688 | 3689 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, |
| 3689 | 3690 | bond->dev); |
| 3691 | + } | |
| 3690 | 3692 | if (should_notify_rtnl) { |
| 3691 | 3693 | bond_slave_state_notify(bond); |
| 3692 | 3694 | bond_slave_link_notify(bond); |
| @@ -2334,6 +2334,7 @@ static int · 2333 unmodified lines | ||
| 2334 | 2334 | qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) |
| 2335 | 2335 | { |
| 2336 | 2336 | struct qca8k_priv *priv = ds->priv; |
| 2337 | + int ret; | |
| 2337 | 2338 | |
| 2338 | 2339 | /* We have only have a general MTU setting. |
| 2339 | 2340 | * DSA always set the CPU port's MTU to the largest MTU of the slave |
| @@ -2344,8 +2345,27 @@ qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) · 4 unmodified lines | ||
| 2344 | 2345 | if (!dsa_is_cpu_port(ds, port)) |
| 2345 | 2346 | return 0; |
| 2346 | 2347 | |
| 2348 | + /* To change the MAX_FRAME_SIZE the cpu ports must be off or | |
| 2349 | + * the switch panics. | |
| 2350 | + * Turn off both cpu ports before applying the new value to prevent | |
| 2351 | + * this. | |
| 2352 | + */ | |
| 2353 | + if (priv->port_enabled_map & BIT(0)) | |
| 2354 | + qca8k_port_set_status(priv, 0, 0); | |
| 2355 | + | |
| 2356 | + if (priv->port_enabled_map & BIT(6)) | |
| 2357 | + qca8k_port_set_status(priv, 6, 0); | |
| 2358 | + | |
| 2347 | 2359 | /* Include L2 header / FCS length */ |
| 2348 | − return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); | |
| 2360 | + ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); | |
| 2361 | + | |
| 2362 | + if (priv->port_enabled_map & BIT(0)) | |
| 2363 | + qca8k_port_set_status(priv, 0, 1); | |
| 2364 | + | |
| 2365 | + if (priv->port_enabled_map & BIT(6)) | |
| 2366 | + qca8k_port_set_status(priv, 6, 1); | |
| 2367 | + | |
| 2368 | + return ret; | |
| 2349 | 2369 | } |
| 2350 | 2370 | |
| 2351 | 2371 | static int |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #define QCA8K_ETHERNET_MDIO_PRIORITY 7 |
| 17 | 17 | #define QCA8K_ETHERNET_PHY_PRIORITY 6 |
| 18 | −#define QCA8K_ETHERNET_TIMEOUT 100 | |
| 18 | +#define QCA8K_ETHERNET_TIMEOUT 5 | |
| 19 | 19 | |
| 20 | 20 | #define QCA8K_NUM_PORTS 7 |
| 21 | 21 | #define QCA8K_NUM_CPU_PORTS 2 |
| @@ -338,7 +338,7 @@ static int xgbe_platform_probe(struct platform_device *pdev) · 337 unmodified lines | ||
| 338 | 338 | * the PHY resources listed last |
| 339 | 339 | */ |
| 340 | 340 | phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3; |
| 341 | − phy_irqnum = xgbe_resource_count(pdev, IORESOURCE_IRQ) - 1; | |
| 341 | + phy_irqnum = platform_irq_count(pdev) - 1; | |
| 342 | 342 | dma_irqnum = 1; |
| 343 | 343 | dma_irqend = phy_irqnum; |
| 344 | 344 | } else { |
| @@ -348,7 +348,7 @@ static int xgbe_platform_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 348 | 348 | phy_memnum = 0; |
| 349 | 349 | phy_irqnum = 0; |
| 350 | 350 | dma_irqnum = 1; |
| 351 | − dma_irqend = xgbe_resource_count(pdev, IORESOURCE_IRQ); | |
| 351 | + dma_irqend = platform_irq_count(pdev); | |
| 352 | 352 | } |
| 353 | 353 | |
| 354 | 354 | /* Obtain the mmio areas for the device */ |
| @@ -332,7 +332,6 @@ static void bgmac_remove(struct bcma_device *core) · 331 unmodified lines | ||
| 332 | 332 | bcma_mdio_mii_unregister(bgmac->mii_bus); |
| 333 | 333 | bgmac_enet_remove(bgmac); |
| 334 | 334 | bcma_set_drvdata(core, NULL); |
| 335 | − kfree(bgmac); | |
| 336 | 335 | } |
| 337 | 336 | |
| 338 | 337 | static struct bcma_driver bgmac_bcma_driver = { |
| @@ -769,6 +769,7 @@ struct hnae3_tc_info { · 768 unmodified lines | ||
| 769 | 769 | u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */ |
| 770 | 770 | u16 tqp_count[HNAE3_MAX_TC]; |
| 771 | 771 | u16 tqp_offset[HNAE3_MAX_TC]; |
| 772 | + u8 max_tc; /* Total number of TCs */ | |
| 772 | 773 | u8 num_tc; /* Total number of enabled TCs */ |
| 773 | 774 | bool mqprio_active; |
| 774 | 775 | }; |
| @@ -1129,7 +1129,7 @@ hns3_is_ringparam_changed(struct net_device *ndev, · 1128 unmodified lines | ||
| 1129 | 1129 | if (old_ringparam->tx_desc_num == new_ringparam->tx_desc_num && |
| 1130 | 1130 | old_ringparam->rx_desc_num == new_ringparam->rx_desc_num && |
| 1131 | 1131 | old_ringparam->rx_buf_len == new_ringparam->rx_buf_len) { |
| 1132 | − netdev_info(ndev, "ringparam not changed\n"); | |
| 1132 | + netdev_info(ndev, "descriptor number and rx buffer length not changed\n"); | |
| 1133 | 1133 | return false; |
| 1134 | 1134 | } |
| 1135 | 1135 | |
| @@ -3268,7 +3268,7 @@ static int hclge_tp_port_init(struct hclge_dev *hdev) · 3267 unmodified lines | ||
| 3268 | 3268 | static int hclge_update_port_info(struct hclge_dev *hdev) |
| 3269 | 3269 | { |
| 3270 | 3270 | struct hclge_mac *mac = &hdev->hw.mac; |
| 3271 | − int speed = HCLGE_MAC_SPEED_UNKNOWN; | |
| 3271 | + int speed; | |
| 3272 | 3272 | int ret; |
| 3273 | 3273 | |
| 3274 | 3274 | /* get the port info from SFP cmd if not copper port */ |
| @@ -3279,10 +3279,13 @@ static int hclge_update_port_info(struct hclge_dev *hdev) · 4 unmodified lines | ||
| 3279 | 3279 | if (!hdev->support_sfp_query) |
| 3280 | 3280 | return 0; |
| 3281 | 3281 | |
| 3282 | − if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) | |
| 3282 | + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { | |
| 3283 | + speed = mac->speed; | |
| 3283 | 3284 | ret = hclge_get_sfp_info(hdev, mac); |
| 3284 | − else | |
| 3285 | + } else { | |
| 3286 | + speed = HCLGE_MAC_SPEED_UNKNOWN; | |
| 3285 | 3287 | ret = hclge_get_sfp_speed(hdev, &speed); |
| 3288 | + } | |
| 3286 | 3289 | |
| 3287 | 3290 | if (ret == -EOPNOTSUPP) { |
| 3288 | 3291 | hdev->support_sfp_query = false; |
| @@ -3294,6 +3297,8 @@ static int hclge_update_port_info(struct hclge_dev *hdev) · 5 unmodified lines | ||
| 3294 | 3297 | if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { |
| 3295 | 3298 | if (mac->speed_type == QUERY_ACTIVE_SPEED) { |
| 3296 | 3299 | hclge_update_port_capability(hdev, mac); |
| 3300 | + if (mac->speed != speed) | |
| 3301 | + (void)hclge_tm_port_shaper_cfg(hdev); | |
| 3297 | 3302 | return 0; |
| 3298 | 3303 | } |
| 3299 | 3304 | return hclge_cfg_mac_speed_dup(hdev, mac->speed, |
| @@ -3376,6 +3381,12 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, · 76 unmodified lines | ||
| 3376 | 3381 | link_state_old = vport->vf_info.link_state; |
| 3377 | 3382 | vport->vf_info.link_state = link_state; |
| 3378 | 3383 | |
| 3384 | + /* return success directly if the VF is unalive, VF will | |
| 3385 | + * query link state itself when it starts work. | |
| 3386 | + */ | |
| 3387 | + if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) | |
| 3388 | + return 0; | |
| 3389 | + | |
| 3379 | 3390 | ret = hclge_push_vf_link_status(vport); |
| 3380 | 3391 | if (ret) { |
| 3381 | 3392 | vport->vf_info.link_state = link_state_old; |
| @@ -10117,6 +10128,7 @@ static int hclge_modify_port_base_vlan_tag(struct hclge_vport *vport, · 6735 unmodified lines | ||
| 10117 | 10128 | if (ret) |
| 10118 | 10129 | return ret; |
| 10119 | 10130 | |
| 10131 | + vport->port_base_vlan_cfg.tbl_sta = false; | |
| 10120 | 10132 | /* remove old VLAN tag */ |
| 10121 | 10133 | if (old_info->vlan_tag == 0) |
| 10122 | 10134 | ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, |
| @@ -282,8 +282,8 @@ static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev, · 281 unmodified lines | ||
| 282 | 282 | return hclge_cmd_send(&hdev->hw, &desc, 1); |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | −static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, | |
| 286 | − u16 qs_id, u8 pri) | |
| 285 | +static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, u16 qs_id, u8 pri, | |
| 286 | + bool link_vld) | |
| 287 | 287 | { |
| 288 | 288 | struct hclge_qs_to_pri_link_cmd *map; |
| 289 | 289 | struct hclge_desc desc; |
| @@ -294,7 +294,7 @@ static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, · 4 unmodified lines | ||
| 294 | 294 | |
| 295 | 295 | map->qs_id = cpu_to_le16(qs_id); |
| 296 | 296 | map->priority = pri; |
| 297 | − map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK; | |
| 297 | + map->link_vld = link_vld ? HCLGE_TM_QS_PRI_LINK_VLD_MSK : 0; | |
| 298 | 298 | |
| 299 | 299 | return hclge_cmd_send(&hdev->hw, &desc, 1); |
| 300 | 300 | } |
| @@ -420,7 +420,7 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, · 119 unmodified lines | ||
| 420 | 420 | return hclge_cmd_send(&hdev->hw, &desc, 1); |
| 421 | 421 | } |
| 422 | 422 | |
| 423 | −static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) | |
| 423 | +int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) | |
| 424 | 424 | { |
| 425 | 425 | struct hclge_port_shapping_cmd *shap_cfg_cmd; |
| 426 | 426 | struct hclge_shaper_ir_para ir_para; |
| @@ -642,11 +642,13 @@ static void hclge_tm_update_kinfo_rss_size(struct hclge_vport *vport) · 215 unmodified lines | ||
| 642 | 642 | * one tc for VF for simplicity. VF's vport_id is non zero. |
| 643 | 643 | */ |
| 644 | 644 | if (vport->vport_id) { |
| 645 | + kinfo->tc_info.max_tc = 1; | |
| 645 | 646 | kinfo->tc_info.num_tc = 1; |
| 646 | 647 | vport->qs_offset = HNAE3_MAX_TC + |
| 647 | 648 | vport->vport_id - HCLGE_VF_VPORT_START_NUM; |
| 648 | 649 | vport_max_rss_size = hdev->vf_rss_size_max; |
| 649 | 650 | } else { |
| 651 | + kinfo->tc_info.max_tc = hdev->tc_max; | |
| 650 | 652 | kinfo->tc_info.num_tc = |
| 651 | 653 | min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); |
| 652 | 654 | vport->qs_offset = 0; |
| @@ -679,7 +681,9 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) · 26 unmodified lines | ||
| 679 | 681 | kinfo->num_tqps = hclge_vport_get_tqp_num(vport); |
| 680 | 682 | vport->dwrr = 100; /* 100 percent as init */ |
| 681 | 683 | vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit; |
| 682 | − hdev->rss_cfg.rss_size = kinfo->rss_size; | |
| 684 | + | |
| 685 | + if (vport->vport_id == PF_VPORT_ID) | |
| 686 | + hdev->rss_cfg.rss_size = kinfo->rss_size; | |
| 683 | 687 | |
| 684 | 688 | /* when enable mqprio, the tc_info has been updated. */ |
| 685 | 689 | if (kinfo->tc_info.mqprio_active) |
| @@ -714,14 +718,22 @@ static void hclge_tm_vport_info_update(struct hclge_dev *hdev) · 28 unmodified lines | ||
| 714 | 718 | |
| 715 | 719 | static void hclge_tm_tc_info_init(struct hclge_dev *hdev) |
| 716 | 720 | { |
| 717 | − u8 i; | |
| 721 | + u8 i, tc_sch_mode; | |
| 722 | + u32 bw_limit; | |
| 723 | + | |
| 724 | + for (i = 0; i < hdev->tc_max; i++) { | |
| 725 | + if (i < hdev->tm_info.num_tc) { | |
| 726 | + tc_sch_mode = HCLGE_SCH_MODE_DWRR; | |
| 727 | + bw_limit = hdev->tm_info.pg_info[0].bw_limit; | |
| 728 | + } else { | |
| 729 | + tc_sch_mode = HCLGE_SCH_MODE_SP; | |
| 730 | + bw_limit = 0; | |
| 731 | + } | |
| 718 | 732 | |
| 719 | − for (i = 0; i < hdev->tm_info.num_tc; i++) { | |
| 720 | 733 | hdev->tm_info.tc_info[i].tc_id = i; |
| 721 | − hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR; | |
| 734 | + hdev->tm_info.tc_info[i].tc_sch_mode = tc_sch_mode; | |
| 722 | 735 | hdev->tm_info.tc_info[i].pgid = 0; |
| 723 | − hdev->tm_info.tc_info[i].bw_limit = | |
| 724 | − hdev->tm_info.pg_info[0].bw_limit; | |
| 736 | + hdev->tm_info.tc_info[i].bw_limit = bw_limit; | |
| 725 | 737 | } |
| 726 | 738 | |
| 727 | 739 | for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) |
| @@ -926,10 +938,13 @@ static int hclge_tm_pri_q_qs_cfg_tc_base(struct hclge_dev *hdev) · 198 unmodified lines | ||
| 926 | 938 | for (k = 0; k < hdev->num_alloc_vport; k++) { |
| 927 | 939 | struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo; |
| 928 | 940 | |
| 929 | − for (i = 0; i < kinfo->tc_info.num_tc; i++) { | |
| 941 | + for (i = 0; i < kinfo->tc_info.max_tc; i++) { | |
| 942 | + u8 pri = i < kinfo->tc_info.num_tc ? i : 0; | |
| 943 | + bool link_vld = i < kinfo->tc_info.num_tc; | |
| 944 | + | |
| 930 | 945 | ret = hclge_tm_qs_to_pri_map_cfg(hdev, |
| 931 | 946 | vport[k].qs_offset + i, |
| 932 | − i); | |
| 947 | + pri, link_vld); | |
| 933 | 948 | if (ret) |
| 934 | 949 | return ret; |
| 935 | 950 | } |
| @@ -949,7 +964,7 @@ static int hclge_tm_pri_q_qs_cfg_vnet_base(struct hclge_dev *hdev) · 13 unmodified lines | ||
| 949 | 964 | for (i = 0; i < HNAE3_MAX_TC; i++) { |
| 950 | 965 | ret = hclge_tm_qs_to_pri_map_cfg(hdev, |
| 951 | 966 | vport[k].qs_offset + i, |
| 952 | − k); | |
| 967 | + k, true); | |
| 953 | 968 | if (ret) |
| 954 | 969 | return ret; |
| 955 | 970 | } |
| @@ -989,33 +1004,39 @@ static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) · 33 unmodified lines | ||
| 989 | 1004 | { |
| 990 | 1005 | u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; |
| 991 | 1006 | struct hclge_shaper_ir_para ir_para; |
| 992 | − u32 shaper_para; | |
| 1007 | + u32 shaper_para_c, shaper_para_p; | |
| 993 | 1008 | int ret; |
| 994 | 1009 | u32 i; |
| 995 | 1010 | |
| 996 | − for (i = 0; i < hdev->tm_info.num_tc; i++) { | |
| 1011 | + for (i = 0; i < hdev->tc_max; i++) { | |
| 997 | 1012 | u32 rate = hdev->tm_info.tc_info[i].bw_limit; |
| 998 | 1013 | |
| 999 | − ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI, | |
| 1000 | − &ir_para, max_tm_rate); | |
| 1001 | − if (ret) | |
| 1002 | − return ret; | |
| 1014 | + if (rate) { | |
| 1015 | + ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI, | |
| 1016 | + &ir_para, max_tm_rate); | |
| 1017 | + if (ret) | |
| 1018 | + return ret; | |
| 1019 | + | |
| 1020 | + shaper_para_c = hclge_tm_get_shapping_para(0, 0, 0, | |
| 1021 | + HCLGE_SHAPER_BS_U_DEF, | |
| 1022 | + HCLGE_SHAPER_BS_S_DEF); | |
| 1023 | + shaper_para_p = hclge_tm_get_shapping_para(ir_para.ir_b, | |
| 1024 | + ir_para.ir_u, | |
| 1025 | + ir_para.ir_s, | |
| 1026 | + HCLGE_SHAPER_BS_U_DEF, | |
| 1027 | + HCLGE_SHAPER_BS_S_DEF); | |
| 1028 | + } else { | |
| 1029 | + shaper_para_c = 0; | |
| 1030 | + shaper_para_p = 0; | |
| 1031 | + } | |
| 1003 | 1032 | |
| 1004 | − shaper_para = hclge_tm_get_shapping_para(0, 0, 0, | |
| 1005 | − HCLGE_SHAPER_BS_U_DEF, | |
| 1006 | − HCLGE_SHAPER_BS_S_DEF); | |
| 1007 | 1033 | ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i, |
| 1008 | − shaper_para, rate); | |
| 1034 | + shaper_para_c, rate); | |
| 1009 | 1035 | if (ret) |
| 1010 | 1036 | return ret; |
| 1011 | 1037 | |
| 1012 | − shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, | |
| 1013 | − ir_para.ir_u, | |
| 1014 | − ir_para.ir_s, | |
| 1015 | − HCLGE_SHAPER_BS_U_DEF, | |
| 1016 | − HCLGE_SHAPER_BS_S_DEF); | |
| 1017 | 1038 | ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, |
| 1018 | − shaper_para, rate); | |
| 1039 | + shaper_para_p, rate); | |
| 1019 | 1040 | if (ret) |
| 1020 | 1041 | return ret; |
| 1021 | 1042 | } |
| @@ -1125,7 +1146,7 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev) · 103 unmodified lines | ||
| 1125 | 1146 | int ret; |
| 1126 | 1147 | u32 i, k; |
| 1127 | 1148 | |
| 1128 | − for (i = 0; i < hdev->tm_info.num_tc; i++) { | |
| 1149 | + for (i = 0; i < hdev->tc_max; i++) { | |
| 1129 | 1150 | pg_info = |
| 1130 | 1151 | &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; |
| 1131 | 1152 | dwrr = pg_info->tc_dwrr[i]; |
| @@ -1135,9 +1156,15 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev) · 3 unmodified lines | ||
| 1135 | 1156 | return ret; |
| 1136 | 1157 | |
| 1137 | 1158 | for (k = 0; k < hdev->num_alloc_vport; k++) { |
| 1159 | + struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo; | |
| 1160 | + | |
| 1161 | + if (i >= kinfo->tc_info.max_tc) | |
| 1162 | + continue; | |
| 1163 | + | |
| 1164 | + dwrr = i < kinfo->tc_info.num_tc ? vport[k].dwrr : 0; | |
| 1138 | 1165 | ret = hclge_tm_qs_weight_cfg( |
| 1139 | 1166 | hdev, vport[k].qs_offset + i, |
| 1140 | − vport[k].dwrr); | |
| 1167 | + dwrr); | |
| 1141 | 1168 | if (ret) |
| 1142 | 1169 | return ret; |
| 1143 | 1170 | } |
| @@ -1303,6 +1330,7 @@ static int hclge_tm_schd_mode_tc_base_cfg(struct hclge_dev *hdev, u8 pri_id) · 159 unmodified lines | ||
| 1303 | 1330 | { |
| 1304 | 1331 | struct hclge_vport *vport = hdev->vport; |
| 1305 | 1332 | int ret; |
| 1333 | + u8 mode; | |
| 1306 | 1334 | u16 i; |
| 1307 | 1335 | |
| 1308 | 1336 | ret = hclge_tm_pri_schd_mode_cfg(hdev, pri_id); |
| @@ -1310,9 +1338,16 @@ static int hclge_tm_schd_mode_tc_base_cfg(struct hclge_dev *hdev, u8 pri_id) · 1 unmodified line | ||
| 1310 | 1338 | return ret; |
| 1311 | 1339 | |
| 1312 | 1340 | for (i = 0; i < hdev->num_alloc_vport; i++) { |
| 1341 | + struct hnae3_knic_private_info *kinfo = &vport[i].nic.kinfo; | |
| 1342 | + | |
| 1343 | + if (pri_id >= kinfo->tc_info.max_tc) | |
| 1344 | + continue; | |
| 1345 | + | |
| 1346 | + mode = pri_id < kinfo->tc_info.num_tc ? HCLGE_SCH_MODE_DWRR : | |
| 1347 | + HCLGE_SCH_MODE_SP; | |
| 1313 | 1348 | ret = hclge_tm_qs_schd_mode_cfg(hdev, |
| 1314 | 1349 | vport[i].qs_offset + pri_id, |
| 1315 | − HCLGE_SCH_MODE_DWRR); | |
| 1350 | + mode); | |
| 1316 | 1351 | if (ret) |
| 1317 | 1352 | return ret; |
| 1318 | 1353 | } |
| @@ -1353,7 +1388,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev) · 34 unmodified lines | ||
| 1353 | 1388 | u8 i; |
| 1354 | 1389 | |
| 1355 | 1390 | if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { |
| 1356 | − for (i = 0; i < hdev->tm_info.num_tc; i++) { | |
| 1391 | + for (i = 0; i < hdev->tc_max; i++) { | |
| 1357 | 1392 | ret = hclge_tm_schd_mode_tc_base_cfg(hdev, i); |
| 1358 | 1393 | if (ret) |
| 1359 | 1394 | return ret; |
| @@ -237,6 +237,7 @@ int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); · 236 unmodified lines | ||
| 237 | 237 | void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); |
| 238 | 238 | void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); |
| 239 | 239 | int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); |
| 240 | +int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev); | |
| 240 | 241 | int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num); |
| 241 | 242 | int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num); |
| 242 | 243 | int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority, |
| @@ -43,9 +43,7 @@ static bool check_image_valid(struct hinic_devlink_priv *priv, const u8 *buf, · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | for (i = 0; i < fw_image->fw_info.fw_section_cnt; i++) { |
| 45 | 45 | len += fw_image->fw_section_info[i].fw_section_len; |
| 46 | − memcpy(&host_image->image_section_info[i], | |
| 47 | − &fw_image->fw_section_info[i], | |
| 48 | − sizeof(struct fw_section_info_st)); | |
| 46 | + host_image->image_section_info[i] = fw_image->fw_section_info[i]; | |
| 49 | 47 | } |
| 50 | 48 | |
| 51 | 49 | if (len != fw_image->fw_len || |
| @@ -2586,15 +2586,16 @@ static void i40e_diag_test(struct net_device *netdev, · 2585 unmodified lines | ||
| 2586 | 2586 | |
| 2587 | 2587 | set_bit(__I40E_TESTING, pf->state); |
| 2588 | 2588 | |
| 2589 | + if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || | |
| 2590 | + test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) { | |
| 2591 | + dev_warn(&pf->pdev->dev, | |
| 2592 | + "Cannot start offline testing when PF is in reset state.\n"); | |
| 2593 | + goto skip_ol_tests; | |
| 2594 | + } | |
| 2595 | + | |
| 2589 | 2596 | if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) { |
| 2590 | 2597 | dev_warn(&pf->pdev->dev, |
| 2591 | 2598 | "Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n"); |
| 2592 | − data[I40E_ETH_TEST_REG] = 1; | |
| 2593 | − data[I40E_ETH_TEST_EEPROM] = 1; | |
| 2594 | − data[I40E_ETH_TEST_INTR] = 1; | |
| 2595 | − data[I40E_ETH_TEST_LINK] = 1; | |
| 2596 | − eth_test->flags |= ETH_TEST_FL_FAILED; | |
| 2597 | − clear_bit(__I40E_TESTING, pf->state); | |
| 2598 | 2599 | goto skip_ol_tests; |
| 2599 | 2600 | } |
| 2600 | 2601 | |
| @@ -2641,9 +2642,17 @@ static void i40e_diag_test(struct net_device *netdev, · 40 unmodified lines | ||
| 2641 | 2642 | data[I40E_ETH_TEST_INTR] = 0; |
| 2642 | 2643 | } |
| 2643 | 2644 | |
| 2644 | −skip_ol_tests: | |
| 2645 | − | |
| 2646 | 2645 | netif_info(pf, drv, netdev, "testing finished\n"); |
| 2646 | + return; | |
| 2647 | + | |
| 2648 | +skip_ol_tests: | |
| 2649 | + data[I40E_ETH_TEST_REG] = 1; | |
| 2650 | + data[I40E_ETH_TEST_EEPROM] = 1; | |
| 2651 | + data[I40E_ETH_TEST_INTR] = 1; | |
| 2652 | + data[I40E_ETH_TEST_LINK] = 1; | |
| 2653 | + eth_test->flags |= ETH_TEST_FL_FAILED; | |
| 2654 | + clear_bit(__I40E_TESTING, pf->state); | |
| 2655 | + netif_info(pf, drv, netdev, "testing failed\n"); | |
| 2647 | 2656 | } |
| 2648 | 2657 | |
| 2649 | 2658 | static void i40e_get_wol(struct net_device *netdev, |
| @@ -8542,6 +8542,11 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi, · 8541 unmodified lines | ||
| 8542 | 8542 | return -EOPNOTSUPP; |
| 8543 | 8543 | } |
| 8544 | 8544 | |
| 8545 | + if (!tc) { | |
| 8546 | + dev_err(&pf->pdev->dev, "Unable to add filter because of invalid destination"); | |
| 8547 | + return -EINVAL; | |
| 8548 | + } | |
| 8549 | + | |
| 8545 | 8550 | if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || |
| 8546 | 8551 | test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) |
| 8547 | 8552 | return -EBUSY; |
| @@ -2282,7 +2282,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) · 2281 unmodified lines | ||
| 2282 | 2282 | } |
| 2283 | 2283 | |
| 2284 | 2284 | if (vf->adq_enabled) { |
| 2285 | − for (i = 0; i < I40E_MAX_VF_VSI; i++) | |
| 2285 | + for (i = 0; i < vf->num_tc; i++) | |
| 2286 | 2286 | num_qps_all += vf->ch[i].num_qps; |
| 2287 | 2287 | if (num_qps_all != qci->num_queue_pairs) { |
| 2288 | 2288 | aq_ret = I40E_ERR_PARAM; |
| @@ -984,7 +984,7 @@ struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, · 983 unmodified lines | ||
| 984 | 984 | list_add_tail(&f->list, &adapter->mac_filter_list); |
| 985 | 985 | f->add = true; |
| 986 | 986 | f->is_new_mac = true; |
| 987 | − f->is_primary = false; | |
| 987 | + f->is_primary = ether_addr_equal(macaddr, adapter->hw.mac.addr); | |
| 988 | 988 | adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; |
| 989 | 989 | } else { |
| 990 | 990 | f->remove = false; |
| @@ -2189,6 +2189,42 @@ ice_setup_autoneg(struct ice_port_info *p, struct ethtool_link_ksettings *ks, · 2188 unmodified lines | ||
| 2189 | 2189 | return err; |
| 2190 | 2190 | } |
| 2191 | 2191 | |
| 2192 | +/** | |
| 2193 | + * ice_set_phy_type_from_speed - set phy_types based on speeds | |
| 2194 | + * and advertised modes | |
| 2195 | + * @ks: ethtool link ksettings struct | |
| 2196 | + * @phy_type_low: pointer to the lower part of phy_type | |
| 2197 | + * @phy_type_high: pointer to the higher part of phy_type | |
| 2198 | + * @adv_link_speed: targeted link speeds bitmap | |
| 2199 | + */ | |
| 2200 | +static void | |
| 2201 | +ice_set_phy_type_from_speed(const struct ethtool_link_ksettings *ks, | |
| 2202 | + u64 *phy_type_low, u64 *phy_type_high, | |
| 2203 | + u16 adv_link_speed) | |
| 2204 | +{ | |
| 2205 | + /* Handle 1000M speed in a special way because ice_update_phy_type | |
| 2206 | + * enables all link modes, but having mixed copper and optical | |
| 2207 | + * standards is not supported. | |
| 2208 | + */ | |
| 2209 | + adv_link_speed &= ~ICE_AQ_LINK_SPEED_1000MB; | |
| 2210 | + | |
| 2211 | + if (ethtool_link_ksettings_test_link_mode(ks, advertising, | |
| 2212 | + 1000baseT_Full)) | |
| 2213 | + *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_T | | |
| 2214 | + ICE_PHY_TYPE_LOW_1G_SGMII; | |
| 2215 | + | |
| 2216 | + if (ethtool_link_ksettings_test_link_mode(ks, advertising, | |
| 2217 | + 1000baseKX_Full)) | |
| 2218 | + *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_KX; | |
| 2219 | + | |
| 2220 | + if (ethtool_link_ksettings_test_link_mode(ks, advertising, | |
| 2221 | + 1000baseX_Full)) | |
| 2222 | + *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_SX | | |
| 2223 | + ICE_PHY_TYPE_LOW_1000BASE_LX; | |
| 2224 | + | |
| 2225 | + ice_update_phy_type(phy_type_low, phy_type_high, adv_link_speed); | |
| 2226 | +} | |
| 2227 | + | |
| 2192 | 2228 | /** |
| 2193 | 2229 | * ice_set_link_ksettings - Set Speed and Duplex |
| 2194 | 2230 | * @netdev: network interface device structure |
| @@ -2320,7 +2356,8 @@ ice_set_link_ksettings(struct net_device *netdev, · 125 unmodified lines | ||
| 2320 | 2356 | adv_link_speed = curr_link_speed; |
| 2321 | 2357 | |
| 2322 | 2358 | /* Convert the advertise link speeds to their corresponded PHY_TYPE */ |
| 2323 | − ice_update_phy_type(&phy_type_low, &phy_type_high, adv_link_speed); | |
| 2359 | + ice_set_phy_type_from_speed(ks, &phy_type_low, &phy_type_high, | |
| 2360 | + adv_link_speed); | |
| 2324 | 2361 | |
| 2325 | 2362 | if (!autoneg_changed && adv_link_speed == curr_link_speed) { |
| 2326 | 2363 | netdev_info(netdev, "Nothing changed, exiting without setting anything.\n"); |
| @@ -3470,6 +3507,16 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch) · 1143 unmodified lines | ||
| 3470 | 3507 | new_rx = ch->combined_count + ch->rx_count; |
| 3471 | 3508 | new_tx = ch->combined_count + ch->tx_count; |
| 3472 | 3509 | |
| 3510 | + if (new_rx < vsi->tc_cfg.numtc) { | |
| 3511 | + netdev_err(dev, "Cannot set less Rx channels, than Traffic Classes you have (%u)\n", | |
| 3512 | + vsi->tc_cfg.numtc); | |
| 3513 | + return -EINVAL; | |
| 3514 | + } | |
| 3515 | + if (new_tx < vsi->tc_cfg.numtc) { | |
| 3516 | + netdev_err(dev, "Cannot set less Tx channels, than Traffic Classes you have (%u)\n", | |
| 3517 | + vsi->tc_cfg.numtc); | |
| 3518 | + return -EINVAL; | |
| 3519 | + } | |
| 3473 | 3520 | if (new_rx > ice_get_max_rxq(pf)) { |
| 3474 | 3521 | netdev_err(dev, "Maximum allowed Rx channels is %d\n", |
| 3475 | 3522 | ice_get_max_rxq(pf)); |
| @@ -909,7 +909,7 @@ static void ice_set_dflt_vsi_ctx(struct ice_hw *hw, struct ice_vsi_ctx *ctxt) · 908 unmodified lines | ||
| 909 | 909 | * @vsi: the VSI being configured |
| 910 | 910 | * @ctxt: VSI context structure |
| 911 | 911 | */ |
| 912 | −static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) | |
| 912 | +static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) | |
| 913 | 913 | { |
| 914 | 914 | u16 offset = 0, qmap = 0, tx_count = 0, pow = 0; |
| 915 | 915 | u16 num_txq_per_tc, num_rxq_per_tc; |
| @@ -982,7 +982,18 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) · 66 unmodified lines | ||
| 982 | 982 | else |
| 983 | 983 | vsi->num_rxq = num_rxq_per_tc; |
| 984 | 984 | |
| 985 | + if (vsi->num_rxq > vsi->alloc_rxq) { | |
| 986 | + dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n", | |
| 987 | + vsi->num_rxq, vsi->alloc_rxq); | |
| 988 | + return -EINVAL; | |
| 989 | + } | |
| 990 | + | |
| 985 | 991 | vsi->num_txq = tx_count; |
| 992 | + if (vsi->num_txq > vsi->alloc_txq) { | |
| 993 | + dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n", | |
| 994 | + vsi->num_txq, vsi->alloc_txq); | |
| 995 | + return -EINVAL; | |
| 996 | + } | |
| 986 | 997 | |
| 987 | 998 | if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) { |
| 988 | 999 | dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n"); |
| @@ -1000,6 +1011,8 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt) · 11 unmodified lines | ||
| 1000 | 1011 | */ |
| 1001 | 1012 | ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]); |
| 1002 | 1013 | ctxt->info.q_mapping[1] = cpu_to_le16(vsi->num_rxq); |
| 1014 | + | |
| 1015 | + return 0; | |
| 1003 | 1016 | } |
| 1004 | 1017 | |
| 1005 | 1018 | /** |
| @@ -1187,7 +1200,10 @@ static int ice_vsi_init(struct ice_vsi *vsi, bool init_vsi) · 181 unmodified lines | ||
| 1187 | 1200 | if (vsi->type == ICE_VSI_CHNL) { |
| 1188 | 1201 | ice_chnl_vsi_setup_q_map(vsi, ctxt); |
| 1189 | 1202 | } else { |
| 1190 | − ice_vsi_setup_q_map(vsi, ctxt); | |
| 1203 | + ret = ice_vsi_setup_q_map(vsi, ctxt); | |
| 1204 | + if (ret) | |
| 1205 | + goto out; | |
| 1206 | + | |
| 1191 | 1207 | if (!init_vsi) /* means VSI being updated */ |
| 1192 | 1208 | /* must to indicate which section of VSI context are |
| 1193 | 1209 | * being modified |
| @@ -3464,7 +3480,7 @@ void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc) · 2270 unmodified lines | ||
| 3464 | 3480 | * |
| 3465 | 3481 | * Prepares VSI tc_config to have queue configurations based on MQPRIO options. |
| 3466 | 3482 | */ |
| 3467 | −static void | |
| 3483 | +static int | |
| 3468 | 3484 | ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt, |
| 3469 | 3485 | u8 ena_tc) |
| 3470 | 3486 | { |
| @@ -3513,7 +3529,18 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt, · 42 unmodified lines | ||
| 3513 | 3529 | |
| 3514 | 3530 | /* Set actual Tx/Rx queue pairs */ |
| 3515 | 3531 | vsi->num_txq = offset + qcount_tx; |
| 3532 | + if (vsi->num_txq > vsi->alloc_txq) { | |
| 3533 | + dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n", | |
| 3534 | + vsi->num_txq, vsi->alloc_txq); | |
| 3535 | + return -EINVAL; | |
| 3536 | + } | |
| 3537 | + | |
| 3516 | 3538 | vsi->num_rxq = offset + qcount_rx; |
| 3539 | + if (vsi->num_rxq > vsi->alloc_rxq) { | |
| 3540 | + dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n", | |
| 3541 | + vsi->num_rxq, vsi->alloc_rxq); | |
| 3542 | + return -EINVAL; | |
| 3543 | + } | |
| 3517 | 3544 | |
| 3518 | 3545 | /* Setup queue TC[0].qmap for given VSI context */ |
| 3519 | 3546 | ctxt->info.tc_mapping[0] = cpu_to_le16(qmap); |
| @@ -3531,6 +3558,8 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt, · 11 unmodified lines | ||
| 3531 | 3558 | dev_dbg(ice_pf_to_dev(vsi->back), "vsi->num_rxq = %d\n", vsi->num_rxq); |
| 3532 | 3559 | dev_dbg(ice_pf_to_dev(vsi->back), "all_numtc %u, all_enatc: 0x%04x, tc_cfg.numtc %u\n", |
| 3533 | 3560 | vsi->all_numtc, vsi->all_enatc, vsi->tc_cfg.numtc); |
| 3561 | + | |
| 3562 | + return 0; | |
| 3534 | 3563 | } |
| 3535 | 3564 | |
| 3536 | 3565 | /** |
| @@ -3580,9 +3609,12 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc) · 43 unmodified lines | ||
| 3580 | 3609 | |
| 3581 | 3610 | if (vsi->type == ICE_VSI_PF && |
| 3582 | 3611 | test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) |
| 3583 | − ice_vsi_setup_q_map_mqprio(vsi, ctx, ena_tc); | |
| 3612 | + ret = ice_vsi_setup_q_map_mqprio(vsi, ctx, ena_tc); | |
| 3584 | 3613 | else |
| 3585 | − ice_vsi_setup_q_map(vsi, ctx); | |
| 3614 | + ret = ice_vsi_setup_q_map(vsi, ctx); | |
| 3615 | + | |
| 3616 | + if (ret) | |
| 3617 | + goto out; | |
| 3586 | 3618 | |
| 3587 | 3619 | /* must to indicate which section of VSI context are being modified */ |
| 3588 | 3620 | ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID); |
| @@ -5763,25 +5763,38 @@ static netdev_features_t · 5762 unmodified lines | ||
| 5763 | 5763 | ice_fix_features(struct net_device *netdev, netdev_features_t features) |
| 5764 | 5764 | { |
| 5765 | 5765 | struct ice_netdev_priv *np = netdev_priv(netdev); |
| 5766 | − netdev_features_t supported_vlan_filtering; | |
| 5767 | − netdev_features_t requested_vlan_filtering; | |
| 5768 | − struct ice_vsi *vsi = np->vsi; | |
| 5769 | − | |
| 5770 | − requested_vlan_filtering = features & NETIF_VLAN_FILTERING_FEATURES; | |
| 5771 | − | |
| 5772 | − /* make sure supported_vlan_filtering works for both SVM and DVM */ | |
| 5773 | − supported_vlan_filtering = NETIF_F_HW_VLAN_CTAG_FILTER; | |
| 5774 | − if (ice_is_dvm_ena(&vsi->back->hw)) | |
| 5775 | − supported_vlan_filtering |= NETIF_F_HW_VLAN_STAG_FILTER; | |
| 5776 | − | |
| 5777 | − if (requested_vlan_filtering && | |
| 5778 | − requested_vlan_filtering != supported_vlan_filtering) { | |
| 5779 | − if (requested_vlan_filtering & NETIF_F_HW_VLAN_CTAG_FILTER) { | |
| 5780 | − netdev_warn(netdev, "cannot support requested VLAN filtering settings, enabling all supported VLAN filtering settings\n"); | |
| 5781 | − features |= supported_vlan_filtering; | |
| 5766 | + netdev_features_t req_vlan_fltr, cur_vlan_fltr; | |
| 5767 | + bool cur_ctag, cur_stag, req_ctag, req_stag; | |
| 5768 | + | |
| 5769 | + cur_vlan_fltr = netdev->features & NETIF_VLAN_FILTERING_FEATURES; | |
| 5770 | + cur_ctag = cur_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER; | |
| 5771 | + cur_stag = cur_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER; | |
| 5772 | + | |
| 5773 | + req_vlan_fltr = features & NETIF_VLAN_FILTERING_FEATURES; | |
| 5774 | + req_ctag = req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER; | |
| 5775 | + req_stag = req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER; | |
| 5776 | + | |
| 5777 | + if (req_vlan_fltr != cur_vlan_fltr) { | |
| 5778 | + if (ice_is_dvm_ena(&np->vsi->back->hw)) { | |
| 5779 | + if (req_ctag && req_stag) { | |
| 5780 | + features |= NETIF_VLAN_FILTERING_FEATURES; | |
| 5781 | + } else if (!req_ctag && !req_stag) { | |
| 5782 | + features &= ~NETIF_VLAN_FILTERING_FEATURES; | |
| 5783 | + } else if ((!cur_ctag && req_ctag && !cur_stag) || | |
| 5784 | + (!cur_stag && req_stag && !cur_ctag)) { | |
| 5785 | + features |= NETIF_VLAN_FILTERING_FEATURES; | |
| 5786 | + netdev_warn(netdev, "802.1Q and 802.1ad VLAN filtering must be either both on or both off. VLAN filtering has been enabled for both types.\n"); | |
| 5787 | + } else if ((cur_ctag && !req_ctag && cur_stag) || | |
| 5788 | + (cur_stag && !req_stag && cur_ctag)) { | |
| 5789 | + features &= ~NETIF_VLAN_FILTERING_FEATURES; | |
| 5790 | + netdev_warn(netdev, "802.1Q and 802.1ad VLAN filtering must be either both on or both off. VLAN filtering has been disabled for both types.\n"); | |
| 5791 | + } | |
| 5782 | 5792 | } else { |
| 5783 | − netdev_warn(netdev, "cannot support requested VLAN filtering settings, clearing all supported VLAN filtering settings\n"); | |
| 5784 | − features &= ~supported_vlan_filtering; | |
| 5793 | + if (req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER) | |
| 5794 | + netdev_warn(netdev, "cannot support requested 802.1ad filtering setting in SVM mode\n"); | |
| 5795 | + | |
| 5796 | + if (req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER) | |
| 5797 | + features |= NETIF_F_HW_VLAN_CTAG_FILTER; | |
| 5785 | 5798 | } |
| 5786 | 5799 | } |
| 5787 | 5800 | |
| @@ -2271,7 +2271,7 @@ static int · 2270 unmodified lines | ||
| 2271 | 2271 | ice_ptp_init_tx_e822(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port) |
| 2272 | 2272 | { |
| 2273 | 2273 | tx->quad = port / ICE_PORTS_PER_QUAD; |
| 2274 | − tx->quad_offset = tx->quad * INDEX_PER_PORT; | |
| 2274 | + tx->quad_offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT; | |
| 2275 | 2275 | tx->len = INDEX_PER_PORT; |
| 2276 | 2276 | |
| 2277 | 2277 | return ice_ptp_alloc_tx_tracker(tx); |
| @@ -49,6 +49,37 @@ struct ice_perout_channel { · 48 unmodified lines | ||
| 49 | 49 | * To allow multiple ports to access the shared register block independently, |
| 50 | 50 | * the blocks are split up so that indexes are assigned to each port based on |
| 51 | 51 | * hardware logical port number. |
| 52 | + * | |
| 53 | + * The timestamp blocks are handled differently for E810- and E822-based | |
| 54 | + * devices. In E810 devices, each port has its own block of timestamps, while in | |
| 55 | + * E822 there is a need to logically break the block of registers into smaller | |
| 56 | + * chunks based on the port number to avoid collisions. | |
| 57 | + * | |
| 58 | + * Example for port 5 in E810: | |
| 59 | + * +--------+--------+--------+--------+--------+--------+--------+--------+ | |
| 60 | + * |register|register|register|register|register|register|register|register| | |
| 61 | + * | block | block | block | block | block | block | block | block | | |
| 62 | + * | for | for | for | for | for | for | for | for | | |
| 63 | + * | port 0 | port 1 | port 2 | port 3 | port 4 | port 5 | port 6 | port 7 | | |
| 64 | + * +--------+--------+--------+--------+--------+--------+--------+--------+ | |
| 65 | + * ^^ | |
| 66 | + * || | |
| 67 | + * |--- quad offset is always 0 | |
| 68 | + * ---- quad number | |
| 69 | + * | |
| 70 | + * Example for port 5 in E822: | |
| 71 | + * +-----------------------------+-----------------------------+ | |
| 72 | + * | register block for quad 0 | register block for quad 1 | | |
| 73 | + * |+------+------+------+------+|+------+------+------+------+| | |
| 74 | + * ||port 0|port 1|port 2|port 3|||port 0|port 1|port 2|port 3|| | |
| 75 | + * |+------+------+------+------+|+------+------+------+------+| | |
| 76 | + * +-----------------------------+-------^---------------------+ | |
| 77 | + * ^ | | |
| 78 | + * | --- quad offset* | |
| 79 | + * ---- quad number | |
| 80 | + * | |
| 81 | + * * PHY port 5 is port 1 in quad 1 | |
| 82 | + * | |
| 52 | 83 | */ |
| 53 | 84 | |
| 54 | 85 | /** |
| @@ -524,6 +524,7 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr) · 523 unmodified lines | ||
| 524 | 524 | */ |
| 525 | 525 | fltr->rid = rule_added.rid; |
| 526 | 526 | fltr->rule_id = rule_added.rule_id; |
| 527 | + fltr->dest_id = rule_added.vsi_handle; | |
| 527 | 528 | |
| 528 | 529 | exit: |
| 529 | 530 | kfree(list); |
| @@ -993,7 +994,9 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi, · 463 unmodified lines | ||
| 993 | 994 | n_proto_key = ntohs(match.key->n_proto); |
| 994 | 995 | n_proto_mask = ntohs(match.mask->n_proto); |
| 995 | 996 | |
| 996 | − if (n_proto_key == ETH_P_ALL || n_proto_key == 0) { | |
| 997 | + if (n_proto_key == ETH_P_ALL || n_proto_key == 0 || | |
| 998 | + fltr->tunnel_type == TNL_GTPU || | |
| 999 | + fltr->tunnel_type == TNL_GTPC) { | |
| 997 | 1000 | n_proto_key = 0; |
| 998 | 1001 | n_proto_mask = 0; |
| 999 | 1002 | } else { |
| @@ -504,6 +504,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) · 503 unmodified lines | ||
| 504 | 504 | } |
| 505 | 505 | |
| 506 | 506 | if (ice_is_vf_disabled(vf)) { |
| 507 | + vsi = ice_get_vf_vsi(vf); | |
| 508 | + if (WARN_ON(!vsi)) | |
| 509 | + return -EINVAL; | |
| 510 | + ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id); | |
| 511 | + ice_vsi_stop_all_rx_rings(vsi); | |
| 507 | 512 | dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n", |
| 508 | 513 | vf->vf_id); |
| 509 | 514 | return 0; |
| @@ -1569,35 +1569,27 @@ error_param: · 1568 unmodified lines | ||
| 1569 | 1569 | */ |
| 1570 | 1570 | static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) |
| 1571 | 1571 | { |
| 1572 | − enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; | |
| 1573 | 1572 | struct virtchnl_vsi_queue_config_info *qci = |
| 1574 | 1573 | (struct virtchnl_vsi_queue_config_info *)msg; |
| 1575 | 1574 | struct virtchnl_queue_pair_info *qpi; |
| 1576 | 1575 | struct ice_pf *pf = vf->pf; |
| 1577 | 1576 | struct ice_vsi *vsi; |
| 1578 | − int i, q_idx; | |
| 1577 | + int i = -1, q_idx; | |
| 1579 | 1578 | |
| 1580 | − if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { | |
| 1581 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1579 | + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) | |
| 1582 | 1580 | goto error_param; |
| 1583 | − } | |
| 1584 | 1581 | |
| 1585 | − if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) { | |
| 1586 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1582 | + if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) | |
| 1587 | 1583 | goto error_param; |
| 1588 | − } | |
| 1589 | 1584 | |
| 1590 | 1585 | vsi = ice_get_vf_vsi(vf); |
| 1591 | − if (!vsi) { | |
| 1592 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1586 | + if (!vsi) | |
| 1593 | 1587 | goto error_param; |
| 1594 | − } | |
| 1595 | 1588 | |
| 1596 | 1589 | if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF || |
| 1597 | 1590 | qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { |
| 1598 | 1591 | dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n", |
| 1599 | 1592 | vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); |
| 1600 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1601 | 1593 | goto error_param; |
| 1602 | 1594 | } |
| 1603 | 1595 | |
| @@ -1610,7 +1602,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 6 unmodified lines | ||
| 1610 | 1602 | !ice_vc_isvalid_ring_len(qpi->txq.ring_len) || |
| 1611 | 1603 | !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) || |
| 1612 | 1604 | !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) { |
| 1613 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1614 | 1605 | goto error_param; |
| 1615 | 1606 | } |
| 1616 | 1607 | |
| @@ -1620,7 +1611,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 3 unmodified lines | ||
| 1620 | 1611 | * for selected "vsi" |
| 1621 | 1612 | */ |
| 1622 | 1613 | if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) { |
| 1623 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1624 | 1614 | goto error_param; |
| 1625 | 1615 | } |
| 1626 | 1616 | |
| @@ -1630,14 +1620,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 3 unmodified lines | ||
| 1630 | 1620 | vsi->tx_rings[i]->count = qpi->txq.ring_len; |
| 1631 | 1621 | |
| 1632 | 1622 | /* Disable any existing queue first */ |
| 1633 | − if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) { | |
| 1634 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1623 | + if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) | |
| 1635 | 1624 | goto error_param; |
| 1636 | − } | |
| 1637 | 1625 | |
| 1638 | 1626 | /* Configure a queue with the requested settings */ |
| 1639 | 1627 | if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { |
| 1640 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1628 | + dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n", | |
| 1629 | + vf->vf_id, i); | |
| 1641 | 1630 | goto error_param; |
| 1642 | 1631 | } |
| 1643 | 1632 | } |
| @@ -1651,17 +1640,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 7 unmodified lines | ||
| 1651 | 1640 | |
| 1652 | 1641 | if (qpi->rxq.databuffer_size != 0 && |
| 1653 | 1642 | (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || |
| 1654 | − qpi->rxq.databuffer_size < 1024)) { | |
| 1655 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1643 | + qpi->rxq.databuffer_size < 1024)) | |
| 1656 | 1644 | goto error_param; |
| 1657 | − } | |
| 1658 | 1645 | vsi->rx_buf_len = qpi->rxq.databuffer_size; |
| 1659 | 1646 | vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len; |
| 1660 | 1647 | if (qpi->rxq.max_pkt_size > max_frame_size || |
| 1661 | − qpi->rxq.max_pkt_size < 64) { | |
| 1662 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1648 | + qpi->rxq.max_pkt_size < 64) | |
| 1663 | 1649 | goto error_param; |
| 1664 | − } | |
| 1665 | 1650 | |
| 1666 | 1651 | vsi->max_frame = qpi->rxq.max_pkt_size; |
| 1667 | 1652 | /* add space for the port VLAN since the VF driver is |
| @@ -1672,16 +1657,30 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 4 unmodified lines | ||
| 1672 | 1657 | vsi->max_frame += VLAN_HLEN; |
| 1673 | 1658 | |
| 1674 | 1659 | if (ice_vsi_cfg_single_rxq(vsi, q_idx)) { |
| 1675 | − v_ret = VIRTCHNL_STATUS_ERR_PARAM; | |
| 1660 | + dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n", | |
| 1661 | + vf->vf_id, i); | |
| 1676 | 1662 | goto error_param; |
| 1677 | 1663 | } |
| 1678 | 1664 | } |
| 1679 | 1665 | } |
| 1680 | 1666 | |
| 1667 | + /* send the response to the VF */ | |
| 1668 | + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, | |
| 1669 | + VIRTCHNL_STATUS_SUCCESS, NULL, 0); | |
| 1681 | 1670 | error_param: |
| 1671 | + /* disable whatever we can */ | |
| 1672 | + for (; i >= 0; i--) { | |
| 1673 | + if (ice_vsi_ctrl_one_rx_ring(vsi, false, i, true)) | |
| 1674 | + dev_err(ice_pf_to_dev(pf), "VF-%d could not disable RX queue %d\n", | |
| 1675 | + vf->vf_id, i); | |
| 1676 | + if (ice_vf_vsi_dis_single_txq(vf, vsi, i)) | |
| 1677 | + dev_err(ice_pf_to_dev(pf), "VF-%d could not disable TX queue %d\n", | |
| 1678 | + vf->vf_id, i); | |
| 1679 | + } | |
| 1680 | + | |
| 1682 | 1681 | /* send the response to the VF */ |
| 1683 | − return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, v_ret, | |
| 1684 | − NULL, 0); | |
| 1682 | + return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, | |
| 1683 | + VIRTCHNL_STATUS_ERR_PARAM, NULL, 0); | |
| 1685 | 1684 | } |
| 1686 | 1685 | |
| 1687 | 1686 | /** |
| @@ -4819,8 +4819,11 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring) · 4818 unmodified lines | ||
| 4819 | 4819 | while (i != tx_ring->next_to_use) { |
| 4820 | 4820 | union e1000_adv_tx_desc *eop_desc, *tx_desc; |
| 4821 | 4821 | |
| 4822 | − /* Free all the Tx ring sk_buffs */ | |
| 4823 | − dev_kfree_skb_any(tx_buffer->skb); | |
| 4822 | + /* Free all the Tx ring sk_buffs or xdp frames */ | |
| 4823 | + if (tx_buffer->type == IGB_TYPE_SKB) | |
| 4824 | + dev_kfree_skb_any(tx_buffer->skb); | |
| 4825 | + else | |
| 4826 | + xdp_return_frame(tx_buffer->xdpf); | |
| 4824 | 4827 | |
| 4825 | 4828 | /* unmap skb header data */ |
| 4826 | 4829 | dma_unmap_single(tx_ring->dev, |
| @@ -9898,11 +9901,10 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) · 5071 unmodified lines | ||
| 9898 | 9901 | struct e1000_hw *hw = &adapter->hw; |
| 9899 | 9902 | u32 dmac_thr; |
| 9900 | 9903 | u16 hwm; |
| 9904 | + u32 reg; | |
| 9901 | 9905 | |
| 9902 | 9906 | if (hw->mac.type > e1000_82580) { |
| 9903 | 9907 | if (adapter->flags & IGB_FLAG_DMAC) { |
| 9904 | − u32 reg; | |
| 9905 | − | |
| 9906 | 9908 | /* force threshold to 0. */ |
| 9907 | 9909 | wr32(E1000_DMCTXTH, 0); |
| 9908 | 9910 | |
| @@ -9935,7 +9937,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) · 26 unmodified lines | ||
| 9935 | 9937 | /* Disable BMC-to-OS Watchdog Enable */ |
| 9936 | 9938 | if (hw->mac.type != e1000_i354) |
| 9937 | 9939 | reg &= ~E1000_DMACR_DC_BMC2OSW_EN; |
| 9938 | − | |
| 9939 | 9940 | wr32(E1000_DMACR, reg); |
| 9940 | 9941 | |
| 9941 | 9942 | /* no lower threshold to disable |
| @@ -9952,12 +9953,12 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) · 10 unmodified lines | ||
| 9952 | 9953 | */ |
| 9953 | 9954 | wr32(E1000_DMCTXTH, (IGB_MIN_TXPBSIZE - |
| 9954 | 9955 | (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6); |
| 9956 | + } | |
| 9955 | 9957 | |
| 9956 | − /* make low power state decision controlled | |
| 9957 | − * by DMA coal | |
| 9958 | − */ | |
| 9958 | + if (hw->mac.type >= e1000_i210 || | |
| 9959 | + (adapter->flags & IGB_FLAG_DMAC)) { | |
| 9959 | 9960 | reg = rd32(E1000_PCIEMISC); |
| 9960 | − reg &= ~E1000_PCIEMISC_LX_DECISION; | |
| 9961 | + reg |= E1000_PCIEMISC_LX_DECISION; | |
| 9961 | 9962 | wr32(E1000_PCIEMISC, reg); |
| 9962 | 9963 | } /* endif adapter->dmac is not disabled */ |
| 9963 | 9964 | } else if (hw->mac.type == e1000_82580) { |
| @@ -1390,7 +1390,8 @@ static int otx2vf_get_link_ksettings(struct net_device *netdev, · 1389 unmodified lines | ||
| 1390 | 1390 | |
| 1391 | 1391 | static const struct ethtool_ops otx2vf_ethtool_ops = { |
| 1392 | 1392 | .supported_coalesce_params = ETHTOOL_COALESCE_USECS | |
| 1393 | − ETHTOOL_COALESCE_MAX_FRAMES, | |
| 1393 | + ETHTOOL_COALESCE_MAX_FRAMES | | |
| 1394 | + ETHTOOL_COALESCE_USE_ADAPTIVE, | |
| 1394 | 1395 | .supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN | |
| 1395 | 1396 | ETHTOOL_RING_USE_CQE_SIZE, |
| 1396 | 1397 | .get_link = otx2_get_link, |
| @@ -8,8 +8,8 @@ · 7 unmodified lines | ||
| 8 | 8 | #include "spectrum.h" |
| 9 | 9 | |
| 10 | 10 | enum mlxsw_sp_counter_sub_pool_id { |
| 11 | − MLXSW_SP_COUNTER_SUB_POOL_FLOW, | |
| 12 | 11 | MLXSW_SP_COUNTER_SUB_POOL_RIF, |
| 12 | + MLXSW_SP_COUNTER_SUB_POOL_FLOW, | |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | 15 | int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp, |
| @@ -547,6 +547,57 @@ static inline void axienet_iow(struct axienet_local *lp, off_t offset, · 546 unmodified lines | ||
| 547 | 547 | iowrite32(value, lp->regs + offset); |
| 548 | 548 | } |
| 549 | 549 | |
| 550 | +/** | |
| 551 | + * axienet_dma_out32 - Memory mapped Axi DMA register write. | |
| 552 | + * @lp: Pointer to axienet local structure | |
| 553 | + * @reg: Address offset from the base address of the Axi DMA core | |
| 554 | + * @value: Value to be written into the Axi DMA register | |
| 555 | + * | |
| 556 | + * This function writes the desired value into the corresponding Axi DMA | |
| 557 | + * register. | |
| 558 | + */ | |
| 559 | + | |
| 560 | +static inline void axienet_dma_out32(struct axienet_local *lp, | |
| 561 | + off_t reg, u32 value) | |
| 562 | +{ | |
| 563 | + iowrite32(value, lp->dma_regs + reg); | |
| 564 | +} | |
| 565 | + | |
| 566 | +#if defined(CONFIG_64BIT) && defined(iowrite64) | |
| 567 | +/** | |
| 568 | + * axienet_dma_out64 - Memory mapped Axi DMA register write. | |
| 569 | + * @lp: Pointer to axienet local structure | |
| 570 | + * @reg: Address offset from the base address of the Axi DMA core | |
| 571 | + * @value: Value to be written into the Axi DMA register | |
| 572 | + * | |
| 573 | + * This function writes the desired value into the corresponding Axi DMA | |
| 574 | + * register. | |
| 575 | + */ | |
| 576 | +static inline void axienet_dma_out64(struct axienet_local *lp, | |
| 577 | + off_t reg, u64 value) | |
| 578 | +{ | |
| 579 | + iowrite64(value, lp->dma_regs + reg); | |
| 580 | +} | |
| 581 | + | |
| 582 | +static inline void axienet_dma_out_addr(struct axienet_local *lp, off_t reg, | |
| 583 | + dma_addr_t addr) | |
| 584 | +{ | |
| 585 | + if (lp->features & XAE_FEATURE_DMA_64BIT) | |
| 586 | + axienet_dma_out64(lp, reg, addr); | |
| 587 | + else | |
| 588 | + axienet_dma_out32(lp, reg, lower_32_bits(addr)); | |
| 589 | +} | |
| 590 | + | |
| 591 | +#else /* CONFIG_64BIT */ | |
| 592 | + | |
| 593 | +static inline void axienet_dma_out_addr(struct axienet_local *lp, off_t reg, | |
| 594 | + dma_addr_t addr) | |
| 595 | +{ | |
| 596 | + axienet_dma_out32(lp, reg, lower_32_bits(addr)); | |
| 597 | +} | |
| 598 | + | |
| 599 | +#endif /* CONFIG_64BIT */ | |
| 600 | + | |
| 550 | 601 | /* Function prototypes visible in xilinx_axienet_mdio.c for other files */ |
| 551 | 602 | int axienet_mdio_enable(struct axienet_local *lp); |
| 552 | 603 | void axienet_mdio_disable(struct axienet_local *lp); |
| @@ -133,30 +133,6 @@ static inline u32 axienet_dma_in32(struct axienet_local *lp, off_t reg) · 132 unmodified lines | ||
| 133 | 133 | return ioread32(lp->dma_regs + reg); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | −/** | |
| 137 | − * axienet_dma_out32 - Memory mapped Axi DMA register write. | |
| 138 | − * @lp: Pointer to axienet local structure | |
| 139 | − * @reg: Address offset from the base address of the Axi DMA core | |
| 140 | − * @value: Value to be written into the Axi DMA register | |
| 141 | − * | |
| 142 | − * This function writes the desired value into the corresponding Axi DMA | |
| 143 | − * register. | |
| 144 | − */ | |
| 145 | −static inline void axienet_dma_out32(struct axienet_local *lp, | |
| 146 | − off_t reg, u32 value) | |
| 147 | −{ | |
| 148 | − iowrite32(value, lp->dma_regs + reg); | |
| 149 | −} | |
| 150 | − | |
| 151 | −static void axienet_dma_out_addr(struct axienet_local *lp, off_t reg, | |
| 152 | − dma_addr_t addr) | |
| 153 | −{ | |
| 154 | − axienet_dma_out32(lp, reg, lower_32_bits(addr)); | |
| 155 | − | |
| 156 | − if (lp->features & XAE_FEATURE_DMA_64BIT) | |
| 157 | − axienet_dma_out32(lp, reg + 4, upper_32_bits(addr)); | |
| 158 | −} | |
| 159 | − | |
| 160 | 136 | static void desc_set_phys_addr(struct axienet_local *lp, dma_addr_t addr, |
| 161 | 137 | struct axidma_bd *desc) |
| 162 | 138 | { |
| @@ -2061,6 +2037,11 @@ static int axienet_probe(struct platform_device *pdev) · 1898 unmodified lines | ||
| 2061 | 2037 | iowrite32(0x0, desc); |
| 2062 | 2038 | } |
| 2063 | 2039 | } |
| 2040 | + if (!IS_ENABLED(CONFIG_64BIT) && lp->features & XAE_FEATURE_DMA_64BIT) { | |
| 2041 | + dev_err(&pdev->dev, "64-bit addressable DMA is not compatible with 32-bit archecture\n"); | |
| 2042 | + ret = -EINVAL; | |
| 2043 | + goto cleanup_clk; | |
| 2044 | + } | |
| 2064 | 2045 | |
| 2065 | 2046 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); |
| 2066 | 2047 | if (ret) { |
| @@ -99,6 +99,7 @@ struct sixpack { · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | unsigned int rx_count; |
| 101 | 101 | unsigned int rx_count_cooked; |
| 102 | + spinlock_t rxlock; | |
| 102 | 103 | |
| 103 | 104 | int mtu; /* Our mtu (to spot changes!) */ |
| 104 | 105 | int buffsize; /* Max buffers sizes */ |
| @@ -565,6 +566,7 @@ static int sixpack_open(struct tty_struct *tty) · 460 unmodified lines | ||
| 565 | 566 | sp->dev = dev; |
| 566 | 567 | |
| 567 | 568 | spin_lock_init(&sp->lock); |
| 569 | + spin_lock_init(&sp->rxlock); | |
| 568 | 570 | refcount_set(&sp->refcnt, 1); |
| 569 | 571 | init_completion(&sp->dead); |
| 570 | 572 | |
| @@ -913,6 +915,7 @@ static void decode_std_command(struct sixpack *sp, unsigned char cmd) · 342 unmodified lines | ||
| 913 | 915 | sp->led_state = 0x60; |
| 914 | 916 | /* fill trailing bytes with zeroes */ |
| 915 | 917 | sp->tty->ops->write(sp->tty, &sp->led_state, 1); |
| 918 | + spin_lock_bh(&sp->rxlock); | |
| 916 | 919 | rest = sp->rx_count; |
| 917 | 920 | if (rest != 0) |
| 918 | 921 | for (i = rest; i <= 3; i++) |
| @@ -930,6 +933,7 @@ static void decode_std_command(struct sixpack *sp, unsigned char cmd) · 11 unmodified lines | ||
| 930 | 933 | sp_bump(sp, 0); |
| 931 | 934 | } |
| 932 | 935 | sp->rx_count_cooked = 0; |
| 936 | + spin_unlock_bh(&sp->rxlock); | |
| 933 | 937 | } |
| 934 | 938 | break; |
| 935 | 939 | case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n"); |
| @@ -959,8 +963,11 @@ sixpack_decode(struct sixpack *sp, const unsigned char *pre_rbuff, int count) · 23 unmodified lines | ||
| 959 | 963 | decode_prio_command(sp, inbyte); |
| 960 | 964 | else if ((inbyte & SIXP_STD_CMD_MASK) != 0) |
| 961 | 965 | decode_std_command(sp, inbyte); |
| 962 | − else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK) | |
| 966 | + else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK) { | |
| 967 | + spin_lock_bh(&sp->rxlock); | |
| 963 | 968 | decode_data(sp, inbyte); |
| 969 | + spin_unlock_bh(&sp->rxlock); | |
| 970 | + } | |
| 964 | 971 | } |
| 965 | 972 | } |
| 966 | 973 | |
| @@ -34,6 +34,8 @@ · 33 unmodified lines | ||
| 34 | 34 | #define MDIO_AN_VEND_PROV 0xc400 |
| 35 | 35 | #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) |
| 36 | 36 | #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) |
| 37 | +#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) | |
| 38 | +#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) | |
| 37 | 39 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) |
| 38 | 40 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) |
| 39 | 41 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 |
| @@ -231,9 +233,20 @@ static int aqr_config_aneg(struct phy_device *phydev) · 191 unmodified lines | ||
| 231 | 233 | phydev->advertising)) |
| 232 | 234 | reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; |
| 233 | 235 | |
| 236 | + /* Handle the case when the 2.5G and 5G speeds are not advertised */ | |
| 237 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, | |
| 238 | + phydev->advertising)) | |
| 239 | + reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; | |
| 240 | + | |
| 241 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, | |
| 242 | + phydev->advertising)) | |
| 243 | + reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; | |
| 244 | + | |
| 234 | 245 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, |
| 235 | 246 | MDIO_AN_VEND_PROV_1000BASET_HALF | |
| 236 | − MDIO_AN_VEND_PROV_1000BASET_FULL, reg); | |
| 247 | + MDIO_AN_VEND_PROV_1000BASET_FULL | | |
| 248 | + MDIO_AN_VEND_PROV_2500BASET_FULL | | |
| 249 | + MDIO_AN_VEND_PROV_5000BASET_FULL, reg); | |
| 237 | 250 | if (ret < 0) |
| 238 | 251 | return ret; |
| 239 | 252 | if (ret > 0) |
| @@ -2072,6 +2072,8 @@ static struct phy_driver at803x_driver[] = { · 2071 unmodified lines | ||
| 2072 | 2072 | /* ATHEROS AR9331 */ |
| 2073 | 2073 | PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), |
| 2074 | 2074 | .name = "Qualcomm Atheros AR9331 built-in PHY", |
| 2075 | + .probe = at803x_probe, | |
| 2076 | + .remove = at803x_remove, | |
| 2075 | 2077 | .suspend = at803x_suspend, |
| 2076 | 2078 | .resume = at803x_resume, |
| 2077 | 2079 | .flags = PHY_POLL_CABLE_TEST, |
| @@ -2087,6 +2089,8 @@ static struct phy_driver at803x_driver[] = { · 9 unmodified lines | ||
| 2087 | 2089 | /* Qualcomm Atheros QCA9561 */ |
| 2088 | 2090 | PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), |
| 2089 | 2091 | .name = "Qualcomm Atheros QCA9561 built-in PHY", |
| 2092 | + .probe = at803x_probe, | |
| 2093 | + .remove = at803x_remove, | |
| 2090 | 2094 | .suspend = at803x_suspend, |
| 2091 | 2095 | .resume = at803x_resume, |
| 2092 | 2096 | .flags = PHY_POLL_CABLE_TEST, |
| @@ -2151,6 +2155,8 @@ static struct phy_driver at803x_driver[] = { · 58 unmodified lines | ||
| 2151 | 2155 | PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), |
| 2152 | 2156 | .name = "Qualcomm QCA8081", |
| 2153 | 2157 | .flags = PHY_POLL_CABLE_TEST, |
| 2158 | + .probe = at803x_probe, | |
| 2159 | + .remove = at803x_remove, | |
| 2154 | 2160 | .config_intr = at803x_config_intr, |
| 2155 | 2161 | .handle_interrupt = at803x_handle_interrupt, |
| 2156 | 2162 | .get_tunable = at803x_get_tunable, |
| @@ -110,7 +110,7 @@ static int smsc_phy_config_init(struct phy_device *phydev) · 109 unmodified lines | ||
| 110 | 110 | struct smsc_phy_priv *priv = phydev->priv; |
| 111 | 111 | int rc; |
| 112 | 112 | |
| 113 | − if (!priv->energy_enable) | |
| 113 | + if (!priv->energy_enable || phydev->irq != PHY_POLL) | |
| 114 | 114 | return 0; |
| 115 | 115 | |
| 116 | 116 | rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); |
| @@ -210,6 +210,8 @@ static int lan95xx_config_aneg_ext(struct phy_device *phydev) · 93 unmodified lines | ||
| 210 | 210 | * response on link pulses to detect presence of plugged Ethernet cable. |
| 211 | 211 | * The Energy Detect Power-Down mode is enabled again in the end of procedure to |
| 212 | 212 | * save approximately 220 mW of power if cable is unplugged. |
| 213 | + * The workaround is only applicable to poll mode. Energy Detect Power-Down may | |
| 214 | + * not be used in interrupt mode lest link change detection becomes unreliable. | |
| 213 | 215 | */ |
| 214 | 216 | static int lan87xx_read_status(struct phy_device *phydev) |
| 215 | 217 | { |
| @@ -217,7 +219,7 @@ static int lan87xx_read_status(struct phy_device *phydev) · 1 unmodified line | ||
| 217 | 219 | |
| 218 | 220 | int err = genphy_read_status(phydev); |
| 219 | 221 | |
| 220 | − if (!phydev->link && priv->energy_enable) { | |
| 222 | + if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) { | |
| 221 | 223 | /* Disable EDPD to wake up PHY */ |
| 222 | 224 | int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); |
| 223 | 225 | if (rc < 0) |
| @@ -1750,7 +1750,7 @@ static const struct driver_info ax88179_info = { · 1749 unmodified lines | ||
| 1750 | 1750 | .link_reset = ax88179_link_reset, |
| 1751 | 1751 | .reset = ax88179_reset, |
| 1752 | 1752 | .stop = ax88179_stop, |
| 1753 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1753 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1754 | 1754 | .rx_fixup = ax88179_rx_fixup, |
| 1755 | 1755 | .tx_fixup = ax88179_tx_fixup, |
| 1756 | 1756 | }; |
| @@ -1763,7 +1763,7 @@ static const struct driver_info ax88178a_info = { · 6 unmodified lines | ||
| 1763 | 1763 | .link_reset = ax88179_link_reset, |
| 1764 | 1764 | .reset = ax88179_reset, |
| 1765 | 1765 | .stop = ax88179_stop, |
| 1766 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1766 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1767 | 1767 | .rx_fixup = ax88179_rx_fixup, |
| 1768 | 1768 | .tx_fixup = ax88179_tx_fixup, |
| 1769 | 1769 | }; |
| @@ -1776,7 +1776,7 @@ static const struct driver_info cypress_GX3_info = { · 6 unmodified lines | ||
| 1776 | 1776 | .link_reset = ax88179_link_reset, |
| 1777 | 1777 | .reset = ax88179_reset, |
| 1778 | 1778 | .stop = ax88179_stop, |
| 1779 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1779 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1780 | 1780 | .rx_fixup = ax88179_rx_fixup, |
| 1781 | 1781 | .tx_fixup = ax88179_tx_fixup, |
| 1782 | 1782 | }; |
| @@ -1789,7 +1789,7 @@ static const struct driver_info dlink_dub1312_info = { · 6 unmodified lines | ||
| 1789 | 1789 | .link_reset = ax88179_link_reset, |
| 1790 | 1790 | .reset = ax88179_reset, |
| 1791 | 1791 | .stop = ax88179_stop, |
| 1792 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1792 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1793 | 1793 | .rx_fixup = ax88179_rx_fixup, |
| 1794 | 1794 | .tx_fixup = ax88179_tx_fixup, |
| 1795 | 1795 | }; |
| @@ -1802,7 +1802,7 @@ static const struct driver_info sitecom_info = { · 6 unmodified lines | ||
| 1802 | 1802 | .link_reset = ax88179_link_reset, |
| 1803 | 1803 | .reset = ax88179_reset, |
| 1804 | 1804 | .stop = ax88179_stop, |
| 1805 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1805 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1806 | 1806 | .rx_fixup = ax88179_rx_fixup, |
| 1807 | 1807 | .tx_fixup = ax88179_tx_fixup, |
| 1808 | 1808 | }; |
| @@ -1815,7 +1815,7 @@ static const struct driver_info samsung_info = { · 6 unmodified lines | ||
| 1815 | 1815 | .link_reset = ax88179_link_reset, |
| 1816 | 1816 | .reset = ax88179_reset, |
| 1817 | 1817 | .stop = ax88179_stop, |
| 1818 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1818 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1819 | 1819 | .rx_fixup = ax88179_rx_fixup, |
| 1820 | 1820 | .tx_fixup = ax88179_tx_fixup, |
| 1821 | 1821 | }; |
| @@ -1828,7 +1828,7 @@ static const struct driver_info lenovo_info = { · 6 unmodified lines | ||
| 1828 | 1828 | .link_reset = ax88179_link_reset, |
| 1829 | 1829 | .reset = ax88179_reset, |
| 1830 | 1830 | .stop = ax88179_stop, |
| 1831 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1831 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1832 | 1832 | .rx_fixup = ax88179_rx_fixup, |
| 1833 | 1833 | .tx_fixup = ax88179_tx_fixup, |
| 1834 | 1834 | }; |
| @@ -1841,7 +1841,7 @@ static const struct driver_info belkin_info = { · 6 unmodified lines | ||
| 1841 | 1841 | .link_reset = ax88179_link_reset, |
| 1842 | 1842 | .reset = ax88179_reset, |
| 1843 | 1843 | .stop = ax88179_stop, |
| 1844 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1844 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1845 | 1845 | .rx_fixup = ax88179_rx_fixup, |
| 1846 | 1846 | .tx_fixup = ax88179_tx_fixup, |
| 1847 | 1847 | }; |
| @@ -1854,7 +1854,7 @@ static const struct driver_info toshiba_info = { · 6 unmodified lines | ||
| 1854 | 1854 | .link_reset = ax88179_link_reset, |
| 1855 | 1855 | .reset = ax88179_reset, |
| 1856 | 1856 | .stop = ax88179_stop, |
| 1857 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1857 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1858 | 1858 | .rx_fixup = ax88179_rx_fixup, |
| 1859 | 1859 | .tx_fixup = ax88179_tx_fixup, |
| 1860 | 1860 | }; |
| @@ -1867,7 +1867,7 @@ static const struct driver_info mct_info = { · 6 unmodified lines | ||
| 1867 | 1867 | .link_reset = ax88179_link_reset, |
| 1868 | 1868 | .reset = ax88179_reset, |
| 1869 | 1869 | .stop = ax88179_stop, |
| 1870 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1870 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1871 | 1871 | .rx_fixup = ax88179_rx_fixup, |
| 1872 | 1872 | .tx_fixup = ax88179_tx_fixup, |
| 1873 | 1873 | }; |
| @@ -1880,7 +1880,7 @@ static const struct driver_info at_umc2000_info = { · 6 unmodified lines | ||
| 1880 | 1880 | .link_reset = ax88179_link_reset, |
| 1881 | 1881 | .reset = ax88179_reset, |
| 1882 | 1882 | .stop = ax88179_stop, |
| 1883 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1883 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1884 | 1884 | .rx_fixup = ax88179_rx_fixup, |
| 1885 | 1885 | .tx_fixup = ax88179_tx_fixup, |
| 1886 | 1886 | }; |
| @@ -1893,7 +1893,7 @@ static const struct driver_info at_umc200_info = { · 6 unmodified lines | ||
| 1893 | 1893 | .link_reset = ax88179_link_reset, |
| 1894 | 1894 | .reset = ax88179_reset, |
| 1895 | 1895 | .stop = ax88179_stop, |
| 1896 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1896 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1897 | 1897 | .rx_fixup = ax88179_rx_fixup, |
| 1898 | 1898 | .tx_fixup = ax88179_tx_fixup, |
| 1899 | 1899 | }; |
| @@ -1906,7 +1906,7 @@ static const struct driver_info at_umc2000sp_info = { · 6 unmodified lines | ||
| 1906 | 1906 | .link_reset = ax88179_link_reset, |
| 1907 | 1907 | .reset = ax88179_reset, |
| 1908 | 1908 | .stop = ax88179_stop, |
| 1909 | − .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1909 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, | |
| 1910 | 1910 | .rx_fixup = ax88179_rx_fixup, |
| 1911 | 1911 | .tx_fixup = ax88179_tx_fixup, |
| 1912 | 1912 | }; |
| @@ -312,6 +312,7 @@ static bool veth_skb_is_eligible_for_gro(const struct net_device *dev, · 311 unmodified lines | ||
| 312 | 312 | static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) |
| 313 | 313 | { |
| 314 | 314 | struct veth_priv *rcv_priv, *priv = netdev_priv(dev); |
| 315 | + struct netdev_queue *queue = NULL; | |
| 315 | 316 | struct veth_rq *rq = NULL; |
| 316 | 317 | struct net_device *rcv; |
| 317 | 318 | int length = skb->len; |
| @@ -329,6 +330,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) · 11 unmodified lines | ||
| 329 | 330 | rxq = skb_get_queue_mapping(skb); |
| 330 | 331 | if (rxq < rcv->real_num_rx_queues) { |
| 331 | 332 | rq = &rcv_priv->rq[rxq]; |
| 333 | + queue = netdev_get_tx_queue(dev, rxq); | |
| 332 | 334 | |
| 333 | 335 | /* The napi pointer is available when an XDP program is |
| 334 | 336 | * attached or when GRO is enabled |
| @@ -340,6 +342,8 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) · 5 unmodified lines | ||
| 340 | 342 | |
| 341 | 343 | skb_tx_timestamp(skb); |
| 342 | 344 | if (likely(veth_forward_skb(rcv, skb, rq, use_napi) == NET_RX_SUCCESS)) { |
| 345 | + if (queue) | |
| 346 | + txq_trans_cond_update(queue); | |
| 343 | 347 | if (!use_napi) |
| 344 | 348 | dev_lstats_add(dev, length); |
| 345 | 349 | } else { |
| @@ -2768,7 +2768,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = { · 2767 unmodified lines | ||
| 2768 | 2768 | static void virtnet_freeze_down(struct virtio_device *vdev) |
| 2769 | 2769 | { |
| 2770 | 2770 | struct virtnet_info *vi = vdev->priv; |
| 2771 | − int i; | |
| 2772 | 2771 | |
| 2773 | 2772 | /* Make sure no work handler is accessing the device */ |
| 2774 | 2773 | flush_work(&vi->config_work); |
| @@ -2776,14 +2775,8 @@ static void virtnet_freeze_down(struct virtio_device *vdev) · 1 unmodified line | ||
| 2776 | 2775 | netif_tx_lock_bh(vi->dev); |
| 2777 | 2776 | netif_device_detach(vi->dev); |
| 2778 | 2777 | netif_tx_unlock_bh(vi->dev); |
| 2779 | − cancel_delayed_work_sync(&vi->refill); | |
| 2780 | − | |
| 2781 | − if (netif_running(vi->dev)) { | |
| 2782 | − for (i = 0; i < vi->max_queue_pairs; i++) { | |
| 2783 | − napi_disable(&vi->rq[i].napi); | |
| 2784 | − virtnet_napi_tx_disable(&vi->sq[i].napi); | |
| 2785 | − } | |
| 2786 | − } | |
| 2778 | + if (netif_running(vi->dev)) | |
| 2779 | + virtnet_close(vi->dev); | |
| 2787 | 2780 | } |
| 2788 | 2781 | |
| 2789 | 2782 | static int init_vqs(struct virtnet_info *vi); |
| @@ -2791,7 +2784,7 @@ static int init_vqs(struct virtnet_info *vi); · 1 unmodified line | ||
| 2791 | 2784 | static int virtnet_restore_up(struct virtio_device *vdev) |
| 2792 | 2785 | { |
| 2793 | 2786 | struct virtnet_info *vi = vdev->priv; |
| 2794 | − int err, i; | |
| 2787 | + int err; | |
| 2795 | 2788 | |
| 2796 | 2789 | err = init_vqs(vi); |
| 2797 | 2790 | if (err) |
| @@ -2800,15 +2793,9 @@ static int virtnet_restore_up(struct virtio_device *vdev) · 2 unmodified lines | ||
| 2800 | 2793 | virtio_device_ready(vdev); |
| 2801 | 2794 | |
| 2802 | 2795 | if (netif_running(vi->dev)) { |
| 2803 | − for (i = 0; i < vi->curr_queue_pairs; i++) | |
| 2804 | − if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL)) | |
| 2805 | − schedule_delayed_work(&vi->refill, 0); | |
| 2806 | − | |
| 2807 | − for (i = 0; i < vi->max_queue_pairs; i++) { | |
| 2808 | − virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); | |
| 2809 | − virtnet_napi_tx_enable(vi, vi->sq[i].vq, | |
| 2810 | − &vi->sq[i].napi); | |
| 2811 | − } | |
| 2796 | + err = virtnet_open(vi->dev); | |
| 2797 | + if (err) | |
| 2798 | + return err; | |
| 2812 | 2799 | } |
| 2813 | 2800 | |
| 2814 | 2801 | netif_tx_lock_bh(vi->dev); |
| @@ -2546,6 +2546,20 @@ static const struct nvme_core_quirk_entry core_quirks[] = { · 2545 unmodified lines | ||
| 2546 | 2546 | .vid = 0x1e0f, |
| 2547 | 2547 | .mn = "KCD6XVUL6T40", |
| 2548 | 2548 | .quirks = NVME_QUIRK_NO_APST, |
| 2549 | + }, | |
| 2550 | + { | |
| 2551 | + /* | |
| 2552 | + * The external Samsung X5 SSD fails initialization without a | |
| 2553 | + * delay before checking if it is ready and has a whole set of | |
| 2554 | + * other problems. To make this even more interesting, it | |
| 2555 | + * shares the PCI ID with internal Samsung 970 Evo Plus that | |
| 2556 | + * does not need or want these quirks. | |
| 2557 | + */ | |
| 2558 | + .vid = 0x144d, | |
| 2559 | + .mn = "Samsung Portable SSD X5", | |
| 2560 | + .quirks = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | | |
| 2561 | + NVME_QUIRK_NO_DEEPEST_PS | | |
| 2562 | + NVME_QUIRK_IGNORE_DEV_SUBNQN, | |
| 2549 | 2563 | } |
| 2550 | 2564 | }; |
| 2551 | 2565 | |
| @@ -3285,8 +3299,8 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, · 733 unmodified lines | ||
| 3285 | 3299 | * we have no UUID set |
| 3286 | 3300 | */ |
| 3287 | 3301 | if (uuid_is_null(&ids->uuid)) { |
| 3288 | − printk_ratelimited(KERN_WARNING | |
| 3289 | − "No UUID available providing old NGUID\n"); | |
| 3302 | + dev_warn_ratelimited(dev, | |
| 3303 | + "No UUID available providing old NGUID\n"); | |
| 3290 | 3304 | return sysfs_emit(buf, "%pU\n", ids->nguid); |
| 3291 | 3305 | } |
| 3292 | 3306 | return sysfs_emit(buf, "%pU\n", &ids->uuid); |
| @@ -3863,6 +3877,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid, · 570 unmodified lines | ||
| 3863 | 3877 | if (ret) { |
| 3864 | 3878 | dev_err(ctrl->device, |
| 3865 | 3879 | "globally duplicate IDs for nsid %d\n", nsid); |
| 3880 | + nvme_print_device_info(ctrl); | |
| 3866 | 3881 | return ret; |
| 3867 | 3882 | } |
| 3868 | 3883 | |
| @@ -503,6 +503,7 @@ struct nvme_ctrl_ops { · 502 unmodified lines | ||
| 503 | 503 | void (*submit_async_event)(struct nvme_ctrl *ctrl); |
| 504 | 504 | void (*delete_ctrl)(struct nvme_ctrl *ctrl); |
| 505 | 505 | int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); |
| 506 | + void (*print_device_info)(struct nvme_ctrl *ctrl); | |
| 506 | 507 | }; |
| 507 | 508 | |
| 508 | 509 | /* |
| @@ -548,6 +549,33 @@ static inline struct request *nvme_cid_to_rq(struct blk_mq_tags *tags, · 39 unmodified lines | ||
| 548 | 549 | return blk_mq_tag_to_rq(tags, nvme_tag_from_cid(command_id)); |
| 549 | 550 | } |
| 550 | 551 | |
| 552 | +/* | |
| 553 | + * Return the length of the string without the space padding | |
| 554 | + */ | |
| 555 | +static inline int nvme_strlen(char *s, int len) | |
| 556 | +{ | |
| 557 | + while (s[len - 1] == ' ') | |
| 558 | + len--; | |
| 559 | + return len; | |
| 560 | +} | |
| 561 | + | |
| 562 | +static inline void nvme_print_device_info(struct nvme_ctrl *ctrl) | |
| 563 | +{ | |
| 564 | + struct nvme_subsystem *subsys = ctrl->subsys; | |
| 565 | + | |
| 566 | + if (ctrl->ops->print_device_info) { | |
| 567 | + ctrl->ops->print_device_info(ctrl); | |
| 568 | + return; | |
| 569 | + } | |
| 570 | + | |
| 571 | + dev_err(ctrl->device, | |
| 572 | + "VID:%04x model:%.*s firmware:%.*s\n", subsys->vendor_id, | |
| 573 | + nvme_strlen(subsys->model, sizeof(subsys->model)), | |
| 574 | + subsys->model, nvme_strlen(subsys->firmware_rev, | |
| 575 | + sizeof(subsys->firmware_rev)), | |
| 576 | + subsys->firmware_rev); | |
| 577 | +} | |
| 578 | + | |
| 551 | 579 | #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS |
| 552 | 580 | void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, |
| 553 | 581 | const char *dev_name); |
| @@ -1334,6 +1334,14 @@ static void nvme_warn_reset(struct nvme_dev *dev, u32 csts) · 1333 unmodified lines | ||
| 1334 | 1334 | dev_warn(dev->ctrl.device, |
| 1335 | 1335 | "controller is down; will reset: CSTS=0x%x, PCI_STATUS read failed (%d)\n", |
| 1336 | 1336 | csts, result); |
| 1337 | + | |
| 1338 | + if (csts != ~0) | |
| 1339 | + return; | |
| 1340 | + | |
| 1341 | + dev_warn(dev->ctrl.device, | |
| 1342 | + "Does your device have a faulty power saving mode enabled?\n"); | |
| 1343 | + dev_warn(dev->ctrl.device, | |
| 1344 | + "Try \"nvme_core.default_ps_max_latency_us=0 pcie_aspm=off\" and report a bug\n"); | |
| 1337 | 1345 | } |
| 1338 | 1346 | |
| 1339 | 1347 | static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) |
| @@ -2976,6 +2984,21 @@ static int nvme_pci_get_address(struct nvme_ctrl *ctrl, char *buf, int size) · 1636 unmodified lines | ||
| 2976 | 2984 | return snprintf(buf, size, "%s\n", dev_name(&pdev->dev)); |
| 2977 | 2985 | } |
| 2978 | 2986 | |
| 2987 | + | |
| 2988 | +static void nvme_pci_print_device_info(struct nvme_ctrl *ctrl) | |
| 2989 | +{ | |
| 2990 | + struct pci_dev *pdev = to_pci_dev(to_nvme_dev(ctrl)->dev); | |
| 2991 | + struct nvme_subsystem *subsys = ctrl->subsys; | |
| 2992 | + | |
| 2993 | + dev_err(ctrl->device, | |
| 2994 | + "VID:DID %04x:%04x model:%.*s firmware:%.*s\n", | |
| 2995 | + pdev->vendor, pdev->device, | |
| 2996 | + nvme_strlen(subsys->model, sizeof(subsys->model)), | |
| 2997 | + subsys->model, nvme_strlen(subsys->firmware_rev, | |
| 2998 | + sizeof(subsys->firmware_rev)), | |
| 2999 | + subsys->firmware_rev); | |
| 3000 | +} | |
| 3001 | + | |
| 2979 | 3002 | static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { |
| 2980 | 3003 | .name = "pcie", |
| 2981 | 3004 | .module = THIS_MODULE, |
| @@ -2987,6 +3010,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { · 5 unmodified lines | ||
| 2987 | 3010 | .free_ctrl = nvme_pci_free_ctrl, |
| 2988 | 3011 | .submit_async_event = nvme_pci_submit_async_event, |
| 2989 | 3012 | .get_address = nvme_pci_get_address, |
| 3013 | + .print_device_info = nvme_pci_print_device_info, | |
| 2990 | 3014 | }; |
| 2991 | 3015 | |
| 2992 | 3016 | static int nvme_dev_map(struct nvme_dev *dev) |
| @@ -3421,7 +3445,8 @@ static const struct pci_device_id nvme_id_table[] = { · 428 unmodified lines | ||
| 3421 | 3445 | { PCI_VDEVICE(REDHAT, 0x0010), /* Qemu emulated controller */ |
| 3422 | 3446 | .driver_data = NVME_QUIRK_BOGUS_NID, }, |
| 3423 | 3447 | { PCI_DEVICE(0x126f, 0x2263), /* Silicon Motion unidentified */ |
| 3424 | − .driver_data = NVME_QUIRK_NO_NS_DESC_LIST, }, | |
| 3448 | + .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | | |
| 3449 | + NVME_QUIRK_BOGUS_NID, }, | |
| 3425 | 3450 | { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ |
| 3426 | 3451 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
| 3427 | 3452 | NVME_QUIRK_NO_NS_DESC_LIST, }, |
| @@ -3437,6 +3462,8 @@ static const struct pci_device_id nvme_id_table[] = { · 9 unmodified lines | ||
| 3437 | 3462 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
| 3438 | 3463 | NVME_QUIRK_DISABLE_WRITE_ZEROES| |
| 3439 | 3464 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3465 | + { PCI_DEVICE(0x1987, 0x5012), /* Phison E12 */ | |
| 3466 | + .driver_data = NVME_QUIRK_BOGUS_NID, }, | |
| 3440 | 3467 | { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ |
| 3441 | 3468 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3442 | 3469 | { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ |
| @@ -3447,12 +3474,24 @@ static const struct pci_device_id nvme_id_table[] = { · 4 unmodified lines | ||
| 3447 | 3474 | { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ |
| 3448 | 3475 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | |
| 3449 | 3476 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3477 | + { PCI_DEVICE(0x1344, 0x5407), /* Micron Technology Inc NVMe SSD */ | |
| 3478 | + .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN }, | |
| 3450 | 3479 | { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */ |
| 3451 | 3480 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, |
| 3481 | + { PCI_DEVICE(0x1c5c, 0x174a), /* SK Hynix P31 SSD */ | |
| 3482 | + .driver_data = NVME_QUIRK_BOGUS_NID, }, | |
| 3452 | 3483 | { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ |
| 3453 | 3484 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, |
| 3454 | 3485 | { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ |
| 3455 | 3486 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, |
| 3487 | + { PCI_DEVICE(0x144d, 0xa80b), /* Samsung PM9B1 256G and 512G */ | |
| 3488 | + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | |
| 3489 | + { PCI_DEVICE(0x144d, 0xa809), /* Samsung MZALQ256HBJD 256G */ | |
| 3490 | + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | |
| 3491 | + { PCI_DEVICE(0x1cc4, 0x6303), /* UMIS RPJTJ512MGE1QDY 512G */ | |
| 3492 | + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | |
| 3493 | + { PCI_DEVICE(0x1cc4, 0x6302), /* UMIS RPJTJ256MGE1QDY 256G */ | |
| 3494 | + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | |
| 3456 | 3495 | { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ |
| 3457 | 3496 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, |
| 3458 | 3497 | { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ |
| @@ -3463,6 +3502,10 @@ static const struct pci_device_id nvme_id_table[] = { · 4 unmodified lines | ||
| 3463 | 3502 | .driver_data = NVME_QUIRK_BOGUS_NID, }, |
| 3464 | 3503 | { PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */ |
| 3465 | 3504 | .driver_data = NVME_QUIRK_BOGUS_NID, }, |
| 3505 | + { PCI_DEVICE(0x1cc1, 0x5350), /* ADATA XPG GAMMIX S50 */ | |
| 3506 | + .driver_data = NVME_QUIRK_BOGUS_NID, }, | |
| 3507 | + { PCI_DEVICE(0x1e49, 0x0041), /* ZHITAI TiPro7000 NVMe SSD */ | |
| 3508 | + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, | |
| 3466 | 3509 | { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0061), |
| 3467 | 3510 | .driver_data = NVME_QUIRK_DMA_ADDRESS_BITS_48, }, |
| 3468 | 3511 | { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0065), |
| @@ -3483,10 +3526,6 @@ static const struct pci_device_id nvme_id_table[] = { · 14 unmodified lines | ||
| 3483 | 3526 | NVME_QUIRK_128_BYTES_SQES | |
| 3484 | 3527 | NVME_QUIRK_SHARED_TAGS | |
| 3485 | 3528 | NVME_QUIRK_SKIP_CID_GEN }, |
| 3486 | − { PCI_DEVICE(0x144d, 0xa808), /* Samsung X5 */ | |
| 3487 | − .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY| | |
| 3488 | − NVME_QUIRK_NO_DEEPEST_PS | | |
| 3489 | − NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | |
| 3490 | 3529 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, |
| 3491 | 3530 | { 0, } |
| 3492 | 3531 | }; |
| @@ -723,19 +723,19 @@ static const struct regulator_desc pms405_pldo600 = { · 722 unmodified lines | ||
| 723 | 723 | |
| 724 | 724 | static const struct regulator_desc mp5496_smpa2 = { |
| 725 | 725 | .linear_ranges = (struct linear_range[]) { |
| 726 | − REGULATOR_LINEAR_RANGE(725000, 0, 27, 12500), | |
| 726 | + REGULATOR_LINEAR_RANGE(600000, 0, 127, 12500), | |
| 727 | 727 | }, |
| 728 | 728 | .n_linear_ranges = 1, |
| 729 | − .n_voltages = 28, | |
| 729 | + .n_voltages = 128, | |
| 730 | 730 | .ops = &rpm_mp5496_ops, |
| 731 | 731 | }; |
| 732 | 732 | |
| 733 | 733 | static const struct regulator_desc mp5496_ldoa2 = { |
| 734 | 734 | .linear_ranges = (struct linear_range[]) { |
| 735 | − REGULATOR_LINEAR_RANGE(1800000, 0, 60, 25000), | |
| 735 | + REGULATOR_LINEAR_RANGE(800000, 0, 127, 25000), | |
| 736 | 736 | }, |
| 737 | 737 | .n_linear_ranges = 1, |
| 738 | − .n_voltages = 61, | |
| 738 | + .n_voltages = 128, | |
| 739 | 739 | .ops = &rpm_mp5496_ops, |
| 740 | 740 | }; |
| 741 | 741 | |
| @@ -160,8 +160,8 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *); · 159 unmodified lines | ||
| 160 | 160 | static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *); |
| 161 | 161 | static void ibmvfc_tgt_move_login(struct ibmvfc_target *); |
| 162 | 162 | |
| 163 | −static void ibmvfc_release_sub_crqs(struct ibmvfc_host *); | |
| 164 | −static void ibmvfc_init_sub_crqs(struct ibmvfc_host *); | |
| 163 | +static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *); | |
| 164 | +static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *); | |
| 165 | 165 | |
| 166 | 166 | static const char *unknown_error = "unknown error"; |
| 167 | 167 | |
| @@ -917,7 +917,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) · 749 unmodified lines | ||
| 917 | 917 | struct vio_dev *vdev = to_vio_dev(vhost->dev); |
| 918 | 918 | unsigned long flags; |
| 919 | 919 | |
| 920 | − ibmvfc_release_sub_crqs(vhost); | |
| 920 | + ibmvfc_dereg_sub_crqs(vhost); | |
| 921 | 921 | |
| 922 | 922 | /* Re-enable the CRQ */ |
| 923 | 923 | do { |
| @@ -936,7 +936,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) · 12 unmodified lines | ||
| 936 | 936 | spin_unlock(vhost->crq.q_lock); |
| 937 | 937 | spin_unlock_irqrestore(vhost->host->host_lock, flags); |
| 938 | 938 | |
| 939 | − ibmvfc_init_sub_crqs(vhost); | |
| 939 | + ibmvfc_reg_sub_crqs(vhost); | |
| 940 | 940 | |
| 941 | 941 | return rc; |
| 942 | 942 | } |
| @@ -955,7 +955,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 12 unmodified lines | ||
| 955 | 955 | struct vio_dev *vdev = to_vio_dev(vhost->dev); |
| 956 | 956 | struct ibmvfc_queue *crq = &vhost->crq; |
| 957 | 957 | |
| 958 | − ibmvfc_release_sub_crqs(vhost); | |
| 958 | + ibmvfc_dereg_sub_crqs(vhost); | |
| 959 | 959 | |
| 960 | 960 | /* Close the CRQ */ |
| 961 | 961 | do { |
| @@ -988,7 +988,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 26 unmodified lines | ||
| 988 | 988 | spin_unlock(vhost->crq.q_lock); |
| 989 | 989 | spin_unlock_irqrestore(vhost->host->host_lock, flags); |
| 990 | 990 | |
| 991 | − ibmvfc_init_sub_crqs(vhost); | |
| 991 | + ibmvfc_reg_sub_crqs(vhost); | |
| 992 | 992 | |
| 993 | 993 | return rc; |
| 994 | 994 | } |
| @@ -5682,6 +5682,8 @@ static int ibmvfc_alloc_queue(struct ibmvfc_host *vhost, · 4687 unmodified lines | ||
| 5682 | 5682 | queue->cur = 0; |
| 5683 | 5683 | queue->fmt = fmt; |
| 5684 | 5684 | queue->size = PAGE_SIZE / fmt_size; |
| 5685 | + | |
| 5686 | + queue->vhost = vhost; | |
| 5685 | 5687 | return 0; |
| 5686 | 5688 | } |
| 5687 | 5689 | |
| @@ -5757,9 +5759,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, · 69 unmodified lines | ||
| 5757 | 5759 | |
| 5758 | 5760 | ENTER; |
| 5759 | 5761 | |
| 5760 | − if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT)) | |
| 5761 | − return -ENOMEM; | |
| 5762 | − | |
| 5763 | 5762 | rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE, |
| 5764 | 5763 | &scrq->cookie, &scrq->hw_irq); |
| 5765 | 5764 | |
| @@ -5790,7 +5789,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, · 24 unmodified lines | ||
| 5790 | 5789 | } |
| 5791 | 5790 | |
| 5792 | 5791 | scrq->hwq_id = index; |
| 5793 | − scrq->vhost = vhost; | |
| 5794 | 5792 | |
| 5795 | 5793 | LEAVE; |
| 5796 | 5794 | return 0; |
| @@ -5800,7 +5798,6 @@ irq_failed: · 3 unmodified lines | ||
| 5800 | 5798 | rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); |
| 5801 | 5799 | } while (rtas_busy_delay(rc)); |
| 5802 | 5800 | reg_failed: |
| 5803 | − ibmvfc_free_queue(vhost, scrq); | |
| 5804 | 5801 | LEAVE; |
| 5805 | 5802 | return rc; |
| 5806 | 5803 | } |
| @@ -5826,12 +5823,50 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index) · 19 unmodified lines | ||
| 5826 | 5823 | if (rc) |
| 5827 | 5824 | dev_err(dev, "Failed to free sub-crq[%d]: rc=%ld\n", index, rc); |
| 5828 | 5825 | |
| 5829 | − ibmvfc_free_queue(vhost, scrq); | |
| 5826 | + /* Clean out the queue */ | |
| 5827 | + memset(scrq->msgs.crq, 0, PAGE_SIZE); | |
| 5828 | + scrq->cur = 0; | |
| 5829 | + | |
| 5830 | + LEAVE; | |
| 5831 | +} | |
| 5832 | + | |
| 5833 | +static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *vhost) | |
| 5834 | +{ | |
| 5835 | + int i, j; | |
| 5836 | + | |
| 5837 | + ENTER; | |
| 5838 | + if (!vhost->mq_enabled || !vhost->scsi_scrqs.scrqs) | |
| 5839 | + return; | |
| 5840 | + | |
| 5841 | + for (i = 0; i < nr_scsi_hw_queues; i++) { | |
| 5842 | + if (ibmvfc_register_scsi_channel(vhost, i)) { | |
| 5843 | + for (j = i; j > 0; j--) | |
| 5844 | + ibmvfc_deregister_scsi_channel(vhost, j - 1); | |
| 5845 | + vhost->do_enquiry = 0; | |
| 5846 | + return; | |
| 5847 | + } | |
| 5848 | + } | |
| 5849 | + | |
| 5850 | + LEAVE; | |
| 5851 | +} | |
| 5852 | + | |
| 5853 | +static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *vhost) | |
| 5854 | +{ | |
| 5855 | + int i; | |
| 5856 | + | |
| 5857 | + ENTER; | |
| 5858 | + if (!vhost->mq_enabled || !vhost->scsi_scrqs.scrqs) | |
| 5859 | + return; | |
| 5860 | + | |
| 5861 | + for (i = 0; i < nr_scsi_hw_queues; i++) | |
| 5862 | + ibmvfc_deregister_scsi_channel(vhost, i); | |
| 5863 | + | |
| 5830 | 5864 | LEAVE; |
| 5831 | 5865 | } |
| 5832 | 5866 | |
| 5833 | 5867 | static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) |
| 5834 | 5868 | { |
| 5869 | + struct ibmvfc_queue *scrq; | |
| 5835 | 5870 | int i, j; |
| 5836 | 5871 | |
| 5837 | 5872 | ENTER; |
| @@ -5847,30 +5882,41 @@ static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) · 9 unmodified lines | ||
| 5847 | 5882 | } |
| 5848 | 5883 | |
| 5849 | 5884 | for (i = 0; i < nr_scsi_hw_queues; i++) { |
| 5850 | − if (ibmvfc_register_scsi_channel(vhost, i)) { | |
| 5851 | − for (j = i; j > 0; j--) | |
| 5852 | − ibmvfc_deregister_scsi_channel(vhost, j - 1); | |
| 5885 | + scrq = &vhost->scsi_scrqs.scrqs[i]; | |
| 5886 | + if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT)) { | |
| 5887 | + for (j = i; j > 0; j--) { | |
| 5888 | + scrq = &vhost->scsi_scrqs.scrqs[j - 1]; | |
| 5889 | + ibmvfc_free_queue(vhost, scrq); | |
| 5890 | + } | |
| 5853 | 5891 | kfree(vhost->scsi_scrqs.scrqs); |
| 5854 | 5892 | vhost->scsi_scrqs.scrqs = NULL; |
| 5855 | 5893 | vhost->scsi_scrqs.active_queues = 0; |
| 5856 | 5894 | vhost->do_enquiry = 0; |
| 5857 | − break; | |
| 5895 | + vhost->mq_enabled = 0; | |
| 5896 | + return; | |
| 5858 | 5897 | } |
| 5859 | 5898 | } |
| 5860 | 5899 | |
| 5900 | + ibmvfc_reg_sub_crqs(vhost); | |
| 5901 | + | |
| 5861 | 5902 | LEAVE; |
| 5862 | 5903 | } |
| 5863 | 5904 | |
| 5864 | 5905 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost) |
| 5865 | 5906 | { |
| 5907 | + struct ibmvfc_queue *scrq; | |
| 5866 | 5908 | int i; |
| 5867 | 5909 | |
| 5868 | 5910 | ENTER; |
| 5869 | 5911 | if (!vhost->scsi_scrqs.scrqs) |
| 5870 | 5912 | return; |
| 5871 | 5913 | |
| 5872 | − for (i = 0; i < nr_scsi_hw_queues; i++) | |
| 5873 | − ibmvfc_deregister_scsi_channel(vhost, i); | |
| 5914 | + ibmvfc_dereg_sub_crqs(vhost); | |
| 5915 | + | |
| 5916 | + for (i = 0; i < nr_scsi_hw_queues; i++) { | |
| 5917 | + scrq = &vhost->scsi_scrqs.scrqs[i]; | |
| 5918 | + ibmvfc_free_queue(vhost, scrq); | |
| 5919 | + } | |
| 5874 | 5920 | |
| 5875 | 5921 | kfree(vhost->scsi_scrqs.scrqs); |
| 5876 | 5922 | vhost->scsi_scrqs.scrqs = NULL; |
| @@ -789,6 +789,7 @@ struct ibmvfc_queue { · 788 unmodified lines | ||
| 789 | 789 | spinlock_t _lock; |
| 790 | 790 | spinlock_t *q_lock; |
| 791 | 791 | |
| 792 | + struct ibmvfc_host *vhost; | |
| 792 | 793 | struct ibmvfc_event_pool evt_pool; |
| 793 | 794 | struct list_head sent; |
| 794 | 795 | struct list_head free; |
| @@ -797,7 +798,6 @@ struct ibmvfc_queue { · 2 unmodified lines | ||
| 797 | 798 | union ibmvfc_iu cancel_rsp; |
| 798 | 799 | |
| 799 | 800 | /* Sub-CRQ fields */ |
| 800 | − struct ibmvfc_host *vhost; | |
| 801 | 801 | unsigned long cookie; |
| 802 | 802 | unsigned long vios_cookie; |
| 803 | 803 | unsigned long hw_irq; |
| @@ -2826,6 +2826,24 @@ static void zbc_open_zone(struct sdebug_dev_info *devip, · 2825 unmodified lines | ||
| 2826 | 2826 | } |
| 2827 | 2827 | } |
| 2828 | 2828 | |
| 2829 | +static inline void zbc_set_zone_full(struct sdebug_dev_info *devip, | |
| 2830 | + struct sdeb_zone_state *zsp) | |
| 2831 | +{ | |
| 2832 | + switch (zsp->z_cond) { | |
| 2833 | + case ZC2_IMPLICIT_OPEN: | |
| 2834 | + devip->nr_imp_open--; | |
| 2835 | + break; | |
| 2836 | + case ZC3_EXPLICIT_OPEN: | |
| 2837 | + devip->nr_exp_open--; | |
| 2838 | + break; | |
| 2839 | + default: | |
| 2840 | + WARN_ONCE(true, "Invalid zone %llu condition %x\n", | |
| 2841 | + zsp->z_start, zsp->z_cond); | |
| 2842 | + break; | |
| 2843 | + } | |
| 2844 | + zsp->z_cond = ZC5_FULL; | |
| 2845 | +} | |
| 2846 | + | |
| 2829 | 2847 | static void zbc_inc_wp(struct sdebug_dev_info *devip, |
| 2830 | 2848 | unsigned long long lba, unsigned int num) |
| 2831 | 2849 | { |
| @@ -2838,7 +2856,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip, · 6 unmodified lines | ||
| 2838 | 2856 | if (zsp->z_type == ZBC_ZTYPE_SWR) { |
| 2839 | 2857 | zsp->z_wp += num; |
| 2840 | 2858 | if (zsp->z_wp >= zend) |
| 2841 | − zsp->z_cond = ZC5_FULL; | |
| 2859 | + zbc_set_zone_full(devip, zsp); | |
| 2842 | 2860 | return; |
| 2843 | 2861 | } |
| 2844 | 2862 | |
| @@ -2857,7 +2875,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip, · 12 unmodified lines | ||
| 2857 | 2875 | n = num; |
| 2858 | 2876 | } |
| 2859 | 2877 | if (zsp->z_wp >= zend) |
| 2860 | − zsp->z_cond = ZC5_FULL; | |
| 2878 | + zbc_set_zone_full(devip, zsp); | |
| 2861 | 2879 | |
| 2862 | 2880 | num -= n; |
| 2863 | 2881 | lba += n; |
| @@ -212,7 +212,12 @@ iscsi_create_endpoint(int dd_size) · 211 unmodified lines | ||
| 212 | 212 | return NULL; |
| 213 | 213 | |
| 214 | 214 | mutex_lock(&iscsi_ep_idr_mutex); |
| 215 | − id = idr_alloc(&iscsi_ep_idr, ep, 0, -1, GFP_NOIO); | |
| 215 | + | |
| 216 | + /* | |
| 217 | + * First endpoint id should be 1 to comply with user space | |
| 218 | + * applications (iscsid). | |
| 219 | + */ | |
| 220 | + id = idr_alloc(&iscsi_ep_idr, ep, 1, -1, GFP_NOIO); | |
| 216 | 221 | if (id < 0) { |
| 217 | 222 | mutex_unlock(&iscsi_ep_idr_mutex); |
| 218 | 223 | printk(KERN_ERR "Could not allocate endpoint ID. Error %d.\n", |
| @@ -1844,7 +1844,7 @@ static struct scsi_host_template scsi_driver = { · 1843 unmodified lines | ||
| 1844 | 1844 | .cmd_per_lun = 2048, |
| 1845 | 1845 | .this_id = -1, |
| 1846 | 1846 | /* Ensure there are no gaps in presented sgls */ |
| 1847 | − .virt_boundary_mask = PAGE_SIZE-1, | |
| 1847 | + .virt_boundary_mask = HV_HYP_PAGE_SIZE - 1, | |
| 1848 | 1848 | .no_write_same = 1, |
| 1849 | 1849 | .track_queue_depth = 1, |
| 1850 | 1850 | .change_queue_depth = storvsc_change_queue_depth, |
| @@ -1895,6 +1895,7 @@ static int storvsc_probe(struct hv_device *device, · 44 unmodified lines | ||
| 1895 | 1895 | int target = 0; |
| 1896 | 1896 | struct storvsc_device *stor_device; |
| 1897 | 1897 | int max_sub_channels = 0; |
| 1898 | + u32 max_xfer_bytes; | |
| 1898 | 1899 | |
| 1899 | 1900 | /* |
| 1900 | 1901 | * We support sub-channels for storage on SCSI and FC controllers. |
| @@ -1968,12 +1969,28 @@ static int storvsc_probe(struct hv_device *device, · 67 unmodified lines | ||
| 1968 | 1969 | } |
| 1969 | 1970 | /* max cmd length */ |
| 1970 | 1971 | host->max_cmd_len = STORVSC_MAX_CMD_LEN; |
| 1971 | − | |
| 1972 | 1972 | /* |
| 1973 | − * set the table size based on the info we got | |
| 1974 | − * from the host. | |
| 1973 | + * Any reasonable Hyper-V configuration should provide | |
| 1974 | + * max_transfer_bytes value aligning to HV_HYP_PAGE_SIZE, | |
| 1975 | + * protecting it from any weird value. | |
| 1976 | + */ | |
| 1977 | + max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE); | |
| 1978 | + /* max_hw_sectors_kb */ | |
| 1979 | + host->max_sectors = max_xfer_bytes >> 9; | |
| 1980 | + /* | |
| 1981 | + * There are 2 requirements for Hyper-V storvsc sgl segments, | |
| 1982 | + * based on which the below calculation for max segments is | |
| 1983 | + * done: | |
| 1984 | + * | |
| 1985 | + * 1. Except for the first and last sgl segment, all sgl segments | |
| 1986 | + * should be align to HV_HYP_PAGE_SIZE, that also means the | |
| 1987 | + * maximum number of segments in a sgl can be calculated by | |
| 1988 | + * dividing the total max transfer length by HV_HYP_PAGE_SIZE. | |
| 1989 | + * | |
| 1990 | + * 2. Except for the first and last, each entry in the SGL must | |
| 1991 | + * have an offset that is a multiple of HV_HYP_PAGE_SIZE. | |
| 1975 | 1992 | */ |
| 1976 | − host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT); | |
| 1993 | + host->sg_tablesize = (max_xfer_bytes >> HV_HYP_PAGE_SHIFT) + 1; | |
| 1977 | 1994 | /* |
| 1978 | 1995 | * For non-IDE disks, the host supports multiple channels. |
| 1979 | 1996 | * Set the number of HW queues we are supporting. |
| @@ -783,6 +783,7 @@ static int brcmstb_pm_probe(struct platform_device *pdev) · 782 unmodified lines | ||
| 783 | 783 | } |
| 784 | 784 | |
| 785 | 785 | ret = brcmstb_init_sram(dn); |
| 786 | + of_node_put(dn); | |
| 786 | 787 | if (ret) { |
| 787 | 788 | pr_err("error setting up SRAM for PM\n"); |
| 788 | 789 | return ret; |
| @@ -667,7 +667,7 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ · 666 unmodified lines | ||
| 667 | 667 | }, |
| 668 | 668 | [IMX8MP_MEDIABLK_PD_LCDIF_2] = { |
| 669 | 669 | .name = "mediablk-lcdif-2", |
| 670 | − .clk_names = (const char *[]){ "disp1", "apb", "axi", }, | |
| 670 | + .clk_names = (const char *[]){ "disp2", "apb", "axi", }, | |
| 671 | 671 | .num_clks = 3, |
| 672 | 672 | .gpc_name = "lcdif2", |
| 673 | 673 | .rst_mask = BIT(11) | BIT(12) | BIT(24), |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | #define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */ |
| 70 | 70 | #define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */ |
| 71 | 71 | #define CDNS_SPI_SS0 0x1 /* Slave Select zero */ |
| 72 | +#define CDNS_SPI_NOSS 0x3C /* No Slave select */ | |
| 72 | 73 | |
| 73 | 74 | /* |
| 74 | 75 | * SPI Interrupt Registers bit Masks |
| @@ -92,9 +93,6 @@ · 17 unmodified lines | ||
| 92 | 93 | #define CDNS_SPI_ER_ENABLE 0x00000001 /* SPI Enable Bit Mask */ |
| 93 | 94 | #define CDNS_SPI_ER_DISABLE 0x0 /* SPI Disable Bit Mask */ |
| 94 | 95 | |
| 95 | −/* SPI FIFO depth in bytes */ | |
| 96 | −#define CDNS_SPI_FIFO_DEPTH 128 | |
| 97 | − | |
| 98 | 96 | /* Default number of chip select lines */ |
| 99 | 97 | #define CDNS_SPI_DEFAULT_NUM_CS 4 |
| 100 | 98 | |
| @@ -110,6 +108,7 @@ · 9 unmodified lines | ||
| 110 | 108 | * @rx_bytes: Number of bytes requested |
| 111 | 109 | * @dev_busy: Device busy flag |
| 112 | 110 | * @is_decoded_cs: Flag for decoder property set or not |
| 111 | + * @tx_fifo_depth: Depth of the TX FIFO | |
| 113 | 112 | */ |
| 114 | 113 | struct cdns_spi { |
| 115 | 114 | void __iomem *regs; |
| @@ -123,6 +122,7 @@ struct cdns_spi { · 7 unmodified lines | ||
| 123 | 122 | int rx_bytes; |
| 124 | 123 | u8 dev_busy; |
| 125 | 124 | u32 is_decoded_cs; |
| 125 | + unsigned int tx_fifo_depth; | |
| 126 | 126 | }; |
| 127 | 127 | |
| 128 | 128 | /* Macros for the SPI controller read/write */ |
| @@ -304,7 +304,7 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi) · 175 unmodified lines | ||
| 304 | 304 | { |
| 305 | 305 | unsigned long trans_cnt = 0; |
| 306 | 306 | |
| 307 | − while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) && | |
| 307 | + while ((trans_cnt < xspi->tx_fifo_depth) && | |
| 308 | 308 | (xspi->tx_bytes > 0)) { |
| 309 | 309 | |
| 310 | 310 | /* When xspi in busy condition, bytes may send failed, |
| @@ -450,19 +450,42 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master) · 139 unmodified lines | ||
| 450 | 450 | * @master: Pointer to the spi_master structure which provides |
| 451 | 451 | * information about the controller. |
| 452 | 452 | * |
| 453 | − * This function disables the SPI master controller. | |
| 453 | + * This function disables the SPI master controller when no slave selected. | |
| 454 | 454 | * |
| 455 | 455 | * Return: 0 always |
| 456 | 456 | */ |
| 457 | 457 | static int cdns_unprepare_transfer_hardware(struct spi_master *master) |
| 458 | 458 | { |
| 459 | 459 | struct cdns_spi *xspi = spi_master_get_devdata(master); |
| 460 | + u32 ctrl_reg; | |
| 460 | 461 | |
| 461 | − cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); | |
| 462 | + /* Disable the SPI if slave is deselected */ | |
| 463 | + ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); | |
| 464 | + ctrl_reg = (ctrl_reg & CDNS_SPI_CR_SSCTRL) >> CDNS_SPI_SS_SHIFT; | |
| 465 | + if (ctrl_reg == CDNS_SPI_NOSS) | |
| 466 | + cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); | |
| 462 | 467 | |
| 463 | 468 | return 0; |
| 464 | 469 | } |
| 465 | 470 | |
| 471 | +/** | |
| 472 | + * cdns_spi_detect_fifo_depth - Detect the FIFO depth of the hardware | |
| 473 | + * @xspi: Pointer to the cdns_spi structure | |
| 474 | + * | |
| 475 | + * The depth of the TX FIFO is a synthesis configuration parameter of the SPI | |
| 476 | + * IP. The FIFO threshold register is sized so that its maximum value can be the | |
| 477 | + * FIFO size - 1. This is used to detect the size of the FIFO. | |
| 478 | + */ | |
| 479 | +static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi) | |
| 480 | +{ | |
| 481 | + /* The MSBs will get truncated giving us the size of the FIFO */ | |
| 482 | + cdns_spi_write(xspi, CDNS_SPI_THLD, 0xffff); | |
| 483 | + xspi->tx_fifo_depth = cdns_spi_read(xspi, CDNS_SPI_THLD) + 1; | |
| 484 | + | |
| 485 | + /* Reset to default */ | |
| 486 | + cdns_spi_write(xspi, CDNS_SPI_THLD, 0x1); | |
| 487 | +} | |
| 488 | + | |
| 466 | 489 | /** |
| 467 | 490 | * cdns_spi_probe - Probe method for the SPI driver |
| 468 | 491 | * @pdev: Pointer to the platform_device structure |
| @@ -535,6 +558,8 @@ static int cdns_spi_probe(struct platform_device *pdev) · 66 unmodified lines | ||
| 535 | 558 | if (ret < 0) |
| 536 | 559 | xspi->is_decoded_cs = 0; |
| 537 | 560 | |
| 561 | + cdns_spi_detect_fifo_depth(xspi); | |
| 562 | + | |
| 538 | 563 | /* SPI controller initializations */ |
| 539 | 564 | cdns_spi_init_hw(xspi); |
| 540 | 565 | |
| @@ -808,7 +808,7 @@ int spi_mem_poll_status(struct spi_mem *mem, · 807 unmodified lines | ||
| 808 | 808 | op->data.dir != SPI_MEM_DATA_IN) |
| 809 | 809 | return -EINVAL; |
| 810 | 810 | |
| 811 | − if (ctlr->mem_ops && ctlr->mem_ops->poll_status) { | |
| 811 | + if (ctlr->mem_ops && ctlr->mem_ops->poll_status && !mem->spi->cs_gpiod) { | |
| 812 | 812 | ret = spi_mem_access_start(mem); |
| 813 | 813 | if (ret) |
| 814 | 814 | return ret; |
| @@ -381,15 +381,18 @@ static int rockchip_spi_prepare_irq(struct rockchip_spi *rs, · 380 unmodified lines | ||
| 381 | 381 | rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0; |
| 382 | 382 | rs->rx_left = xfer->len / rs->n_bytes; |
| 383 | 383 | |
| 384 | − if (rs->cs_inactive) | |
| 385 | − writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR); | |
| 386 | − else | |
| 387 | − writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR); | |
| 384 | + writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR); | |
| 385 | + | |
| 388 | 386 | spi_enable_chip(rs, true); |
| 389 | 387 | |
| 390 | 388 | if (rs->tx_left) |
| 391 | 389 | rockchip_spi_pio_writer(rs); |
| 392 | 390 | |
| 391 | + if (rs->cs_inactive) | |
| 392 | + writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR); | |
| 393 | + else | |
| 394 | + writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR); | |
| 395 | + | |
| 393 | 396 | /* 1 means the transfer is in progress */ |
| 394 | 397 | return 1; |
| 395 | 398 | } |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | config FB_OLPC_DCON |
| 3 | 3 | tristate "One Laptop Per Child Display CONtroller support" |
| 4 | − depends on OLPC && FB | |
| 4 | + depends on OLPC && FB && BROKEN | |
| 5 | 5 | depends on I2C |
| 6 | 6 | depends on GPIO_CS5535 && ACPI |
| 7 | 7 | select BACKLIGHT_CLASS_DEVICE |
| @@ -178,8 +178,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; |
| 180 | 180 | |
| 181 | − res = rtw_alloc_hwxmits(padapter); | |
| 182 | − if (res) { | |
| 181 | + if (rtw_alloc_hwxmits(padapter)) { | |
| 183 | 182 | res = _FAIL; |
| 184 | 183 | goto exit; |
| 185 | 184 | } |
| @@ -1483,19 +1482,10 @@ int rtw_alloc_hwxmits(struct adapter *padapter) · 1297 unmodified lines | ||
| 1483 | 1482 | |
| 1484 | 1483 | hwxmits = pxmitpriv->hwxmits; |
| 1485 | 1484 | |
| 1486 | − if (pxmitpriv->hwxmit_entry == 5) { | |
| 1487 | − hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; | |
| 1488 | − hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; | |
| 1489 | − hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; | |
| 1490 | − hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; | |
| 1491 | − hwxmits[4] .sta_queue = &pxmitpriv->be_pending; | |
| 1492 | − } else if (pxmitpriv->hwxmit_entry == 4) { | |
| 1493 | − hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; | |
| 1494 | − hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; | |
| 1495 | − hwxmits[2] .sta_queue = &pxmitpriv->be_pending; | |
| 1496 | − hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; | |
| 1497 | − } else { | |
| 1498 | − } | |
| 1485 | + hwxmits[0].sta_queue = &pxmitpriv->vo_pending; | |
| 1486 | + hwxmits[1].sta_queue = &pxmitpriv->vi_pending; | |
| 1487 | + hwxmits[2].sta_queue = &pxmitpriv->be_pending; | |
| 1488 | + hwxmits[3].sta_queue = &pxmitpriv->bk_pending; | |
| 1499 | 1489 | |
| 1500 | 1490 | return 0; |
| 1501 | 1491 | } |
| @@ -403,7 +403,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, · 402 unmodified lines | ||
| 403 | 403 | |
| 404 | 404 | if (wep_key_len > 0) { |
| 405 | 405 | wep_key_len = wep_key_len <= 5 ? 5 : 13; |
| 406 | − wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); | |
| 406 | + wep_total_len = wep_key_len + sizeof(*pwep); | |
| 407 | 407 | pwep = kzalloc(wep_total_len, GFP_KERNEL); |
| 408 | 408 | if (!pwep) |
| 409 | 409 | goto exit; |
| @@ -90,7 +90,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, · 89 unmodified lines | ||
| 90 | 90 | if (wep_key_len > 0) { |
| 91 | 91 | wep_key_len = wep_key_len <= 5 ? 5 : 13; |
| 92 | 92 | wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material); |
| 93 | − pwep = kzalloc(wep_total_len, GFP_KERNEL); | |
| 93 | + /* Allocate a full structure to avoid potentially running off the end. */ | |
| 94 | + pwep = kzalloc(sizeof(*pwep), GFP_KERNEL); | |
| 94 | 95 | if (!pwep) { |
| 95 | 96 | ret = -ENOMEM; |
| 96 | 97 | goto exit; |
| @@ -582,7 +583,8 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, · 485 unmodified lines | ||
| 582 | 583 | if (wep_key_len > 0) { |
| 583 | 584 | wep_key_len = wep_key_len <= 5 ? 5 : 13; |
| 584 | 585 | wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material); |
| 585 | − pwep = kzalloc(wep_total_len, GFP_KERNEL); | |
| 586 | + /* Allocate a full structure to avoid potentially running off the end. */ | |
| 587 | + pwep = kzalloc(sizeof(*pwep), GFP_KERNEL); | |
| 586 | 588 | if (!pwep) |
| 587 | 589 | goto exit; |
| 588 | 590 | |
| @@ -426,7 +426,7 @@ static int goldfish_tty_remove(struct platform_device *pdev) · 425 unmodified lines | ||
| 426 | 426 | tty_unregister_device(goldfish_tty_driver, qtty->console.index); |
| 427 | 427 | iounmap(qtty->base); |
| 428 | 428 | qtty->base = NULL; |
| 429 | − free_irq(qtty->irq, pdev); | |
| 429 | + free_irq(qtty->irq, qtty); | |
| 430 | 430 | tty_port_destroy(&qtty->port); |
| 431 | 431 | goldfish_tty_current_line_count--; |
| 432 | 432 | if (goldfish_tty_current_line_count == 0) |
| @@ -455,7 +455,7 @@ static void gsm_hex_dump_bytes(const char *fname, const u8 *data, · 454 unmodified lines | ||
| 455 | 455 | return; |
| 456 | 456 | } |
| 457 | 457 | |
| 458 | − prefix = kasprintf(GFP_KERNEL, "%s: ", fname); | |
| 458 | + prefix = kasprintf(GFP_ATOMIC, "%s: ", fname); | |
| 459 | 459 | if (!prefix) |
| 460 | 460 | return; |
| 461 | 461 | print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, data, len, |
| @@ -1517,6 +1517,8 @@ static inline void __stop_tx(struct uart_8250_port *p) · 1516 unmodified lines | ||
| 1517 | 1517 | unsigned char lsr = serial_in(p, UART_LSR); |
| 1518 | 1518 | u64 stop_delay = 0; |
| 1519 | 1519 | |
| 1520 | + p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | |
| 1521 | + | |
| 1520 | 1522 | if (!(lsr & UART_LSR_THRE)) |
| 1521 | 1523 | return; |
| 1522 | 1524 | /* |
| @@ -1306,6 +1306,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 1305 unmodified lines | ||
| 1306 | 1306 | .stop_tx = qcom_geni_serial_stop_tx, |
| 1307 | 1307 | .start_tx = qcom_geni_serial_start_tx, |
| 1308 | 1308 | .stop_rx = qcom_geni_serial_stop_rx, |
| 1309 | + .start_rx = qcom_geni_serial_start_rx, | |
| 1309 | 1310 | .set_termios = qcom_geni_serial_set_termios, |
| 1310 | 1311 | .startup = qcom_geni_serial_startup, |
| 1311 | 1312 | .request_port = qcom_geni_serial_request_port, |
| @@ -2214,11 +2214,12 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) · 2213 unmodified lines | ||
| 2214 | 2214 | /* |
| 2215 | 2215 | * Nothing to do if the console is not suspending |
| 2216 | 2216 | * except stop_rx to prevent any asynchronous data |
| 2217 | − * over RX line. Re-start_rx, when required, is | |
| 2218 | − * done by set_termios in resume sequence | |
| 2217 | + * over RX line. However ensure that we will be | |
| 2218 | + * able to Re-start_rx later. | |
| 2219 | 2219 | */ |
| 2220 | 2220 | if (!console_suspend_enabled && uart_console(uport)) { |
| 2221 | − uport->ops->stop_rx(uport); | |
| 2221 | + if (uport->ops->start_rx) | |
| 2222 | + uport->ops->stop_rx(uport); | |
| 2222 | 2223 | goto unlock; |
| 2223 | 2224 | } |
| 2224 | 2225 | |
| @@ -2310,6 +2311,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) · 85 unmodified lines | ||
| 2310 | 2311 | if (console_suspend_enabled) |
| 2311 | 2312 | uart_change_pm(state, UART_PM_STATE_ON); |
| 2312 | 2313 | uport->ops->set_termios(uport, &termios, NULL); |
| 2314 | + if (!console_suspend_enabled && uport->ops->start_rx) | |
| 2315 | + uport->ops->start_rx(uport); | |
| 2313 | 2316 | if (console_suspend_enabled) |
| 2314 | 2317 | console_start(uport->cons); |
| 2315 | 2318 | } |
| @@ -581,7 +581,6 @@ void __handle_sysrq(int key, bool check_mask) · 580 unmodified lines | ||
| 581 | 581 | |
| 582 | 582 | rcu_sysrq_start(); |
| 583 | 583 | rcu_read_lock(); |
| 584 | − printk_prefer_direct_enter(); | |
| 585 | 584 | /* |
| 586 | 585 | * Raise the apparent loglevel to maximum so that the sysrq header |
| 587 | 586 | * is shown to provide the user with positive feedback. We do not |
| @@ -623,7 +622,6 @@ void __handle_sysrq(int key, bool check_mask) · 35 unmodified lines | ||
| 623 | 622 | pr_cont("\n"); |
| 624 | 623 | console_loglevel = orig_log_level; |
| 625 | 624 | } |
| 626 | − printk_prefer_direct_exit(); | |
| 627 | 625 | rcu_read_unlock(); |
| 628 | 626 | rcu_sysrq_end(); |
| 629 | 627 | |
| @@ -748,17 +748,28 @@ static enum utp_ocs ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp) · 747 unmodified lines | ||
| 748 | 748 | } |
| 749 | 749 | |
| 750 | 750 | /** |
| 751 | − * ufshcd_utrl_clear - Clear a bit in UTRLCLR register | |
| 751 | + * ufshcd_utrl_clear() - Clear requests from the controller request list. | |
| 752 | 752 | * @hba: per adapter instance |
| 753 | − * @pos: position of the bit to be cleared | |
| 753 | + * @mask: mask with one bit set for each request to be cleared | |
| 754 | 754 | */ |
| 755 | −static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) | |
| 755 | +static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 mask) | |
| 756 | 756 | { |
| 757 | 757 | if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR) |
| 758 | − ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR); | |
| 759 | − else | |
| 760 | − ufshcd_writel(hba, ~(1 << pos), | |
| 761 | − REG_UTP_TRANSFER_REQ_LIST_CLEAR); | |
| 758 | + mask = ~mask; | |
| 759 | + /* | |
| 760 | + * From the UFSHCI specification: "UTP Transfer Request List CLear | |
| 761 | + * Register (UTRLCLR): This field is bit significant. Each bit | |
| 762 | + * corresponds to a slot in the UTP Transfer Request List, where bit 0 | |
| 763 | + * corresponds to request slot 0. A bit in this field is set to ‘0’ | |
| 764 | + * by host software to indicate to the host controller that a transfer | |
| 765 | + * request slot is cleared. The host controller | |
| 766 | + * shall free up any resources associated to the request slot | |
| 767 | + * immediately, and shall set the associated bit in UTRLDBR to ‘0’. The | |
| 768 | + * host software indicates no change to request slots by setting the | |
| 769 | + * associated bits in this field to ‘1’. Bits in this field shall only | |
| 770 | + * be set ‘1’ or ‘0’ by host software when UTRLRSR is set to ‘1’." | |
| 771 | + */ | |
| 772 | + ufshcd_writel(hba, ~mask, REG_UTP_TRANSFER_REQ_LIST_CLEAR); | |
| 762 | 773 | } |
| 763 | 774 | |
| 764 | 775 | /** |
| @@ -2863,27 +2874,26 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba, · 2098 unmodified lines | ||
| 2863 | 2874 | return ufshcd_compose_devman_upiu(hba, lrbp); |
| 2864 | 2875 | } |
| 2865 | 2876 | |
| 2866 | −static int | |
| 2867 | −ufshcd_clear_cmd(struct ufs_hba *hba, int tag) | |
| 2877 | +/* | |
| 2878 | + * Clear all the requests from the controller for which a bit has been set in | |
| 2879 | + * @mask and wait until the controller confirms that these requests have been | |
| 2880 | + * cleared. | |
| 2881 | + */ | |
| 2882 | +static int ufshcd_clear_cmds(struct ufs_hba *hba, u32 mask) | |
| 2868 | 2883 | { |
| 2869 | − int err = 0; | |
| 2870 | 2884 | unsigned long flags; |
| 2871 | − u32 mask = 1 << tag; | |
| 2872 | 2885 | |
| 2873 | 2886 | /* clear outstanding transaction before retry */ |
| 2874 | 2887 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 2875 | − ufshcd_utrl_clear(hba, tag); | |
| 2888 | + ufshcd_utrl_clear(hba, mask); | |
| 2876 | 2889 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 2877 | 2890 | |
| 2878 | 2891 | /* |
| 2879 | 2892 | * wait for h/w to clear corresponding bit in door-bell. |
| 2880 | 2893 | * max. wait is 1 sec. |
| 2881 | 2894 | */ |
| 2882 | − err = ufshcd_wait_for_register(hba, | |
| 2883 | − REG_UTP_TRANSFER_REQ_DOOR_BELL, | |
| 2884 | − mask, ~mask, 1000, 1000); | |
| 2885 | − | |
| 2886 | − return err; | |
| 2895 | + return ufshcd_wait_for_register(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL, | |
| 2896 | + mask, ~mask, 1000, 1000); | |
| 2887 | 2897 | } |
| 2888 | 2898 | |
| 2889 | 2899 | static int |
| @@ -2963,7 +2973,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, · 73 unmodified lines | ||
| 2963 | 2973 | err = -ETIMEDOUT; |
| 2964 | 2974 | dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n", |
| 2965 | 2975 | __func__, lrbp->task_tag); |
| 2966 | − if (!ufshcd_clear_cmd(hba, lrbp->task_tag)) | |
| 2976 | + if (!ufshcd_clear_cmds(hba, 1U << lrbp->task_tag)) | |
| 2967 | 2977 | /* successfully cleared the command, retry if needed */ |
| 2968 | 2978 | err = -EAGAIN; |
| 2969 | 2979 | /* |
| @@ -6958,14 +6968,14 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, · 3988 unmodified lines | ||
| 6958 | 6968 | } |
| 6959 | 6969 | |
| 6960 | 6970 | /** |
| 6961 | − * ufshcd_eh_device_reset_handler - device reset handler registered to | |
| 6962 | − * scsi layer. | |
| 6971 | + * ufshcd_eh_device_reset_handler() - Reset a single logical unit. | |
| 6963 | 6972 | * @cmd: SCSI command pointer |
| 6964 | 6973 | * |
| 6965 | 6974 | * Returns SUCCESS/FAILED |
| 6966 | 6975 | */ |
| 6967 | 6976 | static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) |
| 6968 | 6977 | { |
| 6978 | + unsigned long flags, pending_reqs = 0, not_cleared = 0; | |
| 6969 | 6979 | struct Scsi_Host *host; |
| 6970 | 6980 | struct ufs_hba *hba; |
| 6971 | 6981 | u32 pos; |
| @@ -6984,14 +6994,24 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) · 12 unmodified lines | ||
| 6984 | 6994 | } |
| 6985 | 6995 | |
| 6986 | 6996 | /* clear the commands that were pending for corresponding LUN */ |
| 6987 | − for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) { | |
| 6988 | − if (hba->lrb[pos].lun == lun) { | |
| 6989 | − err = ufshcd_clear_cmd(hba, pos); | |
| 6990 | − if (err) | |
| 6991 | − break; | |
| 6992 | − __ufshcd_transfer_req_compl(hba, 1U << pos); | |
| 6993 | − } | |
| 6997 | + spin_lock_irqsave(&hba->outstanding_lock, flags); | |
| 6998 | + for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) | |
| 6999 | + if (hba->lrb[pos].lun == lun) | |
| 7000 | + __set_bit(pos, &pending_reqs); | |
| 7001 | + hba->outstanding_reqs &= ~pending_reqs; | |
| 7002 | + spin_unlock_irqrestore(&hba->outstanding_lock, flags); | |
| 7003 | + | |
| 7004 | + if (ufshcd_clear_cmds(hba, pending_reqs) < 0) { | |
| 7005 | + spin_lock_irqsave(&hba->outstanding_lock, flags); | |
| 7006 | + not_cleared = pending_reqs & | |
| 7007 | + ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); | |
| 7008 | + hba->outstanding_reqs |= not_cleared; | |
| 7009 | + spin_unlock_irqrestore(&hba->outstanding_lock, flags); | |
| 7010 | + | |
| 7011 | + dev_err(hba->dev, "%s: failed to clear requests %#lx\n", | |
| 7012 | + __func__, not_cleared); | |
| 6994 | 7013 | } |
| 7014 | + __ufshcd_transfer_req_compl(hba, pending_reqs & ~not_cleared); | |
| 6995 | 7015 | |
| 6996 | 7016 | out: |
| 6997 | 7017 | hba->req_abort_count = 0; |
| @@ -7088,7 +7108,7 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag) · 90 unmodified lines | ||
| 7088 | 7108 | goto out; |
| 7089 | 7109 | } |
| 7090 | 7110 | |
| 7091 | − err = ufshcd_clear_cmd(hba, tag); | |
| 7111 | + err = ufshcd_clear_cmds(hba, 1U << tag); | |
| 7092 | 7112 | if (err) |
| 7093 | 7113 | dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n", |
| 7094 | 7114 | __func__, tag, err); |
| @@ -1941,13 +1941,16 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) · 1940 unmodified lines | ||
| 1941 | 1941 | } |
| 1942 | 1942 | |
| 1943 | 1943 | if (enqd_len + trb_buff_len >= full_len) { |
| 1944 | − if (need_zero_pkt) | |
| 1945 | − zero_len_trb = !zero_len_trb; | |
| 1946 | − | |
| 1947 | − field &= ~TRB_CHAIN; | |
| 1948 | − field |= TRB_IOC; | |
| 1949 | − more_trbs_coming = false; | |
| 1950 | − preq->td.last_trb = ring->enqueue; | |
| 1944 | + if (need_zero_pkt && !zero_len_trb) { | |
| 1945 | + zero_len_trb = true; | |
| 1946 | + } else { | |
| 1947 | + zero_len_trb = false; | |
| 1948 | + field &= ~TRB_CHAIN; | |
| 1949 | + field |= TRB_IOC; | |
| 1950 | + more_trbs_coming = false; | |
| 1951 | + need_zero_pkt = false; | |
| 1952 | + preq->td.last_trb = ring->enqueue; | |
| 1953 | + } | |
| 1951 | 1954 | } |
| 1952 | 1955 | |
| 1953 | 1956 | /* Only set interrupt on short packet for OUT endpoints. */ |
| @@ -1962,7 +1965,7 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) · 8 unmodified lines | ||
| 1962 | 1965 | length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) | |
| 1963 | 1966 | TRB_INTR_TARGET(0); |
| 1964 | 1967 | |
| 1965 | − cdnsp_queue_trb(pdev, ring, more_trbs_coming | zero_len_trb, | |
| 1968 | + cdnsp_queue_trb(pdev, ring, more_trbs_coming, | |
| 1966 | 1969 | lower_32_bits(send_addr), |
| 1967 | 1970 | upper_32_bits(send_addr), |
| 1968 | 1971 | length_field, |
| @@ -1048,6 +1048,9 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) · 1047 unmodified lines | ||
| 1048 | 1048 | struct ci_hdrc *ci = req->context; |
| 1049 | 1049 | unsigned long flags; |
| 1050 | 1050 | |
| 1051 | + if (req->status < 0) | |
| 1052 | + return; | |
| 1053 | + | |
| 1051 | 1054 | if (ci->setaddr) { |
| 1052 | 1055 | hw_usb_set_address(ci, ci->address); |
| 1053 | 1056 | ci->setaddr = false; |
| @@ -5190,7 +5190,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg) · 5189 unmodified lines | ||
| 5190 | 5190 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 5191 | 5191 | if (!res) { |
| 5192 | 5192 | retval = -EINVAL; |
| 5193 | − goto error1; | |
| 5193 | + goto error2; | |
| 5194 | 5194 | } |
| 5195 | 5195 | hcd->rsrc_start = res->start; |
| 5196 | 5196 | hcd->rsrc_len = resource_size(res); |
| @@ -1644,13 +1644,8 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) · 1643 unmodified lines | ||
| 1644 | 1644 | * This device property is for kernel internal use only and |
| 1645 | 1645 | * is expected to be set by the glue code. |
| 1646 | 1646 | */ |
| 1647 | − if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) { | |
| 1648 | − edev = extcon_get_extcon_dev(name); | |
| 1649 | − if (!edev) | |
| 1650 | − return ERR_PTR(-EPROBE_DEFER); | |
| 1651 | − | |
| 1652 | − return edev; | |
| 1653 | − } | |
| 1647 | + if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) | |
| 1648 | + return extcon_get_extcon_dev(name); | |
| 1654 | 1649 | |
| 1655 | 1650 | /* |
| 1656 | 1651 | * Try to get an extcon device from the USB PHY controller's "port" |
| @@ -127,6 +127,7 @@ static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[ · 126 unmodified lines | ||
| 127 | 127 | PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), |
| 128 | 128 | PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), |
| 129 | 129 | PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"), |
| 130 | + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), | |
| 130 | 131 | {} |
| 131 | 132 | }; |
| 132 | 133 | |
| @@ -2976,6 +2976,7 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) · 2975 unmodified lines | ||
| 2976 | 2976 | struct dwc3 *dwc = dep->dwc; |
| 2977 | 2977 | u32 mdwidth; |
| 2978 | 2978 | int size; |
| 2979 | + int maxpacket; | |
| 2979 | 2980 | |
| 2980 | 2981 | mdwidth = dwc3_mdwidth(dwc); |
| 2981 | 2982 | |
| @@ -2988,21 +2989,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) · 6 unmodified lines | ||
| 2988 | 2989 | else |
| 2989 | 2990 | size = DWC31_GTXFIFOSIZ_TXFDEP(size); |
| 2990 | 2991 | |
| 2991 | − /* FIFO Depth is in MDWDITH bytes. Multiply */ | |
| 2992 | − size *= mdwidth; | |
| 2993 | − | |
| 2994 | 2992 | /* |
| 2995 | − * To meet performance requirement, a minimum TxFIFO size of 3x | |
| 2996 | − * MaxPacketSize is recommended for endpoints that support burst and a | |
| 2997 | − * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't | |
| 2998 | − * support burst. Use those numbers and we can calculate the max packet | |
| 2999 | − * limit as below. | |
| 2993 | + * maxpacket size is determined as part of the following, after assuming | |
| 2994 | + * a mult value of one maxpacket: | |
| 2995 | + * DWC3 revision 280A and prior: | |
| 2996 | + * fifo_size = mult * (max_packet / mdwidth) + 1; | |
| 2997 | + * maxpacket = mdwidth * (fifo_size - 1); | |
| 2998 | + * | |
| 2999 | + * DWC3 revision 290A and onwards: | |
| 3000 | + * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1 | |
| 3001 | + * maxpacket = mdwidth * ((fifo_size - 1) - 1) - mdwidth; | |
| 3000 | 3002 | */ |
| 3001 | − if (dwc->maximum_speed >= USB_SPEED_SUPER) | |
| 3002 | − size /= 3; | |
| 3003 | + if (DWC3_VER_IS_PRIOR(DWC3, 290A)) | |
| 3004 | + maxpacket = mdwidth * (size - 1); | |
| 3003 | 3005 | else |
| 3004 | − size /= 2; | |
| 3006 | + maxpacket = mdwidth * ((size - 1) - 1) - mdwidth; | |
| 3005 | 3007 | |
| 3008 | + /* Functionally, space for one max packet is sufficient */ | |
| 3009 | + size = min_t(int, maxpacket, 1024); | |
| 3006 | 3010 | usb_ep_set_maxpacket_limit(&dep->endpoint, size); |
| 3007 | 3011 | |
| 3008 | 3012 | dep->endpoint.max_streams = 16; |
| @@ -122,8 +122,6 @@ struct ffs_ep { · 121 unmodified lines | ||
| 122 | 122 | struct usb_endpoint_descriptor *descs[3]; |
| 123 | 123 | |
| 124 | 124 | u8 num; |
| 125 | − | |
| 126 | − int status; /* P: epfile->mutex */ | |
| 127 | 125 | }; |
| 128 | 126 | |
| 129 | 127 | struct ffs_epfile { |
| @@ -227,6 +225,9 @@ struct ffs_io_data { · 97 unmodified lines | ||
| 227 | 225 | bool use_sg; |
| 228 | 226 | |
| 229 | 227 | struct ffs_data *ffs; |
| 228 | + | |
| 229 | + int status; | |
| 230 | + struct completion done; | |
| 230 | 231 | }; |
| 231 | 232 | |
| 232 | 233 | struct ffs_desc_helper { |
| @@ -707,12 +708,15 @@ static const struct file_operations ffs_ep0_operations = { · 474 unmodified lines | ||
| 707 | 708 | |
| 708 | 709 | static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) |
| 709 | 710 | { |
| 711 | + struct ffs_io_data *io_data = req->context; | |
| 712 | + | |
| 710 | 713 | ENTER(); |
| 711 | − if (req->context) { | |
| 712 | − struct ffs_ep *ep = _ep->driver_data; | |
| 713 | − ep->status = req->status ? req->status : req->actual; | |
| 714 | − complete(req->context); | |
| 715 | − } | |
| 714 | + if (req->status) | |
| 715 | + io_data->status = req->status; | |
| 716 | + else | |
| 717 | + io_data->status = req->actual; | |
| 718 | + | |
| 719 | + complete(&io_data->done); | |
| 716 | 720 | } |
| 717 | 721 | |
| 718 | 722 | static ssize_t ffs_copy_to_iter(void *data, int data_len, struct iov_iter *iter) |
| @@ -1050,7 +1054,6 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 331 unmodified lines | ||
| 1050 | 1054 | WARN(1, "%s: data_len == -EINVAL\n", __func__); |
| 1051 | 1055 | ret = -EINVAL; |
| 1052 | 1056 | } else if (!io_data->aio) { |
| 1053 | − DECLARE_COMPLETION_ONSTACK(done); | |
| 1054 | 1057 | bool interrupted = false; |
| 1055 | 1058 | |
| 1056 | 1059 | req = ep->req; |
| @@ -1066,7 +1069,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 9 unmodified lines | ||
| 1066 | 1069 | |
| 1067 | 1070 | io_data->buf = data; |
| 1068 | 1071 | |
| 1069 | − req->context = &done; | |
| 1072 | + init_completion(&io_data->done); | |
| 1073 | + req->context = io_data; | |
| 1070 | 1074 | req->complete = ffs_epfile_io_complete; |
| 1071 | 1075 | |
| 1072 | 1076 | ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); |
| @@ -1075,7 +1079,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 2 unmodified lines | ||
| 1075 | 1079 | |
| 1076 | 1080 | spin_unlock_irq(&epfile->ffs->eps_lock); |
| 1077 | 1081 | |
| 1078 | − if (wait_for_completion_interruptible(&done)) { | |
| 1082 | + if (wait_for_completion_interruptible(&io_data->done)) { | |
| 1083 | + spin_lock_irq(&epfile->ffs->eps_lock); | |
| 1084 | + if (epfile->ep != ep) { | |
| 1085 | + ret = -ESHUTDOWN; | |
| 1086 | + goto error_lock; | |
| 1087 | + } | |
| 1079 | 1088 | /* |
| 1080 | 1089 | * To avoid race condition with ffs_epfile_io_complete, |
| 1081 | 1090 | * dequeue the request first then check |
| @@ -1083,17 +1092,18 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 1 unmodified line | ||
| 1083 | 1092 | * condition with req->complete callback. |
| 1084 | 1093 | */ |
| 1085 | 1094 | usb_ep_dequeue(ep->ep, req); |
| 1086 | − wait_for_completion(&done); | |
| 1087 | − interrupted = ep->status < 0; | |
| 1095 | + spin_unlock_irq(&epfile->ffs->eps_lock); | |
| 1096 | + wait_for_completion(&io_data->done); | |
| 1097 | + interrupted = io_data->status < 0; | |
| 1088 | 1098 | } |
| 1089 | 1099 | |
| 1090 | 1100 | if (interrupted) |
| 1091 | 1101 | ret = -EINTR; |
| 1092 | − else if (io_data->read && ep->status > 0) | |
| 1093 | − ret = __ffs_epfile_read_data(epfile, data, ep->status, | |
| 1102 | + else if (io_data->read && io_data->status > 0) | |
| 1103 | + ret = __ffs_epfile_read_data(epfile, data, io_data->status, | |
| 1094 | 1104 | &io_data->data); |
| 1095 | 1105 | else |
| 1096 | − ret = ep->status; | |
| 1106 | + ret = io_data->status; | |
| 1097 | 1107 | goto error_mutex; |
| 1098 | 1108 | } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) { |
| 1099 | 1109 | ret = -ENOMEM; |
| @@ -775,9 +775,13 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, · 774 unmodified lines | ||
| 775 | 775 | dev->qmult = qmult; |
| 776 | 776 | snprintf(net->name, sizeof(net->name), "%s%%d", netname); |
| 777 | 777 | |
| 778 | − if (get_ether_addr(dev_addr, addr)) | |
| 778 | + if (get_ether_addr(dev_addr, addr)) { | |
| 779 | + net->addr_assign_type = NET_ADDR_RANDOM; | |
| 779 | 780 | dev_warn(&g->dev, |
| 780 | 781 | "using random %s ethernet address\n", "self"); |
| 782 | + } else { | |
| 783 | + net->addr_assign_type = NET_ADDR_SET; | |
| 784 | + } | |
| 781 | 785 | eth_hw_addr_set(net, addr); |
| 782 | 786 | if (get_ether_addr(host_addr, dev->host_mac)) |
| 783 | 787 | dev_warn(&g->dev, |
| @@ -844,6 +848,10 @@ struct net_device *gether_setup_name_default(const char *netname) · 60 unmodified lines | ||
| 844 | 848 | |
| 845 | 849 | eth_random_addr(dev->dev_mac); |
| 846 | 850 | pr_warn("using random %s ethernet address\n", "self"); |
| 851 | + | |
| 852 | + /* by default we always have a random MAC address */ | |
| 853 | + net->addr_assign_type = NET_ADDR_RANDOM; | |
| 854 | + | |
| 847 | 855 | eth_random_addr(dev->host_mac); |
| 848 | 856 | pr_warn("using random %s ethernet address\n", "host"); |
| 849 | 857 | |
| @@ -871,7 +879,6 @@ int gether_register_netdev(struct net_device *net) · 21 unmodified lines | ||
| 871 | 879 | dev = netdev_priv(net); |
| 872 | 880 | g = dev->gadget; |
| 873 | 881 | |
| 874 | − net->addr_assign_type = NET_ADDR_RANDOM; | |
| 875 | 882 | eth_hw_addr_set(net, dev->dev_mac); |
| 876 | 883 | |
| 877 | 884 | status = register_netdev(net); |
| @@ -912,6 +919,7 @@ int gether_set_dev_addr(struct net_device *net, const char *dev_addr) · 34 unmodified lines | ||
| 912 | 919 | if (get_ether_addr(dev_addr, new_addr)) |
| 913 | 920 | return -EINVAL; |
| 914 | 921 | memcpy(dev->dev_mac, new_addr, ETH_ALEN); |
| 922 | + net->addr_assign_type = NET_ADDR_SET; | |
| 915 | 923 | return 0; |
| 916 | 924 | } |
| 917 | 925 | EXPORT_SYMBOL_GPL(gether_set_dev_addr); |
| @@ -424,6 +424,9 @@ static void uvcg_video_pump(struct work_struct *work) · 423 unmodified lines | ||
| 424 | 424 | uvcg_queue_cancel(queue, 0); |
| 425 | 425 | break; |
| 426 | 426 | } |
| 427 | + | |
| 428 | + /* Endpoint now owns the request */ | |
| 429 | + req = NULL; | |
| 427 | 430 | video->req_int_count++; |
| 428 | 431 | } |
| 429 | 432 | |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/ctype.h> |
| 12 | 12 | #include <linux/debugfs.h> |
| 13 | 13 | #include <linux/delay.h> |
| 14 | +#include <linux/idr.h> | |
| 14 | 15 | #include <linux/kref.h> |
| 15 | 16 | #include <linux/miscdevice.h> |
| 16 | 17 | #include <linux/module.h> |
| @@ -36,6 +37,9 @@ MODULE_LICENSE("GPL"); · 19 unmodified lines | ||
| 36 | 37 | |
| 37 | 38 | /*----------------------------------------------------------------------*/ |
| 38 | 39 | |
| 40 | +static DEFINE_IDA(driver_id_numbers); | |
| 41 | +#define DRIVER_DRIVER_NAME_LENGTH_MAX 32 | |
| 42 | + | |
| 39 | 43 | #define RAW_EVENT_QUEUE_SIZE 16 |
| 40 | 44 | |
| 41 | 45 | struct raw_event_queue { |
| @@ -161,6 +165,9 @@ struct raw_dev { · 119 unmodified lines | ||
| 161 | 165 | /* Reference to misc device: */ |
| 162 | 166 | struct device *dev; |
| 163 | 167 | |
| 168 | + /* Make driver names unique */ | |
| 169 | + int driver_id_number; | |
| 170 | + | |
| 164 | 171 | /* Protected by lock: */ |
| 165 | 172 | enum dev_state state; |
| 166 | 173 | bool gadget_registered; |
| @@ -189,6 +196,7 @@ static struct raw_dev *dev_new(void) · 22 unmodified lines | ||
| 189 | 196 | spin_lock_init(&dev->lock); |
| 190 | 197 | init_completion(&dev->ep0_done); |
| 191 | 198 | raw_event_queue_init(&dev->queue); |
| 199 | + dev->driver_id_number = -1; | |
| 192 | 200 | return dev; |
| 193 | 201 | } |
| 194 | 202 | |
| @@ -199,6 +207,9 @@ static void dev_free(struct kref *kref) · 4 unmodified lines | ||
| 199 | 207 | |
| 200 | 208 | kfree(dev->udc_name); |
| 201 | 209 | kfree(dev->driver.udc_name); |
| 210 | + kfree(dev->driver.driver.name); | |
| 211 | + if (dev->driver_id_number >= 0) | |
| 212 | + ida_free(&driver_id_numbers, dev->driver_id_number); | |
| 202 | 213 | if (dev->req) { |
| 203 | 214 | if (dev->ep0_urb_queued) |
| 204 | 215 | usb_ep_dequeue(dev->gadget->ep0, dev->req); |
| @@ -419,9 +430,11 @@ out_put: · 214 unmodified lines | ||
| 419 | 430 | static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) |
| 420 | 431 | { |
| 421 | 432 | int ret = 0; |
| 433 | + int driver_id_number; | |
| 422 | 434 | struct usb_raw_init arg; |
| 423 | 435 | char *udc_driver_name; |
| 424 | 436 | char *udc_device_name; |
| 437 | + char *driver_driver_name; | |
| 425 | 438 | unsigned long flags; |
| 426 | 439 | |
| 427 | 440 | if (copy_from_user(&arg, (void __user *)value, sizeof(arg))) |
| @@ -440,36 +453,43 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) · 12 unmodified lines | ||
| 440 | 453 | return -EINVAL; |
| 441 | 454 | } |
| 442 | 455 | |
| 456 | + driver_id_number = ida_alloc(&driver_id_numbers, GFP_KERNEL); | |
| 457 | + if (driver_id_number < 0) | |
| 458 | + return driver_id_number; | |
| 459 | + | |
| 460 | + driver_driver_name = kmalloc(DRIVER_DRIVER_NAME_LENGTH_MAX, GFP_KERNEL); | |
| 461 | + if (!driver_driver_name) { | |
| 462 | + ret = -ENOMEM; | |
| 463 | + goto out_free_driver_id_number; | |
| 464 | + } | |
| 465 | + snprintf(driver_driver_name, DRIVER_DRIVER_NAME_LENGTH_MAX, | |
| 466 | + DRIVER_NAME ".%d", driver_id_number); | |
| 467 | + | |
| 443 | 468 | udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); |
| 444 | − if (!udc_driver_name) | |
| 445 | − return -ENOMEM; | |
| 469 | + if (!udc_driver_name) { | |
| 470 | + ret = -ENOMEM; | |
| 471 | + goto out_free_driver_driver_name; | |
| 472 | + } | |
| 446 | 473 | ret = strscpy(udc_driver_name, &arg.driver_name[0], |
| 447 | 474 | UDC_NAME_LENGTH_MAX); |
| 448 | − if (ret < 0) { | |
| 449 | − kfree(udc_driver_name); | |
| 450 | − return ret; | |
| 451 | − } | |
| 475 | + if (ret < 0) | |
| 476 | + goto out_free_udc_driver_name; | |
| 452 | 477 | ret = 0; |
| 453 | 478 | |
| 454 | 479 | udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); |
| 455 | 480 | if (!udc_device_name) { |
| 456 | − kfree(udc_driver_name); | |
| 457 | − return -ENOMEM; | |
| 481 | + ret = -ENOMEM; | |
| 482 | + goto out_free_udc_driver_name; | |
| 458 | 483 | } |
| 459 | 484 | ret = strscpy(udc_device_name, &arg.device_name[0], |
| 460 | 485 | UDC_NAME_LENGTH_MAX); |
| 461 | − if (ret < 0) { | |
| 462 | − kfree(udc_driver_name); | |
| 463 | − kfree(udc_device_name); | |
| 464 | − return ret; | |
| 465 | − } | |
| 486 | + if (ret < 0) | |
| 487 | + goto out_free_udc_device_name; | |
| 466 | 488 | ret = 0; |
| 467 | 489 | |
| 468 | 490 | spin_lock_irqsave(&dev->lock, flags); |
| 469 | 491 | if (dev->state != STATE_DEV_OPENED) { |
| 470 | 492 | dev_dbg(dev->dev, "fail, device is not opened\n"); |
| 471 | − kfree(udc_driver_name); | |
| 472 | − kfree(udc_device_name); | |
| 473 | 493 | ret = -EINVAL; |
| 474 | 494 | goto out_unlock; |
| 475 | 495 | } |
| @@ -484,14 +504,25 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) · 8 unmodified lines | ||
| 484 | 504 | dev->driver.suspend = gadget_suspend; |
| 485 | 505 | dev->driver.resume = gadget_resume; |
| 486 | 506 | dev->driver.reset = gadget_reset; |
| 487 | − dev->driver.driver.name = DRIVER_NAME; | |
| 507 | + dev->driver.driver.name = driver_driver_name; | |
| 488 | 508 | dev->driver.udc_name = udc_device_name; |
| 489 | 509 | dev->driver.match_existing_only = 1; |
| 510 | + dev->driver_id_number = driver_id_number; | |
| 490 | 511 | |
| 491 | 512 | dev->state = STATE_DEV_INITIALIZED; |
| 513 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 514 | + return ret; | |
| 492 | 515 | |
| 493 | 516 | out_unlock: |
| 494 | 517 | spin_unlock_irqrestore(&dev->lock, flags); |
| 518 | +out_free_udc_device_name: | |
| 519 | + kfree(udc_device_name); | |
| 520 | +out_free_udc_driver_name: | |
| 521 | + kfree(udc_driver_name); | |
| 522 | +out_free_driver_driver_name: | |
| 523 | + kfree(driver_driver_name); | |
| 524 | +out_free_driver_id_number: | |
| 525 | + ida_free(&driver_id_numbers, driver_id_number); | |
| 495 | 526 | return ret; |
| 496 | 527 | } |
| 497 | 528 | |
| @@ -3016,6 +3016,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) · 3015 unmodified lines | ||
| 3016 | 3016 | } |
| 3017 | 3017 | |
| 3018 | 3018 | udc->isp1301_i2c_client = isp1301_get_client(isp1301_node); |
| 3019 | + of_node_put(isp1301_node); | |
| 3019 | 3020 | if (!udc->isp1301_i2c_client) { |
| 3020 | 3021 | return -EPROBE_DEFER; |
| 3021 | 3022 | } |
| @@ -652,7 +652,7 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd) · 651 unmodified lines | ||
| 652 | 652 | * It will release and re-aquire the lock while calling ACPI |
| 653 | 653 | * method. |
| 654 | 654 | */ |
| 655 | −static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, | |
| 655 | +void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, | |
| 656 | 656 | u16 index, bool on, unsigned long *flags) |
| 657 | 657 | __must_hold(&xhci->lock) |
| 658 | 658 | { |
| @@ -61,6 +61,8 @@ · 60 unmodified lines | ||
| 61 | 61 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e |
| 62 | 62 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI 0x464e |
| 63 | 63 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed |
| 64 | +#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI 0xa71e | |
| 65 | +#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI 0x7ec0 | |
| 64 | 66 | |
| 65 | 67 | #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 |
| 66 | 68 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 |
| @@ -269,7 +271,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 202 unmodified lines | ||
| 269 | 271 | pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || |
| 270 | 272 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI || |
| 271 | 273 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI || |
| 272 | − pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)) | |
| 274 | + pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI || | |
| 275 | + pdev->device == PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI || | |
| 276 | + pdev->device == PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI)) | |
| 273 | 277 | xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; |
| 274 | 278 | |
| 275 | 279 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
| @@ -611,15 +611,37 @@ static int xhci_init(struct usb_hcd *hcd) · 610 unmodified lines | ||
| 611 | 611 | |
| 612 | 612 | static int xhci_run_finished(struct xhci_hcd *xhci) |
| 613 | 613 | { |
| 614 | + unsigned long flags; | |
| 615 | + u32 temp; | |
| 616 | + | |
| 617 | + /* | |
| 618 | + * Enable interrupts before starting the host (xhci 4.2 and 5.5.2). | |
| 619 | + * Protect the short window before host is running with a lock | |
| 620 | + */ | |
| 621 | + spin_lock_irqsave(&xhci->lock, flags); | |
| 622 | + | |
| 623 | + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Enable interrupts"); | |
| 624 | + temp = readl(&xhci->op_regs->command); | |
| 625 | + temp |= (CMD_EIE); | |
| 626 | + writel(temp, &xhci->op_regs->command); | |
| 627 | + | |
| 628 | + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Enable primary interrupter"); | |
| 629 | + temp = readl(&xhci->ir_set->irq_pending); | |
| 630 | + writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending); | |
| 631 | + | |
| 614 | 632 | if (xhci_start(xhci)) { |
| 615 | 633 | xhci_halt(xhci); |
| 634 | + spin_unlock_irqrestore(&xhci->lock, flags); | |
| 616 | 635 | return -ENODEV; |
| 617 | 636 | } |
| 637 | + | |
| 618 | 638 | xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; |
| 619 | 639 | |
| 620 | 640 | if (xhci->quirks & XHCI_NEC_HOST) |
| 621 | 641 | xhci_ring_cmd_db(xhci); |
| 622 | 642 | |
| 643 | + spin_unlock_irqrestore(&xhci->lock, flags); | |
| 644 | + | |
| 623 | 645 | return 0; |
| 624 | 646 | } |
| 625 | 647 | |
| @@ -668,19 +690,6 @@ int xhci_run(struct usb_hcd *hcd) · 42 unmodified lines | ||
| 668 | 690 | temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK; |
| 669 | 691 | writel(temp, &xhci->ir_set->irq_control); |
| 670 | 692 | |
| 671 | − /* Set the HCD state before we enable the irqs */ | |
| 672 | − temp = readl(&xhci->op_regs->command); | |
| 673 | − temp |= (CMD_EIE); | |
| 674 | − xhci_dbg_trace(xhci, trace_xhci_dbg_init, | |
| 675 | − "// Enable interrupts, cmd = 0x%x.", temp); | |
| 676 | − writel(temp, &xhci->op_regs->command); | |
| 677 | − | |
| 678 | − temp = readl(&xhci->ir_set->irq_pending); | |
| 679 | − xhci_dbg_trace(xhci, trace_xhci_dbg_init, | |
| 680 | − "// Enabling event ring interrupter %p by writing 0x%x to irq_pending", | |
| 681 | − xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); | |
| 682 | − writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending); | |
| 683 | − | |
| 684 | 693 | if (xhci->quirks & XHCI_NEC_HOST) { |
| 685 | 694 | struct xhci_command *command; |
| 686 | 695 | |
| @@ -782,6 +791,8 @@ static void xhci_stop(struct usb_hcd *hcd) · 95 unmodified lines | ||
| 782 | 791 | void xhci_shutdown(struct usb_hcd *hcd) |
| 783 | 792 | { |
| 784 | 793 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 794 | + unsigned long flags; | |
| 795 | + int i; | |
| 785 | 796 | |
| 786 | 797 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) |
| 787 | 798 | usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); |
| @@ -797,12 +808,21 @@ void xhci_shutdown(struct usb_hcd *hcd) · 9 unmodified lines | ||
| 797 | 808 | del_timer_sync(&xhci->shared_hcd->rh_timer); |
| 798 | 809 | } |
| 799 | 810 | |
| 800 | − spin_lock_irq(&xhci->lock); | |
| 811 | + spin_lock_irqsave(&xhci->lock, flags); | |
| 801 | 812 | xhci_halt(xhci); |
| 813 | + | |
| 814 | + /* Power off USB2 ports*/ | |
| 815 | + for (i = 0; i < xhci->usb2_rhub.num_ports; i++) | |
| 816 | + xhci_set_port_power(xhci, xhci->main_hcd, i, false, &flags); | |
| 817 | + | |
| 818 | + /* Power off USB3 ports*/ | |
| 819 | + for (i = 0; i < xhci->usb3_rhub.num_ports; i++) | |
| 820 | + xhci_set_port_power(xhci, xhci->shared_hcd, i, false, &flags); | |
| 821 | + | |
| 802 | 822 | /* Workaround for spurious wakeups at shutdown with HSW */ |
| 803 | 823 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) |
| 804 | 824 | xhci_reset(xhci, XHCI_RESET_SHORT_USEC); |
| 805 | − spin_unlock_irq(&xhci->lock); | |
| 825 | + spin_unlock_irqrestore(&xhci->lock, flags); | |
| 806 | 826 | |
| 807 | 827 | xhci_cleanup_msix(xhci); |
| 808 | 828 | |
| @@ -1107,7 +1127,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) · 298 unmodified lines | ||
| 1107 | 1127 | { |
| 1108 | 1128 | u32 command, temp = 0; |
| 1109 | 1129 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
| 1110 | − struct usb_hcd *secondary_hcd; | |
| 1111 | 1130 | int retval = 0; |
| 1112 | 1131 | bool comp_timer_running = false; |
| 1113 | 1132 | bool pending_portevent = false; |
| @@ -1214,23 +1233,19 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) · 100 unmodified lines | ||
| 1214 | 1233 | * first with the primary HCD, and then with the secondary HCD. |
| 1215 | 1234 | * If we don't do the same, the host will never be started. |
| 1216 | 1235 | */ |
| 1217 | − if (!usb_hcd_is_primary_hcd(hcd)) | |
| 1218 | − secondary_hcd = hcd; | |
| 1219 | − else | |
| 1220 | − secondary_hcd = xhci->shared_hcd; | |
| 1221 | − | |
| 1222 | 1236 | xhci_dbg(xhci, "Initialize the xhci_hcd\n"); |
| 1223 | − retval = xhci_init(hcd->primary_hcd); | |
| 1237 | + retval = xhci_init(hcd); | |
| 1224 | 1238 | if (retval) |
| 1225 | 1239 | return retval; |
| 1226 | 1240 | comp_timer_running = true; |
| 1227 | 1241 | |
| 1228 | 1242 | xhci_dbg(xhci, "Start the primary HCD\n"); |
| 1229 | − retval = xhci_run(hcd->primary_hcd); | |
| 1230 | − if (!retval && secondary_hcd) { | |
| 1243 | + retval = xhci_run(hcd); | |
| 1244 | + if (!retval && xhci->shared_hcd) { | |
| 1231 | 1245 | xhci_dbg(xhci, "Start the secondary HCD\n"); |
| 1232 | − retval = xhci_run(secondary_hcd); | |
| 1246 | + retval = xhci_run(xhci->shared_hcd); | |
| 1233 | 1247 | } |
| 1248 | + | |
| 1234 | 1249 | hcd->state = HC_STATE_SUSPENDED; |
| 1235 | 1250 | if (xhci->shared_hcd) |
| 1236 | 1251 | xhci->shared_hcd->state = HC_STATE_SUSPENDED; |
| @@ -2196,6 +2196,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, · 2195 unmodified lines | ||
| 2196 | 2196 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); |
| 2197 | 2197 | int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); |
| 2198 | 2198 | struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); |
| 2199 | +void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index, | |
| 2200 | + bool on, unsigned long *flags); | |
| 2199 | 2201 | |
| 2200 | 2202 | void xhci_hc_died(struct xhci_hcd *xhci); |
| 2201 | 2203 | |
| @@ -166,6 +166,7 @@ static const struct usb_device_id edgeport_2port_id_table[] = { · 165 unmodified lines | ||
| 166 | 166 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, |
| 167 | 167 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, |
| 168 | 168 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, |
| 169 | + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) }, | |
| 169 | 170 | { } |
| 170 | 171 | }; |
| 171 | 172 | |
| @@ -204,6 +205,7 @@ static const struct usb_device_id id_table_combined[] = { · 32 unmodified lines | ||
| 204 | 205 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, |
| 205 | 206 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, |
| 206 | 207 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, |
| 208 | + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) }, | |
| 207 | 209 | { } |
| 208 | 210 | }; |
| 209 | 211 | |
| @@ -212,6 +212,7 @@ · 211 unmodified lines | ||
| 212 | 212 | // |
| 213 | 213 | // Definitions for other product IDs |
| 214 | 214 | #define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device |
| 215 | +#define ION_DEVICE_ID_E5805A 0x1A01 // OEM device (rebranded Edgeport/4) | |
| 215 | 216 | |
| 216 | 217 | |
| 217 | 218 | #define GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId) \ |
| @@ -252,10 +252,12 @@ static void option_instat_callback(struct urb *urb); · 251 unmodified lines | ||
| 252 | 252 | #define QUECTEL_PRODUCT_EG95 0x0195 |
| 253 | 253 | #define QUECTEL_PRODUCT_BG96 0x0296 |
| 254 | 254 | #define QUECTEL_PRODUCT_EP06 0x0306 |
| 255 | +#define QUECTEL_PRODUCT_EM05G 0x030a | |
| 255 | 256 | #define QUECTEL_PRODUCT_EM12 0x0512 |
| 256 | 257 | #define QUECTEL_PRODUCT_RM500Q 0x0800 |
| 257 | 258 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 |
| 258 | 259 | #define QUECTEL_PRODUCT_EC200T 0x6026 |
| 260 | +#define QUECTEL_PRODUCT_RM500K 0x7001 | |
| 259 | 261 | |
| 260 | 262 | #define CMOTECH_VENDOR_ID 0x16d8 |
| 261 | 263 | #define CMOTECH_PRODUCT_6001 0x6001 |
| @@ -432,6 +434,8 @@ static void option_instat_callback(struct urb *urb); · 170 unmodified lines | ||
| 432 | 434 | #define CINTERION_PRODUCT_CLS8 0x00b0 |
| 433 | 435 | #define CINTERION_PRODUCT_MV31_MBIM 0x00b3 |
| 434 | 436 | #define CINTERION_PRODUCT_MV31_RMNET 0x00b7 |
| 437 | +#define CINTERION_PRODUCT_MV31_2_MBIM 0x00b8 | |
| 438 | +#define CINTERION_PRODUCT_MV31_2_RMNET 0x00b9 | |
| 435 | 439 | #define CINTERION_PRODUCT_MV32_WA 0x00f1 |
| 436 | 440 | #define CINTERION_PRODUCT_MV32_WB 0x00f2 |
| 437 | 441 | |
| @@ -1132,6 +1136,8 @@ static const struct usb_device_id option_ids[] = { · 694 unmodified lines | ||
| 1132 | 1136 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), |
| 1133 | 1137 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1134 | 1138 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, |
| 1139 | + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), | |
| 1140 | + .driver_info = RSVD(6) | ZLP }, | |
| 1135 | 1141 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1136 | 1142 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1137 | 1143 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, |
| @@ -1145,6 +1151,7 @@ static const struct usb_device_id option_ids[] = { · 7 unmodified lines | ||
| 1145 | 1151 | .driver_info = ZLP }, |
| 1146 | 1152 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, |
| 1147 | 1153 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, |
| 1154 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, | |
| 1148 | 1155 | |
| 1149 | 1156 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
| 1150 | 1157 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, |
| @@ -1277,6 +1284,7 @@ static const struct usb_device_id option_ids[] = { · 126 unmodified lines | ||
| 1277 | 1284 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1278 | 1285 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */ |
| 1279 | 1286 | .driver_info = NCTRL(2) | RSVD(3) }, |
| 1287 | + { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) }, /* Telit LE910Cx (rmnet) */ | |
| 1280 | 1288 | { USB_DEVICE(TELIT_VENDOR_ID, 0x1260), |
| 1281 | 1289 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1282 | 1290 | { USB_DEVICE(TELIT_VENDOR_ID, 0x1261), |
| @@ -1979,6 +1987,10 @@ static const struct usb_device_id option_ids[] = { · 696 unmodified lines | ||
| 1979 | 1987 | .driver_info = RSVD(3)}, |
| 1980 | 1988 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), |
| 1981 | 1989 | .driver_info = RSVD(0)}, |
| 1990 | + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_MBIM, 0xff), | |
| 1991 | + .driver_info = RSVD(3)}, | |
| 1992 | + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_RMNET, 0xff), | |
| 1993 | + .driver_info = RSVD(0)}, | |
| 1982 | 1994 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), |
| 1983 | 1995 | .driver_info = RSVD(3)}, |
| 1984 | 1996 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), |
| @@ -436,22 +436,27 @@ static int pl2303_detect_type(struct usb_serial *serial) · 435 unmodified lines | ||
| 436 | 436 | break; |
| 437 | 437 | case 0x200: |
| 438 | 438 | switch (bcdDevice) { |
| 439 | − case 0x100: | |
| 439 | + case 0x100: /* GC */ | |
| 440 | 440 | case 0x105: |
| 441 | + return TYPE_HXN; | |
| 442 | + case 0x300: /* GT / TA */ | |
| 443 | + if (pl2303_supports_hx_status(serial)) | |
| 444 | + return TYPE_TA; | |
| 445 | + fallthrough; | |
| 441 | 446 | case 0x305: |
| 447 | + case 0x400: /* GL */ | |
| 442 | 448 | case 0x405: |
| 449 | + return TYPE_HXN; | |
| 450 | + case 0x500: /* GE / TB */ | |
| 451 | + if (pl2303_supports_hx_status(serial)) | |
| 452 | + return TYPE_TB; | |
| 453 | + fallthrough; | |
| 454 | + case 0x505: | |
| 455 | + case 0x600: /* GS */ | |
| 443 | 456 | case 0x605: |
| 444 | − /* | |
| 445 | − * Assume it's an HXN-type if the device doesn't | |
| 446 | − * support the old read request value. | |
| 447 | − */ | |
| 448 | − if (!pl2303_supports_hx_status(serial)) | |
| 449 | − return TYPE_HXN; | |
| 450 | − break; | |
| 451 | − case 0x300: | |
| 452 | − return TYPE_TA; | |
| 453 | − case 0x500: | |
| 454 | − return TYPE_TB; | |
| 457 | + case 0x700: /* GR */ | |
| 458 | + case 0x705: | |
| 459 | + return TYPE_HXN; | |
| 455 | 460 | } |
| 456 | 461 | break; |
| 457 | 462 | } |
| @@ -56,7 +56,6 @@ config TYPEC_WCOVE · 55 unmodified lines | ||
| 56 | 56 | tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver" |
| 57 | 57 | depends on ACPI |
| 58 | 58 | depends on MFD_INTEL_PMC_BXT |
| 59 | − depends on INTEL_SOC_PMIC | |
| 60 | 59 | depends on BXT_WC_PMIC_OPREGION |
| 61 | 60 | help |
| 62 | 61 | This driver adds support for USB Type-C on Intel Broxton platforms |
| @@ -1148,6 +1148,7 @@ int sti_call(const struct sti_struct *sti, unsigned long func, · 1147 unmodified lines | ||
| 1148 | 1148 | return ret; |
| 1149 | 1149 | } |
| 1150 | 1150 | |
| 1151 | +#if defined(CONFIG_FB_STI) | |
| 1151 | 1152 | /* check if given fb_info is the primary device */ |
| 1152 | 1153 | int fb_is_primary_device(struct fb_info *info) |
| 1153 | 1154 | { |
| @@ -1163,6 +1164,7 @@ int fb_is_primary_device(struct fb_info *info) · 9 unmodified lines | ||
| 1163 | 1164 | return (sti->info == info); |
| 1164 | 1165 | } |
| 1165 | 1166 | EXPORT_SYMBOL(fb_is_primary_device); |
| 1167 | +#endif | |
| 1166 | 1168 | |
| 1167 | 1169 | MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); |
| 1168 | 1170 | MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); |
| @@ -560,8 +560,7 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) · 559 unmodified lines | ||
| 560 | 560 | /* Blank the LCD */ |
| 561 | 561 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); |
| 562 | 562 | |
| 563 | − if (fbdev->lcdclk) | |
| 564 | − clk_disable(fbdev->lcdclk); | |
| 563 | + clk_disable(fbdev->lcdclk); | |
| 565 | 564 | |
| 566 | 565 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); |
| 567 | 566 | |
| @@ -577,8 +576,7 @@ int au1100fb_drv_resume(struct platform_device *dev) · 9 unmodified lines | ||
| 577 | 576 | |
| 578 | 577 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); |
| 579 | 578 | |
| 580 | − if (fbdev->lcdclk) | |
| 581 | − clk_enable(fbdev->lcdclk); | |
| 579 | + clk_enable(fbdev->lcdclk); | |
| 582 | 580 | |
| 583 | 581 | /* Unblank the LCD */ |
| 584 | 582 | au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); |
| @@ -2184,12 +2184,6 @@ static struct pci_driver cirrusfb_pci_driver = { · 2183 unmodified lines | ||
| 2184 | 2184 | .id_table = cirrusfb_pci_table, |
| 2185 | 2185 | .probe = cirrusfb_pci_register, |
| 2186 | 2186 | .remove = cirrusfb_pci_unregister, |
| 2187 | −#ifdef CONFIG_PM | |
| 2188 | −#if 0 | |
| 2189 | − .suspend = cirrusfb_pci_suspend, | |
| 2190 | − .resume = cirrusfb_pci_resume, | |
| 2191 | −#endif | |
| 2192 | −#endif | |
| 2193 | 2187 | }; |
| 2194 | 2188 | #endif /* CONFIG_PCI */ |
| 2195 | 2189 | |
| @@ -472,7 +472,7 @@ static int intelfb_pci_register(struct pci_dev *pdev, · 471 unmodified lines | ||
| 472 | 472 | struct fb_info *info; |
| 473 | 473 | struct intelfb_info *dinfo; |
| 474 | 474 | int i, err, dvo; |
| 475 | − int aperture_size, stolen_size; | |
| 475 | + int aperture_size, stolen_size = 0; | |
| 476 | 476 | struct agp_kern_info gtt_info; |
| 477 | 477 | int agp_memtype; |
| 478 | 478 | const char *s; |
| @@ -571,7 +571,7 @@ static int intelfb_pci_register(struct pci_dev *pdev, · 92 unmodified lines | ||
| 571 | 571 | return -ENODEV; |
| 572 | 572 | } |
| 573 | 573 | |
| 574 | − if (intelfbhw_get_memory(pdev, &aperture_size,&stolen_size)) { | |
| 574 | + if (intelfbhw_get_memory(pdev, &aperture_size, &stolen_size)) { | |
| 575 | 575 | cleanup(dinfo); |
| 576 | 576 | return -ENODEV; |
| 577 | 577 | } |
| @@ -201,13 +201,11 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, · 200 unmodified lines | ||
| 201 | 201 | case PCI_DEVICE_ID_INTEL_945GME: |
| 202 | 202 | case PCI_DEVICE_ID_INTEL_965G: |
| 203 | 203 | case PCI_DEVICE_ID_INTEL_965GM: |
| 204 | − /* 915, 945 and 965 chipsets support a 256MB aperture. | |
| 205 | − Aperture size is determined by inspected the | |
| 206 | − base address of the aperture. */ | |
| 207 | − if (pci_resource_start(pdev, 2) & 0x08000000) | |
| 208 | − *aperture_size = MB(128); | |
| 209 | − else | |
| 210 | − *aperture_size = MB(256); | |
| 204 | + /* | |
| 205 | + * 915, 945 and 965 chipsets support 64MB, 128MB or 256MB | |
| 206 | + * aperture. Determine size from PCI resource length. | |
| 207 | + */ | |
| 208 | + *aperture_size = pci_resource_len(pdev, 2); | |
| 211 | 209 | break; |
| 212 | 210 | default: |
| 213 | 211 | if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) |
| @@ -359,7 +359,7 @@ static void sossi_set_bits_per_cycle(int bpc) · 358 unmodified lines | ||
| 359 | 359 | int bus_pick_count, bus_pick_width; |
| 360 | 360 | |
| 361 | 361 | /* |
| 362 | − * We set explicitly the the bus_pick_count as well, although | |
| 362 | + * We set explicitly the bus_pick_count as well, although | |
| 363 | 363 | * with remapping/reordering disabled it will be calculated by HW |
| 364 | 364 | * as (32 / bus_pick_width). |
| 365 | 365 | */ |
| @@ -143,7 +143,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk, · 142 unmodified lines | ||
| 143 | 143 | /* |
| 144 | 144 | * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the |
| 145 | 145 | * HDMI_PHYPWRCMD_LDOON command. |
| 146 | − */ | |
| 146 | + */ | |
| 147 | 147 | if (phy_feat->bist_ctrl) |
| 148 | 148 | REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); |
| 149 | 149 | |
| @@ -381,7 +381,7 @@ pxa3xx_gcu_write(struct file *file, const char *buff, · 380 unmodified lines | ||
| 381 | 381 | struct pxa3xx_gcu_batch *buffer; |
| 382 | 382 | struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file); |
| 383 | 383 | |
| 384 | − int words = count / 4; | |
| 384 | + size_t words = count / 4; | |
| 385 | 385 | |
| 386 | 386 | /* Does not need to be atomic. There's a lock in user space, |
| 387 | 387 | * but anyhow, this is just for statistics. */ |
| @@ -237,8 +237,7 @@ static int simplefb_clocks_get(struct simplefb_par *par, · 236 unmodified lines | ||
| 237 | 237 | if (IS_ERR(clock)) { |
| 238 | 238 | if (PTR_ERR(clock) == -EPROBE_DEFER) { |
| 239 | 239 | while (--i >= 0) { |
| 240 | − if (par->clks[i]) | |
| 241 | − clk_put(par->clks[i]); | |
| 240 | + clk_put(par->clks[i]); | |
| 242 | 241 | } |
| 243 | 242 | kfree(par->clks); |
| 244 | 243 | return -EPROBE_DEFER; |
| @@ -96,7 +96,7 @@ static const struct fb_fix_screeninfo xxxfb_fix = { · 95 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | /* |
| 98 | 98 | * Modern graphical hardware not only supports pipelines but some |
| 99 | − * also support multiple monitors where each display can have its | |
| 99 | + * also support multiple monitors where each display can have | |
| 100 | 100 | * its own unique data. In this case each display could be |
| 101 | 101 | * represented by a separate framebuffer device thus a separate |
| 102 | 102 | * struct fb_info. Now the struct xxx_par represents the graphics |
| @@ -838,9 +838,9 @@ static void xxxfb_remove(struct pci_dev *dev) · 735 unmodified lines | ||
| 838 | 838 | * |
| 839 | 839 | * See Documentation/driver-api/pm/devices.rst for more information |
| 840 | 840 | */ |
| 841 | −static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg) | |
| 841 | +static int xxxfb_suspend(struct device *dev) | |
| 842 | 842 | { |
| 843 | − struct fb_info *info = pci_get_drvdata(dev); | |
| 843 | + struct fb_info *info = dev_get_drvdata(dev); | |
| 844 | 844 | struct xxxfb_par *par = info->par; |
| 845 | 845 | |
| 846 | 846 | /* suspend here */ |
| @@ -853,9 +853,9 @@ static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg) · 6 unmodified lines | ||
| 853 | 853 | * |
| 854 | 854 | * See Documentation/driver-api/pm/devices.rst for more information |
| 855 | 855 | */ |
| 856 | −static int xxxfb_resume(struct pci_dev *dev) | |
| 856 | +static int xxxfb_resume(struct device *dev) | |
| 857 | 857 | { |
| 858 | − struct fb_info *info = pci_get_drvdata(dev); | |
| 858 | + struct fb_info *info = dev_get_drvdata(dev); | |
| 859 | 859 | struct xxxfb_par *par = info->par; |
| 860 | 860 | |
| 861 | 861 | /* resume here */ |
| @@ -873,14 +873,15 @@ static const struct pci_device_id xxxfb_id_table[] = { · 11 unmodified lines | ||
| 873 | 873 | { 0, } |
| 874 | 874 | }; |
| 875 | 875 | |
| 876 | +static SIMPLE_DEV_PM_OPS(xxxfb_pm_ops, xxxfb_suspend, xxxfb_resume); | |
| 877 | + | |
| 876 | 878 | /* For PCI drivers */ |
| 877 | 879 | static struct pci_driver xxxfb_driver = { |
| 878 | 880 | .name = "xxxfb", |
| 879 | 881 | .id_table = xxxfb_id_table, |
| 880 | 882 | .probe = xxxfb_probe, |
| 881 | 883 | .remove = xxxfb_remove, |
| 882 | − .suspend = xxxfb_suspend, /* optional but recommended */ | |
| 883 | − .resume = xxxfb_resume, /* optional but recommended */ | |
| 884 | + .driver.pm = xxxfb_pm_ops, /* optional but recommended */ | |
| 884 | 885 | }; |
| 885 | 886 | |
| 886 | 887 | MODULE_DEVICE_TABLE(pci, xxxfb_id_table); |
| @@ -172,3 +172,4 @@ module_platform_driver(gxp_wdt_driver); · 171 unmodified lines | ||
| 172 | 172 | MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>"); |
| 173 | 173 | MODULE_AUTHOR("Jean-Marie Verdun <verdun@hpe.com>"); |
| 174 | 174 | MODULE_DESCRIPTION("Driver for GXP watchdog timer"); |
| 175 | +MODULE_LICENSE("GPL"); | |
| @@ -42,7 +42,7 @@ void xen_setup_features(void) · 41 unmodified lines | ||
| 42 | 42 | if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) |
| 43 | 43 | break; |
| 44 | 44 | for (j = 0; j < 32; j++) |
| 45 | − xen_features[i * 32 + j] = !!(fi.submap & 1<<j); | |
| 45 | + xen_features[i * 32 + j] = !!(fi.submap & 1U << j); | |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | 48 | if (xen_pv_domain()) { |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/mmu_notifier.h> |
| 17 | 17 | #include <linux/types.h> |
| 18 | 18 | #include <xen/interface/event_channel.h> |
| 19 | +#include <xen/grant_table.h> | |
| 19 | 20 | |
| 20 | 21 | struct gntdev_dmabuf_priv; |
| 21 | 22 | |
| @@ -56,6 +57,7 @@ struct gntdev_grant_map { · 34 unmodified lines | ||
| 56 | 57 | struct gnttab_unmap_grant_ref *unmap_ops; |
| 57 | 58 | struct gnttab_map_grant_ref *kmap_ops; |
| 58 | 59 | struct gnttab_unmap_grant_ref *kunmap_ops; |
| 60 | + bool *being_removed; | |
| 59 | 61 | struct page **pages; |
| 60 | 62 | unsigned long pages_vm_start; |
| 61 | 63 | |
| @@ -73,6 +75,11 @@ struct gntdev_grant_map { · 11 unmodified lines | ||
| 73 | 75 | /* Needed to avoid allocation in gnttab_dma_free_pages(). */ |
| 74 | 76 | xen_pfn_t *frames; |
| 75 | 77 | #endif |
| 78 | + | |
| 79 | + /* Number of live grants */ | |
| 80 | + atomic_t live_grants; | |
| 81 | + /* Needed to avoid allocation in __unmap_grant_pages */ | |
| 82 | + struct gntab_unmap_queue_data unmap_data; | |
| 76 | 83 | }; |
| 77 | 84 | |
| 78 | 85 | struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <linux/slab.h> |
| 36 | 36 | #include <linux/highmem.h> |
| 37 | 37 | #include <linux/refcount.h> |
| 38 | +#include <linux/workqueue.h> | |
| 38 | 39 | |
| 39 | 40 | #include <xen/xen.h> |
| 40 | 41 | #include <xen/grant_table.h> |
| @@ -60,10 +61,11 @@ module_param(limit, uint, 0644); · 19 unmodified lines | ||
| 60 | 61 | MODULE_PARM_DESC(limit, |
| 61 | 62 | "Maximum number of grants that may be mapped by one mapping request"); |
| 62 | 63 | |
| 64 | +/* True in PV mode, false otherwise */ | |
| 63 | 65 | static int use_ptemod; |
| 64 | 66 | |
| 65 | −static int unmap_grant_pages(struct gntdev_grant_map *map, | |
| 66 | − int offset, int pages); | |
| 67 | +static void unmap_grant_pages(struct gntdev_grant_map *map, | |
| 68 | + int offset, int pages); | |
| 67 | 69 | |
| 68 | 70 | static struct miscdevice gntdev_miscdev; |
| 69 | 71 | |
| @@ -120,6 +122,7 @@ static void gntdev_free_map(struct gntdev_grant_map *map) · 50 unmodified lines | ||
| 120 | 122 | kvfree(map->unmap_ops); |
| 121 | 123 | kvfree(map->kmap_ops); |
| 122 | 124 | kvfree(map->kunmap_ops); |
| 125 | + kvfree(map->being_removed); | |
| 123 | 126 | kfree(map); |
| 124 | 127 | } |
| 125 | 128 | |
| @@ -140,10 +143,13 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, · 14 unmodified lines | ||
| 140 | 143 | add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]), |
| 141 | 144 | GFP_KERNEL); |
| 142 | 145 | add->pages = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); |
| 146 | + add->being_removed = | |
| 147 | + kvcalloc(count, sizeof(add->being_removed[0]), GFP_KERNEL); | |
| 143 | 148 | if (NULL == add->grants || |
| 144 | 149 | NULL == add->map_ops || |
| 145 | 150 | NULL == add->unmap_ops || |
| 146 | − NULL == add->pages) | |
| 151 | + NULL == add->pages || | |
| 152 | + NULL == add->being_removed) | |
| 147 | 153 | goto err; |
| 148 | 154 | if (use_ptemod) { |
| 149 | 155 | add->kmap_ops = kvmalloc_array(count, sizeof(add->kmap_ops[0]), |
| @@ -250,9 +256,36 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map) · 100 unmodified lines | ||
| 250 | 256 | if (!refcount_dec_and_test(&map->users)) |
| 251 | 257 | return; |
| 252 | 258 | |
| 253 | − if (map->pages && !use_ptemod) | |
| 259 | + if (map->pages && !use_ptemod) { | |
| 260 | + /* | |
| 261 | + * Increment the reference count. This ensures that the | |
| 262 | + * subsequent call to unmap_grant_pages() will not wind up | |
| 263 | + * re-entering itself. It *can* wind up calling | |
| 264 | + * gntdev_put_map() recursively, but such calls will be with a | |
| 265 | + * reference count greater than 1, so they will return before | |
| 266 | + * this code is reached. The recursion depth is thus limited to | |
| 267 | + * 1. Do NOT use refcount_inc() here, as it will detect that | |
| 268 | + * the reference count is zero and WARN(). | |
| 269 | + */ | |
| 270 | + refcount_set(&map->users, 1); | |
| 271 | + | |
| 272 | + /* | |
| 273 | + * Unmap the grants. This may or may not be asynchronous, so it | |
| 274 | + * is possible that the reference count is 1 on return, but it | |
| 275 | + * could also be greater than 1. | |
| 276 | + */ | |
| 254 | 277 | unmap_grant_pages(map, 0, map->count); |
| 255 | 278 | |
| 279 | + /* Check if the memory now needs to be freed */ | |
| 280 | + if (!refcount_dec_and_test(&map->users)) | |
| 281 | + return; | |
| 282 | + | |
| 283 | + /* | |
| 284 | + * All pages have been returned to the hypervisor, so free the | |
| 285 | + * map. | |
| 286 | + */ | |
| 287 | + } | |
| 288 | + | |
| 256 | 289 | if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { |
| 257 | 290 | notify_remote_via_evtchn(map->notify.event); |
| 258 | 291 | evtchn_put(map->notify.event); |
| @@ -283,6 +316,7 @@ static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data) · 24 unmodified lines | ||
| 283 | 316 | |
| 284 | 317 | int gntdev_map_grant_pages(struct gntdev_grant_map *map) |
| 285 | 318 | { |
| 319 | + size_t alloced = 0; | |
| 286 | 320 | int i, err = 0; |
| 287 | 321 | |
| 288 | 322 | if (!use_ptemod) { |
| @@ -331,97 +365,116 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) · 42 unmodified lines | ||
| 331 | 365 | map->count); |
| 332 | 366 | |
| 333 | 367 | for (i = 0; i < map->count; i++) { |
| 334 | − if (map->map_ops[i].status == GNTST_okay) | |
| 368 | + if (map->map_ops[i].status == GNTST_okay) { | |
| 335 | 369 | map->unmap_ops[i].handle = map->map_ops[i].handle; |
| 336 | − else if (!err) | |
| 370 | + if (!use_ptemod) | |
| 371 | + alloced++; | |
| 372 | + } else if (!err) | |
| 337 | 373 | err = -EINVAL; |
| 338 | 374 | |
| 339 | 375 | if (map->flags & GNTMAP_device_map) |
| 340 | 376 | map->unmap_ops[i].dev_bus_addr = map->map_ops[i].dev_bus_addr; |
| 341 | 377 | |
| 342 | 378 | if (use_ptemod) { |
| 343 | − if (map->kmap_ops[i].status == GNTST_okay) | |
| 379 | + if (map->kmap_ops[i].status == GNTST_okay) { | |
| 380 | + if (map->map_ops[i].status == GNTST_okay) | |
| 381 | + alloced++; | |
| 344 | 382 | map->kunmap_ops[i].handle = map->kmap_ops[i].handle; |
| 345 | − else if (!err) | |
| 383 | + } else if (!err) | |
| 346 | 384 | err = -EINVAL; |
| 347 | 385 | } |
| 348 | 386 | } |
| 387 | + atomic_add(alloced, &map->live_grants); | |
| 349 | 388 | return err; |
| 350 | 389 | } |
| 351 | 390 | |
| 352 | −static int __unmap_grant_pages(struct gntdev_grant_map *map, int offset, | |
| 353 | − int pages) | |
| 391 | +static void __unmap_grant_pages_done(int result, | |
| 392 | + struct gntab_unmap_queue_data *data) | |
| 354 | 393 | { |
| 355 | − int i, err = 0; | |
| 356 | − struct gntab_unmap_queue_data unmap_data; | |
| 357 | − | |
| 358 | − if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { | |
| 359 | − int pgno = (map->notify.addr >> PAGE_SHIFT); | |
| 360 | − if (pgno >= offset && pgno < offset + pages) { | |
| 361 | − /* No need for kmap, pages are in lowmem */ | |
| 362 | − uint8_t *tmp = pfn_to_kaddr(page_to_pfn(map->pages[pgno])); | |
| 363 | − tmp[map->notify.addr & (PAGE_SIZE-1)] = 0; | |
| 364 | − map->notify.flags &= ~UNMAP_NOTIFY_CLEAR_BYTE; | |
| 365 | − } | |
| 366 | − } | |
| 367 | − | |
| 368 | − unmap_data.unmap_ops = map->unmap_ops + offset; | |
| 369 | − unmap_data.kunmap_ops = use_ptemod ? map->kunmap_ops + offset : NULL; | |
| 370 | − unmap_data.pages = map->pages + offset; | |
| 371 | − unmap_data.count = pages; | |
| 372 | − | |
| 373 | − err = gnttab_unmap_refs_sync(&unmap_data); | |
| 374 | − if (err) | |
| 375 | − return err; | |
| 394 | + unsigned int i; | |
| 395 | + struct gntdev_grant_map *map = data->data; | |
| 396 | + unsigned int offset = data->unmap_ops - map->unmap_ops; | |
| 376 | 397 | |
| 377 | − for (i = 0; i < pages; i++) { | |
| 378 | − if (map->unmap_ops[offset+i].status) | |
| 379 | − err = -EINVAL; | |
| 398 | + for (i = 0; i < data->count; i++) { | |
| 399 | + WARN_ON(map->unmap_ops[offset+i].status); | |
| 380 | 400 | pr_debug("unmap handle=%d st=%d\n", |
| 381 | 401 | map->unmap_ops[offset+i].handle, |
| 382 | 402 | map->unmap_ops[offset+i].status); |
| 383 | 403 | map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; |
| 384 | 404 | if (use_ptemod) { |
| 385 | − if (map->kunmap_ops[offset+i].status) | |
| 386 | − err = -EINVAL; | |
| 405 | + WARN_ON(map->kunmap_ops[offset+i].status); | |
| 387 | 406 | pr_debug("kunmap handle=%u st=%d\n", |
| 388 | 407 | map->kunmap_ops[offset+i].handle, |
| 389 | 408 | map->kunmap_ops[offset+i].status); |
| 390 | 409 | map->kunmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; |
| 391 | 410 | } |
| 392 | 411 | } |
| 393 | − return err; | |
| 412 | + /* | |
| 413 | + * Decrease the live-grant counter. This must happen after the loop to | |
| 414 | + * prevent premature reuse of the grants by gnttab_mmap(). | |
| 415 | + */ | |
| 416 | + atomic_sub(data->count, &map->live_grants); | |
| 417 | + | |
| 418 | + /* Release reference taken by __unmap_grant_pages */ | |
| 419 | + gntdev_put_map(NULL, map); | |
| 420 | +} | |
| 421 | + | |
| 422 | +static void __unmap_grant_pages(struct gntdev_grant_map *map, int offset, | |
| 423 | + int pages) | |
| 424 | +{ | |
| 425 | + if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { | |
| 426 | + int pgno = (map->notify.addr >> PAGE_SHIFT); | |
| 427 | + | |
| 428 | + if (pgno >= offset && pgno < offset + pages) { | |
| 429 | + /* No need for kmap, pages are in lowmem */ | |
| 430 | + uint8_t *tmp = pfn_to_kaddr(page_to_pfn(map->pages[pgno])); | |
| 431 | + | |
| 432 | + tmp[map->notify.addr & (PAGE_SIZE-1)] = 0; | |
| 433 | + map->notify.flags &= ~UNMAP_NOTIFY_CLEAR_BYTE; | |
| 434 | + } | |
| 435 | + } | |
| 436 | + | |
| 437 | + map->unmap_data.unmap_ops = map->unmap_ops + offset; | |
| 438 | + map->unmap_data.kunmap_ops = use_ptemod ? map->kunmap_ops + offset : NULL; | |
| 439 | + map->unmap_data.pages = map->pages + offset; | |
| 440 | + map->unmap_data.count = pages; | |
| 441 | + map->unmap_data.done = __unmap_grant_pages_done; | |
| 442 | + map->unmap_data.data = map; | |
| 443 | + refcount_inc(&map->users); /* to keep map alive during async call below */ | |
| 444 | + | |
| 445 | + gnttab_unmap_refs_async(&map->unmap_data); | |
| 394 | 446 | } |
| 395 | 447 | |
| 396 | −static int unmap_grant_pages(struct gntdev_grant_map *map, int offset, | |
| 397 | − int pages) | |
| 448 | +static void unmap_grant_pages(struct gntdev_grant_map *map, int offset, | |
| 449 | + int pages) | |
| 398 | 450 | { |
| 399 | − int range, err = 0; | |
| 451 | + int range; | |
| 452 | + | |
| 453 | + if (atomic_read(&map->live_grants) == 0) | |
| 454 | + return; /* Nothing to do */ | |
| 400 | 455 | |
| 401 | 456 | pr_debug("unmap %d+%d [%d+%d]\n", map->index, map->count, offset, pages); |
| 402 | 457 | |
| 403 | 458 | /* It is possible the requested range will have a "hole" where we |
| 404 | 459 | * already unmapped some of the grants. Only unmap valid ranges. |
| 405 | 460 | */ |
| 406 | − while (pages && !err) { | |
| 407 | − while (pages && | |
| 408 | − map->unmap_ops[offset].handle == INVALID_GRANT_HANDLE) { | |
| 461 | + while (pages) { | |
| 462 | + while (pages && map->being_removed[offset]) { | |
| 409 | 463 | offset++; |
| 410 | 464 | pages--; |
| 411 | 465 | } |
| 412 | 466 | range = 0; |
| 413 | 467 | while (range < pages) { |
| 414 | − if (map->unmap_ops[offset + range].handle == | |
| 415 | − INVALID_GRANT_HANDLE) | |
| 468 | + if (map->being_removed[offset + range]) | |
| 416 | 469 | break; |
| 470 | + map->being_removed[offset + range] = true; | |
| 417 | 471 | range++; |
| 418 | 472 | } |
| 419 | − err = __unmap_grant_pages(map, offset, range); | |
| 473 | + if (range) | |
| 474 | + __unmap_grant_pages(map, offset, range); | |
| 420 | 475 | offset += range; |
| 421 | 476 | pages -= range; |
| 422 | 477 | } |
| 423 | − | |
| 424 | − return err; | |
| 425 | 478 | } |
| 426 | 479 | |
| 427 | 480 | /* ------------------------------------------------------------------ */ |
| @@ -473,7 +526,6 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn, · 45 unmodified lines | ||
| 473 | 526 | struct gntdev_grant_map *map = |
| 474 | 527 | container_of(mn, struct gntdev_grant_map, notifier); |
| 475 | 528 | unsigned long mstart, mend; |
| 476 | − int err; | |
| 477 | 529 | |
| 478 | 530 | if (!mmu_notifier_range_blockable(range)) |
| 479 | 531 | return false; |
| @@ -494,10 +546,9 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn, · 14 unmodified lines | ||
| 494 | 546 | map->index, map->count, |
| 495 | 547 | map->vma->vm_start, map->vma->vm_end, |
| 496 | 548 | range->start, range->end, mstart, mend); |
| 497 | − err = unmap_grant_pages(map, | |
| 549 | + unmap_grant_pages(map, | |
| 498 | 550 | (mstart - map->vma->vm_start) >> PAGE_SHIFT, |
| 499 | 551 | (mend - mstart) >> PAGE_SHIFT); |
| 500 | − WARN_ON(err); | |
| 501 | 552 | |
| 502 | 553 | return true; |
| 503 | 554 | } |
| @@ -985,6 +1036,10 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) · 481 unmodified lines | ||
| 985 | 1036 | goto unlock_out; |
| 986 | 1037 | if (use_ptemod && map->vma) |
| 987 | 1038 | goto unlock_out; |
| 1039 | + if (atomic_read(&map->live_grants)) { | |
| 1040 | + err = -EAGAIN; | |
| 1041 | + goto unlock_out; | |
| 1042 | + } | |
| 988 | 1043 | refcount_inc(&map->users); |
| 989 | 1044 | |
| 990 | 1045 | vma->vm_ops = &gntdev_vmops; |
| @@ -152,7 +152,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, · 151 unmodified lines | ||
| 152 | 152 | const unsigned char **wnames, *uname; |
| 153 | 153 | int i, n, l, clone, access; |
| 154 | 154 | struct v9fs_session_info *v9ses; |
| 155 | − struct p9_fid *fid, *old_fid = NULL; | |
| 155 | + struct p9_fid *fid, *old_fid; | |
| 156 | 156 | |
| 157 | 157 | v9ses = v9fs_dentry2v9ses(dentry); |
| 158 | 158 | access = v9ses->flags & V9FS_ACCESS_MASK; |
| @@ -194,13 +194,12 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, · 35 unmodified lines | ||
| 194 | 194 | if (IS_ERR(fid)) |
| 195 | 195 | return fid; |
| 196 | 196 | |
| 197 | + refcount_inc(&fid->count); | |
| 197 | 198 | v9fs_fid_add(dentry->d_sb->s_root, fid); |
| 198 | 199 | } |
| 199 | 200 | /* If we are root ourself just return that */ |
| 200 | − if (dentry->d_sb->s_root == dentry) { | |
| 201 | − refcount_inc(&fid->count); | |
| 201 | + if (dentry->d_sb->s_root == dentry) | |
| 202 | 202 | return fid; |
| 203 | − } | |
| 204 | 203 | /* |
| 205 | 204 | * Do a multipath walk with attached root. |
| 206 | 205 | * When walking parent we need to make sure we |
| @@ -212,6 +211,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, · 5 unmodified lines | ||
| 212 | 211 | fid = ERR_PTR(n); |
| 213 | 212 | goto err_out; |
| 214 | 213 | } |
| 214 | + old_fid = fid; | |
| 215 | 215 | clone = 1; |
| 216 | 216 | i = 0; |
| 217 | 217 | while (i < n) { |
| @@ -221,19 +221,15 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, · 3 unmodified lines | ||
| 221 | 221 | * walk to ensure none of the patch component change |
| 222 | 222 | */ |
| 223 | 223 | fid = p9_client_walk(fid, l, &wnames[i], clone); |
| 224 | + /* non-cloning walk will return the same fid */ | |
| 225 | + if (fid != old_fid) { | |
| 226 | + p9_client_clunk(old_fid); | |
| 227 | + old_fid = fid; | |
| 228 | + } | |
| 224 | 229 | if (IS_ERR(fid)) { |
| 225 | − if (old_fid) { | |
| 226 | − /* | |
| 227 | − * If we fail, clunk fid which are mapping | |
| 228 | − * to path component and not the last component | |
| 229 | − * of the path. | |
| 230 | − */ | |
| 231 | − p9_client_clunk(old_fid); | |
| 232 | − } | |
| 233 | 230 | kfree(wnames); |
| 234 | 231 | goto err_out; |
| 235 | 232 | } |
| 236 | − old_fid = fid; | |
| 237 | 233 | i += l; |
| 238 | 234 | clone = 0; |
| 239 | 235 | } |
| @@ -58,8 +58,21 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq) · 57 unmodified lines | ||
| 58 | 58 | */ |
| 59 | 59 | static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) |
| 60 | 60 | { |
| 61 | + struct inode *inode = file_inode(file); | |
| 62 | + struct v9fs_inode *v9inode = V9FS_I(inode); | |
| 61 | 63 | struct p9_fid *fid = file->private_data; |
| 62 | 64 | |
| 65 | + BUG_ON(!fid); | |
| 66 | + | |
| 67 | + /* we might need to read from a fid that was opened write-only | |
| 68 | + * for read-modify-write of page cache, use the writeback fid | |
| 69 | + * for that */ | |
| 70 | + if (rreq->origin == NETFS_READ_FOR_WRITE && | |
| 71 | + (fid->mode & O_ACCMODE) == O_WRONLY) { | |
| 72 | + fid = v9inode->writeback_fid; | |
| 73 | + BUG_ON(!fid); | |
| 74 | + } | |
| 75 | + | |
| 63 | 76 | refcount_inc(&fid->count); |
| 64 | 77 | rreq->netfs_priv = fid; |
| 65 | 78 | return 0; |
| @@ -1251,15 +1251,15 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry, · 1250 unmodified lines | ||
| 1251 | 1251 | return ERR_PTR(-ECHILD); |
| 1252 | 1252 | |
| 1253 | 1253 | v9ses = v9fs_dentry2v9ses(dentry); |
| 1254 | − fid = v9fs_fid_lookup(dentry); | |
| 1254 | + if (!v9fs_proto_dotu(v9ses)) | |
| 1255 | + return ERR_PTR(-EBADF); | |
| 1256 | + | |
| 1255 | 1257 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
| 1258 | + fid = v9fs_fid_lookup(dentry); | |
| 1256 | 1259 | |
| 1257 | 1260 | if (IS_ERR(fid)) |
| 1258 | 1261 | return ERR_CAST(fid); |
| 1259 | 1262 | |
| 1260 | − if (!v9fs_proto_dotu(v9ses)) | |
| 1261 | − return ERR_PTR(-EBADF); | |
| 1262 | − | |
| 1263 | 1263 | st = p9_client_stat(fid); |
| 1264 | 1264 | p9_client_clunk(fid); |
| 1265 | 1265 | if (IS_ERR(st)) |
| @@ -274,6 +274,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, · 273 unmodified lines | ||
| 274 | 274 | if (IS_ERR(ofid)) { |
| 275 | 275 | err = PTR_ERR(ofid); |
| 276 | 276 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); |
| 277 | + p9_client_clunk(dfid); | |
| 277 | 278 | goto out; |
| 278 | 279 | } |
| 279 | 280 | |
| @@ -285,6 +286,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, · 5 unmodified lines | ||
| 285 | 286 | if (err) { |
| 286 | 287 | p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n", |
| 287 | 288 | err); |
| 289 | + p9_client_clunk(dfid); | |
| 288 | 290 | goto error; |
| 289 | 291 | } |
| 290 | 292 | err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), |
| @@ -292,6 +294,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, · 1 unmodified line | ||
| 292 | 294 | if (err < 0) { |
| 293 | 295 | p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n", |
| 294 | 296 | err); |
| 297 | + p9_client_clunk(dfid); | |
| 295 | 298 | goto error; |
| 296 | 299 | } |
| 297 | 300 | v9fs_invalidate_inode_attr(dir); |
| @@ -745,7 +745,8 @@ int afs_getattr(struct user_namespace *mnt_userns, const struct path *path, · 744 unmodified lines | ||
| 745 | 745 | |
| 746 | 746 | _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation); |
| 747 | 747 | |
| 748 | − if (!(query_flags & AT_STATX_DONT_SYNC) && | |
| 748 | + if (vnode->volume && | |
| 749 | + !(query_flags & AT_STATX_DONT_SYNC) && | |
| 749 | 750 | !test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { |
| 750 | 751 | key = afs_request_key(vnode->volume->cell); |
| 751 | 752 | if (IS_ERR(key)) |
| @@ -61,9 +61,15 @@ static bool chgrp_ok(struct user_namespace *mnt_userns, · 60 unmodified lines | ||
| 61 | 61 | const struct inode *inode, kgid_t gid) |
| 62 | 62 | { |
| 63 | 63 | kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); |
| 64 | − if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) && | |
| 65 | − (in_group_p(gid) || gid_eq(gid, inode->i_gid))) | |
| 66 | − return true; | |
| 64 | + if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode))) { | |
| 65 | + kgid_t mapped_gid; | |
| 66 | + | |
| 67 | + if (gid_eq(gid, inode->i_gid)) | |
| 68 | + return true; | |
| 69 | + mapped_gid = mapped_kgid_fs(mnt_userns, i_user_ns(inode), gid); | |
| 70 | + if (in_group_p(mapped_gid)) | |
| 71 | + return true; | |
| 72 | + } | |
| 67 | 73 | if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) |
| 68 | 74 | return true; |
| 69 | 75 | if (gid_eq(kgid, INVALID_GID) && |
| @@ -123,12 +129,20 @@ int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry, · 53 unmodified lines | ||
| 123 | 129 | |
| 124 | 130 | /* Make sure a caller can chmod. */ |
| 125 | 131 | if (ia_valid & ATTR_MODE) { |
| 132 | + kgid_t mapped_gid; | |
| 133 | + | |
| 126 | 134 | if (!inode_owner_or_capable(mnt_userns, inode)) |
| 127 | 135 | return -EPERM; |
| 136 | + | |
| 137 | + if (ia_valid & ATTR_GID) | |
| 138 | + mapped_gid = mapped_kgid_fs(mnt_userns, | |
| 139 | + i_user_ns(inode), attr->ia_gid); | |
| 140 | + else | |
| 141 | + mapped_gid = i_gid_into_mnt(mnt_userns, inode); | |
| 142 | + | |
| 128 | 143 | /* Also check the setgid bit! */ |
| 129 | − if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : | |
| 130 | − i_gid_into_mnt(mnt_userns, inode)) && | |
| 131 | − !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) | |
| 144 | + if (!in_group_p(mapped_gid) && | |
| 145 | + !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) | |
| 132 | 146 | attr->ia_mode &= ~S_ISGID; |
| 133 | 147 | } |
| 134 | 148 | |
| @@ -104,6 +104,7 @@ struct btrfs_block_group { · 103 unmodified lines | ||
| 104 | 104 | unsigned int relocating_repair:1; |
| 105 | 105 | unsigned int chunk_item_inserted:1; |
| 106 | 106 | unsigned int zone_is_active:1; |
| 107 | + unsigned int zoned_data_reloc_ongoing:1; | |
| 107 | 108 | |
| 108 | 109 | int disk_cache_state; |
| 109 | 110 | |
| @@ -1330,6 +1330,8 @@ struct btrfs_replace_extent_info { · 1329 unmodified lines | ||
| 1330 | 1330 | * existing extent into a file range. |
| 1331 | 1331 | */ |
| 1332 | 1332 | bool is_new_extent; |
| 1333 | + /* Indicate if we should update the inode's mtime and ctime. */ | |
| 1334 | + bool update_times; | |
| 1333 | 1335 | /* Meaningful only if is_new_extent is true. */ |
| 1334 | 1336 | int qgroup_reserved; |
| 1335 | 1337 | /* |
| @@ -4632,6 +4632,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) · 4631 unmodified lines | ||
| 4632 | 4632 | int ret; |
| 4633 | 4633 | |
| 4634 | 4634 | set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags); |
| 4635 | + | |
| 4636 | + /* | |
| 4637 | + * We may have the reclaim task running and relocating a data block group, | |
| 4638 | + * in which case it may create delayed iputs. So stop it before we park | |
| 4639 | + * the cleaner kthread otherwise we can get new delayed iputs after | |
| 4640 | + * parking the cleaner, and that can make the async reclaim task to hang | |
| 4641 | + * if it's waiting for delayed iputs to complete, since the cleaner is | |
| 4642 | + * parked and can not run delayed iputs - this will make us hang when | |
| 4643 | + * trying to stop the async reclaim task. | |
| 4644 | + */ | |
| 4645 | + cancel_work_sync(&fs_info->reclaim_bgs_work); | |
| 4635 | 4646 | /* |
| 4636 | 4647 | * We don't want the cleaner to start new transactions, add more delayed |
| 4637 | 4648 | * iputs, etc. while we're closing. We can't use kthread_stop() yet |
| @@ -4672,8 +4683,6 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) · 34 unmodified lines | ||
| 4672 | 4683 | cancel_work_sync(&fs_info->async_data_reclaim_work); |
| 4673 | 4684 | cancel_work_sync(&fs_info->preempt_reclaim_work); |
| 4674 | 4685 | |
| 4675 | − cancel_work_sync(&fs_info->reclaim_bgs_work); | |
| 4676 | − | |
| 4677 | 4686 | /* Cancel or finish ongoing discard work */ |
| 4678 | 4687 | btrfs_discard_cleanup(fs_info); |
| 4679 | 4688 | |
| @@ -3832,7 +3832,7 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, · 3831 unmodified lines | ||
| 3832 | 3832 | block_group->start == fs_info->data_reloc_bg || |
| 3833 | 3833 | fs_info->data_reloc_bg == 0); |
| 3834 | 3834 | |
| 3835 | − if (block_group->ro) { | |
| 3835 | + if (block_group->ro || block_group->zoned_data_reloc_ongoing) { | |
| 3836 | 3836 | ret = 1; |
| 3837 | 3837 | goto out; |
| 3838 | 3838 | } |
| @@ -3894,8 +3894,24 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, · 55 unmodified lines | ||
| 3894 | 3894 | out: |
| 3895 | 3895 | if (ret && ffe_ctl->for_treelog) |
| 3896 | 3896 | fs_info->treelog_bg = 0; |
| 3897 | − if (ret && ffe_ctl->for_data_reloc) | |
| 3897 | + if (ret && ffe_ctl->for_data_reloc && | |
| 3898 | + fs_info->data_reloc_bg == block_group->start) { | |
| 3899 | + /* | |
| 3900 | + * Do not allow further allocations from this block group. | |
| 3901 | + * Compared to increasing the ->ro, setting the | |
| 3902 | + * ->zoned_data_reloc_ongoing flag still allows nocow | |
| 3903 | + * writers to come in. See btrfs_inc_nocow_writers(). | |
| 3904 | + * | |
| 3905 | + * We need to disable an allocation to avoid an allocation of | |
| 3906 | + * regular (non-relocation data) extent. With mix of relocation | |
| 3907 | + * extents and regular extents, we can dispatch WRITE commands | |
| 3908 | + * (for relocation extents) and ZONE APPEND commands (for | |
| 3909 | + * regular extents) at the same time to the same zone, which | |
| 3910 | + * easily break the write pointer. | |
| 3911 | + */ | |
| 3912 | + block_group->zoned_data_reloc_ongoing = 1; | |
| 3898 | 3913 | fs_info->data_reloc_bg = 0; |
| 3914 | + } | |
| 3899 | 3915 | spin_unlock(&fs_info->relocation_bg_lock); |
| 3900 | 3916 | spin_unlock(&fs_info->treelog_bg_lock); |
| 3901 | 3917 | spin_unlock(&block_group->lock); |
| @@ -5241,13 +5241,14 @@ int extent_writepages(struct address_space *mapping, · 5240 unmodified lines | ||
| 5241 | 5241 | */ |
| 5242 | 5242 | btrfs_zoned_data_reloc_lock(BTRFS_I(inode)); |
| 5243 | 5243 | ret = extent_write_cache_pages(mapping, wbc, &epd); |
| 5244 | − btrfs_zoned_data_reloc_unlock(BTRFS_I(inode)); | |
| 5245 | 5244 | ASSERT(ret <= 0); |
| 5246 | 5245 | if (ret < 0) { |
| 5246 | + btrfs_zoned_data_reloc_unlock(BTRFS_I(inode)); | |
| 5247 | 5247 | end_write_bio(&epd, ret); |
| 5248 | 5248 | return ret; |
| 5249 | 5249 | } |
| 5250 | 5250 | flush_write_bio(&epd); |
| 5251 | + btrfs_zoned_data_reloc_unlock(BTRFS_I(inode)); | |
| 5251 | 5252 | return ret; |
| 5252 | 5253 | } |
| 5253 | 5254 | |
| @@ -2323,25 +2323,62 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) · 2322 unmodified lines | ||
| 2323 | 2323 | */ |
| 2324 | 2324 | btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP); |
| 2325 | 2325 | |
| 2326 | − if (ret != BTRFS_NO_LOG_SYNC) { | |
| 2326 | + if (ret == BTRFS_NO_LOG_SYNC) { | |
| 2327 | + ret = btrfs_end_transaction(trans); | |
| 2328 | + goto out; | |
| 2329 | + } | |
| 2330 | + | |
| 2331 | + /* We successfully logged the inode, attempt to sync the log. */ | |
| 2332 | + if (!ret) { | |
| 2333 | + ret = btrfs_sync_log(trans, root, &ctx); | |
| 2327 | 2334 | if (!ret) { |
| 2328 | − ret = btrfs_sync_log(trans, root, &ctx); | |
| 2329 | − if (!ret) { | |
| 2330 | − ret = btrfs_end_transaction(trans); | |
| 2331 | − goto out; | |
| 2332 | − } | |
| 2333 | − } | |
| 2334 | − if (!full_sync) { | |
| 2335 | − ret = btrfs_wait_ordered_range(inode, start, len); | |
| 2336 | − if (ret) { | |
| 2337 | − btrfs_end_transaction(trans); | |
| 2338 | − goto out; | |
| 2339 | − } | |
| 2335 | + ret = btrfs_end_transaction(trans); | |
| 2336 | + goto out; | |
| 2340 | 2337 | } |
| 2341 | − ret = btrfs_commit_transaction(trans); | |
| 2342 | − } else { | |
| 2338 | + } | |
| 2339 | + | |
| 2340 | + /* | |
| 2341 | + * At this point we need to commit the transaction because we had | |
| 2342 | + * btrfs_need_log_full_commit() or some other error. | |
| 2343 | + * | |
| 2344 | + * If we didn't do a full sync we have to stop the trans handle, wait on | |
| 2345 | + * the ordered extents, start it again and commit the transaction. If | |
| 2346 | + * we attempt to wait on the ordered extents here we could deadlock with | |
| 2347 | + * something like fallocate() that is holding the extent lock trying to | |
| 2348 | + * start a transaction while some other thread is trying to commit the | |
| 2349 | + * transaction while we (fsync) are currently holding the transaction | |
| 2350 | + * open. | |
| 2351 | + */ | |
| 2352 | + if (!full_sync) { | |
| 2343 | 2353 | ret = btrfs_end_transaction(trans); |
| 2354 | + if (ret) | |
| 2355 | + goto out; | |
| 2356 | + ret = btrfs_wait_ordered_range(inode, start, len); | |
| 2357 | + if (ret) | |
| 2358 | + goto out; | |
| 2359 | + | |
| 2360 | + /* | |
| 2361 | + * This is safe to use here because we're only interested in | |
| 2362 | + * making sure the transaction that had the ordered extents is | |
| 2363 | + * committed. We aren't waiting on anything past this point, | |
| 2364 | + * we're purely getting the transaction and committing it. | |
| 2365 | + */ | |
| 2366 | + trans = btrfs_attach_transaction_barrier(root); | |
| 2367 | + if (IS_ERR(trans)) { | |
| 2368 | + ret = PTR_ERR(trans); | |
| 2369 | + | |
| 2370 | + /* | |
| 2371 | + * We committed the transaction and there's no currently | |
| 2372 | + * running transaction, this means everything we care | |
| 2373 | + * about made it to disk and we are done. | |
| 2374 | + */ | |
| 2375 | + if (ret == -ENOENT) | |
| 2376 | + ret = 0; | |
| 2377 | + goto out; | |
| 2378 | + } | |
| 2344 | 2379 | } |
| 2380 | + | |
| 2381 | + ret = btrfs_commit_transaction(trans); | |
| 2345 | 2382 | out: |
| 2346 | 2383 | ASSERT(list_empty(&ctx.list)); |
| 2347 | 2384 | err = file_check_and_advance_wb_err(file); |
| @@ -2719,7 +2756,8 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, · 371 unmodified lines | ||
| 2719 | 2756 | |
| 2720 | 2757 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv, |
| 2721 | 2758 | min_size, false); |
| 2722 | − BUG_ON(ret); | |
| 2759 | + if (WARN_ON(ret)) | |
| 2760 | + goto out_trans; | |
| 2723 | 2761 | trans->block_rsv = rsv; |
| 2724 | 2762 | |
| 2725 | 2763 | cur_offset = start; |
| @@ -2803,6 +2841,25 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, · 77 unmodified lines | ||
| 2803 | 2841 | extent_info->file_offset += replace_len; |
| 2804 | 2842 | } |
| 2805 | 2843 | |
| 2844 | + /* | |
| 2845 | + * We are releasing our handle on the transaction, balance the | |
| 2846 | + * dirty pages of the btree inode and flush delayed items, and | |
| 2847 | + * then get a new transaction handle, which may now point to a | |
| 2848 | + * new transaction in case someone else may have committed the | |
| 2849 | + * transaction we used to replace/drop file extent items. So | |
| 2850 | + * bump the inode's iversion and update mtime and ctime except | |
| 2851 | + * if we are called from a dedupe context. This is because a | |
| 2852 | + * power failure/crash may happen after the transaction is | |
| 2853 | + * committed and before we finish replacing/dropping all the | |
| 2854 | + * file extent items we need. | |
| 2855 | + */ | |
| 2856 | + inode_inc_iversion(&inode->vfs_inode); | |
| 2857 | + | |
| 2858 | + if (!extent_info || extent_info->update_times) { | |
| 2859 | + inode->vfs_inode.i_mtime = current_time(&inode->vfs_inode); | |
| 2860 | + inode->vfs_inode.i_ctime = inode->vfs_inode.i_mtime; | |
| 2861 | + } | |
| 2862 | + | |
| 2806 | 2863 | ret = btrfs_update_inode(trans, root, inode); |
| 2807 | 2864 | if (ret) |
| 2808 | 2865 | break; |
| @@ -2819,7 +2876,8 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, · 10 unmodified lines | ||
| 2819 | 2876 | |
| 2820 | 2877 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, |
| 2821 | 2878 | rsv, min_size, false); |
| 2822 | − BUG_ON(ret); /* shouldn't happen */ | |
| 2879 | + if (WARN_ON(ret)) | |
| 2880 | + break; | |
| 2823 | 2881 | trans->block_rsv = rsv; |
| 2824 | 2882 | |
| 2825 | 2883 | cur_offset = drop_args.drop_end; |
| @@ -3195,6 +3195,8 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) · 3194 unmodified lines | ||
| 3195 | 3195 | ordered_extent->file_offset, |
| 3196 | 3196 | ordered_extent->file_offset + |
| 3197 | 3197 | logical_len); |
| 3198 | + btrfs_zoned_release_data_reloc_bg(fs_info, ordered_extent->disk_bytenr, | |
| 3199 | + ordered_extent->disk_num_bytes); | |
| 3198 | 3200 | } else { |
| 3199 | 3201 | BUG_ON(root == fs_info->tree_root); |
| 3200 | 3202 | ret = insert_ordered_extent_file_extent(trans, ordered_extent); |
| @@ -9897,6 +9899,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( · 6696 unmodified lines | ||
| 9897 | 9899 | extent_info.file_offset = file_offset; |
| 9898 | 9900 | extent_info.extent_buf = (char *)&stack_fi; |
| 9899 | 9901 | extent_info.is_new_extent = true; |
| 9902 | + extent_info.update_times = true; | |
| 9900 | 9903 | extent_info.qgroup_reserved = qgroup_released; |
| 9901 | 9904 | extent_info.insertions = 0; |
| 9902 | 9905 | |
| @@ -45,7 +45,6 @@ void __btrfs_tree_read_lock(struct extent_buffer *eb, enum btrfs_lock_nesting ne · 44 unmodified lines | ||
| 45 | 45 | start_ns = ktime_get_ns(); |
| 46 | 46 | |
| 47 | 47 | down_read_nested(&eb->lock, nest); |
| 48 | − eb->lock_owner = current->pid; | |
| 49 | 48 | trace_btrfs_tree_read_lock(eb, start_ns); |
| 50 | 49 | } |
| 51 | 50 | |
| @@ -62,7 +61,6 @@ void btrfs_tree_read_lock(struct extent_buffer *eb) · 10 unmodified lines | ||
| 62 | 61 | int btrfs_try_tree_read_lock(struct extent_buffer *eb) |
| 63 | 62 | { |
| 64 | 63 | if (down_read_trylock(&eb->lock)) { |
| 65 | − eb->lock_owner = current->pid; | |
| 66 | 64 | trace_btrfs_try_tree_read_lock(eb); |
| 67 | 65 | return 1; |
| 68 | 66 | } |
| @@ -90,7 +88,6 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) · 21 unmodified lines | ||
| 90 | 88 | void btrfs_tree_read_unlock(struct extent_buffer *eb) |
| 91 | 89 | { |
| 92 | 90 | trace_btrfs_tree_read_unlock(eb); |
| 93 | − eb->lock_owner = 0; | |
| 94 | 91 | up_read(&eb->lock); |
| 95 | 92 | } |
| 96 | 93 | |
| @@ -344,6 +344,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, · 343 unmodified lines | ||
| 344 | 344 | int ret; |
| 345 | 345 | const u64 len = olen_aligned; |
| 346 | 346 | u64 last_dest_end = destoff; |
| 347 | + u64 prev_extent_end = off; | |
| 347 | 348 | |
| 348 | 349 | ret = -ENOMEM; |
| 349 | 350 | buf = kvmalloc(fs_info->nodesize, GFP_KERNEL); |
| @@ -363,7 +364,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode, · 13 unmodified lines | ||
| 363 | 364 | key.offset = off; |
| 364 | 365 | |
| 365 | 366 | while (1) { |
| 366 | − u64 next_key_min_offset = key.offset + 1; | |
| 367 | 367 | struct btrfs_file_extent_item *extent; |
| 368 | 368 | u64 extent_gen; |
| 369 | 369 | int type; |
| @@ -431,14 +431,21 @@ process_slot: · 61 unmodified lines | ||
| 431 | 431 | * The first search might have left us at an extent item that |
| 432 | 432 | * ends before our target range's start, can happen if we have |
| 433 | 433 | * holes and NO_HOLES feature enabled. |
| 434 | + * | |
| 435 | + * Subsequent searches may leave us on a file range we have | |
| 436 | + * processed before - this happens due to a race with ordered | |
| 437 | + * extent completion for a file range that is outside our source | |
| 438 | + * range, but that range was part of a file extent item that | |
| 439 | + * also covered a leading part of our source range. | |
| 434 | 440 | */ |
| 435 | − if (key.offset + datal <= off) { | |
| 441 | + if (key.offset + datal <= prev_extent_end) { | |
| 436 | 442 | path->slots[0]++; |
| 437 | 443 | goto process_slot; |
| 438 | 444 | } else if (key.offset >= off + len) { |
| 439 | 445 | break; |
| 440 | 446 | } |
| 441 | − next_key_min_offset = key.offset + datal; | |
| 447 | + | |
| 448 | + prev_extent_end = key.offset + datal; | |
| 442 | 449 | size = btrfs_item_size(leaf, slot); |
| 443 | 450 | read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, slot), |
| 444 | 451 | size); |
| @@ -489,6 +496,7 @@ process_slot: · 44 unmodified lines | ||
| 489 | 496 | clone_info.file_offset = new_key.offset; |
| 490 | 497 | clone_info.extent_buf = buf; |
| 491 | 498 | clone_info.is_new_extent = false; |
| 499 | + clone_info.update_times = !no_time_update; | |
| 492 | 500 | ret = btrfs_replace_file_extents(BTRFS_I(inode), path, |
| 493 | 501 | drop_start, new_key.offset + datal - 1, |
| 494 | 502 | &clone_info, &trans); |
| @@ -550,7 +558,7 @@ process_slot: · 55 unmodified lines | ||
| 550 | 558 | break; |
| 551 | 559 | |
| 552 | 560 | btrfs_release_path(path); |
| 553 | − key.offset = next_key_min_offset; | |
| 561 | + key.offset = prev_extent_end; | |
| 554 | 562 | |
| 555 | 563 | if (fatal_signal_pending(current)) { |
| 556 | 564 | ret = -EINTR; |
| @@ -763,6 +763,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 762 unmodified lines | ||
| 763 | 763 | compress_force = false; |
| 764 | 764 | no_compress++; |
| 765 | 765 | } else { |
| 766 | + btrfs_err(info, "unrecognized compression value %s", | |
| 767 | + args[0].from); | |
| 766 | 768 | ret = -EINVAL; |
| 767 | 769 | goto out; |
| 768 | 770 | } |
| @@ -821,8 +823,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 52 unmodified lines | ||
| 821 | 823 | case Opt_thread_pool: |
| 822 | 824 | ret = match_int(&args[0], &intarg); |
| 823 | 825 | if (ret) { |
| 826 | + btrfs_err(info, "unrecognized thread_pool value %s", | |
| 827 | + args[0].from); | |
| 824 | 828 | goto out; |
| 825 | 829 | } else if (intarg == 0) { |
| 830 | + btrfs_err(info, "invalid value 0 for thread_pool"); | |
| 826 | 831 | ret = -EINVAL; |
| 827 | 832 | goto out; |
| 828 | 833 | } |
| @@ -883,8 +888,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 54 unmodified lines | ||
| 883 | 888 | break; |
| 884 | 889 | case Opt_ratio: |
| 885 | 890 | ret = match_int(&args[0], &intarg); |
| 886 | − if (ret) | |
| 891 | + if (ret) { | |
| 892 | + btrfs_err(info, "unrecognized metadata_ratio value %s", | |
| 893 | + args[0].from); | |
| 887 | 894 | goto out; |
| 895 | + } | |
| 888 | 896 | info->metadata_ratio = intarg; |
| 889 | 897 | btrfs_info(info, "metadata ratio %u", |
| 890 | 898 | info->metadata_ratio); |
| @@ -901,6 +909,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 10 unmodified lines | ||
| 901 | 909 | btrfs_set_and_info(info, DISCARD_ASYNC, |
| 902 | 910 | "turning on async discard"); |
| 903 | 911 | } else { |
| 912 | + btrfs_err(info, "unrecognized discard mode value %s", | |
| 913 | + args[0].from); | |
| 904 | 914 | ret = -EINVAL; |
| 905 | 915 | goto out; |
| 906 | 916 | } |
| @@ -933,6 +943,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 26 unmodified lines | ||
| 933 | 943 | btrfs_set_and_info(info, FREE_SPACE_TREE, |
| 934 | 944 | "enabling free space tree"); |
| 935 | 945 | } else { |
| 946 | + btrfs_err(info, "unrecognized space_cache value %s", | |
| 947 | + args[0].from); | |
| 936 | 948 | ret = -EINVAL; |
| 937 | 949 | goto out; |
| 938 | 950 | } |
| @@ -1014,8 +1026,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 75 unmodified lines | ||
| 1014 | 1026 | break; |
| 1015 | 1027 | case Opt_check_integrity_print_mask: |
| 1016 | 1028 | ret = match_int(&args[0], &intarg); |
| 1017 | − if (ret) | |
| 1029 | + if (ret) { | |
| 1030 | + btrfs_err(info, | |
| 1031 | + "unrecognized check_integrity_print_mask value %s", | |
| 1032 | + args[0].from); | |
| 1018 | 1033 | goto out; |
| 1034 | + } | |
| 1019 | 1035 | info->check_integrity_print_mask = intarg; |
| 1020 | 1036 | btrfs_info(info, "check_integrity_print_mask 0x%x", |
| 1021 | 1037 | info->check_integrity_print_mask); |
| @@ -1030,13 +1046,15 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 8 unmodified lines | ||
| 1030 | 1046 | goto out; |
| 1031 | 1047 | #endif |
| 1032 | 1048 | case Opt_fatal_errors: |
| 1033 | − if (strcmp(args[0].from, "panic") == 0) | |
| 1049 | + if (strcmp(args[0].from, "panic") == 0) { | |
| 1034 | 1050 | btrfs_set_opt(info->mount_opt, |
| 1035 | 1051 | PANIC_ON_FATAL_ERROR); |
| 1036 | − else if (strcmp(args[0].from, "bug") == 0) | |
| 1052 | + } else if (strcmp(args[0].from, "bug") == 0) { | |
| 1037 | 1053 | btrfs_clear_opt(info->mount_opt, |
| 1038 | 1054 | PANIC_ON_FATAL_ERROR); |
| 1039 | − else { | |
| 1055 | + } else { | |
| 1056 | + btrfs_err(info, "unrecognized fatal_errors value %s", | |
| 1057 | + args[0].from); | |
| 1040 | 1058 | ret = -EINVAL; |
| 1041 | 1059 | goto out; |
| 1042 | 1060 | } |
| @@ -1044,8 +1062,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 1 unmodified line | ||
| 1044 | 1062 | case Opt_commit_interval: |
| 1045 | 1063 | intarg = 0; |
| 1046 | 1064 | ret = match_int(&args[0], &intarg); |
| 1047 | − if (ret) | |
| 1065 | + if (ret) { | |
| 1066 | + btrfs_err(info, "unrecognized commit_interval value %s", | |
| 1067 | + args[0].from); | |
| 1068 | + ret = -EINVAL; | |
| 1048 | 1069 | goto out; |
| 1070 | + } | |
| 1049 | 1071 | if (intarg == 0) { |
| 1050 | 1072 | btrfs_info(info, |
| 1051 | 1073 | "using default commit interval %us", |
| @@ -1059,8 +1081,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 7 unmodified lines | ||
| 1059 | 1081 | break; |
| 1060 | 1082 | case Opt_rescue: |
| 1061 | 1083 | ret = parse_rescue_options(info, args[0].from); |
| 1062 | − if (ret < 0) | |
| 1084 | + if (ret < 0) { | |
| 1085 | + btrfs_err(info, "unrecognized rescue value %s", | |
| 1086 | + args[0].from); | |
| 1063 | 1087 | goto out; |
| 1088 | + } | |
| 1064 | 1089 | break; |
| 1065 | 1090 | #ifdef CONFIG_BTRFS_DEBUG |
| 1066 | 1091 | case Opt_fragment_all: |
| @@ -1985,6 +2010,14 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) · 918 unmodified lines | ||
| 1985 | 2010 | if (ret) |
| 1986 | 2011 | goto restore; |
| 1987 | 2012 | |
| 2013 | + /* V1 cache is not supported for subpage mount. */ | |
| 2014 | + if (fs_info->sectorsize < PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) { | |
| 2015 | + btrfs_warn(fs_info, | |
| 2016 | + "v1 space cache is not supported for page size %lu with sectorsize %u", | |
| 2017 | + PAGE_SIZE, fs_info->sectorsize); | |
| 2018 | + ret = -EINVAL; | |
| 2019 | + goto restore; | |
| 2020 | + } | |
| 1988 | 2021 | btrfs_remount_begin(fs_info, old_opts, *flags); |
| 1989 | 2022 | btrfs_resize_thread_pool(fs_info, |
| 1990 | 2023 | fs_info->thread_pool_size, old_thread_pool_size); |
| @@ -2139,3 +2139,30 @@ bool btrfs_zoned_should_reclaim(struct btrfs_fs_info *fs_info) · 2138 unmodified lines | ||
| 2139 | 2139 | factor = div64_u64(used * 100, total); |
| 2140 | 2140 | return factor >= fs_info->bg_reclaim_threshold; |
| 2141 | 2141 | } |
| 2142 | + | |
| 2143 | +void btrfs_zoned_release_data_reloc_bg(struct btrfs_fs_info *fs_info, u64 logical, | |
| 2144 | + u64 length) | |
| 2145 | +{ | |
| 2146 | + struct btrfs_block_group *block_group; | |
| 2147 | + | |
| 2148 | + if (!btrfs_is_zoned(fs_info)) | |
| 2149 | + return; | |
| 2150 | + | |
| 2151 | + block_group = btrfs_lookup_block_group(fs_info, logical); | |
| 2152 | + /* It should be called on a previous data relocation block group. */ | |
| 2153 | + ASSERT(block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)); | |
| 2154 | + | |
| 2155 | + spin_lock(&block_group->lock); | |
| 2156 | + if (!block_group->zoned_data_reloc_ongoing) | |
| 2157 | + goto out; | |
| 2158 | + | |
| 2159 | + /* All relocation extents are written. */ | |
| 2160 | + if (block_group->start + block_group->alloc_offset == logical + length) { | |
| 2161 | + /* Now, release this block group for further allocations. */ | |
| 2162 | + block_group->zoned_data_reloc_ongoing = 0; | |
| 2163 | + } | |
| 2164 | + | |
| 2165 | +out: | |
| 2166 | + spin_unlock(&block_group->lock); | |
| 2167 | + btrfs_put_block_group(block_group); | |
| 2168 | +} | |
| @@ -77,6 +77,8 @@ void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg, · 76 unmodified lines | ||
| 77 | 77 | void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg); |
| 78 | 78 | void btrfs_free_zone_cache(struct btrfs_fs_info *fs_info); |
| 79 | 79 | bool btrfs_zoned_should_reclaim(struct btrfs_fs_info *fs_info); |
| 80 | +void btrfs_zoned_release_data_reloc_bg(struct btrfs_fs_info *fs_info, u64 logical, | |
| 81 | + u64 length); | |
| 80 | 82 | #else /* CONFIG_BLK_DEV_ZONED */ |
| 81 | 83 | static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, |
| 82 | 84 | struct blk_zone *zone) |
| @@ -243,6 +245,9 @@ static inline bool btrfs_zoned_should_reclaim(struct btrfs_fs_info *fs_info) · 160 unmodified lines | ||
| 243 | 245 | { |
| 244 | 246 | return false; |
| 245 | 247 | } |
| 248 | + | |
| 249 | +static inline void btrfs_zoned_release_data_reloc_bg(struct btrfs_fs_info *fs_info, | |
| 250 | + u64 logical, u64 length) { } | |
| 246 | 251 | #endif |
| 247 | 252 | |
| 248 | 253 | static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos) |
| @@ -162,6 +162,8 @@ cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface) · 161 unmodified lines | ||
| 162 | 162 | seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr); |
| 163 | 163 | else if (iface->sockaddr.ss_family == AF_INET6) |
| 164 | 164 | seq_printf(m, "\t\tIPv6: %pI6\n", &ipv6->sin6_addr); |
| 165 | + if (!iface->is_active) | |
| 166 | + seq_puts(m, "\t\t[for-cleanup]\n"); | |
| 165 | 167 | } |
| 166 | 168 | |
| 167 | 169 | static int cifs_debug_files_proc_show(struct seq_file *m, void *v) |
| @@ -221,6 +223,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) · 53 unmodified lines | ||
| 221 | 223 | struct TCP_Server_Info *server; |
| 222 | 224 | struct cifs_ses *ses; |
| 223 | 225 | struct cifs_tcon *tcon; |
| 226 | + struct cifs_server_iface *iface; | |
| 224 | 227 | int c, i, j; |
| 225 | 228 | |
| 226 | 229 | seq_puts(m, |
| @@ -456,11 +459,10 @@ skip_rdma: · 229 unmodified lines | ||
| 456 | 459 | if (ses->iface_count) |
| 457 | 460 | seq_printf(m, "\n\n\tServer interfaces: %zu", |
| 458 | 461 | ses->iface_count); |
| 459 | − for (j = 0; j < ses->iface_count; j++) { | |
| 460 | − struct cifs_server_iface *iface; | |
| 461 | − | |
| 462 | − iface = &ses->iface_list[j]; | |
| 463 | − seq_printf(m, "\n\t%d)", j+1); | |
| 462 | + j = 0; | |
| 463 | + list_for_each_entry(iface, &ses->iface_list, | |
| 464 | + iface_head) { | |
| 465 | + seq_printf(m, "\n\t%d)", ++j); | |
| 464 | 466 | cifs_dump_iface(m, iface); |
| 465 | 467 | if (is_ses_using_iface(ses, iface)) |
| 466 | 468 | seq_puts(m, "\t\t[CONNECTED]\n"); |
| @@ -80,6 +80,9 @@ · 79 unmodified lines | ||
| 80 | 80 | #define SMB_DNS_RESOLVE_INTERVAL_MIN 120 |
| 81 | 81 | #define SMB_DNS_RESOLVE_INTERVAL_DEFAULT 600 |
| 82 | 82 | |
| 83 | +/* smb multichannel query server interfaces interval in seconds */ | |
| 84 | +#define SMB_INTERFACE_POLL_INTERVAL 600 | |
| 85 | + | |
| 83 | 86 | /* maximum number of PDUs in one compound */ |
| 84 | 87 | #define MAX_COMPOUND 5 |
| 85 | 88 | |
| @@ -933,15 +936,67 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net) · 847 unmodified lines | ||
| 933 | 936 | #endif |
| 934 | 937 | |
| 935 | 938 | struct cifs_server_iface { |
| 939 | + struct list_head iface_head; | |
| 940 | + struct kref refcount; | |
| 936 | 941 | size_t speed; |
| 937 | 942 | unsigned int rdma_capable : 1; |
| 938 | 943 | unsigned int rss_capable : 1; |
| 944 | + unsigned int is_active : 1; /* unset if non existent */ | |
| 939 | 945 | struct sockaddr_storage sockaddr; |
| 940 | 946 | }; |
| 941 | 947 | |
| 948 | +/* release iface when last ref is dropped */ | |
| 949 | +static inline void | |
| 950 | +release_iface(struct kref *ref) | |
| 951 | +{ | |
| 952 | + struct cifs_server_iface *iface = container_of(ref, | |
| 953 | + struct cifs_server_iface, | |
| 954 | + refcount); | |
| 955 | + list_del_init(&iface->iface_head); | |
| 956 | + kfree(iface); | |
| 957 | +} | |
| 958 | + | |
| 959 | +/* | |
| 960 | + * compare two interfaces a and b | |
| 961 | + * return 0 if everything matches. | |
| 962 | + * return 1 if a has higher link speed, or rdma capable, or rss capable | |
| 963 | + * return -1 otherwise. | |
| 964 | + */ | |
| 965 | +static inline int | |
| 966 | +iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b) | |
| 967 | +{ | |
| 968 | + int cmp_ret = 0; | |
| 969 | + | |
| 970 | + WARN_ON(!a || !b); | |
| 971 | + if (a->speed == b->speed) { | |
| 972 | + if (a->rdma_capable == b->rdma_capable) { | |
| 973 | + if (a->rss_capable == b->rss_capable) { | |
| 974 | + cmp_ret = memcmp(&a->sockaddr, &b->sockaddr, | |
| 975 | + sizeof(a->sockaddr)); | |
| 976 | + if (!cmp_ret) | |
| 977 | + return 0; | |
| 978 | + else if (cmp_ret > 0) | |
| 979 | + return 1; | |
| 980 | + else | |
| 981 | + return -1; | |
| 982 | + } else if (a->rss_capable > b->rss_capable) | |
| 983 | + return 1; | |
| 984 | + else | |
| 985 | + return -1; | |
| 986 | + } else if (a->rdma_capable > b->rdma_capable) | |
| 987 | + return 1; | |
| 988 | + else | |
| 989 | + return -1; | |
| 990 | + } else if (a->speed > b->speed) | |
| 991 | + return 1; | |
| 992 | + else | |
| 993 | + return -1; | |
| 994 | +} | |
| 995 | + | |
| 942 | 996 | struct cifs_chan { |
| 943 | 997 | unsigned int in_reconnect : 1; /* if session setup in progress for this channel */ |
| 944 | 998 | struct TCP_Server_Info *server; |
| 999 | + struct cifs_server_iface *iface; /* interface in use */ | |
| 945 | 1000 | __u8 signkey[SMB3_SIGN_KEY_SIZE]; |
| 946 | 1001 | }; |
| 947 | 1002 | |
| @@ -993,7 +1048,7 @@ struct cifs_ses { · 45 unmodified lines | ||
| 993 | 1048 | */ |
| 994 | 1049 | spinlock_t iface_lock; |
| 995 | 1050 | /* ========= begin: protected by iface_lock ======== */ |
| 996 | − struct cifs_server_iface *iface_list; | |
| 1051 | + struct list_head iface_list; | |
| 997 | 1052 | size_t iface_count; |
| 998 | 1053 | unsigned long iface_last_update; /* jiffies */ |
| 999 | 1054 | /* ========= end: protected by iface_lock ======== */ |
| @@ -1203,6 +1258,7 @@ struct cifs_tcon { · 203 unmodified lines | ||
| 1203 | 1258 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 1204 | 1259 | struct list_head ulist; /* cache update list */ |
| 1205 | 1260 | #endif |
| 1261 | + struct delayed_work query_interfaces; /* query interfaces workqueue job */ | |
| 1206 | 1262 | }; |
| 1207 | 1263 | |
| 1208 | 1264 | /* |
| @@ -636,6 +636,13 @@ cifs_chan_clear_need_reconnect(struct cifs_ses *ses, · 635 unmodified lines | ||
| 636 | 636 | bool |
| 637 | 637 | cifs_chan_needs_reconnect(struct cifs_ses *ses, |
| 638 | 638 | struct TCP_Server_Info *server); |
| 639 | +bool | |
| 640 | +cifs_chan_is_iface_active(struct cifs_ses *ses, | |
| 641 | + struct TCP_Server_Info *server); | |
| 642 | +int | |
| 643 | +cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server); | |
| 644 | +int | |
| 645 | +SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon); | |
| 639 | 646 | |
| 640 | 647 | void extract_unc_hostname(const char *unc, const char **h, size_t *len); |
| 641 | 648 | int copy_path_name(char *dst, const char *src); |
| @@ -145,6 +145,25 @@ requeue_resolve: · 144 unmodified lines | ||
| 145 | 145 | return rc; |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | +static void smb2_query_server_interfaces(struct work_struct *work) | |
| 149 | +{ | |
| 150 | + int rc; | |
| 151 | + struct cifs_tcon *tcon = container_of(work, | |
| 152 | + struct cifs_tcon, | |
| 153 | + query_interfaces.work); | |
| 154 | + | |
| 155 | + /* | |
| 156 | + * query server network interfaces, in case they change | |
| 157 | + */ | |
| 158 | + rc = SMB3_request_interfaces(0, tcon); | |
| 159 | + if (rc) { | |
| 160 | + cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n", | |
| 161 | + __func__, rc); | |
| 162 | + } | |
| 163 | + | |
| 164 | + queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, | |
| 165 | + (SMB_INTERFACE_POLL_INTERVAL * HZ)); | |
| 166 | +} | |
| 148 | 167 | |
| 149 | 168 | static void cifs_resolve_server(struct work_struct *work) |
| 150 | 169 | { |
| @@ -217,7 +236,7 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, · 66 unmodified lines | ||
| 217 | 236 | bool mark_smb_session) |
| 218 | 237 | { |
| 219 | 238 | struct TCP_Server_Info *pserver; |
| 220 | − struct cifs_ses *ses; | |
| 239 | + struct cifs_ses *ses, *nses; | |
| 221 | 240 | struct cifs_tcon *tcon; |
| 222 | 241 | |
| 223 | 242 | /* |
| @@ -231,7 +250,20 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, · 7 unmodified lines | ||
| 231 | 250 | |
| 232 | 251 | |
| 233 | 252 | spin_lock(&cifs_tcp_ses_lock); |
| 234 | − list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { | |
| 253 | + list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { | |
| 254 | + /* check if iface is still active */ | |
| 255 | + if (!cifs_chan_is_iface_active(ses, server)) { | |
| 256 | + /* | |
| 257 | + * HACK: drop the lock before calling | |
| 258 | + * cifs_chan_update_iface to avoid deadlock | |
| 259 | + */ | |
| 260 | + ses->ses_count++; | |
| 261 | + spin_unlock(&cifs_tcp_ses_lock); | |
| 262 | + cifs_chan_update_iface(ses, server); | |
| 263 | + spin_lock(&cifs_tcp_ses_lock); | |
| 264 | + ses->ses_count--; | |
| 265 | + } | |
| 266 | + | |
| 235 | 267 | spin_lock(&ses->chan_lock); |
| 236 | 268 | if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) |
| 237 | 269 | goto next_session; |
| @@ -1894,9 +1926,11 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 1656 unmodified lines | ||
| 1894 | 1926 | int i; |
| 1895 | 1927 | |
| 1896 | 1928 | for (i = 1; i < chan_count; i++) { |
| 1897 | − spin_unlock(&ses->chan_lock); | |
| 1929 | + if (ses->chans[i].iface) { | |
| 1930 | + kref_put(&ses->chans[i].iface->refcount, release_iface); | |
| 1931 | + ses->chans[i].iface = NULL; | |
| 1932 | + } | |
| 1898 | 1933 | cifs_put_tcp_session(ses->chans[i].server, 0); |
| 1899 | − spin_lock(&ses->chan_lock); | |
| 1900 | 1934 | ses->chans[i].server = NULL; |
| 1901 | 1935 | } |
| 1902 | 1936 | } |
| @@ -2270,6 +2304,9 @@ cifs_put_tcon(struct cifs_tcon *tcon) · 367 unmodified lines | ||
| 2270 | 2304 | list_del_init(&tcon->tcon_list); |
| 2271 | 2305 | spin_unlock(&cifs_tcp_ses_lock); |
| 2272 | 2306 | |
| 2307 | + /* cancel polling of interfaces */ | |
| 2308 | + cancel_delayed_work_sync(&tcon->query_interfaces); | |
| 2309 | + | |
| 2273 | 2310 | if (tcon->use_witness) { |
| 2274 | 2311 | int rc; |
| 2275 | 2312 | |
| @@ -2507,6 +2544,12 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) · 231 unmodified lines | ||
| 2507 | 2544 | tcon->local_lease = ctx->local_lease; |
| 2508 | 2545 | INIT_LIST_HEAD(&tcon->pending_opens); |
| 2509 | 2546 | |
| 2547 | + /* schedule query interfaces poll */ | |
| 2548 | + INIT_DELAYED_WORK(&tcon->query_interfaces, | |
| 2549 | + smb2_query_server_interfaces); | |
| 2550 | + queue_delayed_work(cifsiod_wq, &tcon->query_interfaces, | |
| 2551 | + (SMB_INTERFACE_POLL_INTERVAL * HZ)); | |
| 2552 | + | |
| 2510 | 2553 | spin_lock(&cifs_tcp_ses_lock); |
| 2511 | 2554 | list_add(&tcon->tcon_list, &ses->tcon_list); |
| 2512 | 2555 | spin_unlock(&cifs_tcp_ses_lock); |
| @@ -3982,10 +4025,16 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 1469 unmodified lines | ||
| 3982 | 4025 | struct nls_table *nls_info) |
| 3983 | 4026 | { |
| 3984 | 4027 | int rc = -ENOSYS; |
| 4028 | + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; | |
| 4029 | + struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; | |
| 3985 | 4030 | bool is_binding = false; |
| 3986 | 4031 | |
| 3987 | − | |
| 3988 | 4032 | spin_lock(&cifs_tcp_ses_lock); |
| 4033 | + if (server->dstaddr.ss_family == AF_INET6) | |
| 4034 | + scnprintf(ses->ip_addr, sizeof(ses->ip_addr), "%pI6", &addr6->sin6_addr); | |
| 4035 | + else | |
| 4036 | + scnprintf(ses->ip_addr, sizeof(ses->ip_addr), "%pI4", &addr->sin_addr); | |
| 4037 | + | |
| 3989 | 4038 | if (ses->ses_status != SES_GOOD && |
| 3990 | 4039 | ses->ses_status != SES_NEW && |
| 3991 | 4040 | ses->ses_status != SES_NEED_RECON) { |
| @@ -75,6 +75,7 @@ sesInfoAlloc(void) · 74 unmodified lines | ||
| 75 | 75 | INIT_LIST_HEAD(&ret_buf->tcon_list); |
| 76 | 76 | mutex_init(&ret_buf->session_mutex); |
| 77 | 77 | spin_lock_init(&ret_buf->iface_lock); |
| 78 | + INIT_LIST_HEAD(&ret_buf->iface_list); | |
| 78 | 79 | spin_lock_init(&ret_buf->chan_lock); |
| 79 | 80 | } |
| 80 | 81 | return ret_buf; |
| @@ -83,6 +84,8 @@ sesInfoAlloc(void) · 2 unmodified lines | ||
| 83 | 84 | void |
| 84 | 85 | sesInfoFree(struct cifs_ses *buf_to_free) |
| 85 | 86 | { |
| 87 | + struct cifs_server_iface *iface = NULL, *niface = NULL; | |
| 88 | + | |
| 86 | 89 | if (buf_to_free == NULL) { |
| 87 | 90 | cifs_dbg(FYI, "Null buffer passed to sesInfoFree\n"); |
| 88 | 91 | return; |
| @@ -96,7 +99,11 @@ sesInfoFree(struct cifs_ses *buf_to_free) · 7 unmodified lines | ||
| 96 | 99 | kfree(buf_to_free->user_name); |
| 97 | 100 | kfree(buf_to_free->domainName); |
| 98 | 101 | kfree_sensitive(buf_to_free->auth_key.response); |
| 99 | − kfree(buf_to_free->iface_list); | |
| 102 | + spin_lock(&buf_to_free->iface_lock); | |
| 103 | + list_for_each_entry_safe(iface, niface, &buf_to_free->iface_list, | |
| 104 | + iface_head) | |
| 105 | + kref_put(&iface->refcount, release_iface); | |
| 106 | + spin_unlock(&buf_to_free->iface_lock); | |
| 100 | 107 | kfree_sensitive(buf_to_free); |
| 101 | 108 | } |
| 102 | 109 | |
| @@ -58,7 +58,7 @@ bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface) · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | spin_lock(&ses->chan_lock); |
| 60 | 60 | for (i = 0; i < ses->chan_count; i++) { |
| 61 | − if (is_server_using_iface(ses->chans[i].server, iface)) { | |
| 61 | + if (ses->chans[i].iface == iface) { | |
| 62 | 62 | spin_unlock(&ses->chan_lock); |
| 63 | 63 | return true; |
| 64 | 64 | } |
| @@ -81,6 +81,9 @@ cifs_ses_get_chan_index(struct cifs_ses *ses, · 16 unmodified lines | ||
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | /* If we didn't find the channel, it is likely a bug */ |
| 84 | + if (server) | |
| 85 | + cifs_dbg(VFS, "unable to get chan index for server: 0x%llx", | |
| 86 | + server->conn_id); | |
| 84 | 87 | WARN_ON(1); |
| 85 | 88 | return 0; |
| 86 | 89 | } |
| @@ -143,16 +146,24 @@ cifs_chan_needs_reconnect(struct cifs_ses *ses, · 56 unmodified lines | ||
| 143 | 146 | return CIFS_CHAN_NEEDS_RECONNECT(ses, chan_index); |
| 144 | 147 | } |
| 145 | 148 | |
| 149 | +bool | |
| 150 | +cifs_chan_is_iface_active(struct cifs_ses *ses, | |
| 151 | + struct TCP_Server_Info *server) | |
| 152 | +{ | |
| 153 | + unsigned int chan_index = cifs_ses_get_chan_index(ses, server); | |
| 154 | + | |
| 155 | + return ses->chans[chan_index].iface && | |
| 156 | + ses->chans[chan_index].iface->is_active; | |
| 157 | +} | |
| 158 | + | |
| 146 | 159 | /* returns number of channels added */ |
| 147 | 160 | int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) |
| 148 | 161 | { |
| 149 | 162 | int old_chan_count, new_chan_count; |
| 150 | 163 | int left; |
| 151 | − int i = 0; | |
| 152 | 164 | int rc = 0; |
| 153 | 165 | int tries = 0; |
| 154 | − struct cifs_server_iface *ifaces = NULL; | |
| 155 | − size_t iface_count; | |
| 166 | + struct cifs_server_iface *iface = NULL, *niface = NULL; | |
| 156 | 167 | |
| 157 | 168 | spin_lock(&ses->chan_lock); |
| 158 | 169 | |
| @@ -181,33 +192,17 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) · 22 unmodified lines | ||
| 181 | 192 | } |
| 182 | 193 | spin_unlock(&ses->chan_lock); |
| 183 | 194 | |
| 184 | − /* | |
| 185 | − * Make a copy of the iface list at the time and use that | |
| 186 | − * instead so as to not hold the iface spinlock for opening | |
| 187 | − * channels | |
| 188 | − */ | |
| 189 | − spin_lock(&ses->iface_lock); | |
| 190 | − iface_count = ses->iface_count; | |
| 191 | − if (iface_count <= 0) { | |
| 192 | − spin_unlock(&ses->iface_lock); | |
| 193 | − cifs_dbg(VFS, "no iface list available to open channels\n"); | |
| 194 | − return 0; | |
| 195 | − } | |
| 196 | − ifaces = kmemdup(ses->iface_list, iface_count*sizeof(*ifaces), | |
| 197 | − GFP_ATOMIC); | |
| 198 | − if (!ifaces) { | |
| 199 | − spin_unlock(&ses->iface_lock); | |
| 200 | − return 0; | |
| 201 | − } | |
| 202 | − spin_unlock(&ses->iface_lock); | |
| 203 | − | |
| 204 | 195 | /* |
| 205 | 196 | * Keep connecting to same, fastest, iface for all channels as |
| 206 | 197 | * long as its RSS. Try next fastest one if not RSS or channel |
| 207 | 198 | * creation fails. |
| 208 | 199 | */ |
| 200 | + spin_lock(&ses->iface_lock); | |
| 201 | + iface = list_first_entry(&ses->iface_list, struct cifs_server_iface, | |
| 202 | + iface_head); | |
| 203 | + spin_unlock(&ses->iface_lock); | |
| 204 | + | |
| 209 | 205 | while (left > 0) { |
| 210 | − struct cifs_server_iface *iface; | |
| 211 | 206 | |
| 212 | 207 | tries++; |
| 213 | 208 | if (tries > 3*ses->chan_max) { |
| @@ -216,30 +211,127 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) · 2 unmodified lines | ||
| 216 | 211 | break; |
| 217 | 212 | } |
| 218 | 213 | |
| 219 | − iface = &ifaces[i]; | |
| 220 | − if (is_ses_using_iface(ses, iface) && !iface->rss_capable) { | |
| 221 | − i = (i+1) % iface_count; | |
| 222 | − continue; | |
| 214 | + spin_lock(&ses->iface_lock); | |
| 215 | + if (!ses->iface_count) { | |
| 216 | + spin_unlock(&ses->iface_lock); | |
| 217 | + break; | |
| 223 | 218 | } |
| 224 | 219 | |
| 225 | − rc = cifs_ses_add_channel(cifs_sb, ses, iface); | |
| 226 | − if (rc) { | |
| 227 | − cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n", | |
| 228 | − i, rc); | |
| 229 | − i = (i+1) % iface_count; | |
| 230 | − continue; | |
| 220 | + list_for_each_entry_safe_from(iface, niface, &ses->iface_list, | |
| 221 | + iface_head) { | |
| 222 | + /* skip ifaces that are unusable */ | |
| 223 | + if (!iface->is_active || | |
| 224 | + (is_ses_using_iface(ses, iface) && | |
| 225 | + !iface->rss_capable)) { | |
| 226 | + continue; | |
| 227 | + } | |
| 228 | + | |
| 229 | + /* take ref before unlock */ | |
| 230 | + kref_get(&iface->refcount); | |
| 231 | + | |
| 232 | + spin_unlock(&ses->iface_lock); | |
| 233 | + rc = cifs_ses_add_channel(cifs_sb, ses, iface); | |
| 234 | + spin_lock(&ses->iface_lock); | |
| 235 | + | |
| 236 | + if (rc) { | |
| 237 | + cifs_dbg(VFS, "failed to open extra channel on iface:%pIS rc=%d\n", | |
| 238 | + &iface->sockaddr, | |
| 239 | + rc); | |
| 240 | + kref_put(&iface->refcount, release_iface); | |
| 241 | + continue; | |
| 242 | + } | |
| 243 | + | |
| 244 | + cifs_dbg(FYI, "successfully opened new channel on iface:%pIS\n", | |
| 245 | + &iface->sockaddr); | |
| 246 | + break; | |
| 231 | 247 | } |
| 248 | + spin_unlock(&ses->iface_lock); | |
| 232 | 249 | |
| 233 | − cifs_dbg(FYI, "successfully opened new channel on iface#%d\n", | |
| 234 | − i); | |
| 235 | 250 | left--; |
| 236 | 251 | new_chan_count++; |
| 237 | 252 | } |
| 238 | 253 | |
| 239 | − kfree(ifaces); | |
| 240 | 254 | return new_chan_count - old_chan_count; |
| 241 | 255 | } |
| 242 | 256 | |
| 257 | +/* | |
| 258 | + * update the iface for the channel if necessary. | |
| 259 | + * will return 0 when iface is updated, 1 if removed, 2 otherwise | |
| 260 | + * Must be called with chan_lock held. | |
| 261 | + */ | |
| 262 | +int | |
| 263 | +cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) | |
| 264 | +{ | |
| 265 | + unsigned int chan_index; | |
| 266 | + struct cifs_server_iface *iface = NULL; | |
| 267 | + struct cifs_server_iface *old_iface = NULL; | |
| 268 | + int rc = 0; | |
| 269 | + | |
| 270 | + spin_lock(&ses->chan_lock); | |
| 271 | + chan_index = cifs_ses_get_chan_index(ses, server); | |
| 272 | + if (!chan_index) { | |
| 273 | + spin_unlock(&ses->chan_lock); | |
| 274 | + return 0; | |
| 275 | + } | |
| 276 | + | |
| 277 | + if (ses->chans[chan_index].iface) { | |
| 278 | + old_iface = ses->chans[chan_index].iface; | |
| 279 | + if (old_iface->is_active) { | |
| 280 | + spin_unlock(&ses->chan_lock); | |
| 281 | + return 1; | |
| 282 | + } | |
| 283 | + } | |
| 284 | + spin_unlock(&ses->chan_lock); | |
| 285 | + | |
| 286 | + spin_lock(&ses->iface_lock); | |
| 287 | + /* then look for a new one */ | |
| 288 | + list_for_each_entry(iface, &ses->iface_list, iface_head) { | |
| 289 | + if (!iface->is_active || | |
| 290 | + (is_ses_using_iface(ses, iface) && | |
| 291 | + !iface->rss_capable)) { | |
| 292 | + continue; | |
| 293 | + } | |
| 294 | + kref_get(&iface->refcount); | |
| 295 | + } | |
| 296 | + | |
| 297 | + if (!list_entry_is_head(iface, &ses->iface_list, iface_head)) { | |
| 298 | + rc = 1; | |
| 299 | + iface = NULL; | |
| 300 | + cifs_dbg(FYI, "unable to find a suitable iface\n"); | |
| 301 | + } | |
| 302 | + | |
| 303 | + /* now drop the ref to the current iface */ | |
| 304 | + if (old_iface && iface) { | |
| 305 | + kref_put(&old_iface->refcount, release_iface); | |
| 306 | + cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n", | |
| 307 | + &old_iface->sockaddr, | |
| 308 | + &iface->sockaddr); | |
| 309 | + } else if (old_iface) { | |
| 310 | + kref_put(&old_iface->refcount, release_iface); | |
| 311 | + cifs_dbg(FYI, "releasing ref to iface: %pIS\n", | |
| 312 | + &old_iface->sockaddr); | |
| 313 | + } else { | |
| 314 | + WARN_ON(!iface); | |
| 315 | + cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr); | |
| 316 | + } | |
| 317 | + spin_unlock(&ses->iface_lock); | |
| 318 | + | |
| 319 | + spin_lock(&ses->chan_lock); | |
| 320 | + chan_index = cifs_ses_get_chan_index(ses, server); | |
| 321 | + ses->chans[chan_index].iface = iface; | |
| 322 | + | |
| 323 | + /* No iface is found. if secondary chan, drop connection */ | |
| 324 | + if (!iface && CIFS_SERVER_IS_CHAN(server)) | |
| 325 | + ses->chans[chan_index].server = NULL; | |
| 326 | + | |
| 327 | + spin_unlock(&ses->chan_lock); | |
| 328 | + | |
| 329 | + if (!iface && CIFS_SERVER_IS_CHAN(server)) | |
| 330 | + cifs_put_tcp_session(server, false); | |
| 331 | + | |
| 332 | + return rc; | |
| 333 | +} | |
| 334 | + | |
| 243 | 335 | /* |
| 244 | 336 | * If server is a channel of ses, return the corresponding enclosing |
| 245 | 337 | * cifs_chan otherwise return NULL. |
| @@ -352,6 +444,7 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, · 106 unmodified lines | ||
| 352 | 444 | spin_unlock(&ses->chan_lock); |
| 353 | 445 | goto out; |
| 354 | 446 | } |
| 447 | + chan->iface = iface; | |
| 355 | 448 | ses->chan_count++; |
| 356 | 449 | atomic_set(&ses->chan_seq, 0); |
| 357 | 450 | |
| @@ -512,73 +512,41 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) · 511 unmodified lines | ||
| 512 | 512 | static int |
| 513 | 513 | parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, |
| 514 | 514 | size_t buf_len, |
| 515 | − struct cifs_server_iface **iface_list, | |
| 516 | − size_t *iface_count) | |
| 515 | + struct cifs_ses *ses) | |
| 517 | 516 | { |
| 518 | 517 | struct network_interface_info_ioctl_rsp *p; |
| 519 | 518 | struct sockaddr_in *addr4; |
| 520 | 519 | struct sockaddr_in6 *addr6; |
| 521 | 520 | struct iface_info_ipv4 *p4; |
| 522 | 521 | struct iface_info_ipv6 *p6; |
| 523 | − struct cifs_server_iface *info; | |
| 522 | + struct cifs_server_iface *info = NULL, *iface = NULL, *niface = NULL; | |
| 523 | + struct cifs_server_iface tmp_iface; | |
| 524 | 524 | ssize_t bytes_left; |
| 525 | 525 | size_t next = 0; |
| 526 | 526 | int nb_iface = 0; |
| 527 | − int rc = 0; | |
| 528 | − | |
| 529 | − *iface_list = NULL; | |
| 530 | − *iface_count = 0; | |
| 531 | − | |
| 532 | − /* | |
| 533 | − * Fist pass: count and sanity check | |
| 534 | − */ | |
| 527 | + int rc = 0, ret = 0; | |
| 535 | 528 | |
| 536 | 529 | bytes_left = buf_len; |
| 537 | 530 | p = buf; |
| 538 | − while (bytes_left >= sizeof(*p)) { | |
| 539 | − nb_iface++; | |
| 540 | − next = le32_to_cpu(p->Next); | |
| 541 | − if (!next) { | |
| 542 | − bytes_left -= sizeof(*p); | |
| 543 | − break; | |
| 544 | − } | |
| 545 | − p = (struct network_interface_info_ioctl_rsp *)((u8 *)p+next); | |
| 546 | − bytes_left -= next; | |
| 547 | − } | |
| 548 | − | |
| 549 | − if (!nb_iface) { | |
| 550 | − cifs_dbg(VFS, "%s: malformed interface info\n", __func__); | |
| 551 | − rc = -EINVAL; | |
| 552 | − goto out; | |
| 553 | − } | |
| 554 | − | |
| 555 | − /* Azure rounds the buffer size up 8, to a 16 byte boundary */ | |
| 556 | − if ((bytes_left > 8) || p->Next) | |
| 557 | − cifs_dbg(VFS, "%s: incomplete interface info\n", __func__); | |
| 558 | − | |
| 559 | 531 | |
| 532 | + spin_lock(&ses->iface_lock); | |
| 560 | 533 | /* |
| 561 | − * Second pass: extract info to internal structure | |
| 534 | + * Go through iface_list and do kref_put to remove | |
| 535 | + * any unused ifaces. ifaces in use will be removed | |
| 536 | + * when the last user calls a kref_put on it | |
| 562 | 537 | */ |
| 563 | − | |
| 564 | − *iface_list = kcalloc(nb_iface, sizeof(**iface_list), GFP_KERNEL); | |
| 565 | − if (!*iface_list) { | |
| 566 | − rc = -ENOMEM; | |
| 567 | − goto out; | |
| 538 | + list_for_each_entry_safe(iface, niface, &ses->iface_list, | |
| 539 | + iface_head) { | |
| 540 | + iface->is_active = 0; | |
| 541 | + kref_put(&iface->refcount, release_iface); | |
| 568 | 542 | } |
| 543 | + spin_unlock(&ses->iface_lock); | |
| 569 | 544 | |
| 570 | − info = *iface_list; | |
| 571 | − bytes_left = buf_len; | |
| 572 | − p = buf; | |
| 573 | 545 | while (bytes_left >= sizeof(*p)) { |
| 574 | − info->speed = le64_to_cpu(p->LinkSpeed); | |
| 575 | − info->rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0; | |
| 576 | − info->rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0; | |
| 577 | − | |
| 578 | − cifs_dbg(FYI, "%s: adding iface %zu\n", __func__, *iface_count); | |
| 579 | − cifs_dbg(FYI, "%s: speed %zu bps\n", __func__, info->speed); | |
| 580 | − cifs_dbg(FYI, "%s: capabilities 0x%08x\n", __func__, | |
| 581 | − le32_to_cpu(p->Capability)); | |
| 546 | + memset(&tmp_iface, 0, sizeof(tmp_iface)); | |
| 547 | + tmp_iface.speed = le64_to_cpu(p->LinkSpeed); | |
| 548 | + tmp_iface.rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0; | |
| 549 | + tmp_iface.rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0; | |
| 582 | 550 | |
| 583 | 551 | switch (p->Family) { |
| 584 | 552 | /* |
| @@ -587,7 +555,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, · 2 unmodified lines | ||
| 587 | 555 | * conversion explicit in case either one changes. |
| 588 | 556 | */ |
| 589 | 557 | case INTERNETWORK: |
| 590 | − addr4 = (struct sockaddr_in *)&info->sockaddr; | |
| 558 | + addr4 = (struct sockaddr_in *)&tmp_iface.sockaddr; | |
| 591 | 559 | p4 = (struct iface_info_ipv4 *)p->Buffer; |
| 592 | 560 | addr4->sin_family = AF_INET; |
| 593 | 561 | memcpy(&addr4->sin_addr, &p4->IPv4Address, 4); |
| @@ -599,7 +567,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, · 5 unmodified lines | ||
| 599 | 567 | &addr4->sin_addr); |
| 600 | 568 | break; |
| 601 | 569 | case INTERNETWORKV6: |
| 602 | − addr6 = (struct sockaddr_in6 *)&info->sockaddr; | |
| 570 | + addr6 = (struct sockaddr_in6 *)&tmp_iface.sockaddr; | |
| 603 | 571 | p6 = (struct iface_info_ipv6 *)p->Buffer; |
| 604 | 572 | addr6->sin6_family = AF_INET6; |
| 605 | 573 | memcpy(&addr6->sin6_addr, &p6->IPv6Address, 16); |
| @@ -619,46 +587,96 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, · 13 unmodified lines | ||
| 619 | 587 | goto next_iface; |
| 620 | 588 | } |
| 621 | 589 | |
| 622 | − (*iface_count)++; | |
| 623 | − info++; | |
| 590 | + /* | |
| 591 | + * The iface_list is assumed to be sorted by speed. | |
| 592 | + * Check if the new interface exists in that list. | |
| 593 | + * NEVER change iface. it could be in use. | |
| 594 | + * Add a new one instead | |
| 595 | + */ | |
| 596 | + spin_lock(&ses->iface_lock); | |
| 597 | + iface = niface = NULL; | |
| 598 | + list_for_each_entry_safe(iface, niface, &ses->iface_list, | |
| 599 | + iface_head) { | |
| 600 | + ret = iface_cmp(iface, &tmp_iface); | |
| 601 | + if (!ret) { | |
| 602 | + /* just get a ref so that it doesn't get picked/freed */ | |
| 603 | + iface->is_active = 1; | |
| 604 | + kref_get(&iface->refcount); | |
| 605 | + spin_unlock(&ses->iface_lock); | |
| 606 | + goto next_iface; | |
| 607 | + } else if (ret < 0) { | |
| 608 | + /* all remaining ifaces are slower */ | |
| 609 | + kref_get(&iface->refcount); | |
| 610 | + break; | |
| 611 | + } | |
| 612 | + } | |
| 613 | + spin_unlock(&ses->iface_lock); | |
| 614 | + | |
| 615 | + /* no match. insert the entry in the list */ | |
| 616 | + info = kmalloc(sizeof(struct cifs_server_iface), | |
| 617 | + GFP_KERNEL); | |
| 618 | + if (!info) { | |
| 619 | + rc = -ENOMEM; | |
| 620 | + goto out; | |
| 621 | + } | |
| 622 | + memcpy(info, &tmp_iface, sizeof(tmp_iface)); | |
| 623 | + | |
| 624 | + /* add this new entry to the list */ | |
| 625 | + kref_init(&info->refcount); | |
| 626 | + info->is_active = 1; | |
| 627 | + | |
| 628 | + cifs_dbg(FYI, "%s: adding iface %zu\n", __func__, ses->iface_count); | |
| 629 | + cifs_dbg(FYI, "%s: speed %zu bps\n", __func__, info->speed); | |
| 630 | + cifs_dbg(FYI, "%s: capabilities 0x%08x\n", __func__, | |
| 631 | + le32_to_cpu(p->Capability)); | |
| 632 | + | |
| 633 | + spin_lock(&ses->iface_lock); | |
| 634 | + if (!list_entry_is_head(iface, &ses->iface_list, iface_head)) { | |
| 635 | + list_add_tail(&info->iface_head, &iface->iface_head); | |
| 636 | + kref_put(&iface->refcount, release_iface); | |
| 637 | + } else | |
| 638 | + list_add_tail(&info->iface_head, &ses->iface_list); | |
| 639 | + spin_unlock(&ses->iface_lock); | |
| 640 | + | |
| 641 | + ses->iface_count++; | |
| 642 | + ses->iface_last_update = jiffies; | |
| 624 | 643 | next_iface: |
| 644 | + nb_iface++; | |
| 625 | 645 | next = le32_to_cpu(p->Next); |
| 626 | − if (!next) | |
| 646 | + if (!next) { | |
| 647 | + bytes_left -= sizeof(*p); | |
| 627 | 648 | break; |
| 649 | + } | |
| 628 | 650 | p = (struct network_interface_info_ioctl_rsp *)((u8 *)p+next); |
| 629 | 651 | bytes_left -= next; |
| 630 | 652 | } |
| 631 | 653 | |
| 632 | − if (!*iface_count) { | |
| 654 | + if (!nb_iface) { | |
| 655 | + cifs_dbg(VFS, "%s: malformed interface info\n", __func__); | |
| 633 | 656 | rc = -EINVAL; |
| 634 | 657 | goto out; |
| 635 | 658 | } |
| 636 | 659 | |
| 637 | −out: | |
| 638 | − if (rc) { | |
| 639 | − kfree(*iface_list); | |
| 640 | − *iface_count = 0; | |
| 641 | − *iface_list = NULL; | |
| 642 | − } | |
| 643 | − return rc; | |
| 644 | −} | |
| 660 | + /* Azure rounds the buffer size up 8, to a 16 byte boundary */ | |
| 661 | + if ((bytes_left > 8) || p->Next) | |
| 662 | + cifs_dbg(VFS, "%s: incomplete interface info\n", __func__); | |
| 645 | 663 | |
| 646 | −static int compare_iface(const void *ia, const void *ib) | |
| 647 | −{ | |
| 648 | − const struct cifs_server_iface *a = (struct cifs_server_iface *)ia; | |
| 649 | − const struct cifs_server_iface *b = (struct cifs_server_iface *)ib; | |
| 650 | 664 | |
| 651 | − return a->speed == b->speed ? 0 : (a->speed > b->speed ? -1 : 1); | |
| 665 | + if (!ses->iface_count) { | |
| 666 | + rc = -EINVAL; | |
| 667 | + goto out; | |
| 668 | + } | |
| 669 | + | |
| 670 | +out: | |
| 671 | + return rc; | |
| 652 | 672 | } |
| 653 | 673 | |
| 654 | −static int | |
| 674 | +int | |
| 655 | 675 | SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) |
| 656 | 676 | { |
| 657 | 677 | int rc; |
| 658 | 678 | unsigned int ret_data_len = 0; |
| 659 | 679 | struct network_interface_info_ioctl_rsp *out_buf = NULL; |
| 660 | − struct cifs_server_iface *iface_list; | |
| 661 | − size_t iface_count; | |
| 662 | 680 | struct cifs_ses *ses = tcon->ses; |
| 663 | 681 | |
| 664 | 682 | rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, |
| @@ -674,21 +692,10 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) · 9 unmodified lines | ||
| 674 | 692 | goto out; |
| 675 | 693 | } |
| 676 | 694 | |
| 677 | − rc = parse_server_interfaces(out_buf, ret_data_len, | |
| 678 | − &iface_list, &iface_count); | |
| 695 | + rc = parse_server_interfaces(out_buf, ret_data_len, ses); | |
| 679 | 696 | if (rc) |
| 680 | 697 | goto out; |
| 681 | 698 | |
| 682 | − /* sort interfaces from fastest to slowest */ | |
| 683 | − sort(iface_list, iface_count, sizeof(*iface_list), compare_iface, NULL); | |
| 684 | − | |
| 685 | − spin_lock(&ses->iface_lock); | |
| 686 | − kfree(ses->iface_list); | |
| 687 | − ses->iface_list = iface_list; | |
| 688 | − ses->iface_count = iface_count; | |
| 689 | − ses->iface_last_update = jiffies; | |
| 690 | − spin_unlock(&ses->iface_lock); | |
| 691 | − | |
| 692 | 699 | out: |
| 693 | 700 | kfree(out_buf); |
| 694 | 701 | return rc; |
| @@ -543,6 +543,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 542 unmodified lines | ||
| 543 | 543 | struct TCP_Server_Info *server, unsigned int *total_len) |
| 544 | 544 | { |
| 545 | 545 | char *pneg_ctxt; |
| 546 | + char *hostname = NULL; | |
| 546 | 547 | unsigned int ctxt_len, neg_context_count; |
| 547 | 548 | |
| 548 | 549 | if (*total_len > 200) { |
| @@ -570,16 +571,24 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 21 unmodified lines | ||
| 570 | 571 | *total_len += ctxt_len; |
| 571 | 572 | pneg_ctxt += ctxt_len; |
| 572 | 573 | |
| 573 | − ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt, | |
| 574 | − server->hostname); | |
| 575 | − *total_len += ctxt_len; | |
| 576 | − pneg_ctxt += ctxt_len; | |
| 577 | − | |
| 578 | 574 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); |
| 579 | 575 | *total_len += sizeof(struct smb2_posix_neg_context); |
| 580 | 576 | pneg_ctxt += sizeof(struct smb2_posix_neg_context); |
| 581 | 577 | |
| 582 | − neg_context_count = 4; | |
| 578 | + /* | |
| 579 | + * secondary channels don't have the hostname field populated | |
| 580 | + * use the hostname field in the primary channel instead | |
| 581 | + */ | |
| 582 | + hostname = CIFS_SERVER_IS_CHAN(server) ? | |
| 583 | + server->primary_server->hostname : server->hostname; | |
| 584 | + if (hostname && (hostname[0] != 0)) { | |
| 585 | + ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt, | |
| 586 | + hostname); | |
| 587 | + *total_len += ctxt_len; | |
| 588 | + pneg_ctxt += ctxt_len; | |
| 589 | + neg_context_count = 4; | |
| 590 | + } else /* second channels do not have a hostname */ | |
| 591 | + neg_context_count = 3; | |
| 583 | 592 | |
| 584 | 593 | if (server->compress_algorithm) { |
| 585 | 594 | build_compression_ctxt((struct smb2_compression_capabilities_context *) |
| @@ -5154,6 +5163,8 @@ SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, · 4568 unmodified lines | ||
| 5154 | 5163 | data = &info; |
| 5155 | 5164 | size = sizeof(struct smb2_file_eof_info); |
| 5156 | 5165 | |
| 5166 | + trace_smb3_set_eof(xid, persistent_fid, tcon->tid, tcon->ses->Suid, le64_to_cpu(*eof)); | |
| 5167 | + | |
| 5157 | 5168 | return send_set_info(xid, tcon, persistent_fid, volatile_fid, |
| 5158 | 5169 | pid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE, |
| 5159 | 5170 | 0, 1, &data, &size); |
| @@ -121,6 +121,44 @@ DEFINE_SMB3_RW_DONE_EVENT(query_dir_done); · 120 unmodified lines | ||
| 121 | 121 | DEFINE_SMB3_RW_DONE_EVENT(zero_done); |
| 122 | 122 | DEFINE_SMB3_RW_DONE_EVENT(falloc_done); |
| 123 | 123 | |
| 124 | +/* For logging successful set EOF (truncate) */ | |
| 125 | +DECLARE_EVENT_CLASS(smb3_eof_class, | |
| 126 | + TP_PROTO(unsigned int xid, | |
| 127 | + __u64 fid, | |
| 128 | + __u32 tid, | |
| 129 | + __u64 sesid, | |
| 130 | + __u64 offset), | |
| 131 | + TP_ARGS(xid, fid, tid, sesid, offset), | |
| 132 | + TP_STRUCT__entry( | |
| 133 | + __field(unsigned int, xid) | |
| 134 | + __field(__u64, fid) | |
| 135 | + __field(__u32, tid) | |
| 136 | + __field(__u64, sesid) | |
| 137 | + __field(__u64, offset) | |
| 138 | + ), | |
| 139 | + TP_fast_assign( | |
| 140 | + __entry->xid = xid; | |
| 141 | + __entry->fid = fid; | |
| 142 | + __entry->tid = tid; | |
| 143 | + __entry->sesid = sesid; | |
| 144 | + __entry->offset = offset; | |
| 145 | + ), | |
| 146 | + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx", | |
| 147 | + __entry->xid, __entry->sesid, __entry->tid, __entry->fid, | |
| 148 | + __entry->offset) | |
| 149 | +) | |
| 150 | + | |
| 151 | +#define DEFINE_SMB3_EOF_EVENT(name) \ | |
| 152 | +DEFINE_EVENT(smb3_eof_class, smb3_##name, \ | |
| 153 | + TP_PROTO(unsigned int xid, \ | |
| 154 | + __u64 fid, \ | |
| 155 | + __u32 tid, \ | |
| 156 | + __u64 sesid, \ | |
| 157 | + __u64 offset), \ | |
| 158 | + TP_ARGS(xid, fid, tid, sesid, offset)) | |
| 159 | + | |
| 160 | +DEFINE_SMB3_EOF_EVENT(set_eof); | |
| 161 | + | |
| 124 | 162 | /* |
| 125 | 163 | * For handle based calls other than read and write, and get/set info |
| 126 | 164 | */ |
| @@ -1198,7 +1198,9 @@ static int __exfat_rename(struct inode *old_parent_inode, · 1197 unmodified lines | ||
| 1198 | 1198 | return -ENOENT; |
| 1199 | 1199 | } |
| 1200 | 1200 | |
| 1201 | − exfat_chain_dup(&olddir, &ei->dir); | |
| 1201 | + exfat_chain_set(&olddir, EXFAT_I(old_parent_inode)->start_clu, | |
| 1202 | + EXFAT_B_TO_CLU_ROUND_UP(i_size_read(old_parent_inode), sbi), | |
| 1203 | + EXFAT_I(old_parent_inode)->flags); | |
| 1202 | 1204 | dentry = ei->entry; |
| 1203 | 1205 | |
| 1204 | 1206 | ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh); |
| @@ -672,17 +672,14 @@ int ext2_empty_dir (struct inode * inode) · 671 unmodified lines | ||
| 672 | 672 | void *page_addr = NULL; |
| 673 | 673 | struct page *page = NULL; |
| 674 | 674 | unsigned long i, npages = dir_pages(inode); |
| 675 | − int dir_has_error = 0; | |
| 676 | 675 | |
| 677 | 676 | for (i = 0; i < npages; i++) { |
| 678 | 677 | char *kaddr; |
| 679 | 678 | ext2_dirent * de; |
| 680 | − page = ext2_get_page(inode, i, dir_has_error, &page_addr); | |
| 679 | + page = ext2_get_page(inode, i, 0, &page_addr); | |
| 681 | 680 | |
| 682 | − if (IS_ERR(page)) { | |
| 683 | − dir_has_error = 1; | |
| 684 | − continue; | |
| 685 | − } | |
| 681 | + if (IS_ERR(page)) | |
| 682 | + goto not_empty; | |
| 686 | 683 | |
| 687 | 684 | kaddr = page_addr; |
| 688 | 685 | de = (ext2_dirent *)kaddr; |
| @@ -829,7 +829,7 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, · 828 unmodified lines | ||
| 829 | 829 | ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n", |
| 830 | 830 | inode->i_ino, create); |
| 831 | 831 | return _ext4_get_block(inode, iblock, bh_result, |
| 832 | − EXT4_GET_BLOCKS_IO_CREATE_EXT); | |
| 832 | + EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT); | |
| 833 | 833 | } |
| 834 | 834 | |
| 835 | 835 | /* Maximum number of blocks we map for direct IO at once. */ |
| @@ -4104,6 +4104,15 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, · 4103 unmodified lines | ||
| 4104 | 4104 | size = size >> bsbits; |
| 4105 | 4105 | start = start_off >> bsbits; |
| 4106 | 4106 | |
| 4107 | + /* | |
| 4108 | + * For tiny groups (smaller than 8MB) the chosen allocation | |
| 4109 | + * alignment may be larger than group size. Make sure the | |
| 4110 | + * alignment does not move allocation to a different group which | |
| 4111 | + * makes mballoc fail assertions later. | |
| 4112 | + */ | |
| 4113 | + start = max(start, rounddown(ac->ac_o_ex.fe_logical, | |
| 4114 | + (ext4_lblk_t)EXT4_BLOCKS_PER_GROUP(ac->ac_sb))); | |
| 4115 | + | |
| 4107 | 4116 | /* don't cover already allocated blocks in selected range */ |
| 4108 | 4117 | if (ar->pleft && start <= ar->lleft) { |
| 4109 | 4118 | size -= ar->lleft + 1 - start; |
| @@ -4176,7 +4185,22 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, · 66 unmodified lines | ||
| 4176 | 4185 | } |
| 4177 | 4186 | rcu_read_unlock(); |
| 4178 | 4187 | |
| 4179 | − if (start + size <= ac->ac_o_ex.fe_logical && | |
| 4188 | + /* | |
| 4189 | + * In this function "start" and "size" are normalized for better | |
| 4190 | + * alignment and length such that we could preallocate more blocks. | |
| 4191 | + * This normalization is done such that original request of | |
| 4192 | + * ac->ac_o_ex.fe_logical & fe_len should always lie within "start" and | |
| 4193 | + * "size" boundaries. | |
| 4194 | + * (Note fe_len can be relaxed since FS block allocation API does not | |
| 4195 | + * provide gurantee on number of contiguous blocks allocation since that | |
| 4196 | + * depends upon free space left, etc). | |
| 4197 | + * In case of inode pa, later we use the allocated blocks | |
| 4198 | + * [pa_start + fe_logical - pa_lstart, fe_len/size] from the preallocated | |
| 4199 | + * range of goal/best blocks [start, size] to put it at the | |
| 4200 | + * ac_o_ex.fe_logical extent of this inode. | |
| 4201 | + * (See ext4_mb_use_inode_pa() for more details) | |
| 4202 | + */ | |
| 4203 | + if (start + size <= ac->ac_o_ex.fe_logical || | |
| 4180 | 4204 | start > ac->ac_o_ex.fe_logical) { |
| 4181 | 4205 | ext4_msg(ac->ac_sb, KERN_ERR, |
| 4182 | 4206 | "start %lu, size %lu, fe_logical %lu", |
| @@ -438,7 +438,7 @@ int ext4_ext_migrate(struct inode *inode) · 437 unmodified lines | ||
| 438 | 438 | |
| 439 | 439 | /* |
| 440 | 440 | * Worst case we can touch the allocation bitmaps and a block |
| 441 | − * group descriptor block. We do need need to worry about | |
| 441 | + * group descriptor block. We do need to worry about | |
| 442 | 442 | * credits for modifying the quota inode. |
| 443 | 443 | */ |
| 444 | 444 | handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, |
| @@ -1929,7 +1929,8 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, · 1928 unmodified lines | ||
| 1929 | 1929 | struct dx_hash_info *hinfo) |
| 1930 | 1930 | { |
| 1931 | 1931 | unsigned blocksize = dir->i_sb->s_blocksize; |
| 1932 | − unsigned count, continued; | |
| 1932 | + unsigned continued; | |
| 1933 | + int count; | |
| 1933 | 1934 | struct buffer_head *bh2; |
| 1934 | 1935 | ext4_lblk_t newblock; |
| 1935 | 1936 | u32 hash2; |
| @@ -465,7 +465,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, · 464 unmodified lines | ||
| 465 | 465 | /* |
| 466 | 466 | * In the first loop we prepare and mark buffers to submit. We have to |
| 467 | 467 | * mark all buffers in the page before submitting so that |
| 468 | − * end_page_writeback() cannot be called from ext4_bio_end_io() when IO | |
| 468 | + * end_page_writeback() cannot be called from ext4_end_bio() when IO | |
| 469 | 469 | * on the first buffer finishes and we are still working on submitting |
| 470 | 470 | * the second buffer. |
| 471 | 471 | */ |
| @@ -53,6 +53,16 @@ int ext4_resize_begin(struct super_block *sb) · 52 unmodified lines | ||
| 53 | 53 | if (!capable(CAP_SYS_RESOURCE)) |
| 54 | 54 | return -EPERM; |
| 55 | 55 | |
| 56 | + /* | |
| 57 | + * If the reserved GDT blocks is non-zero, the resize_inode feature | |
| 58 | + * should always be set. | |
| 59 | + */ | |
| 60 | + if (EXT4_SB(sb)->s_es->s_reserved_gdt_blocks && | |
| 61 | + !ext4_has_feature_resize_inode(sb)) { | |
| 62 | + ext4_error(sb, "resize_inode disabled but reserved GDT blocks non-zero"); | |
| 63 | + return -EFSCORRUPTED; | |
| 64 | + } | |
| 65 | + | |
| 56 | 66 | /* |
| 57 | 67 | * If we are not using the primary superblock/GDT copy don't resize, |
| 58 | 68 | * because the user tools have no way of handling this. Probably a |
| @@ -87,7 +87,7 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb, · 86 unmodified lines | ||
| 87 | 87 | static int ext4_validate_options(struct fs_context *fc); |
| 88 | 88 | static int ext4_check_opt_consistency(struct fs_context *fc, |
| 89 | 89 | struct super_block *sb); |
| 90 | −static int ext4_apply_options(struct fs_context *fc, struct super_block *sb); | |
| 90 | +static void ext4_apply_options(struct fs_context *fc, struct super_block *sb); | |
| 91 | 91 | static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param); |
| 92 | 92 | static int ext4_get_tree(struct fs_context *fc); |
| 93 | 93 | static int ext4_reconfigure(struct fs_context *fc); |
| @@ -1870,31 +1870,12 @@ ext4_sb_read_encoding(const struct ext4_super_block *es) · 1776 unmodified lines | ||
| 1870 | 1870 | } |
| 1871 | 1871 | #endif |
| 1872 | 1872 | |
| 1873 | −static int ext4_set_test_dummy_encryption(struct super_block *sb, char *arg) | |
| 1874 | −{ | |
| 1875 | −#ifdef CONFIG_FS_ENCRYPTION | |
| 1876 | − struct ext4_sb_info *sbi = EXT4_SB(sb); | |
| 1877 | − int err; | |
| 1878 | − | |
| 1879 | − err = fscrypt_set_test_dummy_encryption(sb, arg, | |
| 1880 | − &sbi->s_dummy_enc_policy); | |
| 1881 | − if (err) { | |
| 1882 | − ext4_msg(sb, KERN_WARNING, | |
| 1883 | − "Error while setting test dummy encryption [%d]", err); | |
| 1884 | − return err; | |
| 1885 | − } | |
| 1886 | − ext4_msg(sb, KERN_WARNING, "Test dummy encryption mode enabled"); | |
| 1887 | −#endif | |
| 1888 | − return 0; | |
| 1889 | −} | |
| 1890 | − | |
| 1891 | 1873 | #define EXT4_SPEC_JQUOTA (1 << 0) |
| 1892 | 1874 | #define EXT4_SPEC_JQFMT (1 << 1) |
| 1893 | 1875 | #define EXT4_SPEC_DATAJ (1 << 2) |
| 1894 | 1876 | #define EXT4_SPEC_SB_BLOCK (1 << 3) |
| 1895 | 1877 | #define EXT4_SPEC_JOURNAL_DEV (1 << 4) |
| 1896 | 1878 | #define EXT4_SPEC_JOURNAL_IOPRIO (1 << 5) |
| 1897 | −#define EXT4_SPEC_DUMMY_ENCRYPTION (1 << 6) | |
| 1898 | 1879 | #define EXT4_SPEC_s_want_extra_isize (1 << 7) |
| 1899 | 1880 | #define EXT4_SPEC_s_max_batch_time (1 << 8) |
| 1900 | 1881 | #define EXT4_SPEC_s_min_batch_time (1 << 9) |
| @@ -1911,7 +1892,7 @@ static int ext4_set_test_dummy_encryption(struct super_block *sb, char *arg) · 10 unmodified lines | ||
| 1911 | 1892 | |
| 1912 | 1893 | struct ext4_fs_context { |
| 1913 | 1894 | char *s_qf_names[EXT4_MAXQUOTAS]; |
| 1914 | − char *test_dummy_enc_arg; | |
| 1895 | + struct fscrypt_dummy_policy dummy_enc_policy; | |
| 1915 | 1896 | int s_jquota_fmt; /* Format of quota to use */ |
| 1916 | 1897 | #ifdef CONFIG_EXT4_DEBUG |
| 1917 | 1898 | int s_fc_debug_max_replay; |
| @@ -1953,7 +1934,7 @@ static void ext4_fc_free(struct fs_context *fc) · 35 unmodified lines | ||
| 1953 | 1934 | for (i = 0; i < EXT4_MAXQUOTAS; i++) |
| 1954 | 1935 | kfree(ctx->s_qf_names[i]); |
| 1955 | 1936 | |
| 1956 | − kfree(ctx->test_dummy_enc_arg); | |
| 1937 | + fscrypt_free_dummy_policy(&ctx->dummy_enc_policy); | |
| 1957 | 1938 | kfree(ctx); |
| 1958 | 1939 | } |
| 1959 | 1940 | |
| @@ -2029,6 +2010,29 @@ static int unnote_qf_name(struct fs_context *fc, int qtype) · 69 unmodified lines | ||
| 2029 | 2010 | } |
| 2030 | 2011 | #endif |
| 2031 | 2012 | |
| 2013 | +static int ext4_parse_test_dummy_encryption(const struct fs_parameter *param, | |
| 2014 | + struct ext4_fs_context *ctx) | |
| 2015 | +{ | |
| 2016 | + int err; | |
| 2017 | + | |
| 2018 | + if (!IS_ENABLED(CONFIG_FS_ENCRYPTION)) { | |
| 2019 | + ext4_msg(NULL, KERN_WARNING, | |
| 2020 | + "test_dummy_encryption option not supported"); | |
| 2021 | + return -EINVAL; | |
| 2022 | + } | |
| 2023 | + err = fscrypt_parse_test_dummy_encryption(param, | |
| 2024 | + &ctx->dummy_enc_policy); | |
| 2025 | + if (err == -EINVAL) { | |
| 2026 | + ext4_msg(NULL, KERN_WARNING, | |
| 2027 | + "Value of option \"%s\" is unrecognized", param->key); | |
| 2028 | + } else if (err == -EEXIST) { | |
| 2029 | + ext4_msg(NULL, KERN_WARNING, | |
| 2030 | + "Conflicting test_dummy_encryption options"); | |
| 2031 | + return -EINVAL; | |
| 2032 | + } | |
| 2033 | + return err; | |
| 2034 | +} | |
| 2035 | + | |
| 2032 | 2036 | #define EXT4_SET_CTX(name) \ |
| 2033 | 2037 | static inline void ctx_set_##name(struct ext4_fs_context *ctx, \ |
| 2034 | 2038 | unsigned long flag) \ |
| @@ -2291,29 +2295,7 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param) · 256 unmodified lines | ||
| 2291 | 2295 | ctx->spec |= EXT4_SPEC_JOURNAL_IOPRIO; |
| 2292 | 2296 | return 0; |
| 2293 | 2297 | case Opt_test_dummy_encryption: |
| 2294 | −#ifdef CONFIG_FS_ENCRYPTION | |
| 2295 | − if (param->type == fs_value_is_flag) { | |
| 2296 | − ctx->spec |= EXT4_SPEC_DUMMY_ENCRYPTION; | |
| 2297 | − ctx->test_dummy_enc_arg = NULL; | |
| 2298 | − return 0; | |
| 2299 | − } | |
| 2300 | − if (*param->string && | |
| 2301 | − !(!strcmp(param->string, "v1") || | |
| 2302 | − !strcmp(param->string, "v2"))) { | |
| 2303 | − ext4_msg(NULL, KERN_WARNING, | |
| 2304 | − "Value of option \"%s\" is unrecognized", | |
| 2305 | − param->key); | |
| 2306 | − return -EINVAL; | |
| 2307 | − } | |
| 2308 | − ctx->spec |= EXT4_SPEC_DUMMY_ENCRYPTION; | |
| 2309 | − ctx->test_dummy_enc_arg = kmemdup_nul(param->string, param->size, | |
| 2310 | − GFP_KERNEL); | |
| 2311 | − return 0; | |
| 2312 | −#else | |
| 2313 | − ext4_msg(NULL, KERN_WARNING, | |
| 2314 | − "test_dummy_encryption option not supported"); | |
| 2315 | − return -EINVAL; | |
| 2316 | −#endif | |
| 2298 | + return ext4_parse_test_dummy_encryption(param, ctx); | |
| 2317 | 2299 | case Opt_dax: |
| 2318 | 2300 | case Opt_dax_type: |
| 2319 | 2301 | #ifdef CONFIG_FS_DAX |
| @@ -2504,7 +2486,8 @@ parse_failed: · 184 unmodified lines | ||
| 2504 | 2486 | if (s_ctx->spec & EXT4_SPEC_JOURNAL_IOPRIO) |
| 2505 | 2487 | m_ctx->journal_ioprio = s_ctx->journal_ioprio; |
| 2506 | 2488 | |
| 2507 | − ret = ext4_apply_options(fc, sb); | |
| 2489 | + ext4_apply_options(fc, sb); | |
| 2490 | + ret = 0; | |
| 2508 | 2491 | |
| 2509 | 2492 | out_free: |
| 2510 | 2493 | if (fc) { |
| @@ -2673,11 +2656,11 @@ err_jquota_specified: · 162 unmodified lines | ||
| 2673 | 2656 | static int ext4_check_test_dummy_encryption(const struct fs_context *fc, |
| 2674 | 2657 | struct super_block *sb) |
| 2675 | 2658 | { |
| 2676 | −#ifdef CONFIG_FS_ENCRYPTION | |
| 2677 | 2659 | const struct ext4_fs_context *ctx = fc->fs_private; |
| 2678 | 2660 | const struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 2661 | + int err; | |
| 2679 | 2662 | |
| 2680 | − if (!(ctx->spec & EXT4_SPEC_DUMMY_ENCRYPTION)) | |
| 2663 | + if (!fscrypt_is_dummy_policy_set(&ctx->dummy_enc_policy)) | |
| 2681 | 2664 | return 0; |
| 2682 | 2665 | |
| 2683 | 2666 | if (!ext4_has_feature_encrypt(sb)) { |
| @@ -2691,14 +2674,46 @@ static int ext4_check_test_dummy_encryption(const struct fs_context *fc, · 7 unmodified lines | ||
| 2691 | 2674 | * needed to allow it to be set or changed during remount. We do allow |
| 2692 | 2675 | * it to be specified during remount, but only if there is no change. |
| 2693 | 2676 | */ |
| 2694 | − if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE && | |
| 2695 | − !sbi->s_dummy_enc_policy.policy) { | |
| 2677 | + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { | |
| 2678 | + if (fscrypt_dummy_policies_equal(&sbi->s_dummy_enc_policy, | |
| 2679 | + &ctx->dummy_enc_policy)) | |
| 2680 | + return 0; | |
| 2696 | 2681 | ext4_msg(NULL, KERN_WARNING, |
| 2697 | − "Can't set test_dummy_encryption on remount"); | |
| 2682 | + "Can't set or change test_dummy_encryption on remount"); | |
| 2698 | 2683 | return -EINVAL; |
| 2699 | 2684 | } |
| 2700 | −#endif /* CONFIG_FS_ENCRYPTION */ | |
| 2701 | − return 0; | |
| 2685 | + /* Also make sure s_mount_opts didn't contain a conflicting value. */ | |
| 2686 | + if (fscrypt_is_dummy_policy_set(&sbi->s_dummy_enc_policy)) { | |
| 2687 | + if (fscrypt_dummy_policies_equal(&sbi->s_dummy_enc_policy, | |
| 2688 | + &ctx->dummy_enc_policy)) | |
| 2689 | + return 0; | |
| 2690 | + ext4_msg(NULL, KERN_WARNING, | |
| 2691 | + "Conflicting test_dummy_encryption options"); | |
| 2692 | + return -EINVAL; | |
| 2693 | + } | |
| 2694 | + /* | |
| 2695 | + * fscrypt_add_test_dummy_key() technically changes the super_block, so | |
| 2696 | + * technically it should be delayed until ext4_apply_options() like the | |
| 2697 | + * other changes. But since we never get here for remounts (see above), | |
| 2698 | + * and this is the last chance to report errors, we do it here. | |
| 2699 | + */ | |
| 2700 | + err = fscrypt_add_test_dummy_key(sb, &ctx->dummy_enc_policy); | |
| 2701 | + if (err) | |
| 2702 | + ext4_msg(NULL, KERN_WARNING, | |
| 2703 | + "Error adding test dummy encryption key [%d]", err); | |
| 2704 | + return err; | |
| 2705 | +} | |
| 2706 | + | |
| 2707 | +static void ext4_apply_test_dummy_encryption(struct ext4_fs_context *ctx, | |
| 2708 | + struct super_block *sb) | |
| 2709 | +{ | |
| 2710 | + if (!fscrypt_is_dummy_policy_set(&ctx->dummy_enc_policy) || | |
| 2711 | + /* if already set, it was already verified to be the same */ | |
| 2712 | + fscrypt_is_dummy_policy_set(&EXT4_SB(sb)->s_dummy_enc_policy)) | |
| 2713 | + return; | |
| 2714 | + EXT4_SB(sb)->s_dummy_enc_policy = ctx->dummy_enc_policy; | |
| 2715 | + memset(&ctx->dummy_enc_policy, 0, sizeof(ctx->dummy_enc_policy)); | |
| 2716 | + ext4_msg(sb, KERN_WARNING, "Test dummy encryption mode enabled"); | |
| 2702 | 2717 | } |
| 2703 | 2718 | |
| 2704 | 2719 | static int ext4_check_opt_consistency(struct fs_context *fc, |
| @@ -2785,11 +2800,10 @@ fail_dax_change_remount: · 80 unmodified lines | ||
| 2785 | 2800 | return ext4_check_quota_consistency(fc, sb); |
| 2786 | 2801 | } |
| 2787 | 2802 | |
| 2788 | −static int ext4_apply_options(struct fs_context *fc, struct super_block *sb) | |
| 2803 | +static void ext4_apply_options(struct fs_context *fc, struct super_block *sb) | |
| 2789 | 2804 | { |
| 2790 | 2805 | struct ext4_fs_context *ctx = fc->fs_private; |
| 2791 | 2806 | struct ext4_sb_info *sbi = fc->s_fs_info; |
| 2792 | − int ret = 0; | |
| 2793 | 2807 | |
| 2794 | 2808 | sbi->s_mount_opt &= ~ctx->mask_s_mount_opt; |
| 2795 | 2809 | sbi->s_mount_opt |= ctx->vals_s_mount_opt; |
| @@ -2825,11 +2839,7 @@ static int ext4_apply_options(struct fs_context *fc, struct super_block *sb) · 29 unmodified lines | ||
| 2825 | 2839 | #endif |
| 2826 | 2840 | |
| 2827 | 2841 | ext4_apply_quota_options(fc, sb); |
| 2828 | − | |
| 2829 | − if (ctx->spec & EXT4_SPEC_DUMMY_ENCRYPTION) | |
| 2830 | − ret = ext4_set_test_dummy_encryption(sb, ctx->test_dummy_enc_arg); | |
| 2831 | − | |
| 2832 | − return ret; | |
| 2842 | + ext4_apply_test_dummy_encryption(ctx, sb); | |
| 2833 | 2843 | } |
| 2834 | 2844 | |
| 2835 | 2845 | |
| @@ -4552,9 +4562,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) · 1716 unmodified lines | ||
| 4552 | 4562 | if (err < 0) |
| 4553 | 4563 | goto failed_mount; |
| 4554 | 4564 | |
| 4555 | − err = ext4_apply_options(fc, sb); | |
| 4556 | − if (err < 0) | |
| 4557 | − goto failed_mount; | |
| 4565 | + ext4_apply_options(fc, sb); | |
| 4558 | 4566 | |
| 4559 | 4567 | #if IS_ENABLED(CONFIG_UNICODE) |
| 4560 | 4568 | if (ext4_has_feature_casefold(sb) && !sb->s_encoding) { |
| @@ -5302,14 +5310,6 @@ no_journal: · 741 unmodified lines | ||
| 5302 | 5310 | err = percpu_counter_init(&sbi->s_freeinodes_counter, freei, |
| 5303 | 5311 | GFP_KERNEL); |
| 5304 | 5312 | } |
| 5305 | − /* | |
| 5306 | − * Update the checksum after updating free space/inode | |
| 5307 | − * counters. Otherwise the superblock can have an incorrect | |
| 5308 | − * checksum in the buffer cache until it is written out and | |
| 5309 | − * e2fsprogs programs trying to open a file system immediately | |
| 5310 | − * after it is mounted can fail. | |
| 5311 | − */ | |
| 5312 | − ext4_superblock_csum_set(sb); | |
| 5313 | 5313 | if (!err) |
| 5314 | 5314 | err = percpu_counter_init(&sbi->s_dirs_counter, |
| 5315 | 5315 | ext4_count_dirs(sb), GFP_KERNEL); |
| @@ -5367,6 +5367,14 @@ no_journal: · 51 unmodified lines | ||
| 5367 | 5367 | EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; |
| 5368 | 5368 | ext4_orphan_cleanup(sb, es); |
| 5369 | 5369 | EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; |
| 5370 | + /* | |
| 5371 | + * Update the checksum after updating free space/inode counters and | |
| 5372 | + * ext4_orphan_cleanup. Otherwise the superblock can have an incorrect | |
| 5373 | + * checksum in the buffer cache until it is written out and | |
| 5374 | + * e2fsprogs programs trying to open a file system immediately | |
| 5375 | + * after it is mounted can fail. | |
| 5376 | + */ | |
| 5377 | + ext4_superblock_csum_set(sb); | |
| 5370 | 5378 | if (needs_recovery) { |
| 5371 | 5379 | ext4_msg(sb, KERN_INFO, "recovery complete"); |
| 5372 | 5380 | err = ext4_mark_recovery_complete(sb, es); |
| @@ -5898,7 +5906,6 @@ static void ext4_update_super(struct super_block *sb) · 525 unmodified lines | ||
| 5898 | 5906 | static int ext4_commit_super(struct super_block *sb) |
| 5899 | 5907 | { |
| 5900 | 5908 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; |
| 5901 | − int error = 0; | |
| 5902 | 5909 | |
| 5903 | 5910 | if (!sbh) |
| 5904 | 5911 | return -EINVAL; |
| @@ -5907,6 +5914,13 @@ static int ext4_commit_super(struct super_block *sb) · 2 unmodified lines | ||
| 5907 | 5914 | |
| 5908 | 5915 | ext4_update_super(sb); |
| 5909 | 5916 | |
| 5917 | + lock_buffer(sbh); | |
| 5918 | + /* Buffer got discarded which means block device got invalidated */ | |
| 5919 | + if (!buffer_mapped(sbh)) { | |
| 5920 | + unlock_buffer(sbh); | |
| 5921 | + return -EIO; | |
| 5922 | + } | |
| 5923 | + | |
| 5910 | 5924 | if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) { |
| 5911 | 5925 | /* |
| 5912 | 5926 | * Oh, dear. A previous attempt to write the |
| @@ -5921,17 +5935,21 @@ static int ext4_commit_super(struct super_block *sb) · 8 unmodified lines | ||
| 5921 | 5935 | clear_buffer_write_io_error(sbh); |
| 5922 | 5936 | set_buffer_uptodate(sbh); |
| 5923 | 5937 | } |
| 5924 | − BUFFER_TRACE(sbh, "marking dirty"); | |
| 5925 | − mark_buffer_dirty(sbh); | |
| 5926 | − error = __sync_dirty_buffer(sbh, | |
| 5927 | − REQ_SYNC | (test_opt(sb, BARRIER) ? REQ_FUA : 0)); | |
| 5938 | + get_bh(sbh); | |
| 5939 | + /* Clear potential dirty bit if it was journalled update */ | |
| 5940 | + clear_buffer_dirty(sbh); | |
| 5941 | + sbh->b_end_io = end_buffer_write_sync; | |
| 5942 | + submit_bh(REQ_OP_WRITE, | |
| 5943 | + REQ_SYNC | (test_opt(sb, BARRIER) ? REQ_FUA : 0), sbh); | |
| 5944 | + wait_on_buffer(sbh); | |
| 5928 | 5945 | if (buffer_write_io_error(sbh)) { |
| 5929 | 5946 | ext4_msg(sb, KERN_ERR, "I/O error while writing " |
| 5930 | 5947 | "superblock"); |
| 5931 | 5948 | clear_buffer_write_io_error(sbh); |
| 5932 | 5949 | set_buffer_uptodate(sbh); |
| 5950 | + return -EIO; | |
| 5933 | 5951 | } |
| 5934 | − return error; | |
| 5952 | + return 0; | |
| 5935 | 5953 | } |
| 5936 | 5954 | |
| 5937 | 5955 | /* |
| @@ -1895,11 +1895,10 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, · 1894 unmodified lines | ||
| 1895 | 1895 | |
| 1896 | 1896 | unlock_buffer(bs->bh); |
| 1897 | 1897 | ea_bdebug(bs->bh, "cloning"); |
| 1898 | − s->base = kmalloc(bs->bh->b_size, GFP_NOFS); | |
| 1898 | + s->base = kmemdup(BHDR(bs->bh), bs->bh->b_size, GFP_NOFS); | |
| 1899 | 1899 | error = -ENOMEM; |
| 1900 | 1900 | if (s->base == NULL) |
| 1901 | 1901 | goto cleanup; |
| 1902 | − memcpy(s->base, BHDR(bs->bh), bs->bh->b_size); | |
| 1903 | 1902 | s->first = ENTRY(header(s->base)+1); |
| 1904 | 1903 | header(s->base)->h_refcount = cpu_to_le32(1); |
| 1905 | 1904 | s->here = ENTRY(s->base + offset); |
| @@ -91,8 +91,9 @@ static inline void __record_iostat_latency(struct f2fs_sb_info *sbi) · 90 unmodified lines | ||
| 91 | 91 | unsigned int cnt; |
| 92 | 92 | struct f2fs_iostat_latency iostat_lat[MAX_IO_TYPE][NR_PAGE_TYPE]; |
| 93 | 93 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; |
| 94 | + unsigned long flags; | |
| 94 | 95 | |
| 95 | − spin_lock_bh(&sbi->iostat_lat_lock); | |
| 96 | + spin_lock_irqsave(&sbi->iostat_lat_lock, flags); | |
| 96 | 97 | for (idx = 0; idx < MAX_IO_TYPE; idx++) { |
| 97 | 98 | for (io = 0; io < NR_PAGE_TYPE; io++) { |
| 98 | 99 | cnt = io_lat->bio_cnt[idx][io]; |
| @@ -106,7 +107,7 @@ static inline void __record_iostat_latency(struct f2fs_sb_info *sbi) · 7 unmodified lines | ||
| 106 | 107 | io_lat->bio_cnt[idx][io] = 0; |
| 107 | 108 | } |
| 108 | 109 | } |
| 109 | − spin_unlock_bh(&sbi->iostat_lat_lock); | |
| 110 | + spin_unlock_irqrestore(&sbi->iostat_lat_lock, flags); | |
| 110 | 111 | |
| 111 | 112 | trace_f2fs_iostat_latency(sbi, iostat_lat); |
| 112 | 113 | } |
| @@ -115,14 +116,15 @@ static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi) · 2 unmodified lines | ||
| 115 | 116 | { |
| 116 | 117 | unsigned long long iostat_diff[NR_IO_TYPE]; |
| 117 | 118 | int i; |
| 119 | + unsigned long flags; | |
| 118 | 120 | |
| 119 | 121 | if (time_is_after_jiffies(sbi->iostat_next_period)) |
| 120 | 122 | return; |
| 121 | 123 | |
| 122 | 124 | /* Need double check under the lock */ |
| 123 | − spin_lock_bh(&sbi->iostat_lock); | |
| 125 | + spin_lock_irqsave(&sbi->iostat_lock, flags); | |
| 124 | 126 | if (time_is_after_jiffies(sbi->iostat_next_period)) { |
| 125 | − spin_unlock_bh(&sbi->iostat_lock); | |
| 127 | + spin_unlock_irqrestore(&sbi->iostat_lock, flags); | |
| 126 | 128 | return; |
| 127 | 129 | } |
| 128 | 130 | sbi->iostat_next_period = jiffies + |
| @@ -133,7 +135,7 @@ static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi) · 4 unmodified lines | ||
| 133 | 135 | sbi->prev_rw_iostat[i]; |
| 134 | 136 | sbi->prev_rw_iostat[i] = sbi->rw_iostat[i]; |
| 135 | 137 | } |
| 136 | − spin_unlock_bh(&sbi->iostat_lock); | |
| 138 | + spin_unlock_irqrestore(&sbi->iostat_lock, flags); | |
| 137 | 139 | |
| 138 | 140 | trace_f2fs_iostat(sbi, iostat_diff); |
| 139 | 141 | |
| @@ -145,25 +147,27 @@ void f2fs_reset_iostat(struct f2fs_sb_info *sbi) · 5 unmodified lines | ||
| 145 | 147 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; |
| 146 | 148 | int i; |
| 147 | 149 | |
| 148 | − spin_lock_bh(&sbi->iostat_lock); | |
| 150 | + spin_lock_irq(&sbi->iostat_lock); | |
| 149 | 151 | for (i = 0; i < NR_IO_TYPE; i++) { |
| 150 | 152 | sbi->rw_iostat[i] = 0; |
| 151 | 153 | sbi->prev_rw_iostat[i] = 0; |
| 152 | 154 | } |
| 153 | − spin_unlock_bh(&sbi->iostat_lock); | |
| 155 | + spin_unlock_irq(&sbi->iostat_lock); | |
| 154 | 156 | |
| 155 | − spin_lock_bh(&sbi->iostat_lat_lock); | |
| 157 | + spin_lock_irq(&sbi->iostat_lat_lock); | |
| 156 | 158 | memset(io_lat, 0, sizeof(struct iostat_lat_info)); |
| 157 | − spin_unlock_bh(&sbi->iostat_lat_lock); | |
| 159 | + spin_unlock_irq(&sbi->iostat_lat_lock); | |
| 158 | 160 | } |
| 159 | 161 | |
| 160 | 162 | void f2fs_update_iostat(struct f2fs_sb_info *sbi, |
| 161 | 163 | enum iostat_type type, unsigned long long io_bytes) |
| 162 | 164 | { |
| 165 | + unsigned long flags; | |
| 166 | + | |
| 163 | 167 | if (!sbi->iostat_enable) |
| 164 | 168 | return; |
| 165 | 169 | |
| 166 | − spin_lock_bh(&sbi->iostat_lock); | |
| 170 | + spin_lock_irqsave(&sbi->iostat_lock, flags); | |
| 167 | 171 | sbi->rw_iostat[type] += io_bytes; |
| 168 | 172 | |
| 169 | 173 | if (type == APP_BUFFERED_IO || type == APP_DIRECT_IO) |
| @@ -172,7 +176,7 @@ void f2fs_update_iostat(struct f2fs_sb_info *sbi, · 2 unmodified lines | ||
| 172 | 176 | if (type == APP_BUFFERED_READ_IO || type == APP_DIRECT_READ_IO) |
| 173 | 177 | sbi->rw_iostat[APP_READ_IO] += io_bytes; |
| 174 | 178 | |
| 175 | − spin_unlock_bh(&sbi->iostat_lock); | |
| 179 | + spin_unlock_irqrestore(&sbi->iostat_lock, flags); | |
| 176 | 180 | |
| 177 | 181 | f2fs_record_iostat(sbi); |
| 178 | 182 | } |
| @@ -185,6 +189,7 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx, · 6 unmodified lines | ||
| 185 | 189 | struct f2fs_sb_info *sbi = iostat_ctx->sbi; |
| 186 | 190 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; |
| 187 | 191 | int idx; |
| 192 | + unsigned long flags; | |
| 188 | 193 | |
| 189 | 194 | if (!sbi->iostat_enable) |
| 190 | 195 | return; |
| @@ -202,12 +207,12 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx, · 11 unmodified lines | ||
| 202 | 207 | idx = WRITE_ASYNC_IO; |
| 203 | 208 | } |
| 204 | 209 | |
| 205 | − spin_lock_bh(&sbi->iostat_lat_lock); | |
| 210 | + spin_lock_irqsave(&sbi->iostat_lat_lock, flags); | |
| 206 | 211 | io_lat->sum_lat[idx][iotype] += ts_diff; |
| 207 | 212 | io_lat->bio_cnt[idx][iotype]++; |
| 208 | 213 | if (ts_diff > io_lat->peak_lat[idx][iotype]) |
| 209 | 214 | io_lat->peak_lat[idx][iotype] = ts_diff; |
| 210 | − spin_unlock_bh(&sbi->iostat_lat_lock); | |
| 215 | + spin_unlock_irqrestore(&sbi->iostat_lat_lock, flags); | |
| 211 | 216 | } |
| 212 | 217 | |
| 213 | 218 | void iostat_update_and_unbind_ctx(struct bio *bio, int rw) |
| @@ -89,8 +89,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, · 88 unmodified lines | ||
| 89 | 89 | if (test_opt(sbi, INLINE_XATTR)) |
| 90 | 90 | set_inode_flag(inode, FI_INLINE_XATTR); |
| 91 | 91 | |
| 92 | − if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) | |
| 93 | − set_inode_flag(inode, FI_INLINE_DATA); | |
| 94 | 92 | if (f2fs_may_inline_dentry(inode)) |
| 95 | 93 | set_inode_flag(inode, FI_INLINE_DENTRY); |
| 96 | 94 | |
| @@ -107,10 +105,6 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, · 10 unmodified lines | ||
| 107 | 105 | |
| 108 | 106 | f2fs_init_extent_tree(inode, NULL); |
| 109 | 107 | |
| 110 | − stat_inc_inline_xattr(inode); | |
| 111 | − stat_inc_inline_inode(inode); | |
| 112 | − stat_inc_inline_dir(inode); | |
| 113 | − | |
| 114 | 108 | F2FS_I(inode)->i_flags = |
| 115 | 109 | f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED); |
| 116 | 110 | |
| @@ -127,6 +121,14 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, · 10 unmodified lines | ||
| 127 | 121 | set_compress_context(inode); |
| 128 | 122 | } |
| 129 | 123 | |
| 124 | + /* Should enable inline_data after compression set */ | |
| 125 | + if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) | |
| 126 | + set_inode_flag(inode, FI_INLINE_DATA); | |
| 127 | + | |
| 128 | + stat_inc_inline_xattr(inode); | |
| 129 | + stat_inc_inline_inode(inode); | |
| 130 | + stat_inc_inline_dir(inode); | |
| 131 | + | |
| 130 | 132 | f2fs_set_inode_flags(inode); |
| 131 | 133 | |
| 132 | 134 | trace_f2fs_new_inode(inode, 0); |
| @@ -325,6 +327,9 @@ static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, · 192 unmodified lines | ||
| 325 | 327 | if (!is_extension_exist(name, ext[i], false)) |
| 326 | 328 | continue; |
| 327 | 329 | |
| 330 | + /* Do not use inline_data with compression */ | |
| 331 | + stat_dec_inline_inode(inode); | |
| 332 | + clear_inode_flag(inode, FI_INLINE_DATA); | |
| 328 | 333 | set_compress_context(inode); |
| 329 | 334 | return; |
| 330 | 335 | } |
| @@ -1450,7 +1450,9 @@ page_hit: · 1449 unmodified lines | ||
| 1450 | 1450 | out_err: |
| 1451 | 1451 | ClearPageUptodate(page); |
| 1452 | 1452 | out_put_err: |
| 1453 | − f2fs_handle_page_eio(sbi, page->index, NODE); | |
| 1453 | + /* ENOENT comes from read_node_page which is not an error. */ | |
| 1454 | + if (err != -ENOENT) | |
| 1455 | + f2fs_handle_page_eio(sbi, page->index, NODE); | |
| 1454 | 1456 | f2fs_put_page(page, 1); |
| 1455 | 1457 | return ERR_PTR(err); |
| 1456 | 1458 | } |
| @@ -600,41 +600,79 @@ static void hugetlb_vmtruncate(struct inode *inode, loff_t offset) · 599 unmodified lines | ||
| 600 | 600 | remove_inode_hugepages(inode, offset, LLONG_MAX); |
| 601 | 601 | } |
| 602 | 602 | |
| 603 | +static void hugetlbfs_zero_partial_page(struct hstate *h, | |
| 604 | + struct address_space *mapping, | |
| 605 | + loff_t start, | |
| 606 | + loff_t end) | |
| 607 | +{ | |
| 608 | + pgoff_t idx = start >> huge_page_shift(h); | |
| 609 | + struct folio *folio; | |
| 610 | + | |
| 611 | + folio = filemap_lock_folio(mapping, idx); | |
| 612 | + if (!folio) | |
| 613 | + return; | |
| 614 | + | |
| 615 | + start = start & ~huge_page_mask(h); | |
| 616 | + end = end & ~huge_page_mask(h); | |
| 617 | + if (!end) | |
| 618 | + end = huge_page_size(h); | |
| 619 | + | |
| 620 | + folio_zero_segment(folio, (size_t)start, (size_t)end); | |
| 621 | + | |
| 622 | + folio_unlock(folio); | |
| 623 | + folio_put(folio); | |
| 624 | +} | |
| 625 | + | |
| 603 | 626 | static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) |
| 604 | 627 | { |
| 628 | + struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); | |
| 629 | + struct address_space *mapping = inode->i_mapping; | |
| 605 | 630 | struct hstate *h = hstate_inode(inode); |
| 606 | 631 | loff_t hpage_size = huge_page_size(h); |
| 607 | 632 | loff_t hole_start, hole_end; |
| 608 | 633 | |
| 609 | 634 | /* |
| 610 | − * For hole punch round up the beginning offset of the hole and | |
| 611 | − * round down the end. | |
| 635 | + * hole_start and hole_end indicate the full pages within the hole. | |
| 612 | 636 | */ |
| 613 | 637 | hole_start = round_up(offset, hpage_size); |
| 614 | 638 | hole_end = round_down(offset + len, hpage_size); |
| 615 | 639 | |
| 616 | − if (hole_end > hole_start) { | |
| 617 | − struct address_space *mapping = inode->i_mapping; | |
| 618 | − struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); | |
| 640 | + inode_lock(inode); | |
| 619 | 641 | |
| 620 | − inode_lock(inode); | |
| 642 | + /* protected by i_rwsem */ | |
| 643 | + if (info->seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE)) { | |
| 644 | + inode_unlock(inode); | |
| 645 | + return -EPERM; | |
42 more lines aren’t shown here.
This diff is large: its 734 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 8 lines aren’t shown here.
This diff is large: its 58 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 28 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 18 lines aren’t shown here.
This diff is large: its 45 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 8 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 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 31 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 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 13 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 171 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 12 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 830 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 59 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 99 lines aren’t shown here.
This diff is large: its 34 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 19 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 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
File renamed without changes.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 38 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 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 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 91 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 313 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 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 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 102 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 31 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 489 lines aren’t shown here.
This diff is large: its 16 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 36 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 108 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 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.