Unified · Split
| @@ -10,6 +10,8 @@ · 9 unmodified lines | |||
| 10 | # Please keep this list dictionary sorted. | 10 | # Please keep this list dictionary sorted. |
| 11 | # | 11 | # |
| 12 | Aaron Durbin <adurbin@google.com> | 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 | Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org> | 15 | Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org> |
| 14 | Adam Oldham <oldhamca@gmail.com> | 16 | Adam Oldham <oldhamca@gmail.com> |
| 15 | Adam Radford <aradford@gmail.com> | 17 | Adam Radford <aradford@gmail.com> |
| @@ -85,6 +87,7 @@ Christian Borntraeger <borntraeger@linux.ibm.com> <borntrae@de.ibm.com> · 69 unmodified lines | |||
| 85 | Christian Brauner <brauner@kernel.org> <christian@brauner.io> | 87 | Christian Brauner <brauner@kernel.org> <christian@brauner.io> |
| 86 | Christian Brauner <brauner@kernel.org> <christian.brauner@canonical.com> | 88 | Christian Brauner <brauner@kernel.org> <christian.brauner@canonical.com> |
| 87 | Christian Brauner <brauner@kernel.org> <christian.brauner@ubuntu.com> | 89 | Christian Brauner <brauner@kernel.org> <christian.brauner@ubuntu.com> |
| 90 | Christian Marangi <ansuelsmth@gmail.com> | ||
| 88 | Christophe Ricard <christophe.ricard@gmail.com> | 91 | Christophe Ricard <christophe.ricard@gmail.com> |
| 89 | Christoph Hellwig <hch@lst.de> | 92 | Christoph Hellwig <hch@lst.de> |
| 90 | Colin Ian King <colin.king@intel.com> <colin.king@canonical.com> | 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 | Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com> | 168 | Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com> |
| 166 | Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com> | 169 | Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com> |
| 167 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> | 170 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> |
| 171 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> | ||
| 168 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> | 172 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> |
| 169 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> | 173 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> |
| 170 | Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com> | 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 | KernelVersion: 4.2 | 2 | KernelVersion: 4.2 |
| 3 | Contact: linux-iio@vger.kernel.org | 3 | Contact: linux-iio@vger.kernel.org |
| 4 | Description: | 4 | Description: |
| @@ -526,6 +526,7 @@ What: /sys/devices/system/cpu/vulnerabilities · 525 unmodified lines | |||
| 526 | /sys/devices/system/cpu/vulnerabilities/srbds | 526 | /sys/devices/system/cpu/vulnerabilities/srbds |
| 527 | /sys/devices/system/cpu/vulnerabilities/tsx_async_abort | 527 | /sys/devices/system/cpu/vulnerabilities/tsx_async_abort |
| 528 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit | 528 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit |
| 529 | /sys/devices/system/cpu/vulnerabilities/mmio_stale_data | ||
| 529 | Date: January 2018 | 530 | Date: January 2018 |
| 530 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | 531 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
| 531 | Description: Information about CPU vulnerabilities | 532 | Description: Information about CPU vulnerabilities |
| @@ -17,3 +17,4 @@ are configurable at compile, boot or run time. · 16 unmodified lines | |||
| 17 | special-register-buffer-data-sampling.rst | 17 | special-register-buffer-data-sampling.rst |
| 18 | core-scheduling.rst | 18 | core-scheduling.rst |
| 19 | l1d_flush.rst | 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 | protected: nVHE-based mode with support for guests whose | 2470 | protected: nVHE-based mode with support for guests whose |
| 2471 | state is kept private from the host. | 2471 | state is kept private from the host. |
| 2472 | Not valid if the kernel is running in EL2. | ||
| 2473 | 2472 | ||
| 2474 | Defaults to VHE/nVHE based on hardware support. Setting | 2473 | Defaults to VHE/nVHE based on hardware support. Setting |
| 2475 | mode to "protected" will disable kexec and hibernation | 2474 | mode to "protected" will disable kexec and hibernation |
| @@ -3176,6 +3175,7 @@ · 700 unmodified lines | |||
| 3176 | srbds=off [X86,INTEL] | 3175 | srbds=off [X86,INTEL] |
| 3177 | no_entry_flush [PPC] | 3176 | no_entry_flush [PPC] |
| 3178 | no_uaccess_flush [PPC] | 3177 | no_uaccess_flush [PPC] |
| 3178 | mmio_stale_data=off [X86] | ||
| 3179 | 3179 | ||
| 3180 | Exceptions: | 3180 | Exceptions: |
| 3181 | This does not have any effect on | 3181 | This does not have any effect on |
| @@ -3197,6 +3197,7 @@ · 15 unmodified lines | |||
| 3197 | Equivalent to: l1tf=flush,nosmt [X86] | 3197 | Equivalent to: l1tf=flush,nosmt [X86] |
| 3198 | mds=full,nosmt [X86] | 3198 | mds=full,nosmt [X86] |
| 3199 | tsx_async_abort=full,nosmt [X86] | 3199 | tsx_async_abort=full,nosmt [X86] |
| 3200 | mmio_stale_data=full,nosmt [X86] | ||
| 3200 | 3201 | ||
| 3201 | mminit_loglevel= | 3202 | mminit_loglevel= |
| 3202 | [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this | 3203 | [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this |
| @@ -3206,6 +3207,40 @@ · 3 unmodified lines | |||
| 3206 | log everything. Information is printed at KERN_DEBUG | 3207 | log everything. Information is printed at KERN_DEBUG |
| 3207 | so loglevel=8 may also need to be specified. | 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 | module.sig_enforce | 3244 | module.sig_enforce |
| 3210 | [KNL] When CONFIG_MODULE_SIG is set, this means that | 3245 | [KNL] When CONFIG_MODULE_SIG is set, this means that |
| 3211 | modules without (valid) signatures will fail to load. | 3246 | modules without (valid) signatures will fail to load. |
| @@ -40,9 +40,8 @@ properties: · 39 unmodified lines | |||
| 40 | value to be used for converting remote channel measurements to | 40 | value to be used for converting remote channel measurements to |
| 41 | temperature. | 41 | temperature. |
| 42 | $ref: /schemas/types.yaml#/definitions/int32 | 42 | $ref: /schemas/types.yaml#/definitions/int32 |
| 43 | items: | 43 | minimum: -128 |
| 44 | minimum: -128 | 44 | maximum: 127 |
| 45 | maximum: 127 | ||
| 46 | 45 | ||
| 47 | ti,beta-compensation: | 46 | ti,beta-compensation: |
| 48 | description: | 47 | description: |
| @@ -30,6 +30,7 @@ properties: · 29 unmodified lines | |||
| 30 | - socionext,uniphier-ld11-aidet | 30 | - socionext,uniphier-ld11-aidet |
| 31 | - socionext,uniphier-ld20-aidet | 31 | - socionext,uniphier-ld20-aidet |
| 32 | - socionext,uniphier-pxs3-aidet | 32 | - socionext,uniphier-pxs3-aidet |
| 33 | - socionext,uniphier-nx1-aidet | ||
| 33 | 34 | ||
| 34 | reg: | 35 | reg: |
| 35 | maxItems: 1 | 36 | maxItems: 1 |
| @@ -47,6 +47,5 @@ examples: · 46 unmodified lines | |||
| 47 | clocks = <&clkcfg CLK_SPI0>; | 47 | clocks = <&clkcfg CLK_SPI0>; |
| 48 | interrupt-parent = <&plic>; | 48 | interrupt-parent = <&plic>; |
| 49 | interrupts = <54>; | 49 | interrupts = <54>; |
| 50 | spi-max-frequency = <25000000>; | ||
| 51 | }; | 50 | }; |
| 52 | ... | 51 | ... |
| @@ -110,7 +110,6 @@ examples: · 109 unmodified lines | |||
| 110 | pinctrl-names = "default"; | 110 | pinctrl-names = "default"; |
| 111 | pinctrl-0 = <&qup_spi1_default>; | 111 | pinctrl-0 = <&qup_spi1_default>; |
| 112 | interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; | 112 | interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; |
| 113 | spi-max-frequency = <50000000>; | ||
| 114 | #address-cells = <1>; | 113 | #address-cells = <1>; |
| 115 | #size-cells = <0>; | 114 | #size-cells = <0>; |
| 116 | }; | 115 | }; |
| @@ -136,7 +136,8 @@ properties: · 135 unmodified lines | |||
| 136 | Phandle of a companion. | 136 | Phandle of a companion. |
| 137 | 137 | ||
| 138 | phys: | 138 | phys: |
| 139 | maxItems: 1 | 139 | minItems: 1 |
| 140 | maxItems: 3 | ||
| 140 | 141 | ||
| 141 | phy-names: | 142 | phy-names: |
| 142 | const: usb | 143 | const: usb |
| @@ -103,7 +103,8 @@ properties: · 102 unmodified lines | |||
| 103 | Overrides the detected port count | 103 | Overrides the detected port count |
| 104 | 104 | ||
| 105 | phys: | 105 | phys: |
| 106 | maxItems: 1 | 106 | minItems: 1 |
| 107 | maxItems: 3 | ||
| 107 | 108 | ||
| 108 | phy-names: | 109 | phy-names: |
| 109 | const: usb | 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 | Note that it only applies to the new descriptor-based interface. For a | 7 | Note that it only applies to the new descriptor-based interface. For a |
| 8 | description of the deprecated integer-based GPIO interface please refer to | 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 | interface; you just fetch an integer from somewhere and request the | 10 | interface; you just fetch an integer from somewhere and request the |
| 11 | corresponding GPIO). | 11 | corresponding GPIO). |
| 12 | 12 | ||
| @@ -4,7 +4,7 @@ GPIO Descriptor Consumer Interface · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | This document describes the consumer interface of the GPIO framework. Note that | 5 | This document describes the consumer interface of the GPIO framework. Note that |
| 6 | it describes the new descriptor-based interface. For a description of the | 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 | Guidelines for GPIOs consumers | 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 | The two last flags are used for use cases where open drain is mandatory, such | 79 | The two last flags are used for use cases where open drain is mandatory, such |
| 80 | as I2C: if the line is not already configured as open drain in the mappings | 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 | printed that the board configuration needs to be updated to match the use case. | 82 | printed that the board configuration needs to be updated to match the use case. |
| 83 | 83 | ||
| 84 | Both functions return either a valid GPIO descriptor, or an error code checkable | 84 | Both functions return either a valid GPIO descriptor, or an error code checkable |
| @@ -270,7 +270,7 @@ driven. · 185 unmodified lines | |||
| 270 | The same is applicable for open drain or open source output lines: those do not | 270 | The same is applicable for open drain or open source output lines: those do not |
| 271 | actively drive their output high (open drain) or low (open source), they just | 271 | actively drive their output high (open drain) or low (open source), they just |
| 272 | switch their output to a high impedance value. The consumer should not need to | 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 | With this, all the gpiod_set_(array)_value_xxx() functions interpret the | 275 | With this, all the gpiod_set_(array)_value_xxx() functions interpret the |
| 276 | parameter "value" as "asserted" ("1") or "de-asserted" ("0"). The physical line | 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 | ways to obtain and use GPIOs: | 14 | ways to obtain and use GPIOs: |
| 15 | 15 | ||
| 16 | - The descriptor-based interface is the preferred way to manipulate GPIOs, | 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 | - The legacy integer-based interface which is considered deprecated (but still | 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 | The remainder of this document applies to the new descriptor-based interface. | 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 | integer-based interface. | 23 | integer-based interface. |
| 24 | 24 | ||
| 25 | 25 | ||
| @@ -19,13 +19,23 @@ The main Btrfs features include: · 18 unmodified lines | |||
| 19 | * Subvolumes (separate internal filesystem roots) | 19 | * Subvolumes (separate internal filesystem roots) |
| 20 | * Object level mirroring and striping | 20 | * Object level mirroring and striping |
| 21 | * Checksums on data and metadata (multiple algorithms available) | 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 | * Integrated multiple device support, with several raid algorithms | 26 | * Integrated multiple device support, with several raid algorithms |
| 24 | * Offline filesystem check | 27 | * Offline filesystem check |
| 25 | * Efficient incremental backup and FS mirroring | 28 | * Efficient incremental backup and FS mirroring (send/receive) |
| 29 | * Trim/discard | ||
| 26 | * Online filesystem defragmentation | 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 | https://btrfs.wiki.kernel.org | 40 | https://btrfs.wiki.kernel.org |
| 31 | 41 | ||
| @@ -13,8 +13,8 @@ disappeared as of Linux 3.0. · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | There are two places where extended attributes can be found. The first | 14 | There are two places where extended attributes can be found. The first |
| 15 | place is between the end of each inode entry and the beginning of the | 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 | 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 | 17 | sb.inode_size = 256, then there are 256 - (128 + 28) = 100 bytes |
| 18 | available for in-inode extended attribute storage. The second place | 18 | available for in-inode extended attribute storage. The second place |
| 19 | where extended attributes can be found is in the block pointed to by | 19 | where extended attributes can be found is in the block pointed to by |
| 20 | ``inode.i_file_acl``. As of Linux 3.11, it is not possible for this | 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 | - Name | 38 | - Name |
| 39 | - Description | 39 | - Description |
| 40 | * - 0x0 | 40 | * - 0x0 |
| 41 | - \_\_le32 | 41 | - __le32 |
| 42 | - h\_magic | 42 | - h_magic |
| 43 | - Magic number for identification, 0xEA020000. This value is set by the | 43 | - Magic number for identification, 0xEA020000. This value is set by the |
| 44 | Linux driver, though e2fsprogs doesn't seem to check it(?) | 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 | - Name | 55 | - Name |
| 56 | - Description | 56 | - Description |
| 57 | * - 0x0 | 57 | * - 0x0 |
| 58 | - \_\_le32 | 58 | - __le32 |
| 59 | - h\_magic | 59 | - h_magic |
| 60 | - Magic number for identification, 0xEA020000. | 60 | - Magic number for identification, 0xEA020000. |
| 61 | * - 0x4 | 61 | * - 0x4 |
| 62 | - \_\_le32 | 62 | - __le32 |
| 63 | - h\_refcount | 63 | - h_refcount |
| 64 | - Reference count. | 64 | - Reference count. |
| 65 | * - 0x8 | 65 | * - 0x8 |
| 66 | - \_\_le32 | 66 | - __le32 |
| 67 | - h\_blocks | 67 | - h_blocks |
| 68 | - Number of disk blocks used. | 68 | - Number of disk blocks used. |
| 69 | * - 0xC | 69 | * - 0xC |
| 70 | - \_\_le32 | 70 | - __le32 |
| 71 | - h\_hash | 71 | - h_hash |
| 72 | - Hash value of all attributes. | 72 | - Hash value of all attributes. |
| 73 | * - 0x10 | 73 | * - 0x10 |
| 74 | - \_\_le32 | 74 | - __le32 |
| 75 | - h\_checksum | 75 | - h_checksum |
| 76 | - Checksum of the extended attribute block. | 76 | - Checksum of the extended attribute block. |
| 77 | * - 0x14 | 77 | * - 0x14 |
| 78 | - \_\_u32 | 78 | - __u32 |
| 79 | - h\_reserved[3] | 79 | - h_reserved[3] |
| 80 | - Zero. | 80 | - Zero. |
| 81 | 81 | ||
| 82 | The checksum is calculated against the FS UUID, the 64-bit block number | 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 | - Name | 100 | - Name |
| 101 | - Description | 101 | - Description |
| 102 | * - 0x0 | 102 | * - 0x0 |
| 103 | - \_\_u8 | 103 | - __u8 |
| 104 | - e\_name\_len | 104 | - e_name_len |
| 105 | - Length of name. | 105 | - Length of name. |
| 106 | * - 0x1 | 106 | * - 0x1 |
| 107 | - \_\_u8 | 107 | - __u8 |
| 108 | - e\_name\_index | 108 | - e_name_index |
| 109 | - Attribute name index. There is a discussion of this below. | 109 | - Attribute name index. There is a discussion of this below. |
| 110 | * - 0x2 | 110 | * - 0x2 |
| 111 | - \_\_le16 | 111 | - __le16 |
| 112 | - e\_value\_offs | 112 | - e_value_offs |
| 113 | - Location of this attribute's value on the disk block where it is stored. | 113 | - Location of this attribute's value on the disk block where it is stored. |
| 114 | Multiple attributes can share the same value. For an inode attribute | 114 | Multiple attributes can share the same value. For an inode attribute |
| 115 | this value is relative to the start of the first entry; for a block this | 115 | this value is relative to the start of the first entry; for a block this |
| 116 | value is relative to the start of the block (i.e. the header). | 116 | value is relative to the start of the block (i.e. the header). |
| 117 | * - 0x4 | 117 | * - 0x4 |
| 118 | - \_\_le32 | 118 | - __le32 |
| 119 | - e\_value\_inum | 119 | - e_value_inum |
| 120 | - The inode where the value is stored. Zero indicates the value is in the | 120 | - The inode where the value is stored. Zero indicates the value is in the |
| 121 | same block as this entry. This field is only used if the | 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 | * - 0x8 | 123 | * - 0x8 |
| 124 | - \_\_le32 | 124 | - __le32 |
| 125 | - e\_value\_size | 125 | - e_value_size |
| 126 | - Length of attribute value. | 126 | - Length of attribute value. |
| 127 | * - 0xC | 127 | * - 0xC |
| 128 | - \_\_le32 | 128 | - __le32 |
| 129 | - e\_hash | 129 | - e_hash |
| 130 | - Hash value of attribute name and attribute value. The kernel doesn't | 130 | - Hash value of attribute name and attribute value. The kernel doesn't |
| 131 | update the hash for in-inode attributes, so for that case this value | 131 | update the hash for in-inode attributes, so for that case this value |
| 132 | must be zero, because e2fsck validates any non-zero hash regardless of | 132 | must be zero, because e2fsck validates any non-zero hash regardless of |
| 133 | where the xattr lives. | 133 | where the xattr lives. |
| 134 | * - 0x10 | 134 | * - 0x10 |
| 135 | - char | 135 | - char |
| 136 | - e\_name[e\_name\_len] | 136 | - e_name[e_name_len] |
| 137 | - Attribute name. Does not include trailing NULL. | 137 | - Attribute name. Does not include trailing NULL. |
| 138 | 138 | ||
| 139 | Attribute values can follow the end of the entry table. There appears to | 139 | Attribute values can follow the end of the entry table. There appears to |
| 140 | be a requirement that they be aligned to 4-byte boundaries. The values | 140 | be a requirement that they be aligned to 4-byte boundaries. The values |
| 141 | are stored starting at the end of the block and grow towards the | 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 | put into a separate disk block. If the disk block fills up, the | 143 | put into a separate disk block. If the disk block fills up, the |
| 144 | filesystem returns -ENOSPC. | 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 | * - 1 | 167 | * - 1 |
| 168 | - “user.” | 168 | - “user.” |
| 169 | * - 2 | 169 | * - 2 |
| 170 | - “system.posix\_acl\_access” | 170 | - “system.posix_acl_access” |
| 171 | * - 3 | 171 | * - 3 |
| 172 | - “system.posix\_acl\_default” | 172 | - “system.posix_acl_default” |
| 173 | * - 4 | 173 | * - 4 |
| 174 | - “trusted.” | 174 | - “trusted.” |
| 175 | * - 6 | 175 | * - 6 |
| 176 | - “security.” | 176 | - “security.” |
| 177 | * - 7 | 177 | * - 7 |
| 178 | - “system.” (inline\_data only?) | 178 | - “system.” (inline_data only?) |
| 179 | * - 8 | 179 | * - 8 |
| 180 | - “system.richacl” (SuSE kernels only?) | 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 | also shrinking the amount of file system overhead for metadata. | 23 | also shrinking the amount of file system overhead for metadata. |
| 24 | 24 | ||
| 25 | The administrator can set a block cluster size at mkfs time (which is | 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 | on, the block bitmaps track clusters, not individual blocks. This means | 27 | on, the block bitmaps track clusters, not individual blocks. This means |
| 28 | that block groups can be several gigabytes in size (instead of just | 28 | that block groups can be several gigabytes in size (instead of just |
| 29 | 128MiB); however, the minimum allocation unit becomes a cluster, not a | 29 | 128MiB); however, the minimum allocation unit becomes a cluster, not a |
| @@ -9,15 +9,15 @@ group. · 8 unmodified lines | |||
| 9 | The inode bitmap records which entries in the inode table are in use. | 9 | The inode bitmap records which entries in the inode table are in use. |
| 10 | 10 | ||
| 11 | As with most bitmaps, one bit represents the usage status of one data | 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 \* | 12 | block or inode table entry. This implies a block group size of 8 * |
| 13 | number\_of\_bytes\_in\_a\_logical\_block. | 13 | number_of_bytes_in_a_logical_block. |
| 14 | 14 | ||
| 15 | NOTE: If ``BLOCK_UNINIT`` is set for a given block group, various parts | 15 | NOTE: If ``BLOCK_UNINIT`` is set for a given block group, various parts |
| 16 | of the kernel and e2fsprogs code pretends that the block bitmap contains | 16 | of the kernel and e2fsprogs code pretends that the block bitmap contains |
| 17 | zeros (i.e. all blocks in the group are free). However, it is not | 17 | zeros (i.e. all blocks in the group are free). However, it is not |
| 18 | necessarily the case that no blocks are in use -- if ``meta_bg`` is set, | 18 | necessarily the case that no blocks are in use -- if ``meta_bg`` is set, |
| 19 | the bitmaps and group descriptor live inside the group. Unfortunately, | 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 | which produces confusing debugfs output. | 21 | which produces confusing debugfs output. |
| 22 | 22 | ||
| 23 | Inode Table | 23 | Inode Table |
| @@ -56,39 +56,39 @@ established that the super block and the group descriptor table, if · 55 unmodified lines | |||
| 56 | present, will be at the beginning of the block group. The bitmaps and | 56 | present, will be at the beginning of the block group. The bitmaps and |
| 57 | the inode table can be anywhere, and it is quite possible for the | 57 | the inode table can be anywhere, and it is quite possible for the |
| 58 | bitmaps to come after the inode table, or for both to be in different | 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 | block maps, extent tree blocks, and extended attributes. | 60 | block maps, extent tree blocks, and extended attributes. |
| 61 | 61 | ||
| 62 | Flexible Block Groups | 62 | Flexible Block Groups |
| 63 | --------------------- | 63 | --------------------- |
| 64 | 64 | ||
| 65 | Starting in ext4, there is a new feature called flexible block groups | 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 | logical block group; the bitmap spaces and the inode table space in the | 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 | 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, | 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 | 70 | if the flex_bg size is 4, then group 0 will contain (in order) the |
| 71 | superblock, group descriptors, data block bitmaps for groups 0-3, inode | 71 | superblock, group descriptors, data block bitmaps for groups 0-3, inode |
| 72 | bitmaps for groups 0-3, inode tables for groups 0-3, and the remaining | 72 | bitmaps for groups 0-3, inode tables for groups 0-3, and the remaining |
| 73 | space in group 0 is for file data. The effect of this is to group the | 73 | space in group 0 is for file data. The effect of this is to group the |
| 74 | block group metadata close together for faster loading, and to enable | 74 | block group metadata close together for faster loading, and to enable |
| 75 | large files to be continuous on disk. Backup copies of the superblock | 75 | large files to be continuous on disk. Backup copies of the superblock |
| 76 | and group descriptors are always at the beginning of block groups, even | 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 | 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``. | 78 | flex_bg is given by 2 ^ ``sb.s_log_groups_per_flex``. |
| 79 | 79 | ||
| 80 | Meta Block Groups | 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 | descriptors copies are kept in the first block group. Given the default | 84 | descriptors copies are kept in the first block group. Given the default |
| 85 | 128MiB(2^27 bytes) block group size and 64-byte group descriptors, ext4 | 85 | 128MiB(2^27 bytes) block group size and 64-byte group descriptors, ext4 |
| 86 | can have at most 2^27/64 = 2^21 block groups. This limits the entire | 86 | can have at most 2^27/64 = 2^21 block groups. This limits the entire |
| 87 | filesystem size to 2^21 * 2^27 = 2^48bytes or 256TiB. | 87 | filesystem size to 2^21 * 2^27 = 2^48bytes or 256TiB. |
| 88 | 88 | ||
| 89 | The solution to this problem is to use the metablock group feature | 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 | 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 | 91 | META_BG feature, ext4 filesystems are partitioned into many metablock |
| 92 | groups. Each metablock group is a cluster of block groups whose group | 92 | groups. Each metablock group is a cluster of block groups whose group |
| 93 | descriptor structures can be stored in a single disk block. For ext4 | 93 | descriptor structures can be stored in a single disk block. For ext4 |
| 94 | filesystems with 4 KB block size, a single metablock group partition | 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 | a 1KB block size, and 128 block groups for filesystems with a 4KB | 110 | a 1KB block size, and 128 block groups for filesystems with a 4KB |
| 111 | blocksize. Filesystems can either be created using this new block group | 111 | blocksize. Filesystems can either be created using this new block group |
| 112 | descriptor layout, or existing filesystems can be resized on-line, and | 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 | block group using this new layout. | 114 | block group using this new layout. |
| 115 | 115 | ||
| 116 | Please see an important note about ``BLOCK_UNINIT`` in the section about | 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 | A new feature for ext4 are three block group descriptor flags that | 122 | A new feature for ext4 are three block group descriptor flags that |
| 123 | enable mkfs to skip initializing other parts of the block group | 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 | that the inode and block bitmaps for that group can be calculated and | 125 | that the inode and block bitmaps for that group can be calculated and |
| 126 | therefore the on-disk bitmap blocks are not initialized. This is | 126 | therefore the on-disk bitmap blocks are not initialized. This is |
| 127 | generally the case for an empty block group or a block group containing | 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 | that the inode table has been initialized; mkfs will unset this flag and | 129 | that the inode table has been initialized; mkfs will unset this flag and |
| 130 | rely on the kernel to initialize the inode tables in the background. | 130 | rely on the kernel to initialize the inode tables in the background. |
| 131 | 131 | ||
| 132 | By not writing zeroes to the bitmaps and inode table, mkfs time is | 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, | 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 | 134 | but the dumpe2fs output prints this as “uninit_bg”. They are the same |
| 135 | thing. | 135 | thing. |
| @@ -1,7 +1,7 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | 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 | | 0 to 11 | Direct map to file blocks 0 to 11. | | 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 | Starting in early 2012, metadata checksums were added to all major ext4 | 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 | The desired checksum algorithm is indicated in the superblock, though as | 8 | The desired checksum algorithm is indicated in the superblock, though as |
| 9 | of October 2012 the only supported algorithm is crc32c. Some data | 9 | of October 2012 the only supported algorithm is crc32c. Some data |
| 10 | structures did not have space to fit a full 32-bit checksum, so only the | 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 | checksum, it will request that you run ``e2fsck -D`` to have the | 20 | checksum, it will request that you run ``e2fsck -D`` to have the |
| 21 | directories rebuilt with checksums. This has the added benefit of | 21 | directories rebuilt with checksums. This has the added benefit of |
| 22 | removing slack space from the directory files and rebalancing the htree | 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 | protected by a checksum! | 24 | protected by a checksum! |
| 25 | 25 | ||
| 26 | The following table describes the data elements that go into each type | 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 | - Length | 35 | - Length |
| 36 | - Ingredients | 36 | - Ingredients |
| 37 | * - Superblock | 37 | * - Superblock |
| 38 | - \_\_le32 | 38 | - __le32 |
| 39 | - The entire superblock up to the checksum field. The UUID lives inside | 39 | - The entire superblock up to the checksum field. The UUID lives inside |
| 40 | the superblock. | 40 | the superblock. |
| 41 | * - MMP | 41 | * - MMP |
| 42 | - \_\_le32 | 42 | - __le32 |
| 43 | - UUID + the entire MMP block up to the checksum field. | 43 | - UUID + the entire MMP block up to the checksum field. |
| 44 | * - Extended Attributes | 44 | * - Extended Attributes |
| 45 | - \_\_le32 | 45 | - __le32 |
| 46 | - UUID + the entire extended attribute block. The checksum field is set to | 46 | - UUID + the entire extended attribute block. The checksum field is set to |
| 47 | zero. | 47 | zero. |
| 48 | * - Directory Entries | 48 | * - Directory Entries |
| 49 | - \_\_le32 | 49 | - __le32 |
| 50 | - UUID + inode number + inode generation + the directory block up to the | 50 | - UUID + inode number + inode generation + the directory block up to the |
| 51 | fake entry enclosing the checksum field. | 51 | fake entry enclosing the checksum field. |
| 52 | * - HTREE Nodes | 52 | * - HTREE Nodes |
| 53 | - \_\_le32 | 53 | - __le32 |
| 54 | - UUID + inode number + inode generation + all valid extents + HTREE tail. | 54 | - UUID + inode number + inode generation + all valid extents + HTREE tail. |
| 55 | The checksum field is set to zero. | 55 | The checksum field is set to zero. |
| 56 | * - Extents | 56 | * - Extents |
| 57 | - \_\_le32 | 57 | - __le32 |
| 58 | - UUID + inode number + inode generation + the entire extent block up to | 58 | - UUID + inode number + inode generation + the entire extent block up to |
| 59 | the checksum field. | 59 | the checksum field. |
| 60 | * - Bitmaps | 60 | * - Bitmaps |
| 61 | - \_\_le32 or \_\_le16 | 61 | - __le32 or __le16 |
| 62 | - UUID + the entire bitmap. Checksums are stored in the group descriptor, | 62 | - UUID + the entire bitmap. Checksums are stored in the group descriptor, |
| 63 | and truncated if the group descriptor size is 32 bytes (i.e. ^64bit) | 63 | and truncated if the group descriptor size is 32 bytes (i.e. ^64bit) |
| 64 | * - Inodes | 64 | * - Inodes |
| 65 | - \_\_le32 | 65 | - __le32 |
| 66 | - UUID + inode number + inode generation + the entire inode. The checksum | 66 | - UUID + inode number + inode generation + the entire inode. The checksum |
| 67 | field is set to zero. Each inode has its own checksum. | 67 | field is set to zero. Each inode has its own checksum. |
| 68 | * - Group Descriptors | 68 | * - Group Descriptors |
| 69 | - \_\_le16 | 69 | - __le16 |
| 70 | - If metadata\_csum, then UUID + group number + the entire descriptor; | 70 | - If metadata_csum, then UUID + group number + the entire descriptor; |
| 71 | else if gdt\_csum, then crc16(UUID + group number + the entire | 71 | else if gdt_csum, then crc16(UUID + group number + the entire |
| 72 | descriptor). In all cases, only the lower 16 bits are stored. | 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 | - Name | 42 | - Name |
| 43 | - Description | 43 | - Description |
| 44 | * - 0x0 | 44 | * - 0x0 |
| 45 | - \_\_le32 | 45 | - __le32 |
| 46 | - inode | 46 | - inode |
| 47 | - Number of the inode that this directory entry points to. | 47 | - Number of the inode that this directory entry points to. |
| 48 | * - 0x4 | 48 | * - 0x4 |
| 49 | - \_\_le16 | 49 | - __le16 |
| 50 | - rec\_len | 50 | - rec_len |
| 51 | - Length of this directory entry. Must be a multiple of 4. | 51 | - Length of this directory entry. Must be a multiple of 4. |
| 52 | * - 0x6 | 52 | * - 0x6 |
| 53 | - \_\_le16 | 53 | - __le16 |
| 54 | - name\_len | 54 | - name_len |
| 55 | - Length of the file name. | 55 | - Length of the file name. |
| 56 | * - 0x8 | 56 | * - 0x8 |
| 57 | - char | 57 | - char |
| 58 | - name[EXT4\_NAME\_LEN] | 58 | - name[EXT4_NAME_LEN] |
| 59 | - File name. | 59 | - File name. |
| 60 | 60 | ||
| 61 | Since file names cannot be longer than 255 bytes, the new directory | 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 | type flag, probably to avoid having to load every inode during directory | 63 | type flag, probably to avoid having to load every inode during directory |
| 64 | tree traversal. This format is ``ext4_dir_entry_2``, which is at most | 64 | tree traversal. This format is ``ext4_dir_entry_2``, which is at most |
| 65 | 263 bytes long, though on disk you'll need to reference | 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 | - Name | 74 | - Name |
| 75 | - Description | 75 | - Description |
| 76 | * - 0x0 | 76 | * - 0x0 |
| 77 | - \_\_le32 | 77 | - __le32 |
| 78 | - inode | 78 | - inode |
| 79 | - Number of the inode that this directory entry points to. | 79 | - Number of the inode that this directory entry points to. |
| 80 | * - 0x4 | 80 | * - 0x4 |
| 81 | - \_\_le16 | 81 | - __le16 |
| 82 | - rec\_len | 82 | - rec_len |
| 83 | - Length of this directory entry. | 83 | - Length of this directory entry. |
| 84 | * - 0x6 | 84 | * - 0x6 |
| 85 | - \_\_u8 | 85 | - __u8 |
| 86 | - name\_len | 86 | - name_len |
| 87 | - Length of the file name. | 87 | - Length of the file name. |
| 88 | * - 0x7 | 88 | * - 0x7 |
| 89 | - \_\_u8 | 89 | - __u8 |
| 90 | - file\_type | 90 | - file_type |
| 91 | - File type code, see ftype_ table below. | 91 | - File type code, see ftype_ table below. |
| 92 | * - 0x8 | 92 | * - 0x8 |
| 93 | - char | 93 | - char |
| 94 | - name[EXT4\_NAME\_LEN] | 94 | - name[EXT4_NAME_LEN] |
| 95 | - File name. | 95 | - File name. |
| 96 | 96 | ||
| 97 | .. _ftype: | 97 | .. _ftype: |
| @@ -137,19 +137,19 @@ entry uses this extension, it may be up to 271 bytes. · 39 unmodified lines | |||
| 137 | - Name | 137 | - Name |
| 138 | - Description | 138 | - Description |
| 139 | * - 0x0 | 139 | * - 0x0 |
| 140 | - \_\_le32 | 140 | - __le32 |
| 141 | - hash | 141 | - hash |
| 142 | - The hash of the directory name | 142 | - The hash of the directory name |
| 143 | * - 0x4 | 143 | * - 0x4 |
| 144 | - \_\_le32 | 144 | - __le32 |
| 145 | - minor\_hash | 145 | - minor_hash |
| 146 | - The minor hash of the directory name | 146 | - The minor hash of the directory name |
| 147 | 147 | ||
| 148 | 148 | ||
| 149 | In order to add checksums to these classic directory blocks, a phony | 149 | In order to add checksums to these classic directory blocks, a phony |
| 150 | ``struct ext4_dir_entry`` is placed at the end of each leaf block to | 150 | ``struct ext4_dir_entry`` is placed at the end of each leaf block to |
| 151 | hold the checksum. The directory entry is 12 bytes long. The inode | 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 | ignoring an apparently empty directory entry, and the checksum is stored | 153 | ignoring an apparently empty directory entry, and the checksum is stored |
| 154 | in the place where the name normally goes. The structure is | 154 | in the place where the name normally goes. The structure is |
| 155 | ``struct ext4_dir_entry_tail``: | 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 | - Name | 163 | - Name |
| 164 | - Description | 164 | - Description |
| 165 | * - 0x0 | 165 | * - 0x0 |
| 166 | - \_\_le32 | 166 | - __le32 |
| 167 | - det\_reserved\_zero1 | 167 | - det_reserved_zero1 |
| 168 | - Inode number, which must be zero. | 168 | - Inode number, which must be zero. |
| 169 | * - 0x4 | 169 | * - 0x4 |
| 170 | - \_\_le16 | 170 | - __le16 |
| 171 | - det\_rec\_len | 171 | - det_rec_len |
| 172 | - Length of this directory entry, which must be 12. | 172 | - Length of this directory entry, which must be 12. |
| 173 | * - 0x6 | 173 | * - 0x6 |
| 174 | - \_\_u8 | 174 | - __u8 |
| 175 | - det\_reserved\_zero2 | 175 | - det_reserved_zero2 |
| 176 | - Length of the file name, which must be zero. | 176 | - Length of the file name, which must be zero. |
| 177 | * - 0x7 | 177 | * - 0x7 |
| 178 | - \_\_u8 | 178 | - __u8 |
| 179 | - det\_reserved\_ft | 179 | - det_reserved_ft |
| 180 | - File type, which must be 0xDE. | 180 | - File type, which must be 0xDE. |
| 181 | * - 0x8 | 181 | * - 0x8 |
| 182 | - \_\_le32 | 182 | - __le32 |
| 183 | - det\_checksum | 183 | - det_checksum |
| 184 | - Directory leaf block checksum. | 184 | - Directory leaf block checksum. |
| 185 | 185 | ||
| 186 | The leaf directory block checksum is calculated against the FS UUID, the | 186 | The leaf directory block checksum is calculated against the FS UUID, the |
| @@ -194,7 +194,7 @@ Hash Tree Directories · 7 unmodified lines | |||
| 194 | A linear array of directory entries isn't great for performance, so a | 194 | A linear array of directory entries isn't great for performance, so a |
| 195 | new feature was added to ext3 to provide a faster (but peculiar) | 195 | new feature was added to ext3 to provide a faster (but peculiar) |
| 196 | balanced tree keyed off a hash of the directory entry name. If the | 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 | hashed btree (htree) to organize and find directory entries. For | 198 | hashed btree (htree) to organize and find directory entries. For |
| 199 | backwards read-only compatibility with ext2, this tree is actually | 199 | backwards read-only compatibility with ext2, this tree is actually |
| 200 | hidden inside the directory file, masquerading as “empty” directory data | 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 | The root of the tree always lives in the first data block of the | 206 | The root of the tree always lives in the first data block of the |
| 207 | directory. By ext2 custom, the '.' and '..' entries must appear at the | 207 | directory. By ext2 custom, the '.' and '..' entries must appear at the |
| 208 | beginning of this first block, so they are put here as two | 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 | the root node contains metadata about the tree and finally a hash->block | 210 | the root node contains metadata about the tree and finally a hash->block |
| 211 | map to find nodes that are lower in the htree. If | 211 | map to find nodes that are lower in the htree. If |
| 212 | ``dx_root.info.indirect_levels`` is non-zero then the htree has two | 212 | ``dx_root.info.indirect_levels`` is non-zero then the htree has two |
| 213 | levels; the data block pointed to by the root node's map is an interior | 213 | levels; the data block pointed to by the root node's map is an interior |
| 214 | node, which is indexed by a minor hash. Interior nodes in this tree | 214 | node, which is indexed by a minor hash. Interior nodes in this tree |
| 215 | contains a zeroed out ``struct ext4_dir_entry_2`` followed by a | 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 | array of all ``struct ext4_dir_entry_2``; all of these entries | 217 | array of all ``struct ext4_dir_entry_2``; all of these entries |
| 218 | (presumably) hash to the same value. If there is an overflow, the | 218 | (presumably) hash to the same value. If there is an overflow, the |
| 219 | entries simply overflow into the next leaf node, and the | 219 | entries simply overflow into the next leaf node, and the |
| @@ -245,83 +245,83 @@ of a data block: · 25 unmodified lines | |||
| 245 | - Name | 245 | - Name |
| 246 | - Description | 246 | - Description |
| 247 | * - 0x0 | 247 | * - 0x0 |
| 248 | - \_\_le32 | 248 | - __le32 |
| 249 | - dot.inode | 249 | - dot.inode |
| 250 | - inode number of this directory. | 250 | - inode number of this directory. |
| 251 | * - 0x4 | 251 | * - 0x4 |
| 252 | - \_\_le16 | 252 | - __le16 |
| 253 | - dot.rec\_len | 253 | - dot.rec_len |
| 254 | - Length of this record, 12. | 254 | - Length of this record, 12. |
| 255 | * - 0x6 | 255 | * - 0x6 |
| 256 | - u8 | 256 | - u8 |
| 257 | - dot.name\_len | 257 | - dot.name_len |
| 258 | - Length of the name, 1. | 258 | - Length of the name, 1. |
| 259 | * - 0x7 | 259 | * - 0x7 |
| 260 | - u8 | 260 | - u8 |
| 261 | - dot.file\_type | 261 | - dot.file_type |
| 262 | - File type of this entry, 0x2 (directory) (if the feature flag is set). | 262 | - File type of this entry, 0x2 (directory) (if the feature flag is set). |
| 263 | * - 0x8 | 263 | * - 0x8 |
| 264 | - char | 264 | - char |
| 265 | - dot.name[4] | 265 | - dot.name[4] |
| 266 | - “.\\0\\0\\0” | 266 | - “.\0\0\0” |
| 267 | * - 0xC | 267 | * - 0xC |
| 268 | - \_\_le32 | 268 | - __le32 |
| 269 | - dotdot.inode | 269 | - dotdot.inode |
| 270 | - inode number of parent directory. | 270 | - inode number of parent directory. |
| 271 | * - 0x10 | 271 | * - 0x10 |
| 272 | - \_\_le16 | 272 | - __le16 |
| 273 | - dotdot.rec\_len | 273 | - dotdot.rec_len |
| 274 | - block\_size - 12. The record length is long enough to cover all htree | 274 | - block_size - 12. The record length is long enough to cover all htree |
| 275 | data. | 275 | data. |
| 276 | * - 0x12 | 276 | * - 0x12 |
| 277 | - u8 | 277 | - u8 |
| 278 | - dotdot.name\_len | 278 | - dotdot.name_len |
| 279 | - Length of the name, 2. | 279 | - Length of the name, 2. |
| 280 | * - 0x13 | 280 | * - 0x13 |
| 281 | - u8 | 281 | - u8 |
| 282 | - dotdot.file\_type | 282 | - dotdot.file_type |
| 283 | - File type of this entry, 0x2 (directory) (if the feature flag is set). | 283 | - File type of this entry, 0x2 (directory) (if the feature flag is set). |
| 284 | * - 0x14 | 284 | * - 0x14 |
| 285 | - char | 285 | - char |
| 286 | - dotdot\_name[4] | 286 | - dotdot_name[4] |
| 287 | - “..\\0\\0” | 287 | - “..\0\0” |
| 288 | * - 0x18 | 288 | * - 0x18 |
| 289 | - \_\_le32 | 289 | - __le32 |
| 290 | - struct dx\_root\_info.reserved\_zero | 290 | - struct dx_root_info.reserved_zero |
| 291 | - Zero. | 291 | - Zero. |
| 292 | * - 0x1C | 292 | * - 0x1C |
| 293 | - u8 | 293 | - u8 |
| 294 | - struct dx\_root\_info.hash\_version | 294 | - struct dx_root_info.hash_version |
| 295 | - Hash type, see dirhash_ table below. | 295 | - Hash type, see dirhash_ table below. |
| 296 | * - 0x1D | 296 | * - 0x1D |
| 297 | - u8 | 297 | - u8 |
| 298 | - struct dx\_root\_info.info\_length | 298 | - struct dx_root_info.info_length |
| 299 | - Length of the tree information, 0x8. | 299 | - Length of the tree information, 0x8. |
| 300 | * - 0x1E | 300 | * - 0x1E |
| 301 | - u8 | 301 | - u8 |
| 302 | - struct dx\_root\_info.indirect\_levels | 302 | - struct dx_root_info.indirect_levels |
| 303 | - Depth of the htree. Cannot be larger than 3 if the INCOMPAT\_LARGEDIR | 303 | - Depth of the htree. Cannot be larger than 3 if the INCOMPAT_LARGEDIR |
| 304 | feature is set; cannot be larger than 2 otherwise. | 304 | feature is set; cannot be larger than 2 otherwise. |
| 305 | * - 0x1F | 305 | * - 0x1F |
| 306 | - u8 | 306 | - u8 |
| 307 | - struct dx\_root\_info.unused\_flags | 307 | - struct dx_root_info.unused_flags |
| 308 | - | 308 | - |
| 309 | * - 0x20 | 309 | * - 0x20 |
| 310 | - \_\_le16 | 310 | - __le16 |
| 311 | - limit | 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 | the header itself. | 313 | the header itself. |
| 314 | * - 0x22 | 314 | * - 0x22 |
| 315 | - \_\_le16 | 315 | - __le16 |
| 316 | - count | 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 | header itself. | 318 | header itself. |
| 319 | * - 0x24 | 319 | * - 0x24 |
| 320 | - \_\_le32 | 320 | - __le32 |
| 321 | - block | 321 | - block |
| 322 | - The block number (within the directory file) that goes with hash=0. | 322 | - The block number (within the directory file) that goes with hash=0. |
| 323 | * - 0x28 | 323 | * - 0x28 |
| 324 | - struct dx\_entry | 324 | - struct dx_entry |
| 325 | - entries[0] | 325 | - entries[0] |
| 326 | - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block. | 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 | - Name | 362 | - Name |
| 363 | - Description | 363 | - Description |
| 364 | * - 0x0 | 364 | * - 0x0 |
| 365 | - \_\_le32 | 365 | - __le32 |
| 366 | - fake.inode | 366 | - fake.inode |
| 367 | - Zero, to make it look like this entry is not in use. | 367 | - Zero, to make it look like this entry is not in use. |
| 368 | * - 0x4 | 368 | * - 0x4 |
| 369 | - \_\_le16 | 369 | - __le16 |
| 370 | - fake.rec\_len | 370 | - fake.rec_len |
| 371 | - The size of the block, in order to hide all of the dx\_node data. | 371 | - The size of the block, in order to hide all of the dx_node data. |
| 372 | * - 0x6 | 372 | * - 0x6 |
| 373 | - u8 | 373 | - u8 |
| 374 | - name\_len | 374 | - name_len |
| 375 | - Zero. There is no name for this “unused” directory entry. | 375 | - Zero. There is no name for this “unused” directory entry. |
| 376 | * - 0x7 | 376 | * - 0x7 |
| 377 | - u8 | 377 | - u8 |
| 378 | - file\_type | 378 | - file_type |
| 379 | - Zero. There is no file type for this “unused” directory entry. | 379 | - Zero. There is no file type for this “unused” directory entry. |
| 380 | * - 0x8 | 380 | * - 0x8 |
| 381 | - \_\_le16 | 381 | - __le16 |
| 382 | - limit | 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 | the header itself. | 384 | the header itself. |
| 385 | * - 0xA | 385 | * - 0xA |
| 386 | - \_\_le16 | 386 | - __le16 |
| 387 | - count | 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 | header itself. | 389 | header itself. |
| 390 | * - 0xE | 390 | * - 0xE |
| 391 | - \_\_le32 | 391 | - __le32 |
| 392 | - block | 392 | - block |
| 393 | - The block number (within the directory file) that goes with the lowest | 393 | - The block number (within the directory file) that goes with the lowest |
| 394 | hash value of this block. This value is stored in the parent block. | 394 | hash value of this block. This value is stored in the parent block. |
| 395 | * - 0x12 | 395 | * - 0x12 |
| 396 | - struct dx\_entry | 396 | - struct dx_entry |
| 397 | - entries[0] | 397 | - entries[0] |
| 398 | - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block. | 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 | - Name | 410 | - Name |
| 411 | - Description | 411 | - Description |
| 412 | * - 0x0 | 412 | * - 0x0 |
| 413 | - \_\_le32 | 413 | - __le32 |
| 414 | - hash | 414 | - hash |
| 415 | - Hash code. | 415 | - Hash code. |
| 416 | * - 0x4 | 416 | * - 0x4 |
| 417 | - \_\_le32 | 417 | - __le32 |
| 418 | - block | 418 | - block |
| 419 | - Block number (within the directory file, not filesystem blocks) of the | 419 | - Block number (within the directory file, not filesystem blocks) of the |
| 420 | next node in the htree. | 420 | next node in the htree. |
| @@ -423,13 +423,13 @@ long: · 2 unmodified lines | |||
| 423 | author.) | 423 | author.) |
| 424 | 424 | ||
| 425 | If metadata checksums are enabled, the last 8 bytes of the directory | 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 | ``struct dx_tail``, which contains the checksum. The ``limit`` and | 427 | ``struct dx_tail``, which contains the checksum. The ``limit`` and |
| 428 | ``count`` entries in the dx\_root/dx\_node structures are adjusted as | 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 | 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 | 430 | the dx_tail, the user is notified to run e2fsck -D to rebuild the |
| 431 | directory index (which will ensure that there's space for the checksum. | 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 | .. list-table:: | 434 | .. list-table:: |
| 435 | :widths: 8 8 24 40 | 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 | - Description | 441 | - Description |
| 442 | * - 0x0 | 442 | * - 0x0 |
| 443 | - u32 | 443 | - u32 |
| 444 | - dt\_reserved | 444 | - dt_reserved |
| 445 | - Zero. | 445 | - Zero. |
| 446 | * - 0x4 | 446 | * - 0x4 |
| 447 | - \_\_le32 | 447 | - __le32 |
| 448 | - dt\_checksum | 448 | - dt_checksum |
| 449 | - Checksum of the htree directory block. | 449 | - Checksum of the htree directory block. |
| 450 | 450 | ||
| 451 | The checksum is calculated against the FS UUID, the htree index header | 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 | 452 | (dx_root or dx_node), all of the htree indices (dx_entry) that are in |
| 453 | use, and the tail block (dx\_tail). | 453 | use, and the tail block (dx_tail). |
| @@ -5,14 +5,14 @@ Large Extended Attribute Values · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | To enable ext4 to store extended attribute values that do not fit in the | 6 | To enable ext4 to store extended attribute values that do not fit in the |
| 7 | inode or in the single extended attribute block attached to an inode, | 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 | a regular file inode. This “EA inode” is linked only from the extended | 9 | a regular file inode. This “EA inode” is linked only from the extended |
| 10 | attribute name index and must not appear in a directory entry. The | 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; | 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 | 12 | and i_ctime/i_version store a 64-bit reference count, which enables |
| 13 | sharing of large xattr values between multiple owning inodes. For | 13 | sharing of large xattr values between multiple owning inodes. For |
| 14 | backward compatibility with older versions of this feature, the | 14 | backward compatibility with older versions of this feature, the |
| 15 | i\_mtime/i\_generation *may* store a back-reference to the inode number | 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 | 16 | and i_generation of the **one** owning inode (in cases where the EA |
| 17 | inode is not referenced by multiple inodes) to verify that the EA inode | 17 | inode is not referenced by multiple inodes) to verify that the EA inode |
| 18 | is the correct one being accessed. | 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 | associated with it. As noted in the Layout section above, the group | 7 | associated with it. As noted in the Layout section above, the group |
| 8 | descriptors (if present) are the second item in the block group. The | 8 | descriptors (if present) are the second item in the block group. The |
| 9 | standard configuration is for each block group to contain a full copy of | 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 | is set. | 11 | is set. |
| 12 | 12 | ||
| 13 | Notice how the group descriptor records the location of both bitmaps and | 13 | Notice how the group descriptor records the location of both bitmaps and |
| 14 | the inode table (i.e. they can float). This means that within a block | 14 | the inode table (i.e. they can float). This means that within a block |
| 15 | group, the only data structures with fixed locations are the superblock | 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 | property to group several block groups into a flex group and lay out all | 17 | property to group several block groups into a flex group and lay out all |
| 18 | of the groups' bitmaps and inode tables into one long run in the first | 18 | of the groups' bitmaps and inode tables into one long run in the first |
| 19 | group of the flex group. | 19 | group of the flex group. |
| 20 | 20 | ||
| 21 | If the meta\_bg feature flag is set, then several block groups are | 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, | 22 | grouped together into a meta group. Note that in the meta_bg case, |
| 23 | however, the first and last two block groups within the larger meta | 23 | however, the first and last two block groups within the larger meta |
| 24 | group contain only group descriptors for the groups inside the meta | 24 | group contain only group descriptors for the groups inside the meta |
| 25 | group. | 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 | In ext2, ext3, and ext4 (when the 64bit feature is not enabled), the | 29 | In ext2, ext3, and ext4 (when the 64bit feature is not enabled), the |
| 30 | block group descriptor was only 32 bytes long and therefore ends at | 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 | block group descriptor expands to at least the 64 bytes described below; | 32 | block group descriptor expands to at least the 64 bytes described below; |
| 33 | the size is stored in the superblock. | 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 | checksum is the crc16 of the FS UUID, the group number, and the group | 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 | checksum is the lower 16 bits of the checksum of the FS UUID, the group | 38 | checksum is the lower 16 bits of the checksum of the FS UUID, the group |
| 39 | number, and the group descriptor structure. Both block and inode bitmap | 39 | number, and the group descriptor structure. Both block and inode bitmap |
| 40 | checksums are calculated against the FS UUID, the group number, and the | 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 | - Name | 51 | - Name |
| 52 | - Description | 52 | - Description |
| 53 | * - 0x0 | 53 | * - 0x0 |
| 54 | - \_\_le32 | 54 | - __le32 |
| 55 | - bg\_block\_bitmap\_lo | 55 | - bg_block_bitmap_lo |
| 56 | - Lower 32-bits of location of block bitmap. | 56 | - Lower 32-bits of location of block bitmap. |
| 57 | * - 0x4 | 57 | * - 0x4 |
| 58 | - \_\_le32 | 58 | - __le32 |
| 59 | - bg\_inode\_bitmap\_lo | 59 | - bg_inode_bitmap_lo |
| 60 | - Lower 32-bits of location of inode bitmap. | 60 | - Lower 32-bits of location of inode bitmap. |
| 61 | * - 0x8 | 61 | * - 0x8 |
| 62 | - \_\_le32 | 62 | - __le32 |
| 63 | - bg\_inode\_table\_lo | 63 | - bg_inode_table_lo |
| 64 | - Lower 32-bits of location of inode table. | 64 | - Lower 32-bits of location of inode table. |
| 65 | * - 0xC | 65 | * - 0xC |
| 66 | - \_\_le16 | 66 | - __le16 |
| 67 | - bg\_free\_blocks\_count\_lo | 67 | - bg_free_blocks_count_lo |
| 68 | - Lower 16-bits of free block count. | 68 | - Lower 16-bits of free block count. |
| 69 | * - 0xE | 69 | * - 0xE |
| 70 | - \_\_le16 | 70 | - __le16 |
| 71 | - bg\_free\_inodes\_count\_lo | 71 | - bg_free_inodes_count_lo |
| 72 | - Lower 16-bits of free inode count. | 72 | - Lower 16-bits of free inode count. |
| 73 | * - 0x10 | 73 | * - 0x10 |
| 74 | - \_\_le16 | 74 | - __le16 |
| 75 | - bg\_used\_dirs\_count\_lo | 75 | - bg_used_dirs_count_lo |
| 76 | - Lower 16-bits of directory count. | 76 | - Lower 16-bits of directory count. |
| 77 | * - 0x12 | 77 | * - 0x12 |
| 78 | - \_\_le16 | 78 | - __le16 |
| 79 | - bg\_flags | 79 | - bg_flags |
| 80 | - Block group flags. See the bgflags_ table below. | 80 | - Block group flags. See the bgflags_ table below. |
| 81 | * - 0x14 | 81 | * - 0x14 |
| 82 | - \_\_le32 | 82 | - __le32 |
| 83 | - bg\_exclude\_bitmap\_lo | 83 | - bg_exclude_bitmap_lo |
| 84 | - Lower 32-bits of location of snapshot exclusion bitmap. | 84 | - Lower 32-bits of location of snapshot exclusion bitmap. |
| 85 | * - 0x18 | 85 | * - 0x18 |
| 86 | - \_\_le16 | 86 | - __le16 |
| 87 | - bg\_block\_bitmap\_csum\_lo | 87 | - bg_block_bitmap_csum_lo |
| 88 | - Lower 16-bits of the block bitmap checksum. | 88 | - Lower 16-bits of the block bitmap checksum. |
| 89 | * - 0x1A | 89 | * - 0x1A |
| 90 | - \_\_le16 | 90 | - __le16 |
| 91 | - bg\_inode\_bitmap\_csum\_lo | 91 | - bg_inode_bitmap_csum_lo |
| 92 | - Lower 16-bits of the inode bitmap checksum. | 92 | - Lower 16-bits of the inode bitmap checksum. |
| 93 | * - 0x1C | 93 | * - 0x1C |
| 94 | - \_\_le16 | 94 | - __le16 |
| 95 | - bg\_itable\_unused\_lo | 95 | - bg_itable_unused_lo |
| 96 | - Lower 16-bits of unused inode count. If set, we needn't scan past the | 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 | inode table for this group. | 98 | inode table for this group. |
| 99 | * - 0x1E | 99 | * - 0x1E |
| 100 | - \_\_le16 | 100 | - __le16 |
| 101 | - bg\_checksum | 101 | - bg_checksum |
| 102 | - Group descriptor checksum; crc16(sb\_uuid+group\_num+bg\_desc) if the | 102 | - Group descriptor checksum; crc16(sb_uuid+group_num+bg_desc) if the |
| 103 | RO\_COMPAT\_GDT\_CSUM feature is set, or | 103 | RO_COMPAT_GDT_CSUM feature is set, or |
| 104 | crc32c(sb\_uuid+group\_num+bg\_desc) & 0xFFFF if the | 104 | crc32c(sb_uuid+group_num+bg_desc) & 0xFFFF if the |
| 105 | RO\_COMPAT\_METADATA\_CSUM feature is set. The bg\_checksum | 105 | RO_COMPAT_METADATA_CSUM feature is set. The bg_checksum |
| 106 | field in bg\_desc is skipped when calculating crc16 checksum, | 106 | field in bg_desc is skipped when calculating crc16 checksum, |
| 107 | and set to zero if crc32c checksum is used. | 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 | - These fields only exist if the 64bit feature is enabled and s_desc_size | 111 | - These fields only exist if the 64bit feature is enabled and s_desc_size |
| 112 | > 32. | 112 | > 32. |
| 113 | * - 0x20 | 113 | * - 0x20 |
| 114 | - \_\_le32 | 114 | - __le32 |
| 115 | - bg\_block\_bitmap\_hi | 115 | - bg_block_bitmap_hi |
| 116 | - Upper 32-bits of location of block bitmap. | 116 | - Upper 32-bits of location of block bitmap. |
| 117 | * - 0x24 | 117 | * - 0x24 |
| 118 | - \_\_le32 | 118 | - __le32 |
| 119 | - bg\_inode\_bitmap\_hi | 119 | - bg_inode_bitmap_hi |
| 120 | - Upper 32-bits of location of inodes bitmap. | 120 | - Upper 32-bits of location of inodes bitmap. |
| 121 | * - 0x28 | 121 | * - 0x28 |
| 122 | - \_\_le32 | 122 | - __le32 |
| 123 | - bg\_inode\_table\_hi | 123 | - bg_inode_table_hi |
| 124 | - Upper 32-bits of location of inodes table. | 124 | - Upper 32-bits of location of inodes table. |
| 125 | * - 0x2C | 125 | * - 0x2C |
| 126 | - \_\_le16 | 126 | - __le16 |
| 127 | - bg\_free\_blocks\_count\_hi | 127 | - bg_free_blocks_count_hi |
| 128 | - Upper 16-bits of free block count. | 128 | - Upper 16-bits of free block count. |
| 129 | * - 0x2E | 129 | * - 0x2E |
| 130 | - \_\_le16 | 130 | - __le16 |
| 131 | - bg\_free\_inodes\_count\_hi | 131 | - bg_free_inodes_count_hi |
| 132 | - Upper 16-bits of free inode count. | 132 | - Upper 16-bits of free inode count. |
| 133 | * - 0x30 | 133 | * - 0x30 |
| 134 | - \_\_le16 | 134 | - __le16 |
| 135 | - bg\_used\_dirs\_count\_hi | 135 | - bg_used_dirs_count_hi |
| 136 | - Upper 16-bits of directory count. | 136 | - Upper 16-bits of directory count. |
| 137 | * - 0x32 | 137 | * - 0x32 |
| 138 | - \_\_le16 | 138 | - __le16 |
| 139 | - bg\_itable\_unused\_hi | 139 | - bg_itable_unused_hi |
| 140 | - Upper 16-bits of unused inode count. | 140 | - Upper 16-bits of unused inode count. |
| 141 | * - 0x34 | 141 | * - 0x34 |
| 142 | - \_\_le32 | 142 | - __le32 |
| 143 | - bg\_exclude\_bitmap\_hi | 143 | - bg_exclude_bitmap_hi |
| 144 | - Upper 32-bits of location of snapshot exclusion bitmap. | 144 | - Upper 32-bits of location of snapshot exclusion bitmap. |
| 145 | * - 0x38 | 145 | * - 0x38 |
| 146 | - \_\_le16 | 146 | - __le16 |
| 147 | - bg\_block\_bitmap\_csum\_hi | 147 | - bg_block_bitmap_csum_hi |
| 148 | - Upper 16-bits of the block bitmap checksum. | 148 | - Upper 16-bits of the block bitmap checksum. |
| 149 | * - 0x3A | 149 | * - 0x3A |
| 150 | - \_\_le16 | 150 | - __le16 |
| 151 | - bg\_inode\_bitmap\_csum\_hi | 151 | - bg_inode_bitmap_csum_hi |
| 152 | - Upper 16-bits of the inode bitmap checksum. | 152 | - Upper 16-bits of the inode bitmap checksum. |
| 153 | * - 0x3C | 153 | * - 0x3C |
| 154 | - \_\_u32 | 154 | - __u32 |
| 155 | - bg\_reserved | 155 | - bg_reserved |
| 156 | - Padding to 64 bytes. | 156 | - Padding to 64 bytes. |
| 157 | 157 | ||
| 158 | .. _bgflags: | 158 | .. _bgflags: |
| @@ -166,8 +166,8 @@ Block group flags can be any combination of the following: · 7 unmodified lines | |||
| 166 | * - Value | 166 | * - Value |
| 167 | - Description | 167 | - Description |
| 168 | * - 0x1 | 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 | * - 0x2 | 170 | * - 0x2 |
| 171 | - block bitmap is not initialized (EXT4\_BG\_BLOCK\_UNINIT). | 171 | - block bitmap is not initialized (EXT4_BG_BLOCK_UNINIT). |
| 172 | * - 0x4 | 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 | .. SPDX-License-Identifier: GPL-2.0 | 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 | Depending on the type of file an inode describes, the 60 bytes of | 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 | tree. Under the old scheme, allocating a contiguous run of 1,000 blocks | 47 | tree. Under the old scheme, allocating a contiguous run of 1,000 blocks |
| 48 | requires an indirect block to map all 1,000 entries; with extents, the | 48 | requires an indirect block to map all 1,000 entries; with extents, the |
| 49 | mapping is reduced to a single ``struct ext4_extent`` with | 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 | very large files with a single extent, at a considerable reduction in | 51 | very large files with a single extent, at a considerable reduction in |
| 52 | metadata block use, and some improvement in disk efficiency. The inode | 52 | metadata block use, and some improvement in disk efficiency. The inode |
| 53 | must have the extents flag (0x80000) flag set for this feature to be in | 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 | - Name | 76 | - Name |
| 77 | - Description | 77 | - Description |
| 78 | * - 0x0 | 78 | * - 0x0 |
| 79 | - \_\_le16 | 79 | - __le16 |
| 80 | - eh\_magic | 80 | - eh_magic |
| 81 | - Magic number, 0xF30A. | 81 | - Magic number, 0xF30A. |
| 82 | * - 0x2 | 82 | * - 0x2 |
| 83 | - \_\_le16 | 83 | - __le16 |
| 84 | - eh\_entries | 84 | - eh_entries |
| 85 | - Number of valid entries following the header. | 85 | - Number of valid entries following the header. |
| 86 | * - 0x4 | 86 | * - 0x4 |
| 87 | - \_\_le16 | 87 | - __le16 |
| 88 | - eh\_max | 88 | - eh_max |
| 89 | - Maximum number of entries that could follow the header. | 89 | - Maximum number of entries that could follow the header. |
| 90 | * - 0x6 | 90 | * - 0x6 |
| 91 | - \_\_le16 | 91 | - __le16 |
| 92 | - eh\_depth | 92 | - eh_depth |
| 93 | - Depth of this extent node in the extent tree. 0 = this extent node | 93 | - Depth of this extent node in the extent tree. 0 = this extent node |
| 94 | points to data blocks; otherwise, this extent node points to other | 94 | points to data blocks; otherwise, this extent node points to other |
| 95 | extent nodes. The extent tree can be at most 5 levels deep: a logical | 95 | extent nodes. The extent tree can be at most 5 levels deep: a logical |
| 96 | block number can be at most ``2^32``, and the smallest ``n`` that | 96 | block number can be at most ``2^32``, and the smallest ``n`` that |
| 97 | satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5. | 97 | satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5. |
| 98 | * - 0x8 | 98 | * - 0x8 |
| 99 | - \_\_le32 | 99 | - __le32 |
| 100 | - eh\_generation | 100 | - eh_generation |
| 101 | - Generation of the tree. (Used by Lustre, but not standard ext4). | 101 | - Generation of the tree. (Used by Lustre, but not standard ext4). |
| 102 | 102 | ||
| 103 | Internal nodes of the extent tree, also known as index nodes, are | 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 | - Name | 112 | - Name |
| 113 | - Description | 113 | - Description |
| 114 | * - 0x0 | 114 | * - 0x0 |
| 115 | - \_\_le32 | 115 | - __le32 |
| 116 | - ei\_block | 116 | - ei_block |
| 117 | - This index node covers file blocks from 'block' onward. | 117 | - This index node covers file blocks from 'block' onward. |
| 118 | * - 0x4 | 118 | * - 0x4 |
| 119 | - \_\_le32 | 119 | - __le32 |
| 120 | - ei\_leaf\_lo | 120 | - ei_leaf_lo |
| 121 | - Lower 32-bits of the block number of the extent node that is the next | 121 | - Lower 32-bits of the block number of the extent node that is the next |
| 122 | level lower in the tree. The tree node pointed to can be either another | 122 | level lower in the tree. The tree node pointed to can be either another |
| 123 | internal node or a leaf node, described below. | 123 | internal node or a leaf node, described below. |
| 124 | * - 0x8 | 124 | * - 0x8 |
| 125 | - \_\_le16 | 125 | - __le16 |
| 126 | - ei\_leaf\_hi | 126 | - ei_leaf_hi |
| 127 | - Upper 16-bits of the previous field. | 127 | - Upper 16-bits of the previous field. |
| 128 | * - 0xA | 128 | * - 0xA |
| 129 | - \_\_u16 | 129 | - __u16 |
| 130 | - ei\_unused | 130 | - ei_unused |
| 131 | - | 131 | - |
| 132 | 132 | ||
| 133 | Leaf nodes of the extent tree are recorded as ``struct ext4_extent``, | 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 | - Name | 142 | - Name |
| 143 | - Description | 143 | - Description |
| 144 | * - 0x0 | 144 | * - 0x0 |
| 145 | - \_\_le32 | 145 | - __le32 |
| 146 | - ee\_block | 146 | - ee_block |
| 147 | - First file block number that this extent covers. | 147 | - First file block number that this extent covers. |
| 148 | * - 0x4 | 148 | * - 0x4 |
| 149 | - \_\_le16 | 149 | - __le16 |
| 150 | - ee\_len | 150 | - ee_len |
| 151 | - Number of blocks covered by extent. If the value of this field is <= | 151 | - Number of blocks covered by extent. If the value of this field is <= |
| 152 | 32768, the extent is initialized. If the value of the field is > 32768, | 152 | 32768, the extent is initialized. If the value of the field is > 32768, |
| 153 | the extent is uninitialized and the actual extent length is ``ee_len`` - | 153 | the extent is uninitialized and the actual extent length is ``ee_len`` - |
| 154 | 32768. Therefore, the maximum length of a initialized extent is 32768 | 154 | 32768. Therefore, the maximum length of a initialized extent is 32768 |
| 155 | blocks, and the maximum length of an uninitialized extent is 32767. | 155 | blocks, and the maximum length of an uninitialized extent is 32767. |
| 156 | * - 0x6 | 156 | * - 0x6 |
| 157 | - \_\_le16 | 157 | - __le16 |
| 158 | - ee\_start\_hi | 158 | - ee_start_hi |
| 159 | - Upper 16-bits of the block number to which this extent points. | 159 | - Upper 16-bits of the block number to which this extent points. |
| 160 | * - 0x8 | 160 | * - 0x8 |
| 161 | - \_\_le32 | 161 | - __le32 |
| 162 | - ee\_start\_lo | 162 | - ee_start_lo |
| 163 | - Lower 32-bits of the block number to which this extent points. | 163 | - Lower 32-bits of the block number to which this extent points. |
| 164 | 164 | ||
| 165 | Prior to the introduction of metadata checksums, the extent header + | 165 | Prior to the introduction of metadata checksums, the extent header + |
| @@ -182,8 +182,8 @@ including) the checksum itself. · 16 unmodified lines | |||
| 182 | - Name | 182 | - Name |
| 183 | - Description | 183 | - Description |
| 184 | * - 0x0 | 184 | * - 0x0 |
| 185 | - \_\_le32 | 185 | - __le32 |
| 186 | - eb\_checksum | 186 | - eb_checksum |
| 187 | - Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock) | 187 | - Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock) |
| 188 | 188 | ||
| 189 | Inline Data | 189 | Inline Data |
| @@ -11,12 +11,12 @@ file is smaller than 60 bytes, then the data are stored inline in · 10 unmodified lines | |||
| 11 | attribute space, then it might be found as an extended attribute | 11 | attribute space, then it might be found as an extended attribute |
| 12 | “system.data” within the inode body (“ibody EA”). This of course | 12 | “system.data” within the inode body (“ibody EA”). This of course |
| 13 | constrains the amount of extended attributes one can attach to an inode. | 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 | is allocated and the contents moved to that block. | 15 | is allocated and the contents moved to that block. |
| 16 | 16 | ||
| 17 | Pending a change to compact the extended attribute key used to store | 17 | Pending a change to compact the extended attribute key used to store |
| 18 | inline data, one ought to be able to store 160 bytes of data in a | 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 | that, the limit was 156 bytes due to inefficient use of inode space. | 20 | that, the limit was 156 bytes due to inefficient use of inode space. |
| 21 | 21 | ||
| 22 | The inline data feature requires the presence of an extended attribute | 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 | Inline Directories | 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 | directory. Following that is a 56-byte space for an array of directory | 29 | directory. Following that is a 56-byte space for an array of directory |
| 30 | entries; see ``struct ext4_dir_entry``. If there is a “system.data” | 30 | entries; see ``struct ext4_dir_entry``. If there is a “system.data” |
| 31 | attribute in the inode body, the EA value is an array of | 31 | attribute in the inode body, the EA value is an array of |
| 32 | ``struct ext4_dir_entry`` as well. Note that for inline directories, the | 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 | entries cannot span the two. | 34 | entries cannot span the two. |
| 35 | 35 | ||
| 36 | Inline directory entries are not checksummed, as the inode checksum | 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 | - Name | 38 | - Name |
| 39 | - Description | 39 | - Description |
| 40 | * - 0x0 | 40 | * - 0x0 |
| 41 | - \_\_le16 | 41 | - __le16 |
| 42 | - i\_mode | 42 | - i_mode |
| 43 | - File mode. See the table i_mode_ below. | 43 | - File mode. See the table i_mode_ below. |
| 44 | * - 0x2 | 44 | * - 0x2 |
| 45 | - \_\_le16 | 45 | - __le16 |
| 46 | - i\_uid | 46 | - i_uid |
| 47 | - Lower 16-bits of Owner UID. | 47 | - Lower 16-bits of Owner UID. |
| 48 | * - 0x4 | 48 | * - 0x4 |
| 49 | - \_\_le32 | 49 | - __le32 |
| 50 | - i\_size\_lo | 50 | - i_size_lo |
| 51 | - Lower 32-bits of size in bytes. | 51 | - Lower 32-bits of size in bytes. |
| 52 | * - 0x8 | 52 | * - 0x8 |
| 53 | - \_\_le32 | 53 | - __le32 |
| 54 | - i\_atime | 54 | - i_atime |
| 55 | - Last access time, in seconds since the epoch. However, if the EA\_INODE | 55 | - Last access time, in seconds since the epoch. However, if the EA_INODE |
| 56 | inode flag is set, this inode stores an extended attribute value and | 56 | inode flag is set, this inode stores an extended attribute value and |
| 57 | this field contains the checksum of the value. | 57 | this field contains the checksum of the value. |
| 58 | * - 0xC | 58 | * - 0xC |
| 59 | - \_\_le32 | 59 | - __le32 |
| 60 | - i\_ctime | 60 | - i_ctime |
| 61 | - Last inode change time, in seconds since the epoch. However, if the | 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 | value and this field contains the lower 32 bits of the attribute value's | 63 | value and this field contains the lower 32 bits of the attribute value's |
| 64 | reference count. | 64 | reference count. |
| 65 | * - 0x10 | 65 | * - 0x10 |
| 66 | - \_\_le32 | 66 | - __le32 |
| 67 | - i\_mtime | 67 | - i_mtime |
| 68 | - Last data modification time, in seconds since the epoch. However, if the | 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 | value and this field contains the number of the inode that owns the | 70 | value and this field contains the number of the inode that owns the |
| 71 | extended attribute. | 71 | extended attribute. |
| 72 | * - 0x14 | 72 | * - 0x14 |
| 73 | - \_\_le32 | 73 | - __le32 |
| 74 | - i\_dtime | 74 | - i_dtime |
| 75 | - Deletion Time, in seconds since the epoch. | 75 | - Deletion Time, in seconds since the epoch. |
| 76 | * - 0x18 | 76 | * - 0x18 |
| 77 | - \_\_le16 | 77 | - __le16 |
| 78 | - i\_gid | 78 | - i_gid |
| 79 | - Lower 16-bits of GID. | 79 | - Lower 16-bits of GID. |
| 80 | * - 0x1A | 80 | * - 0x1A |
| 81 | - \_\_le16 | 81 | - __le16 |
| 82 | - i\_links\_count | 82 | - i_links_count |
| 83 | - Hard link count. Normally, ext4 does not permit an inode to have more | 83 | - Hard link count. Normally, ext4 does not permit an inode to have more |
| 84 | than 65,000 hard links. This applies to files as well as directories, | 84 | than 65,000 hard links. This applies to files as well as directories, |
| 85 | which means that there cannot be more than 64,998 subdirectories in a | 85 | which means that there cannot be more than 64,998 subdirectories in a |
| 86 | directory (each subdirectory's '..' entry counts as a hard link, as does | 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 | enabled, ext4 supports more than 64,998 subdirectories by setting this | 88 | enabled, ext4 supports more than 64,998 subdirectories by setting this |
| 89 | field to 1 to indicate that the number of hard links is not known. | 89 | field to 1 to indicate that the number of hard links is not known. |
| 90 | * - 0x1C | 90 | * - 0x1C |
| 91 | - \_\_le32 | 91 | - __le32 |
| 92 | - i\_blocks\_lo | 92 | - i_blocks_lo |
| 93 | - Lower 32-bits of “block” count. If the huge\_file feature flag is not | 93 | - Lower 32-bits of “block” count. If the huge_file feature flag is not |
| 94 | set on the filesystem, the file consumes ``i_blocks_lo`` 512-byte blocks | 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 | ``inode.i_flags``, then the file consumes ``i_blocks_lo + (i_blocks_hi | 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 | 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 | 98 | EXT4_HUGE_FILE_FL IS set in ``inode.i_flags``, then this file |
| 99 | consumes (``i_blocks_lo + i_blocks_hi`` << 32) filesystem blocks on | 99 | consumes (``i_blocks_lo + i_blocks_hi`` << 32) filesystem blocks on |
| 100 | disk. | 100 | disk. |
| 101 | * - 0x20 | 101 | * - 0x20 |
| 102 | - \_\_le32 | 102 | - __le32 |
| 103 | - i\_flags | 103 | - i_flags |
| 104 | - Inode flags. See the table i_flags_ below. | 104 | - Inode flags. See the table i_flags_ below. |
| 105 | * - 0x24 | 105 | * - 0x24 |
| 106 | - 4 bytes | 106 | - 4 bytes |
| 107 | - i\_osd1 | 107 | - i_osd1 |
| 108 | - See the table i_osd1_ for more details. | 108 | - See the table i_osd1_ for more details. |
| 109 | * - 0x28 | 109 | * - 0x28 |
| 110 | - 60 bytes | 110 | - 60 bytes |
| 111 | - i\_block[EXT4\_N\_BLOCKS=15] | 111 | - i_block[EXT4_N_BLOCKS=15] |
| 112 | - Block map or extent tree. See the section “The Contents of inode.i\_block”. | 112 | - Block map or extent tree. See the section “The Contents of inode.i_block”. |
| 113 | * - 0x64 | 113 | * - 0x64 |
| 114 | - \_\_le32 | 114 | - __le32 |
| 115 | - i\_generation | 115 | - i_generation |
| 116 | - File version (for NFS). | 116 | - File version (for NFS). |
| 117 | * - 0x68 | 117 | * - 0x68 |
| 118 | - \_\_le32 | 118 | - __le32 |
| 119 | - i\_file\_acl\_lo | 119 | - i_file_acl_lo |
| 120 | - Lower 32-bits of extended attribute block. ACLs are of course one of | 120 | - Lower 32-bits of extended attribute block. ACLs are of course one of |
| 121 | many possible extended attributes; I think the name of this field is a | 121 | many possible extended attributes; I think the name of this field is a |
| 122 | result of the first use of extended attributes being for ACLs. | 122 | result of the first use of extended attributes being for ACLs. |
| 123 | * - 0x6C | 123 | * - 0x6C |
| 124 | - \_\_le32 | 124 | - __le32 |
| 125 | - i\_size\_high / i\_dir\_acl | 125 | - i_size_high / i_dir_acl |
| 126 | - Upper 32-bits of file/directory size. In ext2/3 this field was named | 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 | * - 0x70 | 128 | * - 0x70 |
| 129 | - \_\_le32 | 129 | - __le32 |
| 130 | - i\_obso\_faddr | 130 | - i_obso_faddr |
| 131 | - (Obsolete) fragment address. | 131 | - (Obsolete) fragment address. |
| 132 | * - 0x74 | 132 | * - 0x74 |
| 133 | - 12 bytes | 133 | - 12 bytes |
| 134 | - i\_osd2 | 134 | - i_osd2 |
| 135 | - See the table i_osd2_ for more details. | 135 | - See the table i_osd2_ for more details. |
| 136 | * - 0x80 | 136 | * - 0x80 |
| 137 | - \_\_le16 | 137 | - __le16 |
| 138 | - i\_extra\_isize | 138 | - i_extra_isize |
| 139 | - Size of this inode - 128. Alternately, the size of the extended inode | 139 | - Size of this inode - 128. Alternately, the size of the extended inode |
| 140 | fields beyond the original ext2 inode, including this field. | 140 | fields beyond the original ext2 inode, including this field. |
| 141 | * - 0x82 | 141 | * - 0x82 |
| 142 | - \_\_le16 | 142 | - __le16 |
| 143 | - i\_checksum\_hi | 143 | - i_checksum_hi |
| 144 | - Upper 16-bits of the inode checksum. | 144 | - Upper 16-bits of the inode checksum. |
| 145 | * - 0x84 | 145 | * - 0x84 |
| 146 | - \_\_le32 | 146 | - __le32 |
| 147 | - i\_ctime\_extra | 147 | - i_ctime_extra |
| 148 | - Extra change time bits. This provides sub-second precision. See Inode | 148 | - Extra change time bits. This provides sub-second precision. See Inode |
| 149 | Timestamps section. | 149 | Timestamps section. |
| 150 | * - 0x88 | 150 | * - 0x88 |
| 151 | - \_\_le32 | 151 | - __le32 |
| 152 | - i\_mtime\_extra | 152 | - i_mtime_extra |
| 153 | - Extra modification time bits. This provides sub-second precision. | 153 | - Extra modification time bits. This provides sub-second precision. |
| 154 | * - 0x8C | 154 | * - 0x8C |
| 155 | - \_\_le32 | 155 | - __le32 |
| 156 | - i\_atime\_extra | 156 | - i_atime_extra |
| 157 | - Extra access time bits. This provides sub-second precision. | 157 | - Extra access time bits. This provides sub-second precision. |
| 158 | * - 0x90 | 158 | * - 0x90 |
| 159 | - \_\_le32 | 159 | - __le32 |
| 160 | - i\_crtime | 160 | - i_crtime |
| 161 | - File creation time, in seconds since the epoch. | 161 | - File creation time, in seconds since the epoch. |
| 162 | * - 0x94 | 162 | * - 0x94 |
| 163 | - \_\_le32 | 163 | - __le32 |
| 164 | - i\_crtime\_extra | 164 | - i_crtime_extra |
| 165 | - Extra file creation time bits. This provides sub-second precision. | 165 | - Extra file creation time bits. This provides sub-second precision. |
| 166 | * - 0x98 | 166 | * - 0x98 |
| 167 | - \_\_le32 | 167 | - __le32 |
| 168 | - i\_version\_hi | 168 | - i_version_hi |
| 169 | - Upper 32-bits for version number. | 169 | - Upper 32-bits for version number. |
| 170 | * - 0x9C | 170 | * - 0x9C |
| 171 | - \_\_le32 | 171 | - __le32 |
| 172 | - i\_projid | 172 | - i_projid |
| 173 | - Project ID. | 173 | - Project ID. |
| 174 | 174 | ||
| 175 | .. _i_mode: | 175 | .. _i_mode: |
| @@ -183,45 +183,45 @@ The ``i_mode`` value is a combination of the following flags: · 7 unmodified lines | |||
| 183 | * - Value | 183 | * - Value |
| 184 | - Description | 184 | - Description |
| 185 | * - 0x1 | 185 | * - 0x1 |
| 186 | - S\_IXOTH (Others may execute) | 186 | - S_IXOTH (Others may execute) |
| 187 | * - 0x2 | 187 | * - 0x2 |
| 188 | - S\_IWOTH (Others may write) | 188 | - S_IWOTH (Others may write) |
| 189 | * - 0x4 | 189 | * - 0x4 |
| 190 | - S\_IROTH (Others may read) | 190 | - S_IROTH (Others may read) |
| 191 | * - 0x8 | 191 | * - 0x8 |
| 192 | - S\_IXGRP (Group members may execute) | 192 | - S_IXGRP (Group members may execute) |
| 193 | * - 0x10 | 193 | * - 0x10 |
| 194 | - S\_IWGRP (Group members may write) | 194 | - S_IWGRP (Group members may write) |
| 195 | * - 0x20 | 195 | * - 0x20 |
| 196 | - S\_IRGRP (Group members may read) | 196 | - S_IRGRP (Group members may read) |
| 197 | * - 0x40 | 197 | * - 0x40 |
| 198 | - S\_IXUSR (Owner may execute) | 198 | - S_IXUSR (Owner may execute) |
| 199 | * - 0x80 | 199 | * - 0x80 |
| 200 | - S\_IWUSR (Owner may write) | 200 | - S_IWUSR (Owner may write) |
| 201 | * - 0x100 | 201 | * - 0x100 |
| 202 | - S\_IRUSR (Owner may read) | 202 | - S_IRUSR (Owner may read) |
| 203 | * - 0x200 | 203 | * - 0x200 |
| 204 | - S\_ISVTX (Sticky bit) | 204 | - S_ISVTX (Sticky bit) |
| 205 | * - 0x400 | 205 | * - 0x400 |
| 206 | - S\_ISGID (Set GID) | 206 | - S_ISGID (Set GID) |
| 207 | * - 0x800 | 207 | * - 0x800 |
| 208 | - S\_ISUID (Set UID) | 208 | - S_ISUID (Set UID) |
| 209 | * - | 209 | * - |
| 210 | - These are mutually-exclusive file types: | 210 | - These are mutually-exclusive file types: |
| 211 | * - 0x1000 | 211 | * - 0x1000 |
| 212 | - S\_IFIFO (FIFO) | 212 | - S_IFIFO (FIFO) |
| 213 | * - 0x2000 | 213 | * - 0x2000 |
| 214 | - S\_IFCHR (Character device) | 214 | - S_IFCHR (Character device) |
| 215 | * - 0x4000 | 215 | * - 0x4000 |
| 216 | - S\_IFDIR (Directory) | 216 | - S_IFDIR (Directory) |
| 217 | * - 0x6000 | 217 | * - 0x6000 |
| 218 | - S\_IFBLK (Block device) | 218 | - S_IFBLK (Block device) |
| 219 | * - 0x8000 | 219 | * - 0x8000 |
| 220 | - S\_IFREG (Regular file) | 220 | - S_IFREG (Regular file) |
| 221 | * - 0xA000 | 221 | * - 0xA000 |
| 222 | - S\_IFLNK (Symbolic link) | 222 | - S_IFLNK (Symbolic link) |
| 223 | * - 0xC000 | 223 | * - 0xC000 |
| 224 | - S\_IFSOCK (Socket) | 224 | - S_IFSOCK (Socket) |
| 225 | 225 | ||
| 226 | .. _i_flags: | 226 | .. _i_flags: |
| 227 | 227 | ||
| @@ -234,56 +234,56 @@ The ``i_flags`` field is a combination of these values: · 6 unmodified lines | |||
| 234 | * - Value | 234 | * - Value |
| 235 | - Description | 235 | - Description |
| 236 | * - 0x1 | 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 | * - 0x2 | 238 | * - 0x2 |
| 239 | - This file should be preserved, should undeletion be desired | 239 | - This file should be preserved, should undeletion be desired |
| 240 | (EXT4\_UNRM\_FL). (not implemented) | 240 | (EXT4_UNRM_FL). (not implemented) |
| 241 | * - 0x4 | 241 | * - 0x4 |
| 242 | - File is compressed (EXT4\_COMPR\_FL). (not really implemented) | 242 | - File is compressed (EXT4_COMPR_FL). (not really implemented) |
| 243 | * - 0x8 | 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 | * - 0x10 | 245 | * - 0x10 |
| 246 | - File is immutable (EXT4\_IMMUTABLE\_FL). | 246 | - File is immutable (EXT4_IMMUTABLE_FL). |
| 247 | * - 0x20 | 247 | * - 0x20 |
| 248 | - File can only be appended (EXT4\_APPEND\_FL). | 248 | - File can only be appended (EXT4_APPEND_FL). |
| 249 | * - 0x40 | 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 | * - 0x80 | 251 | * - 0x80 |
| 252 | - Do not update access time (EXT4\_NOATIME\_FL). | 252 | - Do not update access time (EXT4_NOATIME_FL). |
| 253 | * - 0x100 | 253 | * - 0x100 |
| 254 | - Dirty compressed file (EXT4\_DIRTY\_FL). (not used) | 254 | - Dirty compressed file (EXT4_DIRTY_FL). (not used) |
| 255 | * - 0x200 | 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 | * - 0x400 | 257 | * - 0x400 |
| 258 | - Do not compress file (EXT4\_NOCOMPR\_FL). (not used) | 258 | - Do not compress file (EXT4_NOCOMPR_FL). (not used) |
| 259 | * - 0x800 | 259 | * - 0x800 |
| 260 | - Encrypted inode (EXT4\_ENCRYPT\_FL). This bit value previously was | 260 | - Encrypted inode (EXT4_ENCRYPT_FL). This bit value previously was |
| 261 | EXT4\_ECOMPR\_FL (compression error), which was never used. | 261 | EXT4_ECOMPR_FL (compression error), which was never used. |
| 262 | * - 0x1000 | 262 | * - 0x1000 |
| 263 | - Directory has hashed indexes (EXT4\_INDEX\_FL). | 263 | - Directory has hashed indexes (EXT4_INDEX_FL). |
| 264 | * - 0x2000 | 264 | * - 0x2000 |
| 265 | - AFS magic directory (EXT4\_IMAGIC\_FL). | 265 | - AFS magic directory (EXT4_IMAGIC_FL). |
| 266 | * - 0x4000 | 266 | * - 0x4000 |
| 267 | - File data must always be written through the journal | 267 | - File data must always be written through the journal |
| 268 | (EXT4\_JOURNAL\_DATA\_FL). | 268 | (EXT4_JOURNAL_DATA_FL). |
| 269 | * - 0x8000 | 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 | * - 0x10000 | 271 | * - 0x10000 |
| 272 | - All directory entry data should be written synchronously (see | 272 | - All directory entry data should be written synchronously (see |
| 273 | ``dirsync``) (EXT4\_DIRSYNC\_FL). | 273 | ``dirsync``) (EXT4_DIRSYNC_FL). |
| 274 | * - 0x20000 | 274 | * - 0x20000 |
| 275 | - Top of directory hierarchy (EXT4\_TOPDIR\_FL). | 275 | - Top of directory hierarchy (EXT4_TOPDIR_FL). |
| 276 | * - 0x40000 | 276 | * - 0x40000 |
| 277 | - This is a huge file (EXT4\_HUGE\_FILE\_FL). | 277 | - This is a huge file (EXT4_HUGE_FILE_FL). |
| 278 | * - 0x80000 | 278 | * - 0x80000 |
| 279 | - Inode uses extents (EXT4\_EXTENTS\_FL). | 279 | - Inode uses extents (EXT4_EXTENTS_FL). |
| 280 | * - 0x100000 | 280 | * - 0x100000 |
| 281 | - Verity protected file (EXT4\_VERITY\_FL). | 281 | - Verity protected file (EXT4_VERITY_FL). |
| 282 | * - 0x200000 | 282 | * - 0x200000 |
| 283 | - Inode stores a large extended attribute value in its data blocks | 283 | - Inode stores a large extended attribute value in its data blocks |
| 284 | (EXT4\_EA\_INODE\_FL). | 284 | (EXT4_EA_INODE_FL). |
| 285 | * - 0x400000 | 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 | (deprecated) | 287 | (deprecated) |
| 288 | * - 0x01000000 | 288 | * - 0x01000000 |
| 289 | - Inode is a snapshot (``EXT4_SNAPFILE_FL``). (not in mainline) | 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 | - Snapshot shrink has completed (``EXT4_SNAPFILE_SHRUNK_FL``). (not in | 294 | - Snapshot shrink has completed (``EXT4_SNAPFILE_SHRUNK_FL``). (not in |
| 295 | mainline) | 295 | mainline) |
| 296 | * - 0x10000000 | 296 | * - 0x10000000 |
| 297 | - Inode has inline data (EXT4\_INLINE\_DATA\_FL). | 297 | - Inode has inline data (EXT4_INLINE_DATA_FL). |
| 298 | * - 0x20000000 | 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 | * - 0x80000000 | 300 | * - 0x80000000 |
| 301 | - Reserved for ext4 library (EXT4\_RESERVED\_FL). | 301 | - Reserved for ext4 library (EXT4_RESERVED_FL). |
| 302 | * - | 302 | * - |
| 303 | - Aggregate flags: | 303 | - Aggregate flags: |
| 304 | * - 0x705BDFFF | 304 | * - 0x705BDFFF |
| 305 | - User-visible flags. | 305 | - User-visible flags. |
| 306 | * - 0x604BC0FF | 306 | * - 0x604BC0FF |
| 307 | - User-modifiable flags. Note that while EXT4\_JOURNAL\_DATA\_FL and | 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 | 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 | 309 | EXT4_FL_USER_MODIFIABLE mask, since it needs to handle the setting of |
| 310 | these flags in a special manner and they are masked out of the set of | 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 | .. _i_osd1: | 313 | .. _i_osd1: |
| 314 | 314 | ||
| @@ -325,9 +325,9 @@ Linux: · 10 unmodified lines | |||
| 325 | - Name | 325 | - Name |
| 326 | - Description | 326 | - Description |
| 327 | * - 0x0 | 327 | * - 0x0 |
| 328 | - \_\_le32 | 328 | - __le32 |
| 329 | - l\_i\_version | 329 | - l_i_version |
| 330 | - Inode version. However, if the EA\_INODE inode flag is set, this inode | 330 | - Inode version. However, if the EA_INODE inode flag is set, this inode |
| 331 | stores an extended attribute value and this field contains the upper 32 | 331 | stores an extended attribute value and this field contains the upper 32 |
| 332 | bits of the attribute value's reference count. | 332 | bits of the attribute value's reference count. |
| 333 | 333 | ||
| @@ -342,8 +342,8 @@ Hurd: · 8 unmodified lines | |||
| 342 | - Name | 342 | - Name |
| 343 | - Description | 343 | - Description |
| 344 | * - 0x0 | 344 | * - 0x0 |
| 345 | - \_\_le32 | 345 | - __le32 |
| 346 | - h\_i\_translator | 346 | - h_i_translator |
| 347 | - ?? | 347 | - ?? |
| 348 | 348 | ||
| 349 | Masix: | 349 | Masix: |
| @@ -357,8 +357,8 @@ Masix: · 7 unmodified lines | |||
| 357 | - Name | 357 | - Name |
| 358 | - Description | 358 | - Description |
| 359 | * - 0x0 | 359 | * - 0x0 |
| 360 | - \_\_le32 | 360 | - __le32 |
| 361 | - m\_i\_reserved | 361 | - m_i_reserved |
| 362 | - ?? | 362 | - ?? |
| 363 | 363 | ||
| 364 | .. _i_osd2: | 364 | .. _i_osd2: |
| @@ -376,30 +376,30 @@ Linux: · 11 unmodified lines | |||
| 376 | - Name | 376 | - Name |
| 377 | - Description | 377 | - Description |
| 378 | * - 0x0 | 378 | * - 0x0 |
| 379 | - \_\_le16 | 379 | - __le16 |
| 380 | - l\_i\_blocks\_high | 380 | - l_i_blocks_high |
| 381 | - Upper 16-bits of the block count. Please see the note attached to | 381 | - Upper 16-bits of the block count. Please see the note attached to |
| 382 | i\_blocks\_lo. | 382 | i_blocks_lo. |
| 383 | * - 0x2 | 383 | * - 0x2 |
| 384 | - \_\_le16 | 384 | - __le16 |
| 385 | - l\_i\_file\_acl\_high | 385 | - l_i_file_acl_high |
| 386 | - Upper 16-bits of the extended attribute block (historically, the file | 386 | - Upper 16-bits of the extended attribute block (historically, the file |
| 387 | ACL location). See the Extended Attributes section below. | 387 | ACL location). See the Extended Attributes section below. |
| 388 | * - 0x4 | 388 | * - 0x4 |
| 389 | - \_\_le16 | 389 | - __le16 |
| 390 | - l\_i\_uid\_high | 390 | - l_i_uid_high |
| 391 | - Upper 16-bits of the Owner UID. | 391 | - Upper 16-bits of the Owner UID. |
| 392 | * - 0x6 | 392 | * - 0x6 |
| 393 | - \_\_le16 | 393 | - __le16 |
| 394 | - l\_i\_gid\_high | 394 | - l_i_gid_high |
| 395 | - Upper 16-bits of the GID. | 395 | - Upper 16-bits of the GID. |
| 396 | * - 0x8 | 396 | * - 0x8 |
| 397 | - \_\_le16 | 397 | - __le16 |
| 398 | - l\_i\_checksum\_lo | 398 | - l_i_checksum_lo |
| 399 | - Lower 16-bits of the inode checksum. | 399 | - Lower 16-bits of the inode checksum. |
| 400 | * - 0xA | 400 | * - 0xA |
| 401 | - \_\_le16 | 401 | - __le16 |
| 402 | - l\_i\_reserved | 402 | - l_i_reserved |
| 403 | - Unused. | 403 | - Unused. |
| 404 | 404 | ||
| 405 | Hurd: | 405 | Hurd: |
| @@ -413,24 +413,24 @@ Hurd: · 7 unmodified lines | |||
| 413 | - Name | 413 | - Name |
| 414 | - Description | 414 | - Description |
| 415 | * - 0x0 | 415 | * - 0x0 |
| 416 | - \_\_le16 | 416 | - __le16 |
| 417 | - h\_i\_reserved1 | 417 | - h_i_reserved1 |
| 418 | - ?? | 418 | - ?? |
| 419 | * - 0x2 | 419 | * - 0x2 |
| 420 | - \_\_u16 | 420 | - __u16 |
| 421 | - h\_i\_mode\_high | 421 | - h_i_mode_high |
| 422 | - Upper 16-bits of the file mode. | 422 | - Upper 16-bits of the file mode. |
| 423 | * - 0x4 | 423 | * - 0x4 |
| 424 | - \_\_le16 | 424 | - __le16 |
| 425 | - h\_i\_uid\_high | 425 | - h_i_uid_high |
| 426 | - Upper 16-bits of the Owner UID. | 426 | - Upper 16-bits of the Owner UID. |
| 427 | * - 0x6 | 427 | * - 0x6 |
| 428 | - \_\_le16 | 428 | - __le16 |
| 429 | - h\_i\_gid\_high | 429 | - h_i_gid_high |
| 430 | - Upper 16-bits of the GID. | 430 | - Upper 16-bits of the GID. |
| 431 | * - 0x8 | 431 | * - 0x8 |
| 432 | - \_\_u32 | 432 | - __u32 |
| 433 | - h\_i\_author | 433 | - h_i_author |
| 434 | - Author code? | 434 | - Author code? |
| 435 | 435 | ||
| 436 | Masix: | 436 | Masix: |
| @@ -444,17 +444,17 @@ Masix: · 7 unmodified lines | |||
| 444 | - Name | 444 | - Name |
| 445 | - Description | 445 | - Description |
| 446 | * - 0x0 | 446 | * - 0x0 |
| 447 | - \_\_le16 | 447 | - __le16 |
| 448 | - h\_i\_reserved1 | 448 | - h_i_reserved1 |
| 449 | - ?? | 449 | - ?? |
| 450 | * - 0x2 | 450 | * - 0x2 |
| 451 | - \_\_u16 | 451 | - __u16 |
| 452 | - m\_i\_file\_acl\_high | 452 | - m_i_file_acl_high |
| 453 | - Upper 16-bits of the extended attribute block (historically, the file | 453 | - Upper 16-bits of the extended attribute block (historically, the file |
| 454 | ACL location). | 454 | ACL location). |
| 455 | * - 0x4 | 455 | * - 0x4 |
| 456 | - \_\_u32 | 456 | - __u32 |
| 457 | - m\_i\_reserved2[2] | 457 | - m_i_reserved2[2] |
| 458 | - ?? | 458 | - ?? |
| 459 | 459 | ||
| 460 | Inode Size | 460 | Inode Size |
| @@ -466,11 +466,11 @@ In ext2 and ext3, the inode structure size was fixed at 128 bytes · 5 unmodified lines | |||
| 466 | on-disk inode at format time for all inodes in the filesystem to provide | 466 | on-disk inode at format time for all inodes in the filesystem to provide |
| 467 | space beyond the end of the original ext2 inode. The on-disk inode | 467 | space beyond the end of the original ext2 inode. The on-disk inode |
| 468 | record size is recorded in the superblock as ``s_inode_size``. The | 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 | 128-byte ext2 inode is recorded in the ``i_extra_isize`` field for each | 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 | having to upgrade all of the on-disk inodes. Access to fields beyond | 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 | ``i_extra_isize``. By default, ext4 inode records are 256 bytes, and (as | 474 | ``i_extra_isize``. By default, ext4 inode records are 256 bytes, and (as |
| 475 | of August 2019) the inode structure is 160 bytes | 475 | of August 2019) the inode structure is 160 bytes |
| 476 | (``i_extra_isize = 32``). The extra space between the end of the inode | 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 | same manner as 64-bit [cma]time. Neither crtime nor dtime are accessible | 516 | same manner as 64-bit [cma]time. Neither crtime nor dtime are accessible |
| 517 | through the regular stat() interface, though debugfs will report them. | 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 | In other words: | 520 | In other words: |
| 521 | 521 | ||
| 522 | .. list-table:: | 522 | .. list-table:: |
| @@ -525,8 +525,8 @@ In other words: · 2 unmodified lines | |||
| 525 | 525 | ||
| 526 | * - Extra epoch bits | 526 | * - Extra epoch bits |
| 527 | - MSB of 32-bit time | 527 | - MSB of 32-bit time |
| 528 | - Adjustment for signed 32-bit to 64-bit tv\_sec | 528 | - Adjustment for signed 32-bit to 64-bit tv_sec |
| 529 | - Decoded 64-bit tv\_sec | 529 | - Decoded 64-bit tv_sec |
| 530 | - valid time range | 530 | - valid time range |
| 531 | * - 0 0 | 531 | * - 0 0 |
| 532 | - 1 | 532 | - 1 |
| @@ -63,8 +63,8 @@ Generally speaking, the journal has this format: · 62 unmodified lines | |||
| 63 | :header-rows: 1 | 63 | :header-rows: 1 |
| 64 | 64 | ||
| 65 | * - Superblock | 65 | * - Superblock |
| 66 | - descriptor\_block (data\_blocks or revocation\_block) [more data or | 66 | - descriptor_block (data_blocks or revocation_block) [more data or |
| 67 | revocations] commmit\_block | 67 | revocations] commmit_block |
| 68 | - [more transactions...] | 68 | - [more transactions...] |
| 69 | * - | 69 | * - |
| 70 | - One transaction | 70 | - One transaction |
| @@ -93,8 +93,8 @@ superblock. · 22 unmodified lines | |||
| 93 | * - 1024 bytes of padding | 93 | * - 1024 bytes of padding |
| 94 | - ext4 Superblock | 94 | - ext4 Superblock |
| 95 | - Journal Superblock | 95 | - Journal Superblock |
| 96 | - descriptor\_block (data\_blocks or revocation\_block) [more data or | 96 | - descriptor_block (data_blocks or revocation_block) [more data or |
| 97 | revocations] commmit\_block | 97 | revocations] commmit_block |
| 98 | - [more transactions...] | 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 | - Name | 117 | - Name |
| 118 | - Description | 118 | - Description |
| 119 | * - 0x0 | 119 | * - 0x0 |
| 120 | - \_\_be32 | 120 | - __be32 |
| 121 | - h\_magic | 121 | - h_magic |
| 122 | - jbd2 magic number, 0xC03B3998. | 122 | - jbd2 magic number, 0xC03B3998. |
| 123 | * - 0x4 | 123 | * - 0x4 |
| 124 | - \_\_be32 | 124 | - __be32 |
| 125 | - h\_blocktype | 125 | - h_blocktype |
| 126 | - Description of what this block contains. See the jbd2_blocktype_ table | 126 | - Description of what this block contains. See the jbd2_blocktype_ table |
| 127 | below. | 127 | below. |
| 128 | * - 0x8 | 128 | * - 0x8 |
| 129 | - \_\_be32 | 129 | - __be32 |
| 130 | - h\_sequence | 130 | - h_sequence |
| 131 | - The transaction ID that goes with this block. | 131 | - The transaction ID that goes with this block. |
| 132 | 132 | ||
| 133 | .. _jbd2_blocktype: | 133 | .. _jbd2_blocktype: |
| @@ -177,99 +177,99 @@ which is 1024 bytes long: · 43 unmodified lines | |||
| 177 | - | 177 | - |
| 178 | - Static information describing the journal. | 178 | - Static information describing the journal. |
| 179 | * - 0x0 | 179 | * - 0x0 |
| 180 | - journal\_header\_t (12 bytes) | 180 | - journal_header_t (12 bytes) |
| 181 | - s\_header | 181 | - s_header |
| 182 | - Common header identifying this as a superblock. | 182 | - Common header identifying this as a superblock. |
| 183 | * - 0xC | 183 | * - 0xC |
| 184 | - \_\_be32 | 184 | - __be32 |
| 185 | - s\_blocksize | 185 | - s_blocksize |
| 186 | - Journal device block size. | 186 | - Journal device block size. |
| 187 | * - 0x10 | 187 | * - 0x10 |
| 188 | - \_\_be32 | 188 | - __be32 |
| 189 | - s\_maxlen | 189 | - s_maxlen |
| 190 | - Total number of blocks in this journal. | 190 | - Total number of blocks in this journal. |
| 191 | * - 0x14 | 191 | * - 0x14 |
| 192 | - \_\_be32 | 192 | - __be32 |
| 193 | - s\_first | 193 | - s_first |
| 194 | - First block of log information. | 194 | - First block of log information. |
| 195 | * - | 195 | * - |
| 196 | - | 196 | - |
| 197 | - | 197 | - |
| 198 | - Dynamic information describing the current state of the log. | 198 | - Dynamic information describing the current state of the log. |
| 199 | * - 0x18 | 199 | * - 0x18 |
| 200 | - \_\_be32 | 200 | - __be32 |
| 201 | - s\_sequence | 201 | - s_sequence |
| 202 | - First commit ID expected in log. | 202 | - First commit ID expected in log. |
| 203 | * - 0x1C | 203 | * - 0x1C |
| 204 | - \_\_be32 | 204 | - __be32 |
| 205 | - s\_start | 205 | - s_start |
| 206 | - Block number of the start of log. Contrary to the comments, this field | 206 | - Block number of the start of log. Contrary to the comments, this field |
| 207 | being zero does not imply that the journal is clean! | 207 | being zero does not imply that the journal is clean! |
| 208 | * - 0x20 | 208 | * - 0x20 |
| 209 | - \_\_be32 | 209 | - __be32 |
| 210 | - s\_errno | 210 | - s_errno |
| 211 | - Error value, as set by jbd2\_journal\_abort(). | 211 | - Error value, as set by jbd2_journal_abort(). |
| 212 | * - | 212 | * - |
| 213 | - | 213 | - |
| 214 | - | 214 | - |
| 215 | - The remaining fields are only valid in a v2 superblock. | 215 | - The remaining fields are only valid in a v2 superblock. |
| 216 | * - 0x24 | 216 | * - 0x24 |
| 217 | - \_\_be32 | 217 | - __be32 |
| 218 | - s\_feature\_compat; | 218 | - s_feature_compat; |
| 219 | - Compatible feature set. See the table jbd2_compat_ below. | 219 | - Compatible feature set. See the table jbd2_compat_ below. |
| 220 | * - 0x28 | 220 | * - 0x28 |
| 221 | - \_\_be32 | 221 | - __be32 |
| 222 | - s\_feature\_incompat | 222 | - s_feature_incompat |
| 223 | - Incompatible feature set. See the table jbd2_incompat_ below. | 223 | - Incompatible feature set. See the table jbd2_incompat_ below. |
| 224 | * - 0x2C | 224 | * - 0x2C |
| 225 | - \_\_be32 | 225 | - __be32 |
| 226 | - s\_feature\_ro\_compat | 226 | - s_feature_ro_compat |
| 227 | - Read-only compatible feature set. There aren't any of these currently. | 227 | - Read-only compatible feature set. There aren't any of these currently. |
| 228 | * - 0x30 | 228 | * - 0x30 |
| 229 | - \_\_u8 | 229 | - __u8 |
| 230 | - s\_uuid[16] | 230 | - s_uuid[16] |
| 231 | - 128-bit uuid for journal. This is compared against the copy in the ext4 | 231 | - 128-bit uuid for journal. This is compared against the copy in the ext4 |
| 232 | super block at mount time. | 232 | super block at mount time. |
| 233 | * - 0x40 | 233 | * - 0x40 |
| 234 | - \_\_be32 | 234 | - __be32 |
| 235 | - s\_nr\_users | 235 | - s_nr_users |
| 236 | - Number of file systems sharing this journal. | 236 | - Number of file systems sharing this journal. |
| 237 | * - 0x44 | 237 | * - 0x44 |
| 238 | - \_\_be32 | 238 | - __be32 |
| 239 | - s\_dynsuper | 239 | - s_dynsuper |
| 240 | - Location of dynamic super block copy. (Not used?) | 240 | - Location of dynamic super block copy. (Not used?) |
| 241 | * - 0x48 | 241 | * - 0x48 |
| 242 | - \_\_be32 | 242 | - __be32 |
| 243 | - s\_max\_transaction | 243 | - s_max_transaction |
| 244 | - Limit of journal blocks per transaction. (Not used?) | 244 | - Limit of journal blocks per transaction. (Not used?) |
| 245 | * - 0x4C | 245 | * - 0x4C |
| 246 | - \_\_be32 | 246 | - __be32 |
| 247 | - s\_max\_trans\_data | 247 | - s_max_trans_data |
| 248 | - Limit of data blocks per transaction. (Not used?) | 248 | - Limit of data blocks per transaction. (Not used?) |
| 249 | * - 0x50 | 249 | * - 0x50 |
| 250 | - \_\_u8 | 250 | - __u8 |
| 251 | - s\_checksum\_type | 251 | - s_checksum_type |
| 252 | - Checksum algorithm used for the journal. See jbd2_checksum_type_ for | 252 | - Checksum algorithm used for the journal. See jbd2_checksum_type_ for |
| 253 | more info. | 253 | more info. |
| 254 | * - 0x51 | 254 | * - 0x51 |
| 255 | - \_\_u8[3] | 255 | - __u8[3] |
| 256 | - s\_padding2 | 256 | - s_padding2 |
| 257 | - | 257 | - |
| 258 | * - 0x54 | 258 | * - 0x54 |
| 259 | - \_\_be32 | 259 | - __be32 |
| 260 | - s\_num\_fc\_blocks | 260 | - s_num_fc_blocks |
| 261 | - Number of fast commit blocks in the journal. | 261 | - Number of fast commit blocks in the journal. |
| 262 | * - 0x58 | 262 | * - 0x58 |
| 263 | - \_\_u32 | 263 | - __u32 |
| 264 | - s\_padding[42] | 264 | - s_padding[42] |
| 265 | - | 265 | - |
| 266 | * - 0xFC | 266 | * - 0xFC |
| 267 | - \_\_be32 | 267 | - __be32 |
| 268 | - s\_checksum | 268 | - s_checksum |
| 269 | - Checksum of the entire superblock, with this field set to zero. | 269 | - Checksum of the entire superblock, with this field set to zero. |
| 270 | * - 0x100 | 270 | * - 0x100 |
| 271 | - \_\_u8 | 271 | - __u8 |
| 272 | - s\_users[16\*48] | 272 | - s_users[16*48] |
| 273 | - ids of all file systems sharing the log. e2fsprogs/Linux don't allow | 273 | - ids of all file systems sharing the log. e2fsprogs/Linux don't allow |
| 274 | shared external journals, but I imagine Lustre (or ocfs2?), which use | 274 | shared external journals, but I imagine Lustre (or ocfs2?), which use |
| 275 | the jbd2 code, might. | 275 | the jbd2 code, might. |
| @@ -286,7 +286,7 @@ The journal compat features are any combination of the following: · 10 unmodified lines | |||
| 286 | - Description | 286 | - Description |
| 287 | * - 0x1 | 287 | * - 0x1 |
| 288 | - Journal maintains checksums on the data blocks. | 288 | - Journal maintains checksums on the data blocks. |
| 289 | (JBD2\_FEATURE\_COMPAT\_CHECKSUM) | 289 | (JBD2_FEATURE_COMPAT_CHECKSUM) |
| 290 | 290 | ||
| 291 | .. _jbd2_incompat: | 291 | .. _jbd2_incompat: |
| 292 | 292 | ||
| @@ -299,23 +299,23 @@ The journal incompat features are any combination of the following: · 6 unmodified lines | |||
| 299 | * - Value | 299 | * - Value |
| 300 | - Description | 300 | - Description |
| 301 | * - 0x1 | 301 | * - 0x1 |
| 302 | - Journal has block revocation records. (JBD2\_FEATURE\_INCOMPAT\_REVOKE) | 302 | - Journal has block revocation records. (JBD2_FEATURE_INCOMPAT_REVOKE) |
| 303 | * - 0x2 | 303 | * - 0x2 |
| 304 | - Journal can deal with 64-bit block numbers. | 304 | - Journal can deal with 64-bit block numbers. |
| 305 | (JBD2\_FEATURE\_INCOMPAT\_64BIT) | 305 | (JBD2_FEATURE_INCOMPAT_64BIT) |
| 306 | * - 0x4 | 306 | * - 0x4 |
| 307 | - Journal commits asynchronously. (JBD2\_FEATURE\_INCOMPAT\_ASYNC\_COMMIT) | 307 | - Journal commits asynchronously. (JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) |
| 308 | * - 0x8 | 308 | * - 0x8 |
| 309 | - This journal uses v2 of the checksum on-disk format. Each journal | 309 | - This journal uses v2 of the checksum on-disk format. Each journal |
| 310 | metadata block gets its own checksum, and the block tags in the | 310 | metadata block gets its own checksum, and the block tags in the |
| 311 | descriptor table contain checksums for each of the data blocks in the | 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 | * - 0x10 | 313 | * - 0x10 |
| 314 | - This journal uses v3 of the checksum on-disk format. This is the same as | 314 | - This journal uses v3 of the checksum on-disk format. This is the same as |
| 315 | v2, but the journal block tag size is fixed regardless of the size of | 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 | * - 0x20 | 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 | .. _jbd2_checksum_type: | 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 | - Name | 355 | - Name |
| 356 | - Descriptor | 356 | - Descriptor |
| 357 | * - 0x0 | 357 | * - 0x0 |
| 358 | - journal\_header\_t | 358 | - journal_header_t |
| 359 | - (open coded) | 359 | - (open coded) |
| 360 | - Common block header. | 360 | - Common block header. |
| 361 | * - 0xC | 361 | * - 0xC |
| 362 | - struct journal\_block\_tag\_s | 362 | - struct journal_block_tag_s |
| 363 | - open coded array[] | 363 | - open coded array[] |
| 364 | - Enough tags either to fill up the block or to describe all the data | 364 | - Enough tags either to fill up the block or to describe all the data |
| 365 | blocks that follow this descriptor block. | 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 | Journal block tags have any of the following formats, depending on which | 367 | Journal block tags have any of the following formats, depending on which |
| 368 | journal feature and block tag flags are set. | 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 | defined as ``struct journal_block_tag3_s``, which looks like the | 371 | defined as ``struct journal_block_tag3_s``, which looks like the |
| 372 | following. The size is 16 or 32 bytes. | 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 | - Name | 380 | - Name |
| 381 | - Descriptor | 381 | - Descriptor |
| 382 | * - 0x0 | 382 | * - 0x0 |
| 383 | - \_\_be32 | 383 | - __be32 |
| 384 | - t\_blocknr | 384 | - t_blocknr |
| 385 | - Lower 32-bits of the location of where the corresponding data block | 385 | - Lower 32-bits of the location of where the corresponding data block |
| 386 | should end up on disk. | 386 | should end up on disk. |
| 387 | * - 0x4 | 387 | * - 0x4 |
| 388 | - \_\_be32 | 388 | - __be32 |
| 389 | - t\_flags | 389 | - t_flags |
| 390 | - Flags that go with the descriptor. See the table jbd2_tag_flags_ for | 390 | - Flags that go with the descriptor. See the table jbd2_tag_flags_ for |
| 391 | more info. | 391 | more info. |
| 392 | * - 0x8 | 392 | * - 0x8 |
| 393 | - \_\_be32 | 393 | - __be32 |
| 394 | - t\_blocknr\_high | 394 | - t_blocknr_high |
| 395 | - Upper 32-bits of the location of where the corresponding data block | 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 | not enabled. | 397 | not enabled. |
| 398 | * - 0xC | 398 | * - 0xC |
| 399 | - \_\_be32 | 399 | - __be32 |
| 400 | - t\_checksum | 400 | - t_checksum |
| 401 | - Checksum of the journal UUID, the sequence number, and the data block. | 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 | * - 0x8 | 433 | * - 0x8 |
| 434 | - This is the last tag in this descriptor block. | 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 | is defined as ``struct journal_block_tag_s``, which looks like the | 437 | is defined as ``struct journal_block_tag_s``, which looks like the |
| 438 | following. The size is 8, 12, 24, or 28 bytes: | 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 | - Name | 446 | - Name |
| 447 | - Descriptor | 447 | - Descriptor |
| 448 | * - 0x0 | 448 | * - 0x0 |
| 449 | - \_\_be32 | 449 | - __be32 |
| 450 | - t\_blocknr | 450 | - t_blocknr |
| 451 | - Lower 32-bits of the location of where the corresponding data block | 451 | - Lower 32-bits of the location of where the corresponding data block |
| 452 | should end up on disk. | 452 | should end up on disk. |
| 453 | * - 0x4 | 453 | * - 0x4 |
| 454 | - \_\_be16 | 454 | - __be16 |
| 455 | - t\_checksum | 455 | - t_checksum |
| 456 | - Checksum of the journal UUID, the sequence number, and the data block. | 456 | - Checksum of the journal UUID, the sequence number, and the data block. |
| 457 | Note that only the lower 16 bits are stored. | 457 | Note that only the lower 16 bits are stored. |
| 458 | * - 0x6 | 458 | * - 0x6 |
| 459 | - \_\_be16 | 459 | - __be16 |
| 460 | - t\_flags | 460 | - t_flags |
| 461 | - Flags that go with the descriptor. See the table jbd2_tag_flags_ for | 461 | - Flags that go with the descriptor. See the table jbd2_tag_flags_ for |
| 462 | more info. | 462 | more info. |
| 463 | * - | 463 | * - |
| @@ -466,8 +466,8 @@ following. The size is 8, 12, 24, or 28 bytes: · 2 unmodified lines | |||
| 466 | - This next field is only present if the super block indicates support for | 466 | - This next field is only present if the super block indicates support for |
| 467 | 64-bit block numbers. | 467 | 64-bit block numbers. |
| 468 | * - 0x8 | 468 | * - 0x8 |
| 469 | - \_\_be32 | 469 | - __be32 |
| 470 | - t\_blocknr\_high | 470 | - t_blocknr_high |
| 471 | - Upper 32-bits of the location of where the corresponding data block | 471 | - Upper 32-bits of the location of where the corresponding data block |
| 472 | should end up on disk. | 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 | ``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that | 483 | ``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that |
| 484 | field. | 484 | field. |
| 485 | 485 | ||
| 486 | If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or | 486 | If JBD2_FEATURE_INCOMPAT_CSUM_V2 or |
| 487 | JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the block is a | 487 | JBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the block is a |
| 488 | ``struct jbd2_journal_block_tail``, which looks like this: | 488 | ``struct jbd2_journal_block_tail``, which looks like this: |
| 489 | 489 | ||
| 490 | .. list-table:: | 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 | - Name | 496 | - Name |
| 497 | - Descriptor | 497 | - Descriptor |
| 498 | * - 0x0 | 498 | * - 0x0 |
| 499 | - \_\_be32 | 499 | - __be32 |
| 500 | - t\_checksum | 500 | - t_checksum |
| 501 | - Checksum of the journal UUID + the descriptor block, with this field set | 501 | - Checksum of the journal UUID + the descriptor block, with this field set |
| 502 | to zero. | 502 | to zero. |
| 503 | 503 | ||
| @@ -538,25 +538,25 @@ length, but use a full block: · 34 unmodified lines | |||
| 538 | - Name | 538 | - Name |
| 539 | - Description | 539 | - Description |
| 540 | * - 0x0 | 540 | * - 0x0 |
| 541 | - journal\_header\_t | 541 | - journal_header_t |
| 542 | - r\_header | 542 | - r_header |
| 543 | - Common block header. | 543 | - Common block header. |
| 544 | * - 0xC | 544 | * - 0xC |
| 545 | - \_\_be32 | 545 | - __be32 |
| 546 | - r\_count | 546 | - r_count |
| 547 | - Number of bytes used in this block. | 547 | - Number of bytes used in this block. |
| 548 | * - 0x10 | 548 | * - 0x10 |
| 549 | - \_\_be32 or \_\_be64 | 549 | - __be32 or __be64 |
| 550 | - blocks[0] | 550 | - blocks[0] |
| 551 | - Blocks to revoke. | 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 | revoked by this transaction. The size of each block number is 8 bytes if | 554 | revoked by this transaction. The size of each block number is 8 bytes if |
| 555 | the superblock advertises 64-bit block number support, or 4 bytes | 555 | the superblock advertises 64-bit block number support, or 4 bytes |
| 556 | otherwise. | 556 | otherwise. |
| 557 | 557 | ||
| 558 | If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or | 558 | If JBD2_FEATURE_INCOMPAT_CSUM_V2 or |
| 559 | JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the revocation | 559 | JBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the revocation |
| 560 | block is a ``struct jbd2_journal_revoke_tail``, which has this format: | 560 | block is a ``struct jbd2_journal_revoke_tail``, which has this format: |
| 561 | 561 | ||
| 562 | .. list-table:: | 562 | .. list-table:: |
| @@ -568,8 +568,8 @@ block is a ``struct jbd2_journal_revoke_tail``, which has this format: · 5 unmodified lines | |||
| 568 | - Name | 568 | - Name |
| 569 | - Description | 569 | - Description |
| 570 | * - 0x0 | 570 | * - 0x0 |
| 571 | - \_\_be32 | 571 | - __be32 |
| 572 | - r\_checksum | 572 | - r_checksum |
| 573 | - Checksum of the journal UUID + revocation block | 573 | - Checksum of the journal UUID + revocation block |
| 574 | 574 | ||
| 575 | Commit Block | 575 | Commit Block |
| @@ -592,38 +592,38 @@ bytes long (but uses a full block): · 16 unmodified lines | |||
| 592 | - Name | 592 | - Name |
| 593 | - Descriptor | 593 | - Descriptor |
| 594 | * - 0x0 | 594 | * - 0x0 |
| 595 | - journal\_header\_s | 595 | - journal_header_s |
| 596 | - (open coded) | 596 | - (open coded) |
| 597 | - Common block header. | 597 | - Common block header. |
| 598 | * - 0xC | 598 | * - 0xC |
| 599 | - unsigned char | 599 | - unsigned char |
| 600 | - h\_chksum\_type | 600 | - h_chksum_type |
| 601 | - The type of checksum to use to verify the integrity of the data blocks | 601 | - The type of checksum to use to verify the integrity of the data blocks |
| 602 | in the transaction. See jbd2_checksum_type_ for more info. | 602 | in the transaction. See jbd2_checksum_type_ for more info. |
| 603 | * - 0xD | 603 | * - 0xD |
| 604 | - unsigned char | 604 | - unsigned char |
| 605 | - h\_chksum\_size | 605 | - h_chksum_size |
| 606 | - The number of bytes used by the checksum. Most likely 4. | 606 | - The number of bytes used by the checksum. Most likely 4. |
| 607 | * - 0xE | 607 | * - 0xE |
| 608 | - unsigned char | 608 | - unsigned char |
| 609 | - h\_padding[2] | 609 | - h_padding[2] |
| 610 | - | 610 | - |
| 611 | * - 0x10 | 611 | * - 0x10 |
| 612 | - \_\_be32 | 612 | - __be32 |
| 613 | - h\_chksum[JBD2\_CHECKSUM\_BYTES] | 613 | - h_chksum[JBD2_CHECKSUM_BYTES] |
| 614 | - 32 bytes of space to store checksums. If | 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 | are set, the first ``__be32`` is the checksum of the journal UUID and | 616 | are set, the first ``__be32`` is the checksum of the journal UUID and |
| 617 | the entire commit block, with this field zeroed. If | 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 | crc32 of all the blocks already written to the transaction. | 619 | crc32 of all the blocks already written to the transaction. |
| 620 | * - 0x30 | 620 | * - 0x30 |
| 621 | - \_\_be64 | 621 | - __be64 |
| 622 | - h\_commit\_sec | 622 | - h_commit_sec |
| 623 | - The time that the transaction was committed, in seconds since the epoch. | 623 | - The time that the transaction was committed, in seconds since the epoch. |
| 624 | * - 0x38 | 624 | * - 0x38 |
| 625 | - \_\_be32 | 625 | - __be32 |
| 626 | - h\_commit\_nsec | 626 | - h_commit_nsec |
| 627 | - Nanoseconds component of the above timestamp. | 627 | - Nanoseconds component of the above timestamp. |
| 628 | 628 | ||
| 629 | Fast commits | 629 | Fast commits |
| @@ -7,8 +7,8 @@ Multiple mount protection (MMP) is a feature that protects the · 6 unmodified lines | |||
| 7 | filesystem against multiple hosts trying to use the filesystem | 7 | filesystem against multiple hosts trying to use the filesystem |
| 8 | simultaneously. When a filesystem is opened (for mounting, or fsck, | 8 | simultaneously. When a filesystem is opened (for mounting, or fsck, |
| 9 | etc.), the MMP code running on the node (call it node A) checks a | 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 | 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 | 11 | open continues. If the sequence number is EXT4_MMP_SEQ_FSCK, then |
| 12 | fsck is (hopefully) running, and open fails immediately. Otherwise, the | 12 | fsck is (hopefully) running, and open fails immediately. Otherwise, the |
| 13 | open code will wait for twice the specified MMP check interval and check | 13 | open code will wait for twice the specified MMP check interval and check |
| 14 | the sequence number again. If the sequence number has changed, then the | 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 | - Name | 40 | - Name |
| 41 | - Description | 41 | - Description |
| 42 | * - 0x0 | 42 | * - 0x0 |
| 43 | - \_\_le32 | 43 | - __le32 |
| 44 | - mmp\_magic | 44 | - mmp_magic |
| 45 | - Magic number for MMP, 0x004D4D50 (“MMP”). | 45 | - Magic number for MMP, 0x004D4D50 (“MMP”). |
| 46 | * - 0x4 | 46 | * - 0x4 |
| 47 | - \_\_le32 | 47 | - __le32 |
| 48 | - mmp\_seq | 48 | - mmp_seq |
| 49 | - Sequence number, updated periodically. | 49 | - Sequence number, updated periodically. |
| 50 | * - 0x8 | 50 | * - 0x8 |
| 51 | - \_\_le64 | 51 | - __le64 |
| 52 | - mmp\_time | 52 | - mmp_time |
| 53 | - Time that the MMP block was last updated. | 53 | - Time that the MMP block was last updated. |
| 54 | * - 0x10 | 54 | * - 0x10 |
| 55 | - char[64] | 55 | - char[64] |
| 56 | - mmp\_nodename | 56 | - mmp_nodename |
| 57 | - Hostname of the node that opened the filesystem. | 57 | - Hostname of the node that opened the filesystem. |
| 58 | * - 0x50 | 58 | * - 0x50 |
| 59 | - char[32] | 59 | - char[32] |
| 60 | - mmp\_bdevname | 60 | - mmp_bdevname |
| 61 | - Block device name of the filesystem. | 61 | - Block device name of the filesystem. |
| 62 | * - 0x70 | 62 | * - 0x70 |
| 63 | - \_\_le16 | 63 | - __le16 |
| 64 | - mmp\_check\_interval | 64 | - mmp_check_interval |
| 65 | - The MMP re-check interval, in seconds. | 65 | - The MMP re-check interval, in seconds. |
| 66 | * - 0x72 | 66 | * - 0x72 |
| 67 | - \_\_le16 | 67 | - __le16 |
| 68 | - mmp\_pad1 | 68 | - mmp_pad1 |
| 69 | - Zero. | 69 | - Zero. |
| 70 | * - 0x74 | 70 | * - 0x74 |
| 71 | - \_\_le32[226] | 71 | - __le32[226] |
| 72 | - mmp\_pad2 | 72 | - mmp_pad2 |
| 73 | - Zero. | 73 | - Zero. |
| 74 | * - 0x3FC | 74 | * - 0x3FC |
| 75 | - \_\_le32 | 75 | - __le32 |
| 76 | - mmp\_checksum | 76 | - mmp_checksum |
| 77 | - Checksum of the MMP block. | 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 | performance difficulties due to fragmentation, the block allocator tries | 7 | performance difficulties due to fragmentation, the block allocator tries |
| 8 | very hard to keep each file's blocks within the same group, thereby | 8 | very hard to keep each file's blocks within the same group, thereby |
| 9 | reducing seek times. The size of a block group is specified in | 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 | ``block_size_in_bytes``. With the default block size of 4KiB, each group | 11 | ``block_size_in_bytes``. With the default block size of 4KiB, each group |
| 12 | will contain 32,768 blocks, for a length of 128MiB. The number of block | 12 | will contain 32,768 blocks, for a length of 128MiB. The number of block |
| 13 | groups is the size of the device divided by the size of a block group. | 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 | * - 10 | 34 | * - 10 |
| 35 | - Replica inode, used for some non-upstream feature? | 35 | - Replica inode, used for some non-upstream feature? |
| 36 | * - 11 | 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 | Note that there are also some inodes allocated from non-reserved inode numbers | 39 | Note that there are also some inodes allocated from non-reserved inode numbers |
| 40 | for other filesystem features which are not referenced from standard directory | 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 | * - Superblock field | 47 | * - Superblock field |
| 48 | - Description | 48 | - Description |
| 49 | 49 | ||
| 50 | * - s\_lpf\_ino | 50 | * - s_lpf_ino |
| 51 | - Inode number of lost+found directory. | 51 | - Inode number of lost+found directory. |
| 52 | * - s\_prj\_quota\_inum | 52 | * - s_prj_quota_inum |
| 53 | - Inode number of quota file tracking project quotas | 53 | - Inode number of quota file tracking project quotas |
| 54 | * - s\_orphan\_file\_inum | 54 | * - s_orphan_file_inum |
| 55 | - Inode number of file tracking orphan inodes. | 55 | - Inode number of file tracking orphan inodes. |
| @@ -7,7 +7,7 @@ The superblock records various information about the enclosing · 6 unmodified lines | |||
| 7 | filesystem, such as block counts, inode counts, supported features, | 7 | filesystem, such as block counts, inode counts, supported features, |
| 8 | maintenance information, and more. | 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 | superblock and group descriptors are kept only in the groups whose group | 11 | superblock and group descriptors are kept only in the groups whose group |
| 12 | number is either 0 or a power of 3, 5, or 7. If the flag is not set, | 12 | number is either 0 or a power of 3, 5, or 7. If the flag is not set, |
| 13 | redundant copies are kept in all groups. | 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 | - Name | 27 | - Name |
| 28 | - Description | 28 | - Description |
| 29 | * - 0x0 | 29 | * - 0x0 |
| 30 | - \_\_le32 | 30 | - __le32 |
| 31 | - s\_inodes\_count | 31 | - s_inodes_count |
| 32 | - Total inode count. | 32 | - Total inode count. |
| 33 | * - 0x4 | 33 | * - 0x4 |
| 34 | - \_\_le32 | 34 | - __le32 |
| 35 | - s\_blocks\_count\_lo | 35 | - s_blocks_count_lo |
| 36 | - Total block count. | 36 | - Total block count. |
| 37 | * - 0x8 | 37 | * - 0x8 |
| 38 | - \_\_le32 | 38 | - __le32 |
| 39 | - s\_r\_blocks\_count\_lo | 39 | - s_r_blocks_count_lo |
| 40 | - This number of blocks can only be allocated by the super-user. | 40 | - This number of blocks can only be allocated by the super-user. |
| 41 | * - 0xC | 41 | * - 0xC |
| 42 | - \_\_le32 | 42 | - __le32 |
| 43 | - s\_free\_blocks\_count\_lo | 43 | - s_free_blocks_count_lo |
| 44 | - Free block count. | 44 | - Free block count. |
| 45 | * - 0x10 | 45 | * - 0x10 |
| 46 | - \_\_le32 | 46 | - __le32 |
| 47 | - s\_free\_inodes\_count | 47 | - s_free_inodes_count |
| 48 | - Free inode count. | 48 | - Free inode count. |
| 49 | * - 0x14 | 49 | * - 0x14 |
| 50 | - \_\_le32 | 50 | - __le32 |
| 51 | - s\_first\_data\_block | 51 | - s_first_data_block |
| 52 | - First data block. This must be at least 1 for 1k-block filesystems and | 52 | - First data block. This must be at least 1 for 1k-block filesystems and |
| 53 | is typically 0 for all other block sizes. | 53 | is typically 0 for all other block sizes. |
| 54 | * - 0x18 | 54 | * - 0x18 |
| 55 | - \_\_le32 | 55 | - __le32 |
| 56 | - s\_log\_block\_size | 56 | - s_log_block_size |
| 57 | - Block size is 2 ^ (10 + s\_log\_block\_size). | 57 | - Block size is 2 ^ (10 + s_log_block_size). |
| 58 | * - 0x1C | 58 | * - 0x1C |
| 59 | - \_\_le32 | 59 | - __le32 |
| 60 | - s\_log\_cluster\_size | 60 | - s_log_cluster_size |
| 61 | - Cluster size is 2 ^ (10 + s\_log\_cluster\_size) blocks if bigalloc is | 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. | 62 | enabled. Otherwise s_log_cluster_size must equal s_log_block_size. |
| 63 | * - 0x20 | 63 | * - 0x20 |
| 64 | - \_\_le32 | 64 | - __le32 |
| 65 | - s\_blocks\_per\_group | 65 | - s_blocks_per_group |
| 66 | - Blocks per group. | 66 | - Blocks per group. |
| 67 | * - 0x24 | 67 | * - 0x24 |
| 68 | - \_\_le32 | 68 | - __le32 |
| 69 | - s\_clusters\_per\_group | 69 | - s_clusters_per_group |
| 70 | - Clusters per group, if bigalloc is enabled. Otherwise | 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 | * - 0x28 | 72 | * - 0x28 |
| 73 | - \_\_le32 | 73 | - __le32 |
| 74 | - s\_inodes\_per\_group | 74 | - s_inodes_per_group |
| 75 | - Inodes per group. | 75 | - Inodes per group. |
| 76 | * - 0x2C | 76 | * - 0x2C |
| 77 | - \_\_le32 | 77 | - __le32 |
| 78 | - s\_mtime | 78 | - s_mtime |
| 79 | - Mount time, in seconds since the epoch. | 79 | - Mount time, in seconds since the epoch. |
| 80 | * - 0x30 | 80 | * - 0x30 |
| 81 | - \_\_le32 | 81 | - __le32 |
| 82 | - s\_wtime | 82 | - s_wtime |
| 83 | - Write time, in seconds since the epoch. | 83 | - Write time, in seconds since the epoch. |
| 84 | * - 0x34 | 84 | * - 0x34 |
| 85 | - \_\_le16 | 85 | - __le16 |
| 86 | - s\_mnt\_count | 86 | - s_mnt_count |
| 87 | - Number of mounts since the last fsck. | 87 | - Number of mounts since the last fsck. |
| 88 | * - 0x36 | 88 | * - 0x36 |
| 89 | - \_\_le16 | 89 | - __le16 |
| 90 | - s\_max\_mnt\_count | 90 | - s_max_mnt_count |
| 91 | - Number of mounts beyond which a fsck is needed. | 91 | - Number of mounts beyond which a fsck is needed. |
| 92 | * - 0x38 | 92 | * - 0x38 |
| 93 | - \_\_le16 | 93 | - __le16 |
| 94 | - s\_magic | 94 | - s_magic |
| 95 | - Magic signature, 0xEF53 | 95 | - Magic signature, 0xEF53 |
| 96 | * - 0x3A | 96 | * - 0x3A |
| 97 | - \_\_le16 | 97 | - __le16 |
| 98 | - s\_state | 98 | - s_state |
| 99 | - File system state. See super_state_ for more info. | 99 | - File system state. See super_state_ for more info. |
| 100 | * - 0x3C | 100 | * - 0x3C |
| 101 | - \_\_le16 | 101 | - __le16 |
| 102 | - s\_errors | 102 | - s_errors |
| 103 | - Behaviour when detecting errors. See super_errors_ for more info. | 103 | - Behaviour when detecting errors. See super_errors_ for more info. |
| 104 | * - 0x3E | 104 | * - 0x3E |
| 105 | - \_\_le16 | 105 | - __le16 |
| 106 | - s\_minor\_rev\_level | 106 | - s_minor_rev_level |
| 107 | - Minor revision level. | 107 | - Minor revision level. |
| 108 | * - 0x40 | 108 | * - 0x40 |
| 109 | - \_\_le32 | 109 | - __le32 |
| 110 | - s\_lastcheck | 110 | - s_lastcheck |
| 111 | - Time of last check, in seconds since the epoch. | 111 | - Time of last check, in seconds since the epoch. |
| 112 | * - 0x44 | 112 | * - 0x44 |
| 113 | - \_\_le32 | 113 | - __le32 |
| 114 | - s\_checkinterval | 114 | - s_checkinterval |
| 115 | - Maximum time between checks, in seconds. | 115 | - Maximum time between checks, in seconds. |
| 116 | * - 0x48 | 116 | * - 0x48 |
| 117 | - \_\_le32 | 117 | - __le32 |
| 118 | - s\_creator\_os | 118 | - s_creator_os |
| 119 | - Creator OS. See the table super_creator_ for more info. | 119 | - Creator OS. See the table super_creator_ for more info. |
| 120 | * - 0x4C | 120 | * - 0x4C |
| 121 | - \_\_le32 | 121 | - __le32 |
| 122 | - s\_rev\_level | 122 | - s_rev_level |
| 123 | - Revision level. See the table super_revision_ for more info. | 123 | - Revision level. See the table super_revision_ for more info. |
| 124 | * - 0x50 | 124 | * - 0x50 |
| 125 | - \_\_le16 | 125 | - __le16 |
| 126 | - s\_def\_resuid | 126 | - s_def_resuid |
| 127 | - Default uid for reserved blocks. | 127 | - Default uid for reserved blocks. |
| 128 | * - 0x52 | 128 | * - 0x52 |
| 129 | - \_\_le16 | 129 | - __le16 |
| 130 | - s\_def\_resgid | 130 | - s_def_resgid |
| 131 | - Default gid for reserved blocks. | 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 | about a feature in either the compatible or incompatible feature set, it | 143 | about a feature in either the compatible or incompatible feature set, it |
| 144 | must abort and not try to meddle with things it doesn't understand... | 144 | must abort and not try to meddle with things it doesn't understand... |
| 145 | * - 0x54 | 145 | * - 0x54 |
| 146 | - \_\_le32 | 146 | - __le32 |
| 147 | - s\_first\_ino | 147 | - s_first_ino |
| 148 | - First non-reserved inode. | 148 | - First non-reserved inode. |
| 149 | * - 0x58 | 149 | * - 0x58 |
| 150 | - \_\_le16 | 150 | - __le16 |
| 151 | - s\_inode\_size | 151 | - s_inode_size |
| 152 | - Size of inode structure, in bytes. | 152 | - Size of inode structure, in bytes. |
| 153 | * - 0x5A | 153 | * - 0x5A |
| 154 | - \_\_le16 | 154 | - __le16 |
| 155 | - s\_block\_group\_nr | 155 | - s_block_group_nr |
| 156 | - Block group # of this superblock. | 156 | - Block group # of this superblock. |
| 157 | * - 0x5C | 157 | * - 0x5C |
| 158 | - \_\_le32 | 158 | - __le32 |
| 159 | - s\_feature\_compat | 159 | - s_feature_compat |
| 160 | - Compatible feature set flags. Kernel can still read/write this fs even | 160 | - Compatible feature set flags. Kernel can still read/write this fs even |
| 161 | if it doesn't understand a flag; fsck should not do that. See the | 161 | if it doesn't understand a flag; fsck should not do that. See the |
| 162 | super_compat_ table for more info. | 162 | super_compat_ table for more info. |
| 163 | * - 0x60 | 163 | * - 0x60 |
| 164 | - \_\_le32 | 164 | - __le32 |
| 165 | - s\_feature\_incompat | 165 | - s_feature_incompat |
| 166 | - Incompatible feature set. If the kernel or fsck doesn't understand one | 166 | - Incompatible feature set. If the kernel or fsck doesn't understand one |
| 167 | of these bits, it should stop. See the super_incompat_ table for more | 167 | of these bits, it should stop. See the super_incompat_ table for more |
| 168 | info. | 168 | info. |
| 169 | * - 0x64 | 169 | * - 0x64 |
| 170 | - \_\_le32 | 170 | - __le32 |
| 171 | - s\_feature\_ro\_compat | 171 | - s_feature_ro_compat |
| 172 | - Readonly-compatible feature set. If the kernel doesn't understand one of | 172 | - Readonly-compatible feature set. If the kernel doesn't understand one of |
| 173 | these bits, it can still mount read-only. See the super_rocompat_ table | 173 | these bits, it can still mount read-only. See the super_rocompat_ table |
| 174 | for more info. | 174 | for more info. |
| 175 | * - 0x68 | 175 | * - 0x68 |
| 176 | - \_\_u8 | 176 | - __u8 |
| 177 | - s\_uuid[16] | 177 | - s_uuid[16] |
| 178 | - 128-bit UUID for volume. | 178 | - 128-bit UUID for volume. |
| 179 | * - 0x78 | 179 | * - 0x78 |
| 180 | - char | 180 | - char |
| 181 | - s\_volume\_name[16] | 181 | - s_volume_name[16] |
| 182 | - Volume label. | 182 | - Volume label. |
| 183 | * - 0x88 | 183 | * - 0x88 |
| 184 | - char | 184 | - char |
| 185 | - s\_last\_mounted[64] | 185 | - s_last_mounted[64] |
| 186 | - Directory where filesystem was last mounted. | 186 | - Directory where filesystem was last mounted. |
| 187 | * - 0xC8 | 187 | * - 0xC8 |
| 188 | - \_\_le32 | 188 | - __le32 |
| 189 | - s\_algorithm\_usage\_bitmap | 189 | - s_algorithm_usage_bitmap |
| 190 | - For compression (Not used in e2fsprogs/Linux) | 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 | - Performance hints. Directory preallocation should only happen if the | 194 | - Performance hints. Directory preallocation should only happen if the |
| 195 | EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. | 195 | EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. |
| 196 | * - 0xCC | 196 | * - 0xCC |
| 197 | - \_\_u8 | 197 | - __u8 |
| 198 | - s\_prealloc\_blocks | 198 | - s_prealloc_blocks |
| 199 | - #. of blocks to try to preallocate for ... files? (Not used in | 199 | - #. of blocks to try to preallocate for ... files? (Not used in |
| 200 | e2fsprogs/Linux) | 200 | e2fsprogs/Linux) |
| 201 | * - 0xCD | 201 | * - 0xCD |
| 202 | - \_\_u8 | 202 | - __u8 |
| 203 | - s\_prealloc\_dir\_blocks | 203 | - s_prealloc_dir_blocks |
| 204 | - #. of blocks to preallocate for directories. (Not used in | 204 | - #. of blocks to preallocate for directories. (Not used in |
| 205 | e2fsprogs/Linux) | 205 | e2fsprogs/Linux) |
| 206 | * - 0xCE | 206 | * - 0xCE |
| 207 | - \_\_le16 | 207 | - __le16 |
| 208 | - s\_reserved\_gdt\_blocks | 208 | - s_reserved_gdt_blocks |
| 209 | - Number of reserved GDT entries for future filesystem expansion. | 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 | - Journalling support is valid only if EXT4_FEATURE_COMPAT_HAS_JOURNAL is | 213 | - Journalling support is valid only if EXT4_FEATURE_COMPAT_HAS_JOURNAL is |
| 214 | set. | 214 | set. |
| 215 | * - 0xD0 | 215 | * - 0xD0 |
| 216 | - \_\_u8 | 216 | - __u8 |
| 217 | - s\_journal\_uuid[16] | 217 | - s_journal_uuid[16] |
| 218 | - UUID of journal superblock | 218 | - UUID of journal superblock |
| 219 | * - 0xE0 | 219 | * - 0xE0 |
| 220 | - \_\_le32 | 220 | - __le32 |
| 221 | - s\_journal\_inum | 221 | - s_journal_inum |
| 222 | - inode number of journal file. | 222 | - inode number of journal file. |
| 223 | * - 0xE4 | 223 | * - 0xE4 |
| 224 | - \_\_le32 | 224 | - __le32 |
| 225 | - s\_journal\_dev | 225 | - s_journal_dev |
| 226 | - Device number of journal file, if the external journal feature flag is | 226 | - Device number of journal file, if the external journal feature flag is |
| 227 | set. | 227 | set. |
| 228 | * - 0xE8 | 228 | * - 0xE8 |
| 229 | - \_\_le32 | 229 | - __le32 |
| 230 | - s\_last\_orphan | 230 | - s_last_orphan |
| 231 | - Start of list of orphaned inodes to delete. | 231 | - Start of list of orphaned inodes to delete. |
| 232 | * - 0xEC | 232 | * - 0xEC |
| 233 | - \_\_le32 | 233 | - __le32 |
| 234 | - s\_hash\_seed[4] | 234 | - s_hash_seed[4] |
| 235 | - HTREE hash seed. | 235 | - HTREE hash seed. |
| 236 | * - 0xFC | 236 | * - 0xFC |
| 237 | - \_\_u8 | 237 | - __u8 |
| 238 | - s\_def\_hash\_version | 238 | - s_def_hash_version |
| 239 | - Default hash algorithm to use for directory hashes. See super_def_hash_ | 239 | - Default hash algorithm to use for directory hashes. See super_def_hash_ |
| 240 | for more info. | 240 | for more info. |
| 241 | * - 0xFD | 241 | * - 0xFD |
| 242 | - \_\_u8 | 242 | - __u8 |
| 243 | - s\_jnl\_backup\_type | 243 | - s_jnl_backup_type |
| 244 | - If this value is 0 or EXT3\_JNL\_BACKUP\_BLOCKS (1), then the | 244 | - If this value is 0 or EXT3_JNL_BACKUP_BLOCKS (1), then the |
| 245 | ``s_jnl_blocks`` field contains a duplicate copy of the inode's | 245 | ``s_jnl_blocks`` field contains a duplicate copy of the inode's |
| 246 | ``i_block[]`` array and ``i_size``. | 246 | ``i_block[]`` array and ``i_size``. |
| 247 | * - 0xFE | 247 | * - 0xFE |
| 248 | - \_\_le16 | 248 | - __le16 |
| 249 | - s\_desc\_size | 249 | - s_desc_size |
| 250 | - Size of group descriptors, in bytes, if the 64bit incompat feature flag | 250 | - Size of group descriptors, in bytes, if the 64bit incompat feature flag |
| 251 | is set. | 251 | is set. |
| 252 | * - 0x100 | 252 | * - 0x100 |
| 253 | - \_\_le32 | 253 | - __le32 |
| 254 | - s\_default\_mount\_opts | 254 | - s_default_mount_opts |
| 255 | - Default mount options. See the super_mountopts_ table for more info. | 255 | - Default mount options. See the super_mountopts_ table for more info. |
| 256 | * - 0x104 | 256 | * - 0x104 |
| 257 | - \_\_le32 | 257 | - __le32 |
| 258 | - s\_first\_meta\_bg | 258 | - s_first_meta_bg |
| 259 | - First metablock block group, if the meta\_bg feature is enabled. | 259 | - First metablock block group, if the meta_bg feature is enabled. |
| 260 | * - 0x108 | 260 | * - 0x108 |
| 261 | - \_\_le32 | 261 | - __le32 |
| 262 | - s\_mkfs\_time | 262 | - s_mkfs_time |
| 263 | - When the filesystem was created, in seconds since the epoch. | 263 | - When the filesystem was created, in seconds since the epoch. |
| 264 | * - 0x10C | 264 | * - 0x10C |
| 265 | - \_\_le32 | 265 | - __le32 |
| 266 | - s\_jnl\_blocks[17] | 266 | - s_jnl_blocks[17] |
| 267 | - Backup copy of the journal inode's ``i_block[]`` array in the first 15 | 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 | respectively. | 269 | respectively. |
| 270 | * - | 270 | * - |
| 271 | - | 271 | - |
| 272 | - | 272 | - |
| 273 | - 64bit support is valid only if EXT4_FEATURE_COMPAT_64BIT is set. | 273 | - 64bit support is valid only if EXT4_FEATURE_COMPAT_64BIT is set. |
| 274 | * - 0x150 | 274 | * - 0x150 |
| 275 | - \_\_le32 | 275 | - __le32 |
| 276 | - s\_blocks\_count\_hi | 276 | - s_blocks_count_hi |
| 277 | - High 32-bits of the block count. | 277 | - High 32-bits of the block count. |
| 278 | * - 0x154 | 278 | * - 0x154 |
| 279 | - \_\_le32 | 279 | - __le32 |
| 280 | - s\_r\_blocks\_count\_hi | 280 | - s_r_blocks_count_hi |
| 281 | - High 32-bits of the reserved block count. | 281 | - High 32-bits of the reserved block count. |
| 282 | * - 0x158 | 282 | * - 0x158 |
| 283 | - \_\_le32 | 283 | - __le32 |
| 284 | - s\_free\_blocks\_count\_hi | 284 | - s_free_blocks_count_hi |
| 285 | - High 32-bits of the free block count. | 285 | - High 32-bits of the free block count. |
| 286 | * - 0x15C | 286 | * - 0x15C |
| 287 | - \_\_le16 | 287 | - __le16 |
| 288 | - s\_min\_extra\_isize | 288 | - s_min_extra_isize |
| 289 | - All inodes have at least # bytes. | 289 | - All inodes have at least # bytes. |
| 290 | * - 0x15E | 290 | * - 0x15E |
| 291 | - \_\_le16 | 291 | - __le16 |
| 292 | - s\_want\_extra\_isize | 292 | - s_want_extra_isize |
| 293 | - New inodes should reserve # bytes. | 293 | - New inodes should reserve # bytes. |
| 294 | * - 0x160 | 294 | * - 0x160 |
| 295 | - \_\_le32 | 295 | - __le32 |
| 296 | - s\_flags | 296 | - s_flags |
| 297 | - Miscellaneous flags. See the super_flags_ table for more info. | 297 | - Miscellaneous flags. See the super_flags_ table for more info. |
| 298 | * - 0x164 | 298 | * - 0x164 |
| 299 | - \_\_le16 | 299 | - __le16 |
| 300 | - s\_raid\_stride | 300 | - s_raid_stride |
| 301 | - RAID stride. This is the number of logical blocks read from or written | 301 | - RAID stride. This is the number of logical blocks read from or written |
| 302 | to the disk before moving to the next disk. This affects the placement | 302 | to the disk before moving to the next disk. This affects the placement |
| 303 | of filesystem metadata, which will hopefully make RAID storage faster. | 303 | of filesystem metadata, which will hopefully make RAID storage faster. |
| 304 | * - 0x166 | 304 | * - 0x166 |
| 305 | - \_\_le16 | 305 | - __le16 |
| 306 | - s\_mmp\_interval | 306 | - s_mmp_interval |
| 307 | - #. seconds to wait in multi-mount prevention (MMP) checking. In theory, | 307 | - #. seconds to wait in multi-mount prevention (MMP) checking. In theory, |
| 308 | MMP is a mechanism to record in the superblock which host and device | 308 | MMP is a mechanism to record in the superblock which host and device |
| 309 | have mounted the filesystem, in order to prevent multiple mounts. This | 309 | have mounted the filesystem, in order to prevent multiple mounts. This |
| 310 | feature does not seem to be implemented... | 310 | feature does not seem to be implemented... |
| 311 | * - 0x168 | 311 | * - 0x168 |
| 312 | - \_\_le64 | 312 | - __le64 |
| 313 | - s\_mmp\_block | 313 | - s_mmp_block |
| 314 | - Block # for multi-mount protection data. | 314 | - Block # for multi-mount protection data. |
| 315 | * - 0x170 | 315 | * - 0x170 |
| 316 | - \_\_le32 | 316 | - __le32 |
| 317 | - s\_raid\_stripe\_width | 317 | - s_raid_stripe_width |
| 318 | - RAID stripe width. This is the number of logical blocks read from or | 318 | - RAID stripe width. This is the number of logical blocks read from or |
| 319 | written to the disk before coming back to the current disk. This is used | 319 | written to the disk before coming back to the current disk. This is used |
| 320 | by the block allocator to try to reduce the number of read-modify-write | 320 | by the block allocator to try to reduce the number of read-modify-write |
| 321 | operations in a RAID5/6. | 321 | operations in a RAID5/6. |
| 322 | * - 0x174 | 322 | * - 0x174 |
| 323 | - \_\_u8 | 323 | - __u8 |
| 324 | - s\_log\_groups\_per\_flex | 324 | - s_log_groups_per_flex |
| 325 | - Size of a flexible block group is 2 ^ ``s_log_groups_per_flex``. | 325 | - Size of a flexible block group is 2 ^ ``s_log_groups_per_flex``. |
| 326 | * - 0x175 | 326 | * - 0x175 |
| 327 | - \_\_u8 | 327 | - __u8 |
| 328 | - s\_checksum\_type | 328 | - s_checksum_type |
| 329 | - Metadata checksum algorithm type. The only valid value is 1 (crc32c). | 329 | - Metadata checksum algorithm type. The only valid value is 1 (crc32c). |
| 330 | * - 0x176 | 330 | * - 0x176 |
| 331 | - \_\_le16 | 331 | - __le16 |
| 332 | - s\_reserved\_pad | 332 | - s_reserved_pad |
| 333 | - | 333 | - |
| 334 | * - 0x178 | 334 | * - 0x178 |
| 335 | - \_\_le64 | 335 | - __le64 |
| 336 | - s\_kbytes\_written | 336 | - s_kbytes_written |
| 337 | - Number of KiB written to this filesystem over its lifetime. | 337 | - Number of KiB written to this filesystem over its lifetime. |
| 338 | * - 0x180 | 338 | * - 0x180 |
| 339 | - \_\_le32 | 339 | - __le32 |
| 340 | - s\_snapshot\_inum | 340 | - s_snapshot_inum |
| 341 | - inode number of active snapshot. (Not used in e2fsprogs/Linux.) | 341 | - inode number of active snapshot. (Not used in e2fsprogs/Linux.) |
| 342 | * - 0x184 | 342 | * - 0x184 |
| 343 | - \_\_le32 | 343 | - __le32 |
| 344 | - s\_snapshot\_id | 344 | - s_snapshot_id |
| 345 | - Sequential ID of active snapshot. (Not used in e2fsprogs/Linux.) | 345 | - Sequential ID of active snapshot. (Not used in e2fsprogs/Linux.) |
| 346 | * - 0x188 | 346 | * - 0x188 |
| 347 | - \_\_le64 | 347 | - __le64 |
| 348 | - s\_snapshot\_r\_blocks\_count | 348 | - s_snapshot_r_blocks_count |
| 349 | - Number of blocks reserved for active snapshot's future use. (Not used in | 349 | - Number of blocks reserved for active snapshot's future use. (Not used in |
| 350 | e2fsprogs/Linux.) | 350 | e2fsprogs/Linux.) |
| 351 | * - 0x190 | 351 | * - 0x190 |
| 352 | - \_\_le32 | 352 | - __le32 |
| 353 | - s\_snapshot\_list | 353 | - s_snapshot_list |
| 354 | - inode number of the head of the on-disk snapshot list. (Not used in | 354 | - inode number of the head of the on-disk snapshot list. (Not used in |
| 355 | e2fsprogs/Linux.) | 355 | e2fsprogs/Linux.) |
| 356 | * - 0x194 | 356 | * - 0x194 |
| 357 | - \_\_le32 | 357 | - __le32 |
| 358 | - s\_error\_count | 358 | - s_error_count |
| 359 | - Number of errors seen. | 359 | - Number of errors seen. |
| 360 | * - 0x198 | 360 | * - 0x198 |
| 361 | - \_\_le32 | 361 | - __le32 |
| 362 | - s\_first\_error\_time | 362 | - s_first_error_time |
| 363 | - First time an error happened, in seconds since the epoch. | 363 | - First time an error happened, in seconds since the epoch. |
| 364 | * - 0x19C | 364 | * - 0x19C |
| 365 | - \_\_le32 | 365 | - __le32 |
| 366 | - s\_first\_error\_ino | 366 | - s_first_error_ino |
| 367 | - inode involved in first error. | 367 | - inode involved in first error. |
| 368 | * - 0x1A0 | 368 | * - 0x1A0 |
| 369 | - \_\_le64 | 369 | - __le64 |
| 370 | - s\_first\_error\_block | 370 | - s_first_error_block |
| 371 | - Number of block involved of first error. | 371 | - Number of block involved of first error. |
| 372 | * - 0x1A8 | 372 | * - 0x1A8 |
| 373 | - \_\_u8 | 373 | - __u8 |
| 374 | - s\_first\_error\_func[32] | 374 | - s_first_error_func[32] |
| 375 | - Name of function where the error happened. | 375 | - Name of function where the error happened. |
| 376 | * - 0x1C8 | 376 | * - 0x1C8 |
| 377 | - \_\_le32 | 377 | - __le32 |
| 378 | - s\_first\_error\_line | 378 | - s_first_error_line |
| 379 | - Line number where error happened. | 379 | - Line number where error happened. |
| 380 | * - 0x1CC | 380 | * - 0x1CC |
| 381 | - \_\_le32 | 381 | - __le32 |
| 382 | - s\_last\_error\_time | 382 | - s_last_error_time |
| 383 | - Time of most recent error, in seconds since the epoch. | 383 | - Time of most recent error, in seconds since the epoch. |
| 384 | * - 0x1D0 | 384 | * - 0x1D0 |
| 385 | - \_\_le32 | 385 | - __le32 |
| 386 | - s\_last\_error\_ino | 386 | - s_last_error_ino |
| 387 | - inode involved in most recent error. | 387 | - inode involved in most recent error. |
| 388 | * - 0x1D4 | 388 | * - 0x1D4 |
| 389 | - \_\_le32 | 389 | - __le32 |
| 390 | - s\_last\_error\_line | 390 | - s_last_error_line |
| 391 | - Line number where most recent error happened. | 391 | - Line number where most recent error happened. |
| 392 | * - 0x1D8 | 392 | * - 0x1D8 |
| 393 | - \_\_le64 | 393 | - __le64 |
| 394 | - s\_last\_error\_block | 394 | - s_last_error_block |
| 395 | - Number of block involved in most recent error. | 395 | - Number of block involved in most recent error. |
| 396 | * - 0x1E0 | 396 | * - 0x1E0 |
| 397 | - \_\_u8 | 397 | - __u8 |
| 398 | - s\_last\_error\_func[32] | 398 | - s_last_error_func[32] |
| 399 | - Name of function where the most recent error happened. | 399 | - Name of function where the most recent error happened. |
| 400 | * - 0x200 | 400 | * - 0x200 |
| 401 | - \_\_u8 | 401 | - __u8 |
| 402 | - s\_mount\_opts[64] | 402 | - s_mount_opts[64] |
| 403 | - ASCIIZ string of mount options. | 403 | - ASCIIZ string of mount options. |
| 404 | * - 0x240 | 404 | * - 0x240 |
| 405 | - \_\_le32 | 405 | - __le32 |
| 406 | - s\_usr\_quota\_inum | 406 | - s_usr_quota_inum |
| 407 | - Inode number of user `quota <quota>`__ file. | 407 | - Inode number of user `quota <quota>`__ file. |
| 408 | * - 0x244 | 408 | * - 0x244 |
| 409 | - \_\_le32 | 409 | - __le32 |
| 410 | - s\_grp\_quota\_inum | 410 | - s_grp_quota_inum |
| 411 | - Inode number of group `quota <quota>`__ file. | 411 | - Inode number of group `quota <quota>`__ file. |
| 412 | * - 0x248 | 412 | * - 0x248 |
| 413 | - \_\_le32 | 413 | - __le32 |
| 414 | - s\_overhead\_blocks | 414 | - s_overhead_blocks |
| 415 | - Overhead blocks/clusters in fs. (Huh? This field is always zero, which | 415 | - Overhead blocks/clusters in fs. (Huh? This field is always zero, which |
| 416 | means that the kernel calculates it dynamically.) | 416 | means that the kernel calculates it dynamically.) |
| 417 | * - 0x24C | 417 | * - 0x24C |
| 418 | - \_\_le32 | 418 | - __le32 |
| 419 | - s\_backup\_bgs[2] | 419 | - s_backup_bgs[2] |
| 420 | - Block groups containing superblock backups (if sparse\_super2) | 420 | - Block groups containing superblock backups (if sparse_super2) |
| 421 | * - 0x254 | 421 | * - 0x254 |
| 422 | - \_\_u8 | 422 | - __u8 |
| 423 | - s\_encrypt\_algos[4] | 423 | - s_encrypt_algos[4] |
| 424 | - Encryption algorithms in use. There can be up to four algorithms in use | 424 | - Encryption algorithms in use. There can be up to four algorithms in use |
| 425 | at any time; valid algorithm codes are given in the super_encrypt_ table | 425 | at any time; valid algorithm codes are given in the super_encrypt_ table |
| 426 | below. | 426 | below. |
| 427 | * - 0x258 | 427 | * - 0x258 |
| 428 | - \_\_u8 | 428 | - __u8 |
| 429 | - s\_encrypt\_pw\_salt[16] | 429 | - s_encrypt_pw_salt[16] |
| 430 | - Salt for the string2key algorithm for encryption. | 430 | - Salt for the string2key algorithm for encryption. |
| 431 | * - 0x268 | 431 | * - 0x268 |
| 432 | - \_\_le32 | 432 | - __le32 |
| 433 | - s\_lpf\_ino | 433 | - s_lpf_ino |
| 434 | - Inode number of lost+found | 434 | - Inode number of lost+found |
| 435 | * - 0x26C | 435 | * - 0x26C |
| 436 | - \_\_le32 | 436 | - __le32 |
| 437 | - s\_prj\_quota\_inum | 437 | - s_prj_quota_inum |
| 438 | - Inode that tracks project quotas. | 438 | - Inode that tracks project quotas. |
| 439 | * - 0x270 | 439 | * - 0x270 |
| 440 | - \_\_le32 | 440 | - __le32 |
| 441 | - s\_checksum\_seed | 441 | - s_checksum_seed |
| 442 | - Checksum seed used for metadata\_csum calculations. This value is | 442 | - Checksum seed used for metadata_csum calculations. This value is |
| 443 | crc32c(~0, $orig\_fs\_uuid). | 443 | crc32c(~0, $orig_fs_uuid). |
| 444 | * - 0x274 | 444 | * - 0x274 |
| 445 | - \_\_u8 | 445 | - __u8 |
| 446 | - s\_wtime_hi | 446 | - s_wtime_hi |
| 447 | - Upper 8 bits of the s_wtime field. | 447 | - Upper 8 bits of the s_wtime field. |
| 448 | * - 0x275 | 448 | * - 0x275 |
| 449 | - \_\_u8 | 449 | - __u8 |
| 450 | - s\_mtime_hi | 450 | - s_mtime_hi |
| 451 | - Upper 8 bits of the s_mtime field. | 451 | - Upper 8 bits of the s_mtime field. |
| 452 | * - 0x276 | 452 | * - 0x276 |
| 453 | - \_\_u8 | 453 | - __u8 |
| 454 | - s\_mkfs_time_hi | 454 | - s_mkfs_time_hi |
| 455 | - Upper 8 bits of the s_mkfs_time field. | 455 | - Upper 8 bits of the s_mkfs_time field. |
| 456 | * - 0x277 | 456 | * - 0x277 |
| 457 | - \_\_u8 | 457 | - __u8 |
| 458 | - s\_lastcheck_hi | 458 | - s_lastcheck_hi |
| 459 | - Upper 8 bits of the s_lastcheck_hi field. | 459 | - Upper 8 bits of the s_lastcheck_hi field. |
| 460 | * - 0x278 | 460 | * - 0x278 |
| 461 | - \_\_u8 | 461 | - __u8 |
| 462 | - s\_first_error_time_hi | 462 | - s_first_error_time_hi |
| 463 | - Upper 8 bits of the s_first_error_time_hi field. | 463 | - Upper 8 bits of the s_first_error_time_hi field. |
| 464 | * - 0x279 | 464 | * - 0x279 |
| 465 | - \_\_u8 | 465 | - __u8 |
| 466 | - s\_last_error_time_hi | 466 | - s_last_error_time_hi |
| 467 | - Upper 8 bits of the s_last_error_time_hi field. | 467 | - Upper 8 bits of the s_last_error_time_hi field. |
| 468 | * - 0x27A | 468 | * - 0x27A |
| 469 | - \_\_u8 | 469 | - __u8 |
| 470 | - s\_pad[2] | 470 | - s_pad[2] |
| 471 | - Zero padding. | 471 | - Zero padding. |
| 472 | * - 0x27C | 472 | * - 0x27C |
| 473 | - \_\_le16 | 473 | - __le16 |
| 474 | - s\_encoding | 474 | - s_encoding |
| 475 | - Filename charset encoding. | 475 | - Filename charset encoding. |
| 476 | * - 0x27E | 476 | * - 0x27E |
| 477 | - \_\_le16 | 477 | - __le16 |
| 478 | - s\_encoding_flags | 478 | - s_encoding_flags |
| 479 | - Filename charset encoding flags. | 479 | - Filename charset encoding flags. |
| 480 | * - 0x280 | 480 | * - 0x280 |
| 481 | - \_\_le32 | 481 | - __le32 |
| 482 | - s\_orphan\_file\_inum | 482 | - s_orphan_file_inum |
| 483 | - Orphan file inode number. | 483 | - Orphan file inode number. |
| 484 | * - 0x284 | 484 | * - 0x284 |
| 485 | - \_\_le32 | 485 | - __le32 |
| 486 | - s\_reserved[94] | 486 | - s_reserved[94] |
| 487 | - Padding to the end of the block. | 487 | - Padding to the end of the block. |
| 488 | * - 0x3FC | 488 | * - 0x3FC |
| 489 | - \_\_le32 | 489 | - __le32 |
| 490 | - s\_checksum | 490 | - s_checksum |
| 491 | - Superblock checksum. | 491 | - Superblock checksum. |
| 492 | 492 | ||
| 493 | .. _super_state: | 493 | .. _super_state: |
| @@ -574,44 +574,44 @@ following: · 80 unmodified lines | |||
| 574 | * - Value | 574 | * - Value |
| 575 | - Description | 575 | - Description |
| 576 | * - 0x1 | 576 | * - 0x1 |
| 577 | - Directory preallocation (COMPAT\_DIR\_PREALLOC). | 577 | - Directory preallocation (COMPAT_DIR_PREALLOC). |
| 578 | * - 0x2 | 578 | * - 0x2 |
| 579 | - “imagic inodes”. Not clear from the code what this does | 579 | - “imagic inodes”. Not clear from the code what this does |
| 580 | (COMPAT\_IMAGIC\_INODES). | 580 | (COMPAT_IMAGIC_INODES). |
| 581 | * - 0x4 | 581 | * - 0x4 |
| 582 | - Has a journal (COMPAT\_HAS\_JOURNAL). | 582 | - Has a journal (COMPAT_HAS_JOURNAL). |
| 583 | * - 0x8 | 583 | * - 0x8 |
| 584 | - Supports extended attributes (COMPAT\_EXT\_ATTR). | 584 | - Supports extended attributes (COMPAT_EXT_ATTR). |
| 585 | * - 0x10 | 585 | * - 0x10 |
| 586 | - Has reserved GDT blocks for filesystem expansion | 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 | * - 0x20 | 588 | * - 0x20 |
| 589 | - Has directory indices (COMPAT\_DIR\_INDEX). | 589 | - Has directory indices (COMPAT_DIR_INDEX). |
| 590 | * - 0x40 | 590 | * - 0x40 |
| 591 | - “Lazy BG”. Not in Linux kernel, seems to have been for uninitialized | 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 | * - 0x80 | 593 | * - 0x80 |
| 594 | - “Exclude inode”. Not used. (COMPAT\_EXCLUDE\_INODE). | 594 | - “Exclude inode”. Not used. (COMPAT_EXCLUDE_INODE). |
| 595 | * - 0x100 | 595 | * - 0x100 |
| 596 | - “Exclude bitmap”. Seems to be used to indicate the presence of | 596 | - “Exclude bitmap”. Seems to be used to indicate the presence of |
| 597 | snapshot-related exclude bitmaps? Not defined in kernel or used in | 597 | snapshot-related exclude bitmaps? Not defined in kernel or used in |
| 598 | e2fsprogs (COMPAT\_EXCLUDE\_BITMAP). | 598 | e2fsprogs (COMPAT_EXCLUDE_BITMAP). |
| 599 | * - 0x200 | 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 | points to the two block groups that contain backup superblocks | 601 | points to the two block groups that contain backup superblocks |
| 602 | (COMPAT\_SPARSE\_SUPER2). | 602 | (COMPAT_SPARSE_SUPER2). |
| 603 | * - 0x400 | 603 | * - 0x400 |
| 604 | - Fast commits supported. Although fast commits blocks are | 604 | - Fast commits supported. Although fast commits blocks are |
| 605 | backward incompatible, fast commit blocks are not always | 605 | backward incompatible, fast commit blocks are not always |
| 606 | present in the journal. If fast commit blocks are present in | 606 | present in the journal. If fast commit blocks are present in |
| 607 | the journal, JBD2 incompat feature | 607 | the journal, JBD2 incompat feature |
| 608 | (JBD2\_FEATURE\_INCOMPAT\_FAST\_COMMIT) gets | 608 | (JBD2_FEATURE_INCOMPAT_FAST_COMMIT) gets |
| 609 | set (COMPAT\_FAST\_COMMIT). | 609 | set (COMPAT_FAST_COMMIT). |
| 610 | * - 0x1000 | 610 | * - 0x1000 |
| 611 | - Orphan file allocated. This is the special file for more efficient | 611 | - Orphan file allocated. This is the special file for more efficient |
| 612 | tracking of unlinked but still open inodes. When there may be any | 612 | tracking of unlinked but still open inodes. When there may be any |
| 613 | entries in the file, we additionally set proper rocompat feature | 613 | entries in the file, we additionally set proper rocompat feature |
| 614 | (RO\_COMPAT\_ORPHAN\_PRESENT). | 614 | (RO_COMPAT_ORPHAN_PRESENT). |
| 615 | 615 | ||
| 616 | .. _super_incompat: | 616 | .. _super_incompat: |
| 617 | 617 | ||
| @@ -625,45 +625,45 @@ following: · 7 unmodified lines | |||
| 625 | * - Value | 625 | * - Value |
| 626 | - Description | 626 | - Description |
| 627 | * - 0x1 | 627 | * - 0x1 |
| 628 | - Compression (INCOMPAT\_COMPRESSION). | 628 | - Compression (INCOMPAT_COMPRESSION). |
| 629 | * - 0x2 | 629 | * - 0x2 |
| 630 | - Directory entries record the file type. See ext4\_dir\_entry\_2 below | 630 | - Directory entries record the file type. See ext4_dir_entry_2 below |
| 631 | (INCOMPAT\_FILETYPE). | 631 | (INCOMPAT_FILETYPE). |
| 632 | * - 0x4 | 632 | * - 0x4 |
| 633 | - Filesystem needs recovery (INCOMPAT\_RECOVER). | 633 | - Filesystem needs recovery (INCOMPAT_RECOVER). |
| 634 | * - 0x8 | 634 | * - 0x8 |
| 635 | - Filesystem has a separate journal device (INCOMPAT\_JOURNAL\_DEV). | 635 | - Filesystem has a separate journal device (INCOMPAT_JOURNAL_DEV). |
| 636 | * - 0x10 | 636 | * - 0x10 |
| 637 | - Meta block groups. See the earlier discussion of this feature | 637 | - Meta block groups. See the earlier discussion of this feature |
| 638 | (INCOMPAT\_META\_BG). | 638 | (INCOMPAT_META_BG). |
| 639 | * - 0x40 | 639 | * - 0x40 |
| 640 | - Files in this filesystem use extents (INCOMPAT\_EXTENTS). | 640 | - Files in this filesystem use extents (INCOMPAT_EXTENTS). |
| 641 | * - 0x80 | 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 | * - 0x100 | 643 | * - 0x100 |
| 644 | - Multiple mount protection (INCOMPAT\_MMP). | 644 | - Multiple mount protection (INCOMPAT_MMP). |
| 645 | * - 0x200 | 645 | * - 0x200 |
| 646 | - Flexible block groups. See the earlier discussion of this feature | 646 | - Flexible block groups. See the earlier discussion of this feature |
| 647 | (INCOMPAT\_FLEX\_BG). | 647 | (INCOMPAT_FLEX_BG). |
| 648 | * - 0x400 | 648 | * - 0x400 |
| 649 | - Inodes can be used to store large extended attribute values | 649 | - Inodes can be used to store large extended attribute values |
| 650 | (INCOMPAT\_EA\_INODE). | 650 | (INCOMPAT_EA_INODE). |
| 651 | * - 0x1000 | 651 | * - 0x1000 |
| 652 | - Data in directory entry (INCOMPAT\_DIRDATA). (Not implemented?) | 652 | - Data in directory entry (INCOMPAT_DIRDATA). (Not implemented?) |
| 653 | * - 0x2000 | 653 | * - 0x2000 |
| 654 | - Metadata checksum seed is stored in the superblock. This feature enables | 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 | while the filesystem is mounted; without it, the checksum definition | 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 | * - 0x4000 | 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 | this feature, directories could not be larger than 4GiB and could not | 660 | this feature, directories could not be larger than 4GiB and could not |
| 661 | have an htree more than 2 levels deep. If this feature is enabled, | 661 | have an htree more than 2 levels deep. If this feature is enabled, |
| 662 | directories can be larger than 4GiB and have a maximum htree depth of 3. | 662 | directories can be larger than 4GiB and have a maximum htree depth of 3. |
| 663 | * - 0x8000 | 663 | * - 0x8000 |
| 664 | - Data in inode (INCOMPAT\_INLINE\_DATA). | 664 | - Data in inode (INCOMPAT_INLINE_DATA). |
| 665 | * - 0x10000 | 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 | .. _super_rocompat: | 668 | .. _super_rocompat: |
| 669 | 669 | ||
| @@ -678,54 +678,54 @@ the following: · 8 unmodified lines | |||
| 678 | - Description | 678 | - Description |
| 679 | * - 0x1 | 679 | * - 0x1 |
| 680 | - Sparse superblocks. See the earlier discussion of this feature | 680 | - Sparse superblocks. See the earlier discussion of this feature |
| 681 | (RO\_COMPAT\_SPARSE\_SUPER). | 681 | (RO_COMPAT_SPARSE_SUPER). |
| 682 | * - 0x2 | 682 | * - 0x2 |
| 683 | - This filesystem has been used to store a file greater than 2GiB | 683 | - This filesystem has been used to store a file greater than 2GiB |
| 684 | (RO\_COMPAT\_LARGE\_FILE). | 684 | (RO_COMPAT_LARGE_FILE). |
| 685 | * - 0x4 | 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 | * - 0x8 | 687 | * - 0x8 |
| 688 | - This filesystem has files whose sizes are represented in units of | 688 | - This filesystem has files whose sizes are represented in units of |
| 689 | logical blocks, not 512-byte sectors. This implies a very large file | 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 | * - 0x10 | 691 | * - 0x10 |
| 692 | - Group descriptors have checksums. In addition to detecting corruption, | 692 | - Group descriptors have checksums. In addition to detecting corruption, |
| 693 | this is useful for lazy formatting with uninitialized groups | 693 | this is useful for lazy formatting with uninitialized groups |
| 694 | (RO\_COMPAT\_GDT\_CSUM). | 694 | (RO_COMPAT_GDT_CSUM). |
| 695 | * - 0x20 | 695 | * - 0x20 |
| 696 | - Indicates that the old ext3 32,000 subdirectory limit no longer applies | 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 | if it is incremented past 64,999. | 698 | if it is incremented past 64,999. |
| 699 | * - 0x40 | 699 | * - 0x40 |
| 700 | - Indicates that large inodes exist on this filesystem | 700 | - Indicates that large inodes exist on this filesystem |
| 701 | (RO\_COMPAT\_EXTRA\_ISIZE). | 701 | (RO_COMPAT_EXTRA_ISIZE). |
| 702 | * - 0x80 | 702 | * - 0x80 |
| 703 | - This filesystem has a snapshot (RO\_COMPAT\_HAS\_SNAPSHOT). | 703 | - This filesystem has a snapshot (RO_COMPAT_HAS_SNAPSHOT). |
| 704 | * - 0x100 | 704 | * - 0x100 |
| 705 | - `Quota <Quota>`__ (RO\_COMPAT\_QUOTA). | 705 | - `Quota <Quota>`__ (RO_COMPAT_QUOTA). |
| 706 | * - 0x200 | 706 | * - 0x200 |
| 707 | - This filesystem supports “bigalloc”, which means that file extents are | 707 | - This filesystem supports “bigalloc”, which means that file extents are |
| 708 | tracked in units of clusters (of blocks) instead of blocks | 708 | tracked in units of clusters (of blocks) instead of blocks |
| 709 | (RO\_COMPAT\_BIGALLOC). | 709 | (RO_COMPAT_BIGALLOC). |
| 710 | * - 0x400 | 710 | * - 0x400 |
| 711 | - This filesystem supports metadata checksumming. | 711 | - This filesystem supports metadata checksumming. |
| 712 | (RO\_COMPAT\_METADATA\_CSUM; implies RO\_COMPAT\_GDT\_CSUM, though | 712 | (RO_COMPAT_METADATA_CSUM; implies RO_COMPAT_GDT_CSUM, though |
| 713 | GDT\_CSUM must not be set) | 713 | GDT_CSUM must not be set) |
| 714 | * - 0x800 | 714 | * - 0x800 |
| 715 | - Filesystem supports replicas. This feature is neither in the kernel nor | 715 | - Filesystem supports replicas. This feature is neither in the kernel nor |
| 716 | e2fsprogs. (RO\_COMPAT\_REPLICA) | 716 | e2fsprogs. (RO_COMPAT_REPLICA) |
| 717 | * - 0x1000 | 717 | * - 0x1000 |
| 718 | - Read-only filesystem image; the kernel will not mount this image | 718 | - Read-only filesystem image; the kernel will not mount this image |
| 719 | read-write and most tools will refuse to write to the image. | 719 | read-write and most tools will refuse to write to the image. |
| 720 | (RO\_COMPAT\_READONLY) | 720 | (RO_COMPAT_READONLY) |
| 721 | * - 0x2000 | 721 | * - 0x2000 |
| 722 | - Filesystem tracks project quotas. (RO\_COMPAT\_PROJECT) | 722 | - Filesystem tracks project quotas. (RO_COMPAT_PROJECT) |
| 723 | * - 0x8000 | 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 | * - 0x10000 | 725 | * - 0x10000 |
| 726 | - Indicates orphan file may have valid orphan entries and thus we need | 726 | - Indicates orphan file may have valid orphan entries and thus we need |
| 727 | to clean them up when mounting the filesystem | 727 | to clean them up when mounting the filesystem |
| 728 | (RO\_COMPAT\_ORPHAN\_PRESENT). | 728 | (RO_COMPAT_ORPHAN_PRESENT). |
| 729 | 729 | ||
| 730 | .. _super_def_hash: | 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 | * - Value | 761 | * - Value |
| 762 | - Description | 762 | - Description |
| 763 | * - 0x0001 | 763 | * - 0x0001 |
| 764 | - Print debugging info upon (re)mount. (EXT4\_DEFM\_DEBUG) | 764 | - Print debugging info upon (re)mount. (EXT4_DEFM_DEBUG) |
| 765 | * - 0x0002 | 765 | * - 0x0002 |
| 766 | - New files take the gid of the containing directory (instead of the fsgid | 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 | * - 0x0004 | 768 | * - 0x0004 |
| 769 | - Support userspace-provided extended attributes. (EXT4\_DEFM\_XATTR\_USER) | 769 | - Support userspace-provided extended attributes. (EXT4_DEFM_XATTR_USER) |
| 770 | * - 0x0008 | 770 | * - 0x0008 |
| 771 | - Support POSIX access control lists (ACLs). (EXT4\_DEFM\_ACL) | 771 | - Support POSIX access control lists (ACLs). (EXT4_DEFM_ACL) |
| 772 | * - 0x0010 | 772 | * - 0x0010 |
| 773 | - Do not support 32-bit UIDs. (EXT4\_DEFM\_UID16) | 773 | - Do not support 32-bit UIDs. (EXT4_DEFM_UID16) |
| 774 | * - 0x0020 | 774 | * - 0x0020 |
| 775 | - All data and metadata are commited to the journal. | 775 | - All data and metadata are commited to the journal. |
| 776 | (EXT4\_DEFM\_JMODE\_DATA) | 776 | (EXT4_DEFM_JMODE_DATA) |
| 777 | * - 0x0040 | 777 | * - 0x0040 |
| 778 | - All data are flushed to the disk before metadata are committed to the | 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 | * - 0x0060 | 780 | * - 0x0060 |
| 781 | - Data ordering is not preserved; data may be written after the metadata | 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 | * - 0x0100 | 783 | * - 0x0100 |
| 784 | - Disable write flushes. (EXT4\_DEFM\_NOBARRIER) | 784 | - Disable write flushes. (EXT4_DEFM_NOBARRIER) |
| 785 | * - 0x0200 | 785 | * - 0x0200 |
| 786 | - Track which blocks in a filesystem are metadata and therefore should not | 786 | - Track which blocks in a filesystem are metadata and therefore should not |
| 787 | be used as data blocks. This option will be enabled by default on 3.18, | 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 | * - 0x0400 | 789 | * - 0x0400 |
| 790 | - Enable DISCARD support, where the storage device is told about blocks | 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 | * - 0x0800 | 792 | * - 0x0800 |
| 793 | - Disable delayed allocation. (EXT4\_DEFM\_NODELALLOC) | 793 | - Disable delayed allocation. (EXT4_DEFM_NODELALLOC) |
| 794 | 794 | ||
| 795 | .. _super_flags: | 795 | .. _super_flags: |
| 796 | 796 | ||
| @@ -820,12 +820,12 @@ The ``s_encrypt_algos`` list can contain any of the following: · 23 unmodified lines | |||
| 820 | * - Value | 820 | * - Value |
| 821 | - Description | 821 | - Description |
| 822 | * - 0 | 822 | * - 0 |
| 823 | - Invalid algorithm (ENCRYPTION\_MODE\_INVALID). | 823 | - Invalid algorithm (ENCRYPTION_MODE_INVALID). |
| 824 | * - 1 | 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 | * - 2 | 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 | * - 3 | 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 | Total size of the superblock is 1024 bytes. | 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 | * - arm64 | 129 | * - arm64 |
| 130 | - Supported | 130 | - Supported |
| 131 | - ``LLVM=1`` | 131 | - ``LLVM=1`` |
| 132 | * - hexagon | ||
| 133 | - Maintained | ||
| 134 | - ``LLVM=1`` | ||
| 132 | * - mips | 135 | * - mips |
| 133 | - Maintained | 136 | - Maintained |
| 134 | - ``CC=clang`` | 137 | - ``LLVM=1`` |
| 135 | * - powerpc | 138 | * - powerpc |
| 136 | - Maintained | 139 | - Maintained |
| 137 | - ``CC=clang`` | 140 | - ``CC=clang`` |
| 138 | * - riscv | 141 | * - riscv |
| 139 | - Maintained | 142 | - Maintained |
| 140 | - ``CC=clang`` | 143 | - ``LLVM=1`` |
| 141 | * - s390 | 144 | * - s390 |
| 142 | - Maintained | 145 | - Maintained |
| 143 | - ``CC=clang`` | 146 | - ``CC=clang`` |
| 147 | * - um (User Mode) | ||
| 148 | - Maintained | ||
| 149 | - ``LLVM=1`` | ||
| 144 | * - x86 | 150 | * - x86 |
| 145 | - Supported | 151 | - Supported |
| 146 | - ``LLVM=1`` | 152 | - ``LLVM=1`` |
| @@ -45,10 +45,12 @@ Name Alias Usage Preserved · 44 unmodified lines | |||
| 45 | ``$r23``-``$r31`` ``$s0``-``$s8`` Static registers Yes | 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 | 48 | .. Note:: |
| 49 | kernel for storing the percpu base address. It normally has no ABI name, but is | 49 | The register ``$r21`` is reserved in the ELF psABI, but used by the Linux |
| 50 | called ``$u0`` in the kernel. You may also see ``$v0`` or ``$v1`` in some old code, | 50 | kernel for storing the percpu base address. It normally has no ABI name, |
| 51 | however they are deprecated aliases of ``$a0`` and ``$a1`` respectively. | 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 | FPRs | 55 | FPRs |
| 54 | ---- | 56 | ---- |
| @@ -69,8 +71,9 @@ Name Alias Usage Preserved · 14 unmodified lines | |||
| 69 | ``$f24``-``$f31`` ``$fs0``-``$fs7`` Static registers Yes | 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 | 74 | .. Note:: |
| 73 | aliases of ``$fa0`` and ``$fa1`` respectively. | 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 | VRs | 78 | VRs |
| 76 | ---- | 79 | ---- |
| @@ -145,12 +145,16 @@ Documentation of Loongson's LS7A chipset: · 144 unmodified lines | |||
| 145 | 145 | ||
| 146 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (in English) | 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 | 148 | .. Note:: |
| 149 | in Section 7.4 of "LoongArch Reference Manual, Vol 1"; LIOINTC is "Legacy I/O | 149 | - CPUINTC is CSR.ECFG/CSR.ESTAT and its interrupt controller described |
| 150 | Interrupts" described in Section 11.1 of "Loongson 3A5000 Processor Reference | 150 | in Section 7.4 of "LoongArch Reference Manual, Vol 1"; |
| 151 | Manual"; EIOINTC is "Extended I/O Interrupts" described in Section 11.2 of | 151 | - LIOINTC is "Legacy I/OInterrupts" described in Section 11.1 of |
| 152 | "Loongson 3A5000 Processor Reference Manual"; HTVECINTC is "HyperTransport | 152 | "Loongson 3A5000 Processor Reference Manual"; |
| 153 | Interrupts" described in Section 14.3 of "Loongson 3A5000 Processor Reference | 153 | - EIOINTC is "Extended I/O Interrupts" described in Section 11.2 of |
| 154 | Manual"; PCH-PIC/PCH-MSI is "Interrupt Controller" described in Section 5 of | 154 | "Loongson 3A5000 Processor Reference Manual"; |
| 155 | "Loongson 7A1000 Bridge User Manual"; PCH-LPC is "LPC Interrupts" described in | 155 | - HTVECINTC is "HyperTransport Interrupts" described in Section 14.3 of |
| 156 | Section 24.3 of "Loongson 7A1000 Bridge User Manual". | 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 | Default: 0 | 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 | ``/proc/sys/net/core/*`` | 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 | * PHY device drivers in PHYLIB being reusable by nature, being able to | 105 | * PHY device drivers in PHYLIB being reusable by nature, being able to |
| 106 | configure correctly a specified delay enables more designs with similar delay | 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 | For cases where the PHY is not capable of providing this delay, but the | 109 | For cases where the PHY is not capable of providing this delay, but the |
| 110 | Ethernet MAC driver is capable of doing so, the correct phy_interface_t value | 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 | ``$r23``-``$r31`` ``$s0``-``$s8`` 静态寄存器 是 | 46 | ``$r23``-``$r31`` ``$s0``-``$s8`` 静态寄存器 是 |
| 47 | ================= =============== =================== ========== | 47 | ================= =============== =================== ========== |
| 48 | 48 | ||
| 49 | 注意:``$r21``寄存器在ELF psABI中保留未使用,但是在Linux内核用于保存每CPU | 49 | .. note:: |
| 50 | 变量基地址。该寄存器没有ABI命名,不过在内核中称为``$u0``。在一些遗留代码 | 50 | 注意: ``$r21`` 寄存器在ELF psABI中保留未使用,但是在Linux内核用于保 |
| 51 | 中有时可能见到``$v0``和``$v1``,它们是``$a0``和``$a1``的别名,属于已经废弃 | 51 | 存每CPU变量基地址。该寄存器没有ABI命名,不过在内核中称为 ``$u0`` 。在 |
| 52 | 的用法。 | 52 | 一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 ``$a0`` 和 |
| 53 | ``$a1`` 的别名,属于已经废弃的用法。 | ||
| 53 | 54 | ||
| 54 | 浮点寄存器 | 55 | 浮点寄存器 |
| 55 | ---------- | 56 | ---------- |
| @@ -68,8 +69,9 @@ LA64中每个寄存器为64位宽。 ``$r0`` 的内容总是固定为0,而其 · 12 unmodified lines | |||
| 68 | ``$f24``-``$f31`` ``$fs0``-``$fs7`` 静态寄存器 是 | 69 | ``$f24``-``$f31`` ``$fs0``-``$fs7`` 静态寄存器 是 |
| 69 | ================= ================== =================== ========== | 70 | ================= ================== =================== ========== |
| 70 | 71 | ||
| 71 | 注意:在一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 ``$a0`` | 72 | .. note:: |
| 72 | 和 ``$a1`` 的别名,属于已经废弃的用法。 | 73 | 注意:在一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 |
| 74 | ``$a0`` 和 ``$a1`` 的别名,属于已经废弃的用法。 | ||
| 73 | 75 | ||
| 74 | 76 | ||
| 75 | 向量寄存器 | 77 | 向量寄存器 |
| @@ -147,9 +147,11 @@ PCH-LPC:: · 146 unmodified lines | |||
| 147 | 147 | ||
| 148 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (英文版) | 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寄存器及其中断 | 150 | .. note:: |
| 151 | 控制逻辑;LIOINTC即《龙芯3A5000处理器使用手册》第11.1节所描述的“传统I/O中断”;EIOINTC | 151 | - CPUINTC:即《龙芯架构参考手册卷一》第7.4节所描述的CSR.ECFG/CSR.ESTAT寄存器及其 |
| 152 | 即《龙芯3A5000处理器使用手册》第11.2节所描述的“扩展I/O中断”;HTVECINTC即《龙芯3A5000 | 152 | 中断控制逻辑; |
| 153 | 处理器使用手册》第14.3节所描述的“HyperTransport中断”;PCH-PIC/PCH-MSI即《龙芯7A1000桥 | 153 | - LIOINTC:即《龙芯3A5000处理器使用手册》第11.1节所描述的“传统I/O中断”; |
| 154 | 片用户手册》第5章所描述的“中断控制器”;PCH-LPC即《龙芯7A1000桥片用户手册》第24.3节所 | 154 | - EIOINTC:即《龙芯3A5000处理器使用手册》第11.2节所描述的“扩展I/O中断”; |
| 155 | 描述的“LPC中断”。 | 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 | unpoison-pfn | 120 | unpoison-pfn |
| 121 | Software-unpoison page at PFN echoed into this file. This way | 121 | Software-unpoison page at PFN echoed into this file. This way |
| 122 | a page can be reused again. This only works for Linux | 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 | Note these injection interfaces are not stable and might change between | 126 | Note these injection interfaces are not stable and might change between |
| 126 | kernel versions | 127 | kernel versions |
| @@ -427,6 +427,7 @@ ACPI VIOT DRIVER · 426 unmodified lines | |||
| 427 | M: Jean-Philippe Brucker <jean-philippe@linaro.org> | 427 | M: Jean-Philippe Brucker <jean-philippe@linaro.org> |
| 428 | L: linux-acpi@vger.kernel.org | 428 | L: linux-acpi@vger.kernel.org |
| 429 | L: iommu@lists.linux-foundation.org | 429 | L: iommu@lists.linux-foundation.org |
| 430 | L: iommu@lists.linux.dev | ||
| 430 | S: Maintained | 431 | S: Maintained |
| 431 | F: drivers/acpi/viot.c | 432 | F: drivers/acpi/viot.c |
| 432 | F: include/linux/acpi_viot.h | 433 | F: include/linux/acpi_viot.h |
| @@ -960,6 +961,7 @@ AMD IOMMU (AMD-VI) · 527 unmodified lines | |||
| 960 | M: Joerg Roedel <joro@8bytes.org> | 961 | M: Joerg Roedel <joro@8bytes.org> |
| 961 | R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | 962 | R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> |
| 962 | L: iommu@lists.linux-foundation.org | 963 | L: iommu@lists.linux-foundation.org |
| 964 | L: iommu@lists.linux.dev | ||
| 963 | S: Maintained | 965 | S: Maintained |
| 964 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 966 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 965 | F: drivers/iommu/amd/ | 967 | F: drivers/iommu/amd/ |
| @@ -2467,6 +2469,7 @@ ARM/NXP S32G ARCHITECTURE · 1501 unmodified lines | |||
| 2467 | M: Chester Lin <clin@suse.com> | 2469 | M: Chester Lin <clin@suse.com> |
| 2468 | R: Andreas Färber <afaerber@suse.de> | 2470 | R: Andreas Färber <afaerber@suse.de> |
| 2469 | R: Matthias Brugger <mbrugger@suse.com> | 2471 | R: Matthias Brugger <mbrugger@suse.com> |
| 2472 | R: NXP S32 Linux Team <s32@nxp.com> | ||
| 2470 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 2473 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2471 | S: Maintained | 2474 | S: Maintained |
| 2472 | F: arch/arm64/boot/dts/freescale/s32g*.dts* | 2475 | F: arch/arm64/boot/dts/freescale/s32g*.dts* |
| @@ -3662,7 +3665,7 @@ BPF JIT for ARM · 1189 unmodified lines | |||
| 3662 | M: Shubham Bansal <illusionist.neo@gmail.com> | 3665 | M: Shubham Bansal <illusionist.neo@gmail.com> |
| 3663 | L: netdev@vger.kernel.org | 3666 | L: netdev@vger.kernel.org |
| 3664 | L: bpf@vger.kernel.org | 3667 | L: bpf@vger.kernel.org |
| 3665 | S: Maintained | 3668 | S: Odd Fixes |
| 3666 | F: arch/arm/net/ | 3669 | F: arch/arm/net/ |
| 3667 | 3670 | ||
| 3668 | BPF JIT for ARM64 | 3671 | BPF JIT for ARM64 |
| @@ -3686,14 +3689,15 @@ BPF JIT for NFP NICs · 17 unmodified lines | |||
| 3686 | M: Jakub Kicinski <kuba@kernel.org> | 3689 | M: Jakub Kicinski <kuba@kernel.org> |
| 3687 | L: netdev@vger.kernel.org | 3690 | L: netdev@vger.kernel.org |
| 3688 | L: bpf@vger.kernel.org | 3691 | L: bpf@vger.kernel.org |
| 3689 | S: Supported | 3692 | S: Odd Fixes |
| 3690 | F: drivers/net/ethernet/netronome/nfp/bpf/ | 3693 | F: drivers/net/ethernet/netronome/nfp/bpf/ |
| 3691 | 3694 | ||
| 3692 | BPF JIT for POWERPC (32-BIT AND 64-BIT) | 3695 | BPF JIT for POWERPC (32-BIT AND 64-BIT) |
| 3693 | M: Naveen N. Rao <naveen.n.rao@linux.ibm.com> | 3696 | M: Naveen N. Rao <naveen.n.rao@linux.ibm.com> |
| 3697 | M: Michael Ellerman <mpe@ellerman.id.au> | ||
| 3694 | L: netdev@vger.kernel.org | 3698 | L: netdev@vger.kernel.org |
| 3695 | L: bpf@vger.kernel.org | 3699 | L: bpf@vger.kernel.org |
| 3696 | S: Maintained | 3700 | S: Supported |
| 3697 | F: arch/powerpc/net/ | 3701 | F: arch/powerpc/net/ |
| 3698 | 3702 | ||
| 3699 | BPF JIT for RISC-V (32-bit) | 3703 | BPF JIT for RISC-V (32-bit) |
| @@ -3719,7 +3723,7 @@ M: Heiko Carstens <hca@linux.ibm.com> · 19 unmodified lines | |||
| 3719 | M: Vasily Gorbik <gor@linux.ibm.com> | 3723 | M: Vasily Gorbik <gor@linux.ibm.com> |
| 3720 | L: netdev@vger.kernel.org | 3724 | L: netdev@vger.kernel.org |
| 3721 | L: bpf@vger.kernel.org | 3725 | L: bpf@vger.kernel.org |
| 3722 | S: Maintained | 3726 | S: Supported |
| 3723 | F: arch/s390/net/ | 3727 | F: arch/s390/net/ |
| 3724 | X: arch/s390/net/pnet.c | 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 | M: David S. Miller <davem@davemloft.net> | 3731 | M: David S. Miller <davem@davemloft.net> |
| 3728 | L: netdev@vger.kernel.org | 3732 | L: netdev@vger.kernel.org |
| 3729 | L: bpf@vger.kernel.org | 3733 | L: bpf@vger.kernel.org |
| 3730 | S: Maintained | 3734 | S: Odd Fixes |
| 3731 | F: arch/sparc/net/ | 3735 | F: arch/sparc/net/ |
| 3732 | 3736 | ||
| 3733 | BPF JIT for X86 32-BIT | 3737 | BPF JIT for X86 32-BIT |
| 3734 | M: Wang YanQing <udknight@gmail.com> | 3738 | M: Wang YanQing <udknight@gmail.com> |
| 3735 | L: netdev@vger.kernel.org | 3739 | L: netdev@vger.kernel.org |
| 3736 | L: bpf@vger.kernel.org | 3740 | L: bpf@vger.kernel.org |
| 3737 | S: Maintained | 3741 | S: Odd Fixes |
| 3738 | F: arch/x86/net/bpf_jit_comp32.c | 3742 | F: arch/x86/net/bpf_jit_comp32.c |
| 3739 | 3743 | ||
| 3740 | BPF JIT for X86 64-BIT | 3744 | BPF JIT for X86 64-BIT |
| @@ -3757,6 +3761,19 @@ F: include/linux/bpf_lsm.h · 16 unmodified lines | |||
| 3757 | F: kernel/bpf/bpf_lsm.c | 3761 | F: kernel/bpf/bpf_lsm.c |
| 3758 | F: security/bpf/ | 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 | BPFTOOL | 3777 | BPFTOOL |
| 3761 | M: Quentin Monnet <quentin@isovalent.com> | 3778 | M: Quentin Monnet <quentin@isovalent.com> |
| 3762 | L: bpf@vger.kernel.org | 3779 | L: bpf@vger.kernel.org |
| @@ -3796,12 +3813,12 @@ N: bcmbca · 33 unmodified lines | |||
| 3796 | N: bcm[9]?47622 | 3813 | N: bcm[9]?47622 |
| 3797 | 3814 | ||
| 3798 | BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE | 3815 | BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE |
| 3799 | M: Nicolas Saenz Julienne <nsaenz@kernel.org> | 3816 | M: Florian Fainelli <f.fainelli@gmail.com> |
| 3800 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> | 3817 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 3801 | L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) | 3818 | L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) |
| 3802 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 3819 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 3803 | S: Maintained | 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 | F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml | 3822 | F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml |
| 3806 | F: drivers/pci/controller/pcie-brcmstb.c | 3823 | F: drivers/pci/controller/pcie-brcmstb.c |
| 3807 | F: drivers/staging/vc04_services | 3824 | F: drivers/staging/vc04_services |
| @@ -5962,6 +5979,7 @@ M: Christoph Hellwig <hch@lst.de> · 2154 unmodified lines | |||
| 5962 | M: Marek Szyprowski <m.szyprowski@samsung.com> | 5979 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
| 5963 | R: Robin Murphy <robin.murphy@arm.com> | 5980 | R: Robin Murphy <robin.murphy@arm.com> |
| 5964 | L: iommu@lists.linux-foundation.org | 5981 | L: iommu@lists.linux-foundation.org |
| 5982 | L: iommu@lists.linux.dev | ||
| 5965 | S: Supported | 5983 | S: Supported |
| 5966 | W: http://git.infradead.org/users/hch/dma-mapping.git | 5984 | W: http://git.infradead.org/users/hch/dma-mapping.git |
| 5967 | T: git git://git.infradead.org/users/hch/dma-mapping.git | 5985 | T: git git://git.infradead.org/users/hch/dma-mapping.git |
| @@ -5974,6 +5992,7 @@ F: kernel/dma/ · 6 unmodified lines | |||
| 5974 | DMA MAPPING BENCHMARK | 5992 | DMA MAPPING BENCHMARK |
| 5975 | M: Xiang Chen <chenxiang66@hisilicon.com> | 5993 | M: Xiang Chen <chenxiang66@hisilicon.com> |
| 5976 | L: iommu@lists.linux-foundation.org | 5994 | L: iommu@lists.linux-foundation.org |
| 5995 | L: iommu@lists.linux.dev | ||
| 5977 | F: kernel/dma/map_benchmark.c | 5996 | F: kernel/dma/map_benchmark.c |
| 5978 | F: tools/testing/selftests/dma/ | 5997 | F: tools/testing/selftests/dma/ |
| 5979 | 5998 | ||
| @@ -7558,6 +7577,7 @@ F: drivers/gpu/drm/exynos/exynos_dp* · 1578 unmodified lines | |||
| 7558 | EXYNOS SYSMMU (IOMMU) driver | 7577 | EXYNOS SYSMMU (IOMMU) driver |
| 7559 | M: Marek Szyprowski <m.szyprowski@samsung.com> | 7578 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
| 7560 | L: iommu@lists.linux-foundation.org | 7579 | L: iommu@lists.linux-foundation.org |
| 7580 | L: iommu@lists.linux.dev | ||
| 7561 | S: Maintained | 7581 | S: Maintained |
| 7562 | F: drivers/iommu/exynos-iommu.c | 7582 | F: drivers/iommu/exynos-iommu.c |
| 7563 | 7583 | ||
| @@ -8479,6 +8499,7 @@ F: Documentation/devicetree/bindings/gpio/ · 915 unmodified lines | |||
| 8479 | F: Documentation/driver-api/gpio/ | 8499 | F: Documentation/driver-api/gpio/ |
| 8480 | F: drivers/gpio/ | 8500 | F: drivers/gpio/ |
| 8481 | F: include/asm-generic/gpio.h | 8501 | F: include/asm-generic/gpio.h |
| 8502 | F: include/dt-bindings/gpio/ | ||
| 8482 | F: include/linux/gpio.h | 8503 | F: include/linux/gpio.h |
| 8483 | F: include/linux/gpio/ | 8504 | F: include/linux/gpio/ |
| 8484 | F: include/linux/of_gpio.h | 8505 | F: include/linux/of_gpio.h |
| @@ -9132,6 +9153,7 @@ F: drivers/media/platform/st/sti/hva · 647 unmodified lines | |||
| 9132 | 9153 | ||
| 9133 | HWPOISON MEMORY FAILURE HANDLING | 9154 | HWPOISON MEMORY FAILURE HANDLING |
| 9134 | M: Naoya Horiguchi <naoya.horiguchi@nec.com> | 9155 | M: Naoya Horiguchi <naoya.horiguchi@nec.com> |
| 9156 | R: Miaohe Lin <linmiaohe@huawei.com> | ||
| 9135 | L: linux-mm@kvack.org | 9157 | L: linux-mm@kvack.org |
| 9136 | S: Maintained | 9158 | S: Maintained |
| 9137 | F: mm/hwpoison-inject.c | 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 | F: Documentation/devicetree/bindings/i2c/i2c.txt | 9298 | F: Documentation/devicetree/bindings/i2c/i2c.txt |
| 9277 | F: Documentation/i2c/ | 9299 | F: Documentation/i2c/ |
| 9278 | F: drivers/i2c/* | 9300 | F: drivers/i2c/* |
| 9301 | F: include/dt-bindings/i2c/i2c.h | ||
| 9279 | F: include/linux/i2c-dev.h | 9302 | F: include/linux/i2c-dev.h |
| 9280 | F: include/linux/i2c-smbus.h | 9303 | F: include/linux/i2c-smbus.h |
| 9281 | F: include/linux/i2c.h | 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 | F: Documentation/devicetree/bindings/i2c/ | 9314 | F: Documentation/devicetree/bindings/i2c/ |
| 9292 | F: drivers/i2c/algos/ | 9315 | F: drivers/i2c/algos/ |
| 9293 | F: drivers/i2c/busses/ | 9316 | F: drivers/i2c/busses/ |
| 9317 | F: include/dt-bindings/i2c/ | ||
| 9294 | 9318 | ||
| 9295 | I2C-TAOS-EVM DRIVER | 9319 | I2C-TAOS-EVM DRIVER |
| 9296 | M: Jean Delvare <jdelvare@suse.com> | 9320 | M: Jean Delvare <jdelvare@suse.com> |
| @@ -9975,6 +9999,7 @@ INTEL IOMMU (VT-d) · 678 unmodified lines | |||
| 9975 | M: David Woodhouse <dwmw2@infradead.org> | 9999 | M: David Woodhouse <dwmw2@infradead.org> |
| 9976 | M: Lu Baolu <baolu.lu@linux.intel.com> | 10000 | M: Lu Baolu <baolu.lu@linux.intel.com> |
| 9977 | L: iommu@lists.linux-foundation.org | 10001 | L: iommu@lists.linux-foundation.org |
| 10002 | L: iommu@lists.linux.dev | ||
| 9978 | S: Supported | 10003 | S: Supported |
| 9979 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 10004 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 9980 | F: drivers/iommu/intel/ | 10005 | F: drivers/iommu/intel/ |
| @@ -10354,6 +10379,7 @@ IOMMU DRIVERS · 373 unmodified lines | |||
| 10354 | M: Joerg Roedel <joro@8bytes.org> | 10379 | M: Joerg Roedel <joro@8bytes.org> |
| 10355 | M: Will Deacon <will@kernel.org> | 10380 | M: Will Deacon <will@kernel.org> |
| 10356 | L: iommu@lists.linux-foundation.org | 10381 | L: iommu@lists.linux-foundation.org |
| 10382 | L: iommu@lists.linux.dev | ||
| 10357 | S: Maintained | 10383 | S: Maintained |
| 10358 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 10384 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 10359 | F: Documentation/devicetree/bindings/iommu/ | 10385 | F: Documentation/devicetree/bindings/iommu/ |
| @@ -10830,6 +10856,7 @@ M: Marc Zyngier <maz@kernel.org> · 470 unmodified lines | |||
| 10830 | R: James Morse <james.morse@arm.com> | 10856 | R: James Morse <james.morse@arm.com> |
| 10831 | R: Alexandru Elisei <alexandru.elisei@arm.com> | 10857 | R: Alexandru Elisei <alexandru.elisei@arm.com> |
| 10832 | R: Suzuki K Poulose <suzuki.poulose@arm.com> | 10858 | R: Suzuki K Poulose <suzuki.poulose@arm.com> |
| 10859 | R: Oliver Upton <oliver.upton@linux.dev> | ||
| 10833 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 10860 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 10834 | L: kvmarm@lists.cs.columbia.edu (moderated for non-subscribers) | 10861 | L: kvmarm@lists.cs.columbia.edu (moderated for non-subscribers) |
| 10835 | S: Maintained | 10862 | S: Maintained |
| @@ -10872,7 +10899,6 @@ F: arch/riscv/include/asm/kvm* · 36 unmodified lines | |||
| 10872 | F: arch/riscv/include/uapi/asm/kvm* | 10899 | F: arch/riscv/include/uapi/asm/kvm* |
| 10873 | F: arch/riscv/kvm/ | 10900 | F: arch/riscv/kvm/ |
| 10874 | F: tools/testing/selftests/kvm/*/riscv/ | 10901 | F: tools/testing/selftests/kvm/*/riscv/ |
| 10875 | F: tools/testing/selftests/kvm/riscv/ | ||
| 10876 | 10902 | ||
| 10877 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) | 10903 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) |
| 10878 | M: Christian Borntraeger <borntraeger@linux.ibm.com> | 10904 | M: Christian Borntraeger <borntraeger@linux.ibm.com> |
| @@ -10897,28 +10923,51 @@ F: tools/testing/selftests/kvm/*/s390x/ · 18 unmodified lines | |||
| 10897 | F: tools/testing/selftests/kvm/s390x/ | 10923 | F: tools/testing/selftests/kvm/s390x/ |
| 10898 | 10924 | ||
| 10899 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) | 10925 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) |
| 10926 | M: Sean Christopherson <seanjc@google.com> | ||
| 10900 | M: Paolo Bonzini <pbonzini@redhat.com> | 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 | L: kvm@vger.kernel.org | 10928 | L: kvm@vger.kernel.org |
| 10907 | S: Supported | 10929 | S: Supported |
| 10908 | W: http://www.linux-kvm.org | ||
| 10909 | T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git | 10930 | T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git |
| 10910 | F: arch/x86/include/asm/kvm* | 10931 | F: arch/x86/include/asm/kvm* |
| 10911 | F: arch/x86/include/asm/pvclock-abi.h | ||
| 10912 | F: arch/x86/include/asm/svm.h | 10932 | F: arch/x86/include/asm/svm.h |
| 10913 | F: arch/x86/include/asm/vmx*.h | 10933 | F: arch/x86/include/asm/vmx*.h |
| 10914 | F: arch/x86/include/uapi/asm/kvm* | 10934 | F: arch/x86/include/uapi/asm/kvm* |
| 10915 | F: arch/x86/include/uapi/asm/svm.h | 10935 | F: arch/x86/include/uapi/asm/svm.h |
| 10916 | F: arch/x86/include/uapi/asm/vmx.h | 10936 | F: arch/x86/include/uapi/asm/vmx.h |
| 10917 | F: arch/x86/kernel/kvm.c | ||
| 10918 | F: arch/x86/kernel/kvmclock.c | ||
| 10919 | F: arch/x86/kvm/ | 10937 | F: arch/x86/kvm/ |
| 10920 | F: arch/x86/kvm/*/ | 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 | KERNFS | 10971 | KERNFS |
| 10923 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 10972 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 10924 | M: Tejun Heo <tj@kernel.org> | 10973 | M: Tejun Heo <tj@kernel.org> |
| @@ -11097,20 +11146,6 @@ S: Maintained · 172 unmodified lines | |||
| 11097 | F: include/net/l3mdev.h | 11146 | F: include/net/l3mdev.h |
| 11098 | F: net/l3mdev | 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 | LANDLOCK SECURITY MODULE | 11149 | LANDLOCK SECURITY MODULE |
| 11115 | M: Mickaël Salaün <mic@digikod.net> | 11150 | M: Mickaël Salaün <mic@digikod.net> |
| 11116 | L: linux-security-module@vger.kernel.org | 11151 | L: linux-security-module@vger.kernel.org |
| @@ -11590,6 +11625,7 @@ F: drivers/gpu/drm/bridge/lontium-lt8912b.c · 473 unmodified lines | |||
| 11590 | LOONGARCH | 11625 | LOONGARCH |
| 11591 | M: Huacai Chen <chenhuacai@kernel.org> | 11626 | M: Huacai Chen <chenhuacai@kernel.org> |
| 11592 | R: WANG Xuerui <kernel@xen0n.name> | 11627 | R: WANG Xuerui <kernel@xen0n.name> |
| 11628 | L: loongarch@lists.linux.dev | ||
| 11593 | S: Maintained | 11629 | S: Maintained |
| 11594 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git | 11630 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git |
| 11595 | F: arch/loongarch/ | 11631 | F: arch/loongarch/ |
| @@ -12503,6 +12539,7 @@ F: drivers/i2c/busses/i2c-mt65xx.c · 907 unmodified lines | |||
| 12503 | MEDIATEK IOMMU DRIVER | 12539 | MEDIATEK IOMMU DRIVER |
| 12504 | M: Yong Wu <yong.wu@mediatek.com> | 12540 | M: Yong Wu <yong.wu@mediatek.com> |
| 12505 | L: iommu@lists.linux-foundation.org | 12541 | L: iommu@lists.linux-foundation.org |
| 12542 | L: iommu@lists.linux.dev | ||
| 12506 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) | 12543 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) |
| 12507 | S: Supported | 12544 | S: Supported |
| 12508 | F: Documentation/devicetree/bindings/iommu/mediatek* | 12545 | F: Documentation/devicetree/bindings/iommu/mediatek* |
| @@ -12845,9 +12882,8 @@ M: Andrew Morton <akpm@linux-foundation.org> · 336 unmodified lines | |||
| 12845 | L: linux-mm@kvack.org | 12882 | L: linux-mm@kvack.org |
| 12846 | S: Maintained | 12883 | S: Maintained |
| 12847 | W: http://www.linux-mm.org | 12884 | W: http://www.linux-mm.org |
| 12848 | T: quilt https://ozlabs.org/~akpm/mmotm/ | 12885 | T: git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm |
| 12849 | T: quilt https://ozlabs.org/~akpm/mmots/ | 12886 | T: quilt git://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new |
| 12850 | T: git git://github.com/hnaz/linux-mm.git | ||
| 12851 | F: include/linux/gfp.h | 12887 | F: include/linux/gfp.h |
| 12852 | F: include/linux/memory_hotplug.h | 12888 | F: include/linux/memory_hotplug.h |
| 12853 | F: include/linux/mm.h | 12889 | F: include/linux/mm.h |
| @@ -12857,6 +12893,18 @@ F: include/linux/vmalloc.h · 3 unmodified lines | |||
| 12857 | F: mm/ | 12893 | F: mm/ |
| 12858 | F: tools/testing/selftests/vm/ | 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 | MEMORY TECHNOLOGY DEVICES (MTD) | 12908 | MEMORY TECHNOLOGY DEVICES (MTD) |
| 12861 | M: Miquel Raynal <miquel.raynal@bootlin.com> | 12909 | M: Miquel Raynal <miquel.raynal@bootlin.com> |
| 12862 | M: Richard Weinberger <richard@nod.at> | 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 | F: Documentation/devicetree/bindings/net/ | 13849 | F: Documentation/devicetree/bindings/net/ |
| 13802 | F: drivers/connector/ | 13850 | F: drivers/connector/ |
| 13803 | F: drivers/net/ | 13851 | F: drivers/net/ |
| 13852 | F: include/dt-bindings/net/ | ||
| 13804 | F: include/linux/etherdevice.h | 13853 | F: include/linux/etherdevice.h |
| 13805 | F: include/linux/fcdevice.h | 13854 | F: include/linux/fcdevice.h |
| 13806 | F: include/linux/fddidevice.h | 13855 | F: include/linux/fddidevice.h |
| @@ -13952,7 +14001,6 @@ F: net/ipv6/tcp*.c · 145 unmodified lines | |||
| 13952 | NETWORKING [TLS] | 14001 | NETWORKING [TLS] |
| 13953 | M: Boris Pismenny <borisp@nvidia.com> | 14002 | M: Boris Pismenny <borisp@nvidia.com> |
| 13954 | M: John Fastabend <john.fastabend@gmail.com> | 14003 | M: John Fastabend <john.fastabend@gmail.com> |
| 13955 | M: Daniel Borkmann <daniel@iogearbox.net> | ||
| 13956 | M: Jakub Kicinski <kuba@kernel.org> | 14004 | M: Jakub Kicinski <kuba@kernel.org> |
| 13957 | L: netdev@vger.kernel.org | 14005 | L: netdev@vger.kernel.org |
| 13958 | S: Maintained | 14006 | S: Maintained |
| @@ -14261,7 +14309,7 @@ F: drivers/iio/gyro/fxas21002c_i2c.c · 302 unmodified lines | |||
| 14261 | F: drivers/iio/gyro/fxas21002c_spi.c | 14309 | F: drivers/iio/gyro/fxas21002c_spi.c |
| 14262 | 14310 | ||
| 14263 | NXP i.MX CLOCK DRIVERS | 14311 | NXP i.MX CLOCK DRIVERS |
| 14264 | M: Abel Vesa <abel.vesa@nxp.com> | 14312 | M: Abel Vesa <abelvesa@kernel.org> |
| 14265 | L: linux-clk@vger.kernel.org | 14313 | L: linux-clk@vger.kernel.org |
| 14266 | L: linux-imx@nxp.com | 14314 | L: linux-imx@nxp.com |
| 14267 | S: Maintained | 14315 | S: Maintained |
| @@ -14869,6 +14917,7 @@ F: include/dt-bindings/ · 601 unmodified lines | |||
| 14869 | 14917 | ||
| 14870 | OPENCOMPUTE PTP CLOCK DRIVER | 14918 | OPENCOMPUTE PTP CLOCK DRIVER |
| 14871 | M: Jonathan Lemon <jonathan.lemon@gmail.com> | 14919 | M: Jonathan Lemon <jonathan.lemon@gmail.com> |
| 14920 | M: Vadim Fedorenko <vadfed@fb.com> | ||
| 14872 | L: netdev@vger.kernel.org | 14921 | L: netdev@vger.kernel.org |
| 14873 | S: Maintained | 14922 | S: Maintained |
| 14874 | F: drivers/ptp/ptp_ocp.c | 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 | F: drivers/cpufreq/qcom-cpufreq-nvmem.c | 16537 | F: drivers/cpufreq/qcom-cpufreq-nvmem.c |
| 16489 | 16538 | ||
| 16490 | QUALCOMM CRYPTO DRIVERS | 16539 | QUALCOMM CRYPTO DRIVERS |
| 16491 | M: Thara Gopinath <thara.gopinath@linaro.org> | 16540 | M: Thara Gopinath <thara.gopinath@gmail.com> |
| 16492 | L: linux-crypto@vger.kernel.org | 16541 | L: linux-crypto@vger.kernel.org |
| 16493 | L: linux-arm-msm@vger.kernel.org | 16542 | L: linux-arm-msm@vger.kernel.org |
| 16494 | S: Maintained | 16543 | S: Maintained |
| @@ -16543,6 +16592,7 @@ F: drivers/i2c/busses/i2c-qcom-cci.c · 48 unmodified lines | |||
| 16543 | QUALCOMM IOMMU | 16592 | QUALCOMM IOMMU |
| 16544 | M: Rob Clark <robdclark@gmail.com> | 16593 | M: Rob Clark <robdclark@gmail.com> |
| 16545 | L: iommu@lists.linux-foundation.org | 16594 | L: iommu@lists.linux-foundation.org |
| 16595 | L: iommu@lists.linux.dev | ||
| 16546 | L: linux-arm-msm@vger.kernel.org | 16596 | L: linux-arm-msm@vger.kernel.org |
| 16547 | S: Maintained | 16597 | S: Maintained |
| 16548 | F: drivers/iommu/arm/arm-smmu/qcom_iommu.c | 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 | QUALCOMM TSENS THERMAL DRIVER | 16649 | QUALCOMM TSENS THERMAL DRIVER |
| 16600 | M: Amit Kucheria <amitk@kernel.org> | 16650 | M: Amit Kucheria <amitk@kernel.org> |
| 16601 | M: Thara Gopinath <thara.gopinath@linaro.org> | 16651 | M: Thara Gopinath <thara.gopinath@gmail.com> |
| 16602 | L: linux-pm@vger.kernel.org | 16652 | L: linux-pm@vger.kernel.org |
| 16603 | L: linux-arm-msm@vger.kernel.org | 16653 | L: linux-arm-msm@vger.kernel.org |
| 16604 | S: Maintained | 16654 | S: Maintained |
| @@ -19168,6 +19218,7 @@ F: arch/x86/boot/video* · 2563 unmodified lines | |||
| 19168 | SWIOTLB SUBSYSTEM | 19218 | SWIOTLB SUBSYSTEM |
| 19169 | M: Christoph Hellwig <hch@infradead.org> | 19219 | M: Christoph Hellwig <hch@infradead.org> |
| 19170 | L: iommu@lists.linux-foundation.org | 19220 | L: iommu@lists.linux-foundation.org |
| 19221 | L: iommu@lists.linux.dev | ||
| 19171 | S: Supported | 19222 | S: Supported |
| 19172 | W: http://git.infradead.org/users/hch/dma-mapping.git | 19223 | W: http://git.infradead.org/users/hch/dma-mapping.git |
| 19173 | T: git git://git.infradead.org/users/hch/dma-mapping.git | 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 | R: Mika Westerberg <mika.westerberg@linux.intel.com> | 19356 | R: Mika Westerberg <mika.westerberg@linux.intel.com> |
| 19306 | R: Jan Dabros <jsd@semihalf.com> | 19357 | R: Jan Dabros <jsd@semihalf.com> |
| 19307 | L: linux-i2c@vger.kernel.org | 19358 | L: linux-i2c@vger.kernel.org |
| 19308 | S: Maintained | 19359 | S: Supported |
| 19309 | F: drivers/i2c/busses/i2c-designware-* | 19360 | F: drivers/i2c/busses/i2c-designware-* |
| 19310 | 19361 | ||
| 19311 | SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER | 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 | F: Documentation/devicetree/bindings/usb/ | 20763 | F: Documentation/devicetree/bindings/usb/ |
| 20713 | F: Documentation/usb/ | 20764 | F: Documentation/usb/ |
| 20714 | F: drivers/usb/ | 20765 | F: drivers/usb/ |
| 20766 | F: include/dt-bindings/usb/ | ||
| 20715 | F: include/linux/usb.h | 20767 | F: include/linux/usb.h |
| 20716 | F: include/linux/usb/ | 20768 | F: include/linux/usb/ |
| 20717 | 20769 | ||
| @@ -21843,6 +21895,7 @@ M: Juergen Gross <jgross@suse.com> · 1125 unmodified lines | |||
| 21843 | M: Stefano Stabellini <sstabellini@kernel.org> | 21895 | M: Stefano Stabellini <sstabellini@kernel.org> |
| 21844 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) | 21896 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) |
| 21845 | L: iommu@lists.linux-foundation.org | 21897 | L: iommu@lists.linux-foundation.org |
| 21898 | L: iommu@lists.linux.dev | ||
| 21846 | S: Supported | 21899 | S: Supported |
| 21847 | F: arch/x86/xen/*swiotlb* | 21900 | F: arch/x86/xen/*swiotlb* |
| 21848 | F: drivers/xen/*swiotlb* | 21901 | F: drivers/xen/*swiotlb* |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 19 | 3 | PATCHLEVEL = 19 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Superb Owl | 6 | NAME = Superb Owl |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -1141,7 +1141,7 @@ KBUILD_MODULES := 1 · 1132 unmodified lines | |||
| 1141 | 1141 | ||
| 1142 | autoksyms_recursive: descend modules.order | 1142 | autoksyms_recursive: descend modules.order |
| 1143 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ | 1143 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ |
| 1144 | "$(MAKE) -f $(srctree)/Makefile vmlinux" | 1144 | "$(MAKE) -f $(srctree)/Makefile autoksyms_recursive" |
| 1145 | endif | 1145 | endif |
| 1146 | 1146 | ||
| 1147 | autoksyms_h := $(if $(CONFIG_TRIM_UNUSED_KSYMS), include/generated/autoksyms.h) | 1147 | autoksyms_h := $(if $(CONFIG_TRIM_UNUSED_KSYMS), include/generated/autoksyms.h) |
| @@ -1586,7 +1586,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ · 1585 unmodified lines | |||
| 1586 | aspeed-bmc-lenovo-hr630.dtb \ | 1586 | aspeed-bmc-lenovo-hr630.dtb \ |
| 1587 | aspeed-bmc-lenovo-hr855xg2.dtb \ | 1587 | aspeed-bmc-lenovo-hr855xg2.dtb \ |
| 1588 | aspeed-bmc-microsoft-olympus.dtb \ | 1588 | aspeed-bmc-microsoft-olympus.dtb \ |
| 1589 | aspeed-bmc-nuvia-dc-scm.dtb \ | ||
| 1590 | aspeed-bmc-opp-lanyang.dtb \ | 1589 | aspeed-bmc-opp-lanyang.dtb \ |
| 1591 | aspeed-bmc-opp-mihawk.dtb \ | 1590 | aspeed-bmc-opp-mihawk.dtb \ |
| 1592 | aspeed-bmc-opp-mowgli.dtb \ | 1591 | aspeed-bmc-opp-mowgli.dtb \ |
| @@ -1599,6 +1598,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ · 6 unmodified lines | |||
| 1599 | aspeed-bmc-opp-witherspoon.dtb \ | 1598 | aspeed-bmc-opp-witherspoon.dtb \ |
| 1600 | aspeed-bmc-opp-zaius.dtb \ | 1599 | aspeed-bmc-opp-zaius.dtb \ |
| 1601 | aspeed-bmc-portwell-neptune.dtb \ | 1600 | aspeed-bmc-portwell-neptune.dtb \ |
| 1601 | aspeed-bmc-qcom-dc-scm-v1.dtb \ | ||
| 1602 | aspeed-bmc-quanta-q71l.dtb \ | 1602 | aspeed-bmc-quanta-q71l.dtb \ |
| 1603 | aspeed-bmc-quanta-s6q.dtb \ | 1603 | aspeed-bmc-quanta-s6q.dtb \ |
| 1604 | aspeed-bmc-supermicro-x11spi.dtb \ | 1604 | aspeed-bmc-supermicro-x11spi.dtb \ |
| @@ -6,8 +6,8 @@ · 5 unmodified lines | |||
| 6 | #include "aspeed-g6.dtsi" | 6 | #include "aspeed-g6.dtsi" |
| 7 | 7 | ||
| 8 | / { | 8 | / { |
| 9 | model = "Nuvia DC-SCM BMC"; | 9 | model = "Qualcomm DC-SCM V1 BMC"; |
| 10 | compatible = "nuvia,dc-scm-bmc", "aspeed,ast2600"; | 10 | compatible = "qcom,dc-scm-v1-bmc", "aspeed,ast2600"; |
| 11 | 11 | ||
| 12 | aliases { | 12 | aliases { |
| 13 | serial4 = &uart5; | 13 | serial4 = &uart5; |
| @@ -120,26 +120,31 @@ · 119 unmodified lines | |||
| 120 | port@0 { | 120 | port@0 { |
| 121 | reg = <0>; | 121 | reg = <0>; |
| 122 | label = "lan1"; | 122 | label = "lan1"; |
| 123 | phy-mode = "internal"; | ||
| 123 | }; | 124 | }; |
| 124 | 125 | ||
| 125 | port@1 { | 126 | port@1 { |
| 126 | reg = <1>; | 127 | reg = <1>; |
| 127 | label = "lan2"; | 128 | label = "lan2"; |
| 129 | phy-mode = "internal"; | ||
| 128 | }; | 130 | }; |
| 129 | 131 | ||
| 130 | port@2 { | 132 | port@2 { |
| 131 | reg = <2>; | 133 | reg = <2>; |
| 132 | label = "lan3"; | 134 | label = "lan3"; |
| 135 | phy-mode = "internal"; | ||
| 133 | }; | 136 | }; |
| 134 | 137 | ||
| 135 | port@3 { | 138 | port@3 { |
| 136 | reg = <3>; | 139 | reg = <3>; |
| 137 | label = "lan4"; | 140 | label = "lan4"; |
| 141 | phy-mode = "internal"; | ||
| 138 | }; | 142 | }; |
| 139 | 143 | ||
| 140 | port@4 { | 144 | port@4 { |
| 141 | reg = <4>; | 145 | reg = <4>; |
| 142 | label = "lan5"; | 146 | label = "lan5"; |
| 147 | phy-mode = "internal"; | ||
| 143 | }; | 148 | }; |
| 144 | 149 | ||
| 145 | port@5 { | 150 | port@5 { |
| @@ -28,12 +28,12 @@ · 27 unmodified lines | |||
| 28 | &expgpio { | 28 | &expgpio { |
| 29 | gpio-line-names = "BT_ON", | 29 | gpio-line-names = "BT_ON", |
| 30 | "WL_ON", | 30 | "WL_ON", |
| 31 | "", | 31 | "PWR_LED_OFF", |
| 32 | "GLOBAL_RESET", | 32 | "GLOBAL_RESET", |
| 33 | "VDD_SD_IO_SEL", | 33 | "VDD_SD_IO_SEL", |
| 34 | "CAM_GPIO", | 34 | "GLOBAL_SHUTDOWN", |
| 35 | "SD_PWR_ON", | 35 | "SD_PWR_ON", |
| 36 | "SD_OC_N"; | 36 | "SHUTDOWN_REQUEST"; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | &genet_mdio { | 39 | &genet_mdio { |
| @@ -593,7 +593,7 @@ · 592 unmodified lines | |||
| 593 | pinctrl-names = "default"; | 593 | pinctrl-names = "default"; |
| 594 | pinctrl-0 = <&pinctrl_atmel_conn>; | 594 | pinctrl-0 = <&pinctrl_atmel_conn>; |
| 595 | reg = <0x4a>; | 595 | reg = <0x4a>; |
| 596 | reset-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; /* SODIMM 106 */ | 596 | reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* SODIMM 106 */ |
| 597 | status = "disabled"; | 597 | status = "disabled"; |
| 598 | }; | 598 | }; |
| 599 | }; | 599 | }; |
| @@ -762,7 +762,7 @@ · 761 unmodified lines | |||
| 762 | regulator-name = "vddpu"; | 762 | regulator-name = "vddpu"; |
| 763 | regulator-min-microvolt = <725000>; | 763 | regulator-min-microvolt = <725000>; |
| 764 | regulator-max-microvolt = <1450000>; | 764 | regulator-max-microvolt = <1450000>; |
| 765 | regulator-enable-ramp-delay = <150>; | 765 | regulator-enable-ramp-delay = <380>; |
| 766 | anatop-reg-offset = <0x140>; | 766 | anatop-reg-offset = <0x140>; |
| 767 | anatop-vol-bit-shift = <9>; | 767 | anatop-vol-bit-shift = <9>; |
| 768 | anatop-vol-bit-width = <5>; | 768 | anatop-vol-bit-width = <5>; |
| @@ -120,6 +120,7 @@ · 119 unmodified lines | |||
| 120 | compatible = "usb-nop-xceiv"; | 120 | compatible = "usb-nop-xceiv"; |
| 121 | clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>; | 121 | clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>; |
| 122 | clock-names = "main_clk"; | 122 | clock-names = "main_clk"; |
| 123 | power-domains = <&pgc_hsic_phy>; | ||
| 123 | #phy-cells = <0>; | 124 | #phy-cells = <0>; |
| 124 | }; | 125 | }; |
| 125 | 126 | ||
| @@ -1153,7 +1154,6 @@ · 1027 unmodified lines | |||
| 1153 | compatible = "fsl,imx7d-usb", "fsl,imx27-usb"; | 1154 | compatible = "fsl,imx7d-usb", "fsl,imx27-usb"; |
| 1154 | reg = <0x30b30000 0x200>; | 1155 | reg = <0x30b30000 0x200>; |
| 1155 | interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; | 1156 | interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; |
| 1156 | power-domains = <&pgc_hsic_phy>; | ||
| 1157 | clocks = <&clks IMX7D_USB_CTRL_CLK>; | 1157 | clocks = <&clks IMX7D_USB_CTRL_CLK>; |
| 1158 | fsl,usbphy = <&usbphynop3>; | 1158 | fsl,usbphy = <&usbphynop3>; |
| 1159 | fsl,usbmisc = <&usbmisc3 0>; | 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 | status = "disabled"; | 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 | soc { | 118 | soc { |
| 146 | compatible = "simple-bus"; | 119 | compatible = "simple-bus"; |
| 147 | #address-cells = <1>; | 120 | #address-cells = <1>; |
| @@ -149,20 +122,6 @@ · 1 unmodified line | |||
| 149 | interrupt-parent = <&intc>; | 122 | interrupt-parent = <&intc>; |
| 150 | ranges; | 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 | timers2: timer@40000000 { | 125 | timers2: timer@40000000 { |
| 167 | #address-cells = <1>; | 126 | #address-cells = <1>; |
| 168 | #size-cells = <0>; | 127 | #size-cells = <0>; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | /dts-v1/; | 7 | /dts-v1/; |
| 8 | 8 | ||
| 9 | #include "stm32mp157a-dk1.dts" | 9 | #include "stm32mp157a-dk1.dts" |
| 10 | #include "stm32mp15-scmi.dtsi" | ||
| 10 | 11 | ||
| 11 | / { | 12 | / { |
| 12 | model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; | 13 | model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; |
| @@ -54,10 +55,6 @@ · 41 unmodified lines | |||
| 54 | resets = <&scmi_reset RST_SCMI_MCU>; | 55 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 57 | &optee { | ||
| 58 | status = "okay"; | ||
| 59 | }; | ||
| 60 | |||
| 61 | &rcc { | 58 | &rcc { |
| 62 | compatible = "st,stm32mp1-rcc-secure", "syscon"; | 59 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 63 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; | 60 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -76,11 +73,3 @@ · 12 unmodified lines | |||
| 76 | &rtc { | 73 | &rtc { |
| 77 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; | 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 | /dts-v1/; | 7 | /dts-v1/; |
| 8 | 8 | ||
| 9 | #include "stm32mp157c-dk2.dts" | 9 | #include "stm32mp157c-dk2.dts" |
| 10 | #include "stm32mp15-scmi.dtsi" | ||
| 10 | 11 | ||
| 11 | / { | 12 | / { |
| 12 | model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; | 13 | model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; |
| @@ -63,10 +64,6 @@ · 50 unmodified lines | |||
| 63 | resets = <&scmi_reset RST_SCMI_MCU>; | 64 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | &optee { | ||
| 67 | status = "okay"; | ||
| 68 | }; | ||
| 69 | |||
| 70 | &rcc { | 67 | &rcc { |
| 71 | compatible = "st,stm32mp1-rcc-secure", "syscon"; | 68 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 72 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; | 69 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -85,11 +82,3 @@ · 12 unmodified lines | |||
| 85 | &rtc { | 82 | &rtc { |
| 86 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; | 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 | /dts-v1/; | 7 | /dts-v1/; |
| 8 | 8 | ||
| 9 | #include "stm32mp157c-ed1.dts" | 9 | #include "stm32mp157c-ed1.dts" |
| 10 | #include "stm32mp15-scmi.dtsi" | ||
| 10 | 11 | ||
| 11 | / { | 12 | / { |
| 12 | model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; | 13 | model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; |
| @@ -59,10 +60,6 @@ · 46 unmodified lines | |||
| 59 | resets = <&scmi_reset RST_SCMI_MCU>; | 60 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 60 | }; | 61 | }; |
| 61 | 62 | ||
| 62 | &optee { | ||
| 63 | status = "okay"; | ||
| 64 | }; | ||
| 65 | |||
| 66 | &rcc { | 63 | &rcc { |
| 67 | compatible = "st,stm32mp1-rcc-secure", "syscon"; | 64 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 68 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; | 65 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -81,11 +78,3 @@ · 12 unmodified lines | |||
| 81 | &rtc { | 78 | &rtc { |
| 82 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; | 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 | /dts-v1/; | 7 | /dts-v1/; |
| 8 | 8 | ||
| 9 | #include "stm32mp157c-ev1.dts" | 9 | #include "stm32mp157c-ev1.dts" |
| 10 | #include "stm32mp15-scmi.dtsi" | ||
| 10 | 11 | ||
| 11 | / { | 12 | / { |
| 12 | model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; | 13 | model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; |
| @@ -68,10 +69,6 @@ · 55 unmodified lines | |||
| 68 | resets = <&scmi_reset RST_SCMI_MCU>; | 69 | resets = <&scmi_reset RST_SCMI_MCU>; |
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 71 | &optee { | ||
| 72 | status = "okay"; | ||
| 73 | }; | ||
| 74 | |||
| 75 | &rcc { | 72 | &rcc { |
| 76 | compatible = "st,stm32mp1-rcc-secure", "syscon"; | 73 | compatible = "st,stm32mp1-rcc-secure", "syscon"; |
| 77 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; | 74 | clock-names = "hse", "hsi", "csi", "lse", "lsi"; |
| @@ -90,11 +87,3 @@ · 12 unmodified lines | |||
| 90 | &rtc { | 87 | &rtc { |
| 91 | clocks = <&scmi_clk CK_SCMI_RTCAPB>, <&scmi_clk CK_SCMI_RTC>; | 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 | return -ENOENT; | 39 | return -ENOENT; |
| 40 | 40 | ||
| 41 | syscon = of_iomap(syscon_np, 0); | 41 | syscon = of_iomap(syscon_np, 0); |
| 42 | of_node_put(syscon_np); | ||
| 42 | if (!syscon) | 43 | if (!syscon) |
| 43 | return -ENOMEM; | 44 | return -ENOMEM; |
| 44 | 45 | ||
| @@ -372,6 +372,7 @@ static void __init cns3xxx_init(void) · 371 unmodified lines | |||
| 372 | /* De-Asscer SATA Reset */ | 372 | /* De-Asscer SATA Reset */ |
| 373 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA)); | 373 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA)); |
| 374 | } | 374 | } |
| 375 | of_node_put(dn); | ||
| 375 | 376 | ||
| 376 | dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-sdhci"); | 377 | dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-sdhci"); |
| 377 | if (of_device_is_available(dn)) { | 378 | if (of_device_is_available(dn)) { |
| @@ -385,6 +386,7 @@ static void __init cns3xxx_init(void) · 7 unmodified lines | |||
| 385 | cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO)); | 386 | cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO)); |
| 386 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO)); | 387 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO)); |
| 387 | } | 388 | } |
| 389 | of_node_put(dn); | ||
| 388 | 390 | ||
| 389 | pm_power_off = cns3xxx_power_off; | 391 | pm_power_off = cns3xxx_power_off; |
| 390 | 392 | ||
| @@ -149,6 +149,7 @@ static void exynos_map_pmu(void) · 148 unmodified lines | |||
| 149 | np = of_find_matching_node(NULL, exynos_dt_pmu_match); | 149 | np = of_find_matching_node(NULL, exynos_dt_pmu_match); |
| 150 | if (np) | 150 | if (np) |
| 151 | pmu_base_addr = of_iomap(np, 0); | 151 | pmu_base_addr = of_iomap(np, 0); |
| 152 | of_node_put(np); | ||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | static void __init exynos_init_irq(void) | 155 | static void __init exynos_init_irq(void) |
| @@ -218,13 +218,13 @@ void __init spear_setup_of_timer(void) · 217 unmodified lines | |||
| 218 | irq = irq_of_parse_and_map(np, 0); | 218 | irq = irq_of_parse_and_map(np, 0); |
| 219 | if (!irq) { | 219 | if (!irq) { |
| 220 | pr_err("%s: No irq passed for timer via DT\n", __func__); | 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 | gpt_base = of_iomap(np, 0); | 224 | gpt_base = of_iomap(np, 0); |
| 225 | if (!gpt_base) { | 225 | if (!gpt_base) { |
| 226 | pr_err("%s: of iomap failed\n", __func__); | 226 | pr_err("%s: of iomap failed\n", __func__); |
| 227 | return; | 227 | goto err_put_np; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | gpt_clk = clk_get_sys("gpt0", NULL); | 230 | gpt_clk = clk_get_sys("gpt0", NULL); |
| @@ -239,6 +239,8 @@ void __init spear_setup_of_timer(void) · 8 unmodified lines | |||
| 239 | goto err_prepare_enable_clk; | 239 | goto err_prepare_enable_clk; |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | of_node_put(np); | ||
| 243 | |||
| 242 | spear_clockevent_init(irq); | 244 | spear_clockevent_init(irq); |
| 243 | spear_clocksource_init(); | 245 | spear_clocksource_init(); |
| 244 | 246 | ||
| @@ -248,4 +250,6 @@ err_prepare_enable_clk: · 3 unmodified lines | |||
| 248 | clk_put(gpt_clk); | 250 | clk_put(gpt_clk); |
| 249 | err_iomap: | 251 | err_iomap: |
| 250 | iounmap(gpt_base); | 252 | iounmap(gpt_base); |
| 253 | err_put_np: | ||
| 254 | of_node_put(np); | ||
| 251 | } | 255 | } |
| @@ -280,8 +280,8 @@ · 279 unmodified lines | |||
| 280 | interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; | 280 | interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; |
| 281 | pinctrl-names = "default"; | 281 | pinctrl-names = "default"; |
| 282 | pinctrl-0 = <&uart0_bus>; | 282 | pinctrl-0 = <&uart0_bus>; |
| 283 | clocks = <&cmu_peri CLK_GOUT_UART0_EXT_UCLK>, | 283 | clocks = <&cmu_peri CLK_GOUT_UART0_PCLK>, |
| 284 | <&cmu_peri CLK_GOUT_UART0_PCLK>; | 284 | <&cmu_peri CLK_GOUT_UART0_EXT_UCLK>; |
| 285 | clock-names = "uart", "clk_uart_baud0"; | 285 | clock-names = "uart", "clk_uart_baud0"; |
| 286 | samsung,uart-fifosize = <64>; | 286 | samsung,uart-fifosize = <64>; |
| 287 | status = "disabled"; | 287 | status = "disabled"; |
| @@ -293,8 +293,8 @@ · 5 unmodified lines | |||
| 293 | interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>; | 293 | interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>; |
| 294 | pinctrl-names = "default"; | 294 | pinctrl-names = "default"; |
| 295 | pinctrl-0 = <&uart1_bus>; | 295 | pinctrl-0 = <&uart1_bus>; |
| 296 | clocks = <&cmu_peri CLK_GOUT_UART1_EXT_UCLK>, | 296 | clocks = <&cmu_peri CLK_GOUT_UART1_PCLK>, |
| 297 | <&cmu_peri CLK_GOUT_UART1_PCLK>; | 297 | <&cmu_peri CLK_GOUT_UART1_EXT_UCLK>; |
| 298 | clock-names = "uart", "clk_uart_baud0"; | 298 | clock-names = "uart", "clk_uart_baud0"; |
| 299 | samsung,uart-fifosize = <256>; | 299 | samsung,uart-fifosize = <256>; |
| 300 | status = "disabled"; | 300 | status = "disabled"; |
| @@ -306,8 +306,8 @@ · 5 unmodified lines | |||
| 306 | interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>; | 306 | interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>; |
| 307 | pinctrl-names = "default"; | 307 | pinctrl-names = "default"; |
| 308 | pinctrl-0 = <&uart2_bus>; | 308 | pinctrl-0 = <&uart2_bus>; |
| 309 | clocks = <&cmu_peri CLK_GOUT_UART2_EXT_UCLK>, | 309 | clocks = <&cmu_peri CLK_GOUT_UART2_PCLK>, |
| 310 | <&cmu_peri CLK_GOUT_UART2_PCLK>; | 310 | <&cmu_peri CLK_GOUT_UART2_EXT_UCLK>; |
| 311 | clock-names = "uart", "clk_uart_baud0"; | 311 | clock-names = "uart", "clk_uart_baud0"; |
| 312 | samsung,uart-fifosize = <256>; | 312 | samsung,uart-fifosize = <256>; |
| 313 | status = "disabled"; | 313 | status = "disabled"; |
| @@ -79,7 +79,7 @@ · 78 unmodified lines | |||
| 79 | }; | 79 | }; |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | soc { | 82 | soc@0 { |
| 83 | compatible = "simple-bus"; | 83 | compatible = "simple-bus"; |
| 84 | #address-cells = <1>; | 84 | #address-cells = <1>; |
| 85 | #size-cells = <1>; | 85 | #size-cells = <1>; |
| @@ -456,13 +456,11 @@ · 455 unmodified lines | |||
| 456 | clock-names = "clk_ahb", "clk_xin"; | 456 | clock-names = "clk_ahb", "clk_xin"; |
| 457 | mmc-ddr-1_8v; | 457 | mmc-ddr-1_8v; |
| 458 | mmc-hs200-1_8v; | 458 | mmc-hs200-1_8v; |
| 459 | mmc-hs400-1_8v; | ||
| 460 | ti,trm-icp = <0x2>; | 459 | ti,trm-icp = <0x2>; |
| 461 | ti,otap-del-sel-legacy = <0x0>; | 460 | ti,otap-del-sel-legacy = <0x0>; |
| 462 | ti,otap-del-sel-mmc-hs = <0x0>; | 461 | ti,otap-del-sel-mmc-hs = <0x0>; |
| 463 | ti,otap-del-sel-ddr52 = <0x6>; | 462 | ti,otap-del-sel-ddr52 = <0x6>; |
| 464 | ti,otap-del-sel-hs200 = <0x7>; | 463 | ti,otap-del-sel-hs200 = <0x7>; |
| 465 | ti,otap-del-sel-hs400 = <0x4>; | ||
| 466 | }; | 464 | }; |
| 467 | 465 | ||
| 468 | sdhci1: mmc@fa00000 { | 466 | sdhci1: mmc@fa00000 { |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | |||
| 33 | ranges; | 33 | ranges; |
| 34 | #interrupt-cells = <3>; | 34 | #interrupt-cells = <3>; |
| 35 | interrupt-controller; | 35 | interrupt-controller; |
| 36 | reg = <0x00 0x01800000 0x00 0x200000>, /* GICD */ | 36 | reg = <0x00 0x01800000 0x00 0x100000>, /* GICD */ |
| 37 | <0x00 0x01900000 0x00 0x100000>, /* GICR */ | 37 | <0x00 0x01900000 0x00 0x100000>, /* GICR */ |
| 38 | <0x00 0x6f000000 0x00 0x2000>, /* GICC */ | 38 | <0x00 0x6f000000 0x00 0x2000>, /* GICC */ |
| 39 | <0x00 0x6f010000 0x00 0x1000>, /* GICH */ | 39 | <0x00 0x6f010000 0x00 0x1000>, /* GICH */ |
| @@ -362,11 +362,6 @@ struct kvm_vcpu_arch { · 361 unmodified lines | |||
| 362 | struct arch_timer_cpu timer_cpu; | 362 | struct arch_timer_cpu timer_cpu; |
| 363 | struct kvm_pmu pmu; | 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 | * Guest registers we preserve during guest debugging. | 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 | * Code only run in VHE/NVHE hyp context can assume VHE is present or | 114 | * Code only run in VHE/NVHE hyp context can assume VHE is present or |
| 115 | * absent. Otherwise fall back to caps. | 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 | if (is_vhe_hyp_code()) | 120 | if (is_vhe_hyp_code()) |
| 118 | return true; | 121 | return true; |
| @@ -1974,15 +1974,7 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) · 1973 unmodified lines | |||
| 1974 | #ifdef CONFIG_KVM | 1974 | #ifdef CONFIG_KVM |
| 1975 | static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused) | 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) | 1977 | return 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; | ||
| 1986 | } | 1978 | } |
| 1987 | #endif /* CONFIG_KVM */ | 1979 | #endif /* CONFIG_KVM */ |
| 1988 | 1980 | ||
| @@ -3109,7 +3101,6 @@ void cpu_set_feature(unsigned int num) · 1120 unmodified lines | |||
| 3109 | WARN_ON(num >= MAX_CPU_FEATURES); | 3101 | WARN_ON(num >= MAX_CPU_FEATURES); |
| 3110 | elf_hwcap |= BIT(num); | 3102 | elf_hwcap |= BIT(num); |
| 3111 | } | 3103 | } |
| 3112 | EXPORT_SYMBOL_GPL(cpu_set_feature); | ||
| 3113 | 3104 | ||
| 3114 | bool cpu_have_feature(unsigned int num) | 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 | * x19-x29 per the AAPCS, and we created frame records upon entry, so we need | 102 | * x19-x29 per the AAPCS, and we created frame records upon entry, so we need |
| 103 | * to restore x0-x8, x29, and x30. | 103 | * to restore x0-x8, x29, and x30. |
| 104 | */ | 104 | */ |
| 105 | ftrace_common_return: | ||
| 106 | /* Restore function arguments */ | 105 | /* Restore function arguments */ |
| 107 | ldp x0, x1, [sp] | 106 | ldp x0, x1, [sp] |
| 108 | ldp x2, x3, [sp, #S_X2] | 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 | unsigned long pc = rec->ip; | 93 | unsigned long pc = rec->ip; |
| 86 | u32 old, new; | 94 | long offset = (long)*addr - (long)pc; |
| 87 | long offset = (long)pc - (long)addr; | 95 | struct plt_entry *plt; |
| 88 | 96 | ||
| 89 | if (offset < -SZ_128M || offset >= SZ_128M) { | 97 | /* |
| 90 | struct module *mod; | 98 | * When the target is within range of the 'BL' instruction, use 'addr' |
| 91 | struct plt_entry *plt; | 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)) | 104 | /* |
| 94 | return -EINVAL; | 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 | /* | 112 | /* |
| 97 | * On kernels that support module PLTs, the offset between the | 113 | * 'mod' is only set at module load time, but if we end up |
| 98 | * branch instruction and its target may legally exceed the | 114 | * dealing with an out-of-range condition, we can assume it |
| 99 | * range of an ordinary relative 'bl' opcode. In this case, we | 115 | * is due to a module being loaded far away from the kernel. |
| 100 | * need to branch via a trampoline in the module. | 116 | * |
| 101 | * | 117 | * NOTE: __module_text_address() must be called with preemption |
| 102 | * NOTE: __module_text_address() must be called with preemption | 118 | * disabled, but we can rely on ftrace_lock to ensure that 'mod' |
| 103 | * disabled, but we can rely on ftrace_lock to ensure that 'mod' | 119 | * retains its validity throughout the remainder of this code. |
| 104 | * retains its validity throughout the remainder of this code. | 120 | */ |
| 105 | */ | 121 | if (!mod) { |
| 106 | preempt_disable(); | 122 | preempt_disable(); |
| 107 | mod = __module_text_address(pc); | 123 | mod = __module_text_address(pc); |
| 108 | preempt_enable(); | 124 | preempt_enable(); |
| 125 | } | ||
| 109 | 126 | ||
| 110 | if (WARN_ON(!mod)) | 127 | if (WARN_ON(!mod)) |
| 111 | return -EINVAL; | 128 | return false; |
| 112 | 129 | ||
| 113 | plt = get_ftrace_plt(mod, addr); | 130 | plt = get_ftrace_plt(mod, *addr); |
| 114 | if (!plt) { | 131 | if (!plt) { |
| 115 | pr_err("ftrace: no module PLT for %ps\n", (void *)addr); | 132 | pr_err("ftrace: no module PLT for %ps\n", (void *)*addr); |
| 116 | return -EINVAL; | 133 | return false; |
| 117 | } | ||
| 118 | |||
| 119 | addr = (unsigned long)plt; | ||
| 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 | old = aarch64_insn_gen_nop(); | 151 | old = aarch64_insn_gen_nop(); |
| 123 | new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); | 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 | unsigned long pc = rec->ip; | 161 | unsigned long pc = rec->ip; |
| 133 | u32 old, new; | 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 | old = aarch64_insn_gen_branch_imm(pc, old_addr, | 169 | old = aarch64_insn_gen_branch_imm(pc, old_addr, |
| 136 | AARCH64_INSN_BRANCH_LINK); | 170 | AARCH64_INSN_BRANCH_LINK); |
| 137 | new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); | 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 | unsigned long addr) | 215 | unsigned long addr) |
| 182 | { | 216 | { |
| 183 | unsigned long pc = rec->ip; | 217 | unsigned long pc = rec->ip; |
| 184 | bool validate = true; | ||
| 185 | u32 old = 0, new; | 218 | u32 old = 0, new; |
| 186 | long offset = (long)pc - (long)addr; | ||
| 187 | 219 | ||
| 188 | if (offset < -SZ_128M || offset >= SZ_128M) { | 220 | if (!ftrace_find_callable_addr(rec, mod, &addr)) |
| 189 | u32 replaced; | 221 | return -EINVAL; |
| 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 | } | ||
| 228 | 222 | ||
| 223 | old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); | ||
| 229 | new = aarch64_insn_gen_nop(); | 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 | void arch_ftrace_update_code(int command) | 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 | early_fixmap_init(); | 303 | early_fixmap_init(); |
| 304 | early_ioremap_init(); | 304 | early_ioremap_init(); |
| 305 | 305 | ||
| 306 | setup_machine_fdt(__fdt_pointer); | ||
| 307 | |||
| 306 | /* | 308 | /* |
| 307 | * Initialise the static keys early as they may be enabled by the | 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 | jump_label_init(); | 312 | jump_label_init(); |
| 311 | |||
| 312 | setup_machine_fdt(__fdt_pointer); | ||
| 313 | |||
| 314 | parse_early_param(); | 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 | struct kvm_vcpu *vcpu = kvm_get_running_vcpu(); | 1230 | struct kvm_vcpu *vcpu = kvm_get_running_vcpu(); |
| 1231 | struct arch_timer_context *timer; | 1231 | struct arch_timer_context *timer; |
| 1232 | 1232 | ||
| 1233 | if (WARN(!vcpu, "No vcpu context!\n")) | ||
| 1234 | return false; | ||
| 1235 | |||
| 1233 | if (vintid == vcpu_vtimer(vcpu)->irq.irq) | 1236 | if (vintid == vcpu_vtimer(vcpu)->irq.irq) |
| 1234 | timer = vcpu_vtimer(vcpu); | 1237 | timer = vcpu_vtimer(vcpu); |
| 1235 | else if (vintid == vcpu_ptimer(vcpu)->irq.irq) | 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 | if (ret) | 150 | if (ret) |
| 151 | goto out_free_stage2_pgd; | 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 | goto out_free_stage2_pgd; | 155 | goto out_free_stage2_pgd; |
| 156 | } | ||
| 155 | cpumask_copy(kvm->arch.supported_cpus, cpu_possible_mask); | 157 | cpumask_copy(kvm->arch.supported_cpus, cpu_possible_mask); |
| 156 | 158 | ||
| 157 | kvm_vgic_early_init(kvm); | 159 | kvm_vgic_early_init(kvm); |
| @@ -2110,11 +2112,11 @@ static int finalize_hyp_mode(void) · 1952 unmodified lines | |||
| 2110 | return 0; | 2112 | return 0; |
| 2111 | 2113 | ||
| 2112 | /* | 2114 | /* |
| 2113 | * Exclude HYP BSS from kmemleak so that it doesn't get peeked | 2115 | * Exclude HYP sections from kmemleak so that they don't get peeked |
| 2114 | * at, which would end badly once the section is inaccessible. | 2116 | * at, which would end badly once inaccessible. |
| 2115 | * None of other sections should ever be introspected. | ||
| 2116 | */ | 2117 | */ |
| 2117 | kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); | 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 | return pkvm_drop_host_privileges(); | 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 | return -EINVAL; | 2273 | return -EINVAL; |
| 2272 | 2274 | ||
| 2273 | if (strcmp(arg, "protected") == 0) { | 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 | return 0; | 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 | vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED; | 80 | vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED; |
| 81 | vcpu->arch.flags |= KVM_ARM64_FP_HOST; | 81 | vcpu->arch.flags |= KVM_ARM64_FP_HOST; |
| 82 | 82 | ||
| 83 | vcpu->arch.flags &= ~KVM_ARM64_HOST_SVE_ENABLED; | ||
| 83 | if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN) | 84 | if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN) |
| 84 | vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED; | 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 | * operations. Do this for ZA as well for now for simplicity. | 94 | * operations. Do this for ZA as well for now for simplicity. |
| 94 | */ | 95 | */ |
| 95 | if (system_supports_sme()) { | 96 | if (system_supports_sme()) { |
| 97 | vcpu->arch.flags &= ~KVM_ARM64_HOST_SME_ENABLED; | ||
| 96 | if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN) | 98 | if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN) |
| 97 | vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED; | 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 | int host_stage2_idmap_locked(phys_addr_t addr, u64 size, | 314 | int host_stage2_idmap_locked(phys_addr_t addr, u64 size, |
| 315 | enum kvm_pgtable_prot prot) | 315 | enum kvm_pgtable_prot prot) |
| 316 | { | 316 | { |
| 317 | hyp_assert_lock_held(&host_kvm.lock); | ||
| 318 | |||
| 319 | return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); | 317 | return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); |
| 320 | } | 318 | } |
| 321 | 319 | ||
| 322 | int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) | 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 | return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, | 322 | return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, |
| 327 | addr, size, &host_s2_pool, owner_id); | 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 | case SYS_ID_AA64MMFR2_EL1: | 243 | case SYS_ID_AA64MMFR2_EL1: |
| 244 | return get_pvm_id_aa64mmfr2(vcpu); | 244 | return get_pvm_id_aa64mmfr2(vcpu); |
| 245 | default: | 245 | default: |
| 246 | /* | 246 | /* Unhandled ID register, RAZ */ |
| 247 | * Should never happen because all cases are covered in | 247 | return 0; |
| 248 | * pvm_sys_reg_descs[]. | ||
| 249 | */ | ||
| 250 | WARN_ON(1); | ||
| 251 | break; | ||
| 252 | } | 248 | } |
| 253 | |||
| 254 | return 0; | ||
| 255 | } | 249 | } |
| 256 | 250 | ||
| 257 | static u64 read_id_reg(const struct kvm_vcpu *vcpu, | 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 | /* Mark the specified system register as an AArch64 feature id register. */ | 326 | /* Mark the specified system register as an AArch64 feature id register. */ |
| 333 | #define AARCH64(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch64 } | 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 | /* Mark the specified system register as Read-As-Zero/Write-Ignored */ | 339 | /* Mark the specified system register as Read-As-Zero/Write-Ignored */ |
| 336 | #define RAZ_WI(REG) { SYS_DESC(REG), .access = pvm_access_raz_wi } | 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 | AARCH32(SYS_MVFR0_EL1), | 379 | AARCH32(SYS_MVFR0_EL1), |
| 376 | AARCH32(SYS_MVFR1_EL1), | 380 | AARCH32(SYS_MVFR1_EL1), |
| 377 | AARCH32(SYS_MVFR2_EL1), | 381 | AARCH32(SYS_MVFR2_EL1), |
| 382 | ID_UNALLOCATED(3,3), | ||
| 378 | AARCH32(SYS_ID_PFR2_EL1), | 383 | AARCH32(SYS_ID_PFR2_EL1), |
| 379 | AARCH32(SYS_ID_DFR1_EL1), | 384 | AARCH32(SYS_ID_DFR1_EL1), |
| 380 | AARCH32(SYS_ID_MMFR5_EL1), | 385 | AARCH32(SYS_ID_MMFR5_EL1), |
| 386 | ID_UNALLOCATED(3,7), | ||
| 381 | 387 | ||
| 382 | /* AArch64 ID registers */ | 388 | /* AArch64 ID registers */ |
| 383 | /* CRm=4 */ | 389 | /* CRm=4 */ |
| 384 | AARCH64(SYS_ID_AA64PFR0_EL1), | 390 | AARCH64(SYS_ID_AA64PFR0_EL1), |
| 385 | AARCH64(SYS_ID_AA64PFR1_EL1), | 391 | AARCH64(SYS_ID_AA64PFR1_EL1), |
| 392 | ID_UNALLOCATED(4,2), | ||
| 393 | ID_UNALLOCATED(4,3), | ||
| 386 | AARCH64(SYS_ID_AA64ZFR0_EL1), | 394 | AARCH64(SYS_ID_AA64ZFR0_EL1), |
| 395 | ID_UNALLOCATED(4,5), | ||
| 396 | ID_UNALLOCATED(4,6), | ||
| 397 | ID_UNALLOCATED(4,7), | ||
| 387 | AARCH64(SYS_ID_AA64DFR0_EL1), | 398 | AARCH64(SYS_ID_AA64DFR0_EL1), |
| 388 | AARCH64(SYS_ID_AA64DFR1_EL1), | 399 | AARCH64(SYS_ID_AA64DFR1_EL1), |
| 400 | ID_UNALLOCATED(5,2), | ||
| 401 | ID_UNALLOCATED(5,3), | ||
| 389 | AARCH64(SYS_ID_AA64AFR0_EL1), | 402 | AARCH64(SYS_ID_AA64AFR0_EL1), |
| 390 | AARCH64(SYS_ID_AA64AFR1_EL1), | 403 | AARCH64(SYS_ID_AA64AFR1_EL1), |
| 404 | ID_UNALLOCATED(5,6), | ||
| 405 | ID_UNALLOCATED(5,7), | ||
| 391 | AARCH64(SYS_ID_AA64ISAR0_EL1), | 406 | AARCH64(SYS_ID_AA64ISAR0_EL1), |
| 392 | AARCH64(SYS_ID_AA64ISAR1_EL1), | 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 | AARCH64(SYS_ID_AA64MMFR0_EL1), | 414 | AARCH64(SYS_ID_AA64MMFR0_EL1), |
| 394 | AARCH64(SYS_ID_AA64MMFR1_EL1), | 415 | AARCH64(SYS_ID_AA64MMFR1_EL1), |
| 395 | AARCH64(SYS_ID_AA64MMFR2_EL1), | 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 | /* Scalable Vector Registers are restricted. */ | 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 | VGIC_ACCESS_32bit), | 429 | VGIC_ACCESS_32bit), |
| 430 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_SET, | 430 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_SET, |
| 431 | vgic_mmio_read_pending, vgic_mmio_write_spending, | 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 | VGIC_ACCESS_32bit), | 433 | VGIC_ACCESS_32bit), |
| 434 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_CLEAR, | 434 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_CLEAR, |
| 435 | vgic_mmio_read_pending, vgic_mmio_write_cpending, | 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 | VGIC_ACCESS_32bit), | 437 | VGIC_ACCESS_32bit), |
| 438 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET, | 438 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET, |
| 439 | vgic_mmio_read_active, vgic_mmio_write_sactive, | 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 | return 0; | 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 | static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu, | 356 | static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu, |
| 393 | gpa_t addr, unsigned int len, | 357 | gpa_t addr, unsigned int len, |
| 394 | unsigned long val) | 358 | unsigned long val) |
| @@ -666,7 +630,7 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = { · 271 unmodified lines | |||
| 666 | VGIC_ACCESS_32bit), | 630 | VGIC_ACCESS_32bit), |
| 667 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISPENDR, | 631 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISPENDR, |
| 668 | vgic_mmio_read_pending, vgic_mmio_write_spending, | 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 | VGIC_ACCESS_32bit), | 634 | VGIC_ACCESS_32bit), |
| 671 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICPENDR, | 635 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICPENDR, |
| 672 | vgic_mmio_read_pending, vgic_mmio_write_cpending, | 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 | VGIC_ACCESS_32bit), | 714 | VGIC_ACCESS_32bit), |
| 751 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISPENDR0, | 715 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISPENDR0, |
| 752 | vgic_mmio_read_pending, vgic_mmio_write_spending, | 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 | VGIC_ACCESS_32bit), | 718 | VGIC_ACCESS_32bit), |
| 755 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICPENDR0, | 719 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICPENDR0, |
| 756 | vgic_mmio_read_pending, vgic_mmio_write_cpending, | 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 | return 0; | 226 | return 0; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, | 229 | static unsigned long __read_pending(struct kvm_vcpu *vcpu, |
| 230 | gpa_t addr, unsigned int len) | 230 | gpa_t addr, unsigned int len, |
| 231 | bool is_user) | ||
| 231 | { | 232 | { |
| 232 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | 233 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 233 | u32 value = 0; | 234 | u32 value = 0; |
| @@ -239,6 +240,15 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 5 unmodified lines | |||
| 239 | unsigned long flags; | 240 | unsigned long flags; |
| 240 | bool val; | 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 | raw_spin_lock_irqsave(&irq->irq_lock, flags); | 252 | raw_spin_lock_irqsave(&irq->irq_lock, flags); |
| 243 | if (irq->hw && vgic_irq_is_sgi(irq->intid)) { | 253 | if (irq->hw && vgic_irq_is_sgi(irq->intid)) { |
| 244 | int err; | 254 | int err; |
| @@ -248,10 +258,20 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 3 unmodified lines | |||
| 248 | IRQCHIP_STATE_PENDING, | 258 | IRQCHIP_STATE_PENDING, |
| 249 | &val); | 259 | &val); |
| 250 | WARN_RATELIMIT(err, "IRQ %d", irq->host_irq); | 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 | val = vgic_get_phys_line_level(irq); | 262 | val = vgic_get_phys_line_level(irq); |
| 253 | } else { | 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 | value |= ((u32)val << i); | 277 | value |= ((u32)val << i); |
| @@ -263,6 +283,18 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 5 unmodified lines | |||
| 263 | return value; | 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 | static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq) | 298 | static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq) |
| 267 | { | 299 | { |
| 268 | return (vgic_irq_is_sgi(irq->intid) && | 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 | unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, | 149 | unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, |
| 150 | gpa_t addr, unsigned int len); | 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 | void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, | 155 | void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, |
| 153 | gpa_t addr, unsigned int len, | 156 | gpa_t addr, unsigned int len, |
| 154 | unsigned long val); | 157 | unsigned long val); |
| @@ -66,7 +66,7 @@ static void flush_context(void) · 65 unmodified lines | |||
| 66 | * the next context-switch, we broadcast TLB flush + I-cache | 66 | * the next context-switch, we broadcast TLB flush + I-cache |
| 67 | * invalidation over the inner shareable domain on rollover. | 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 | static bool check_update_reserved_vmid(u64 vmid, u64 newvmid) | 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 | SYM_FUNC_START(__pi___dma_map_area) | 219 | SYM_FUNC_START(__pi___dma_map_area) |
| 220 | add x1, x0, x1 | 220 | add x1, x0, x1 |
| 221 | cmp w2, #DMA_FROM_DEVICE | ||
| 222 | b.eq __pi_dcache_inval_poc | ||
| 223 | b __pi_dcache_clean_poc | 221 | b __pi_dcache_clean_poc |
| 224 | SYM_FUNC_END(__pi___dma_map_area) | 222 | SYM_FUNC_END(__pi___dma_map_area) |
| 225 | SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area) | 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 | return regs->csr_era; | 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 | regs->csr_era += 4; | 17 | regs->csr_era += 4; |
| 18 | return 0; | ||
| 19 | } | 18 | } |
| 20 | 19 | ||
| 21 | #endif /* _ASM_BRANCH_H */ | 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 | #define kern_addr_valid(addr) (1) | 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 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 434 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 430 | 435 | ||
| 431 | /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/ | 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 | return pmd; | 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 | static inline struct page *pmd_page(pmd_t pmd) | 505 | static inline struct page *pmd_page(pmd_t pmd) |
| 506 | { | 506 | { |
| 507 | if (pmd_trans_huge(pmd)) | 507 | if (pmd_trans_huge(pmd)) |
| @@ -263,7 +263,7 @@ void cpu_probe(void) · 262 unmodified lines | |||
| 263 | 263 | ||
| 264 | c->cputype = CPU_UNKNOWN; | 264 | c->cputype = CPU_UNKNOWN; |
| 265 | c->processor_id = read_cpucfg(LOONGARCH_CPUCFG0); | 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 | c->fpu_csr0 = FPU_CSR_RN; | 268 | c->fpu_csr0 = FPU_CSR_RN; |
| 269 | c->fpu_mask = FPU_CSR_RSVD; | 269 | c->fpu_mask = FPU_CSR_RSVD; |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | __REF | 15 | __REF |
| 16 | 16 | ||
| 17 | SYM_ENTRY(_stext, SYM_L_GLOBAL, SYM_A_NONE) | ||
| 18 | |||
| 19 | SYM_CODE_START(kernel_entry) # kernel entry point | 17 | SYM_CODE_START(kernel_entry) # kernel entry point |
| 20 | 18 | ||
| 21 | /* Config direct window and set PG */ | 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 | die_if_kernel("Reserved instruction in kernel code", regs); | 476 | die_if_kernel("Reserved instruction in kernel code", regs); |
| 477 | 477 | ||
| 478 | if (unlikely(compute_return_era(regs) < 0)) | 478 | compute_return_era(regs); |
| 479 | goto out; | ||
| 480 | 479 | ||
| 481 | if (unlikely(get_user(opcode, era) < 0)) { | 480 | if (unlikely(get_user(opcode, era) < 0)) { |
| 482 | status = SIGSEGV; | 481 | status = SIGSEGV; |
| @@ -37,6 +37,7 @@ SECTIONS · 36 unmodified lines | |||
| 37 | HEAD_TEXT_SECTION | 37 | HEAD_TEXT_SECTION |
| 38 | 38 | ||
| 39 | . = ALIGN(PECOFF_SEGMENT_ALIGN); | 39 | . = ALIGN(PECOFF_SEGMENT_ALIGN); |
| 40 | _stext = .; | ||
| 40 | .text : { | 41 | .text : { |
| 41 | TEXT_TEXT | 42 | TEXT_TEXT |
| 42 | SCHED_TEXT | 43 | SCHED_TEXT |
| @@ -101,6 +102,7 @@ SECTIONS · 58 unmodified lines | |||
| 101 | 102 | ||
| 102 | STABS_DEBUG | 103 | STABS_DEBUG |
| 103 | DWARF_DEBUG | 104 | DWARF_DEBUG |
| 105 | ELF_DETAILS | ||
| 104 | 106 | ||
| 105 | .gptab.sdata : { | 107 | .gptab.sdata : { |
| 106 | *(.gptab.data) | 108 | *(.gptab.data) |
| @@ -281,15 +281,16 @@ void setup_tlb_handler(int cpu) · 280 unmodified lines | |||
| 281 | if (pcpu_handlers[cpu]) | 281 | if (pcpu_handlers[cpu]) |
| 282 | return; | 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 | if (!page) | 285 | if (!page) |
| 286 | return; | 286 | return; |
| 287 | 287 | ||
| 288 | addr = page_address(page); | 288 | addr = page_address(page); |
| 289 | pcpu_handlers[cpu] = virt_to_phys(addr); | 289 | pcpu_handlers[cpu] = (unsigned long)addr; |
| 290 | memcpy((void *)addr, (void *)eentry, vec_sz); | 290 | memcpy((void *)addr, (void *)eentry, vec_sz); |
| 291 | local_flush_icache_range((unsigned long)addr, (unsigned long)addr + vec_sz); | 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 | csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY); | 294 | csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY); |
| 294 | } | 295 | } |
| 295 | #endif | 296 | #endif |
| @@ -111,8 +111,9 @@ · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | clocks = <&cgu X1000_CLK_RTCLK>, | 112 | clocks = <&cgu X1000_CLK_RTCLK>, |
| 113 | <&cgu X1000_CLK_EXCLK>, | 113 | <&cgu X1000_CLK_EXCLK>, |
| 114 | <&cgu X1000_CLK_PCLK>; | 114 | <&cgu X1000_CLK_PCLK>, |
| 115 | clock-names = "rtc", "ext", "pclk"; | 115 | <&cgu X1000_CLK_TCU>; |
| 116 | clock-names = "rtc", "ext", "pclk", "tcu"; | ||
| 116 | 117 | ||
| 117 | interrupt-controller; | 118 | interrupt-controller; |
| 118 | #interrupt-cells = <1>; | 119 | #interrupt-cells = <1>; |
| @@ -104,8 +104,9 @@ · 103 unmodified lines | |||
| 104 | 104 | ||
| 105 | clocks = <&cgu X1830_CLK_RTCLK>, | 105 | clocks = <&cgu X1830_CLK_RTCLK>, |
| 106 | <&cgu X1830_CLK_EXCLK>, | 106 | <&cgu X1830_CLK_EXCLK>, |
| 107 | <&cgu X1830_CLK_PCLK>; | 107 | <&cgu X1830_CLK_PCLK>, |
| 108 | clock-names = "rtc", "ext", "pclk"; | 108 | <&cgu X1830_CLK_TCU>; |
| 109 | clock-names = "rtc", "ext", "pclk", "tcu"; | ||
| 109 | 110 | ||
| 110 | interrupt-controller; | 111 | interrupt-controller; |
| 111 | #interrupt-cells = <1>; | 112 | #interrupt-cells = <1>; |
| @@ -44,6 +44,7 @@ static __init unsigned int ranchu_measure_hpt_freq(void) · 43 unmodified lines | |||
| 44 | __func__); | 44 | __func__); |
| 45 | 45 | ||
| 46 | rtc_base = of_iomap(np, 0); | 46 | rtc_base = of_iomap(np, 0); |
| 47 | of_node_put(np); | ||
| 47 | if (!rtc_base) | 48 | if (!rtc_base) |
| 48 | panic("%s(): Failed to ioremap Goldfish RTC base!", __func__); | 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 | of_address_to_resource(np_sysgpe, 0, &res_sys[2])) | 208 | of_address_to_resource(np_sysgpe, 0, &res_sys[2])) |
| 209 | panic("Failed to get core resources"); | 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 | if ((request_mem_region(res_status.start, resource_size(&res_status), | 217 | if ((request_mem_region(res_status.start, resource_size(&res_status), |
| 212 | res_status.name) < 0) || | 218 | res_status.name) < 0) || |
| 213 | (request_mem_region(res_ebu.start, resource_size(&res_ebu), | 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 | if (!ltq_eiu_membase) | 408 | if (!ltq_eiu_membase) |
| 409 | panic("Failed to remap eiu memory"); | 409 | panic("Failed to remap eiu memory"); |
| 410 | } | 410 | } |
| 411 | of_node_put(eiu_node); | ||
| 411 | 412 | ||
| 412 | return 0; | 413 | return 0; |
| 413 | } | 414 | } |
| @@ -441,6 +441,10 @@ void __init ltq_soc_init(void) · 440 unmodified lines | |||
| 441 | of_address_to_resource(np_ebu, 0, &res_ebu)) | 441 | of_address_to_resource(np_ebu, 0, &res_ebu)) |
| 442 | panic("Failed to get core resources"); | 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 | if (!request_mem_region(res_pmu.start, resource_size(&res_pmu), | 448 | if (!request_mem_region(res_pmu.start, resource_size(&res_pmu), |
| 445 | res_pmu.name) || | 449 | res_pmu.name) || |
| 446 | !request_mem_region(res_cgu.start, resource_size(&res_cgu), | 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 | if (of_update_property(node, &gic_frequency_prop) < 0) | 215 | if (of_update_property(node, &gic_frequency_prop) < 0) |
| 216 | pr_err("error updating gic frequency property\n"); | 216 | pr_err("error updating gic frequency property\n"); |
| 217 | |||
| 218 | of_node_put(node); | ||
| 217 | } | 219 | } |
| 218 | 220 | ||
| 219 | #endif | 221 | #endif |
| @@ -98,13 +98,18 @@ static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup) · 97 unmodified lines | |||
| 98 | np = of_find_compatible_node(NULL, NULL, lookup->compatible); | 98 | np = of_find_compatible_node(NULL, NULL, lookup->compatible); |
| 99 | if (np) { | 99 | if (np) { |
| 100 | lookup->name = (char *)np->name; | 100 | lookup->name = (char *)np->name; |
| 101 | if (lookup->phys_addr) | 101 | if (lookup->phys_addr) { |
| 102 | of_node_put(np); | ||
| 102 | continue; | 103 | continue; |
| 104 | } | ||
| 103 | if (!of_address_to_resource(np, 0, &res)) | 105 | if (!of_address_to_resource(np, 0, &res)) |
| 104 | lookup->phys_addr = res.start; | 106 | lookup->phys_addr = res.start; |
| 107 | of_node_put(np); | ||
| 105 | } | 108 | } |
| 106 | } | 109 | } |
| 107 | 110 | ||
| 111 | of_node_put(root); | ||
| 112 | |||
| 108 | return 0; | 113 | return 0; |
| 109 | } | 114 | } |
| 110 | 115 | ||
| @@ -32,6 +32,9 @@ static unsigned int pic32_xlate_core_timer_irq(void) · 31 unmodified lines | |||
| 32 | goto default_map; | 32 | goto default_map; |
| 33 | 33 | ||
| 34 | irq = irq_of_parse_and_map(node, 0); | 34 | irq = irq_of_parse_and_map(node, 0); |
| 35 | |||
| 36 | of_node_put(node); | ||
| 37 | |||
| 35 | if (!irq) | 38 | if (!irq) |
| 36 | goto default_map; | 39 | goto default_map; |
| 37 | 40 | ||
| @@ -40,6 +40,8 @@ __iomem void *plat_of_remap_node(const char *node) · 39 unmodified lines | |||
| 40 | if (of_address_to_resource(np, 0, &res)) | 40 | if (of_address_to_resource(np, 0, &res)) |
| 41 | panic("Failed to get resource for %s", node); | 41 | panic("Failed to get resource for %s", node); |
| 42 | 42 | ||
| 43 | of_node_put(np); | ||
| 44 | |||
| 43 | if (!request_mem_region(res.start, | 45 | if (!request_mem_region(res.start, |
| 44 | resource_size(&res), | 46 | resource_size(&res), |
| 45 | res.name)) | 47 | res.name)) |
| @@ -640,8 +640,6 @@ static int icu_get_irq(unsigned int irq) · 639 unmodified lines | |||
| 640 | 640 | ||
| 641 | printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); | 641 | printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); |
| 642 | 642 | ||
| 643 | atomic_inc(&irq_err_count); | ||
| 644 | |||
| 645 | return -1; | 643 | return -1; |
| 646 | } | 644 | } |
| 647 | 645 | ||
| @@ -10,6 +10,7 @@ config PARISC · 9 unmodified lines | |||
| 10 | select ARCH_WANT_FRAME_POINTERS | 10 | select ARCH_WANT_FRAME_POINTERS |
| 11 | select ARCH_HAS_ELF_RANDOMIZE | 11 | select ARCH_HAS_ELF_RANDOMIZE |
| 12 | select ARCH_HAS_STRICT_KERNEL_RWX | 12 | select ARCH_HAS_STRICT_KERNEL_RWX |
| 13 | select ARCH_HAS_STRICT_MODULE_RWX | ||
| 13 | select ARCH_HAS_UBSAN_SANITIZE_ALL | 14 | select ARCH_HAS_UBSAN_SANITIZE_ALL |
| 14 | select ARCH_HAS_PTE_SPECIAL | 15 | select ARCH_HAS_PTE_SPECIAL |
| 15 | select ARCH_NO_SG_CHAIN | 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 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; | 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 | int fb_is_primary_device(struct fb_info *info); | 16 | int fb_is_primary_device(struct fb_info *info); |
| 17 | #else | 17 | #else |
| 18 | static inline int fb_is_primary_device(struct fb_info *info) | 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 | return; | 722 | return; |
| 723 | 723 | ||
| 724 | if (parisc_requires_coherency()) { | 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 | return; | 729 | return; |
| 727 | } | 730 | } |
| 728 | 731 | ||
| @@ -102,7 +102,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[]) · 101 unmodified lines | |||
| 102 | * that happen. Want to keep this overhead low, but still provide | 102 | * that happen. Want to keep this overhead low, but still provide |
| 103 | * some information to the customer. All exits from this routine | 103 | * some information to the customer. All exits from this routine |
| 104 | * need to restore Fpu_register[0] | 104 | * need to restore Fpu_register[0] |
| 105 | */ | 105 | */ |
| 106 | 106 | ||
| 107 | bflags=(Fpu_register[0] & 0xf8000000); | 107 | bflags=(Fpu_register[0] & 0xf8000000); |
| 108 | Fpu_register[0] &= 0x07ffffff; | 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 | tm_reclaim_current(0); | 1855 | tm_reclaim_current(0); |
| 1856 | #endif | 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 | regs->ctr = 0; | 1859 | regs->ctr = 0; |
| 1860 | regs->link = 0; | 1860 | regs->link = 0; |
| 1861 | regs->xer = 0; | 1861 | regs->xer = 0; |
| @@ -2302,7 +2302,7 @@ static void __init prom_init_stdout(void) · 2301 unmodified lines | |||
| 2302 | 2302 | ||
| 2303 | static int __init prom_find_machine_type(void) | 2303 | static int __init prom_find_machine_type(void) |
| 2304 | { | 2304 | { |
| 2305 | char compat[256]; | 2305 | static char compat[256] __prombss; |
| 2306 | int len, i = 0; | 2306 | int len, i = 0; |
| 2307 | #ifdef CONFIG_PPC64 | 2307 | #ifdef CONFIG_PPC64 |
| 2308 | phandle rtas; | 2308 | phandle rtas; |
| @@ -1071,7 +1071,7 @@ static struct rtas_filter rtas_filters[] __ro_after_init = { · 1070 unmodified lines | |||
| 1071 | { "get-time-of-day", -1, -1, -1, -1, -1 }, | 1071 | { "get-time-of-day", -1, -1, -1, -1, -1 }, |
| 1072 | { "ibm,get-vpd", -1, 0, -1, 1, 2 }, | 1072 | { "ibm,get-vpd", -1, 0, -1, 1, 2 }, |
| 1073 | { "ibm,lpar-perftools", -1, 2, 3, -1, -1 }, | 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 | { "ibm,read-slot-reset-state", -1, -1, -1, -1, -1 }, | 1075 | { "ibm,read-slot-reset-state", -1, -1, -1, -1, -1 }, |
| 1076 | { "ibm,scan-log-dump", -1, 0, 1, -1, -1 }, | 1076 | { "ibm,scan-log-dump", -1, 0, 1, -1, -1 }, |
| 1077 | { "ibm,set-dynamic-indicator", -1, 2, -1, -1, -1 }, | 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 | size = 1; | 1120 | size = 1; |
| 1121 | 1121 | ||
| 1122 | end = base + size - 1; | 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 | if (!in_rmo_buf(base, end)) | 1132 | if (!in_rmo_buf(base, end)) |
| 1124 | goto err; | 1133 | goto err; |
| 1125 | } | 1134 | } |
| @@ -935,12 +935,6 @@ void __init setup_arch(char **cmdline_p) · 934 unmodified lines | |||
| 935 | /* Print various info about the machine that has been gathered so far. */ | 935 | /* Print various info about the machine that has been gathered so far. */ |
| 936 | print_system_info(); | 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 | klp_init_thread_info(&init_task); | 938 | klp_init_thread_info(&init_task); |
| 945 | 939 | ||
| 946 | setup_initial_init_mm(_stext, _etext, _edata, _end); | 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 | initmem_init(); | 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 | early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); | 959 | early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); |
| 959 | 960 | ||
| 960 | if (ppc_md.setup_arch) | 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 | #include <asm/archrandom.h> | 11 | #include <asm/archrandom.h> |
| 12 | #include <asm/cputable.h> | 12 | #include <asm/cputable.h> |
| 13 | #include <asm/machdep.h> | 13 | #include <asm/machdep.h> |
| 14 | #include "microwatt.h" | ||
| 14 | 15 | ||
| 15 | #define DARN_ERR 0xFFFFFFFFFFFFFFFFul | 16 | #define DARN_ERR 0xFFFFFFFFFFFFFFFFul |
| 16 | 17 | ||
| @@ -29,7 +30,7 @@ static int microwatt_get_random_darn(unsigned long *v) · 12 unmodified lines | |||
| 29 | return 1; | 30 | return 1; |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | static __init int rng_init(void) | 33 | void __init microwatt_rng_init(void) |
| 33 | { | 34 | { |
| 34 | unsigned long val; | 35 | unsigned long val; |
| 35 | int i; | 36 | int i; |
| @@ -37,12 +38,7 @@ static __init int rng_init(void) · 1 unmodified line | |||
| 37 | for (i = 0; i < 10; i++) { | 38 | for (i = 0; i < 10; i++) { |
| 38 | if (microwatt_get_random_darn(&val)) { | 39 | if (microwatt_get_random_darn(&val)) { |
| 39 | ppc_md.get_random_seed = microwatt_get_random_darn; | 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 | #include <asm/xics.h> | 16 | #include <asm/xics.h> |
| 17 | #include <asm/udbg.h> | 17 | #include <asm/udbg.h> |
| 18 | 18 | ||
| 19 | #include "microwatt.h" | ||
| 20 | |||
| 19 | static void __init microwatt_init_IRQ(void) | 21 | static void __init microwatt_init_IRQ(void) |
| 20 | { | 22 | { |
| 21 | xics_init(); | 23 | xics_init(); |
| @@ -32,10 +34,16 @@ static int __init microwatt_populate(void) · 10 unmodified lines | |||
| 32 | } | 34 | } |
| 33 | machine_arch_initcall(microwatt, microwatt_populate); | 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 | define_machine(microwatt) { | 42 | define_machine(microwatt) { |
| 36 | .name = "microwatt", | 43 | .name = "microwatt", |
| 37 | .probe = microwatt_probe, | 44 | .probe = microwatt_probe, |
| 38 | .init_IRQ = microwatt_init_IRQ, | 45 | .init_IRQ = microwatt_init_IRQ, |
| 46 | .setup_arch = microwatt_setup_arch, | ||
| 39 | .progress = udbg_progress, | 47 | .progress = udbg_progress, |
| 40 | .calibrate_decr = generic_calibrate_decr, | 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 | u32 __init memcons_get_size(struct memcons *mc); | 42 | u32 __init memcons_get_size(struct memcons *mc); |
| 43 | struct memcons *__init memcons_init(struct device_node *node, const char *mc_prop_name); | 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 | #endif /* _POWERNV_H */ | 47 | #endif /* _POWERNV_H */ |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <asm/prom.h> | 17 | #include <asm/prom.h> |
| 18 | #include <asm/machdep.h> | 18 | #include <asm/machdep.h> |
| 19 | #include <asm/smp.h> | 19 | #include <asm/smp.h> |
| 20 | #include "powernv.h" | ||
| 20 | 21 | ||
| 21 | #define DARN_ERR 0xFFFFFFFFFFFFFFFFul | 22 | #define DARN_ERR 0xFFFFFFFFFFFFFFFFul |
| 22 | 23 | ||
| @@ -28,7 +29,6 @@ struct powernv_rng { · 5 unmodified lines | |||
| 28 | 29 | ||
| 29 | static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); | 30 | static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); |
| 30 | 31 | ||
| 31 | |||
| 32 | int powernv_hwrng_present(void) | 32 | int powernv_hwrng_present(void) |
| 33 | { | 33 | { |
| 34 | struct powernv_rng *rng; | 34 | struct powernv_rng *rng; |
| @@ -98,9 +98,6 @@ static int __init initialise_darn(void) · 63 unmodified lines | |||
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| 100 | } | 100 | } |
| 101 | |||
| 102 | pr_warn("Unable to use DARN for get_random_seed()\n"); | ||
| 103 | |||
| 104 | return -EIO; | 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 | rng_init_per_cpu(rng, dn); | 161 | rng_init_per_cpu(rng, dn); |
| 165 | 162 | ||
| 166 | pr_info_once("Registering arch random hook.\n"); | ||
| 167 | |||
| 168 | ppc_md.get_random_seed = powernv_get_random_long; | 163 | ppc_md.get_random_seed = powernv_get_random_long; |
| 169 | 164 | ||
| 170 | return 0; | 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 | struct device_node *dn; | 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 | for_each_compatible_node(dn, NULL, "ibm,power-rng") { | 179 | for_each_compatible_node(dn, NULL, "ibm,power-rng") { |
| 179 | rc = rng_create(dn); | 180 | if (rng_create(dn)) |
| 180 | if (rc) { | ||
| 181 | pr_err("Failed creating rng for %pOF (%d).\n", | ||
| 182 | dn, rc); | ||
| 183 | continue; | 181 | continue; |
| 184 | } | ||
| 185 | |||
| 186 | /* Create devices for hwrng driver */ | 182 | /* Create devices for hwrng driver */ |
| 187 | of_platform_device_create(dn, NULL, NULL); | 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 | return 0; | 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 | pnv_check_guarded_cores(); | 203 | pnv_check_guarded_cores(); |
| 204 | 204 | ||
| 205 | /* XXX PMCS */ | 205 | /* XXX PMCS */ |
| 206 | |||
| 207 | pnv_rng_init(); | ||
| 206 | } | 208 | } |
| 207 | 209 | ||
| 208 | static void __init pnv_init(void) | 210 | static void __init pnv_init(void) |
| @@ -122,4 +122,6 @@ void pseries_lpar_read_hblkrm_characteristics(void); · 121 unmodified lines | |||
| 122 | static inline void pseries_lpar_read_hblkrm_characteristics(void) { } | 122 | static inline void pseries_lpar_read_hblkrm_characteristics(void) { } |
| 123 | #endif | 123 | #endif |
| 124 | 124 | ||
| 125 | void pseries_rng_init(void); | ||
| 126 | |||
| 125 | #endif /* _PSERIES_PSERIES_H */ | 127 | #endif /* _PSERIES_PSERIES_H */ |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <asm/archrandom.h> | 10 | #include <asm/archrandom.h> |
| 11 | #include <asm/machdep.h> | 11 | #include <asm/machdep.h> |
| 12 | #include <asm/plpar_wrappers.h> | 12 | #include <asm/plpar_wrappers.h> |
| 13 | #include "pseries.h" | ||
| 13 | 14 | ||
| 14 | 15 | ||
| 15 | static int pseries_get_random_long(unsigned long *v) | 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 | return 0; | 25 | return 0; |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | static __init int rng_init(void) | 28 | void __init pseries_rng_init(void) |
| 28 | { | 29 | { |
| 29 | struct device_node *dn; | 30 | struct device_node *dn; |
| 30 | 31 | ||
| 31 | dn = of_find_compatible_node(NULL, NULL, "ibm,random"); | 32 | dn = of_find_compatible_node(NULL, NULL, "ibm,random"); |
| 32 | if (!dn) | 33 | if (!dn) |
| 33 | return -ENODEV; | 34 | return; |
| 34 | |||
| 35 | pr_info("Registering arch random hook.\n"); | ||
| 36 | |||
| 37 | ppc_md.get_random_seed = pseries_get_random_long; | 35 | ppc_md.get_random_seed = pseries_get_random_long; |
| 38 | |||
| 39 | of_node_put(dn); | 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 | ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; | 841 | ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; |
| 842 | pseries_rng_init(); | ||
| 842 | } | 843 | } |
| 843 | 844 | ||
| 844 | static void pseries_panic(char *str) | 845 | static void pseries_panic(char *str) |
| @@ -364,8 +364,13 @@ config RISCV_ISA_SVPBMT · 363 unmodified lines | |||
| 364 | select RISCV_ALTERNATIVE | 364 | select RISCV_ALTERNATIVE |
| 365 | default y | 365 | default y |
| 366 | help | 366 | help |
| 367 | Adds support to dynamically detect the presence of the SVPBMT extension | 367 | Adds support to dynamically detect the presence of the SVPBMT |
| 368 | (Supervisor-mode: page-based memory types) and enable its usage. | 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 | The SVPBMT extension is only available on 64Bit cpus. | 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 | config ERRATA_THEAD | 36 | config ERRATA_THEAD |
| 37 | bool "T-HEAD errata" | 37 | bool "T-HEAD errata" |
| 38 | depends on !XIP_KERNEL | ||
| 38 | select RISCV_ALTERNATIVE | 39 | select RISCV_ALTERNATIVE |
| 39 | help | 40 | help |
| 40 | All T-HEAD errata Kconfig depend on this Kconfig. Disabling | 41 | All T-HEAD errata Kconfig depend on this Kconfig. Disabling |
| @@ -192,6 +192,15 @@ · 191 unmodified lines | |||
| 192 | riscv,ndev = <186>; | 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 | clkcfg: clkcfg@20002000 { | 204 | clkcfg: clkcfg@20002000 { |
| 196 | compatible = "microchip,mpfs-clkcfg"; | 205 | compatible = "microchip,mpfs-clkcfg"; |
| 197 | reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; | 206 | reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; |
| @@ -75,20 +75,20 @@ asm volatile(ALTERNATIVE( \ · 74 unmodified lines | |||
| 75 | "nop\n\t" \ | 75 | "nop\n\t" \ |
| 76 | "nop\n\t" \ | 76 | "nop\n\t" \ |
| 77 | "nop", \ | 77 | "nop", \ |
| 78 | "li t3, %2\n\t" \ | 78 | "li t3, %1\n\t" \ |
| 79 | "slli t3, t3, %4\n\t" \ | 79 | "slli t3, t3, %3\n\t" \ |
| 80 | "and t3, %0, t3\n\t" \ | 80 | "and t3, %0, t3\n\t" \ |
| 81 | "bne t3, zero, 2f\n\t" \ | 81 | "bne t3, zero, 2f\n\t" \ |
| 82 | "li t3, %3\n\t" \ | 82 | "li t3, %2\n\t" \ |
| 83 | "slli t3, t3, %4\n\t" \ | 83 | "slli t3, t3, %3\n\t" \ |
| 84 | "or %0, %0, t3\n\t" \ | 84 | "or %0, %0, t3\n\t" \ |
| 85 | "2:", THEAD_VENDOR_ID, \ | 85 | "2:", THEAD_VENDOR_ID, \ |
| 86 | ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \ | 86 | ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \ |
| 87 | : "+r"(_val) \ | 87 | : "+r"(_val) \ |
| 88 | : "0"(_val), \ | 88 | : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \ |
| 89 | "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \ | ||
| 90 | "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT), \ | 89 | "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT), \ |
| 91 | "I"(ALT_THEAD_PBMT_SHIFT)) | 90 | "I"(ALT_THEAD_PBMT_SHIFT) \ |
| 91 | : "t3") | ||
| 92 | #else | 92 | #else |
| 93 | #define ALT_THEAD_PMA(_val) | 93 | #define ALT_THEAD_PMA(_val) |
| 94 | #endif | 94 | #endif |
| @@ -293,7 +293,6 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin, · 292 unmodified lines | |||
| 293 | unsigned int stage) | 293 | unsigned int stage) |
| 294 | { | 294 | { |
| 295 | u32 cpu_req_feature = cpufeature_probe(stage); | 295 | u32 cpu_req_feature = cpufeature_probe(stage); |
| 296 | u32 cpu_apply_feature = 0; | ||
| 297 | struct alt_entry *alt; | 296 | struct alt_entry *alt; |
| 298 | u32 tmp; | 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 | tmp = (1U << alt->errata_id); | 308 | tmp = (1U << alt->errata_id); |
| 310 | if (cpu_req_feature & tmp) { | 309 | if (cpu_req_feature & tmp) |
| 311 | patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); | 310 | patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); |
| 312 | cpu_apply_feature |= tmp; | ||
| 313 | } | ||
| 314 | } | 311 | } |
| 315 | } | 312 | } |
| 316 | #endif | 313 | #endif |
| @@ -97,7 +97,7 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu) · 96 unmodified lines | |||
| 97 | * We ran out of VMIDs so we increment vmid_version and | 97 | * We ran out of VMIDs so we increment vmid_version and |
| 98 | * start assigning VMIDs from 1. | 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 | * instances is invalid and we have force VMID re-assignement | 101 | * instances is invalid and we have force VMID re-assignement |
| 102 | * for all Guest instances. The Guest instances that were not | 102 | * for all Guest instances. The Guest instances that were not |
| 103 | * running will automatically pick-up new VMIDs because will | 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 | unsigned long src; | 219 | unsigned long src; |
| 220 | int rc; | 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 | if (!csize) | 227 | if (!csize) |
| 223 | return 0; | 228 | return 0; |
| 224 | src = pfn_to_phys(pfn) + offset; | 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 | rc = copy_oldmem_user(iter->iov->iov_base, src, csize); | 233 | rc = copy_oldmem_user(iter->iov->iov_base, src, csize); |
| 229 | else | 234 | else |
| 230 | rc = copy_oldmem_kernel(iter->kvec->iov_base, src, csize); | 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 | return err; | 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 | static int cpumf_pmu_event_init(struct perf_event *event) | 539 | static int cpumf_pmu_event_init(struct perf_event *event) |
| 520 | { | 540 | { |
| 521 | unsigned int type = event->attr.type; | 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 | err = __hw_perf_event_init(event, type); | 545 | err = __hw_perf_event_init(event, type); |
| 526 | else if (event->pmu->type == type) | 546 | else if (event->pmu->type == type) |
| 527 | /* Registered as unknown PMU */ | 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 | else | 549 | else |
| 530 | return -ENOENT; | 550 | return -ENOENT; |
| 531 | 551 | ||
| @@ -193,8 +193,9 @@ static int paicrypt_event_init(struct perf_event *event) · 192 unmodified lines | |||
| 193 | /* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */ | 193 | /* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */ |
| 194 | if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type) | 194 | if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type) |
| 195 | return -ENOENT; | 195 | return -ENOENT; |
| 196 | /* PAI crypto event must be valid */ | 196 | /* PAI crypto event must be in valid range */ |
| 197 | if (a->config > PAI_CRYPTO_BASE + paicrypt_cnt) | 197 | if (a->config < PAI_CRYPTO_BASE || |
| 198 | a->config > PAI_CRYPTO_BASE + paicrypt_cnt) | ||
| 198 | return -EINVAL; | 199 | return -EINVAL; |
| 199 | /* Allow only CPU wide operation, no process context for now. */ | 200 | /* Allow only CPU wide operation, no process context for now. */ |
| 200 | if (event->hw.target || event->cpu == -1) | 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 | if (rc) | 209 | if (rc) |
| 209 | return rc; | 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 | cpump->event = event; | 218 | cpump->event = event; |
| 212 | event->destroy = paicrypt_event_destroy; | 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 | u64 sum; | 250 | u64 sum; |
| 244 | 251 | ||
| 245 | sum = paicrypt_getall(event); /* Get current value */ | 252 | if (!event->hw.last_tag) { |
| 246 | local64_set(&event->hw.prev_count, sum); | 253 | event->hw.last_tag = 1; |
| 247 | local64_set(&event->count, 0); | 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 | static int paicrypt_add(struct perf_event *event, int flags) | 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 | return BIT_ULL(gpa_width - 1); | 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 | static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti) | 172 | static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti) |
| 128 | { | 173 | { |
| 129 | struct tdx_hypercall_args args = { | 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 | return __tdx_hypercall(&args, do_sti ? TDX_HCALL_ISSUE_STI : 0); | 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 | * Since non safe halt is mainly used in CPU offlining | 198 | * Since non safe halt is mainly used in CPU offlining |
| @@ -158,9 +203,9 @@ static bool handle_halt(void) · 4 unmodified lines | |||
| 158 | const bool do_sti = false; | 203 | const bool do_sti = false; |
| 159 | 204 | ||
| 160 | if (__halt(irq_disabled, do_sti)) | 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 | void __cpuidle tdx_safe_halt(void) | 211 | void __cpuidle tdx_safe_halt(void) |
| @@ -180,7 +225,7 @@ void __cpuidle tdx_safe_halt(void) · 13 unmodified lines | |||
| 180 | WARN_ONCE(1, "HLT instruction emulation failed\n"); | 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 | struct tdx_hypercall_args args = { | 230 | struct tdx_hypercall_args args = { |
| 186 | .r10 = TDX_HYPERCALL_STANDARD, | 231 | .r10 = TDX_HYPERCALL_STANDARD, |
| @@ -194,14 +239,14 @@ static bool read_msr(struct pt_regs *regs) · 7 unmodified lines | |||
| 194 | * (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>". | 239 | * (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>". |
| 195 | */ | 240 | */ |
| 196 | if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) | 241 | if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) |
| 197 | return false; | 242 | return -EIO; |
| 198 | 243 | ||
| 199 | regs->ax = lower_32_bits(args.r11); | 244 | regs->ax = lower_32_bits(args.r11); |
| 200 | regs->dx = upper_32_bits(args.r11); | 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 | struct tdx_hypercall_args args = { | 251 | struct tdx_hypercall_args args = { |
| 207 | .r10 = TDX_HYPERCALL_STANDARD, | 252 | .r10 = TDX_HYPERCALL_STANDARD, |
| @@ -215,10 +260,13 @@ static bool write_msr(struct pt_regs *regs) · 7 unmodified lines | |||
| 215 | * can be found in TDX Guest-Host-Communication Interface | 260 | * can be found in TDX Guest-Host-Communication Interface |
| 216 | * (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>". | 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 | struct tdx_hypercall_args args = { | 271 | struct tdx_hypercall_args args = { |
| 224 | .r10 = TDX_HYPERCALL_STANDARD, | 272 | .r10 = TDX_HYPERCALL_STANDARD, |
| @@ -236,7 +284,7 @@ static bool handle_cpuid(struct pt_regs *regs) · 11 unmodified lines | |||
| 236 | */ | 284 | */ |
| 237 | if (regs->ax < 0x40000000 || regs->ax > 0x4FFFFFFF) { | 285 | if (regs->ax < 0x40000000 || regs->ax > 0x4FFFFFFF) { |
| 238 | regs->ax = regs->bx = regs->cx = regs->dx = 0; | 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 | * (GHCI), section titled "VP.VMCALL<Instruction.CPUID>". | 293 | * (GHCI), section titled "VP.VMCALL<Instruction.CPUID>". |
| 246 | */ | 294 | */ |
| 247 | if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) | 295 | if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) |
| 248 | return false; | 296 | return -EIO; |
| 249 | 297 | ||
| 250 | /* | 298 | /* |
| 251 | * As per TDX GHCI CPUID ABI, r12-r15 registers contain contents of | 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 | regs->cx = args.r14; | 305 | regs->cx = args.r14; |
| 258 | regs->dx = args.r15; | 306 | regs->dx = args.r15; |
| 259 | 307 | ||
| 260 | return true; | 308 | return ve_instr_len(ve); |
| 261 | } | 309 | } |
| 262 | 310 | ||
| 263 | static bool mmio_read(int size, unsigned long addr, unsigned long *val) | 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 | EPT_WRITE, addr, val); | 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 | char buffer[MAX_INSN_SIZE]; | 337 | char buffer[MAX_INSN_SIZE]; |
| 289 | unsigned long *reg, val; | ||
| 290 | struct insn insn = {}; | 338 | struct insn insn = {}; |
| 291 | enum mmio_type mmio; | 339 | enum mmio_type mmio; |
| 292 | int size, extend_size; | 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 | /* Only in-kernel MMIO is supported */ | 343 | /* Only in-kernel MMIO is supported */ |
| 296 | if (WARN_ON_ONCE(user_mode(regs))) | 344 | if (WARN_ON_ONCE(user_mode(regs))) |
| 297 | return false; | 345 | return -EFAULT; |
| 298 | 346 | ||
| 299 | if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) | 347 | if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) |
| 300 | return false; | 348 | return -EFAULT; |
| 301 | 349 | ||
| 302 | if (insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) | 350 | if (insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) |
| 303 | return false; | 351 | return -EINVAL; |
| 304 | 352 | ||
| 305 | mmio = insn_decode_mmio(&insn, &size); | 353 | mmio = insn_decode_mmio(&insn, &size); |
| 306 | if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED)) | 354 | if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED)) |
| 307 | return false; | 355 | return -EINVAL; |
| 308 | 356 | ||
| 309 | if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) { | 357 | if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) { |
| 310 | reg = insn_get_modrm_reg_ptr(&insn, regs); | 358 | reg = insn_get_modrm_reg_ptr(&insn, regs); |
| 311 | if (!reg) | 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 | /* Handle writes first */ | 376 | /* Handle writes first */ |
| 318 | switch (mmio) { | 377 | switch (mmio) { |
| 319 | case MMIO_WRITE: | 378 | case MMIO_WRITE: |
| 320 | memcpy(&val, reg, size); | 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 | case MMIO_WRITE_IMM: | 383 | case MMIO_WRITE_IMM: |
| 323 | val = insn.immediate.value; | 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 | case MMIO_READ: | 388 | case MMIO_READ: |
| 326 | case MMIO_READ_ZERO_EXTEND: | 389 | case MMIO_READ_ZERO_EXTEND: |
| 327 | case MMIO_READ_SIGN_EXTEND: | 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 | * decoded or handled properly. It was likely not using io.h | 397 | * decoded or handled properly. It was likely not using io.h |
| 335 | * helpers or accessed MMIO accidentally. | 398 | * helpers or accessed MMIO accidentally. |
| 336 | */ | 399 | */ |
| 337 | return false; | 400 | return -EINVAL; |
| 338 | default: | 401 | default: |
| 339 | WARN_ONCE(1, "Unknown insn_decode_mmio() decode value?"); | 402 | WARN_ONCE(1, "Unknown insn_decode_mmio() decode value?"); |
| 340 | return false; | 403 | return -EINVAL; |
| 341 | } | 404 | } |
| 342 | 405 | ||
| 343 | /* Handle reads */ | 406 | /* Handle reads */ |
| 344 | if (!mmio_read(size, ve->gpa, &val)) | 407 | if (!mmio_read(size, ve->gpa, &val)) |
| 345 | return false; | 408 | return -EIO; |
| 346 | 409 | ||
| 347 | switch (mmio) { | 410 | switch (mmio) { |
| 348 | case MMIO_READ: | 411 | case MMIO_READ: |
| @@ -364,13 +427,13 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve) · 15 unmodified lines | |||
| 364 | default: | 427 | default: |
| 365 | /* All other cases has to be covered with the first switch() */ | 428 | /* All other cases has to be covered with the first switch() */ |
| 366 | WARN_ON_ONCE(1); | 429 | WARN_ON_ONCE(1); |
| 367 | return false; | 430 | return -EINVAL; |
| 368 | } | 431 | } |
| 369 | 432 | ||
| 370 | if (extend_size) | 433 | if (extend_size) |
| 371 | memset(reg, extend_val, extend_size); | 434 | memset(reg, extend_val, extend_size); |
| 372 | memcpy(reg, &val, size); | 435 | memcpy(reg, &val, size); |
| 373 | return true; | 436 | return insn.length; |
| 374 | } | 437 | } |
| 375 | 438 | ||
| 376 | static bool handle_in(struct pt_regs *regs, int size, int port) | 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 | * Return True on success or False on failure. | 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 | int size, port; | 490 | int size, port; |
| 427 | bool in; | 491 | bool in, ret; |
| 428 | 492 | ||
| 429 | if (VE_IS_IO_STRING(exit_qual)) | 493 | if (VE_IS_IO_STRING(exit_qual)) |
| 430 | return false; | 494 | return -EIO; |
| 431 | 495 | ||
| 432 | in = VE_IS_IO_IN(exit_qual); | 496 | in = VE_IS_IO_IN(exit_qual); |
| 433 | size = VE_GET_IO_SIZE(exit_qual); | 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 | if (in) | 501 | if (in) |
| 438 | return handle_in(regs, size, port); | 502 | ret = handle_in(regs, size, port); |
| 439 | else | 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 | __init bool tdx_early_handle_ve(struct pt_regs *regs) | 515 | __init bool tdx_early_handle_ve(struct pt_regs *regs) |
| 448 | { | 516 | { |
| 449 | struct ve_info ve; | 517 | struct ve_info ve; |
| 518 | int insn_len; | ||
| 450 | 519 | ||
| 451 | tdx_get_ve_info(&ve); | 520 | tdx_get_ve_info(&ve); |
| 452 | 521 | ||
| 453 | if (ve.exit_reason != EXIT_REASON_IO_INSTRUCTION) | 522 | if (ve.exit_reason != EXIT_REASON_IO_INSTRUCTION) |
| 454 | return false; | 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 | void tdx_get_ve_info(struct ve_info *ve) | 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 | ve->instr_info = upper_32_bits(out.r10); | 560 | ve->instr_info = upper_32_bits(out.r10); |
| 487 | } | 561 | } |
| 488 | 562 | ||
| 489 | /* Handle the user initiated #VE */ | 563 | /* |
| 490 | static bool virt_exception_user(struct pt_regs *regs, struct ve_info *ve) | 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 | switch (ve->exit_reason) { | 571 | switch (ve->exit_reason) { |
| 493 | case EXIT_REASON_CPUID: | 572 | case EXIT_REASON_CPUID: |
| 494 | return handle_cpuid(regs); | 573 | return handle_cpuid(regs, ve); |
| 495 | default: | 574 | default: |
| 496 | pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); | 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 */ | 580 | /* |
| 502 | static bool virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve) | 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 | switch (ve->exit_reason) { | 588 | switch (ve->exit_reason) { |
| 505 | case EXIT_REASON_HLT: | 589 | case EXIT_REASON_HLT: |
| 506 | return handle_halt(); | 590 | return handle_halt(ve); |
| 507 | case EXIT_REASON_MSR_READ: | 591 | case EXIT_REASON_MSR_READ: |
| 508 | return read_msr(regs); | 592 | return read_msr(regs, ve); |
| 509 | case EXIT_REASON_MSR_WRITE: | 593 | case EXIT_REASON_MSR_WRITE: |
| 510 | return write_msr(regs); | 594 | return write_msr(regs, ve); |
| 511 | case EXIT_REASON_CPUID: | 595 | case EXIT_REASON_CPUID: |
| 512 | return handle_cpuid(regs); | 596 | return handle_cpuid(regs, ve); |
| 513 | case EXIT_REASON_EPT_VIOLATION: | 597 | case EXIT_REASON_EPT_VIOLATION: |
| 514 | return handle_mmio(regs, ve); | 598 | return handle_mmio(regs, ve); |
| 515 | case EXIT_REASON_IO_INSTRUCTION: | 599 | case EXIT_REASON_IO_INSTRUCTION: |
| 516 | return handle_io(regs, ve->exit_qual); | 600 | return handle_io(regs, ve); |
| 517 | default: | 601 | default: |
| 518 | pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); | 602 | pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); |
| 519 | return false; | 603 | return -EIO; |
| 520 | } | 604 | } |
| 521 | } | 605 | } |
| 522 | 606 | ||
| 523 | bool tdx_handle_virt_exception(struct pt_regs *regs, struct ve_info *ve) | 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 | if (user_mode(regs)) | 611 | if (user_mode(regs)) |
| 528 | ret = virt_exception_user(regs, ve); | 612 | insn_len = virt_exception_user(regs, ve); |
| 529 | else | 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 | /* After successful #VE handling, move the IP */ | 618 | /* After successful #VE handling, move the IP */ |
| 533 | if (ret) | 619 | regs->ip += insn_len; |
| 534 | regs->ip += ve->instr_len; | ||
| 535 | 620 | ||
| 536 | return ret; | 621 | return true; |
| 537 | } | 622 | } |
| 538 | 623 | ||
| 539 | static bool tdx_tlb_flush_required(bool private) | 624 | static bool tdx_tlb_flush_required(bool private) |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
| 14 | #include <asm/apic.h> | 14 | #include <asm/apic.h> |
| 15 | #include <asm/desc.h> | 15 | #include <asm/desc.h> |
| 16 | #include <asm/sev.h> | ||
| 16 | #include <asm/hypervisor.h> | 17 | #include <asm/hypervisor.h> |
| 17 | #include <asm/hyperv-tlfs.h> | 18 | #include <asm/hyperv-tlfs.h> |
| 18 | #include <asm/mshyperv.h> | 19 | #include <asm/mshyperv.h> |
| @@ -405,6 +406,11 @@ void __init hyperv_init(void) · 386 unmodified lines | |||
| 405 | } | 406 | } |
| 406 | 407 | ||
| 407 | if (hv_isolation_type_snp()) { | 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 | hv_ghcb_pg = alloc_percpu(union hv_ghcb *); | 414 | hv_ghcb_pg = alloc_percpu(union hv_ghcb *); |
| 409 | if (!hv_ghcb_pg) | 415 | if (!hv_ghcb_pg) |
| 410 | goto free_vp_assist_page; | 416 | goto free_vp_assist_page; |
| @@ -53,6 +53,8 @@ union hv_ghcb { · 52 unmodified lines | |||
| 53 | } hypercall; | 53 | } hypercall; |
| 54 | } __packed __aligned(HV_HYP_PAGE_SIZE); | 54 | } __packed __aligned(HV_HYP_PAGE_SIZE); |
| 55 | 55 | ||
| 56 | static u16 hv_ghcb_version __ro_after_init; | ||
| 57 | |||
| 56 | u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size) | 58 | u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size) |
| 57 | { | 59 | { |
| 58 | union hv_ghcb *hv_ghcb; | 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 | return status; | 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 | void hv_ghcb_msr_write(u64 msr, u64 value) | 175 | void hv_ghcb_msr_write(u64 msr, u64 value) |
| 100 | { | 176 | { |
| 101 | union hv_ghcb *hv_ghcb; | 177 | union hv_ghcb *hv_ghcb; |
| 102 | void **ghcb_base; | 178 | void **ghcb_base; |
| 103 | unsigned long flags; | 179 | unsigned long flags; |
| 104 | struct es_em_ctxt ctxt; | ||
| 105 | 180 | ||
| 106 | if (!hv_ghcb_pg) | 181 | if (!hv_ghcb_pg) |
| 107 | return; | 182 | return; |
| @@ -120,8 +195,7 @@ void hv_ghcb_msr_write(u64 msr, u64 value) · 12 unmodified lines | |||
| 120 | ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value)); | 195 | ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value)); |
| 121 | ghcb_set_rdx(&hv_ghcb->ghcb, upper_32_bits(value)); | 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, | 198 | if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 1, 0)) |
| 124 | SVM_EXIT_MSR, 1, 0)) | ||
| 125 | pr_warn("Fail to write msr via ghcb %llx.\n", msr); | 199 | pr_warn("Fail to write msr via ghcb %llx.\n", msr); |
| 126 | 200 | ||
| 127 | local_irq_restore(flags); | 201 | local_irq_restore(flags); |
| @@ -133,7 +207,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value) · 5 unmodified lines | |||
| 133 | union hv_ghcb *hv_ghcb; | 207 | union hv_ghcb *hv_ghcb; |
| 134 | void **ghcb_base; | 208 | void **ghcb_base; |
| 135 | unsigned long flags; | 209 | unsigned long flags; |
| 136 | struct es_em_ctxt ctxt; | ||
| 137 | 210 | ||
| 138 | /* Check size of union hv_ghcb here. */ | 211 | /* Check size of union hv_ghcb here. */ |
| 139 | BUILD_BUG_ON(sizeof(union hv_ghcb) != HV_HYP_PAGE_SIZE); | 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 | ghcb_set_rcx(&hv_ghcb->ghcb, msr); | 227 | ghcb_set_rcx(&hv_ghcb->ghcb, msr); |
| 155 | if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt, | 228 | if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 0, 0)) |
| 156 | SVM_EXIT_MSR, 0, 0)) | ||
| 157 | pr_warn("Fail to read msr via ghcb %llx.\n", msr); | 229 | pr_warn("Fail to read msr via ghcb %llx.\n", msr); |
| 158 | else | 230 | else |
| 159 | *value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax) | 231 | *value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax) |
| @@ -446,5 +446,6 @@ · 445 unmodified lines | |||
| 446 | #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ | 446 | #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ |
| 447 | #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ | 447 | #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ |
| 448 | #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ | 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 | #endif /* _ASM_X86_CPUFEATURES_H */ | 451 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -4,9 +4,6 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <asm/e820/types.h> | 5 | #include <asm/e820/types.h> |
| 6 | 6 | ||
| 7 | struct device; | ||
| 8 | struct resource; | ||
| 9 | |||
| 10 | extern struct e820_table *e820_table; | 7 | extern struct e820_table *e820_table; |
| 11 | extern struct e820_table *e820_table_kexec; | 8 | extern struct e820_table *e820_table_kexec; |
| 12 | extern struct e820_table *e820_table_firmware; | 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 | extern int e820__get_entry_type(u64 start, u64 end); | 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 | * Returns true iff the specified range [start,end) is completely contained inside | 47 | * Returns true iff the specified range [start,end) is completely contained inside |
| 53 | * the ISA region. | 48 | * the ISA region. |
| @@ -323,7 +323,7 @@ static inline u32 efi64_convert_status(efi_status_t status) · 322 unmodified lines | |||
| 323 | #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ | 323 | #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ |
| 324 | (__efi64_split(phys), (desc)) | 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 | (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) | 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 | enum kvm_apicv_inhibit { | 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 | APICV_INHIBIT_REASON_DISABLE, | 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 | APICV_INHIBIT_REASON_HYPERV, | 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 | APICV_INHIBIT_REASON_NESTED, | 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 | APICV_INHIBIT_REASON_IRQWIN, | 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 | APICV_INHIBIT_REASON_PIT_REINJ, | 1111 | APICV_INHIBIT_REASON_PIT_REINJ, |
| 1112 | |||
| 1113 | /* | ||
| 1114 | * AVIC is inhibited because the guest has x2apic in its CPUID. | ||
| 1115 | */ | ||
| 1055 | APICV_INHIBIT_REASON_X2APIC, | 1116 | APICV_INHIBIT_REASON_X2APIC, |
| 1056 | APICV_INHIBIT_REASON_BLOCKIRQ, | 1117 | |
| 1057 | APICV_INHIBIT_REASON_ABSENT, | 1118 | /* |
| 1119 | * AVIC is disabled because SEV doesn't support it. | ||
| 1120 | */ | ||
| 1058 | APICV_INHIBIT_REASON_SEV, | 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 | #ifdef CONFIG_AMD_MEM_ENCRYPT | 179 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 180 | void hv_ghcb_msr_write(u64 msr, u64 value); | 180 | void hv_ghcb_msr_write(u64 msr, u64 value); |
| 181 | void hv_ghcb_msr_read(u64 msr, u64 *value); | 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 | #else | 184 | #else |
| 183 | static inline void hv_ghcb_msr_write(u64 msr, u64 value) {} | 185 | static inline void hv_ghcb_msr_write(u64 msr, u64 value) {} |
| 184 | static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {} | 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 | #endif | 189 | #endif |
| 186 | 190 | ||
| 187 | extern bool hv_isolation_type_snp(void); | 191 | extern bool hv_isolation_type_snp(void); |
| @@ -116,6 +116,30 @@ · 115 unmodified lines | |||
| 116 | * Not susceptible to | 116 | * Not susceptible to |
| 117 | * TSX Async Abort (TAA) vulnerabilities. | 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 | #define MSR_IA32_FLUSH_CMD 0x0000010b | 144 | #define MSR_IA32_FLUSH_CMD 0x0000010b |
| 121 | #define L1D_FLUSH BIT(0) /* | 145 | #define L1D_FLUSH BIT(0) /* |
| @@ -133,6 +157,7 @@ · 11 unmodified lines | |||
| 133 | #define MSR_IA32_MCU_OPT_CTRL 0x00000123 | 157 | #define MSR_IA32_MCU_OPT_CTRL 0x00000123 |
| 134 | #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ | 158 | #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ |
| 135 | #define RTM_ALLOW BIT(1) /* TSX development mode */ | 159 | #define RTM_ALLOW BIT(1) /* TSX development mode */ |
| 160 | #define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ | ||
| 136 | 161 | ||
| 137 | #define MSR_IA32_SYSENTER_CS 0x00000174 | 162 | #define MSR_IA32_SYSENTER_CS 0x00000174 |
| 138 | #define MSR_IA32_SYSENTER_ESP 0x00000175 | 163 | #define MSR_IA32_SYSENTER_ESP 0x00000175 |
| @@ -269,6 +269,8 @@ DECLARE_STATIC_KEY_FALSE(mds_idle_clear); · 268 unmodified lines | |||
| 269 | 269 | ||
| 270 | DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); | 270 | DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); |
| 271 | 271 | ||
| 272 | DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear); | ||
| 273 | |||
| 272 | #include <asm/segment.h> | 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 | /* pci-irq.c */ | 70 | /* pci-irq.c */ |
| 71 | 71 | ||
| 72 | struct pci_dev; | ||
| 73 | |||
| 72 | struct irq_info { | 74 | struct irq_info { |
| 73 | u8 bus, devfn; /* Bus, device and function */ | 75 | u8 bus, devfn; /* Bus, device and function */ |
| 74 | struct { | 76 | struct { |
| @@ -246,3 +248,9 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val) · 171 unmodified lines | |||
| 246 | # define x86_default_pci_init_irq NULL | 248 | # define x86_default_pci_init_irq NULL |
| 247 | # define x86_default_pci_fixup_irqs NULL | 249 | # define x86_default_pci_fixup_irqs NULL |
| 248 | #endif | 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 | void *extend_brk(size_t size, size_t align); | 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, | 111 | * Reserve space in the .brk section, which is a block of memory from which the |
| 112 | * and somewhat descriptive. The size is in bytes. | 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 | 116 | * The size is in bytes. |
| 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. | ||
| 117 | */ | 117 | */ |
| 118 | #define RESERVE_BRK(name, size) \ | 118 | #define RESERVE_BRK(name, size) \ |
| 119 | asm(".pushsection .brk_reservation,\"aw\",@nobits\n\t" \ | 119 | __section(".bss..brk") __aligned(1) __used \ |
| 120 | ".brk." #name ":\n\t" \ | 120 | static char __brk_##name[size] |
| 121 | ".skip " __stringify(size) "\n\t" \ | ||
| 122 | ".size .brk." #name ", " __stringify(size) "\n\t" \ | ||
| 123 | ".popsection\n\t") | ||
| 124 | 121 | ||
| 125 | extern void probe_roms(void); | 122 | extern void probe_roms(void); |
| 126 | #ifdef __i386__ | 123 | #ifdef __i386__ |
| @@ -133,12 +130,19 @@ asmlinkage void __init x86_64_start_reservations(char *real_mode_data); · 6 unmodified lines | |||
| 133 | 130 | ||
| 134 | #endif /* __i386__ */ | 131 | #endif /* __i386__ */ |
| 135 | #endif /* _SETUP */ | 132 | #endif /* _SETUP */ |
| 136 | #else | 133 | |
| 137 | #define RESERVE_BRK(name,sz) \ | 134 | #else /* __ASSEMBLY */ |
| 138 | .pushsection .brk_reservation,"aw",@nobits; \ | 135 | |
| 139 | .brk.name: \ | 136 | .macro __RESERVE_BRK name, size |
| 140 | 1: .skip sz; \ | 137 | .pushsection .bss..brk, "aw" |
| 141 | .size .brk.name,.-1b; \ | 138 | SYM_DATA_START(__brk_\name) |
| 139 | .skip \size | ||
| 140 | SYM_DATA_END(__brk_\name) | ||
| 142 | .popsection | 141 | .popsection |
| 142 | .endm | ||
| 143 | |||
| 144 | #define RESERVE_BRK(name, size) __RESERVE_BRK name, size | ||
| 145 | |||
| 143 | #endif /* __ASSEMBLY__ */ | 146 | #endif /* __ASSEMBLY__ */ |
| 147 | |||
| 144 | #endif /* _ASM_X86_SETUP_H */ | 148 | #endif /* _ASM_X86_SETUP_H */ |
| @@ -36,10 +36,6 @@ KCSAN_SANITIZE := n · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | OBJECT_FILES_NON_STANDARD_test_nx.o := y | 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 | # If instrumentation of this dir is enabled, boot hangs during first second. | 39 | # If instrumentation of this dir is enabled, boot hangs during first second. |
| 44 | # Probably could be more selective here, but note that files related to irqs, | 40 | # Probably could be more selective here, but note that files related to irqs, |
| 45 | # boot, dumpstack/stacktrace, etc are either non-interesting or can lead to | 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 | static void __init ssb_select_mitigation(void); | 41 | static void __init ssb_select_mitigation(void); |
| 42 | static void __init l1tf_select_mitigation(void); | 42 | static void __init l1tf_select_mitigation(void); |
| 43 | static void __init mds_select_mitigation(void); | 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 | static void __init taa_select_mitigation(void); | 46 | static void __init taa_select_mitigation(void); |
| 47 | static void __init mmio_select_mitigation(void); | ||
| 46 | static void __init srbds_select_mitigation(void); | 48 | static void __init srbds_select_mitigation(void); |
| 47 | static void __init l1d_flush_select_mitigation(void); | 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 | DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); | 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 | void __init check_bugs(void) | 94 | void __init check_bugs(void) |
| 89 | { | 95 | { |
| 90 | identify_boot_cpu(); | 96 | identify_boot_cpu(); |
| @@ -117,17 +123,10 @@ void __init check_bugs(void) · 26 unmodified lines | |||
| 117 | spectre_v2_select_mitigation(); | 123 | spectre_v2_select_mitigation(); |
| 118 | ssb_select_mitigation(); | 124 | ssb_select_mitigation(); |
| 119 | l1tf_select_mitigation(); | 125 | l1tf_select_mitigation(); |
| 120 | mds_select_mitigation(); | 126 | md_clear_select_mitigation(); |
| 121 | taa_select_mitigation(); | ||
| 122 | srbds_select_mitigation(); | 127 | srbds_select_mitigation(); |
| 123 | l1d_flush_select_mitigation(); | 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 | arch_smt_update(); | 130 | arch_smt_update(); |
| 132 | 131 | ||
| 133 | #ifdef CONFIG_X86_32 | 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 | static int __init mds_cmdline(char *str) | 269 | static int __init mds_cmdline(char *str) |
| 279 | { | 270 | { |
| 280 | if (!boot_cpu_has_bug(X86_BUG_MDS)) | 271 | if (!boot_cpu_has_bug(X86_BUG_MDS)) |
| @@ -329,7 +320,7 @@ static void __init taa_select_mitigation(void) · 48 unmodified lines | |||
| 329 | /* TSX previously disabled by tsx=off */ | 320 | /* TSX previously disabled by tsx=off */ |
| 330 | if (!boot_cpu_has(X86_FEATURE_RTM)) { | 321 | if (!boot_cpu_has(X86_FEATURE_RTM)) { |
| 331 | taa_mitigation = TAA_MITIGATION_TSX_DISABLED; | 322 | taa_mitigation = TAA_MITIGATION_TSX_DISABLED; |
| 332 | goto out; | 323 | return; |
| 333 | } | 324 | } |
| 334 | 325 | ||
| 335 | if (cpu_mitigations_off()) { | 326 | if (cpu_mitigations_off()) { |
| @@ -343,7 +334,7 @@ static void __init taa_select_mitigation(void) · 7 unmodified lines | |||
| 343 | */ | 334 | */ |
| 344 | if (taa_mitigation == TAA_MITIGATION_OFF && | 335 | if (taa_mitigation == TAA_MITIGATION_OFF && |
| 345 | mds_mitigation == MDS_MITIGATION_OFF) | 336 | mds_mitigation == MDS_MITIGATION_OFF) |
| 346 | goto out; | 337 | return; |
| 347 | 338 | ||
| 348 | if (boot_cpu_has(X86_FEATURE_MD_CLEAR)) | 339 | if (boot_cpu_has(X86_FEATURE_MD_CLEAR)) |
| 349 | taa_mitigation = TAA_MITIGATION_VERW; | 340 | taa_mitigation = TAA_MITIGATION_VERW; |
| @@ -375,18 +366,6 @@ static void __init taa_select_mitigation(void) · 25 unmodified lines | |||
| 375 | 366 | ||
| 376 | if (taa_nosmt || cpu_mitigations_auto_nosmt()) | 367 | if (taa_nosmt || cpu_mitigations_auto_nosmt()) |
| 377 | cpu_smt_disable(false); | 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 | static int __init tsx_async_abort_parse_cmdline(char *str) | 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 | early_param("tsx_async_abort", tsx_async_abort_parse_cmdline); | 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 | #undef pr_fmt | 537 | #undef pr_fmt |
| 414 | #define pr_fmt(fmt) "SRBDS: " fmt | 538 | #define pr_fmt(fmt) "SRBDS: " fmt |
| 415 | 539 | ||
| @@ -478,11 +602,13 @@ static void __init srbds_select_mitigation(void) · 62 unmodified lines | |||
| 478 | return; | 602 | return; |
| 479 | 603 | ||
| 480 | /* | 604 | /* |
| 481 | * Check to see if this is one of the MDS_NO systems supporting | 605 | * Check to see if this is one of the MDS_NO systems supporting TSX that |
| 482 | * TSX that are only exposed to SRBDS when TSX is enabled. | 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 | ia32_cap = x86_read_arch_cap_msr(); | 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 | srbds_mitigation = SRBDS_MITIGATION_TSX_OFF; | 612 | srbds_mitigation = SRBDS_MITIGATION_TSX_OFF; |
| 487 | else if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) | 613 | else if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
| 488 | srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR; | 614 | srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR; |
| @@ -1116,6 +1242,8 @@ static void update_indir_branch_cond(void) · 627 unmodified lines | |||
| 1116 | /* Update the static key controlling the MDS CPU buffer clear in idle */ | 1242 | /* Update the static key controlling the MDS CPU buffer clear in idle */ |
| 1117 | static void update_mds_branch_idle(void) | 1243 | static void update_mds_branch_idle(void) |
| 1118 | { | 1244 | { |
| 1245 | u64 ia32_cap = x86_read_arch_cap_msr(); | ||
| 1246 | |||
| 1119 | /* | 1247 | /* |
| 1120 | * Enable the idle clearing if SMT is active on CPUs which are | 1248 | * Enable the idle clearing if SMT is active on CPUs which are |
| 1121 | * affected only by MSBDS and not any other MDS variant. | 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 | if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY)) | 1255 | if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY)) |
| 1128 | return; | 1256 | return; |
| 1129 | 1257 | ||
| 1130 | if (sched_smt_active()) | 1258 | if (sched_smt_active()) { |
| 1131 | static_branch_enable(&mds_idle_clear); | 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 | static_branch_disable(&mds_idle_clear); | 1262 | static_branch_disable(&mds_idle_clear); |
| 1263 | } | ||
| 1134 | } | 1264 | } |
| 1135 | 1265 | ||
| 1136 | #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" | 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 | #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" | 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 | void cpu_bugs_smt_update(void) | 1270 | void cpu_bugs_smt_update(void) |
| 1140 | { | 1271 | { |
| @@ -1179,6 +1310,16 @@ void cpu_bugs_smt_update(void) · 38 unmodified lines | |||
| 1179 | break; | 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 | mutex_unlock(&spec_ctrl_mutex); | 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 | sched_smt_active() ? "vulnerable" : "disabled"); | 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 | static char *stibp_state(void) | 1939 | static char *stibp_state(void) |
| 1785 | { | 1940 | { |
| 1786 | if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) | 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 | case X86_BUG_SRBDS: | 2036 | case X86_BUG_SRBDS: |
| 1882 | return srbds_show_state(buf); | 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 | default: | 2042 | default: |
| 1885 | break; | 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 | return cpu_show_common(dev, attr, buf, X86_BUG_SRBDS); | 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 | #endif | 2098 | #endif |
| @@ -1211,18 +1211,42 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { · 1210 unmodified lines | |||
| 1211 | X86_FEATURE_ANY, issues) | 1211 | X86_FEATURE_ANY, issues) |
| 1212 | 1212 | ||
| 1213 | #define SRBDS BIT(0) | 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 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { | 1219 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { |
| 1216 | VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), | 1220 | VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), |
| 1217 | VULNBL_INTEL_STEPPINGS(HASWELL, X86_STEPPING_ANY, SRBDS), | 1221 | VULNBL_INTEL_STEPPINGS(HASWELL, X86_STEPPING_ANY, SRBDS), |
| 1218 | VULNBL_INTEL_STEPPINGS(HASWELL_L, X86_STEPPING_ANY, SRBDS), | 1222 | VULNBL_INTEL_STEPPINGS(HASWELL_L, X86_STEPPING_ANY, SRBDS), |
| 1219 | VULNBL_INTEL_STEPPINGS(HASWELL_G, X86_STEPPING_ANY, SRBDS), | 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 | VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), | 1226 | VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), |
| 1227 | VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), | ||
| 1221 | VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), | 1228 | VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), |
| 1229 | VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO), | ||
| 1222 | VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS), | 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 | VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS), | 1234 | VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS), |
| 1224 | VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0xC), SRBDS), | 1235 | VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x9, 0xC), SRBDS | MMIO), |
| 1225 | VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0xD), SRBDS), | 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 | return ia32_cap; | 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 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | 1277 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
| 1247 | { | 1278 | { |
| 1248 | u64 ia32_cap = x86_read_arch_cap_msr(); | 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 | * SRBDS affects CPUs which support RDRAND or RDSEED and are listed | 1328 | * SRBDS affects CPUs which support RDRAND or RDSEED and are listed |
| 1298 | * in the vulnerability blacklist. | 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 | if ((cpu_has(c, X86_FEATURE_RDRAND) || | 1335 | if ((cpu_has(c, X86_FEATURE_RDRAND) || |
| 1301 | cpu_has(c, X86_FEATURE_RDSEED)) && | 1336 | cpu_has(c, X86_FEATURE_RDSEED)) && |
| 1302 | cpu_matches(cpu_vuln_blacklist, SRBDS)) | 1337 | cpu_matches(cpu_vuln_blacklist, SRBDS | MMIO_SBDS)) |
| 1303 | setup_force_cpu_bug(X86_BUG_SRBDS); | 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 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) | 1351 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1306 | return; | 1352 | return; |
| 1307 | 1353 | ||
| @@ -175,6 +175,7 @@ SYM_INNER_LABEL(ftrace_caller_end, SYM_L_GLOBAL) · 174 unmodified lines | |||
| 175 | 175 | ||
| 176 | jmp ftrace_epilogue | 176 | jmp ftrace_epilogue |
| 177 | SYM_FUNC_END(ftrace_caller); | 177 | SYM_FUNC_END(ftrace_caller); |
| 178 | STACK_FRAME_NON_STANDARD_FP(ftrace_caller) | ||
| 178 | 179 | ||
| 179 | SYM_FUNC_START(ftrace_epilogue) | 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 | jmp ftrace_epilogue | 283 | jmp ftrace_epilogue |
| 283 | 284 | ||
| 284 | SYM_FUNC_END(ftrace_regs_caller) | 285 | SYM_FUNC_END(ftrace_regs_caller) |
| 286 | STACK_FRAME_NON_STANDARD_FP(ftrace_regs_caller) | ||
| 285 | 287 | ||
| 286 | 288 | ||
| 287 | #else /* ! CONFIG_DYNAMIC_FTRACE */ | 289 | #else /* ! CONFIG_DYNAMIC_FTRACE */ |
| @@ -311,10 +313,14 @@ trace: · 23 unmodified lines | |||
| 311 | jmp ftrace_stub | 313 | jmp ftrace_stub |
| 312 | SYM_FUNC_END(__fentry__) | 314 | SYM_FUNC_END(__fentry__) |
| 313 | EXPORT_SYMBOL(__fentry__) | 315 | EXPORT_SYMBOL(__fentry__) |
| 316 | STACK_FRAME_NON_STANDARD_FP(__fentry__) | ||
| 317 | |||
| 314 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 318 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 315 | 319 | ||
| 316 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 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 | subq $16, %rsp | 324 | subq $16, %rsp |
| 319 | 325 | ||
| 320 | /* Save the return values */ | 326 | /* Save the return values */ |
| @@ -339,7 +345,6 @@ SYM_FUNC_START(return_to_handler) · 18 unmodified lines | |||
| 339 | int3 | 345 | int3 |
| 340 | .Ldo_rop: | 346 | .Ldo_rop: |
| 341 | mov %rdi, (%rsp) | 347 | mov %rdi, (%rsp) |
| 342 | UNWIND_HINT_FUNC | ||
| 343 | RET | 348 | RET |
| 344 | SYM_FUNC_END(return_to_handler) | 349 | SYM_CODE_END(return_to_handler) |
| 345 | #endif | 350 | #endif |
| @@ -1,7 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/dev_printk.h> | ||
| 3 | #include <linux/ioport.h> | 2 | #include <linux/ioport.h> |
| 3 | #include <linux/printk.h> | ||
| 4 | #include <asm/e820/api.h> | 4 | #include <asm/e820/api.h> |
| 5 | #include <asm/pci_x86.h> | ||
| 5 | 6 | ||
| 6 | static void resource_clip(struct resource *res, resource_size_t start, | 7 | static void resource_clip(struct resource *res, resource_size_t start, |
| 7 | resource_size_t end) | 8 | resource_size_t end) |
| @@ -24,14 +25,14 @@ static void resource_clip(struct resource *res, resource_size_t start, · 16 unmodified lines | |||
| 24 | res->start = end + 1; | 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 | int i; | 30 | int i; |
| 30 | struct e820_entry *entry; | 31 | struct e820_entry *entry; |
| 31 | u64 e820_start, e820_end; | 32 | u64 e820_start, e820_end; |
| 32 | struct resource orig = *avail; | 33 | struct resource orig = *avail; |
| 33 | 34 | ||
| 34 | if (!(avail->flags & IORESOURCE_MEM)) | 35 | if (!pci_use_e820) |
| 35 | return; | 36 | return; |
| 36 | 37 | ||
| 37 | for (i = 0; i < e820_table->nr_entries; i++) { | 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 | resource_clip(avail, e820_start, e820_end); | 43 | resource_clip(avail, e820_start, e820_end); |
| 43 | if (orig.start != avail->start || orig.end != avail->end) { | 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 | &orig, avail, e820_start, e820_end); | 46 | &orig, avail, e820_start, e820_end); |
| 46 | orig = *avail; | 47 | orig = *avail; |
| 47 | } | 48 | } |
| @@ -55,6 +56,9 @@ void arch_remove_reservations(struct resource *avail) · 7 unmodified lines | |||
| 55 | * the low 1MB unconditionally, as this area is needed for some ISA | 56 | * the low 1MB unconditionally, as this area is needed for some ISA |
| 56 | * cards requiring a memory range, e.g. the i82365 PCMCIA controller. | 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 | resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); | 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 | #endif | 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 | unsigned long _brk_start = (unsigned long)__brk_base; | 70 | unsigned long _brk_start = (unsigned long)__brk_base; |
| 76 | unsigned long _brk_end = (unsigned long)__brk_base; | 71 | unsigned long _brk_end = (unsigned long)__brk_base; |
| 77 | 72 | ||
| @@ -385,10 +385,10 @@ SECTIONS · 384 unmodified lines | |||
| 385 | __end_of_kernel_reserve = .; | 385 | __end_of_kernel_reserve = .; |
| 386 | 386 | ||
| 387 | . = ALIGN(PAGE_SIZE); | 387 | . = ALIGN(PAGE_SIZE); |
| 388 | .brk : AT(ADDR(.brk) - LOAD_OFFSET) { | 388 | .brk (NOLOAD) : AT(ADDR(.brk) - LOAD_OFFSET) { |
| 389 | __brk_base = .; | 389 | __brk_base = .; |
| 390 | . += 64 * 1024; /* 64k alignment slop space */ | 390 | . += 64 * 1024; /* 64k alignment slop space */ |
| 391 | *(.brk_reservation) /* areas brk users have reserved */ | 391 | *(.bss..brk) /* areas brk users have reserved */ |
| 392 | __brk_limit = .; | 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 | static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | 2055 | static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) |
| 2043 | { | 2056 | { |
| 2044 | int ret = 0; | 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 | switch (reg) { | 2061 | switch (reg) { |
| 2049 | case APIC_ID: /* Local APIC ID */ | 2062 | case APIC_ID: /* Local APIC ID */ |
| 2050 | if (!apic_x2apic_mode(apic)) | 2063 | if (!apic_x2apic_mode(apic)) { |
| 2051 | kvm_apic_set_xapic_id(apic, val >> 24); | 2064 | kvm_apic_set_xapic_id(apic, val >> 24); |
| 2052 | else | 2065 | kvm_lapic_xapic_id_updated(apic); |
| 2066 | } else { | ||
| 2053 | ret = 1; | 2067 | ret = 1; |
| 2068 | } | ||
| 2054 | break; | 2069 | break; |
| 2055 | 2070 | ||
| 2056 | case APIC_TASKPRI: | 2071 | case APIC_TASKPRI: |
| @@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) · 279 unmodified lines | |||
| 2336 | MSR_IA32_APICBASE_BASE; | 2351 | MSR_IA32_APICBASE_BASE; |
| 2337 | 2352 | ||
| 2338 | if ((value & MSR_IA32_APICBASE_ENABLE) && | 2353 | if ((value & MSR_IA32_APICBASE_ENABLE) && |
| 2339 | apic->base_address != APIC_DEFAULT_PHYS_BASE) | 2354 | apic->base_address != APIC_DEFAULT_PHYS_BASE) { |
| 2340 | pr_warn_once("APIC base relocation is unsupported by KVM"); | 2355 | kvm_set_apicv_inhibit(apic->vcpu->kvm, |
| 2356 | APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); | ||
| 2357 | } | ||
| 2341 | } | 2358 | } |
| 2342 | 2359 | ||
| 2343 | void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) | 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 | icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); | 2665 | icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); |
| 2649 | __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32); | 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 | return 0; | 2672 | return 0; |
| @@ -3411,7 +3411,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) · 3410 unmodified lines | |||
| 3411 | root = mmu_alloc_root(vcpu, i << (30 - PAGE_SHIFT), | 3411 | root = mmu_alloc_root(vcpu, i << (30 - PAGE_SHIFT), |
| 3412 | i << 30, PT32_ROOT_LEVEL, true); | 3412 | i << 30, PT32_ROOT_LEVEL, true); |
| 3413 | mmu->pae_root[i] = root | PT_PRESENT_MASK | | 3413 | mmu->pae_root[i] = root | PT_PRESENT_MASK | |
| 3414 | shadow_me_mask; | 3414 | shadow_me_value; |
| 3415 | } | 3415 | } |
| 3416 | mmu->root.hpa = __pa(mmu->pae_root); | 3416 | mmu->root.hpa = __pa(mmu->pae_root); |
| 3417 | } else { | 3417 | } else { |
| @@ -291,58 +291,91 @@ void avic_ring_doorbell(struct kvm_vcpu *vcpu) · 290 unmodified lines | |||
| 291 | static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source, | 291 | static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source, |
| 292 | u32 icrl, u32 icrh, u32 index) | 292 | u32 icrl, u32 icrh, u32 index) |
| 293 | { | 293 | { |
| 294 | u32 dest, apic_id; | 294 | u32 l1_physical_id, dest; |
| 295 | struct kvm_vcpu *vcpu; | 295 | struct kvm_vcpu *target_vcpu; |
| 296 | int dest_mode = icrl & APIC_DEST_MASK; | 296 | int dest_mode = icrl & APIC_DEST_MASK; |
| 297 | int shorthand = icrl & APIC_SHORT_MASK; | 297 | int shorthand = icrl & APIC_SHORT_MASK; |
| 298 | struct kvm_svm *kvm_svm = to_kvm_svm(kvm); | 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 | if (shorthand != APIC_DEST_NOSHORT) | 300 | if (shorthand != APIC_DEST_NOSHORT) |
| 302 | return -EINVAL; | 301 | return -EINVAL; |
| 303 | 302 | ||
| 304 | /* | 303 | if (apic_x2apic_mode(source)) |
| 305 | * The AVIC incomplete IPI #vmexit info provides index into | 304 | dest = icrh; |
| 306 | * the physical APIC ID table, which can be used to derive | 305 | else |
| 307 | * guest physical APIC ID. | 306 | dest = GET_APIC_DEST_FIELD(icrh); |
| 308 | */ | 307 | |
| 309 | if (dest_mode == APIC_DEST_PHYSICAL) { | 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 | } else { | 320 | } else { |
| 312 | if (!apic_x2apic_mode(source)) { | 321 | u32 bitmap, cluster; |
| 313 | /* For xAPIC logical mode, the index is for logical APIC table. */ | 322 | int logid_index; |
| 314 | apic_id = avic_logical_id_table[index] & 0x1ff; | 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 | } else { | 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 | /* | 338 | if (unlikely(!bitmap)) |
| 321 | * Assuming vcpu ID is the same as physical apic ID, | 339 | /* guest bug: nobody to send the logical interrupt to */ |
| 322 | * and use it to retrieve the target vCPU. | 340 | return 0; |
| 323 | */ | ||
| 324 | vcpu = kvm_get_vcpu_by_id(kvm, apic_id); | ||
| 325 | if (!vcpu) | ||
| 326 | return -EINVAL; | ||
| 327 | 341 | ||
| 328 | if (apic_x2apic_mode(vcpu->arch.apic)) | 342 | if (!is_power_of_2(bitmap)) |
| 329 | dest = icrh; | 343 | /* multiple logical destinations, use slow path */ |
| 330 | else | 344 | return -EINVAL; |
| 331 | dest = GET_APIC_DEST_FIELD(icrh); | ||
| 332 | 345 | ||
| 333 | /* | 346 | logid_index = cluster + __ffs(bitmap); |
| 334 | * Try matching the destination APIC ID with the vCPU. | 347 | |
| 335 | */ | 348 | if (apic_x2apic_mode(source)) { |
| 336 | if (kvm_apic_match_dest(vcpu, source, shorthand, dest, dest_mode)) { | 349 | l1_physical_id = logid_index; |
| 337 | vcpu->arch.apic->irr_pending = true; | 350 | } else { |
| 338 | svm_complete_interrupt_delivery(vcpu, | 351 | u32 *avic_logical_id_table = |
| 339 | icrl & APIC_MODE_MASK, | 352 | page_address(kvm_svm->avic_logical_id_table_page); |
| 340 | icrl & APIC_INT_LEVELTRIG, | 353 | |
| 341 | icrl & APIC_VECTOR_MASK); | 354 | u32 logid_entry = avic_logical_id_table[logid_index]; |
| 342 | return 0; | 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 | static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source, | 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 | return ret; | 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 | static void avic_handle_dfr_update(struct kvm_vcpu *vcpu) | 544 | static void avic_handle_dfr_update(struct kvm_vcpu *vcpu) |
| 541 | { | 545 | { |
| 542 | struct vcpu_svm *svm = to_svm(vcpu); | 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 | AVIC_UNACCEL_ACCESS_OFFSET_MASK; | 559 | AVIC_UNACCEL_ACCESS_OFFSET_MASK; |
| 556 | 560 | ||
| 557 | switch (offset) { | 561 | switch (offset) { |
| 558 | case APIC_ID: | ||
| 559 | if (avic_handle_apic_id_update(vcpu)) | ||
| 560 | return 0; | ||
| 561 | break; | ||
| 562 | case APIC_LDR: | 562 | case APIC_LDR: |
| 563 | if (avic_handle_ldr_update(vcpu)) | 563 | if (avic_handle_ldr_update(vcpu)) |
| 564 | return 0; | 564 | return 0; |
| @@ -650,8 +650,6 @@ int avic_init_vcpu(struct vcpu_svm *svm) · 85 unmodified lines | |||
| 650 | 650 | ||
| 651 | void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu) | 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 | avic_handle_dfr_update(vcpu); | 653 | avic_handle_dfr_update(vcpu); |
| 656 | avic_handle_ldr_update(vcpu); | 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 | BIT(APICV_INHIBIT_REASON_PIT_REINJ) | | 908 | BIT(APICV_INHIBIT_REASON_PIT_REINJ) | |
| 911 | BIT(APICV_INHIBIT_REASON_X2APIC) | | 909 | BIT(APICV_INHIBIT_REASON_X2APIC) | |
| 912 | BIT(APICV_INHIBIT_REASON_BLOCKIRQ) | | 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 | return supported & BIT(reason); | 915 | return supported & BIT(reason); |
| 916 | } | 916 | } |
| @@ -946,7 +946,7 @@ out: · 29 unmodified lines | |||
| 946 | return ret; | 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 | u64 entry; | 951 | u64 entry; |
| 952 | int h_physical_id = kvm_cpu_get_apicid(cpu); | 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 | avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true); | 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 | u64 entry; | 983 | u64 entry; |
| 984 | struct vcpu_svm *svm = to_svm(vcpu); | 984 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -997,25 +997,6 @@ void __avic_vcpu_put(struct kvm_vcpu *vcpu) · 12 unmodified lines | |||
| 997 | WRITE_ONCE(*(svm->avic_physical_id_cache), entry); | 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 | void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) | 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 | vmcb_mark_dirty(vmcb, VMCB_AVIC); | 1023 | vmcb_mark_dirty(vmcb, VMCB_AVIC); |
| 1043 | 1024 | ||
| 1044 | if (activated) | 1025 | if (activated) |
| 1045 | avic_vcpu_load(vcpu); | 1026 | avic_vcpu_load(vcpu, vcpu->cpu); |
| 1046 | else | 1027 | else |
| 1047 | avic_vcpu_put(vcpu); | 1028 | avic_vcpu_put(vcpu); |
| 1048 | 1029 | ||
| @@ -1075,5 +1056,5 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu) · 26 unmodified lines | |||
| 1075 | if (!kvm_vcpu_apicv_active(vcpu)) | 1056 | if (!kvm_vcpu_apicv_active(vcpu)) |
| 1076 | return; | 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 | struct kvm_vcpu *vcpu = &svm->vcpu; | 616 | struct kvm_vcpu *vcpu = &svm->vcpu; |
| 617 | struct vmcb *vmcb01 = svm->vmcb01.ptr; | 617 | struct vmcb *vmcb01 = svm->vmcb01.ptr; |
| 618 | struct vmcb *vmcb02 = svm->nested.vmcb02.ptr; | 618 | struct vmcb *vmcb02 = svm->nested.vmcb02.ptr; |
| 619 | u32 pause_count12; | ||
| 620 | u32 pause_thresh12; | ||
| 619 | 621 | ||
| 620 | /* | 622 | /* |
| 621 | * Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2, | 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 | if (!nested_vmcb_needs_vls_intercept(svm)) | 673 | if (!nested_vmcb_needs_vls_intercept(svm)) |
| 672 | vmcb02->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK; | 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 | if (kvm_pause_in_guest(svm->vcpu.kvm)) { | 678 | if (kvm_pause_in_guest(svm->vcpu.kvm)) { |
| 675 | /* use guest values since host doesn't use them */ | 679 | /* use guest values since host doesn't intercept PAUSE */ |
| 676 | vmcb02->control.pause_filter_count = | 680 | vmcb02->control.pause_filter_count = pause_count12; |
| 677 | svm->pause_filter_enabled ? | 681 | vmcb02->control.pause_filter_thresh = pause_thresh12; |
| 678 | svm->nested.ctl.pause_filter_count : 0; | ||
| 679 | 682 | ||
| 680 | vmcb02->control.pause_filter_thresh = | 683 | } else { |
| 681 | svm->pause_threshold_enabled ? | 684 | /* start from host values otherwise */ |
| 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 */ | ||
| 686 | vmcb02->control.pause_filter_count = vmcb01->control.pause_filter_count; | 685 | vmcb02->control.pause_filter_count = vmcb01->control.pause_filter_count; |
| 687 | vmcb02->control.pause_filter_thresh = vmcb01->control.pause_filter_thresh; | 686 | vmcb02->control.pause_filter_thresh = vmcb01->control.pause_filter_thresh; |
| 688 | } else { | 687 | |
| 689 | /* | 688 | /* ... but ensure filtering is disabled if so requested. */ |
| 690 | * Intercept every PAUSE otherwise and | 689 | if (vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_PAUSE)) { |
| 691 | * ignore both host and guest values | 690 | if (!pause_count12) |
| 692 | */ | 691 | vmcb02->control.pause_filter_count = 0; |
| 693 | vmcb02->control.pause_filter_count = 0; | 692 | if (!pause_thresh12) |
| 694 | vmcb02->control.pause_filter_thresh = 0; | 693 | vmcb02->control.pause_filter_thresh = 0; |
| 694 | } | ||
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | nested_svm_transition_tlb_flush(vcpu); | 697 | nested_svm_transition_tlb_flush(vcpu); |
| @@ -951,8 +951,11 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 253 unmodified lines | |||
| 951 | vmcb12->control.event_inj = svm->nested.ctl.event_inj; | 951 | vmcb12->control.event_inj = svm->nested.ctl.event_inj; |
| 952 | vmcb12->control.event_inj_err = svm->nested.ctl.event_inj_err; | 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 | vmcb01->control.pause_filter_count = vmcb02->control.pause_filter_count; | 955 | vmcb01->control.pause_filter_count = vmcb02->control.pause_filter_count; |
| 956 | vmcb_mark_dirty(vmcb01, VMCB_INTERCEPTS); | ||
| 957 | |||
| 958 | } | ||
| 956 | 959 | ||
| 957 | nested_svm_copy_common_state(svm->nested.vmcb02.ptr, svm->vmcb01.ptr); | 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 | /* If source buffer is not aligned then use an intermediate buffer */ | 845 | /* If source buffer is not aligned then use an intermediate buffer */ |
| 846 | if (!IS_ALIGNED((unsigned long)vaddr, 16)) { | 846 | if (!IS_ALIGNED((unsigned long)vaddr, 16)) { |
| 847 | src_tpage = alloc_page(GFP_KERNEL); | 847 | src_tpage = alloc_page(GFP_KERNEL_ACCOUNT); |
| 848 | if (!src_tpage) | 848 | if (!src_tpage) |
| 849 | return -ENOMEM; | 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 | if (!IS_ALIGNED((unsigned long)dst_vaddr, 16) || !IS_ALIGNED(size, 16)) { | 865 | if (!IS_ALIGNED((unsigned long)dst_vaddr, 16) || !IS_ALIGNED(size, 16)) { |
| 866 | int dst_offset; | 866 | int dst_offset; |
| 867 | 867 | ||
| 868 | dst_tpage = alloc_page(GFP_KERNEL); | 868 | dst_tpage = alloc_page(GFP_KERNEL_ACCOUNT); |
| 869 | if (!dst_tpage) { | 869 | if (!dst_tpage) { |
| 870 | ret = -ENOMEM; | 870 | ret = -ENOMEM; |
| 871 | goto e_free; | 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 | struct kvm_sev_info *dst = &to_kvm_svm(dst_kvm)->sev_info; | 1666 | struct kvm_sev_info *dst = &to_kvm_svm(dst_kvm)->sev_info; |
| 1667 | struct kvm_sev_info *src = &to_kvm_svm(src_kvm)->sev_info; | 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 | struct kvm_sev_info *mirror; | 1670 | struct kvm_sev_info *mirror; |
| 1671 | unsigned long i; | ||
| 1669 | 1672 | ||
| 1670 | dst->active = true; | 1673 | dst->active = true; |
| 1671 | dst->asid = src->asid; | 1674 | dst->asid = src->asid; |
| 1672 | dst->handle = src->handle; | 1675 | dst->handle = src->handle; |
| 1673 | dst->pages_locked = src->pages_locked; | 1676 | dst->pages_locked = src->pages_locked; |
| 1674 | dst->enc_context_owner = src->enc_context_owner; | 1677 | dst->enc_context_owner = src->enc_context_owner; |
| 1678 | dst->es_active = src->es_active; | ||
| 1675 | 1679 | ||
| 1676 | src->asid = 0; | 1680 | src->asid = 0; |
| 1677 | src->active = false; | 1681 | src->active = false; |
| 1678 | src->handle = 0; | 1682 | src->handle = 0; |
| 1679 | src->pages_locked = 0; | 1683 | src->pages_locked = 0; |
| 1680 | src->enc_context_owner = NULL; | 1684 | src->enc_context_owner = NULL; |
| 1685 | src->es_active = false; | ||
| 1681 | 1686 | ||
| 1682 | list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list); | 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 | list_del(&src->mirror_entry); | 1709 | list_del(&src->mirror_entry); |
| 1705 | list_add_tail(&dst->mirror_entry, &owner_sev_info->mirror_vms); | 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) | 1713 | kvm_for_each_vcpu(i, dst_vcpu, dst_kvm) { |
| 1710 | { | 1714 | dst_svm = to_svm(dst_vcpu); |
| 1711 | unsigned long i; | ||
| 1712 | struct kvm_vcpu *dst_vcpu, *src_vcpu; | ||
| 1713 | struct vcpu_svm *dst_svm, *src_svm; | ||
| 1714 | 1715 | ||
| 1715 | if (atomic_read(&src->online_vcpus) != atomic_read(&dst->online_vcpus)) | 1716 | sev_init_vmcb(dst_svm); |
| 1716 | return -EINVAL; | ||
| 1717 | 1717 | ||
| 1718 | kvm_for_each_vcpu(i, src_vcpu, src) { | 1718 | if (!dst->es_active) |
| 1719 | if (!src_vcpu->arch.guest_state_protected) | 1719 | continue; |
| 1720 | return -EINVAL; | ||
| 1721 | } | ||
| 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 | src_svm = to_svm(src_vcpu); | 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 | * Transfer VMSA and GHCB state to the destination. Nullify and | 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 | src_svm->vmcb->control.vmsa_pa = INVALID_PAGE; | 1740 | src_svm->vmcb->control.vmsa_pa = INVALID_PAGE; |
| 1741 | src_vcpu->arch.guest_state_protected = false; | 1741 | src_vcpu->arch.guest_state_protected = false; |
| 1742 | } | 1742 | } |
| 1743 | to_kvm_svm(src)->sev_info.es_active = false; | 1743 | } |
| 1744 | to_kvm_svm(dst)->sev_info.es_active = true; | 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 | return 0; | 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 | if (ret) | 1804 | if (ret) |
| 1790 | goto out_dst_vcpu; | 1805 | goto out_dst_vcpu; |
| 1791 | 1806 | ||
| 1792 | if (sev_es_guest(source_kvm)) { | 1807 | ret = sev_check_source_vcpus(kvm, source_kvm); |
| 1793 | ret = sev_es_migrate_from(kvm, source_kvm); | 1808 | if (ret) |
| 1794 | if (ret) | 1809 | goto out_source_vcpu; |
| 1795 | goto out_source_vcpu; | ||
| 1796 | } | ||
| 1797 | 1810 | ||
| 1798 | sev_migrate_from(kvm, source_kvm); | 1811 | sev_migrate_from(kvm, source_kvm); |
| 1799 | kvm_vm_dead(source_kvm); | 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 | count, in); | 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 | struct kvm_vcpu *vcpu = &svm->vcpu; | 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 | void sev_es_vcpu_reset(struct vcpu_svm *svm) | 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 | struct vmcb_control_area *control = &svm->vmcb->control; | 921 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 922 | int old = control->pause_filter_count; | 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 | return; | 925 | return; |
| 926 | 926 | ||
| 927 | control->pause_filter_count = __grow_ple_window(old, | 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 | struct vmcb_control_area *control = &svm->vmcb->control; | 942 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 943 | int old = control->pause_filter_count; | 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 | return; | 946 | return; |
| 947 | 947 | ||
| 948 | control->pause_filter_count = | 948 | control->pause_filter_count = |
| @@ -1212,15 +1212,8 @@ static void init_vmcb(struct kvm_vcpu *vcpu) · 263 unmodified lines | |||
| 1212 | svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK; | 1212 | svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK; |
| 1213 | } | 1213 | } |
| 1214 | 1214 | ||
| 1215 | if (sev_guest(vcpu->kvm)) { | 1215 | if (sev_guest(vcpu->kvm)) |
| 1216 | svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; | 1216 | sev_init_vmcb(svm); |
| 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 | } | ||
| 1224 | 1217 | ||
| 1225 | svm_hv_init_vmcb(vmcb); | 1218 | svm_hv_init_vmcb(vmcb); |
| 1226 | init_vmcb_after_set_cpuid(vcpu); | 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 | indirect_branch_prediction_barrier(); | 1393 | indirect_branch_prediction_barrier(); |
| 1401 | } | 1394 | } |
| 1402 | if (kvm_vcpu_apicv_active(vcpu)) | 1395 | if (kvm_vcpu_apicv_active(vcpu)) |
| 1403 | __avic_vcpu_load(vcpu, cpu); | 1396 | avic_vcpu_load(vcpu, cpu); |
| 1404 | } | 1397 | } |
| 1405 | 1398 | ||
| 1406 | static void svm_vcpu_put(struct kvm_vcpu *vcpu) | 1399 | static void svm_vcpu_put(struct kvm_vcpu *vcpu) |
| 1407 | { | 1400 | { |
| 1408 | if (kvm_vcpu_apicv_active(vcpu)) | 1401 | if (kvm_vcpu_apicv_active(vcpu)) |
| 1409 | __avic_vcpu_put(vcpu); | 1402 | avic_vcpu_put(vcpu); |
| 1410 | 1403 | ||
| 1411 | svm_prepare_host_switch(vcpu); | 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 | int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu); | 610 | int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu); |
| 611 | int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu); | 611 | int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu); |
| 612 | int avic_init_vcpu(struct vcpu_svm *svm); | 612 | int avic_init_vcpu(struct vcpu_svm *svm); |
| 613 | void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu); | 613 | void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu); |
| 614 | void __avic_vcpu_put(struct kvm_vcpu *vcpu); | 614 | void avic_vcpu_put(struct kvm_vcpu *vcpu); |
| 615 | void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu); | 615 | void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu); |
| 616 | void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu); | 616 | void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu); |
| 617 | void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu); | 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 | void __init sev_hardware_setup(void); | 649 | void __init sev_hardware_setup(void); |
| 650 | void sev_hardware_unsetup(void); | 650 | void sev_hardware_unsetup(void); |
| 651 | int sev_cpu_init(struct svm_cpu_data *sd); | 651 | int sev_cpu_init(struct svm_cpu_data *sd); |
| 652 | void sev_init_vmcb(struct vcpu_svm *svm); | ||
| 652 | void sev_free_vcpu(struct kvm_vcpu *vcpu); | 653 | void sev_free_vcpu(struct kvm_vcpu *vcpu); |
| 653 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); | 654 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); |
| 654 | int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); | 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 | void sev_es_vcpu_reset(struct vcpu_svm *svm); | 656 | void sev_es_vcpu_reset(struct vcpu_svm *svm); |
| 657 | void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); | 657 | void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); |
| 658 | void sev_es_prepare_switch_to_guest(struct sev_es_save_area *hostsa); | 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 | #define L1D_CACHE_ORDER 4 | 229 | #define L1D_CACHE_ORDER 4 |
| 230 | static void *vmx_l1d_flush_pages; | 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 | static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) | 235 | static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) |
| 233 | { | 236 | { |
| 234 | struct page *page; | 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 | return sprintf(s, "%s\n", vmentry_l1d_param[l1tf_vmx_mitigation].option); | 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 | static const struct kernel_param_ops vmentry_l1d_flush_ops = { | 420 | static const struct kernel_param_ops vmentry_l1d_flush_ops = { |
| 364 | .set = vmentry_l1d_flush_set, | 421 | .set = vmentry_l1d_flush_set, |
| 365 | .get = vmentry_l1d_flush_get, | 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 | ret = kvm_set_msr_common(vcpu, msr_info); | 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 | return ret; | 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 | kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); | 4614 | kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); |
| 4554 | 4615 | ||
| 4555 | vpid_sync_context(vmx->vpid); | 4616 | vpid_sync_context(vmx->vpid); |
| 4617 | |||
| 4618 | vmx_update_fb_clear_dis(vcpu, vmx); | ||
| 4556 | } | 4619 | } |
| 4557 | 4620 | ||
| 4558 | static void vmx_enable_irq_window(struct kvm_vcpu *vcpu) | 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 | vmx_l1d_flush(vcpu); | 6835 | vmx_l1d_flush(vcpu); |
| 6773 | else if (static_branch_unlikely(&mds_user_clear)) | 6836 | else if (static_branch_unlikely(&mds_user_clear)) |
| 6774 | mds_clear_cpu_buffers(); | 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 | if (vcpu->arch.cr2 != native_read_cr2()) | 6844 | if (vcpu->arch.cr2 != native_read_cr2()) |
| 6777 | native_write_cr2(vcpu->arch.cr2); | 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 | vcpu->arch.cr2 = native_read_cr2(); | 6850 | vcpu->arch.cr2 = native_read_cr2(); |
| 6783 | 6851 | ||
| 6852 | vmx_enable_fb_clear(vmx); | ||
| 6853 | |||
| 6784 | guest_state_exit_irqoff(); | 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 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | | 7779 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | |
| 7710 | BIT(APICV_INHIBIT_REASON_ABSENT) | | 7780 | BIT(APICV_INHIBIT_REASON_ABSENT) | |
| 7711 | BIT(APICV_INHIBIT_REASON_HYPERV) | | 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 | return supported & BIT(reason); | 7786 | return supported & BIT(reason); |
| 7715 | } | 7787 | } |
| @@ -8212,6 +8284,8 @@ static int __init vmx_init(void) · 496 unmodified lines | |||
| 8212 | return r; | 8284 | return r; |
| 8213 | } | 8285 | } |
| 8214 | 8286 | ||
| 8287 | vmx_setup_fb_clear_ctrl(); | ||
| 8288 | |||
| 8215 | for_each_possible_cpu(cpu) { | 8289 | for_each_possible_cpu(cpu) { |
| 8216 | INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); | 8290 | INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); |
| 8217 | 8291 | ||
| @@ -348,6 +348,8 @@ struct vcpu_vmx { · 347 unmodified lines | |||
| 348 | u64 msr_ia32_feature_control_valid_bits; | 348 | u64 msr_ia32_feature_control_valid_bits; |
| 349 | /* SGX Launch Control public key hash */ | 349 | /* SGX Launch Control public key hash */ |
| 350 | u64 msr_ia32_sgxlepubkeyhash[4]; | 350 | u64 msr_ia32_sgxlepubkeyhash[4]; |
| 351 | u64 msr_ia32_mcu_opt_ctrl; | ||
| 352 | bool disable_fb_clear; | ||
| 351 | 353 | ||
| 352 | struct pt_desc pt_desc; | 354 | struct pt_desc pt_desc; |
| 353 | struct lbr_desc lbr_desc; | 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 | return data; | 1623 | return data; |
| 1621 | } | 1624 | } |
| 1622 | 1625 | ||
| @@ -9850,6 +9853,7 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu) · 8227 unmodified lines | |||
| 9850 | return; | 9853 | return; |
| 9851 | 9854 | ||
| 9852 | down_read(&vcpu->kvm->arch.apicv_update_lock); | 9855 | down_read(&vcpu->kvm->arch.apicv_update_lock); |
| 9856 | preempt_disable(); | ||
| 9853 | 9857 | ||
| 9854 | activate = kvm_vcpu_apicv_activated(vcpu); | 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 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 9874 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
| 9871 | 9875 | ||
| 9872 | out: | 9876 | out: |
| 9877 | preempt_enable(); | ||
| 9873 | up_read(&vcpu->kvm->arch.apicv_update_lock); | 9878 | up_read(&vcpu->kvm->arch.apicv_update_lock); |
| 9874 | } | 9879 | } |
| 9875 | EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv); | 9880 | EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv); |
| @@ -1420,8 +1420,9 @@ st: if (is_imm8(insn->off)) · 1419 unmodified lines | |||
| 1420 | case BPF_JMP | BPF_CALL: | 1420 | case BPF_JMP | BPF_CALL: |
| 1421 | func = (u8 *) __bpf_call_base + imm32; | 1421 | func = (u8 *) __bpf_call_base + imm32; |
| 1422 | if (tail_call_reachable) { | 1422 | if (tail_call_reachable) { |
| 1423 | /* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */ | ||
| 1423 | EMIT3_off32(0x48, 0x8B, 0x85, | 1424 | EMIT3_off32(0x48, 0x8B, 0x85, |
| 1424 | -(bpf_prog->aux->stack_depth + 8)); | 1425 | -round_up(bpf_prog->aux->stack_depth, 8) - 8); |
| 1425 | if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7)) | 1426 | if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7)) |
| 1426 | return -EINVAL; | 1427 | return -EINVAL; |
| 1427 | } else { | 1428 | } else { |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <linux/pci-acpi.h> | 8 | #include <linux/pci-acpi.h> |
| 9 | #include <asm/numa.h> | 9 | #include <asm/numa.h> |
| 10 | #include <asm/pci_x86.h> | 10 | #include <asm/pci_x86.h> |
| 11 | #include <asm/e820/api.h> | ||
| 12 | 11 | ||
| 13 | struct pci_root_info { | 12 | struct pci_root_info { |
| 14 | struct acpi_pci_root_info common; | 13 | struct acpi_pci_root_info common; |
| @@ -20,7 +19,7 @@ struct pci_root_info { · 5 unmodified lines | |||
| 20 | #endif | 19 | #endif |
| 21 | }; | 20 | }; |
| 22 | 21 | ||
| 23 | static bool pci_use_e820 = true; | 22 | bool pci_use_e820 = true; |
| 24 | static bool pci_use_crs = true; | 23 | static bool pci_use_crs = true; |
| 25 | static bool pci_ignore_seg; | 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 | status = acpi_pci_probe_root_resources(ci); | 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 | if (pci_use_crs) { | 389 | if (pci_use_crs) { |
| 396 | resource_list_for_each_entry_safe(entry, tmp, &ci->resources) | 390 | resource_list_for_each_entry_safe(entry, tmp, &ci->resources) |
| 397 | if (resource_is_pcicfg_ioport(entry->res)) | 391 | if (resource_is_pcicfg_ioport(entry->res)) |
| @@ -2173,7 +2173,7 @@ ENDPROC(ret_from_kernel_thread) · 2172 unmodified lines | |||
| 2173 | 2173 | ||
| 2174 | #ifdef CONFIG_HIBERNATION | 2174 | #ifdef CONFIG_HIBERNATION |
| 2175 | 2175 | ||
| 2176 | .bss | 2176 | .section .bss, "aw" |
| 2177 | .align 4 | 2177 | .align 4 |
| 2178 | .Lsaved_regs: | 2178 | .Lsaved_regs: |
| 2179 | #if defined(__XTENSA_WINDOWED_ABI__) | 2179 | #if defined(__XTENSA_WINDOWED_ABI__) |
| @@ -154,6 +154,7 @@ static void __init calibrate_ccount(void) · 153 unmodified lines | |||
| 154 | cpu = of_find_compatible_node(NULL, NULL, "cdns,xtensa-cpu"); | 154 | cpu = of_find_compatible_node(NULL, NULL, "cdns,xtensa-cpu"); |
| 155 | if (cpu) { | 155 | if (cpu) { |
| 156 | clk = of_clk_get(cpu, 0); | 156 | clk = of_clk_get(cpu, 0); |
| 157 | of_node_put(cpu); | ||
| 157 | if (!IS_ERR(clk)) { | 158 | if (!IS_ERR(clk)) { |
| 158 | ccount_freq = clk_get_rate(clk); | 159 | ccount_freq = clk_get_rate(clk); |
| 159 | return; | 160 | return; |
| @@ -133,6 +133,7 @@ static int __init machine_setup(void) · 132 unmodified lines | |||
| 133 | 133 | ||
| 134 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) | 134 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) |
| 135 | update_local_mac(eth); | 135 | update_local_mac(eth); |
| 136 | of_node_put(eth); | ||
| 136 | return 0; | 137 | return 0; |
| 137 | } | 138 | } |
| 138 | arch_initcall(machine_setup); | 139 | arch_initcall(machine_setup); |
| @@ -7046,6 +7046,7 @@ static void bfq_exit_queue(struct elevator_queue *e) · 7045 unmodified lines | |||
| 7046 | spin_unlock_irq(&bfqd->lock); | 7046 | spin_unlock_irq(&bfqd->lock); |
| 7047 | #endif | 7047 | #endif |
| 7048 | 7048 | ||
| 7049 | blk_stat_disable_accounting(bfqd->queue); | ||
| 7049 | wbt_enable_default(bfqd->queue); | 7050 | wbt_enable_default(bfqd->queue); |
| 7050 | 7051 | ||
| 7051 | kfree(bfqd); | 7052 | kfree(bfqd); |
| @@ -7188,7 +7189,12 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) · 136 unmodified lines | |||
| 7188 | bfq_init_root_group(bfqd->root_group, bfqd); | 7189 | bfq_init_root_group(bfqd->root_group, bfqd); |
| 7189 | bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); | 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 | wbt_disable_default(q); | 7195 | wbt_disable_default(q); |
| 7196 | blk_stat_enable_accounting(q); | ||
| 7197 | |||
| 7192 | return 0; | 7198 | return 0; |
| 7193 | 7199 | ||
| 7194 | out_free: | 7200 | out_free: |
| @@ -322,19 +322,6 @@ void blk_cleanup_queue(struct request_queue *q) · 321 unmodified lines | |||
| 322 | blk_mq_exit_queue(q); | 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 | /* @q is and will stay empty, shutdown and put */ | 325 | /* @q is and will stay empty, shutdown and put */ |
| 339 | blk_put_queue(q); | 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 | for (i = 0; i < iars->nr_ia_ranges; i++) { | 146 | for (i = 0; i < iars->nr_ia_ranges; i++) { |
| 147 | iars->ia_range[i].queue = q; | ||
| 148 | ret = kobject_init_and_add(&iars->ia_range[i].kobj, | 147 | ret = kobject_init_and_add(&iars->ia_range[i].kobj, |
| 149 | &blk_ia_range_ktype, &iars->kobj, | 148 | &blk_ia_range_ktype, &iars->kobj, |
| 150 | "%d", i); | 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 | static void blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx, | 714 | static void blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx, |
| 720 | struct blk_mq_ctx *ctx) | 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 | void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx) | 742 | void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx) |
| 748 | { | 743 | { |
| 744 | if (!hctx->queue->debugfs_dir) | ||
| 745 | return; | ||
| 749 | debugfs_remove_recursive(hctx->debugfs_dir); | 746 | debugfs_remove_recursive(hctx->debugfs_dir); |
| 750 | hctx->sched_debugfs_dir = NULL; | 747 | hctx->sched_debugfs_dir = NULL; |
| 751 | hctx->debugfs_dir = NULL; | 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 | struct elevator_type *e = q->elevator->type; | 771 | struct elevator_type *e = q->elevator->type; |
| 775 | 772 | ||
| 773 | lockdep_assert_held(&q->debugfs_mutex); | ||
| 774 | |||
| 776 | /* | 775 | /* |
| 777 | * If the parent directory has not been created yet, return, we will be | 776 | * If the parent directory has not been created yet, return, we will be |
| 778 | * called again later on and the directory/files will be created then. | 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 | void blk_mq_debugfs_unregister_sched(struct request_queue *q) | 790 | void blk_mq_debugfs_unregister_sched(struct request_queue *q) |
| 792 | { | 791 | { |
| 792 | lockdep_assert_held(&q->debugfs_mutex); | ||
| 793 | |||
| 793 | debugfs_remove_recursive(q->sched_debugfs_dir); | 794 | debugfs_remove_recursive(q->sched_debugfs_dir); |
| 794 | q->sched_debugfs_dir = NULL; | 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 | void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos) | 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 | debugfs_remove_recursive(rqos->debugfs_dir); | 819 | debugfs_remove_recursive(rqos->debugfs_dir); |
| 815 | rqos->debugfs_dir = NULL; | 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 | struct request_queue *q = rqos->q; | 825 | struct request_queue *q = rqos->q; |
| 821 | const char *dir_name = rq_qos_id_to_name(rqos->id); | 826 | const char *dir_name = rq_qos_id_to_name(rqos->id); |
| 822 | 827 | ||
| 828 | lockdep_assert_held(&q->debugfs_mutex); | ||
| 829 | |||
| 823 | if (rqos->debugfs_dir || !rqos->ops->debugfs_attrs) | 830 | if (rqos->debugfs_dir || !rqos->ops->debugfs_attrs) |
| 824 | return; | 831 | return; |
| 825 | 832 | ||
| @@ -833,17 +840,13 @@ void blk_mq_debugfs_register_rqos(struct rq_qos *rqos) · 7 unmodified lines | |||
| 833 | debugfs_create_files(rqos->debugfs_dir, rqos, rqos->ops->debugfs_attrs); | 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 | void blk_mq_debugfs_register_sched_hctx(struct request_queue *q, | 843 | void blk_mq_debugfs_register_sched_hctx(struct request_queue *q, |
| 843 | struct blk_mq_hw_ctx *hctx) | 844 | struct blk_mq_hw_ctx *hctx) |
| 844 | { | 845 | { |
| 845 | struct elevator_type *e = q->elevator->type; | 846 | struct elevator_type *e = q->elevator->type; |
| 846 | 847 | ||
| 848 | lockdep_assert_held(&q->debugfs_mutex); | ||
| 849 | |||
| 847 | /* | 850 | /* |
| 848 | * If the parent debugfs directory has not been created yet, return; | 851 | * If the parent debugfs directory has not been created yet, return; |
| 849 | * We will be called again later on with appropriate parent debugfs | 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 | void blk_mq_debugfs_unregister_sched_hctx(struct blk_mq_hw_ctx *hctx) | 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 | debugfs_remove_recursive(hctx->sched_debugfs_dir); | 873 | debugfs_remove_recursive(hctx->sched_debugfs_dir); |
| 867 | hctx->sched_debugfs_dir = NULL; | 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 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v); | 21 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v); |
| 22 | 22 | ||
| 23 | void blk_mq_debugfs_register(struct request_queue *q); | 23 | void blk_mq_debugfs_register(struct request_queue *q); |
| 24 | void blk_mq_debugfs_unregister(struct request_queue *q); | ||
| 25 | void blk_mq_debugfs_register_hctx(struct request_queue *q, | 24 | void blk_mq_debugfs_register_hctx(struct request_queue *q, |
| 26 | struct blk_mq_hw_ctx *hctx); | 25 | struct blk_mq_hw_ctx *hctx); |
| 27 | void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx); | 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 | void blk_mq_debugfs_register_rqos(struct rq_qos *rqos); | 36 | void blk_mq_debugfs_register_rqos(struct rq_qos *rqos); |
| 38 | void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos); | 37 | void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos); |
| 39 | void blk_mq_debugfs_unregister_queue_rqos(struct request_queue *q); | ||
| 40 | #else | 38 | #else |
| 41 | static inline void blk_mq_debugfs_register(struct request_queue *q) | 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 | static inline void blk_mq_debugfs_register_hctx(struct request_queue *q, | 43 | static inline void blk_mq_debugfs_register_hctx(struct request_queue *q, |
| 50 | struct blk_mq_hw_ctx *hctx) | 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 | static inline void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos) | 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 | #endif | 84 | #endif |
| 95 | 85 | ||
| 96 | #ifdef CONFIG_BLK_DEBUG_FS_ZONED | 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 | int ret; | 564 | int ret; |
| 565 | 565 | ||
| 566 | if (!e) { | 566 | if (!e) { |
| 567 | blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q); | ||
| 567 | q->elevator = NULL; | 568 | q->elevator = NULL; |
| 568 | q->nr_requests = q->tag_set->queue_depth; | 569 | q->nr_requests = q->tag_set->queue_depth; |
| 569 | return 0; | 570 | return 0; |
| @@ -593,7 +594,9 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) · 23 unmodified lines | |||
| 593 | if (ret) | 594 | if (ret) |
| 594 | goto err_free_map_and_rqs; | 595 | goto err_free_map_and_rqs; |
| 595 | 596 | ||
| 597 | mutex_lock(&q->debugfs_mutex); | ||
| 596 | blk_mq_debugfs_register_sched(q); | 598 | blk_mq_debugfs_register_sched(q); |
| 599 | mutex_unlock(&q->debugfs_mutex); | ||
| 597 | 600 | ||
| 598 | queue_for_each_hw_ctx(q, hctx, i) { | 601 | queue_for_each_hw_ctx(q, hctx, i) { |
| 599 | if (e->ops.init_hctx) { | 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 | return ret; | 609 | return ret; |
| 607 | } | 610 | } |
| 608 | } | 611 | } |
| 612 | mutex_lock(&q->debugfs_mutex); | ||
| 609 | blk_mq_debugfs_register_sched_hctx(q, hctx); | 613 | blk_mq_debugfs_register_sched_hctx(q, hctx); |
| 614 | mutex_unlock(&q->debugfs_mutex); | ||
| 610 | } | 615 | } |
| 611 | 616 | ||
| 612 | return 0; | 617 | return 0; |
| @@ -647,14 +652,21 @@ void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e) · 34 unmodified lines | |||
| 647 | unsigned int flags = 0; | 652 | unsigned int flags = 0; |
| 648 | 653 | ||
| 649 | queue_for_each_hw_ctx(q, hctx, i) { | 654 | queue_for_each_hw_ctx(q, hctx, i) { |
| 655 | mutex_lock(&q->debugfs_mutex); | ||
| 650 | blk_mq_debugfs_unregister_sched_hctx(hctx); | 656 | blk_mq_debugfs_unregister_sched_hctx(hctx); |
| 657 | mutex_unlock(&q->debugfs_mutex); | ||
| 658 | |||
| 651 | if (e->type->ops.exit_hctx && hctx->sched_data) { | 659 | if (e->type->ops.exit_hctx && hctx->sched_data) { |
| 652 | e->type->ops.exit_hctx(hctx, i); | 660 | e->type->ops.exit_hctx(hctx, i); |
| 653 | hctx->sched_data = NULL; | 661 | hctx->sched_data = NULL; |
| 654 | } | 662 | } |
| 655 | flags = hctx->flags; | 663 | flags = hctx->flags; |
| 656 | } | 664 | } |
| 665 | |||
| 666 | mutex_lock(&q->debugfs_mutex); | ||
| 657 | blk_mq_debugfs_unregister_sched(q); | 667 | blk_mq_debugfs_unregister_sched(q); |
| 668 | mutex_unlock(&q->debugfs_mutex); | ||
| 669 | |||
| 658 | if (e->type->ops.exit_sched) | 670 | if (e->type->ops.exit_sched) |
| 659 | e->type->ops.exit_sched(e); | 671 | e->type->ops.exit_sched(e); |
| 660 | blk_mq_sched_tags_teardown(q, flags); | 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 | if (!blk_mq_hw_queue_mapped(data.hctx)) | 579 | if (!blk_mq_hw_queue_mapped(data.hctx)) |
| 580 | goto out_queue_exit; | 580 | goto out_queue_exit; |
| 581 | cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask); | 581 | cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask); |
| 582 | if (cpu >= nr_cpu_ids) | ||
| 583 | goto out_queue_exit; | ||
| 582 | data.ctx = __blk_mq_get_ctx(q, cpu); | 584 | data.ctx = __blk_mq_get_ctx(q, cpu); |
| 583 | 585 | ||
| 584 | if (!q->elevator) | 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 | EXPORT_SYMBOL(blk_mq_run_hw_queue); | 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 | * Return prefered queue to dispatch from (if any) for non-mq aware IO | 2146 | * Return prefered queue to dispatch from (if any) for non-mq aware IO |
| 2159 | * scheduler. | 2147 | * scheduler. |
| @@ -2186,7 +2174,7 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async) · 26 unmodified lines | |||
| 2186 | unsigned long i; | 2174 | unsigned long i; |
| 2187 | 2175 | ||
| 2188 | sq_hctx = NULL; | 2176 | sq_hctx = NULL; |
| 2189 | if (blk_mq_has_sqsched(q)) | 2177 | if (blk_queue_sq_sched(q)) |
| 2190 | sq_hctx = blk_mq_get_sq_hctx(q); | 2178 | sq_hctx = blk_mq_get_sq_hctx(q); |
| 2191 | queue_for_each_hw_ctx(q, hctx, i) { | 2179 | queue_for_each_hw_ctx(q, hctx, i) { |
| 2192 | if (blk_mq_hctx_stopped(hctx)) | 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 | unsigned long i; | 2202 | unsigned long i; |
| 2215 | 2203 | ||
| 2216 | sq_hctx = NULL; | 2204 | sq_hctx = NULL; |
| 2217 | if (blk_mq_has_sqsched(q)) | 2205 | if (blk_queue_sq_sched(q)) |
| 2218 | sq_hctx = blk_mq_get_sq_hctx(q); | 2206 | sq_hctx = blk_mq_get_sq_hctx(q); |
| 2219 | queue_for_each_hw_ctx(q, hctx, i) { | 2207 | queue_for_each_hw_ctx(q, hctx, i) { |
| 2220 | if (blk_mq_hctx_stopped(hctx)) | 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 | return NULL; | 2765 | return NULL; |
| 2778 | } | 2766 | } |
| 2779 | 2767 | ||
| 2780 | rq_qos_throttle(q, *bio); | ||
| 2781 | |||
| 2782 | if (blk_mq_get_hctx_type((*bio)->bi_opf) != rq->mq_hctx->type) | 2768 | if (blk_mq_get_hctx_type((*bio)->bi_opf) != rq->mq_hctx->type) |
| 2783 | return NULL; | 2769 | return NULL; |
| 2784 | if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) | 2770 | if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) |
| 2785 | return NULL; | 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 | plug->cached_rq = rq_list_next(rq); | 2778 | plug->cached_rq = rq_list_next(rq); |
| 2779 | rq_qos_throttle(q, *bio); | ||
| 2780 | |||
| 2781 | rq->cmd_flags = (*bio)->bi_opf; | ||
| 2789 | INIT_LIST_HEAD(&rq->queuelist); | 2782 | INIT_LIST_HEAD(&rq->queuelist); |
| 2790 | return rq; | 2783 | return rq; |
| 2791 | } | 2784 | } |
| @@ -3443,8 +3436,9 @@ static void blk_mq_exit_hctx(struct request_queue *q, · 651 unmodified lines | |||
| 3443 | if (blk_mq_hw_queue_mapped(hctx)) | 3436 | if (blk_mq_hw_queue_mapped(hctx)) |
| 3444 | blk_mq_tag_idle(hctx); | 3437 | blk_mq_tag_idle(hctx); |
| 3445 | 3438 | ||
| 3446 | blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx], | 3439 | if (blk_queue_init_done(q)) |
| 3447 | set->queue_depth, flush_rq); | 3440 | blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx], |
| 3441 | set->queue_depth, flush_rq); | ||
| 3448 | if (set->ops->exit_request) | 3442 | if (set->ops->exit_request) |
| 3449 | set->ops->exit_request(set, flush_rq, hctx_idx); | 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 | if (!qe) | 4432 | if (!qe) |
| 4439 | return false; | 4433 | return false; |
| 4440 | 4434 | ||
| 4435 | /* q->elevator needs protection from ->sysfs_lock */ | ||
| 4436 | mutex_lock(&q->sysfs_lock); | ||
| 4437 | |||
| 4441 | INIT_LIST_HEAD(&qe->node); | 4438 | INIT_LIST_HEAD(&qe->node); |
| 4442 | qe->q = q; | 4439 | qe->q = q; |
| 4443 | qe->type = q->elevator->type; | 4440 | qe->type = q->elevator->type; |
| 4444 | list_add(&qe->node, head); | 4441 | list_add(&qe->node, head); |
| 4445 | 4442 | ||
| 4446 | mutex_lock(&q->sysfs_lock); | ||
| 4447 | /* | 4443 | /* |
| 4448 | * After elevator_switch_mq, the previous elevator_queue will be | 4444 | * After elevator_switch_mq, the previous elevator_queue will be |
| 4449 | * released by elevator_release. The reference of the io scheduler | 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 | void rq_qos_exit(struct request_queue *q) | 295 | void rq_qos_exit(struct request_queue *q) |
| 296 | { | 296 | { |
| 297 | blk_mq_debugfs_unregister_queue_rqos(q); | ||
| 298 | |||
| 299 | while (q->rq_qos) { | 297 | while (q->rq_qos) { |
| 300 | struct rq_qos *rqos = q->rq_qos; | 298 | struct rq_qos *rqos = q->rq_qos; |
| 301 | q->rq_qos = rqos->next; | 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 | blk_mq_unfreeze_queue(q); | 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 | blk_mq_debugfs_register_rqos(rqos); | 109 | blk_mq_debugfs_register_rqos(rqos); |
| 110 | mutex_unlock(&q->debugfs_mutex); | ||
| 111 | } | ||
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) | 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 | blk_mq_unfreeze_queue(q); | 133 | blk_mq_unfreeze_queue(q); |
| 131 | 134 | ||
| 135 | mutex_lock(&q->debugfs_mutex); | ||
| 132 | blk_mq_debugfs_unregister_rqos(rqos); | 136 | blk_mq_debugfs_unregister_rqos(rqos); |
| 137 | mutex_unlock(&q->debugfs_mutex); | ||
| 133 | } | 138 | } |
| 134 | 139 | ||
| 135 | typedef bool (acquire_inflight_cb_t)(struct rq_wait *rqw, void *private_data); | 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 | if (queue_is_mq(q)) | 779 | if (queue_is_mq(q)) |
| 780 | blk_mq_release(q); | 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 | bioset_exit(&q->bio_split); | 782 | bioset_exit(&q->bio_split); |
| 791 | 783 | ||
| 792 | if (blk_queue_has_srcu(q)) | 784 | if (blk_queue_has_srcu(q)) |
| @@ -836,17 +828,16 @@ int blk_register_queue(struct gendisk *disk) · 43 unmodified lines | |||
| 836 | goto unlock; | 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 | mutex_lock(&q->debugfs_mutex); | 835 | mutex_lock(&q->debugfs_mutex); |
| 840 | q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), | 836 | q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), |
| 841 | blk_debugfs_root); | 837 | blk_debugfs_root); |
| 842 | mutex_unlock(&q->debugfs_mutex); | 838 | if (queue_is_mq(q)) |
| 843 | |||
| 844 | if (queue_is_mq(q)) { | ||
| 845 | __blk_mq_register_dev(dev, q); | ||
| 846 | blk_mq_debugfs_register(q); | 839 | blk_mq_debugfs_register(q); |
| 847 | } | 840 | mutex_unlock(&q->debugfs_mutex); |
| 848 | |||
| 849 | mutex_lock(&q->sysfs_lock); | ||
| 850 | 841 | ||
| 851 | ret = disk_register_independent_access_ranges(disk, NULL); | 842 | ret = disk_register_independent_access_ranges(disk, NULL); |
| 852 | if (ret) | 843 | if (ret) |
| @@ -948,8 +939,15 @@ void blk_unregister_queue(struct gendisk *disk) · 95 unmodified lines | |||
| 948 | /* Now that we've deleted all child objects, we can delete the queue. */ | 939 | /* Now that we've deleted all child objects, we can delete the queue. */ |
| 949 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 940 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
| 950 | kobject_del(&q->kobj); | 941 | kobject_del(&q->kobj); |
| 951 | |||
| 952 | mutex_unlock(&q->sysfs_dir_lock); | 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 | kobject_put(&disk_to_dev(disk)->kobj); | 952 | kobject_put(&disk_to_dev(disk)->kobj); |
| 955 | } | 953 | } |
| @@ -623,6 +623,7 @@ void del_gendisk(struct gendisk *disk) · 622 unmodified lines | |||
| 623 | * Prevent new I/O from crossing bio_queue_enter(). | 623 | * Prevent new I/O from crossing bio_queue_enter(). |
| 624 | */ | 624 | */ |
| 625 | blk_queue_start_drain(q); | 625 | blk_queue_start_drain(q); |
| 626 | blk_mq_freeze_queue_wait(q); | ||
| 626 | 627 | ||
| 627 | if (!(disk->flags & GENHD_FL_HIDDEN)) { | 628 | if (!(disk->flags & GENHD_FL_HIDDEN)) { |
| 628 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); | 629 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); |
| @@ -646,12 +647,21 @@ void del_gendisk(struct gendisk *disk) · 17 unmodified lines | |||
| 646 | pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); | 647 | pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); |
| 647 | device_del(disk_to_dev(disk)); | 648 | device_del(disk_to_dev(disk)); |
| 648 | 649 | ||
| 649 | blk_mq_freeze_queue_wait(q); | ||
| 650 | |||
| 651 | blk_throtl_cancel_bios(disk->queue); | 650 | blk_throtl_cancel_bios(disk->queue); |
| 652 | 651 | ||
| 653 | blk_sync_queue(q); | 652 | blk_sync_queue(q); |
| 654 | blk_flush_integrity(); | 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 | * Allow using passthrough request again after the queue is torn down. | 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 | NULL | 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 | * disk_release - releases all allocated resources of the gendisk | 1134 | * disk_release - releases all allocated resources of the gendisk |
| 1150 | * @dev: the device representing this disk | 1135 | * @dev: the device representing this disk |
| @@ -1166,9 +1151,6 @@ static void disk_release(struct device *dev) · 15 unmodified lines | |||
| 1166 | might_sleep(); | 1151 | might_sleep(); |
| 1167 | WARN_ON_ONCE(disk_live(disk)); | 1152 | WARN_ON_ONCE(disk_live(disk)); |
| 1168 | 1153 | ||
| 1169 | if (queue_is_mq(disk->queue)) | ||
| 1170 | disk_release_mq(disk->queue); | ||
| 1171 | |||
| 1172 | blkcg_exit_queue(disk->queue); | 1154 | blkcg_exit_queue(disk->queue); |
| 1173 | 1155 | ||
| 1174 | disk_release_events(disk); | 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 | WARN_ON_ONCE(!bdev->bd_holder); | 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 | holder = bd_find_holder_disk(bdev, disk); | 82 | holder = bd_find_holder_disk(bdev, disk); |
| 87 | if (holder) { | 83 | if (holder) { |
| 88 | holder->refcnt++; | 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 | blk_stat_enable_accounting(q); | 422 | blk_stat_enable_accounting(q); |
| 423 | 423 | ||
| 424 | blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q); | ||
| 425 | |||
| 424 | eq->elevator_data = kqd; | 426 | eq->elevator_data = kqd; |
| 425 | q->elevator = eq; | 427 | q->elevator = eq; |
| 426 | 428 | ||
| @@ -1033,7 +1035,6 @@ static struct elevator_type kyber_sched = { · 606 unmodified lines | |||
| 1033 | #endif | 1035 | #endif |
| 1034 | .elevator_attrs = kyber_sched_attrs, | 1036 | .elevator_attrs = kyber_sched_attrs, |
| 1035 | .elevator_name = "kyber", | 1037 | .elevator_name = "kyber", |
| 1036 | .elevator_features = ELEVATOR_F_MQ_AWARE, | ||
| 1037 | .elevator_owner = THIS_MODULE, | 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 | spin_lock_init(&dd->lock); | 642 | spin_lock_init(&dd->lock); |
| 643 | spin_lock_init(&dd->zone_lock); | 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 | q->elevator = eq; | 648 | q->elevator = eq; |
| 646 | return 0; | 649 | return 0; |
| 647 | 650 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | /blacklist_hashes_checked | 2 | /blacklist_hash_list |
| 3 | /extract-cert | 3 | /extract-cert |
| 4 | /x509_certificate_list | 4 | /x509_certificate_list |
| 5 | /x509_revocation_list | 5 | /x509_revocation_list |
| @@ -3,26 +3,26 @@ · 2 unmodified lines | |||
| 3 | # Makefile for the linux kernel signature checking certificates. | 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 | 6 | obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o |
| 7 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o | 7 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o |
| 8 | obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o | 8 | obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o |
| 9 | ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),) | 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) | 19 | $(obj)/blacklist_hash_list: $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) FORCE |
| 18 | 20 | $(call if_changed,check_and_copy_blacklist_hash_list) | |
| 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)) | ||
| 22 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o | 21 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o |
| 23 | else | 22 | else |
| 24 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o | 23 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o |
| 25 | endif | 24 | endif |
| 25 | targets += blacklist_hash_list | ||
| 26 | 26 | ||
| 27 | quiet_cmd_extract_certs = CERT $@ | 27 | quiet_cmd_extract_certs = CERT $@ |
| 28 | cmd_extract_certs = $(obj)/extract-cert $(extract-cert-in) $@ | 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 | $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE | 33 | $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE |
| 34 | $(call if_changed,extract_certs) | 34 | $(call if_changed,extract_certs) |
| 35 | 35 | ||
| 36 | targets += x509_certificate_list blacklist_hashes_checked | 36 | targets += x509_certificate_list |
| 37 | 37 | ||
| 38 | # If module signing is requested, say by allyesconfig, but a key has not been | 38 | # If module signing is requested, say by allyesconfig, but a key has not been |
| 39 | # supplied, then one will need to be generated to make sure the build does not | 39 | # supplied, then one will need to be generated to make sure the build does not |
| @@ -15,10 +15,9 @@ · 14 unmodified lines | |||
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
| 17 | #include <linux/uidgid.h> | 17 | #include <linux/uidgid.h> |
| 18 | #include <linux/verification.h> | 18 | #include <keys/asymmetric-type.h> |
| 19 | #include <keys/system_keyring.h> | 19 | #include <keys/system_keyring.h> |
| 20 | #include "blacklist.h" | 20 | #include "blacklist.h" |
| 21 | #include "common.h" | ||
| 22 | 21 | ||
| 23 | /* | 22 | /* |
| 24 | * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), | 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 | if (revocation_certificate_list_size) | 364 | if (revocation_certificate_list_size) |
| 366 | pr_notice("Loading compiled-in revocation X.509 certificates\n"); | 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, | 367 | return x509_load_certificate_list(revocation_certificate_list, |
| 369 | blacklist_keyring); | 368 | revocation_certificate_list_size, |
| 369 | blacklist_keyring); | ||
| 370 | } | 370 | } |
| 371 | late_initcall(load_revocation_certificate_list); | 371 | late_initcall(load_revocation_certificate_list); |
| 372 | #endif | 372 | #endif |
| @@ -1,7 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include "blacklist.h" | 2 | #include "blacklist.h" |
| 3 | 3 | ||
| 4 | const char __initdata *const blacklist_hashes[] = { | 4 | const char __initconst *const blacklist_hashes[] = { |
| 5 | #include CONFIG_SYSTEM_BLACKLIST_HASH_LIST | 5 | #include "blacklist_hash_list" |
| 6 | , NULL | 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 | #include <keys/asymmetric-type.h> | 16 | #include <keys/asymmetric-type.h> |
| 17 | #include <keys/system_keyring.h> | 17 | #include <keys/system_keyring.h> |
| 18 | #include <crypto/pkcs7.h> | 18 | #include <crypto/pkcs7.h> |
| 19 | #include "common.h" | ||
| 20 | 19 | ||
| 21 | static struct key *builtin_trusted_keys; | 20 | static struct key *builtin_trusted_keys; |
| 22 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING | 21 | #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING |
| @@ -183,7 +182,8 @@ __init int load_module_cert(struct key *keyring) · 160 unmodified lines | |||
| 183 | 182 | ||
| 184 | pr_notice("Loading compiled-in module X.509 certificates\n"); | 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 | size = system_certificate_list_size - module_cert_size; | 204 | size = system_certificate_list_size - module_cert_size; |
| 205 | #endif | 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 | late_initcall(load_system_certificate_list); | 209 | late_initcall(load_system_certificate_list); |
| 210 | 210 | ||
| @@ -15,6 +15,7 @@ source "crypto/async_tx/Kconfig" · 14 unmodified lines | |||
| 15 | # | 15 | # |
| 16 | menuconfig CRYPTO | 16 | menuconfig CRYPTO |
| 17 | tristate "Cryptographic API" | 17 | tristate "Cryptographic API" |
| 18 | select LIB_MEMNEQ | ||
| 18 | help | 19 | help |
| 19 | This option provides the core Cryptographic API. | 20 | This option provides the core Cryptographic API. |
| 20 | 21 | ||
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_CRYPTO) += crypto.o | 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 | obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o | 9 | obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o |
| 10 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o | 10 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o |
| @@ -75,4 +75,14 @@ config SIGNED_PE_FILE_VERIFICATION · 74 unmodified lines | |||
| 75 | This option provides support for verifying the signature(s) on a | 75 | This option provides support for verifying the signature(s) on a |
| 76 | signed PE binary. | 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 | endif # ASYMMETRIC_KEY_TYPE | 88 | endif # ASYMMETRIC_KEY_TYPE |
| @@ -20,7 +20,9 @@ x509_key_parser-y := \ · 19 unmodified lines | |||
| 20 | x509.asn1.o \ | 20 | x509.asn1.o \ |
| 21 | x509_akid.asn1.o \ | 21 | x509_akid.asn1.o \ |
| 22 | x509_cert_parser.o \ | 22 | x509_cert_parser.o \ |
| 23 | x509_loader.o \ | ||
| 23 | x509_public_key.o | 24 | x509_public_key.o |
| 25 | x509_key_parser-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += selftest.o | ||
| 24 | 26 | ||
| 25 | $(obj)/x509_cert_parser.o: \ | 27 | $(obj)/x509_cert_parser.o: \ |
| 26 | $(obj)/x509.asn1.h \ | 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 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 4 | #include <linux/key.h> | 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[], | 7 | int x509_load_certificate_list(const u8 cert_list[], |
| 8 | const unsigned long list_size, | 8 | const unsigned long list_size, |
| 9 | const struct key *keyring) | 9 | const struct key *keyring) |
| 10 | { | 10 | { |
| 11 | key_ref_t key; | 11 | key_ref_t key; |
| 12 | const u8 *p, *end; | 12 | const u8 *p, *end; |
| @@ -40,6 +40,15 @@ struct x509_certificate { · 39 unmodified lines | |||
| 40 | bool blacklisted; | 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 | * x509_cert_parser.c | 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 | * Module stuff | 245 | * Module stuff |
| 246 | */ | 246 | */ |
| 247 | extern int __init certs_selftest(void); | ||
| 247 | static int __init x509_key_init(void) | 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 | static void __exit x509_key_exit(void) | 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 | return sysfs_emit(buf, "Not affected\n"); | 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 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); | 573 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
| 568 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); | 574 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); |
| 569 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); | 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 | static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); | 579 | static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); |
| 574 | static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); | 580 | static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); |
| 575 | static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); | 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 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { | 584 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
| 578 | &dev_attr_meltdown.attr, | 585 | &dev_attr_meltdown.attr, |
| @@ -584,6 +591,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { · 5 unmodified lines | |||
| 584 | &dev_attr_tsx_async_abort.attr, | 591 | &dev_attr_tsx_async_abort.attr, |
| 585 | &dev_attr_itlb_multihit.attr, | 592 | &dev_attr_itlb_multihit.attr, |
| 586 | &dev_attr_srbds.attr, | 593 | &dev_attr_srbds.attr, |
| 594 | &dev_attr_mmio_stale_data.attr, | ||
| 587 | NULL | 595 | NULL |
| 588 | }; | 596 | }; |
| 589 | 597 | ||
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include <linux/memory.h> | 9 | #include <linux/memory.h> |
| 10 | #include <linux/of.h> | 10 | #include <linux/of.h> |
| 11 | #include <linux/backing-dev.h> | ||
| 11 | 12 | ||
| 12 | #include "base.h" | 13 | #include "base.h" |
| 13 | 14 | ||
| @@ -20,6 +21,7 @@ · 6 unmodified lines | |||
| 20 | void __init driver_init(void) | 21 | void __init driver_init(void) |
| 21 | { | 22 | { |
| 22 | /* These are the core pieces */ | 23 | /* These are the core pieces */ |
| 24 | bdi_init(&noop_backing_dev_info); | ||
| 23 | devtmpfs_init(); | 25 | devtmpfs_init(); |
| 24 | devices_init(); | 26 | devices_init(); |
| 25 | buses_init(); | 27 | buses_init(); |
| @@ -558,7 +558,7 @@ static ssize_t hard_offline_page_store(struct device *dev, · 557 unmodified lines | |||
| 558 | if (kstrtoull(buf, 0, &pfn) < 0) | 558 | if (kstrtoull(buf, 0, &pfn) < 0) |
| 559 | return -EINVAL; | 559 | return -EINVAL; |
| 560 | pfn >>= PAGE_SHIFT; | 560 | pfn >>= PAGE_SHIFT; |
| 561 | ret = memory_failure(pfn, 0); | 561 | ret = memory_failure(pfn, MF_SW_SIMULATED); |
| 562 | if (ret == -EOPNOTSUPP) | 562 | if (ret == -EOPNOTSUPP) |
| 563 | ret = 0; | 563 | ret = 0; |
| 564 | return ret ? ret : count; | 564 | return ret ? ret : count; |
| @@ -252,6 +252,7 @@ static void regmap_irq_enable(struct irq_data *data) · 251 unmodified lines | |||
| 252 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); | 252 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); |
| 253 | struct regmap *map = d->map; | 253 | struct regmap *map = d->map; |
| 254 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); | 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 | unsigned int mask, type; | 256 | unsigned int mask, type; |
| 256 | 257 | ||
| 257 | type = irq_data->type.type_falling_val | irq_data->type.type_rising_val; | 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 | * at the corresponding offset in regmap_irq_set_type(). | 269 | * at the corresponding offset in regmap_irq_set_type(). |
| 269 | */ | 270 | */ |
| 270 | if (d->chip->type_in_mask && type) | 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 | else | 273 | else |
| 273 | mask = irq_data->mask; | 274 | mask = irq_data->mask; |
| 274 | 275 | ||
| 275 | if (d->chip->clear_on_unmask) | 276 | if (d->chip->clear_on_unmask) |
| 276 | d->clear_status = true; | 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 | static void regmap_irq_disable(struct irq_data *data) | 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 | subreg = &chip->sub_reg_offsets[b]; | 387 | subreg = &chip->sub_reg_offsets[b]; |
| 387 | for (i = 0; i < subreg->num_regs; i++) { | 388 | for (i = 0; i < subreg->num_regs; i++) { |
| 388 | unsigned int offset = subreg->offset[i]; | 389 | unsigned int offset = subreg->offset[i]; |
| 390 | unsigned int index = offset / map->reg_stride; | ||
| 389 | 391 | ||
| 390 | if (chip->not_fixed_stride) | 392 | if (chip->not_fixed_stride) |
| 391 | ret = regmap_read(map, | 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 | else | 396 | else |
| 395 | ret = regmap_read(map, | 397 | ret = regmap_read(map, |
| 396 | chip->status_base + offset, | 398 | chip->status_base + offset, |
| 397 | &data->status_buf[offset]); | 399 | &data->status_buf[index]); |
| 398 | 400 | ||
| 399 | if (ret) | 401 | if (ret) |
| 400 | break; | 402 | break; |
| @@ -1880,8 +1880,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, · 1879 unmodified lines | |||
| 1880 | */ | 1880 | */ |
| 1881 | bool regmap_can_raw_write(struct regmap *map) | 1881 | bool regmap_can_raw_write(struct regmap *map) |
| 1882 | { | 1882 | { |
| 1883 | return map->bus && map->bus->write && map->format.format_val && | 1883 | return map->write && map->format.format_val && map->format.format_reg; |
| 1884 | map->format.format_reg; | ||
| 1885 | } | 1884 | } |
| 1886 | EXPORT_SYMBOL_GPL(regmap_can_raw_write); | 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 | size_t write_len; | 2154 | size_t write_len; |
| 2156 | int ret; | 2155 | int ret; |
| 2157 | 2156 | ||
| 2158 | if (!map->bus) | 2157 | if (!map->write) |
| 2159 | return -EINVAL; | ||
| 2160 | if (!map->bus->write) | ||
| 2161 | return -ENOTSUPP; | 2158 | return -ENOTSUPP; |
| 2159 | |||
| 2162 | if (val_len % map->format.val_bytes) | 2160 | if (val_len % map->format.val_bytes) |
| 2163 | return -EINVAL; | 2161 | return -EINVAL; |
| 2164 | if (!IS_ALIGNED(reg, map->reg_stride)) | 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 | * Some devices don't support bulk write, for them we have a series of | 2276 | * Some devices don't support bulk write, for them we have a series of |
| 2279 | * single write operations. | 2277 | * single write operations. |
| 2280 | */ | 2278 | */ |
| 2281 | if (!map->bus || !map->format.parse_inplace) { | 2279 | if (!map->write || !map->format.parse_inplace) { |
| 2282 | map->lock(map->lock_arg); | 2280 | map->lock(map->lock_arg); |
| 2283 | for (i = 0; i < val_count; i++) { | 2281 | for (i = 0; i < val_count; i++) { |
| 2284 | unsigned int ival; | 2282 | unsigned int ival; |
| @@ -2904,6 +2902,9 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, · 619 unmodified lines | |||
| 2904 | size_t read_len; | 2902 | size_t read_len; |
| 2905 | int ret; | 2903 | int ret; |
| 2906 | 2904 | ||
| 2905 | if (!map->read) | ||
| 2906 | return -ENOTSUPP; | ||
| 2907 | |||
| 2907 | if (val_len % map->format.val_bytes) | 2908 | if (val_len % map->format.val_bytes) |
| 2908 | return -EINVAL; | 2909 | return -EINVAL; |
| 2909 | if (!IS_ALIGNED(reg, map->reg_stride)) | 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 | if (val_count == 0) | 3018 | if (val_count == 0) |
| 3018 | return -EINVAL; | 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 | ret = regmap_raw_read(map, reg, val, val_bytes * val_count); | 3022 | ret = regmap_raw_read(map, reg, val, val_bytes * val_count); |
| 3022 | if (ret != 0) | 3023 | if (ret != 0) |
| 3023 | return ret; | 3024 | return ret; |
| @@ -2114,9 +2114,11 @@ static void blkfront_closing(struct blkfront_info *info) · 2113 unmodified lines | |||
| 2114 | return; | 2114 | return; |
| 2115 | 2115 | ||
| 2116 | /* No more blkif_request(). */ | 2116 | /* No more blkif_request(). */ |
| 2117 | blk_mq_stop_hw_queues(info->rq); | 2117 | if (info->rq && info->gd) { |
| 2118 | blk_mark_disk_dead(info->gd); | 2118 | blk_mq_stop_hw_queues(info->rq); |
| 2119 | set_capacity(info->gd, 0); | 2119 | blk_mark_disk_dead(info->gd); |
| 2120 | set_capacity(info->gd, 0); | ||
| 2121 | } | ||
| 2120 | 2122 | ||
| 2121 | for_each_rinfo(info, rinfo, i) { | 2123 | for_each_rinfo(info, rinfo, i) { |
| 2122 | /* No more gnttab callback work. */ | 2124 | /* No more gnttab callback work. */ |
| @@ -2457,16 +2459,19 @@ static int blkfront_remove(struct xenbus_device *xbdev) · 334 unmodified lines | |||
| 2457 | 2459 | ||
| 2458 | dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename); | 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 | mutex_lock(&blkfront_mutex); | 2465 | mutex_lock(&blkfront_mutex); |
| 2463 | list_del(&info->info_list); | 2466 | list_del(&info->info_list); |
| 2464 | mutex_unlock(&blkfront_mutex); | 2467 | mutex_unlock(&blkfront_mutex); |
| 2465 | 2468 | ||
| 2466 | blkif_free(info, 0); | 2469 | blkif_free(info, 0); |
| 2467 | xlbd_release_minors(info->gd->first_minor, info->gd->minors); | 2470 | if (info->gd) { |
| 2468 | blk_cleanup_disk(info->gd); | 2471 | xlbd_release_minors(info->gd->first_minor, info->gd->minors); |
| 2469 | blk_mq_free_tag_set(&info->tag_set); | 2472 | blk_cleanup_disk(info->gd); |
| 2473 | blk_mq_free_tag_set(&info->tag_set); | ||
| 2474 | } | ||
| 2470 | 2475 | ||
| 2471 | kfree(info); | 2476 | kfree(info); |
| 2472 | return 0; | 2477 | return 0; |
| @@ -175,10 +175,9 @@ static int bt1_apb_request_rst(struct bt1_apb *apb) · 174 unmodified lines | |||
| 175 | int ret; | 175 | int ret; |
| 176 | 176 | ||
| 177 | apb->prst = devm_reset_control_get_optional_exclusive(apb->dev, "prst"); | 177 | apb->prst = devm_reset_control_get_optional_exclusive(apb->dev, "prst"); |
| 178 | if (IS_ERR(apb->prst)) { | 178 | if (IS_ERR(apb->prst)) |
| 179 | dev_warn(apb->dev, "Couldn't get reset control line\n"); | 179 | return dev_err_probe(apb->dev, PTR_ERR(apb->prst), |
| 180 | return PTR_ERR(apb->prst); | 180 | "Couldn't get reset control line\n"); |
| 181 | } | ||
| 182 | 181 | ||
| 183 | ret = reset_control_deassert(apb->prst); | 182 | ret = reset_control_deassert(apb->prst); |
| 184 | if (ret) | 183 | if (ret) |
| @@ -199,10 +198,9 @@ static int bt1_apb_request_clk(struct bt1_apb *apb) · 14 unmodified lines | |||
| 199 | int ret; | 198 | int ret; |
| 200 | 199 | ||
| 201 | apb->pclk = devm_clk_get(apb->dev, "pclk"); | 200 | apb->pclk = devm_clk_get(apb->dev, "pclk"); |
| 202 | if (IS_ERR(apb->pclk)) { | 201 | if (IS_ERR(apb->pclk)) |
| 203 | dev_err(apb->dev, "Couldn't get APB clock descriptor\n"); | 202 | return dev_err_probe(apb->dev, PTR_ERR(apb->pclk), |
| 204 | return PTR_ERR(apb->pclk); | 203 | "Couldn't get APB clock descriptor\n"); |
| 205 | } | ||
| 206 | 204 | ||
| 207 | ret = clk_prepare_enable(apb->pclk); | 205 | ret = clk_prepare_enable(apb->pclk); |
| 208 | if (ret) { | 206 | if (ret) { |
| @@ -135,10 +135,9 @@ static int bt1_axi_request_rst(struct bt1_axi *axi) · 134 unmodified lines | |||
| 135 | int ret; | 135 | int ret; |
| 136 | 136 | ||
| 137 | axi->arst = devm_reset_control_get_optional_exclusive(axi->dev, "arst"); | 137 | axi->arst = devm_reset_control_get_optional_exclusive(axi->dev, "arst"); |
| 138 | if (IS_ERR(axi->arst)) { | 138 | if (IS_ERR(axi->arst)) |
| 139 | dev_warn(axi->dev, "Couldn't get reset control line\n"); | 139 | return dev_err_probe(axi->dev, PTR_ERR(axi->arst), |
| 140 | return PTR_ERR(axi->arst); | 140 | "Couldn't get reset control line\n"); |
| 141 | } | ||
| 142 | 141 | ||
| 143 | ret = reset_control_deassert(axi->arst); | 142 | ret = reset_control_deassert(axi->arst); |
| 144 | if (ret) | 143 | if (ret) |
| @@ -159,10 +158,9 @@ static int bt1_axi_request_clk(struct bt1_axi *axi) · 14 unmodified lines | |||
| 159 | int ret; | 158 | int ret; |
| 160 | 159 | ||
| 161 | axi->aclk = devm_clk_get(axi->dev, "aclk"); | 160 | axi->aclk = devm_clk_get(axi->dev, "aclk"); |
| 162 | if (IS_ERR(axi->aclk)) { | 161 | if (IS_ERR(axi->aclk)) |
| 163 | dev_err(axi->dev, "Couldn't get AXI Interconnect clock\n"); | 162 | return dev_err_probe(axi->dev, PTR_ERR(axi->aclk), |
| 164 | return PTR_ERR(axi->aclk); | 163 | "Couldn't get AXI Interconnect clock\n"); |
| 165 | } | ||
| 166 | 164 | ||
| 167 | ret = clk_prepare_enable(axi->aclk); | 165 | ret = clk_prepare_enable(axi->aclk); |
| 168 | if (ret) { | 166 | if (ret) { |
| @@ -1239,14 +1239,14 @@ error_cleanup_mc_io: · 1238 unmodified lines | |||
| 1239 | static int fsl_mc_bus_remove(struct platform_device *pdev) | 1239 | static int fsl_mc_bus_remove(struct platform_device *pdev) |
| 1240 | { | 1240 | { |
| 1241 | struct fsl_mc *mc = platform_get_drvdata(pdev); | 1241 | struct fsl_mc *mc = platform_get_drvdata(pdev); |
| 1242 | struct fsl_mc_io *mc_io; | ||
| 1242 | 1243 | ||
| 1243 | if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev)) | 1244 | if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev)) |
| 1244 | return -EINVAL; | 1245 | return -EINVAL; |
| 1245 | 1246 | ||
| 1247 | mc_io = mc->root_mc_bus_dev->mc_io; | ||
| 1246 | fsl_mc_device_remove(mc->root_mc_bus_dev); | 1248 | fsl_mc_device_remove(mc->root_mc_bus_dev); |
| 1247 | 1249 | fsl_destroy_mc_io(mc_io); | |
| 1248 | fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io); | ||
| 1249 | mc->root_mc_bus_dev->mc_io = NULL; | ||
| 1250 | 1250 | ||
| 1251 | bus_unregister_notifier(&fsl_mc_bus_type, &fsl_mc_nb); | 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 | static int __init lp_init(void) | 1020 | static int __init lp_init(void) |
| 1021 | { | 1021 | { |
| 1022 | int i, err = 0; | 1022 | int i, err; |
| 1023 | 1023 | ||
| 1024 | if (parport_nr[0] == LP_PARPORT_OFF) | 1024 | if (parport_nr[0] == LP_PARPORT_OFF) |
| 1025 | return 0; | 1025 | return 0; |
| @@ -87,7 +87,7 @@ static struct fasync_struct *fasync; · 86 unmodified lines | |||
| 87 | 87 | ||
| 88 | /* Control how we warn userspace. */ | 88 | /* Control how we warn userspace. */ |
| 89 | static struct ratelimit_state urandom_warning = | 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 | static int ratelimit_disable __read_mostly = | 91 | static int ratelimit_disable __read_mostly = |
| 92 | IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM); | 92 | IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM); |
| 93 | module_param_named(ratelimit_disable, ratelimit_disable, int, 0644); | 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 | * Immediately overwrite the ChaCha key at index 4 with random | 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 | * forever, so that we still retain forward secrecy in that case. | 412 | * forever, so that we still retain forward secrecy in that case. |
| 413 | */ | 413 | */ |
| 414 | crng_make_state(chacha_state, (u8 *)&chacha_state[4], CHACHA_KEY_SIZE); | 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 | if (new_count & MIX_INFLIGHT) | 1009 | if (new_count & MIX_INFLIGHT) |
| 1010 | return; | 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 | return; | 1013 | return; |
| 1014 | 1014 | ||
| 1015 | if (unlikely(!fast_pool->mix.func)) | 1015 | if (unlikely(!fast_pool->mix.func)) |
| @@ -565,4 +565,3 @@ void __init hv_init_clocksource(void) · 564 unmodified lines | |||
| 565 | hv_sched_clock_offset = hv_read_reference_counter(); | 565 | hv_sched_clock_offset = hv_read_reference_counter(); |
| 566 | hv_setup_sched_clock(read_hv_sched_clock_msr); | 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 | if (!devpriv->usb_rx_buf) | 684 | if (!devpriv->usb_rx_buf) |
| 685 | return -ENOMEM; | 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 | devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); | 688 | devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); |
| 689 | if (!devpriv->usb_tx_buf) | 689 | if (!devpriv->usb_tx_buf) |
| 690 | return -ENOMEM; | 690 | return -ENOMEM; |
| @@ -32,8 +32,11 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) · 31 unmodified lines | |||
| 32 | { | 32 | { |
| 33 | struct vm_area_struct *vma = vmf->vma; | 33 | struct vm_area_struct *vma = vmf->vma; |
| 34 | struct udmabuf *ubuf = vma->vm_private_data; | 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 | get_page(vmf->page); | 40 | get_page(vmf->page); |
| 38 | return 0; | 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 | struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2; | 1211 | struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2; |
| 1212 | struct fw_card *card = client->device->card; | 1212 | struct fw_card *card = client->device->card; |
| 1213 | struct timespec64 ts = {0, 0}; | 1213 | struct timespec64 ts = {0, 0}; |
| 1214 | u32 cycle_time; | 1214 | u32 cycle_time = 0; |
| 1215 | int ret = 0; | 1215 | int ret = 0; |
| 1216 | 1216 | ||
| 1217 | local_irq_disable(); | 1217 | local_irq_disable(); |
| @@ -372,8 +372,7 @@ static ssize_t rom_index_show(struct device *dev, · 371 unmodified lines | |||
| 372 | struct fw_device *device = fw_device(dev->parent); | 372 | struct fw_device *device = fw_device(dev->parent); |
| 373 | struct fw_unit *unit = fw_unit(dev); | 373 | struct fw_unit *unit = fw_unit(dev); |
| 374 | 374 | ||
| 375 | return snprintf(buf, PAGE_SIZE, "%d\n", | 375 | return sysfs_emit(buf, "%td\n", unit->directory - device->config_rom); |
| 376 | (int)(unit->directory - device->config_rom)); | ||
| 377 | } | 376 | } |
| 378 | 377 | ||
| 379 | static struct device_attribute fw_unit_attributes[] = { | 378 | static struct device_attribute fw_unit_attributes[] = { |
| @@ -403,8 +402,7 @@ static ssize_t guid_show(struct device *dev, · 23 unmodified lines | |||
| 403 | int ret; | 402 | int ret; |
| 404 | 403 | ||
| 405 | down_read(&fw_device_rwsem); | 404 | down_read(&fw_device_rwsem); |
| 406 | ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", | 405 | ret = sysfs_emit(buf, "0x%08x%08x\n", device->config_rom[3], device->config_rom[4]); |
| 407 | device->config_rom[3], device->config_rom[4]); | ||
| 408 | up_read(&fw_device_rwsem); | 406 | up_read(&fw_device_rwsem); |
| 409 | 407 | ||
| 410 | return ret; | 408 | return ret; |
| @@ -36,7 +36,7 @@ struct scmi_msg_resp_base_attributes { · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | struct scmi_msg_resp_base_discover_agent { | 37 | struct scmi_msg_resp_base_discover_agent { |
| 38 | __le32 agent_id; | 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 | ret = ph->xops->do_xfer(ph, t); | 120 | ret = ph->xops->do_xfer(ph, t); |
| 121 | if (!ret) | 121 | if (!ret) |
| 122 | memcpy(vendor_id, t->rx.buf, size); | 122 | strscpy(vendor_id, t->rx.buf, size); |
| 123 | 123 | ||
| 124 | ph->xops->xfer_put(ph, t); | 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 | calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) * | 221 | calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) * |
| 222 | sizeof(u32); | 222 | sizeof(u32); |
| 223 | if (calc_list_sz != real_list_sz) { | 223 | if (calc_list_sz != real_list_sz) { |
| 224 | dev_err(dev, | 224 | dev_warn(dev, |
| 225 | "Malformed reply - real_sz:%zd calc_sz:%u\n", | 225 | "Malformed reply - real_sz:%zd calc_sz:%u (loop_num_ret:%d)\n", |
| 226 | real_list_sz, calc_list_sz); | 226 | real_list_sz, calc_list_sz, loop_num_ret); |
| 227 | ret = -EPROTO; | 227 | /* |
| 228 | break; | 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 | for (loop = 0; loop < loop_num_ret; loop++) | 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 | ret = ph->xops->do_xfer(ph, t); | 276 | ret = ph->xops->do_xfer(ph, t); |
| 271 | if (!ret) { | 277 | if (!ret) { |
| 272 | agent_info = t->rx.buf; | 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 | ph->xops->xfer_put(ph, t); | 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 | int id, ret; | 375 | int id, ret; |
| 370 | u8 *prot_imp; | 376 | u8 *prot_imp; |
| 371 | u32 version; | 377 | u32 version; |
| 372 | char name[SCMI_MAX_STR_SIZE]; | 378 | char name[SCMI_SHORT_NAME_MAX_SIZE]; |
| 373 | struct device *dev = ph->dev; | 379 | struct device *dev = ph->dev; |
| 374 | struct scmi_revision_info *rev = scmi_revision_area_get(ph); | 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 | if (!ret) { | 153 | if (!ret) { |
| 154 | u32 latency = 0; | 154 | u32 latency = 0; |
| 155 | attributes = le32_to_cpu(attr->attributes); | 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 | /* clock_enable_latency field is present only since SCMI v3.1 */ | 157 | /* clock_enable_latency field is present only since SCMI v3.1 */ |
| 158 | if (PROTOCOL_REV_MAJOR(version) >= 0x2) | 158 | if (PROTOCOL_REV_MAJOR(version) >= 0x2) |
| 159 | latency = le32_to_cpu(attr->clock_enable_latency); | 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 | struct scmi_clock_info *clk) | 266 | struct scmi_clock_info *clk) |
| 267 | { | 267 | { |
| 268 | int ret; | 268 | int ret; |
| 269 | |||
| 270 | void *iter; | 269 | void *iter; |
| 271 | struct scmi_msg_clock_describe_rates *msg; | ||
| 272 | struct scmi_iterator_ops ops = { | 270 | struct scmi_iterator_ops ops = { |
| 273 | .prepare_message = iter_clk_describe_prepare_message, | 271 | .prepare_message = iter_clk_describe_prepare_message, |
| 274 | .update_state = iter_clk_describe_update_state, | 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 | iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES, | 280 | iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES, |
| 283 | CLOCK_DESCRIBE_RATES, | 281 | CLOCK_DESCRIBE_RATES, |
| 284 | sizeof(*msg), &cpriv); | 282 | sizeof(struct scmi_msg_clock_describe_rates), |
| 283 | &cpriv); | ||
| 285 | if (IS_ERR(iter)) | 284 | if (IS_ERR(iter)) |
| 286 | return PTR_ERR(iter); | 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 | dom_info->mult_factor = | 252 | dom_info->mult_factor = |
| 253 | (dom_info->sustained_freq_khz * 1000) / | 253 | (dom_info->sustained_freq_khz * 1000) / |
| 254 | dom_info->sustained_perf_level; | 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 | ph->xops->xfer_put(ph, t); | 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 | int ret; | 333 | int ret; |
| 334 | void *iter; | 334 | void *iter; |
| 335 | struct scmi_msg_perf_describe_levels *msg; | ||
| 336 | struct scmi_iterator_ops ops = { | 335 | struct scmi_iterator_ops ops = { |
| 337 | .prepare_message = iter_perf_levels_prepare_message, | 336 | .prepare_message = iter_perf_levels_prepare_message, |
| 338 | .update_state = iter_perf_levels_update_state, | 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 | iter = ph->hops->iter_response_init(ph, &ops, MAX_OPPS, | 345 | iter = ph->hops->iter_response_init(ph, &ops, MAX_OPPS, |
| 347 | PERF_DESCRIBE_LEVELS, | 346 | PERF_DESCRIBE_LEVELS, |
| 348 | sizeof(*msg), &ppriv); | 347 | sizeof(struct scmi_msg_perf_describe_levels), |
| 348 | &ppriv); | ||
| 349 | if (IS_ERR(iter)) | 349 | if (IS_ERR(iter)) |
| 350 | return PTR_ERR(iter); | 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 | dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); | 122 | dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); |
| 123 | dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); | 123 | dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); |
| 124 | dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags); | 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 | ph->xops->xfer_put(ph, t); | 127 | ph->xops->xfer_put(ph, t); |
| 128 | 128 | ||
| @@ -24,8 +24,6 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
| 26 | 26 | ||
| 27 | #define SCMI_SHORT_NAME_MAX_SIZE 16 | ||
| 28 | |||
| 29 | #define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0) | 27 | #define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0) |
| 30 | #define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16) | 28 | #define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16) |
| 31 | #define PROTOCOL_REV_MAJOR(x) ((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))) | 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 | dom_info->latency_us = le32_to_cpu(attr->latency); | 116 | dom_info->latency_us = le32_to_cpu(attr->latency); |
| 117 | if (dom_info->latency_us == U32_MAX) | 117 | if (dom_info->latency_us == U32_MAX) |
| 118 | dom_info->latency_us = 0; | 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 | ph->xops->xfer_put(ph, t); | 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 | struct scmi_sensor_info *s) | 338 | struct scmi_sensor_info *s) |
| 339 | { | 339 | { |
| 340 | void *iter; | 340 | void *iter; |
| 341 | struct scmi_msg_sensor_list_update_intervals *msg; | ||
| 342 | struct scmi_iterator_ops ops = { | 341 | struct scmi_iterator_ops ops = { |
| 343 | .prepare_message = iter_intervals_prepare_message, | 342 | .prepare_message = iter_intervals_prepare_message, |
| 344 | .update_state = iter_intervals_update_state, | 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 | iter = ph->hops->iter_response_init(ph, &ops, s->intervals.count, | 351 | iter = ph->hops->iter_response_init(ph, &ops, s->intervals.count, |
| 353 | SENSOR_LIST_UPDATE_INTERVALS, | 352 | SENSOR_LIST_UPDATE_INTERVALS, |
| 354 | sizeof(*msg), &upriv); | 353 | sizeof(struct scmi_msg_sensor_list_update_intervals), |
| 354 | &upriv); | ||
| 355 | if (IS_ERR(iter)) | 355 | if (IS_ERR(iter)) |
| 356 | return PTR_ERR(iter); | 356 | return PTR_ERR(iter); |
| 357 | 357 | ||
| 358 | return ph->hops->iter_response_run(iter); | 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 | static void iter_axes_desc_prepare_message(void *message, | 366 | static void iter_axes_desc_prepare_message(void *message, |
| 362 | const unsigned int desc_index, | 367 | const unsigned int desc_index, |
| 363 | const void *priv) | 368 | const void *priv) |
| 364 | { | 369 | { |
| 365 | struct scmi_msg_sensor_axis_description_get *msg = message; | 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 | /* Set the number of sensors to be skipped/already read */ | 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 | msg->axis_desc_index = cpu_to_le32(desc_index); | 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 | u32 attrh, attrl; | 398 | u32 attrh, attrl; |
| 394 | struct scmi_sensor_axis_info *a; | 399 | struct scmi_sensor_axis_info *a; |
| 395 | size_t dsize = SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ; | 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 | const struct scmi_axis_descriptor *adesc = st->priv; | 402 | const struct scmi_axis_descriptor *adesc = st->priv; |
| 398 | 403 | ||
| 399 | attrl = le32_to_cpu(adesc->attributes_low); | 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 | a->id = le32_to_cpu(adesc->id); | 409 | a->id = le32_to_cpu(adesc->id); |
| 403 | a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl); | 410 | a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl); |
| 404 | 411 | ||
| 405 | attrh = le32_to_cpu(adesc->attributes_high); | 412 | attrh = le32_to_cpu(adesc->attributes_high); |
| 406 | a->scale = S32_EXT(SENSOR_SCALE(attrh)); | 413 | a->scale = S32_EXT(SENSOR_SCALE(attrh)); |
| 407 | a->type = SENSOR_TYPE(attrh); | 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 | if (a->extended_attrs) { | 417 | if (a->extended_attrs) { |
| 411 | unsigned int ares = le32_to_cpu(adesc->resolution); | 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 | void *priv) | 451 | void *priv) |
| 445 | { | 452 | { |
| 446 | struct scmi_sensor_axis_info *a; | 453 | struct scmi_sensor_axis_info *a; |
| 447 | const struct scmi_sensor_info *s = priv; | 454 | const struct scmi_apriv *apriv = priv; |
| 448 | struct scmi_sensor_axis_name_descriptor *adesc = st->priv; | 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 | strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE); | 467 | strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE); |
| 452 | st->priv = ++adesc; | 468 | st->priv = ++adesc; |
| 453 | 469 | ||
| @@ -458,21 +474,36 @@ static int · 4 unmodified lines | |||
| 458 | scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph, | 474 | scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph, |
| 459 | struct scmi_sensor_info *s) | 475 | struct scmi_sensor_info *s) |
| 460 | { | 476 | { |
| 477 | int ret; | ||
| 461 | void *iter; | 478 | void *iter; |
| 462 | struct scmi_msg_sensor_axis_description_get *msg; | ||
| 463 | struct scmi_iterator_ops ops = { | 479 | struct scmi_iterator_ops ops = { |
| 464 | .prepare_message = iter_axes_desc_prepare_message, | 480 | .prepare_message = iter_axes_desc_prepare_message, |
| 465 | .update_state = iter_axes_extended_name_update_state, | 481 | .update_state = iter_axes_extended_name_update_state, |
| 466 | .process_response = iter_axes_extended_name_process_response, | 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 | iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, | 489 | iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, |
| 470 | SENSOR_AXIS_NAME_GET, | 490 | SENSOR_AXIS_NAME_GET, |
| 471 | sizeof(*msg), s); | 491 | sizeof(struct scmi_msg_sensor_axis_description_get), |
| 492 | &apriv); | ||
| 472 | if (IS_ERR(iter)) | 493 | if (IS_ERR(iter)) |
| 473 | return PTR_ERR(iter); | 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 | static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, | 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 | int ret; | 513 | int ret; |
| 483 | void *iter; | 514 | void *iter; |
| 484 | struct scmi_msg_sensor_axis_description_get *msg; | ||
| 485 | struct scmi_iterator_ops ops = { | 515 | struct scmi_iterator_ops ops = { |
| 486 | .prepare_message = iter_axes_desc_prepare_message, | 516 | .prepare_message = iter_axes_desc_prepare_message, |
| 487 | .update_state = iter_axes_desc_update_state, | 517 | .update_state = iter_axes_desc_update_state, |
| 488 | .process_response = iter_axes_desc_process_response, | 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 | s->axis = devm_kcalloc(ph->dev, s->num_axis, | 525 | s->axis = devm_kcalloc(ph->dev, s->num_axis, |
| 492 | sizeof(*s->axis), GFP_KERNEL); | 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 | iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, | 530 | iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, |
| 497 | SENSOR_AXIS_DESCRIPTION_GET, | 531 | SENSOR_AXIS_DESCRIPTION_GET, |
| 498 | sizeof(*msg), s); | 532 | sizeof(struct scmi_msg_sensor_axis_description_get), |
| 533 | &apriv); | ||
| 499 | if (IS_ERR(iter)) | 534 | if (IS_ERR(iter)) |
| 500 | return PTR_ERR(iter); | 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 | if (ret) | 538 | if (ret) |
| 504 | return ret; | 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 | ret = scmi_sensor_axis_extended_names_get(ph, s); | 543 | ret = scmi_sensor_axis_extended_names_get(ph, s); |
| 508 | 544 | ||
| 509 | return ret; | 545 | return ret; |
| @@ -598,7 +634,7 @@ iter_sens_descr_process_response(const struct scmi_protocol_handle *ph, · 88 unmodified lines | |||
| 598 | SUPPORTS_AXIS(attrh) ? | 634 | SUPPORTS_AXIS(attrh) ? |
| 599 | SENSOR_AXIS_NUMBER(attrh) : 0, | 635 | SENSOR_AXIS_NUMBER(attrh) : 0, |
| 600 | SCMI_MAX_NUM_SENSOR_AXIS); | 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 | * If supported overwrite short name with the extended | 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 | int ret; | 181 | int ret; |
| 182 | void *iter; | 182 | void *iter; |
| 183 | struct scmi_msg_cmd_describe_levels *msg; | ||
| 184 | struct scmi_iterator_ops ops = { | 183 | struct scmi_iterator_ops ops = { |
| 185 | .prepare_message = iter_volt_levels_prepare_message, | 184 | .prepare_message = iter_volt_levels_prepare_message, |
| 186 | .update_state = iter_volt_levels_update_state, | 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 | iter = ph->hops->iter_response_init(ph, &ops, v->num_levels, | 193 | iter = ph->hops->iter_response_init(ph, &ops, v->num_levels, |
| 195 | VOLTAGE_DESCRIBE_LEVELS, | 194 | VOLTAGE_DESCRIBE_LEVELS, |
| 196 | sizeof(*msg), &vpriv); | 195 | sizeof(struct scmi_msg_cmd_describe_levels), |
| 196 | &vpriv); | ||
| 197 | if (IS_ERR(iter)) | 197 | if (IS_ERR(iter)) |
| 198 | return PTR_ERR(iter); | 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 | /* Retrieve domain attributes at first ... */ | 226 | /* Retrieve domain attributes at first ... */ |
| 227 | put_unaligned_le32(dom, td->tx.buf); | 227 | put_unaligned_le32(dom, td->tx.buf); |
| 228 | ret = ph->xops->do_xfer(ph, td); | ||
| 229 | /* Skip domain on comms error */ | 228 | /* Skip domain on comms error */ |
| 230 | if (ret) | 229 | if (ph->xops->do_xfer(ph, td)) |
| 231 | continue; | 230 | continue; |
| 232 | 231 | ||
| 233 | v = vinfo->domains + dom; | 232 | v = vinfo->domains + dom; |
| 234 | v->id = dom; | 233 | v->id = dom; |
| 235 | attributes = le32_to_cpu(resp_dom->attr); | 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 | * If supported overwrite short name with the extended one; | 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 | v->async_level_set = true; | 248 | v->async_level_set = true; |
| 250 | } | 249 | } |
| 251 | 250 | ||
| 252 | ret = scmi_voltage_levels_get(ph, v); | ||
| 253 | /* Skip invalid voltage descriptors */ | 251 | /* Skip invalid voltage descriptors */ |
| 254 | if (ret) | 252 | scmi_voltage_levels_get(ph, v); |
| 255 | continue; | ||
| 256 | |||
| 257 | ph->xops->reset_rx_to_maxsz(ph, td); | ||
| 258 | } | 253 | } |
| 259 | 254 | ||
| 260 | ph->xops->xfer_put(ph, td); | 255 | ph->xops->xfer_put(ph, td); |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | #include <linux/sysfb.h> | 26 | #include <linux/sysfb.h> |
| 27 | #include <video/vga.h> | 27 | #include <video/vga.h> |
| 28 | 28 | ||
| 29 | #include <asm/efi.h> | ||
| 30 | |||
| 31 | enum { | 29 | enum { |
| 32 | OVERRIDE_NONE = 0x0, | 30 | OVERRIDE_NONE = 0x0, |
| 33 | OVERRIDE_BASE = 0x1, | 31 | OVERRIDE_BASE = 0x1, |
| @@ -434,25 +434,13 @@ static int grgpio_probe(struct platform_device *ofdev) · 433 unmodified lines | |||
| 434 | static int grgpio_remove(struct platform_device *ofdev) | 434 | static int grgpio_remove(struct platform_device *ofdev) |
| 435 | { | 435 | { |
| 436 | struct grgpio_priv *priv = platform_get_drvdata(ofdev); | 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 | gpiochip_remove(&priv->gc); | 438 | gpiochip_remove(&priv->gc); |
| 450 | 439 | ||
| 451 | if (priv->domain) | 440 | if (priv->domain) |
| 452 | irq_domain_remove(priv->domain); | 441 | irq_domain_remove(priv->domain); |
| 453 | 442 | ||
| 454 | out: | 443 | return 0; |
| 455 | return ret; | ||
| 456 | } | 444 | } |
| 457 | 445 | ||
| 458 | static const struct of_device_id grgpio_match[] = { | 446 | static const struct of_device_id grgpio_match[] = { |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | 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 | // Copyright 2008 Juergen Beisert, kernel@pengutronix.de | 4 | // Copyright 2008 Juergen Beisert, kernel@pengutronix.de |
| 5 | // | 5 | // |
| 6 | // Based on code from Freescale, | 6 | // Based on code from Freescale, |
| @@ -172,6 +172,8 @@ static void realtek_gpio_irq_unmask(struct irq_data *data) · 171 unmodified lines | |||
| 172 | unsigned long flags; | 172 | unsigned long flags; |
| 173 | u16 m; | 173 | u16 m; |
| 174 | 174 | ||
| 175 | gpiochip_enable_irq(&ctrl->gc, line); | ||
| 176 | |||
| 175 | raw_spin_lock_irqsave(&ctrl->lock, flags); | 177 | raw_spin_lock_irqsave(&ctrl->lock, flags); |
| 176 | m = ctrl->intr_mask[port]; | 178 | m = ctrl->intr_mask[port]; |
| 177 | m |= realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK); | 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 | ctrl->intr_mask[port] = m; | 197 | ctrl->intr_mask[port] = m; |
| 196 | realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m); | 198 | realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m); |
| 197 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); | 199 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
| 200 | |||
| 201 | gpiochip_disable_irq(&ctrl->gc, line); | ||
| 198 | } | 202 | } |
| 199 | 203 | ||
| 200 | static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) | 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 | return 0; | 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 | .name = "realtek-otto-gpio", | 323 | .name = "realtek-otto-gpio", |
| 320 | .irq_ack = realtek_gpio_irq_ack, | 324 | .irq_ack = realtek_gpio_irq_ack, |
| 321 | .irq_mask = realtek_gpio_irq_mask, | 325 | .irq_mask = realtek_gpio_irq_mask, |
| 322 | .irq_unmask = realtek_gpio_irq_unmask, | 326 | .irq_unmask = realtek_gpio_irq_unmask, |
| 323 | .irq_set_type = realtek_gpio_irq_set_type, | 327 | .irq_set_type = realtek_gpio_irq_set_type, |
| 324 | .irq_set_affinity = realtek_gpio_irq_set_affinity, | 328 | .irq_set_affinity = realtek_gpio_irq_set_affinity, |
| 329 | .flags = IRQCHIP_IMMUTABLE, | ||
| 330 | GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||
| 325 | }; | 331 | }; |
| 326 | 332 | ||
| 327 | static const struct of_device_id realtek_gpio_of_match[] = { | 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 | irq = platform_get_irq_optional(pdev, 0); | 410 | irq = platform_get_irq_optional(pdev, 0); |
| 405 | if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) { | 411 | if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) { |
| 406 | girq = &ctrl->gc.irq; | 412 | girq = &ctrl->gc.irq; |
| 407 | girq->chip = &realtek_gpio_irq_chip; | 413 | gpio_irq_chip_set_chip(girq, &realtek_gpio_irq_chip); |
| 408 | girq->default_type = IRQ_TYPE_NONE; | 414 | girq->default_type = IRQ_TYPE_NONE; |
| 409 | girq->handler = handle_bad_irq; | 415 | girq->handler = handle_bad_irq; |
| 410 | girq->parent_handler = realtek_gpio_irq_handler; | 416 | girq->parent_handler = realtek_gpio_irq_handler; |
| @@ -217,8 +217,6 @@ static int giu_get_irq(unsigned int irq) · 216 unmodified lines | |||
| 217 | printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", | 217 | printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", |
| 218 | maskl, pendl, maskh, pendh); | 218 | maskl, pendl, maskh, pendh); |
| 219 | 219 | ||
| 220 | atomic_inc(&irq_err_count); | ||
| 221 | |||
| 222 | return -EINVAL; | 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 | unsigned long *base = gpiochip_get_data(gc); | 385 | unsigned long *base = gpiochip_get_data(gc); |
| 386 | const struct winbond_gpio_info *info; | 386 | const struct winbond_gpio_info *info; |
| 387 | bool val; | 387 | bool val; |
| 388 | int ret; | ||
| 388 | 389 | ||
| 389 | winbond_gpio_get_info(&offset, &info); | 390 | winbond_gpio_get_info(&offset, &info); |
| 390 | 391 | ||
| 391 | val = winbond_sio_enter(*base); | 392 | ret = winbond_sio_enter(*base); |
| 392 | if (val) | 393 | if (ret) |
| 393 | return val; | 394 | return ret; |
| 394 | 395 | ||
| 395 | winbond_sio_select_logical(*base, info->dev); | 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 | atomic64_read(&adev->visible_pin_size), | 642 | atomic64_read(&adev->visible_pin_size), |
| 643 | vram_gtt.vram_size); | 643 | vram_gtt.vram_size); |
| 644 | vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size; | 644 | vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size; |
| 645 | vram_gtt.gtt_size *= PAGE_SIZE; | ||
| 646 | vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); | 645 | vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); |
| 647 | return copy_to_user(out, &vram_gtt, | 646 | return copy_to_user(out, &vram_gtt, |
| 648 | min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0; | 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 | mem.cpu_accessible_vram.usable_heap_size * 3 / 4; | 674 | mem.cpu_accessible_vram.usable_heap_size * 3 / 4; |
| 676 | 675 | ||
| 677 | mem.gtt.total_heap_size = gtt_man->size; | 676 | mem.gtt.total_heap_size = gtt_man->size; |
| 678 | mem.gtt.total_heap_size *= PAGE_SIZE; | ||
| 679 | mem.gtt.usable_heap_size = mem.gtt.total_heap_size - | 677 | mem.gtt.usable_heap_size = mem.gtt.total_heap_size - |
| 680 | atomic64_read(&adev->gart_pin_size); | 678 | atomic64_read(&adev->gart_pin_size); |
| 681 | mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man); | 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 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", | 1798 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", |
| 1799 | (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); | 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 | * or whatever the user passed on module init */ | 1802 | * or whatever the user passed on module init */ |
| 1803 | if (amdgpu_gtt_size == -1) { | 1803 | if (amdgpu_gtt_size == -1) { |
| 1804 | struct sysinfo si; | 1804 | struct sysinfo si; |
| 1805 | 1805 | ||
| 1806 | si_meminfo(&si); | 1806 | si_meminfo(&si); |
| 1807 | gtt_size = min(max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20), | 1807 | /* Certain GL unit tests for large textures can cause problems |
| 1808 | adev->gmc.mc_vram_size), | 1808 | * with the OOM killer since there is no way to link this memory |
| 1809 | ((uint64_t)si.totalram * si.mem_unit * 3/4)); | 1809 | * to a process. This was originally mitigated (but not necessarily |
| 1810 | } | 1810 | * eliminated) by limiting the GTT size. The problem is this limit |
| 1811 | else | 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 | gtt_size = (uint64_t)amdgpu_gtt_size << 20; | 1819 | gtt_size = (uint64_t)amdgpu_gtt_size << 20; |
| 1820 | } | ||
| 1813 | 1821 | ||
| 1814 | /* Initialize GTT memory pool */ | 1822 | /* Initialize GTT memory pool */ |
| 1815 | r = amdgpu_gtt_mgr_init(adev, gtt_size); | 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 | static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) | 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 | struct amdgpu_dm_backlight_caps *caps; | 2816 | struct amdgpu_dm_backlight_caps *caps; |
| 2817 | struct amdgpu_display_manager *dm; | 2817 | struct amdgpu_display_manager *dm; |
| 2818 | struct drm_connector *conn_base; | 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 | caps = &dm->backlight_caps[i]; | 2842 | caps = &dm->backlight_caps[i]; |
| 2843 | caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; | 2843 | caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; |
| 2844 | caps->aux_support = false; | 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 | min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; | 2846 | min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; |
| 2847 | 2847 | ||
| 2848 | if (caps->ext_caps->bits.oled == 1 /*|| | 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 | * The results of the above expressions can be verified at | 2870 | * The results of the above expressions can be verified at |
| 2871 | * pre_computed_values. | 2871 | * pre_computed_values. |
| 2872 | */ | 2872 | */ |
| 2873 | q = max_cll >> 5; | 2873 | q = max_avg >> 5; |
| 2874 | r = max_cll % 32; | 2874 | r = max_avg % 32; |
| 2875 | max = (1 << q) * pre_computed_values[r]; | 2875 | max = (1 << q) * pre_computed_values[r]; |
| 2876 | 2876 | ||
| 2877 | // min luminance: maxLum * (CV/255)^2 / 100 | 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 | if (!bw_params->clk_table.entries[i].dtbclk_mhz) | 550 | if (!bw_params->clk_table.entries[i].dtbclk_mhz) |
| 551 | bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz; | 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 | bw_params->vram_type = bios_info->memory_type; | 554 | bw_params->vram_type = bios_info->memory_type; |
| 555 | bw_params->num_channels = bios_info->ma_channel_number; | 555 | bw_params->num_channels = bios_info->ma_channel_number; |
| 556 | if (!bw_params->num_channels) | 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 | return; | 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 | if (lt_settings->voltage_swing) | 948 | if (lt_settings->voltage_swing) |
| 949 | lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing; | 949 | lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing; |
| 950 | if (lt_settings->pre_emphasis) | 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 | break; | 1766 | break; |
| 1767 | } | 1767 | } |
| 1768 | } | 1768 | } |
| 1769 | 1769 | // We are trying to enable eDP, don't power down VDD | |
| 1770 | /* | 1770 | if (can_apply_edp_fast_boot) |
| 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) { | ||
| 1787 | keep_edp_vdd_on = true; | 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 | // Check seamless boot support | 1774 | // Check seamless boot support |
| @@ -212,6 +212,9 @@ static void dpp2_cnv_setup ( · 211 unmodified lines | |||
| 212 | break; | 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 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { | 218 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { |
| 216 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); | 219 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); |
| 217 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); | 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 | break; | 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 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { | 159 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { |
| 157 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); | 160 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); |
| 158 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); | 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 | break; | 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 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { | 300 | if (is_2bit == 1 && alpha_2bit_lut != NULL) { |
| 298 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); | 301 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); |
| 299 | REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); | 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 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"), | 152 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"), |
| 153 | }, | 153 | }, |
| 154 | .driver_data = (void *)&lcd800x1280_rightside_up, | 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 | }, { /* Chuwi HiBook (CWI514) */ | 161 | }, { /* Chuwi HiBook (CWI514) */ |
| 156 | .matches = { | 162 | .matches = { |
| 157 | DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), | 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 | DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), | 177 | DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), |
| 178 | DRM_COMPONENT_DRIVER | 178 | DRM_COMPONENT_DRIVER |
| 179 | }, { | ||
| 180 | DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), | ||
| 181 | DRM_COMPONENT_DRIVER | ||
| 182 | }, { | 179 | }, { |
| 183 | DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP), | 180 | DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP), |
| 184 | DRM_COMPONENT_DRIVER | 181 | DRM_COMPONENT_DRIVER |
| 185 | }, { | 182 | }, { |
| 186 | DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI), | 183 | DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI), |
| 187 | DRM_COMPONENT_DRIVER | 184 | DRM_COMPONENT_DRIVER |
| 185 | }, { | ||
| 186 | DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), | ||
| 187 | DRM_COMPONENT_DRIVER | ||
| 188 | }, { | 188 | }, { |
| 189 | DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI), | 189 | DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI), |
| 190 | DRM_COMPONENT_DRIVER | 190 | DRM_COMPONENT_DRIVER |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <drm/drm_print.h> | 26 | #include <drm/drm_print.h> |
| 27 | 27 | ||
| 28 | #include "exynos_drm_drv.h" | 28 | #include "exynos_drm_drv.h" |
| 29 | #include "exynos_drm_crtc.h" | ||
| 29 | 30 | ||
| 30 | /* Sysreg registers for MIC */ | 31 | /* Sysreg registers for MIC */ |
| 31 | #define DSD_CFG_MUX 0x1004 | 32 | #define DSD_CFG_MUX 0x1004 |
| @@ -100,9 +101,7 @@ struct exynos_mic { · 68 unmodified lines | |||
| 100 | 101 | ||
| 101 | bool i80_mode; | 102 | bool i80_mode; |
| 102 | struct videomode vm; | 103 | struct videomode vm; |
| 103 | struct drm_encoder *encoder; | ||
| 104 | struct drm_bridge bridge; | 104 | struct drm_bridge bridge; |
| 105 | struct drm_bridge *next_bridge; | ||
| 106 | 105 | ||
| 107 | bool enabled; | 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 | writel(reg, mic->reg + MIC_OP); | 228 | writel(reg, mic->reg + MIC_OP); |
| 230 | } | 229 | } |
| 231 | 230 | ||
| 232 | static void mic_disable(struct drm_bridge *bridge) { } | ||
| 233 | |||
| 234 | static void mic_post_disable(struct drm_bridge *bridge) | 231 | static void mic_post_disable(struct drm_bridge *bridge) |
| 235 | { | 232 | { |
| 236 | struct exynos_mic *mic = bridge->driver_private; | 233 | struct exynos_mic *mic = bridge->driver_private; |
| @@ -297,34 +294,30 @@ unlock: · 60 unmodified lines | |||
| 297 | mutex_unlock(&mic_mutex); | 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 | static const struct drm_bridge_funcs mic_bridge_funcs = { | 297 | static const struct drm_bridge_funcs mic_bridge_funcs = { |
| 312 | .disable = mic_disable, | ||
| 313 | .post_disable = mic_post_disable, | 298 | .post_disable = mic_post_disable, |
| 314 | .mode_set = mic_mode_set, | 299 | .mode_set = mic_mode_set, |
| 315 | .pre_enable = mic_pre_enable, | 300 | .pre_enable = mic_pre_enable, |
| 316 | .enable = mic_enable, | ||
| 317 | .attach = mic_attach, | ||
| 318 | }; | 301 | }; |
| 319 | 302 | ||
| 320 | static int exynos_mic_bind(struct device *dev, struct device *master, | 303 | static int exynos_mic_bind(struct device *dev, struct device *master, |
| 321 | void *data) | 304 | void *data) |
| 322 | { | 305 | { |
| 323 | struct exynos_mic *mic = dev_get_drvdata(dev); | 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 | mic->bridge.driver_private = mic; | 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 | static void exynos_mic_unbind(struct device *dev, struct device *master, | 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 | struct device *dev = &pdev->dev; | 382 | struct device *dev = &pdev->dev; |
| 390 | struct exynos_mic *mic; | 383 | struct exynos_mic *mic; |
| 391 | struct device_node *remote; | ||
| 392 | struct resource res; | 384 | struct resource res; |
| 393 | int ret, i; | 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 | platform_set_drvdata(pdev, mic); | 427 | platform_set_drvdata(pdev, mic); |
| 446 | 428 | ||
| 447 | mic->bridge.funcs = &mic_bridge_funcs; | 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 | return intel_dp_is_edp(intel_dp) ? 810000 : 1350000; | 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 | static int icl_max_source_rate(struct intel_dp *intel_dp) | 400 | static int icl_max_source_rate(struct intel_dp *intel_dp) |
| 392 | { | 401 | { |
| 393 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 402 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 394 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | 403 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
| 395 | enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); | 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 | return 540000; | 408 | return 540000; |
| 399 | 409 | ||
| 400 | return 810000; | 410 | return 810000; |
| @@ -402,7 +412,23 @@ static int icl_max_source_rate(struct intel_dp *intel_dp) · 1 unmodified line | |||
| 402 | 412 | ||
| 403 | static int ehl_max_source_rate(struct intel_dp *intel_dp) | 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 | return 540000; | 432 | return 540000; |
| 407 | 433 | ||
| 408 | return 810000; | 434 | return 810000; |
| @@ -445,7 +471,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) · 36 unmodified lines | |||
| 445 | max_rate = dg2_max_source_rate(intel_dp); | 471 | max_rate = dg2_max_source_rate(intel_dp); |
| 446 | else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) || | 472 | else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) || |
| 447 | IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) | 473 | IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) |
| 448 | max_rate = 810000; | 474 | max_rate = dg1_max_source_rate(intel_dp); |
| 449 | else if (IS_JSL_EHL(dev_priv)) | 475 | else if (IS_JSL_EHL(dev_priv)) |
| 450 | max_rate = ehl_max_source_rate(intel_dp); | 476 | max_rate = ehl_max_source_rate(intel_dp); |
| 451 | else | 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 | * Program half of the nominal DCO divider fraction value. | 2400 | * Program half of the nominal DCO divider fraction value. |
| 2401 | */ | 2401 | */ |
| 2402 | static bool | 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 | return ((IS_PLATFORM(i915, INTEL_ELKHARTLAKE) && | 2405 | return ((IS_PLATFORM(i915, INTEL_ELKHARTLAKE) && |
| 2406 | IS_JSL_EHL_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) || | 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 | i915->dpll.ref_clks.nssc == 38400; | 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 | if (err) | 1004 | if (err) |
| 1004 | return err; | 1005 | return err; |
| 1005 | 1006 | ||
| @@ -785,6 +785,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt) · 784 unmodified lines | |||
| 785 | { | 785 | { |
| 786 | intel_wakeref_t wakeref; | 786 | intel_wakeref_t wakeref; |
| 787 | 787 | ||
| 788 | intel_gt_sysfs_unregister(gt); | ||
| 788 | intel_rps_driver_unregister(>->rps); | 789 | intel_rps_driver_unregister(>->rps); |
| 789 | intel_gsc_fini(>->gsc); | 790 | intel_gsc_fini(>->gsc); |
| 790 | 791 | ||
| @@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj) · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | static struct intel_gt *kobj_to_gt(struct kobject *kobj) | 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 | struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, | 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 | ATTRIBUTE_GROUPS(id); | 73 | ATTRIBUTE_GROUPS(id); |
| 74 | 74 | ||
| 75 | /* A kobject needs a release() method even if it does nothing */ | ||
| 75 | static void kobj_gt_release(struct kobject *kobj) | 76 | static void kobj_gt_release(struct kobject *kobj) |
| 76 | { | 77 | { |
| 77 | kfree(kobj); | ||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static struct kobj_type kobj_gt_type = { | 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 | void intel_gt_sysfs_register(struct intel_gt *gt) | 86 | void intel_gt_sysfs_register(struct intel_gt *gt) |
| 87 | { | 87 | { |
| 88 | struct kobj_gt *kg; | ||
| 89 | |||
| 90 | /* | 88 | /* |
| 91 | * We need to make things right with the | 89 | * We need to make things right with the |
| 92 | * ABI compatibility. The files were originally | 90 | * ABI compatibility. The files were originally |
| @@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt) · 5 unmodified lines | |||
| 98 | if (gt_is_root(gt)) | 96 | if (gt_is_root(gt)) |
| 99 | intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt)); | 97 | intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt)); |
| 100 | 98 | ||
| 101 | kg = kzalloc(sizeof(*kg), GFP_KERNEL); | 99 | /* init and xfer ownership to sysfs tree */ |
| 102 | if (!kg) | 100 | if (kobject_init_and_add(>->sysfs_gt, &kobj_gt_type, |
| 101 | gt->i915->sysfs_gt, "gt%d", gt->info.id)) | ||
| 103 | goto exit_fail; | 102 | goto exit_fail; |
| 104 | 103 | ||
| 105 | kobject_init(&kg->base, &kobj_gt_type); | 104 | intel_gt_sysfs_pm_init(gt, >->sysfs_gt); |
| 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); | ||
| 113 | 105 | ||
| 114 | return; | 106 | return; |
| 115 | 107 | ||
| 116 | exit_kobj_put: | ||
| 117 | kobject_put(&kg->base); | ||
| 118 | |||
| 119 | exit_fail: | 108 | exit_fail: |
| 109 | kobject_put(>->sysfs_gt); | ||
| 120 | drm_warn(>->i915->drm, | 110 | drm_warn(>->i915->drm, |
| 121 | "failed to initialize gt%d sysfs root\n", gt->info.id); | 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 | struct intel_gt; | 14 | struct intel_gt; |
| 15 | 15 | ||
| 16 | struct kobj_gt { | ||
| 17 | struct kobject base; | ||
| 18 | struct intel_gt *gt; | ||
| 19 | }; | ||
| 20 | |||
| 21 | bool is_object_gt(struct kobject *kobj); | 16 | bool is_object_gt(struct kobject *kobj); |
| 22 | 17 | ||
| 23 | struct drm_i915_private *kobj_to_i915(struct kobject *kobj); | 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 | const char *name); | 23 | const char *name); |
| 29 | 24 | ||
| 30 | void intel_gt_sysfs_register(struct intel_gt *gt); | 25 | void intel_gt_sysfs_register(struct intel_gt *gt); |
| 26 | void intel_gt_sysfs_unregister(struct intel_gt *gt); | ||
| 31 | struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, | 27 | struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, |
| 32 | const char *name); | 28 | const char *name); |
| 33 | 29 | ||
| @@ -224,6 +224,9 @@ struct intel_gt { · 223 unmodified lines | |||
| 224 | } mocs; | 224 | } mocs; |
| 225 | 225 | ||
| 226 | struct intel_pxp pxp; | 226 | struct intel_pxp pxp; |
| 227 | |||
| 228 | /* gt/gtN sysfs */ | ||
| 229 | struct kobject sysfs_gt; | ||
| 227 | }; | 230 | }; |
| 228 | 231 | ||
| 229 | enum intel_gt_scratch_field { | 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 | [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) }, | 156 | [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) }, |
| 157 | [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) }, | 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 | enum intel_platform p = INTEL_INFO(i915)->platform; | 160 | enum intel_platform p = INTEL_INFO(i915)->platform; |
| 161 | u32 fw_count; | 161 | u32 fw_count; |
| 162 | u8 rev = INTEL_REVID(i915); | 162 | u8 rev = INTEL_REVID(i915); |
| @@ -116,8 +116,9 @@ show_client_class(struct seq_file *m, · 115 unmodified lines | |||
| 116 | total += busy_add(ctx, class); | 116 | total += busy_add(ctx, class); |
| 117 | rcu_read_unlock(); | 117 | rcu_read_unlock(); |
| 118 | 118 | ||
| 119 | seq_printf(m, "drm-engine-%s:\t%llu ns\n", | 119 | if (capacity) |
| 120 | uabi_class_names[class], total); | 120 | seq_printf(m, "drm-engine-%s:\t%llu ns\n", |
| 121 | uabi_class_names[class], total); | ||
| 121 | 122 | ||
| 122 | if (capacity > 1) | 123 | if (capacity > 1) |
| 123 | seq_printf(m, "drm-engine-capacity-%s:\t%u\n", | 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 | struct device *kdev = kobj_to_dev(kobj); | 166 | struct device *kdev = kobj_to_dev(kobj); |
| 167 | struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); | 167 | struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); |
| 168 | struct i915_gpu_coredump *gpu; | 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 | gpu = i915_first_error_state(i915); | 178 | gpu = i915_first_error_state(i915); |
| 172 | if (IS_ERR(gpu)) { | 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 | const char *str = "No error state collected\n"; | 185 | const char *str = "No error state collected\n"; |
| 179 | size_t len = strlen(str); | 186 | size_t len = strlen(str); |
| 180 | 187 | ||
| 181 | ret = min_t(size_t, count, len - off); | 188 | if (off < len) { |
| 182 | memcpy(buf, str + off, ret); | 189 | ret = min_t(size_t, count, len - off); |
| 190 | memcpy(buf, str + off, ret); | ||
| 191 | } | ||
| 183 | } | 192 | } |
| 184 | 193 | ||
| 185 | return ret; | 194 | return ret; |
| @@ -259,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv) · 73 unmodified lines | |||
| 259 | 268 | ||
| 260 | device_remove_bin_file(kdev, &dpf_attrs_1); | 269 | device_remove_bin_file(kdev, &dpf_attrs_1); |
| 261 | device_remove_bin_file(kdev, &dpf_attrs); | 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 | #include <linux/sched/mm.h> | 25 | #include <linux/sched/mm.h> |
| 26 | #include <linux/dma-fence-array.h> | ||
| 26 | #include <drm/drm_gem.h> | 27 | #include <drm/drm_gem.h> |
| 27 | 28 | ||
| 28 | #include "display/intel_frontbuffer.h" | 29 | #include "display/intel_frontbuffer.h" |
| @@ -1823,6 +1824,21 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 1794 unmodified lines | |||
| 1823 | if (unlikely(err)) | 1824 | if (unlikely(err)) |
| 1824 | return err; | 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 | if (flags & EXEC_OBJECT_WRITE) { | 1842 | if (flags & EXEC_OBJECT_WRITE) { |
| 1827 | struct intel_frontbuffer *front; | 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 | i915_active_add_request(&front->write, rq); | 1848 | i915_active_add_request(&front->write, rq); |
| 1833 | intel_frontbuffer_put(front); | 1849 | intel_frontbuffer_put(front); |
| 1834 | } | 1850 | } |
| 1851 | } | ||
| 1835 | 1852 | ||
| 1836 | if (!(flags & __EXEC_OBJECT_NO_RESERVE)) { | 1853 | if (fence) { |
| 1837 | err = dma_resv_reserve_fences(vma->obj->base.resv, 1); | 1854 | struct dma_fence *curr; |
| 1838 | if (unlikely(err)) | 1855 | enum dma_resv_usage usage; |
| 1839 | return err; | 1856 | int idx; |
| 1840 | } | ||
| 1841 | 1857 | ||
| 1842 | if (fence) { | 1858 | obj->read_domains = 0; |
| 1843 | dma_resv_add_fence(vma->obj->base.resv, fence, | 1859 | if (flags & EXEC_OBJECT_WRITE) { |
| 1844 | DMA_RESV_USAGE_WRITE); | 1860 | usage = DMA_RESV_USAGE_WRITE; |
| 1845 | obj->write_domain = I915_GEM_DOMAIN_RENDER; | 1861 | obj->write_domain = I915_GEM_DOMAIN_RENDER; |
| 1846 | obj->read_domains = 0; | 1862 | } else { |
| 1847 | } | 1863 | usage = DMA_RESV_USAGE_READ; |
| 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; | ||
| 1853 | } | 1864 | } |
| 1854 | 1865 | ||
| 1855 | if (fence) { | 1866 | dma_fence_array_for_each(curr, idx, fence) |
| 1856 | dma_resv_add_fence(vma->obj->base.resv, fence, | 1867 | dma_resv_add_fence(vma->obj->base.resv, curr, usage); |
| 1857 | DMA_RESV_USAGE_READ); | ||
| 1858 | obj->write_domain = 0; | ||
| 1859 | } | ||
| 1860 | } | 1868 | } |
| 1861 | 1869 | ||
| 1862 | if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence) | 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 | ring->cur = ring->start; | 499 | ring->cur = ring->start; |
| 500 | ring->next = ring->start; | 500 | ring->next = ring->start; |
| 501 | |||
| 502 | /* reset completed fence seqno: */ | ||
| 503 | ring->memptrs->fence = ring->fctx->completed_fence; | ||
| 504 | ring->memptrs->rptr = 0; | 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 | return 0; | 512 | return 0; |
| @@ -1057,7 +1062,8 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) · 549 unmodified lines | |||
| 1057 | for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) | 1062 | for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) |
| 1058 | release_firmware(adreno_gpu->fw[i]); | 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 | msm_gpu_cleanup(&adreno_gpu->base); | 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 | struct msm_drm_private *priv = dev->dev_private; | 11 | struct msm_drm_private *priv = dev->dev_private; |
| 12 | struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); | 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 | dev->mode_config.max_height); | 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 | encoder = mdp4_lcdc_encoder_init(dev, panel_node); | 216 | encoder = mdp4_lcdc_encoder_init(dev, panel_node); |
| 217 | if (IS_ERR(encoder)) { | 217 | if (IS_ERR(encoder)) { |
| 218 | DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); | 218 | DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); |
| 219 | of_node_put(panel_node); | ||
| 219 | return PTR_ERR(encoder); | 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 | connector = mdp4_lvds_connector_init(dev, panel_node, encoder); | 226 | connector = mdp4_lvds_connector_init(dev, panel_node, encoder); |
| 226 | if (IS_ERR(connector)) { | 227 | if (IS_ERR(connector)) { |
| 227 | DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); | 228 | DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); |
| 229 | of_node_put(panel_node); | ||
| 228 | return PTR_ERR(connector); | 230 | return PTR_ERR(connector); |
| 229 | } | 231 | } |
| 230 | 232 | ||
| @@ -1534,6 +1534,8 @@ end: · 1533 unmodified lines | |||
| 1534 | return ret; | 1534 | return ret; |
| 1535 | } | 1535 | } |
| 1536 | 1536 | ||
| 1537 | static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl); | ||
| 1538 | |||
| 1537 | static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) | 1539 | static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) |
| 1538 | { | 1540 | { |
| 1539 | int ret = 0; | 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 | ret = dp_ctrl_on_link(&ctrl->dp_ctrl); | 1560 | ret = dp_ctrl_on_link(&ctrl->dp_ctrl); |
| 1559 | if (!ret) | 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 | else | 1563 | else |
| 1562 | DRM_ERROR("failed to enable DP link controller\n"); | 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 | return dp_ctrl_setup_main_link(ctrl, &training_step); | 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 | int ret = 0; | 1840 | int ret = 0; |
| 1819 | bool mainlink_ready = false; | 1841 | bool mainlink_ready = false; |
| @@ -1849,12 +1871,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) · 29 unmodified lines | |||
| 1849 | goto end; | 1871 | goto end; |
| 1850 | } | 1872 | } |
| 1851 | 1873 | ||
| 1852 | if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { | 1874 | if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl)) |
| 1853 | dp_ctrl_send_phy_test_pattern(ctrl); | ||
| 1854 | return 0; | ||
| 1855 | } | ||
| 1856 | |||
| 1857 | if (!dp_ctrl_channel_eq_ok(ctrl)) | ||
| 1858 | dp_ctrl_link_retrain(ctrl); | 1875 | dp_ctrl_link_retrain(ctrl); |
| 1859 | 1876 | ||
| 1860 | /* stop txing train pattern to end link training */ | 1877 | /* stop txing train pattern to end link training */ |
| @@ -21,7 +21,7 @@ struct dp_ctrl { · 20 unmodified lines | |||
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); | 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 | int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); | 25 | int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); |
| 26 | int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl); | 26 | int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl); |
| 27 | int dp_ctrl_off(struct dp_ctrl *dp_ctrl); | 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 | struct msm_drm_private *priv = dev_get_drvdata(master); | 309 | struct msm_drm_private *priv = dev_get_drvdata(master); |
| 310 | 310 | ||
| 311 | /* disable all HPD interrupts */ | 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 | kthread_stop(dp->ev_tsk); | 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 | return 0; | 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 | if (!rc) | 877 | if (!rc) |
| 877 | dp_display->power_on = true; | 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 | int rc = 0; | 1660 | int rc = 0; |
| 1660 | struct dp_display_private *dp_display; | 1661 | struct dp_display_private *dp_display; |
| 1661 | u32 state; | 1662 | u32 state; |
| 1663 | bool force_link_train = false; | ||
| 1662 | 1664 | ||
| 1663 | dp_display = container_of(dp, struct dp_display_private, dp_display); | 1665 | dp_display = container_of(dp, struct dp_display_private, dp_display); |
| 1664 | if (!dp_display->dp_mode.drm_mode.clock) { | 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 | state = dp_display->hpd_state; | 1696 | state = dp_display->hpd_state; |
| 1695 | 1697 | ||
| 1696 | if (state == ST_DISPLAY_OFF) | 1698 | if (state == ST_DISPLAY_OFF) { |
| 1697 | dp_display_host_phy_init(dp_display); | 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 | rc = dp_display_post_enable(dp); | 1705 | rc = dp_display_post_enable(dp); |
| 1702 | if (rc) { | 1706 | if (rc) { |
| @@ -1705,10 +1709,6 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) · 2 unmodified lines | |||
| 1705 | dp_display_unprepare(dp); | 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 | /* completed connection */ | 1712 | /* completed connection */ |
| 1713 | dp_display->hpd_state = ST_CONNECTED; | 1713 | dp_display->hpd_state = ST_CONNECTED; |
| 1714 | 1714 | ||
| @@ -964,7 +964,7 @@ static const struct drm_driver msm_driver = { · 963 unmodified lines | |||
| 964 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | 964 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
| 965 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | 965 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, |
| 966 | .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, | 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 | #ifdef CONFIG_DEBUG_FS | 968 | #ifdef CONFIG_DEBUG_FS |
| 969 | .debugfs_init = msm_debugfs_init, | 969 | .debugfs_init = msm_debugfs_init, |
| 970 | #endif | 970 | #endif |
| @@ -246,6 +246,7 @@ unsigned long msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_t · 245 unmodified lines | |||
| 246 | void msm_gem_shrinker_init(struct drm_device *dev); | 246 | void msm_gem_shrinker_init(struct drm_device *dev); |
| 247 | void msm_gem_shrinker_cleanup(struct drm_device *dev); | 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 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj); | 250 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj); |
| 250 | int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map); | 251 | int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map); |
| 251 | void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map); | 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 | (int32_t)(*fctx->fenceptr - fence) >= 0; | 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 | void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence) | 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 | fctx->completed_fence = max(fence, fctx->completed_fence); | 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 | struct msm_fence { | 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 | return ret; | 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 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 444 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 445 | 445 | ||
| 446 | GEM_WARN_ON(!msm_gem_is_locked(obj)); | 446 | GEM_WARN_ON(!msm_gem_is_locked(obj)); |
| 447 | 447 | ||
| 448 | msm_gem_unpin_vma(vma); | ||
| 449 | |||
| 450 | msm_obj->pin_count--; | 448 | msm_obj->pin_count--; |
| 451 | GEM_WARN_ON(msm_obj->pin_count < 0); | 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 | msm_gem_lock(obj); | 584 | msm_gem_lock(obj); |
| 587 | vma = lookup_vma(obj, aspace); | 585 | vma = lookup_vma(obj, aspace); |
| 588 | if (!GEM_WARN_ON(!vma)) { | 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 | msm_gem_unlock(obj); | 590 | msm_gem_unlock(obj); |
| 592 | } | 591 | } |
| @@ -145,7 +145,7 @@ struct msm_gem_object { · 144 unmodified lines | |||
| 145 | 145 | ||
| 146 | uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); | 146 | uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); |
| 147 | int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma); | 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 | struct msm_gem_vma *msm_gem_get_vma_locked(struct drm_gem_object *obj, | 149 | struct msm_gem_vma *msm_gem_get_vma_locked(struct drm_gem_object *obj, |
| 150 | struct msm_gem_address_space *aspace); | 150 | struct msm_gem_address_space *aspace); |
| 151 | int msm_gem_get_iova(struct drm_gem_object *obj, | 151 | int msm_gem_get_iova(struct drm_gem_object *obj, |
| @@ -377,10 +377,11 @@ struct msm_gem_submit { · 225 unmodified lines | |||
| 377 | } *cmd; /* array of size nr_cmds */ | 377 | } *cmd; /* array of size nr_cmds */ |
| 378 | struct { | 378 | struct { |
| 379 | /* make sure these don't conflict w/ MSM_SUBMIT_BO_x */ | 379 | /* make sure these don't conflict w/ MSM_SUBMIT_BO_x */ |
| 380 | #define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */ | 380 | #define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */ |
| 381 | #define BO_LOCKED 0x4000 /* obj lock is held */ | 381 | #define BO_LOCKED 0x4000 /* obj lock is held */ |
| 382 | #define BO_ACTIVE 0x2000 /* active refcnt is held */ | 382 | #define BO_ACTIVE 0x2000 /* active refcnt is held */ |
| 383 | #define BO_PINNED 0x1000 /* obj is pinned and on active list */ | 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 | uint32_t flags; | 385 | uint32_t flags; |
| 385 | union { | 386 | union { |
| 386 | struct msm_gem_object *obj; | 387 | struct msm_gem_object *obj; |
| @@ -11,6 +11,21 @@ · 10 unmodified lines | |||
| 11 | #include "msm_drv.h" | 11 | #include "msm_drv.h" |
| 12 | #include "msm_gem.h" | 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 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) | 29 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) |
| 15 | { | 30 | { |
| 16 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 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 | submit->bos[i].flags &= ~cleanup_flags; | 233 | submit->bos[i].flags &= ~cleanup_flags; |
| 234 | 234 | ||
| 235 | if (flags & BO_PINNED) | 235 | if (flags & BO_VMA_PINNED) |
| 236 | msm_gem_unpin_vma_locked(obj, submit->bos[i].vma); | 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 | if (flags & BO_ACTIVE) | 241 | if (flags & BO_ACTIVE) |
| 239 | msm_gem_active_put(obj); | 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 | static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) | 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 | if (!(submit->bos[i].flags & BO_VALID)) | 254 | if (!(submit->bos[i].flags & BO_VALID)) |
| 250 | submit->bos[i].iova = 0; | 255 | submit->bos[i].iova = 0; |
| @@ -375,7 +380,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 124 unmodified lines | |||
| 375 | if (ret) | 380 | if (ret) |
| 376 | break; | 381 | break; |
| 377 | 382 | ||
| 378 | submit->bos[i].flags |= BO_PINNED; | 383 | submit->bos[i].flags |= BO_OBJ_PINNED | BO_VMA_PINNED; |
| 379 | submit->bos[i].vma = vma; | 384 | submit->bos[i].vma = vma; |
| 380 | 385 | ||
| 381 | if (vma->iova == submit->bos[i].iova) { | 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 | unsigned i; | 516 | unsigned i; |
| 512 | 517 | ||
| 513 | if (error) | 518 | if (error) |
| 514 | cleanup_flags |= BO_PINNED | BO_ACTIVE; | 519 | cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED | BO_ACTIVE; |
| 515 | 520 | ||
| 516 | for (i = 0; i < submit->nr_bos; i++) { | 521 | for (i = 0; i < submit->nr_bos; i++) { |
| 517 | struct msm_gem_object *msm_obj = submit->bos[i].obj; | 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 | struct drm_gem_object *obj = &submit->bos[i].obj->base; | 534 | struct drm_gem_object *obj = &submit->bos[i].obj->base; |
| 530 | 535 | ||
| 531 | msm_gem_lock(obj); | 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 | msm_gem_unlock(obj); | 539 | msm_gem_unlock(obj); |
| 534 | drm_gem_object_put(obj); | 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 | unsigned size = vma->node.size; | 62 | unsigned size = vma->node.size; |
| 63 | 63 | ||
| 64 | /* Print a message if we try to purge a vma in use */ | 64 | /* Print a message if we try to purge a vma in use */ |
| 65 | if (GEM_WARN_ON(msm_gem_vma_inuse(vma))) | 65 | GEM_WARN_ON(msm_gem_vma_inuse(vma)); |
| 66 | return; | ||
| 67 | 66 | ||
| 68 | /* Don't do anything if the memory isn't mapped */ | 67 | /* Don't do anything if the memory isn't mapped */ |
| 69 | if (!vma->mapped) | 68 | if (!vma->mapped) |
| @@ -128,8 +127,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, · 58 unmodified lines | |||
| 128 | void msm_gem_close_vma(struct msm_gem_address_space *aspace, | 127 | void msm_gem_close_vma(struct msm_gem_address_space *aspace, |
| 129 | struct msm_gem_vma *vma) | 128 | struct msm_gem_vma *vma) |
| 130 | { | 129 | { |
| 131 | if (GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped)) | 130 | GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped); |
| 132 | return; | ||
| 133 | 131 | ||
| 134 | spin_lock(&aspace->lock); | 132 | spin_lock(&aspace->lock); |
| 135 | if (vma->iova) | 133 | if (vma->iova) |
| @@ -164,24 +164,6 @@ int msm_gpu_hw_init(struct msm_gpu *gpu) · 163 unmodified lines | |||
| 164 | return ret; | 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 | #ifdef CONFIG_DEV_COREDUMP | 167 | #ifdef CONFIG_DEV_COREDUMP |
| 186 | static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset, | 168 | static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset, |
| 187 | size_t count, void *data, size_t datalen) | 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 | * one more to clear the faulting submit | 418 | * one more to clear the faulting submit |
| 437 | */ | 419 | */ |
| 438 | if (ring == cur_ring) | 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 | if (msm_gpu_active(gpu)) { | 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 | msm_submit_retire(submit); | 654 | msm_submit_retire(submit); |
| 673 | 655 | ||
| 674 | pm_runtime_mark_last_busy(&gpu->pdev->dev); | 656 | pm_runtime_mark_last_busy(&gpu->pdev->dev); |
| 675 | pm_runtime_put_autosuspend(&gpu->pdev->dev); | ||
| 676 | 657 | ||
| 677 | spin_lock_irqsave(&ring->submit_lock, flags); | 658 | spin_lock_irqsave(&ring->submit_lock, flags); |
| 678 | list_del(&submit->node); | 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 | msm_devfreq_idle(gpu); | 667 | msm_devfreq_idle(gpu); |
| 687 | mutex_unlock(&gpu->active_lock); | 668 | mutex_unlock(&gpu->active_lock); |
| 688 | 669 | ||
| 670 | pm_runtime_put_autosuspend(&gpu->pdev->dev); | ||
| 671 | |||
| 689 | msm_gem_submit_put(submit); | 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 | int i; | 718 | int i; |
| 736 | 719 | ||
| 737 | for (i = 0; i < gpu->nr_rings; i++) | 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 | kthread_queue_work(gpu->worker, &gpu->retire_work); | 723 | kthread_queue_work(gpu->worker, &gpu->retire_work); |
| 741 | update_sw_cntrs(gpu); | 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 | u64 addr = iova; | 58 | u64 addr = iova; |
| 59 | unsigned int i; | 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 | size_t size = sg->length; | 62 | size_t size = sg->length; |
| 63 | phys_addr_t phys = sg_phys(sg); | 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 | msm_gem_lock(obj); | 26 | msm_gem_lock(obj); |
| 27 | msm_gem_unpin_vma_fenced(submit->bos[i].vma, fctx); | 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 | msm_gem_unlock(obj); | 29 | msm_gem_unlock(obj); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/component.h> | 9 | #include <linux/component.h> |
| 10 | #include <linux/dma-mapping.h> | ||
| 10 | #include <linux/kfifo.h> | 11 | #include <linux/kfifo.h> |
| 11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 12 | #include <linux/of_graph.h> | 13 | #include <linux/of_graph.h> |
| @@ -73,7 +74,6 @@ static int sun4i_drv_bind(struct device *dev) · 60 unmodified lines | |||
| 73 | goto free_drm; | 74 | goto free_drm; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | dev_set_drvdata(dev, drm); | ||
| 77 | drm->dev_private = drv; | 77 | drm->dev_private = drv; |
| 78 | INIT_LIST_HEAD(&drv->frontend_list); | 78 | INIT_LIST_HEAD(&drv->frontend_list); |
| 79 | INIT_LIST_HEAD(&drv->engine_list); | 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 | drm_fbdev_generic_setup(drm, 32); | 115 | drm_fbdev_generic_setup(drm, 32); |
| 116 | 116 | ||
| 117 | dev_set_drvdata(dev, drm); | ||
| 118 | |||
| 117 | return 0; | 119 | return 0; |
| 118 | 120 | ||
| 119 | finish_poll: | 121 | finish_poll: |
| @@ -130,6 +132,7 @@ static void sun4i_drv_unbind(struct device *dev) · 10 unmodified lines | |||
| 130 | { | 132 | { |
| 131 | struct drm_device *drm = dev_get_drvdata(dev); | 133 | struct drm_device *drm = dev_get_drvdata(dev); |
| 132 | 134 | ||
| 135 | dev_set_drvdata(dev, NULL); | ||
| 133 | drm_dev_unregister(drm); | 136 | drm_dev_unregister(drm); |
| 134 | drm_kms_helper_poll_fini(drm); | 137 | drm_kms_helper_poll_fini(drm); |
| 135 | drm_atomic_helper_shutdown(drm); | 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 | INIT_KFIFO(list.fifo); | 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 | for (i = 0;; i++) { | 380 | for (i = 0;; i++) { |
| 371 | struct device_node *pipeline = of_parse_phandle(np, | 381 | struct device_node *pipeline = of_parse_phandle(np, |
| 372 | "allwinner,pipelines", | 382 | "allwinner,pipelines", |
| @@ -117,7 +117,7 @@ static bool sun4i_layer_format_mod_supported(struct drm_plane *plane, · 116 unmodified lines | |||
| 117 | struct sun4i_layer *layer = plane_to_sun4i_layer(plane); | 117 | struct sun4i_layer *layer = plane_to_sun4i_layer(plane); |
| 118 | 118 | ||
| 119 | if (IS_ERR_OR_NULL(layer->backend->frontend)) | 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 | return sun4i_backend_format_is_supported(format, modifier) || | 122 | return sun4i_backend_format_is_supported(format, modifier) || |
| 123 | sun4i_frontend_format_is_supported(format, modifier); | 123 | sun4i_frontend_format_is_supported(format, modifier); |
| @@ -93,34 +93,10 @@ crtcs_exit: · 92 unmodified lines | |||
| 93 | return crtcs; | 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 | static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, | 96 | static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, |
| 121 | void *data) | 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 | struct dw_hdmi_plat_data *plat_data; | 100 | struct dw_hdmi_plat_data *plat_data; |
| 125 | struct drm_device *drm = data; | 101 | struct drm_device *drm = data; |
| 126 | struct device_node *phy_node; | 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 | return dev_err_probe(dev, PTR_ERR(hdmi->regulator), | 143 | return dev_err_probe(dev, PTR_ERR(hdmi->regulator), |
| 168 | "Couldn't get regulator\n"); | 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 | ret = regulator_enable(hdmi->regulator); | 146 | ret = regulator_enable(hdmi->regulator); |
| 183 | if (ret) { | 147 | if (ret) { |
| 184 | dev_err(dev, "Failed to enable regulator\n"); | 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 | ret = reset_control_deassert(hdmi->rst_ctrl); | 152 | ret = reset_control_deassert(hdmi->rst_ctrl); |
| 191 | if (ret) { | 153 | if (ret) { |
| 192 | dev_err(dev, "Could not deassert ctrl reset control\n"); | 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 | ret = clk_prepare_enable(hdmi->clk_tmds); | 158 | ret = clk_prepare_enable(hdmi->clk_tmds); |
| @@ -245,12 +207,8 @@ err_disable_clk_tmds: · 48 unmodified lines | |||
| 245 | clk_disable_unprepare(hdmi->clk_tmds); | 207 | clk_disable_unprepare(hdmi->clk_tmds); |
| 246 | err_assert_ctrl_reset: | 208 | err_assert_ctrl_reset: |
| 247 | reset_control_assert(hdmi->rst_ctrl); | 209 | reset_control_assert(hdmi->rst_ctrl); |
| 248 | err_disable_ddc_en: | 210 | err_disable_regulator: |
| 249 | gpiod_set_value(hdmi->ddc_en, 0); | ||
| 250 | regulator_disable(hdmi->regulator); | 211 | regulator_disable(hdmi->regulator); |
| 251 | err_unref_ddc_en: | ||
| 252 | if (hdmi->ddc_en) | ||
| 253 | gpiod_put(hdmi->ddc_en); | ||
| 254 | 212 | ||
| 255 | return ret; | 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 | sun8i_hdmi_phy_deinit(hdmi->phy); | 222 | sun8i_hdmi_phy_deinit(hdmi->phy); |
| 265 | clk_disable_unprepare(hdmi->clk_tmds); | 223 | clk_disable_unprepare(hdmi->clk_tmds); |
| 266 | reset_control_assert(hdmi->rst_ctrl); | 224 | reset_control_assert(hdmi->rst_ctrl); |
| 267 | gpiod_set_value(hdmi->ddc_en, 0); | ||
| 268 | regulator_disable(hdmi->regulator); | 225 | regulator_disable(hdmi->regulator); |
| 269 | |||
| 270 | if (hdmi->ddc_en) | ||
| 271 | gpiod_put(hdmi->ddc_en); | ||
| 272 | } | 226 | } |
| 273 | 227 | ||
| 274 | static const struct component_ops sun8i_dw_hdmi_ops = { | 228 | static const struct component_ops sun8i_dw_hdmi_ops = { |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | |||
| 9 | #include <drm/bridge/dw_hdmi.h> | 9 | #include <drm/bridge/dw_hdmi.h> |
| 10 | #include <drm/drm_encoder.h> | 10 | #include <drm/drm_encoder.h> |
| 11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 12 | #include <linux/gpio/consumer.h> | ||
| 13 | #include <linux/regmap.h> | 12 | #include <linux/regmap.h> |
| 14 | #include <linux/regulator/consumer.h> | 13 | #include <linux/regulator/consumer.h> |
| 15 | #include <linux/reset.h> | 14 | #include <linux/reset.h> |
| @@ -193,7 +192,6 @@ struct sun8i_dw_hdmi { · 177 unmodified lines | |||
| 193 | struct regulator *regulator; | 192 | struct regulator *regulator; |
| 194 | const struct sun8i_dw_hdmi_quirks *quirks; | 193 | const struct sun8i_dw_hdmi_quirks *quirks; |
| 195 | struct reset_control *rst_ctrl; | 194 | struct reset_control *rst_ctrl; |
| 196 | struct gpio_desc *ddc_en; | ||
| 197 | }; | 195 | }; |
| 198 | 196 | ||
| 199 | extern struct platform_driver sun8i_hdmi_phy_driver; | 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 | return; | 109 | return; |
| 110 | 110 | ||
| 111 | spin_lock(&bo->bdev->lru_lock); | 111 | spin_lock(&bo->bdev->lru_lock); |
| 112 | if (bo->bulk_move && bo->resource) | 112 | if (bo->resource) |
| 113 | ttm_lru_bulk_move_del(bo->bulk_move, bo->resource); | 113 | ttm_resource_del_bulk_move(bo->resource, bo); |
| 114 | bo->bulk_move = bulk; | 114 | bo->bulk_move = bulk; |
| 115 | if (bo->bulk_move && bo->resource) | 115 | if (bo->resource) |
| 116 | ttm_lru_bulk_move_add(bo->bulk_move, bo->resource); | 116 | ttm_resource_add_bulk_move(bo->resource, bo); |
| 117 | spin_unlock(&bo->bdev->lru_lock); | 117 | spin_unlock(&bo->bdev->lru_lock); |
| 118 | } | 118 | } |
| 119 | EXPORT_SYMBOL(ttm_bo_set_bulk_move); | 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 | dma_resv_assert_held(bo->base.resv); | 690 | dma_resv_assert_held(bo->base.resv); |
| 691 | WARN_ON_ONCE(!kref_read(&bo->kref)); | 691 | WARN_ON_ONCE(!kref_read(&bo->kref)); |
| 692 | if (!(bo->pin_count++) && bo->bulk_move && bo->resource) | 692 | spin_lock(&bo->bdev->lru_lock); |
| 693 | ttm_lru_bulk_move_del(bo->bulk_move, bo->resource); | 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 | EXPORT_SYMBOL(ttm_bo_pin); | 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 | if (WARN_ON_ONCE(!bo->pin_count)) | 710 | if (WARN_ON_ONCE(!bo->pin_count)) |
| 708 | return; | 711 | return; |
| 709 | 712 | ||
| 710 | if (!(--bo->pin_count) && bo->bulk_move && bo->resource) | 713 | spin_lock(&bo->bdev->lru_lock); |
| 711 | ttm_lru_bulk_move_add(bo->bulk_move, bo->resource); | 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 | EXPORT_SYMBOL(ttm_bo_unpin); | 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 | ttm_resource_manager_for_each_res(man, &cursor, res) { | 157 | ttm_resource_manager_for_each_res(man, &cursor, res) { |
| 158 | struct ttm_buffer_object *bo = res->bo; | 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 | ret = ttm_bo_swapout(bo, ctx, gfp_flags); | 165 | ret = ttm_bo_swapout(bo, ctx, gfp_flags); |
| 162 | /* ttm_bo_swapout has dropped the lru_lock */ | 166 | /* ttm_bo_swapout has dropped the lru_lock */ |
| 163 | if (!ret) | 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 | /* Add the resource to a bulk_move cursor */ | 93 | /* Add the resource to a bulk_move cursor */ |
| 94 | void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk, | 94 | static void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk, |
| 95 | struct ttm_resource *res) | 95 | struct ttm_resource *res) |
| 96 | { | 96 | { |
| 97 | struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); | 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 | /* Remove the resource from a bulk_move range */ | 107 | /* Remove the resource from a bulk_move range */ |
| 108 | void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, | 108 | static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, |
| 109 | struct ttm_resource *res) | 109 | struct ttm_resource *res) |
| 110 | { | 110 | { |
| 111 | struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); | 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 | /* Move a resource to the LRU or bulk tail */ | 141 | /* Move a resource to the LRU or bulk tail */ |
| 126 | void ttm_resource_move_to_lru_tail(struct ttm_resource *res) | 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 | res->bus.is_iomem = false; | 185 | res->bus.is_iomem = false; |
| 170 | res->bus.caching = ttm_cached; | 186 | res->bus.caching = ttm_cached; |
| 171 | res->bo = bo; | 187 | res->bo = bo; |
| 172 | INIT_LIST_HEAD(&res->lru); | ||
| 173 | 188 | ||
| 174 | man = ttm_manager_type(bo->bdev, place->mem_type); | 189 | man = ttm_manager_type(bo->bdev, place->mem_type); |
| 175 | spin_lock(&bo->bdev->lru_lock); | 190 | spin_lock(&bo->bdev->lru_lock); |
| 176 | man->usage += res->num_pages << PAGE_SHIFT; | 191 | if (bo->pin_count) |
| 177 | if (bo->bulk_move) | 192 | list_add_tail(&res->lru, &bo->bdev->pinned); |
| 178 | ttm_lru_bulk_move_add(bo->bulk_move, res); | ||
| 179 | else | 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 | spin_unlock(&bo->bdev->lru_lock); | 196 | spin_unlock(&bo->bdev->lru_lock); |
| 182 | } | 197 | } |
| 183 | EXPORT_SYMBOL(ttm_resource_init); | 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 | struct ttm_resource_manager *man = | 226 | struct ttm_resource_manager *man = |
| 212 | ttm_manager_type(bo->bdev, place->mem_type); | 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 | void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res) | 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 | if (!*res) | 244 | if (!*res) |
| 222 | return; | 245 | return; |
| 223 | 246 | ||
| 224 | if (bo->bulk_move) { | 247 | spin_lock(&bo->bdev->lru_lock); |
| 225 | spin_lock(&bo->bdev->lru_lock); | 248 | ttm_resource_del_bulk_move(*res, bo); |
| 226 | ttm_lru_bulk_move_del(bo->bulk_move, *res); | 249 | spin_unlock(&bo->bdev->lru_lock); |
| 227 | spin_unlock(&bo->bdev->lru_lock); | ||
| 228 | } | ||
| 229 | |||
| 230 | man = ttm_manager_type(bo->bdev, (*res)->mem_type); | 250 | man = ttm_manager_type(bo->bdev, (*res)->mem_type); |
| 231 | man->func->free(man, *res); | 251 | man->func->free(man, *res); |
| 232 | *res = NULL; | 252 | *res = NULL; |
| @@ -248,6 +248,9 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo) · 247 unmodified lines | |||
| 248 | { | 248 | { |
| 249 | struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); | 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 | mutex_lock(&vc4->purgeable.lock); | 254 | mutex_lock(&vc4->purgeable.lock); |
| 252 | list_add_tail(&bo->size_head, &vc4->purgeable.list); | 255 | list_add_tail(&bo->size_head, &vc4->purgeable.list); |
| 253 | vc4->purgeable.num++; | 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 | struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); | 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 | /* list_del_init() is used here because the caller might release | 268 | /* list_del_init() is used here because the caller might release |
| 263 | * the purgeable lock in order to acquire the madv one and update the | 269 | * the purgeable lock in order to acquire the madv one and update the |
| 264 | * madv status. | 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 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 393 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 388 | struct vc4_bo *bo; | 394 | struct vc4_bo *bo; |
| 389 | 395 | ||
| 396 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 397 | return ERR_PTR(-ENODEV); | ||
| 398 | |||
| 390 | bo = kzalloc(sizeof(*bo), GFP_KERNEL); | 399 | bo = kzalloc(sizeof(*bo), GFP_KERNEL); |
| 391 | if (!bo) | 400 | if (!bo) |
| 392 | return ERR_PTR(-ENOMEM); | 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 | struct drm_gem_cma_object *cma_obj; | 422 | struct drm_gem_cma_object *cma_obj; |
| 414 | struct vc4_bo *bo; | 423 | struct vc4_bo *bo; |
| 415 | 424 | ||
| 425 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 426 | return ERR_PTR(-ENODEV); | ||
| 427 | |||
| 416 | if (size == 0) | 428 | if (size == 0) |
| 417 | return ERR_PTR(-EINVAL); | 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 | return bo; | 483 | return bo; |
| 472 | } | 484 | } |
| 473 | 485 | ||
| 474 | int vc4_dumb_create(struct drm_file *file_priv, | 486 | int vc4_bo_dumb_create(struct drm_file *file_priv, |
| 475 | struct drm_device *dev, | 487 | struct drm_device *dev, |
| 476 | struct drm_mode_create_dumb *args) | 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 | struct vc4_bo *bo = NULL; | 491 | struct vc4_bo *bo = NULL; |
| 480 | int ret; | 492 | int ret; |
| 481 | 493 | ||
| 482 | if (args->pitch < min_pitch) | 494 | if (WARN_ON_ONCE(vc4->is_vc5)) |
| 483 | args->pitch = min_pitch; | 495 | return -ENODEV; |
| 484 | 496 | ||
| 485 | if (args->size < args->pitch * args->height) | 497 | ret = vc4_dumb_fixup_args(args); |
| 486 | args->size = args->pitch * args->height; | 498 | if (ret) |
| 499 | return ret; | ||
| 487 | 500 | ||
| 488 | bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB); | 501 | bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB); |
| 489 | if (IS_ERR(bo)) | 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 | int vc4_bo_inc_usecnt(struct vc4_bo *bo) | 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 | int ret; | 618 | int ret; |
| 605 | 619 | ||
| 620 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 621 | return -ENODEV; | ||
| 622 | |||
| 606 | /* Fast path: if the BO is already retained by someone, no need to | 623 | /* Fast path: if the BO is already retained by someone, no need to |
| 607 | * check the madv status. | 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 | void vc4_bo_dec_usecnt(struct vc4_bo *bo) | 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 | /* Fast path: if the BO is still retained by someone, no need to test | 662 | /* Fast path: if the BO is still retained by someone, no need to test |
| 641 | * the madv value. | 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 | struct vc4_bo *bo = NULL; | 778 | struct vc4_bo *bo = NULL; |
| 757 | int ret; | 779 | int ret; |
| 758 | 780 | ||
| 781 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 782 | return -ENODEV; | ||
| 783 | |||
| 759 | ret = vc4_grab_bin_bo(vc4, vc4file); | 784 | ret = vc4_grab_bin_bo(vc4, vc4file); |
| 760 | if (ret) | 785 | if (ret) |
| 761 | return ret; | 786 | return ret; |
| @@ -779,9 +804,13 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, · 17 unmodified lines | |||
| 779 | int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, | 804 | int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, |
| 780 | struct drm_file *file_priv) | 805 | struct drm_file *file_priv) |
| 781 | { | 806 | { |
| 807 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 782 | struct drm_vc4_mmap_bo *args = data; | 808 | struct drm_vc4_mmap_bo *args = data; |
| 783 | struct drm_gem_object *gem_obj; | 809 | struct drm_gem_object *gem_obj; |
| 784 | 810 | ||
| 811 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 812 | return -ENODEV; | ||
| 813 | |||
| 785 | gem_obj = drm_gem_object_lookup(file_priv, args->handle); | 814 | gem_obj = drm_gem_object_lookup(file_priv, args->handle); |
| 786 | if (!gem_obj) { | 815 | if (!gem_obj) { |
| 787 | DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); | 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 | struct vc4_bo *bo = NULL; | 834 | struct vc4_bo *bo = NULL; |
| 806 | int ret; | 835 | int ret; |
| 807 | 836 | ||
| 837 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 838 | return -ENODEV; | ||
| 839 | |||
| 808 | if (args->size == 0) | 840 | if (args->size == 0) |
| 809 | return -EINVAL; | 841 | return -EINVAL; |
| 810 | 842 | ||
| @@ -875,11 +907,15 @@ fail: · 64 unmodified lines | |||
| 875 | int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, | 907 | int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, |
| 876 | struct drm_file *file_priv) | 908 | struct drm_file *file_priv) |
| 877 | { | 909 | { |
| 910 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 878 | struct drm_vc4_set_tiling *args = data; | 911 | struct drm_vc4_set_tiling *args = data; |
| 879 | struct drm_gem_object *gem_obj; | 912 | struct drm_gem_object *gem_obj; |
| 880 | struct vc4_bo *bo; | 913 | struct vc4_bo *bo; |
| 881 | bool t_format; | 914 | bool t_format; |
| 882 | 915 | ||
| 916 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 917 | return -ENODEV; | ||
| 918 | |||
| 883 | if (args->flags != 0) | 919 | if (args->flags != 0) |
| 884 | return -EINVAL; | 920 | return -EINVAL; |
| 885 | 921 | ||
| @@ -918,10 +954,14 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, · 32 unmodified lines | |||
| 918 | int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, | 954 | int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, |
| 919 | struct drm_file *file_priv) | 955 | struct drm_file *file_priv) |
| 920 | { | 956 | { |
| 957 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 921 | struct drm_vc4_get_tiling *args = data; | 958 | struct drm_vc4_get_tiling *args = data; |
| 922 | struct drm_gem_object *gem_obj; | 959 | struct drm_gem_object *gem_obj; |
| 923 | struct vc4_bo *bo; | 960 | struct vc4_bo *bo; |
| 924 | 961 | ||
| 962 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 963 | return -ENODEV; | ||
| 964 | |||
| 925 | if (args->flags != 0 || args->modifier != 0) | 965 | if (args->flags != 0 || args->modifier != 0) |
| 926 | return -EINVAL; | 966 | return -EINVAL; |
| 927 | 967 | ||
| @@ -948,6 +988,9 @@ int vc4_bo_cache_init(struct drm_device *dev) · 20 unmodified lines | |||
| 948 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 988 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 949 | int i; | 989 | int i; |
| 950 | 990 | ||
| 991 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 992 | return -ENODEV; | ||
| 993 | |||
| 951 | /* Create the initial set of BO labels that the kernel will | 994 | /* Create the initial set of BO labels that the kernel will |
| 952 | * use. This lets us avoid a bunch of string reallocation in | 995 | * use. This lets us avoid a bunch of string reallocation in |
| 953 | * the kernel's draw and BO allocation paths. | 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 | struct drm_gem_object *gem_obj; | 1050 | struct drm_gem_object *gem_obj; |
| 1008 | int ret = 0, label; | 1051 | int ret = 0, label; |
| 1009 | 1052 | ||
| 1053 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1054 | return -ENODEV; | ||
| 1055 | |||
| 1010 | if (!args->len) | 1056 | if (!args->len) |
| 1011 | return -EINVAL; | 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 | * Removing 1 from the FIFO full level however | 256 | * Removing 1 from the FIFO full level however |
| 257 | * seems to completely remove that issue. | 257 | * seems to completely remove that issue. |
| 258 | */ | 258 | */ |
| 259 | if (!vc4->hvs->hvs5) | 259 | if (!vc4->is_vc5) |
| 260 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1; | 260 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1; |
| 261 | 261 | ||
| 262 | return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX; | 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 | if (is_dsi) | 389 | if (is_dsi) |
| 390 | CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); | 390 | CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); |
| 391 | 391 | ||
| 392 | if (vc4->hvs->hvs5) | 392 | if (vc4->is_vc5) |
| 393 | CRTC_WRITE(PV_MUX_CFG, | 393 | CRTC_WRITE(PV_MUX_CFG, |
| 394 | VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP, | 394 | VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP, |
| 395 | PV_MUX_CFG_RGB_PIXEL_MUX_MODE)); | 395 | PV_MUX_CFG_RGB_PIXEL_MUX_MODE)); |
| @@ -775,17 +775,18 @@ struct vc4_async_flip_state { · 379 unmodified lines | |||
| 775 | struct drm_framebuffer *old_fb; | 775 | struct drm_framebuffer *old_fb; |
| 776 | struct drm_pending_vblank_event *event; | 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 | /* Called when the V3D execution for the BO being flipped to is done, so that | 784 | /* Called when the V3D execution for the BO being flipped to is done, so that |
| 782 | * we can actually update the plane's address to point to it. | 785 | * we can actually update the plane's address to point to it. |
| 783 | */ | 786 | */ |
| 784 | static void | 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 | struct drm_crtc *crtc = flip_state->crtc; | 790 | struct drm_crtc *crtc = flip_state->crtc; |
| 790 | struct drm_device *dev = crtc->dev; | 791 | struct drm_device *dev = crtc->dev; |
| 791 | struct drm_plane *plane = crtc->primary; | 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 | drm_crtc_vblank_put(crtc); | 803 | drm_crtc_vblank_put(crtc); |
| 803 | drm_framebuffer_put(flip_state->fb); | 804 | drm_framebuffer_put(flip_state->fb); |
| 804 | 805 | ||
| 805 | /* Decrement the BO usecnt in order to keep the inc/dec calls balanced | 806 | if (flip_state->old_fb) |
| 806 | * when the planes are updated through the async update path. | 807 | drm_framebuffer_put(flip_state->old_fb); |
| 807 | * FIXME: we should move to generic async-page-flip when it's | 808 | |
| 808 | * available, so that we can get rid of this hand-made cleanup_fb() | 809 | kfree(flip_state); |
| 809 | * logic. | 810 | } |
| 810 | */ | 811 | |
| 811 | if (flip_state->old_fb) { | 812 | static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb) |
| 812 | struct drm_gem_cma_object *cma_bo; | 813 | { |
| 813 | struct vc4_bo *bo; | 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 | bo = to_vc4_bo(&cma_bo->base); | 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. | 839 | static void vc4_async_page_flip_fence_complete(struct dma_fence *fence, |
| 825 | * | 840 | struct dma_fence_cb *cb) |
| 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) | ||
| 834 | { | 841 | { |
| 835 | struct drm_device *dev = crtc->dev; | 842 | struct vc4_async_flip_state *flip_state = |
| 836 | struct drm_plane *plane = crtc->primary; | 843 | container_of(cb, struct vc4_async_flip_state, cb.fence); |
| 837 | int ret = 0; | 844 | |
| 838 | struct vc4_async_flip_state *flip_state; | 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 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); | 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 | 858 | if (!vc4->is_vc5) { |
| 843 | * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the | 859 | struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); |
| 844 | * plane is later updated through the non-async path. | 860 | |
| 845 | * FIXME: we should move to generic async-page-flip when it's | 861 | return vc4_queue_seqno_cb(dev, &flip_state->cb.seqno, bo->seqno, |
| 846 | * available, so that we can get rid of this hand-made prepare_fb() | 862 | vc4_async_page_flip_seqno_complete); |
| 847 | * logic. | 863 | } |
| 848 | */ | 864 | |
| 849 | ret = vc4_bo_inc_usecnt(bo); | 865 | ret = dma_resv_get_singleton(cma_bo->base.resv, DMA_RESV_USAGE_READ, &fence); |
| 850 | if (ret) | 866 | if (ret) |
| 851 | return ret; | 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 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); | 893 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); |
| 854 | if (!flip_state) { | 894 | if (!flip_state) |
| 855 | vc4_bo_dec_usecnt(bo); | ||
| 856 | return -ENOMEM; | 895 | return -ENOMEM; |
| 857 | } | ||
| 858 | 896 | ||
| 859 | drm_framebuffer_get(fb); | 897 | drm_framebuffer_get(fb); |
| 860 | flip_state->fb = fb; | 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 | drm_atomic_set_fb_for_plane(plane->state, fb); | 920 | drm_atomic_set_fb_for_plane(plane->state, fb); |
| 883 | 921 | ||
| 884 | vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno, | 922 | vc4_async_set_fence_cb(dev, flip_state); |
| 885 | vc4_async_page_flip_complete); | ||
| 886 | 923 | ||
| 887 | /* Driver takes ownership of state on successful async commit. */ | 924 | /* Driver takes ownership of state on successful async commit. */ |
| 888 | return 0; | 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 | int vc4_page_flip(struct drm_crtc *crtc, | 978 | int vc4_page_flip(struct drm_crtc *crtc, |
| 892 | struct drm_framebuffer *fb, | 979 | struct drm_framebuffer *fb, |
| 893 | struct drm_pending_vblank_event *event, | 980 | struct drm_pending_vblank_event *event, |
| 894 | uint32_t flags, | 981 | uint32_t flags, |
| 895 | struct drm_modeset_acquire_ctx *ctx) | 982 | struct drm_modeset_acquire_ctx *ctx) |
| 896 | { | 983 | { |
| 897 | if (flags & DRM_MODE_PAGE_FLIP_ASYNC) | 984 | if (flags & DRM_MODE_PAGE_FLIP_ASYNC) { |
| 898 | return vc4_async_page_flip(crtc, fb, event, flags); | 985 | struct drm_device *dev = crtc->dev; |
| 899 | else | 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 | return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); | 993 | return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); |
| 994 | } | ||
| 901 | } | 995 | } |
| 902 | 996 | ||
| 903 | struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) | 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 | crtc_funcs, NULL); | 1243 | crtc_funcs, NULL); |
| 1150 | drm_crtc_helper_add(crtc, crtc_helper_funcs); | 1244 | drm_crtc_helper_add(crtc, crtc_helper_funcs); |
| 1151 | 1245 | ||
| 1152 | if (!vc4->hvs->hvs5) { | 1246 | if (!vc4->is_vc5) { |
| 1153 | drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); | 1247 | drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); |
| 1154 | 1248 | ||
| 1155 | drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size); | 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 | return map; | 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 | static int vc4_get_param_ioctl(struct drm_device *dev, void *data, | 92 | static int vc4_get_param_ioctl(struct drm_device *dev, void *data, |
| 67 | struct drm_file *file_priv) | 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 | if (args->pad != 0) | 99 | if (args->pad != 0) |
| 74 | return -EINVAL; | 100 | return -EINVAL; |
| 75 | 101 | ||
| 102 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 103 | return -ENODEV; | ||
| 104 | |||
| 76 | if (!vc4->v3d) | 105 | if (!vc4->v3d) |
| 77 | return -ENODEV; | 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 | static int vc4_open(struct drm_device *dev, struct drm_file *file) | 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 | struct vc4_file *vc4file; | 149 | struct vc4_file *vc4file; |
| 120 | 150 | ||
| 151 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 152 | return -ENODEV; | ||
| 153 | |||
| 121 | vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL); | 154 | vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL); |
| 122 | if (!vc4file) | 155 | if (!vc4file) |
| 123 | return -ENOMEM; | 156 | return -ENOMEM; |
| 157 | vc4file->dev = vc4; | ||
| 124 | 158 | ||
| 125 | vc4_perfmon_open_file(vc4file); | 159 | vc4_perfmon_open_file(vc4file); |
| 126 | file->driver_priv = vc4file; | 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 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 166 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 133 | struct vc4_file *vc4file = file->driver_priv; | 167 | struct vc4_file *vc4file = file->driver_priv; |
| 134 | 168 | ||
| 169 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 170 | return; | ||
| 171 | |||
| 135 | if (vc4file->bin_bo_used) | 172 | if (vc4file->bin_bo_used) |
| 136 | vc4_v3d_bin_bo_put(vc4); | 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 | DRM_IOCTL_DEF_DRV(VC4_PERFMON_GET_VALUES, vc4_perfmon_get_values_ioctl, DRM_RENDER_ALLOW), | 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 | .driver_features = (DRIVER_MODESET | | 201 | .driver_features = (DRIVER_MODESET | |
| 165 | DRIVER_ATOMIC | | 202 | DRIVER_ATOMIC | |
| 166 | DRIVER_GEM | | 203 | DRIVER_GEM | |
| @@ -175,7 +212,7 @@ static struct drm_driver vc4_drm_driver = { · 8 unmodified lines | |||
| 175 | 212 | ||
| 176 | .gem_create_object = vc4_create_object, | 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 | .ioctls = vc4_drm_ioctls, | 217 | .ioctls = vc4_drm_ioctls, |
| 181 | .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), | 218 | .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), |
| @@ -189,6 +226,27 @@ static struct drm_driver vc4_drm_driver = { · 7 unmodified lines | |||
| 189 | .patchlevel = DRIVER_PATCHLEVEL, | 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 | static void vc4_match_add_drivers(struct device *dev, | 250 | static void vc4_match_add_drivers(struct device *dev, |
| 193 | struct component_match **match, | 251 | struct component_match **match, |
| 194 | struct platform_driver *const *drivers, | 252 | struct platform_driver *const *drivers, |
| @@ -212,42 +270,49 @@ static void vc4_match_add_drivers(struct device *dev, · 17 unmodified lines | |||
| 212 | static int vc4_drm_bind(struct device *dev) | 270 | static int vc4_drm_bind(struct device *dev) |
| 213 | { | 271 | { |
| 214 | struct platform_device *pdev = to_platform_device(dev); | 272 | struct platform_device *pdev = to_platform_device(dev); |
| 273 | const struct drm_driver *driver; | ||
| 215 | struct rpi_firmware *firmware = NULL; | 274 | struct rpi_firmware *firmware = NULL; |
| 216 | struct drm_device *drm; | 275 | struct drm_device *drm; |
| 217 | struct vc4_dev *vc4; | 276 | struct vc4_dev *vc4; |
| 218 | struct device_node *node; | 277 | struct device_node *node; |
| 219 | struct drm_crtc *crtc; | 278 | struct drm_crtc *crtc; |
| 279 | bool is_vc5; | ||
| 220 | int ret = 0; | 280 | int ret = 0; |
| 221 | 281 | ||
| 222 | dev->coherent_dma_mask = DMA_BIT_MASK(32); | 282 | dev->coherent_dma_mask = DMA_BIT_MASK(32); |
| 223 | 283 | ||
| 224 | /* If VC4 V3D is missing, don't advertise render nodes. */ | 284 | is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5"); |
| 225 | node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL); | 285 | if (is_vc5) |
| 226 | if (!node || !of_device_is_available(node)) | 286 | driver = &vc5_drm_driver; |
| 227 | vc4_drm_driver.driver_features &= ~DRIVER_RENDER; | 287 | else |
| 228 | of_node_put(node); | 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 | if (IS_ERR(vc4)) | 291 | if (IS_ERR(vc4)) |
| 232 | return PTR_ERR(vc4); | 292 | return PTR_ERR(vc4); |
| 293 | vc4->is_vc5 = is_vc5; | ||
| 233 | 294 | ||
| 234 | drm = &vc4->base; | 295 | drm = &vc4->base; |
| 235 | platform_set_drvdata(pdev, drm); | 296 | platform_set_drvdata(pdev, drm); |
| 236 | INIT_LIST_HEAD(&vc4->debugfs_list); | 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); | 302 | ret = vc4_bo_cache_init(drm); |
| 241 | if (ret) | 303 | if (ret) |
| 242 | return ret; | 304 | return ret; |
| 305 | } | ||
| 243 | 306 | ||
| 244 | ret = drmm_mode_config_init(drm); | 307 | ret = drmm_mode_config_init(drm); |
| 245 | if (ret) | 308 | if (ret) |
| 246 | return ret; | 309 | return ret; |
| 247 | 310 | ||
| 248 | ret = vc4_gem_init(drm); | 311 | if (!is_vc5) { |
| 249 | if (ret) | 312 | ret = vc4_gem_init(drm); |
| 250 | return ret; | 313 | if (ret) |
| 314 | return ret; | ||
| 315 | } | ||
| 251 | 316 | ||
| 252 | node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); | 317 | node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); |
| 253 | if (node) { | 318 | if (node) { |
| @@ -258,7 +323,7 @@ static int vc4_drm_bind(struct device *dev) · 4 unmodified lines | |||
| 258 | return -EPROBE_DEFER; | 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 | if (ret) | 327 | if (ret) |
| 263 | return ret; | 328 | return ret; |
| 264 | 329 | ||
| @@ -48,6 +48,8 @@ enum vc4_kernel_bo_type { · 47 unmodified lines | |||
| 48 | * done. This way, only events related to a specific job will be counted. | 48 | * done. This way, only events related to a specific job will be counted. |
| 49 | */ | 49 | */ |
| 50 | struct vc4_perfmon { | 50 | struct vc4_perfmon { |
| 51 | struct vc4_dev *dev; | ||
| 52 | |||
| 51 | /* Tracks the number of users of the perfmon, when this counter reaches | 53 | /* Tracks the number of users of the perfmon, when this counter reaches |
| 52 | * zero the perfmon is destroyed. | 54 | * zero the perfmon is destroyed. |
| 53 | */ | 55 | */ |
| @@ -74,6 +76,8 @@ struct vc4_perfmon { · 20 unmodified lines | |||
| 74 | struct vc4_dev { | 76 | struct vc4_dev { |
| 75 | struct drm_device base; | 77 | struct drm_device base; |
| 76 | 78 | ||
| 79 | bool is_vc5; | ||
| 80 | |||
| 77 | unsigned int irq; | 81 | unsigned int irq; |
| 78 | 82 | ||
| 79 | struct vc4_hvs *hvs; | 83 | struct vc4_hvs *hvs; |
| @@ -316,6 +320,7 @@ struct vc4_v3d { · 236 unmodified lines | |||
| 316 | }; | 320 | }; |
| 317 | 321 | ||
| 318 | struct vc4_hvs { | 322 | struct vc4_hvs { |
| 323 | struct vc4_dev *vc4; | ||
| 319 | struct platform_device *pdev; | 324 | struct platform_device *pdev; |
| 320 | void __iomem *regs; | 325 | void __iomem *regs; |
| 321 | u32 __iomem *dlist; | 326 | u32 __iomem *dlist; |
| @@ -333,9 +338,6 @@ struct vc4_hvs { · 11 unmodified lines | |||
| 333 | struct drm_mm_node mitchell_netravali_filter; | 338 | struct drm_mm_node mitchell_netravali_filter; |
| 334 | 339 | ||
| 335 | struct debugfs_regset32 regset; | 340 | struct debugfs_regset32 regset; |
| 336 | |||
| 337 | /* HVS version 5 flag, therefore requires updated dlist structures */ | ||
| 338 | bool hvs5; | ||
| 339 | }; | 341 | }; |
| 340 | 342 | ||
| 341 | struct vc4_plane { | 343 | struct vc4_plane { |
| @@ -580,6 +582,8 @@ to_vc4_crtc_state(struct drm_crtc_state *crtc_state) · 238 unmodified lines | |||
| 580 | #define VC4_REG32(reg) { .name = #reg, .offset = reg } | 582 | #define VC4_REG32(reg) { .name = #reg, .offset = reg } |
| 581 | 583 | ||
| 582 | struct vc4_exec_info { | 584 | struct vc4_exec_info { |
| 585 | struct vc4_dev *dev; | ||
| 586 | |||
| 583 | /* Sequence number for this bin/render job. */ | 587 | /* Sequence number for this bin/render job. */ |
| 584 | uint64_t seqno; | 588 | uint64_t seqno; |
| 585 | 589 | ||
| @@ -701,6 +705,8 @@ struct vc4_exec_info { · 115 unmodified lines | |||
| 701 | * released when the DRM file is closed should be placed here. | 705 | * released when the DRM file is closed should be placed here. |
| 702 | */ | 706 | */ |
| 703 | struct vc4_file { | 707 | struct vc4_file { |
| 708 | struct vc4_dev *dev; | ||
| 709 | |||
| 704 | struct { | 710 | struct { |
| 705 | struct idr idr; | 711 | struct idr idr; |
| 706 | struct mutex lock; | 712 | struct mutex lock; |
| @@ -814,9 +820,9 @@ struct vc4_validated_shader_info { · 107 unmodified lines | |||
| 814 | struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); | 820 | struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); |
| 815 | struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, | 821 | struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, |
| 816 | bool from_cache, enum vc4_kernel_bo_type type); | 822 | bool from_cache, enum vc4_kernel_bo_type type); |
| 817 | int vc4_dumb_create(struct drm_file *file_priv, | 823 | int vc4_bo_dumb_create(struct drm_file *file_priv, |
| 818 | struct drm_device *dev, | 824 | struct drm_device *dev, |
| 819 | struct drm_mode_create_dumb *args); | 825 | struct drm_mode_create_dumb *args); |
| 820 | int vc4_create_bo_ioctl(struct drm_device *dev, void *data, | 826 | int vc4_create_bo_ioctl(struct drm_device *dev, void *data, |
| 821 | struct drm_file *file_priv); | 827 | struct drm_file *file_priv); |
| 822 | int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, | 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 | /* vc4_drv.c */ | 892 | /* vc4_drv.c */ |
| 887 | void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); | 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 | /* vc4_dpi.c */ | 896 | /* vc4_dpi.c */ |
| 890 | extern struct platform_driver vc4_dpi_driver; | 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 | u32 i; | 76 | u32 i; |
| 77 | int ret = 0; | 77 | int ret = 0; |
| 78 | 78 | ||
| 79 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 80 | return -ENODEV; | ||
| 81 | |||
| 79 | if (!vc4->v3d) { | 82 | if (!vc4->v3d) { |
| 80 | DRM_DEBUG("VC4_GET_HANG_STATE with no VC4 V3D probed\n"); | 83 | DRM_DEBUG("VC4_GET_HANG_STATE with no VC4 V3D probed\n"); |
| 81 | return -ENODEV; | 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 | unsigned long timeout_expire; | 389 | unsigned long timeout_expire; |
| 387 | DEFINE_WAIT(wait); | 390 | DEFINE_WAIT(wait); |
| 388 | 391 | ||
| 392 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 393 | return -ENODEV; | ||
| 394 | |||
| 389 | if (vc4->finished_seqno >= seqno) | 395 | if (vc4->finished_seqno >= seqno) |
| 390 | return 0; | 396 | return 0; |
| 391 | 397 | ||
| @@ -468,6 +474,9 @@ vc4_submit_next_bin_job(struct drm_device *dev) · 76 unmodified lines | |||
| 468 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 474 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 469 | struct vc4_exec_info *exec; | 475 | struct vc4_exec_info *exec; |
| 470 | 476 | ||
| 477 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 478 | return; | ||
| 479 | |||
| 471 | again: | 480 | again: |
| 472 | exec = vc4_first_bin_job(vc4); | 481 | exec = vc4_first_bin_job(vc4); |
| 473 | if (!exec) | 482 | if (!exec) |
| @@ -513,6 +522,9 @@ vc4_submit_next_render_job(struct drm_device *dev) · 39 unmodified lines | |||
| 513 | if (!exec) | 522 | if (!exec) |
| 514 | return; | 523 | return; |
| 515 | 524 | ||
| 525 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 526 | return; | ||
| 527 | |||
| 516 | /* A previous RCL may have written to one of our textures, and | 528 | /* A previous RCL may have written to one of our textures, and |
| 517 | * our full cache flush at bin time may have occurred before | 529 | * our full cache flush at bin time may have occurred before |
| 518 | * that RCL completed. Flush the texture cache now, but not | 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 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 543 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 532 | bool was_empty = list_empty(&vc4->render_job_list); | 544 | bool was_empty = list_empty(&vc4->render_job_list); |
| 533 | 545 | ||
| 546 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 547 | return; | ||
| 548 | |||
| 534 | list_move_tail(&exec->head, &vc4->render_job_list); | 549 | list_move_tail(&exec->head, &vc4->render_job_list); |
| 535 | if (was_empty) | 550 | if (was_empty) |
| 536 | vc4_submit_next_render_job(dev); | 551 | vc4_submit_next_render_job(dev); |
| @@ -997,6 +1012,9 @@ vc4_job_handle_completed(struct vc4_dev *vc4) · 460 unmodified lines | |||
| 997 | unsigned long irqflags; | 1012 | unsigned long irqflags; |
| 998 | struct vc4_seqno_cb *cb, *cb_temp; | 1013 | struct vc4_seqno_cb *cb, *cb_temp; |
| 999 | 1014 | ||
| 1015 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1016 | return; | ||
| 1017 | |||
| 1000 | spin_lock_irqsave(&vc4->job_lock, irqflags); | 1018 | spin_lock_irqsave(&vc4->job_lock, irqflags); |
| 1001 | while (!list_empty(&vc4->job_done_list)) { | 1019 | while (!list_empty(&vc4->job_done_list)) { |
| 1002 | struct vc4_exec_info *exec = | 1020 | struct vc4_exec_info *exec = |
| @@ -1033,6 +1051,9 @@ int vc4_queue_seqno_cb(struct drm_device *dev, · 30 unmodified lines | |||
| 1033 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 1051 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 1034 | unsigned long irqflags; | 1052 | unsigned long irqflags; |
| 1035 | 1053 | ||
| 1054 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1055 | return -ENODEV; | ||
| 1056 | |||
| 1036 | cb->func = func; | 1057 | cb->func = func; |
| 1037 | INIT_WORK(&cb->work, vc4_seqno_cb_work); | 1058 | INIT_WORK(&cb->work, vc4_seqno_cb_work); |
| 1038 | 1059 | ||
| @@ -1083,8 +1104,12 @@ int · 44 unmodified lines | |||
| 1083 | vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, | 1104 | vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, |
| 1084 | struct drm_file *file_priv) | 1105 | struct drm_file *file_priv) |
| 1085 | { | 1106 | { |
| 1107 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 1086 | struct drm_vc4_wait_seqno *args = data; | 1108 | struct drm_vc4_wait_seqno *args = data; |
| 1087 | 1109 | ||
| 1110 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1111 | return -ENODEV; | ||
| 1112 | |||
| 1088 | return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, | 1113 | return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, |
| 1089 | &args->timeout_ns); | 1114 | &args->timeout_ns); |
| 1090 | } | 1115 | } |
| @@ -1093,11 +1118,15 @@ int · 2 unmodified lines | |||
| 1093 | vc4_wait_bo_ioctl(struct drm_device *dev, void *data, | 1118 | vc4_wait_bo_ioctl(struct drm_device *dev, void *data, |
| 1094 | struct drm_file *file_priv) | 1119 | struct drm_file *file_priv) |
| 1095 | { | 1120 | { |
| 1121 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 1096 | int ret; | 1122 | int ret; |
| 1097 | struct drm_vc4_wait_bo *args = data; | 1123 | struct drm_vc4_wait_bo *args = data; |
| 1098 | struct drm_gem_object *gem_obj; | 1124 | struct drm_gem_object *gem_obj; |
| 1099 | struct vc4_bo *bo; | 1125 | struct vc4_bo *bo; |
| 1100 | 1126 | ||
| 1127 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1128 | return -ENODEV; | ||
| 1129 | |||
| 1101 | if (args->pad != 0) | 1130 | if (args->pad != 0) |
| 1102 | return -EINVAL; | 1131 | return -EINVAL; |
| 1103 | 1132 | ||
| @@ -1144,6 +1173,9 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, · 40 unmodified lines | |||
| 1144 | args->shader_rec_size, | 1173 | args->shader_rec_size, |
| 1145 | args->bo_handle_count); | 1174 | args->bo_handle_count); |
| 1146 | 1175 | ||
| 1176 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1177 | return -ENODEV; | ||
| 1178 | |||
| 1147 | if (!vc4->v3d) { | 1179 | if (!vc4->v3d) { |
| 1148 | DRM_DEBUG("VC4_SUBMIT_CL with no VC4 V3D probed\n"); | 1180 | DRM_DEBUG("VC4_SUBMIT_CL with no VC4 V3D probed\n"); |
| 1149 | return -ENODEV; | 1181 | return -ENODEV; |
| @@ -1167,6 +1199,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, · 17 unmodified lines | |||
| 1167 | DRM_ERROR("malloc failure on exec struct\n"); | 1199 | DRM_ERROR("malloc failure on exec struct\n"); |
| 1168 | return -ENOMEM; | 1200 | return -ENOMEM; |
| 1169 | } | 1201 | } |
| 1202 | exec->dev = vc4; | ||
| 1170 | 1203 | ||
| 1171 | ret = vc4_v3d_pm_get(vc4); | 1204 | ret = vc4_v3d_pm_get(vc4); |
| 1172 | if (ret) { | 1205 | if (ret) { |
| @@ -1276,6 +1309,9 @@ int vc4_gem_init(struct drm_device *dev) · 103 unmodified lines | |||
| 1276 | { | 1309 | { |
| 1277 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 1310 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 1278 | 1311 | ||
| 1312 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1313 | return -ENODEV; | ||
| 1314 | |||
| 1279 | vc4->dma_fence_context = dma_fence_context_alloc(1); | 1315 | vc4->dma_fence_context = dma_fence_context_alloc(1); |
| 1280 | 1316 | ||
| 1281 | INIT_LIST_HEAD(&vc4->bin_job_list); | 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 | int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data, | 1357 | int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data, |
| 1322 | struct drm_file *file_priv) | 1358 | struct drm_file *file_priv) |
| 1323 | { | 1359 | { |
| 1360 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 1324 | struct drm_vc4_gem_madvise *args = data; | 1361 | struct drm_vc4_gem_madvise *args = data; |
| 1325 | struct drm_gem_object *gem_obj; | 1362 | struct drm_gem_object *gem_obj; |
| 1326 | struct vc4_bo *bo; | 1363 | struct vc4_bo *bo; |
| 1327 | int ret; | 1364 | int ret; |
| 1328 | 1365 | ||
| 1366 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 1367 | return -ENODEV; | ||
| 1368 | |||
| 1329 | switch (args->madv) { | 1369 | switch (args->madv) { |
| 1330 | case VC4_MADV_DONTNEED: | 1370 | case VC4_MADV_DONTNEED: |
| 1331 | case VC4_MADV_WILLNEED: | 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 | unsigned int bpc, | 1481 | unsigned int bpc, |
| 1482 | enum vc4_hdmi_output_format fmt) | 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 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) | 1486 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) |
| 1487 | clock = clock * 2; | 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 | int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output) | 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 | u32 reg; | 224 | u32 reg; |
| 224 | int ret; | 225 | int ret; |
| 225 | 226 | ||
| 226 | if (!hvs->hvs5) | 227 | if (!vc4->is_vc5) |
| 227 | return output; | 228 | return output; |
| 228 | 229 | ||
| 229 | switch (output) { | 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 | static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, | 274 | static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, |
| 274 | struct drm_display_mode *mode, bool oneshot) | 275 | struct drm_display_mode *mode, bool oneshot) |
| 275 | { | 276 | { |
| 277 | struct vc4_dev *vc4 = hvs->vc4; | ||
| 276 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); | 278 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
| 277 | struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); | 279 | struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); |
| 278 | unsigned int chan = vc4_crtc_state->assigned_channel; | 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 | dispctrl = SCALER_DISPCTRLX_ENABLE; | 294 | dispctrl = SCALER_DISPCTRLX_ENABLE; |
| 293 | 295 | ||
| 294 | if (!hvs->hvs5) | 296 | if (!vc4->is_vc5) |
| 295 | dispctrl |= VC4_SET_FIELD(mode->hdisplay, | 297 | dispctrl |= VC4_SET_FIELD(mode->hdisplay, |
| 296 | SCALER_DISPCTRLX_WIDTH) | | 298 | SCALER_DISPCTRLX_WIDTH) | |
| 297 | VC4_SET_FIELD(mode->vdisplay, | 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 | HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx | | 315 | HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx | |
| 314 | SCALER_DISPBKGND_AUTOHS | | 316 | SCALER_DISPBKGND_AUTOHS | |
| 315 | ((!hvs->hvs5) ? SCALER_DISPBKGND_GAMMA : 0) | | 317 | ((!vc4->is_vc5) ? SCALER_DISPBKGND_GAMMA : 0) | |
| 316 | (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); | 318 | (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); |
| 317 | 319 | ||
| 318 | /* Reload the LUT, since the SRAMs would have been disabled if | 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 | if (!hvs) | 619 | if (!hvs) |
| 618 | return -ENOMEM; | 620 | return -ENOMEM; |
| 619 | 621 | ||
| 622 | hvs->vc4 = vc4; | ||
| 620 | hvs->pdev = pdev; | 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 | hvs->regs = vc4_ioremap_regs(pdev, 0); | 625 | hvs->regs = vc4_ioremap_regs(pdev, 0); |
| 626 | if (IS_ERR(hvs->regs)) | 626 | if (IS_ERR(hvs->regs)) |
| 627 | return PTR_ERR(hvs->regs); | 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 | hvs->regset.regs = hvs_regs; | 630 | hvs->regset.regs = hvs_regs; |
| 631 | hvs->regset.nregs = ARRAY_SIZE(hvs_regs); | 631 | hvs->regset.nregs = ARRAY_SIZE(hvs_regs); |
| 632 | 632 | ||
| 633 | if (hvs->hvs5) { | 633 | if (vc4->is_vc5) { |
| 634 | hvs->core_clk = devm_clk_get(&pdev->dev, NULL); | 634 | hvs->core_clk = devm_clk_get(&pdev->dev, NULL); |
| 635 | if (IS_ERR(hvs->core_clk)) { | 635 | if (IS_ERR(hvs->core_clk)) { |
| 636 | dev_err(&pdev->dev, "Couldn't get core clock\n"); | 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 | hvs->dlist = hvs->regs + SCALER_DLIST_START; | 648 | hvs->dlist = hvs->regs + SCALER_DLIST_START; |
| 649 | else | 649 | else |
| 650 | hvs->dlist = hvs->regs + SCALER5_DLIST_START; | 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 | * between planes when they don't overlap on the screen, but | 665 | * between planes when they don't overlap on the screen, but |
| 666 | * for now we just allocate globally. | 666 | * for now we just allocate globally. |
| 667 | */ | 667 | */ |
| 668 | if (!hvs->hvs5) | 668 | if (!vc4->is_vc5) |
| 669 | /* 48k words of 2x12-bit pixels */ | 669 | /* 48k words of 2x12-bit pixels */ |
| 670 | drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024); | 670 | drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024); |
| 671 | else | 671 | else |
| @@ -265,6 +265,9 @@ vc4_irq_enable(struct drm_device *dev) · 264 unmodified lines | |||
| 265 | { | 265 | { |
| 266 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 266 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 267 | 267 | ||
| 268 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 269 | return; | ||
| 270 | |||
| 268 | if (!vc4->v3d) | 271 | if (!vc4->v3d) |
| 269 | return; | 272 | return; |
| 270 | 273 | ||
| @@ -279,6 +282,9 @@ vc4_irq_disable(struct drm_device *dev) · 8 unmodified lines | |||
| 279 | { | 282 | { |
| 280 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 283 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 281 | 284 | ||
| 285 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 286 | return; | ||
| 287 | |||
| 282 | if (!vc4->v3d) | 288 | if (!vc4->v3d) |
| 283 | return; | 289 | return; |
| 284 | 290 | ||
| @@ -296,8 +302,12 @@ vc4_irq_disable(struct drm_device *dev) · 11 unmodified lines | |||
| 296 | 302 | ||
| 297 | int vc4_irq_install(struct drm_device *dev, int irq) | 303 | int vc4_irq_install(struct drm_device *dev, int irq) |
| 298 | { | 304 | { |
| 305 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 299 | int ret; | 306 | int ret; |
| 300 | 307 | ||
| 308 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 309 | return -ENODEV; | ||
| 310 | |||
| 301 | if (irq == IRQ_NOTCONNECTED) | 311 | if (irq == IRQ_NOTCONNECTED) |
| 302 | return -ENOTCONN; | 312 | return -ENOTCONN; |
| 303 | 313 | ||
| @@ -316,6 +326,9 @@ void vc4_irq_uninstall(struct drm_device *dev) · 12 unmodified lines | |||
| 316 | { | 326 | { |
| 317 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 327 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 318 | 328 | ||
| 329 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 330 | return; | ||
| 331 | |||
| 319 | vc4_irq_disable(dev); | 332 | vc4_irq_disable(dev); |
| 320 | free_irq(vc4->irq, dev); | 333 | free_irq(vc4->irq, dev); |
| 321 | } | 334 | } |
| @@ -326,6 +339,9 @@ void vc4_irq_reset(struct drm_device *dev) · 4 unmodified lines | |||
| 326 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 339 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 327 | unsigned long irqflags; | 340 | unsigned long irqflags; |
| 328 | 341 | ||
| 342 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 343 | return; | ||
| 344 | |||
| 329 | /* Acknowledge any stale IRQs. */ | 345 | /* Acknowledge any stale IRQs. */ |
| 330 | V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); | 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 | old_hvs_state->fifo_state[channel].pending_commit = NULL; | 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 | unsigned long state_rate = max(old_hvs_state->core_clock_rate, | 397 | unsigned long state_rate = max(old_hvs_state->core_clock_rate, |
| 398 | new_hvs_state->core_clock_rate); | 398 | new_hvs_state->core_clock_rate); |
| 399 | unsigned long core_rate = max_t(unsigned long, | 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 | vc4_ctm_commit(vc4, state); | 413 | vc4_ctm_commit(vc4, state); |
| 414 | 414 | ||
| 415 | if (vc4->hvs->hvs5) | 415 | if (vc4->is_vc5) |
| 416 | vc5_hvs_pv_muxing_commit(vc4, state); | 416 | vc5_hvs_pv_muxing_commit(vc4, state); |
| 417 | else | 417 | else |
| 418 | vc4_hvs_pv_muxing_commit(vc4, state); | 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 | drm_atomic_helper_cleanup_planes(dev, state); | 431 | drm_atomic_helper_cleanup_planes(dev, state); |
| 432 | 432 | ||
| 433 | if (vc4->hvs->hvs5) { | 433 | if (vc4->is_vc5) { |
| 434 | drm_dbg(dev, "Running the core clock at %lu Hz\n", | 434 | drm_dbg(dev, "Running the core clock at %lu Hz\n", |
| 435 | new_hvs_state->core_clock_rate); | 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 | struct drm_file *file_priv, | 479 | struct drm_file *file_priv, |
| 480 | const struct drm_mode_fb_cmd2 *mode_cmd) | 480 | const struct drm_mode_fb_cmd2 *mode_cmd) |
| 481 | { | 481 | { |
| 482 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 482 | struct drm_mode_fb_cmd2 mode_cmd_local; | 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 | /* If the user didn't specify a modifier, use the | 488 | /* If the user didn't specify a modifier, use the |
| 485 | * vc4_set_tiling_ioctl() state for the BO. | 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 | .fb_create = vc4_fb_create, | 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 | int vc4_kms_load(struct drm_device *dev) | 1010 | int vc4_kms_load(struct drm_device *dev) |
| 1001 | { | 1011 | { |
| 1002 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 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 | int ret; | 1013 | int ret; |
| 1006 | 1014 | ||
| 1007 | /* | 1015 | /* |
| @@ -1009,7 +1017,7 @@ int vc4_kms_load(struct drm_device *dev) · 1 unmodified line | |||
| 1009 | * the BCM2711, but the load tracker computations are used for | 1017 | * the BCM2711, but the load tracker computations are used for |
| 1010 | * the core clock rate calculation. | 1018 | * the core clock rate calculation. |
| 1011 | */ | 1019 | */ |
| 1012 | if (!is_vc5) { | 1020 | if (!vc4->is_vc5) { |
| 1013 | /* Start with the load tracker enabled. Can be | 1021 | /* Start with the load tracker enabled. Can be |
| 1014 | * disabled through the debugfs load_tracker file. | 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 | return ret; | 1033 | return ret; |
| 1026 | } | 1034 | } |
| 1027 | 1035 | ||
| 1028 | if (is_vc5) { | 1036 | if (vc4->is_vc5) { |
| 1029 | dev->mode_config.max_width = 7680; | 1037 | dev->mode_config.max_width = 7680; |
| 1030 | dev->mode_config.max_height = 7680; | 1038 | dev->mode_config.max_height = 7680; |
| 1031 | } else { | 1039 | } else { |
| @@ -1033,7 +1041,7 @@ int vc4_kms_load(struct drm_device *dev) · 1 unmodified line | |||
| 1033 | dev->mode_config.max_height = 2048; | 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 | dev->mode_config.helper_private = &vc4_mode_config_helpers; | 1045 | dev->mode_config.helper_private = &vc4_mode_config_helpers; |
| 1038 | dev->mode_config.preferred_depth = 24; | 1046 | dev->mode_config.preferred_depth = 24; |
| 1039 | dev->mode_config.async_page_flip = true; | 1047 | dev->mode_config.async_page_flip = true; |
| @@ -17,13 +17,27 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | void vc4_perfmon_get(struct vc4_perfmon *perfmon) | 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 | if (perfmon) | 25 | if (perfmon) |
| 21 | refcount_inc(&perfmon->refcnt); | 26 | refcount_inc(&perfmon->refcnt); |
| 22 | } | 27 | } |
| 23 | 28 | ||
| 24 | void vc4_perfmon_put(struct vc4_perfmon *perfmon) | 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 | kfree(perfmon); | 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 | unsigned int i; | 46 | unsigned int i; |
| 33 | u32 mask; | 47 | u32 mask; |
| 34 | 48 | ||
| 49 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 50 | return; | ||
| 51 | |||
| 35 | if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon)) | 52 | if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon)) |
| 36 | return; | 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 | unsigned int i; | 67 | unsigned int i; |
| 51 | 68 | ||
| 69 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 70 | return; | ||
| 71 | |||
| 52 | if (WARN_ON_ONCE(!vc4->active_perfmon || | 72 | if (WARN_ON_ONCE(!vc4->active_perfmon || |
| 53 | perfmon != vc4->active_perfmon)) | 73 | perfmon != vc4->active_perfmon)) |
| 54 | return; | 74 | return; |
| @@ -64,8 +84,12 @@ void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon, · 9 unmodified lines | |||
| 64 | 84 | ||
| 65 | struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) | 85 | struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) |
| 66 | { | 86 | { |
| 87 | struct vc4_dev *vc4 = vc4file->dev; | ||
| 67 | struct vc4_perfmon *perfmon; | 88 | struct vc4_perfmon *perfmon; |
| 68 | 89 | ||
| 90 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 91 | return NULL; | ||
| 92 | |||
| 69 | mutex_lock(&vc4file->perfmon.lock); | 93 | mutex_lock(&vc4file->perfmon.lock); |
| 70 | perfmon = idr_find(&vc4file->perfmon.idr, id); | 94 | perfmon = idr_find(&vc4file->perfmon.idr, id); |
| 71 | vc4_perfmon_get(perfmon); | 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 | void vc4_perfmon_open_file(struct vc4_file *vc4file) | 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 | mutex_init(&vc4file->perfmon.lock); | 108 | mutex_init(&vc4file->perfmon.lock); |
| 80 | idr_init_base(&vc4file->perfmon.idr, VC4_PERFMONID_MIN); | 109 | idr_init_base(&vc4file->perfmon.idr, VC4_PERFMONID_MIN); |
| 110 | vc4file->dev = vc4; | ||
| 81 | } | 111 | } |
| 82 | 112 | ||
| 83 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) | 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 | void vc4_perfmon_close_file(struct vc4_file *vc4file) | 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 | mutex_lock(&vc4file->perfmon.lock); | 129 | mutex_lock(&vc4file->perfmon.lock); |
| 95 | idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL); | 130 | idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL); |
| 96 | idr_destroy(&vc4file->perfmon.idr); | 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 | unsigned int i; | 142 | unsigned int i; |
| 108 | int ret; | 143 | int ret; |
| 109 | 144 | ||
| 145 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 146 | return -ENODEV; | ||
| 147 | |||
| 110 | if (!vc4->v3d) { | 148 | if (!vc4->v3d) { |
| 111 | DRM_DEBUG("Creating perfmon no VC4 V3D probed\n"); | 149 | DRM_DEBUG("Creating perfmon no VC4 V3D probed\n"); |
| 112 | return -ENODEV; | 150 | return -ENODEV; |
| @@ -127,6 +165,7 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, · 14 unmodified lines | |||
| 127 | GFP_KERNEL); | 165 | GFP_KERNEL); |
| 128 | if (!perfmon) | 166 | if (!perfmon) |
| 129 | return -ENOMEM; | 167 | return -ENOMEM; |
| 168 | perfmon->dev = vc4; | ||
| 130 | 169 | ||
| 131 | for (i = 0; i < req->ncounters; i++) | 170 | for (i = 0; i < req->ncounters; i++) |
| 132 | perfmon->events[i] = req->events[i]; | 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 | struct drm_vc4_perfmon_destroy *req = data; | 196 | struct drm_vc4_perfmon_destroy *req = data; |
| 158 | struct vc4_perfmon *perfmon; | 197 | struct vc4_perfmon *perfmon; |
| 159 | 198 | ||
| 199 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 200 | return -ENODEV; | ||
| 201 | |||
| 160 | if (!vc4->v3d) { | 202 | if (!vc4->v3d) { |
| 161 | DRM_DEBUG("Destroying perfmon no VC4 V3D probed\n"); | 203 | DRM_DEBUG("Destroying perfmon no VC4 V3D probed\n"); |
| 162 | return -ENODEV; | 204 | return -ENODEV; |
| @@ -182,6 +224,9 @@ int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, · 19 unmodified lines | |||
| 182 | struct vc4_perfmon *perfmon; | 224 | struct vc4_perfmon *perfmon; |
| 183 | int ret; | 225 | int ret; |
| 184 | 226 | ||
| 227 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 228 | return -ENODEV; | ||
| 229 | |||
| 185 | if (!vc4->v3d) { | 230 | if (!vc4->v3d) { |
| 186 | DRM_DEBUG("Getting perfmon no VC4 V3D probed\n"); | 231 | DRM_DEBUG("Getting perfmon no VC4 V3D probed\n"); |
| 187 | return -ENODEV; | 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 | /* Align it to 64 or 128 (hvs5) bytes */ | 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 | /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */ | 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 | return lbm; | 497 | return lbm; |
| 498 | } | 498 | } |
| @@ -608,7 +608,7 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) · 109 unmodified lines | |||
| 608 | ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, | 608 | ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, |
| 609 | &vc4_state->lbm, | 609 | &vc4_state->lbm, |
| 610 | lbm_size, | 610 | lbm_size, |
| 611 | vc4->hvs->hvs5 ? 64 : 32, | 611 | vc4->is_vc5 ? 64 : 32, |
| 612 | 0, 0); | 612 | 0, 0); |
| 613 | spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); | 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 | mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && | 917 | mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && |
| 918 | fb->format->has_alpha; | 918 | fb->format->has_alpha; |
| 919 | 919 | ||
| 920 | if (!vc4->hvs->hvs5) { | 920 | if (!vc4->is_vc5) { |
| 921 | /* Control word */ | 921 | /* Control word */ |
| 922 | vc4_dlist_write(vc4_state, | 922 | vc4_dlist_write(vc4_state, |
| 923 | SCALER_CTL0_VALID | | 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 | old_vc4_state = to_vc4_plane_state(plane->state); | 1322 | old_vc4_state = to_vc4_plane_state(plane->state); |
| 1323 | new_vc4_state = to_vc4_plane_state(new_plane_state); | 1323 | new_vc4_state = to_vc4_plane_state(new_plane_state); |
| 1324 | |||
| 1325 | if (!new_vc4_state->hw_dlist) | ||
| 1326 | return -EINVAL; | ||
| 1327 | |||
| 1324 | if (old_vc4_state->dlist_count != new_vc4_state->dlist_count || | 1328 | if (old_vc4_state->dlist_count != new_vc4_state->dlist_count || |
| 1325 | old_vc4_state->pos0_offset != new_vc4_state->pos0_offset || | 1329 | old_vc4_state->pos0_offset != new_vc4_state->pos0_offset || |
| 1326 | old_vc4_state->pos2_offset != new_vc4_state->pos2_offset || | 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 | .atomic_async_update = vc4_plane_atomic_async_update, | 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 | static bool vc4_format_mod_supported(struct drm_plane *plane, | 1399 | static bool vc4_format_mod_supported(struct drm_plane *plane, |
| 1389 | uint32_t format, | 1400 | uint32_t format, |
| 1390 | uint64_t modifier) | 1401 | uint64_t modifier) |
| @@ -1453,14 +1464,13 @@ static const struct drm_plane_funcs vc4_plane_funcs = { · 62 unmodified lines | |||
| 1453 | struct drm_plane *vc4_plane_init(struct drm_device *dev, | 1464 | struct drm_plane *vc4_plane_init(struct drm_device *dev, |
| 1454 | enum drm_plane_type type) | 1465 | enum drm_plane_type type) |
| 1455 | { | 1466 | { |
| 1467 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 1456 | struct drm_plane *plane = NULL; | 1468 | struct drm_plane *plane = NULL; |
| 1457 | struct vc4_plane *vc4_plane; | 1469 | struct vc4_plane *vc4_plane; |
| 1458 | u32 formats[ARRAY_SIZE(hvs_formats)]; | 1470 | u32 formats[ARRAY_SIZE(hvs_formats)]; |
| 1459 | int num_formats = 0; | 1471 | int num_formats = 0; |
| 1460 | int ret = 0; | 1472 | int ret = 0; |
| 1461 | unsigned i; | 1473 | unsigned i; |
| 1462 | bool hvs5 = of_device_is_compatible(dev->dev->of_node, | ||
| 1463 | "brcm,bcm2711-vc5"); | ||
| 1464 | static const uint64_t modifiers[] = { | 1474 | static const uint64_t modifiers[] = { |
| 1465 | DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, | 1475 | DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, |
| 1466 | DRM_FORMAT_MOD_BROADCOM_SAND128, | 1476 | DRM_FORMAT_MOD_BROADCOM_SAND128, |
| @@ -1476,7 +1486,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, · 9 unmodified lines | |||
| 1476 | return ERR_PTR(-ENOMEM); | 1486 | return ERR_PTR(-ENOMEM); |
| 1477 | 1487 | ||
| 1478 | for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { | 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 | formats[num_formats] = hvs_formats[i].drm; | 1490 | formats[num_formats] = hvs_formats[i].drm; |
| 1481 | num_formats++; | 1491 | num_formats++; |
| 1482 | } | 1492 | } |
| @@ -1490,7 +1500,10 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, · 7 unmodified lines | |||
| 1490 | if (ret) | 1500 | if (ret) |
| 1491 | return ERR_PTR(ret); | 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 | drm_plane_create_alpha_property(plane); | 1508 | drm_plane_create_alpha_property(plane); |
| 1496 | drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, | 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 | int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) | 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 | struct vc4_rcl_setup setup = {0}; | 597 | struct vc4_rcl_setup setup = {0}; |
| 597 | struct drm_vc4_submit_cl *args = exec->args; | 598 | struct drm_vc4_submit_cl *args = exec->args; |
| 598 | bool has_bin = args->bin_cl_size != 0; | 599 | bool has_bin = args->bin_cl_size != 0; |
| 599 | int ret; | 600 | int ret; |
| 600 | 601 | ||
| 602 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 603 | return -ENODEV; | ||
| 604 | |||
| 601 | if (args->min_x_tile > args->max_x_tile || | 605 | if (args->min_x_tile > args->max_x_tile || |
| 602 | args->min_y_tile > args->max_y_tile) { | 606 | args->min_y_tile > args->max_y_tile) { |
| 603 | DRM_DEBUG("Bad render tile set (%d,%d)-(%d,%d)\n", | 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 | int | 127 | int |
| 128 | vc4_v3d_pm_get(struct vc4_dev *vc4) | 128 | vc4_v3d_pm_get(struct vc4_dev *vc4) |
| 129 | { | 129 | { |
| 130 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 131 | return -ENODEV; | ||
| 132 | |||
| 130 | mutex_lock(&vc4->power_lock); | 133 | mutex_lock(&vc4->power_lock); |
| 131 | if (vc4->power_refcount++ == 0) { | 134 | if (vc4->power_refcount++ == 0) { |
| 132 | int ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); | 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 | void | 148 | void |
| 146 | vc4_v3d_pm_put(struct vc4_dev *vc4) | 149 | vc4_v3d_pm_put(struct vc4_dev *vc4) |
| 147 | { | 150 | { |
| 151 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 152 | return; | ||
| 153 | |||
| 148 | mutex_lock(&vc4->power_lock); | 154 | mutex_lock(&vc4->power_lock); |
| 149 | if (--vc4->power_refcount == 0) { | 155 | if (--vc4->power_refcount == 0) { |
| 150 | pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev); | 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 | uint64_t seqno = 0; | 178 | uint64_t seqno = 0; |
| 173 | struct vc4_exec_info *exec; | 179 | struct vc4_exec_info *exec; |
| 174 | 180 | ||
| 181 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 182 | return -ENODEV; | ||
| 183 | |||
| 175 | try_again: | 184 | try_again: |
| 176 | spin_lock_irqsave(&vc4->job_lock, irqflags); | 185 | spin_lock_irqsave(&vc4->job_lock, irqflags); |
| 177 | slot = ffs(~vc4->bin_alloc_used); | 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 | int ret = 0; | 326 | int ret = 0; |
| 318 | 327 | ||
| 328 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 329 | return -ENODEV; | ||
| 330 | |||
| 319 | mutex_lock(&vc4->bin_bo_lock); | 331 | mutex_lock(&vc4->bin_bo_lock); |
| 320 | 332 | ||
| 321 | if (used && *used) | 333 | if (used && *used) |
| @@ -348,6 +360,9 @@ static void bin_bo_release(struct kref *ref) · 26 unmodified lines | |||
| 348 | 360 | ||
| 349 | void vc4_v3d_bin_bo_put(struct vc4_dev *vc4) | 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 | mutex_lock(&vc4->bin_bo_lock); | 366 | mutex_lock(&vc4->bin_bo_lock); |
| 352 | kref_put(&vc4->bin_bo_kref, bin_bo_release); | 367 | kref_put(&vc4->bin_bo_kref, bin_bo_release); |
| 353 | mutex_unlock(&vc4->bin_bo_lock); | 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 | struct drm_gem_cma_object * | 105 | struct drm_gem_cma_object * |
| 106 | vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) | 106 | vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) |
| 107 | { | 107 | { |
| 108 | struct vc4_dev *vc4 = exec->dev; | ||
| 108 | struct drm_gem_cma_object *obj; | 109 | struct drm_gem_cma_object *obj; |
| 109 | struct vc4_bo *bo; | 110 | struct vc4_bo *bo; |
| 110 | 111 | ||
| 112 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 113 | return NULL; | ||
| 114 | |||
| 111 | if (hindex >= exec->bo_count) { | 115 | if (hindex >= exec->bo_count) { |
| 112 | DRM_DEBUG("BO index %d greater than BO count %d\n", | 116 | DRM_DEBUG("BO index %d greater than BO count %d\n", |
| 113 | hindex, exec->bo_count); | 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 | uint32_t offset, uint8_t tiling_format, | 164 | uint32_t offset, uint8_t tiling_format, |
| 161 | uint32_t width, uint32_t height, uint8_t cpp) | 165 | uint32_t width, uint32_t height, uint8_t cpp) |
| 162 | { | 166 | { |
| 167 | struct vc4_dev *vc4 = exec->dev; | ||
| 163 | uint32_t aligned_width, aligned_height, stride, size; | 168 | uint32_t aligned_width, aligned_height, stride, size; |
| 164 | uint32_t utile_w = utile_width(cpp); | 169 | uint32_t utile_w = utile_width(cpp); |
| 165 | uint32_t utile_h = utile_height(cpp); | 170 | uint32_t utile_h = utile_height(cpp); |
| 166 | 171 | ||
| 172 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 173 | return false; | ||
| 174 | |||
| 167 | /* The shaded vertex format stores signed 12.4 fixed point | 175 | /* The shaded vertex format stores signed 12.4 fixed point |
| 168 | * (-2048,2047) offsets from the viewport center, so we should | 176 | * (-2048,2047) offsets from the viewport center, so we should |
| 169 | * never have a render target larger than 4096. The texture | 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 | void *unvalidated, | 490 | void *unvalidated, |
| 483 | struct vc4_exec_info *exec) | 491 | struct vc4_exec_info *exec) |
| 484 | { | 492 | { |
| 493 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 485 | uint32_t len = exec->args->bin_cl_size; | 494 | uint32_t len = exec->args->bin_cl_size; |
| 486 | uint32_t dst_offset = 0; | 495 | uint32_t dst_offset = 0; |
| 487 | uint32_t src_offset = 0; | 496 | uint32_t src_offset = 0; |
| 488 | 497 | ||
| 498 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 499 | return -ENODEV; | ||
| 500 | |||
| 489 | while (src_offset < len) { | 501 | while (src_offset < len) { |
| 490 | void *dst_pkt = validated + dst_offset; | 502 | void *dst_pkt = validated + dst_offset; |
| 491 | void *src_pkt = unvalidated + src_offset; | 503 | void *src_pkt = unvalidated + src_offset; |
| @@ -926,9 +938,13 @@ int · 434 unmodified lines | |||
| 926 | vc4_validate_shader_recs(struct drm_device *dev, | 938 | vc4_validate_shader_recs(struct drm_device *dev, |
| 927 | struct vc4_exec_info *exec) | 939 | struct vc4_exec_info *exec) |
| 928 | { | 940 | { |
| 941 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 929 | uint32_t i; | 942 | uint32_t i; |
| 930 | int ret = 0; | 943 | int ret = 0; |
| 931 | 944 | ||
| 945 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 946 | return -ENODEV; | ||
| 947 | |||
| 932 | for (i = 0; i < exec->shader_state_count; i++) { | 948 | for (i = 0; i < exec->shader_state_count; i++) { |
| 933 | ret = validate_gl_shader_rec(dev, exec, &exec->shader_state[i]); | 949 | ret = validate_gl_shader_rec(dev, exec, &exec->shader_state[i]); |
| 934 | if (ret) | 950 | if (ret) |
| @@ -778,6 +778,7 @@ vc4_handle_branch_target(struct vc4_shader_validation_state *validation_state) · 777 unmodified lines | |||
| 778 | struct vc4_validated_shader_info * | 778 | struct vc4_validated_shader_info * |
| 779 | vc4_validate_shader(struct drm_gem_cma_object *shader_obj) | 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 | bool found_shader_end = false; | 782 | bool found_shader_end = false; |
| 782 | int shader_end_ip = 0; | 783 | int shader_end_ip = 0; |
| 783 | uint32_t last_thread_switch_ip = -3; | 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 | struct vc4_validated_shader_info *validated_shader = NULL; | 786 | struct vc4_validated_shader_info *validated_shader = NULL; |
| 786 | struct vc4_shader_validation_state validation_state; | 787 | struct vc4_shader_validation_state validation_state; |
| 787 | 788 | ||
| 789 | if (WARN_ON_ONCE(vc4->is_vc5)) | ||
| 790 | return NULL; | ||
| 791 | |||
| 788 | memset(&validation_state, 0, sizeof(validation_state)); | 792 | memset(&validation_state, 0, sizeof(validation_state)); |
| 789 | validation_state.shader = shader_obj->vaddr; | 793 | validation_state.shader = shader_obj->vaddr; |
| 790 | validation_state.max_ip = shader_obj->base.size / sizeof(uint64_t); | 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 | * the whole buffer. | 71 | * the whole buffer. |
| 72 | */ | 72 | */ |
| 73 | vma->vm_flags &= ~VM_PFNMAP; | 73 | vma->vm_flags &= ~VM_PFNMAP; |
| 74 | vma->vm_flags |= VM_MIXEDMAP; | 74 | vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; |
| 75 | vma->vm_pgoff = 0; | 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 | if (!input_device->hid_desc) | 199 | if (!input_device->hid_desc) |
| 200 | goto cleanup; | 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 | if (input_device->report_desc_size == 0) { | 204 | if (input_device->report_desc_size == 0) { |
| 204 | input_device->dev_info_status = -EINVAL; | 205 | input_device->dev_info_status = -EINVAL; |
| 205 | goto cleanup; | 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 | memcpy(input_device->report_desc, | 219 | memcpy(input_device->report_desc, |
| 219 | ((unsigned char *)desc) + desc->bLength, | 220 | ((unsigned char *)desc) + desc->bLength, |
| 220 | desc->desc[0].wDescriptorLength); | 221 | le16_to_cpu(desc->desc[0].wDescriptorLength)); |
| 221 | 222 | ||
| 222 | /* Send the ack */ | 223 | /* Send the ack */ |
| 223 | memset(&ack, 0, sizeof(struct mousevsc_prt_msg)); | 224 | memset(&ack, 0, sizeof(struct mousevsc_prt_msg)); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/cpu.h> | 21 | #include <linux/cpu.h> |
| 22 | #include <linux/hyperv.h> | 22 | #include <linux/hyperv.h> |
| 23 | #include <asm/mshyperv.h> | 23 | #include <asm/mshyperv.h> |
| 24 | #include <linux/sched/isolation.h> | ||
| 24 | 25 | ||
| 25 | #include "hyperv_vmbus.h" | 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 | if (newchannel->offermsg.offer.sub_channel_index == 0) { | 640 | if (newchannel->offermsg.offer.sub_channel_index == 0) { |
| 640 | mutex_unlock(&vmbus_connection.channel_mutex); | 641 | mutex_unlock(&vmbus_connection.channel_mutex); |
| 642 | cpus_read_unlock(); | ||
| 641 | /* | 643 | /* |
| 642 | * Don't call free_channel(), because newchannel->kobj | 644 | * Don't call free_channel(), because newchannel->kobj |
| 643 | * is not initialized yet. | 645 | * is not initialized yet. |
| @@ -728,16 +730,20 @@ static void init_vp_index(struct vmbus_channel *channel) · 84 unmodified lines | |||
| 728 | u32 i, ncpu = num_online_cpus(); | 730 | u32 i, ncpu = num_online_cpus(); |
| 729 | cpumask_var_t available_mask; | 731 | cpumask_var_t available_mask; |
| 730 | struct cpumask *allocated_mask; | 732 | struct cpumask *allocated_mask; |
| 733 | const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ); | ||
| 731 | u32 target_cpu; | 734 | u32 target_cpu; |
| 732 | int numa_node; | 735 | int numa_node; |
| 733 | 736 | ||
| 734 | if (!perf_chn || | 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 | * If the channel is not a performance critical | 741 | * If the channel is not a performance critical |
| 738 | * channel, bind it to VMBUS_CONNECT_CPU. | 742 | * channel, bind it to VMBUS_CONNECT_CPU. |
| 739 | * In case alloc_cpumask_var() fails, bind it to | 743 | * In case alloc_cpumask_var() fails, bind it to |
| 740 | * VMBUS_CONNECT_CPU. | 744 | * VMBUS_CONNECT_CPU. |
| 745 | * If all the cpus are isolated, bind it to | ||
| 746 | * VMBUS_CONNECT_CPU. | ||
| 741 | */ | 747 | */ |
| 742 | channel->target_cpu = VMBUS_CONNECT_CPU; | 748 | channel->target_cpu = VMBUS_CONNECT_CPU; |
| 743 | if (perf_chn) | 749 | if (perf_chn) |
| @@ -758,17 +764,19 @@ static void init_vp_index(struct vmbus_channel *channel) · 14 unmodified lines | |||
| 758 | } | 764 | } |
| 759 | allocated_mask = &hv_context.hv_numa_map[numa_node]; | 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 | * We have cycled through all the CPUs in the node; | 773 | * We have cycled through all the CPUs in the node; |
| 764 | * reset the allocated map. | 774 | * reset the allocated map. |
| 765 | */ | 775 | */ |
| 766 | cpumask_clear(allocated_mask); | 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 | target_cpu = cpumask_first(available_mask); | 780 | target_cpu = cpumask_first(available_mask); |
| 773 | cpumask_set_cpu(target_cpu, allocated_mask); | 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 | in_msg = kvp_transaction.kvp_msg; | 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 | * in utf16; convert it to utf8 strings. | 398 | * in utf16; convert it to utf8 strings. |
| 399 | * The host assures us that the utf16 strings will not exceed | 399 | * The host assures us that the utf16 strings will not exceed |
| 400 | * the max lengths specified. We will however, reserve room | 400 | * the max lengths specified. We will however, reserve room |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/kernel_stat.h> | 21 | #include <linux/kernel_stat.h> |
| 22 | #include <linux/clockchips.h> | 22 | #include <linux/clockchips.h> |
| 23 | #include <linux/cpu.h> | 23 | #include <linux/cpu.h> |
| 24 | #include <linux/sched/isolation.h> | ||
| 24 | #include <linux/sched/task_stack.h> | 25 | #include <linux/sched/task_stack.h> |
| 25 | 26 | ||
| 26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| @@ -1770,6 +1771,9 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel, · 1743 unmodified lines | |||
| 1770 | if (target_cpu >= nr_cpumask_bits) | 1771 | if (target_cpu >= nr_cpumask_bits) |
| 1771 | return -EINVAL; | 1772 | return -EINVAL; |
| 1772 | 1773 | ||
| 1774 | if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ))) | ||
| 1775 | return -EINVAL; | ||
| 1776 | |||
| 1773 | /* No CPUs should come up or down during this. */ | 1777 | /* No CPUs should come up or down during this. */ |
| 1774 | cpus_read_lock(); | 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 | .board_names = { | 261 | .board_names = { |
| 262 | "ROG CROSSHAIR VIII FORMULA" | 262 | "ROG CROSSHAIR VIII FORMULA", |
| 263 | "ROG CROSSHAIR VIII HERO", | 263 | "ROG CROSSHAIR VIII HERO", |
| 264 | "ROG CROSSHAIR VIII HERO (WI-FI)", | 264 | "ROG CROSSHAIR VIII HERO (WI-FI)", |
| 265 | }, | 265 | }, |
| @@ -1228,10 +1228,15 @@ EXPORT_SYMBOL_GPL(occ_setup); · 1227 unmodified lines | |||
| 1228 | 1228 | ||
| 1229 | void occ_shutdown(struct occ *occ) | 1229 | void occ_shutdown(struct occ *occ) |
| 1230 | { | 1230 | { |
| 1231 | mutex_lock(&occ->lock); | ||
| 1232 | |||
| 1231 | occ_shutdown_sysfs(occ); | 1233 | occ_shutdown_sysfs(occ); |
| 1232 | 1234 | ||
| 1233 | if (occ->hwmon) | 1235 | if (occ->hwmon) |
| 1234 | hwmon_device_unregister(occ->hwmon); | 1236 | hwmon_device_unregister(occ->hwmon); |
| 1237 | occ->hwmon = NULL; | ||
| 1238 | |||
| 1239 | mutex_unlock(&occ->lock); | ||
| 1235 | } | 1240 | } |
| 1236 | EXPORT_SYMBOL_GPL(occ_shutdown); | 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 | int ret; | 478 | int ret; |
| 479 | 479 | ||
| 480 | if (IS_ERR(dev->clk)) | ||
| 481 | return PTR_ERR(dev->clk); | ||
| 482 | |||
| 483 | if (prepare) { | 480 | if (prepare) { |
| 484 | /* Optional interface clock */ | 481 | /* Optional interface clock */ |
| 485 | ret = clk_prepare_enable(dev->pclk); | 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 | goto exit_reset; | 320 | goto exit_reset; |
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | dev->clk = devm_clk_get(&pdev->dev, NULL); | 323 | dev->clk = devm_clk_get_optional(&pdev->dev, NULL); |
| 324 | if (!i2c_dw_prepare_clk(dev, true)) { | 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 | u64 clk_khz; | 334 | u64 clk_khz; |
| 326 | 335 | ||
| 327 | dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; | 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 | if (ret < 0) { | 1420 | if (ret < 0) { |
| 1421 | dev_err(&pdev->dev, | 1421 | dev_err(&pdev->dev, |
| 1422 | "Request I2C IRQ %d fail\n", irq); | 1422 | "Request I2C IRQ %d fail\n", irq); |
| 1423 | return ret; | 1423 | goto err_bulk_unprepare; |
| 1424 | } | 1424 | } |
| 1425 | 1425 | ||
| 1426 | i2c_set_adapdata(&i2c->adap, i2c); | 1426 | i2c_set_adapdata(&i2c->adap, i2c); |
| 1427 | ret = i2c_add_adapter(&i2c->adap); | 1427 | ret = i2c_add_adapter(&i2c->adap); |
| 1428 | if (ret) | 1428 | if (ret) |
| 1429 | return ret; | 1429 | goto err_bulk_unprepare; |
| 1430 | 1430 | ||
| 1431 | platform_set_drvdata(pdev, i2c); | 1431 | platform_set_drvdata(pdev, i2c); |
| 1432 | 1432 | ||
| 1433 | return 0; | 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 | static int mtk_i2c_remove(struct platform_device *pdev) | 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 | static int __init npcm_i2c_init(void) | 2372 | static int __init npcm_i2c_init(void) |
| 2373 | { | 2373 | { |
| 2374 | npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL); | 2374 | npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL); |
| 2375 | platform_driver_register(&npcm_i2c_bus_driver); | 2375 | return platform_driver_register(&npcm_i2c_bus_driver); |
| 2376 | return 0; | ||
| 2377 | } | 2376 | } |
| 2378 | module_init(npcm_i2c_init); | 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 | data->trig->ops = &bma180_trigger_ops; | 1007 | data->trig->ops = &bma180_trigger_ops; |
| 1008 | iio_trigger_set_drvdata(data->trig, indio_dev); | 1008 | iio_trigger_set_drvdata(data->trig, indio_dev); |
| 1009 | indio_dev->trig = iio_trigger_get(data->trig); | ||
| 1010 | 1009 | ||
| 1011 | ret = iio_trigger_register(data->trig); | 1010 | ret = iio_trigger_register(data->trig); |
| 1012 | if (ret) | 1011 | if (ret) |
| 1013 | goto err_trigger_free; | 1012 | goto err_trigger_free; |
| 1013 | |||
| 1014 | indio_dev->trig = iio_trigger_get(data->trig); | ||
| 1014 | } | 1015 | } |
| 1015 | 1016 | ||
| 1016 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 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 | data->dready_trig->ops = &kxcjk1013_trigger_ops; | 1555 | data->dready_trig->ops = &kxcjk1013_trigger_ops; |
| 1556 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); | 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 | ret = iio_trigger_register(data->dready_trig); | 1557 | ret = iio_trigger_register(data->dready_trig); |
| 1560 | if (ret) | 1558 | if (ret) |
| 1561 | goto err_poweroff; | 1559 | goto err_poweroff; |
| 1562 | 1560 | ||
| 1561 | indio_dev->trig = iio_trigger_get(data->dready_trig); | ||
| 1562 | |||
| 1563 | data->motion_trig->ops = &kxcjk1013_trigger_ops; | 1563 | data->motion_trig->ops = &kxcjk1013_trigger_ops; |
| 1564 | iio_trigger_set_drvdata(data->motion_trig, indio_dev); | 1564 | iio_trigger_set_drvdata(data->motion_trig, indio_dev); |
| 1565 | ret = iio_trigger_register(data->motion_trig); | 1565 | ret = iio_trigger_register(data->motion_trig); |
| @@ -1511,10 +1511,14 @@ static int mma8452_reset(struct i2c_client *client) · 1510 unmodified lines | |||
| 1511 | int i; | 1511 | int i; |
| 1512 | int ret; | 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 | MMA8452_CTRL_REG2_RST); | 1521 | MMA8452_CTRL_REG2_RST); |
| 1516 | if (ret < 0) | ||
| 1517 | return ret; | ||
| 1518 | 1522 | ||
| 1519 | for (i = 0; i < 10; i++) { | 1523 | for (i = 0; i < 10; i++) { |
| 1520 | usleep_range(100, 200); | 1524 | usleep_range(100, 200); |
| @@ -1557,11 +1561,13 @@ static int mma8452_probe(struct i2c_client *client, · 36 unmodified lines | |||
| 1557 | mutex_init(&data->lock); | 1561 | mutex_init(&data->lock); |
| 1558 | 1562 | ||
| 1559 | data->chip_info = device_get_match_data(&client->dev); | 1563 | data->chip_info = device_get_match_data(&client->dev); |
| 1560 | if (!data->chip_info && id) { | 1564 | if (!data->chip_info) { |
| 1561 | data->chip_info = &mma_chip_info_table[id->driver_data]; | 1565 | if (id) { |
| 1562 | } else { | 1566 | data->chip_info = &mma_chip_info_table[id->driver_data]; |
| 1563 | dev_err(&client->dev, "unknown device model\n"); | 1567 | } else { |
| 1564 | return -ENODEV; | 1568 | dev_err(&client->dev, "unknown device model\n"); |
| 1569 | return -ENODEV; | ||
| 1570 | } | ||
| 1565 | } | 1571 | } |
| 1566 | 1572 | ||
| 1567 | ret = iio_read_mount_matrix(&client->dev, &data->orientation); | 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 | data->dready_trig->ops = &mxc4005_trigger_ops; | 457 | data->dready_trig->ops = &mxc4005_trigger_ops; |
| 458 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); | 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 | ret = devm_iio_trigger_register(&client->dev, | 459 | ret = devm_iio_trigger_register(&client->dev, |
| 462 | data->dready_trig); | 460 | data->dready_trig); |
| 463 | if (ret) { | 461 | if (ret) { |
| @@ -465,6 +463,8 @@ static int mxc4005_probe(struct i2c_client *client, · 1 unmodified line | |||
| 465 | "failed to register trigger\n"); | 463 | "failed to register trigger\n"); |
| 466 | return ret; | 464 | return ret; |
| 467 | } | 465 | } |
| 466 | |||
| 467 | indio_dev->trig = iio_trigger_get(data->dready_trig); | ||
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | return devm_iio_device_register(&client->dev, indio_dev); | 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 | if (!try_module_get(cl->dev->driver->owner)) { | 323 | if (!try_module_get(cl->dev->driver->owner)) { |
| 324 | mutex_unlock(®istered_clients_lock); | 324 | mutex_unlock(®istered_clients_lock); |
| 325 | of_node_put(cln); | ||
| 325 | return ERR_PTR(-ENODEV); | 326 | return ERR_PTR(-ENODEV); |
| 326 | } | 327 | } |
| 327 | 328 | ||
| 328 | get_device(cl->dev); | 329 | get_device(cl->dev); |
| 329 | cl->info = info; | 330 | cl->info = info; |
| 330 | mutex_unlock(®istered_clients_lock); | 331 | mutex_unlock(®istered_clients_lock); |
| 332 | of_node_put(cln); | ||
| 331 | return cl; | 333 | return cl; |
| 332 | } | 334 | } |
| 333 | 335 | ||
| 334 | mutex_unlock(®istered_clients_lock); | 336 | mutex_unlock(®istered_clients_lock); |
| 337 | of_node_put(cln); | ||
| 335 | 338 | ||
| 336 | return ERR_PTR(-EPROBE_DEFER); | 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 | return -EOPNOTSUPP; | 186 | return -EOPNOTSUPP; |
| 187 | } | 187 | } |
| 188 | scu = syscon_node_to_regmap(syscon); | 188 | scu = syscon_node_to_regmap(syscon); |
| 189 | of_node_put(syscon); | ||
| 189 | if (IS_ERR(scu)) { | 190 | if (IS_ERR(scu)) { |
| 190 | dev_warn(data->dev, "Failed to get syscon regmap\n"); | 191 | dev_warn(data->dev, "Failed to get syscon regmap\n"); |
| 191 | return -EOPNOTSUPP; | 192 | return -EOPNOTSUPP; |
| @@ -196,6 +196,14 @@ static const struct dmi_system_id axp288_adc_ts_bias_override[] = { · 195 unmodified lines | |||
| 196 | }, | 196 | }, |
| 197 | .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA, | 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 | i = 0; | 334 | i = 0; |
| 335 | device_for_each_child_node(&pdev->dev, fwnode) { | 335 | device_for_each_child_node(&pdev->dev, fwnode) { |
| 336 | ret = fwnode_property_read_u32(fwnode, "reg", &channel); | 336 | ret = fwnode_property_read_u32(fwnode, "reg", &channel); |
| 337 | if (ret) | 337 | if (ret) { |
| 338 | fwnode_handle_put(fwnode); | ||
| 338 | return ret; | 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 | return -EINVAL; | 344 | return -EINVAL; |
| 345 | } | ||
| 342 | 346 | ||
| 343 | chan_array[i].type = IIO_VOLTAGE; | 347 | chan_array[i].type = IIO_VOLTAGE; |
| 344 | chan_array[i].indexed = 1; | 348 | chan_array[i].indexed = 1; |
| @@ -64,6 +64,7 @@ struct stm32_adc_priv; · 63 unmodified lines | |||
| 64 | * @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet) | 64 | * @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet) |
| 65 | * @has_syscfg: SYSCFG capability flags | 65 | * @has_syscfg: SYSCFG capability flags |
| 66 | * @num_irqs: number of interrupt lines | 66 | * @num_irqs: number of interrupt lines |
| 67 | * @num_adcs: maximum number of ADC instances in the common registers | ||
| 67 | */ | 68 | */ |
| 68 | struct stm32_adc_priv_cfg { | 69 | struct stm32_adc_priv_cfg { |
| 69 | const struct stm32_adc_common_regs *regs; | 70 | const struct stm32_adc_common_regs *regs; |
| @@ -71,6 +72,7 @@ struct stm32_adc_priv_cfg { · 1 unmodified line | |||
| 71 | u32 max_clk_rate_hz; | 72 | u32 max_clk_rate_hz; |
| 72 | unsigned int has_syscfg; | 73 | unsigned int has_syscfg; |
| 73 | unsigned int num_irqs; | 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 | * before invoking the interrupt handler (e.g. call ISR only for | 354 | * before invoking the interrupt handler (e.g. call ISR only for |
| 353 | * IRQ-enabled ADCs). | 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 | if ((status & priv->cfg->regs->eoc_msk[i] && | 358 | if ((status & priv->cfg->regs->eoc_msk[i] && |
| 357 | stm32_adc_eoc_enabled(priv, i)) || | 359 | stm32_adc_eoc_enabled(priv, i)) || |
| 358 | (status & priv->cfg->regs->ovr_msk[i])) | 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 | .clk_sel = stm32f4_adc_clk_sel, | 794 | .clk_sel = stm32f4_adc_clk_sel, |
| 793 | .max_clk_rate_hz = 36000000, | 795 | .max_clk_rate_hz = 36000000, |
| 794 | .num_irqs = 1, | 796 | .num_irqs = 1, |
| 797 | .num_adcs = 3, | ||
| 795 | }; | 798 | }; |
| 796 | 799 | ||
| 797 | static const struct stm32_adc_priv_cfg stm32h7_adc_priv_cfg = { | 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 | .max_clk_rate_hz = 36000000, | 803 | .max_clk_rate_hz = 36000000, |
| 801 | .has_syscfg = HAS_VBOOSTER, | 804 | .has_syscfg = HAS_VBOOSTER, |
| 802 | .num_irqs = 1, | 805 | .num_irqs = 1, |
| 806 | .num_adcs = 2, | ||
| 803 | }; | 807 | }; |
| 804 | 808 | ||
| 805 | static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = { | 809 | static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = { |
| 806 | .regs = &stm32h7_adc_common_regs, | 810 | .regs = &stm32h7_adc_common_regs, |
| 807 | .clk_sel = stm32h7_adc_clk_sel, | 811 | .clk_sel = stm32h7_adc_clk_sel, |
| 808 | .max_clk_rate_hz = 40000000, | 812 | .max_clk_rate_hz = 36000000, |
| 809 | .has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD, | 813 | .has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD, |
| 810 | .num_irqs = 2, | 814 | .num_irqs = 2, |
| 815 | .num_adcs = 2, | ||
| 811 | }; | 816 | }; |
| 812 | 817 | ||
| 813 | static const struct of_device_id stm32_adc_of_match[] = { | 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 | else | 1365 | else |
| 1366 | ret = -EINVAL; | 1366 | ret = -EINVAL; |
| 1367 | 1367 | ||
| 1368 | if (mask == IIO_CHAN_INFO_PROCESSED && adc->vrefint.vrefint_cal) | 1368 | if (mask == IIO_CHAN_INFO_PROCESSED) |
| 1369 | *val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val; | 1369 | *val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val; |
| 1370 | 1370 | ||
| 1371 | iio_device_release_direct_mode(indio_dev); | 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 | struct stm32_adc *adc = iio_priv(indio_dev); | 1407 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1408 | const struct stm32_adc_regspec *regs = adc->cfg->regs; | 1408 | const struct stm32_adc_regspec *regs = adc->cfg->regs; |
| 1409 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); | 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 | /* Check ovr status right now, as ovr mask should be already disabled */ | 1411 | /* Check ovr status right now, as ovr mask should be already disabled */ |
| 1413 | if (status & regs->isr_ovr.mask) { | 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 | return IRQ_HANDLED; | 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 | return IRQ_NONE; | 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 | struct stm32_adc *adc = iio_priv(indio_dev); | 1430 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1437 | const struct stm32_adc_regspec *regs = adc->cfg->regs; | 1431 | const struct stm32_adc_regspec *regs = adc->cfg->regs; |
| 1438 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); | 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 | if (status & regs->isr_ovr.mask) { | 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 | for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { | 1970 | for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { |
| 1981 | if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) { | 1971 | if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) { |
| 1982 | adc->int_ch[i] = chan; | 1972 | if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) { |
| 1983 | 1973 | adc->int_ch[i] = chan; | |
| 1984 | if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) | 1974 | break; |
| 1985 | continue; | 1975 | } |
| 1986 | 1976 | ||
| 1987 | /* Get calibration data for vrefint channel */ | 1977 | /* Get calibration data for vrefint channel */ |
| 1988 | ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint); | 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 | return dev_err_probe(indio_dev->dev.parent, ret, | 1980 | return dev_err_probe(indio_dev->dev.parent, ret, |
| 1991 | "nvmem access error\n"); | 1981 | "nvmem access error\n"); |
| 1992 | } | 1982 | } |
| 1993 | if (ret == -ENOENT) | 1983 | if (ret == -ENOENT) { |
| 1994 | dev_dbg(&indio_dev->dev, "vrefint calibration not found\n"); | 1984 | dev_dbg(&indio_dev->dev, "vrefint calibration not found. Skip vrefint channel\n"); |
| 1995 | else | 1985 | return ret; |
| 1996 | adc->vrefint.vrefint_cal = vrefint; | 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 | strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ); | 2026 | strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ); |
| 2032 | ret = stm32_adc_populate_int_ch(indio_dev, name, val); | 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 | goto err; | 2031 | goto err; |
| 2035 | } else if (ret != -EINVAL) { | 2032 | } else if (ret != -EINVAL) { |
| 2036 | dev_err(&indio_dev->dev, "Invalid label %d\n", ret); | 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 | device_for_each_child_node(dev, node) { | 739 | device_for_each_child_node(dev, node) { |
| 740 | ret = fwnode_property_read_u32(node, "reg", &channel); | 740 | ret = fwnode_property_read_u32(node, "reg", &channel); |
| 741 | if (ret) | 741 | if (ret) |
| 742 | return ret; | 742 | goto err_child_out; |
| 743 | 743 | ||
| 744 | ret = fwnode_property_read_u32(node, "ti,gain", &tmp); | 744 | ret = fwnode_property_read_u32(node, "ti,gain", &tmp); |
| 745 | if (ret) { | 745 | if (ret) { |
| @@ -747,7 +747,7 @@ static int ads131e08_alloc_channels(struct iio_dev *indio_dev) · 1 unmodified line | |||
| 747 | } else { | 747 | } else { |
| 748 | ret = ads131e08_pga_gain_to_field_value(st, tmp); | 748 | ret = ads131e08_pga_gain_to_field_value(st, tmp); |
| 749 | if (ret < 0) | 749 | if (ret < 0) |
| 750 | return ret; | 750 | goto err_child_out; |
| 751 | 751 | ||
| 752 | channel_config[i].pga_gain = tmp; | 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 | } else { | 758 | } else { |
| 759 | ret = ads131e08_validate_channel_mux(st, tmp); | 759 | ret = ads131e08_validate_channel_mux(st, tmp); |
| 760 | if (ret) | 760 | if (ret) |
| 761 | return ret; | 761 | goto err_child_out; |
| 762 | 762 | ||
| 763 | channel_config[i].mux = tmp; | 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 | st->channel_config = channel_config; | 784 | st->channel_config = channel_config; |
| 785 | 785 | ||
| 786 | return 0; | 786 | return 0; |
| 787 | |||
| 788 | err_child_out: | ||
| 789 | fwnode_handle_put(node); | ||
| 790 | return ret; | ||
| 787 | } | 791 | } |
| 788 | 792 | ||
| 789 | static void ads131e08_regulator_disable(void *data) | 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 | irq = platform_get_irq(pdev, 0); | 1410 | irq = platform_get_irq(pdev, 0); |
| 1411 | if (irq < 0) | 1411 | if (irq < 0) |
| 1412 | return ret; | 1412 | return irq; |
| 1413 | 1413 | ||
| 1414 | ret = devm_request_irq(&pdev->dev, irq, &ams_irq, 0, "ams-irq", | 1414 | ret = devm_request_irq(&pdev->dev, irq, &ams_irq, 0, "ams-irq", |
| 1415 | indio_dev); | 1415 | indio_dev); |
| @@ -277,7 +277,7 @@ static int rescale_configure_channel(struct device *dev, · 276 unmodified lines | |||
| 277 | chan->ext_info = rescale->ext_info; | 277 | chan->ext_info = rescale->ext_info; |
| 278 | chan->type = rescale->cfg->type; | 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 | iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) { | 281 | iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) { |
| 282 | dev_info(dev, "using raw+scale source channel\n"); | 282 | dev_info(dev, "using raw+scale source channel\n"); |
| 283 | } else if (iio_channel_has_info(schan, IIO_CHAN_INFO_PROCESSED)) { | 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 | data->drdy_trig->ops = &ccs811_trigger_ops; | 500 | data->drdy_trig->ops = &ccs811_trigger_ops; |
| 501 | iio_trigger_set_drvdata(data->drdy_trig, indio_dev); | 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 | ret = iio_trigger_register(data->drdy_trig); | 502 | ret = iio_trigger_register(data->drdy_trig); |
| 505 | if (ret) | 503 | if (ret) |
| 506 | goto err_poweroff; | 504 | goto err_poweroff; |
| 505 | |||
| 506 | indio_dev->trig = iio_trigger_get(data->drdy_trig); | ||
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 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 | ADMV1014_DET_EN_MSK; | 700 | ADMV1014_DET_EN_MSK; |
| 701 | 701 | ||
| 702 | enable_reg = FIELD_PREP(ADMV1014_P1DB_COMPENSATION_MSK, st->p1db_comp ? 3 : 0) | | 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)) | | 703 | FIELD_PREP(ADMV1014_IF_AMP_PD_MSK, |
| 704 | FIELD_PREP(ADMV1014_BB_AMP_PD_MSK, st->input_mode) | | 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 | FIELD_PREP(ADMV1014_DET_EN_MSK, st->det_en); | 707 | FIELD_PREP(ADMV1014_DET_EN_MSK, st->det_en); |
| 706 | 708 | ||
| 707 | return __admv1014_spi_update_bits(st, ADMV1014_REG_ENABLE, enable_reg_msk, enable_reg); | 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 | ret = regmap_update_bits(mpu3050->map, MPU3050_PWR_MGM, | 875 | ret = regmap_update_bits(mpu3050->map, MPU3050_PWR_MGM, |
| 876 | MPU3050_PWR_MGM_SLEEP, 0); | 876 | MPU3050_PWR_MGM_SLEEP, 0); |
| 877 | if (ret) { | 877 | if (ret) { |
| 878 | regulator_bulk_disable(ARRAY_SIZE(mpu3050->regs), mpu3050->regs); | ||
| 878 | dev_err(mpu3050->dev, "error setting power mode\n"); | 879 | dev_err(mpu3050->dev, "error setting power mode\n"); |
| 879 | return ret; | 880 | return ret; |
| 880 | } | 881 | } |
| @@ -135,9 +135,12 @@ int hts221_allocate_trigger(struct iio_dev *iio_dev) · 134 unmodified lines | |||
| 135 | 135 | ||
| 136 | iio_trigger_set_drvdata(hw->trig, iio_dev); | 136 | iio_trigger_set_drvdata(hw->trig, iio_dev); |
| 137 | hw->trig->ops = &hts221_trigger_ops; | 137 | hw->trig->ops = &hts221_trigger_ops; |
| 138 | |||
| 139 | err = devm_iio_trigger_register(hw->dev, hw->trig); | ||
| 140 | |||
| 138 | iio_dev->trig = iio_trigger_get(hw->trig); | 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 | static int hts221_buffer_preenable(struct iio_dev *iio_dev) | 146 | static int hts221_buffer_preenable(struct iio_dev *iio_dev) |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include "inv_icm42600_buffer.h" | 17 | #include "inv_icm42600_buffer.h" |
| 18 | 18 | ||
| 19 | enum inv_icm42600_chip { | 19 | enum inv_icm42600_chip { |
| 20 | INV_CHIP_INVALID, | ||
| 20 | INV_CHIP_ICM42600, | 21 | INV_CHIP_ICM42600, |
| 21 | INV_CHIP_ICM42602, | 22 | INV_CHIP_ICM42602, |
| 22 | INV_CHIP_ICM42605, | 23 | INV_CHIP_ICM42605, |
| @@ -565,7 +565,7 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, · 564 unmodified lines | |||
| 565 | bool open_drain; | 565 | bool open_drain; |
| 566 | int ret; | 566 | int ret; |
| 567 | 567 | ||
| 568 | if (chip < 0 || chip >= INV_CHIP_NB) { | 568 | if (chip <= INV_CHIP_INVALID || chip >= INV_CHIP_NB) { |
| 569 | dev_err(dev, "invalid chip = %d\n", chip); | 569 | dev_err(dev, "invalid chip = %d\n", chip); |
| 570 | return -ENODEV; | 570 | return -ENODEV; |
| 571 | } | 571 | } |
| @@ -639,7 +639,7 @@ static int yas532_get_calibration_data(struct yas5xx *yas5xx) · 638 unmodified lines | |||
| 639 | dev_dbg(yas5xx->dev, "calibration data: %*ph\n", 14, data); | 639 | dev_dbg(yas5xx->dev, "calibration data: %*ph\n", 14, data); |
| 640 | 640 | ||
| 641 | /* Sanity check, is this all zeroes? */ | 641 | /* Sanity check, is this all zeroes? */ |
| 642 | if (memchr_inv(data, 0x00, 13)) { | 642 | if (memchr_inv(data, 0x00, 13) == NULL) { |
| 643 | if (!(data[13] & BIT(7))) | 643 | if (!(data[13] & BIT(7))) |
| 644 | dev_warn(yas5xx->dev, "calibration is blank!\n"); | 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 | break; | 885 | break; |
| 886 | ret = device_property_read_u32_array(dev, prop, pin_defs, | 886 | ret = device_property_read_u32_array(dev, prop, pin_defs, |
| 887 | ARRAY_SIZE(pin_defs)); | 887 | ARRAY_SIZE(pin_defs)); |
| 888 | if (ret) | ||
| 889 | break; | ||
| 890 | |||
| 888 | for (pin = 0; pin < SX9324_NUM_PINS; pin++) | 891 | for (pin = 0; pin < SX9324_NUM_PINS; pin++) |
| 889 | raw |= (pin_defs[pin] << (2 * pin)) & | 892 | raw |= (pin_defs[pin] << (2 * pin)) & |
| 890 | SX9324_REG_AFE_PH0_PIN_MASK(pin); | 893 | SX9324_REG_AFE_PH0_PIN_MASK(pin); |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | # Keep in alphabetical order | 6 | # Keep in alphabetical order |
| 7 | config IIO_RESCALE_KUNIT_TEST | 7 | config IIO_RESCALE_KUNIT_TEST |
| 8 | bool "Test IIO rescale conversion functions" | 8 | bool "Test IIO rescale conversion functions" |
| 9 | depends on KUNIT=y && !IIO_RESCALE | 9 | depends on KUNIT=y && IIO_RESCALE=y |
| 10 | default KUNIT_ALL_TESTS | 10 | default KUNIT_ALL_TESTS |
| 11 | help | 11 | help |
| 12 | If you want to run tests on the iio-rescale code say Y here. | 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 | # Keep in alphabetical order | 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 | obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o | 8 | obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o |
| 9 | CFLAGS_iio-test-format.o += $(DISABLE_STRUCTLEAK_PLUGIN) | 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 | iio_trigger_unregister(t->trig); | 192 | iio_trigger_unregister(t->trig); |
| 193 | irq_work_sync(&t->work); | ||
| 193 | iio_trigger_free(t->trig); | 194 | iio_trigger_free(t->trig); |
| 194 | 195 | ||
| 195 | list_del(&t->l); | 196 | list_del(&t->l); |
| @@ -987,7 +987,7 @@ static const struct of_device_id ipmmu_of_ids[] = { · 986 unmodified lines | |||
| 987 | .compatible = "renesas,ipmmu-r8a779a0", | 987 | .compatible = "renesas,ipmmu-r8a779a0", |
| 988 | .data = &ipmmu_features_rcar_gen4, | 988 | .data = &ipmmu_features_rcar_gen4, |
| 989 | }, { | 989 | }, { |
| 990 | .compatible = "renesas,rcar-gen4-ipmmu", | 990 | .compatible = "renesas,rcar-gen4-ipmmu-vmsa", |
| 991 | .data = &ipmmu_features_rcar_gen4, | 991 | .data = &ipmmu_features_rcar_gen4, |
| 992 | }, { | 992 | }, { |
| 993 | /* Terminator */ | 993 | /* Terminator */ |
| @@ -298,7 +298,7 @@ config XTENSA_MX · 297 unmodified lines | |||
| 298 | 298 | ||
| 299 | config XILINX_INTC | 299 | config XILINX_INTC |
| 300 | bool "Xilinx Interrupt Controller IP" | 300 | bool "Xilinx Interrupt Controller IP" |
| 301 | depends on MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP | 301 | depends on OF |
| 302 | select IRQ_DOMAIN | 302 | select IRQ_DOMAIN |
| 303 | help | 303 | help |
| 304 | Support for the Xilinx Interrupt Controller IP core. | 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 | continue; | 1035 | continue; |
| 1036 | 1036 | ||
| 1037 | cpu = of_cpu_node_to_id(cpu_node); | 1037 | cpu = of_cpu_node_to_id(cpu_node); |
| 1038 | of_node_put(cpu_node); | ||
| 1038 | if (WARN_ON(cpu < 0)) | 1039 | if (WARN_ON(cpu < 0)) |
| 1039 | continue; | 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 | for_each_child_of_node(affs, chld) | 1144 | for_each_child_of_node(affs, chld) |
| 1144 | build_fiq_affinity(irqc, chld); | 1145 | build_fiq_affinity(irqc, chld); |
| 1145 | } | 1146 | } |
| 1147 | of_node_put(affs); | ||
| 1146 | 1148 | ||
| 1147 | set_handle_irq(aic_handle_irq); | 1149 | set_handle_irq(aic_handle_irq); |
| 1148 | set_handle_fiq(aic_handle_fiq); | 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 | /* The PB11MPCore GIC needs to be configured in the syscon */ | 58 | /* The PB11MPCore GIC needs to be configured in the syscon */ |
| 59 | map = syscon_node_to_regmap(np); | 59 | map = syscon_node_to_regmap(np); |
| 60 | of_node_put(np); | ||
| 60 | if (!IS_ERR(map)) { | 61 | if (!IS_ERR(map)) { |
| 61 | /* new irq mode with no DCC */ | 62 | /* new irq mode with no DCC */ |
| 62 | regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, | 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 | gic_data.ppi_descs = kcalloc(gic_data.ppi_nr, sizeof(*gic_data.ppi_descs), GFP_KERNEL); | 1933 | gic_data.ppi_descs = kcalloc(gic_data.ppi_nr, sizeof(*gic_data.ppi_descs), GFP_KERNEL); |
| 1934 | if (!gic_data.ppi_descs) | 1934 | if (!gic_data.ppi_descs) |
| 1935 | return; | 1935 | goto out_put_node; |
| 1936 | 1936 | ||
| 1937 | nr_parts = of_get_child_count(parts_node); | 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 | continue; | 1973 | continue; |
| 1974 | 1974 | ||
| 1975 | cpu = of_cpu_node_to_id(cpu_node); | 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 | continue; | 1978 | continue; |
| 1979 | } | ||
| 1978 | 1980 | ||
| 1979 | pr_cont("%pOF[%d] ", cpu_node, cpu); | 1981 | pr_cont("%pOF[%d] ", cpu_node, cpu); |
| 1980 | 1982 | ||
| 1981 | cpumask_set_cpu(cpu, &part->mask); | 1983 | cpumask_set_cpu(cpu, &part->mask); |
| 1984 | of_node_put(cpu_node); | ||
| 1982 | } | 1985 | } |
| 1983 | 1986 | ||
| 1984 | pr_cont("}\n"); | 1987 | pr_cont("}\n"); |
| @@ -39,6 +39,12 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #define LIOINTC_ERRATA_IRQ 10 | 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 | struct liointc_handler_data { | 48 | struct liointc_handler_data { |
| 43 | struct liointc_priv *priv; | 49 | struct liointc_priv *priv; |
| 44 | u32 parent_int_map; | 50 | u32 parent_int_map; |
| @@ -57,7 +63,7 @@ static void liointc_chained_handle_irq(struct irq_desc *desc) · 12 unmodified lines | |||
| 57 | struct liointc_handler_data *handler = irq_desc_get_handler_data(desc); | 63 | struct liointc_handler_data *handler = irq_desc_get_handler_data(desc); |
| 58 | struct irq_chip *chip = irq_desc_get_chip(desc); | 64 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 59 | struct irq_chip_generic *gc = handler->priv->gc; | 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 | u32 pending; | 67 | u32 pending; |
| 62 | 68 | ||
| 63 | chained_irq_enter(chip, desc); | 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 | if (!cpu_ictl) | 134 | if (!cpu_ictl) |
| 135 | return -EINVAL; | 135 | return -EINVAL; |
| 136 | ret = of_property_read_u32(cpu_ictl, "#interrupt-cells", &tmp); | 136 | ret = of_property_read_u32(cpu_ictl, "#interrupt-cells", &tmp); |
| 137 | of_node_put(cpu_ictl); | ||
| 137 | if (ret || tmp != 1) | 138 | if (ret || tmp != 1) |
| 138 | return -EINVAL; | 139 | return -EINVAL; |
| 139 | of_node_put(cpu_ictl); | ||
| 140 | 140 | ||
| 141 | cpu_int = be32_to_cpup(imap + 2); | 141 | cpu_int = be32_to_cpup(imap + 2); |
| 142 | if (cpu_int > 7 || cpu_int < 2) | 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 | { .compatible = "socionext,uniphier-ld11-aidet" }, | 237 | { .compatible = "socionext,uniphier-ld11-aidet" }, |
| 238 | { .compatible = "socionext,uniphier-ld20-aidet" }, | 238 | { .compatible = "socionext,uniphier-ld20-aidet" }, |
| 239 | { .compatible = "socionext,uniphier-pxs3-aidet" }, | 239 | { .compatible = "socionext,uniphier-pxs3-aidet" }, |
| 240 | { .compatible = "socionext,uniphier-nx1-aidet" }, | ||
| 240 | { /* sentinel */ } | 241 | { /* sentinel */ } |
| 241 | }; | 242 | }; |
| 242 | 243 | ||
| @@ -272,6 +272,7 @@ struct dm_io { · 271 unmodified lines | |||
| 272 | atomic_t io_count; | 272 | atomic_t io_count; |
| 273 | struct mapped_device *md; | 273 | struct mapped_device *md; |
| 274 | 274 | ||
| 275 | struct bio *split_bio; | ||
| 275 | /* The three fields represent mapped part of original bio */ | 276 | /* The three fields represent mapped part of original bio */ |
| 276 | struct bio *orig_bio; | 277 | struct bio *orig_bio; |
| 277 | unsigned int sector_offset; /* offset to end of orig_bio */ | 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 | static void stop_worker(struct era *era) | 1400 | static void stop_worker(struct era *era) |
| 1401 | { | 1401 | { |
| 1402 | atomic_set(&era->suspended, 1); | 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 | stop_worker(era); | 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 | static int era_preresume(struct dm_target *ti) | 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 | * Work out how many "unsigned long"s we need to hold the bitset. | 416 | * Work out how many "unsigned long"s we need to hold the bitset. |
| 417 | */ | 417 | */ |
| 418 | bitset_size = dm_round_up(region_count, | 418 | bitset_size = dm_round_up(region_count, BITS_PER_LONG); |
| 419 | sizeof(*lc->clean_bits) << BYTE_SHIFT); | ||
| 420 | bitset_size >>= BYTE_SHIFT; | 419 | bitset_size >>= BYTE_SHIFT; |
| 421 | 420 | ||
| 422 | lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits); | 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 | log_clear_bit(lc, lc->clean_bits, i); | 615 | log_clear_bit(lc, lc->clean_bits, i); |
| 617 | 616 | ||
| 618 | /* clear any old bits -- device has shrunk */ | 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 | log_clear_bit(lc, lc->clean_bits, i); | 619 | log_clear_bit(lc, lc->clean_bits, i); |
| 621 | 620 | ||
| 622 | /* copy clean across to sync */ | 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 | if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) { | 3725 | if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) { |
| 3726 | if (mddev->sync_thread) { | 3726 | if (mddev->sync_thread) { |
| 3727 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 3727 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 3728 | md_reap_sync_thread(mddev, false); | 3728 | md_reap_sync_thread(mddev); |
| 3729 | } | 3729 | } |
| 3730 | } else if (decipher_sync_action(mddev, mddev->recovery) != st_idle) | 3730 | } else if (decipher_sync_action(mddev, mddev->recovery) != st_idle) |
| 3731 | return -EBUSY; | 3731 | return -EBUSY; |
| @@ -555,6 +555,10 @@ static void dm_start_io_acct(struct dm_io *io, struct bio *clone) · 554 unmodified lines | |||
| 555 | unsigned long flags; | 555 | unsigned long flags; |
| 556 | /* Can afford locking given DM_TIO_IS_DUPLICATE_BIO */ | 556 | /* Can afford locking given DM_TIO_IS_DUPLICATE_BIO */ |
| 557 | spin_lock_irqsave(&io->lock, flags); | 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 | dm_io_set_flag(io, DM_IO_ACCOUNTED); | 562 | dm_io_set_flag(io, DM_IO_ACCOUNTED); |
| 559 | spin_unlock_irqrestore(&io->lock, flags); | 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 | atomic_set(&io->io_count, 2); | 594 | atomic_set(&io->io_count, 2); |
| 591 | this_cpu_inc(*md->pending_io); | 595 | this_cpu_inc(*md->pending_io); |
| 592 | io->orig_bio = bio; | 596 | io->orig_bio = bio; |
| 597 | io->split_bio = NULL; | ||
| 593 | io->md = md; | 598 | io->md = md; |
| 594 | spin_lock_init(&io->lock); | 599 | spin_lock_init(&io->lock); |
| 595 | io->start_time = jiffies; | 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 | static inline struct dm_table *dm_get_live_table_bio(struct mapped_device *md, | 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 | return dm_get_live_table_fast(md); | 722 | return dm_get_live_table_fast(md); |
| 718 | else | 723 | else |
| 719 | return dm_get_live_table(md, srcu_idx); | 724 | return dm_get_live_table(md, srcu_idx); |
| 720 | } | 725 | } |
| 721 | 726 | ||
| 722 | static inline void dm_put_live_table_bio(struct mapped_device *md, int srcu_idx, | 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 | dm_put_live_table_fast(md); | 731 | dm_put_live_table_fast(md); |
| 727 | else | 732 | else |
| 728 | dm_put_live_table(md, srcu_idx); | 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 | blk_status_t io_error; | 889 | blk_status_t io_error; |
| 885 | struct mapped_device *md = io->md; | 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 | if (io->status == BLK_STS_DM_REQUEUE) { | 893 | if (io->status == BLK_STS_DM_REQUEUE) { |
| 889 | unsigned long flags; | 894 | unsigned long flags; |
| @@ -935,9 +940,11 @@ static void dm_io_complete(struct dm_io *io) · 45 unmodified lines | |||
| 935 | if (io_error == BLK_STS_AGAIN) { | 940 | if (io_error == BLK_STS_AGAIN) { |
| 936 | /* io_uring doesn't handle BLK_STS_AGAIN (yet) */ | 941 | /* io_uring doesn't handle BLK_STS_AGAIN (yet) */ |
| 937 | queue_io(md, bio); | 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 | if (bio_is_flush_with_data(bio)) { | 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 | ti = dm_table_find_target(ci->map, ci->sector); | 1616 | ti = dm_table_find_target(ci->map, ci->sector); |
| 1610 | if (unlikely(!ti)) | 1617 | if (unlikely(!ti)) |
| 1611 | return BLK_STS_IOERR; | 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 | return __process_abnormal_io(ci, ti); | 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 | * Remainder must be passed to submit_bio_noacct() so it gets handled | 1694 | * Remainder must be passed to submit_bio_noacct() so it gets handled |
| 1683 | * *after* bios already submitted have been completely processed. | 1695 | * *after* bios already submitted have been completely processed. |
| 1684 | */ | 1696 | */ |
| 1685 | bio_trim(bio, io->sectors, ci.sector_count); | 1697 | WARN_ON_ONCE(!dm_io_flagged(io, DM_IO_WAS_SPLIT)); |
| 1686 | trace_block_split(bio, bio->bi_iter.bi_sector); | 1698 | io->split_bio = bio_split(bio, io->sectors, GFP_NOIO, |
| 1687 | bio_inc_remaining(bio); | 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 | submit_bio_noacct(bio); | 1702 | submit_bio_noacct(bio); |
| 1689 | out: | 1703 | out: |
| 1690 | /* | 1704 | /* |
| @@ -1711,8 +1725,9 @@ static void dm_submit_bio(struct bio *bio) · 20 unmodified lines | |||
| 1711 | struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; | 1725 | struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; |
| 1712 | int srcu_idx; | 1726 | int srcu_idx; |
| 1713 | struct dm_table *map; | 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 | /* If suspended, or map not yet available, queue this IO for later */ | 1732 | /* If suspended, or map not yet available, queue this IO for later */ |
| 1718 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || | 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 | dm_split_and_process_bio(md, map, bio); | 1744 | dm_split_and_process_bio(md, map, bio); |
| 1730 | out: | 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 | static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob, | 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 | flush_workqueue(md_misc_wq); | 4831 | flush_workqueue(md_misc_wq); |
| 4832 | if (mddev->sync_thread) { | 4832 | if (mddev->sync_thread) { |
| 4833 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 4833 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 4834 | md_reap_sync_thread(mddev, true); | 4834 | md_reap_sync_thread(mddev); |
| 4835 | } | 4835 | } |
| 4836 | mddev_unlock(mddev); | 4836 | mddev_unlock(mddev); |
| 4837 | } | 4837 | } |
| @@ -6197,7 +6197,7 @@ static void __md_stop_writes(struct mddev *mddev) · 1359 unmodified lines | |||
| 6197 | flush_workqueue(md_misc_wq); | 6197 | flush_workqueue(md_misc_wq); |
| 6198 | if (mddev->sync_thread) { | 6198 | if (mddev->sync_thread) { |
| 6199 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 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 | del_timer_sync(&mddev->safemode_timer); | 6203 | del_timer_sync(&mddev->safemode_timer); |
| @@ -9303,7 +9303,7 @@ void md_check_recovery(struct mddev *mddev) · 3099 unmodified lines | |||
| 9303 | * ->spare_active and clear saved_raid_disk | 9303 | * ->spare_active and clear saved_raid_disk |
| 9304 | */ | 9304 | */ |
| 9305 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 9305 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 9306 | md_reap_sync_thread(mddev, true); | 9306 | md_reap_sync_thread(mddev); |
| 9307 | clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | 9307 | clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); |
| 9308 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 9308 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 9309 | clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags); | 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 | goto unlock; | 9338 | goto unlock; |
| 9339 | } | 9339 | } |
| 9340 | if (mddev->sync_thread) { | 9340 | if (mddev->sync_thread) { |
| 9341 | md_reap_sync_thread(mddev, true); | 9341 | md_reap_sync_thread(mddev); |
| 9342 | goto unlock; | 9342 | goto unlock; |
| 9343 | } | 9343 | } |
| 9344 | /* Set RUNNING before clearing NEEDED to avoid | 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 | EXPORT_SYMBOL(md_check_recovery); | 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 | struct md_rdev *rdev; | 9416 | struct md_rdev *rdev; |
| 9417 | sector_t old_dev_sectors = mddev->dev_sectors; | 9417 | sector_t old_dev_sectors = mddev->dev_sectors; |
| 9418 | bool is_reshaped = false; | 9418 | bool is_reshaped = false; |
| 9419 | 9419 | ||
| 9420 | if (reconfig_mutex_held) | ||
| 9421 | mddev_unlock(mddev); | ||
| 9422 | /* resync has finished, collect result */ | 9420 | /* resync has finished, collect result */ |
| 9423 | md_unregister_thread(&mddev->sync_thread); | 9421 | md_unregister_thread(&mddev->sync_thread); |
| 9424 | if (reconfig_mutex_held) | ||
| 9425 | mddev_lock_nointr(mddev); | ||
| 9426 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && | 9422 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
| 9427 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && | 9423 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && |
| 9428 | mddev->degraded != mddev->raid_disks) { | 9424 | mddev->degraded != mddev->raid_disks) { |
| @@ -719,7 +719,7 @@ extern struct md_thread *md_register_thread( · 718 unmodified lines | |||
| 719 | extern void md_unregister_thread(struct md_thread **threadp); | 719 | extern void md_unregister_thread(struct md_thread **threadp); |
| 720 | extern void md_wakeup_thread(struct md_thread *thread); | 720 | extern void md_wakeup_thread(struct md_thread *thread); |
| 721 | extern void md_check_recovery(struct mddev *mddev); | 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 | extern int mddev_init_writes_pending(struct mddev *mddev); | 723 | extern int mddev_init_writes_pending(struct mddev *mddev); |
| 724 | extern bool md_write_start(struct mddev *mddev, struct bio *bi); | 724 | extern bool md_write_start(struct mddev *mddev, struct bio *bi); |
| 725 | extern void md_write_inc(struct mddev *mddev, struct bio *bi); | 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 | if (bdev) { | 629 | if (bdev) { |
| 630 | struct bio *bio; | 630 | struct bio *bio; |
| 631 | 631 | ||
| 632 | bio = bio_alloc_bioset(bdev, 0, GFP_NOIO, | 632 | bio = bio_alloc_bioset(bdev, 0, |
| 633 | REQ_OP_WRITE | REQ_PREFLUSH, | 633 | REQ_OP_WRITE | REQ_PREFLUSH, |
| 634 | &ppl_conf->flush_bs); | 634 | GFP_NOIO, &ppl_conf->flush_bs); |
| 635 | bio->bi_private = io; | 635 | bio->bi_private = io; |
| 636 | bio->bi_end_io = ppl_flush_endio; | 636 | bio->bi_end_io = ppl_flush_endio; |
| 637 | 637 | ||
| @@ -105,6 +105,7 @@ config TI_EMIF · 104 unmodified lines | |||
| 105 | config OMAP_GPMC | 105 | config OMAP_GPMC |
| 106 | tristate "Texas Instruments OMAP SoC GPMC driver" | 106 | tristate "Texas Instruments OMAP SoC GPMC driver" |
| 107 | depends on OF_ADDRESS | 107 | depends on OF_ADDRESS |
| 108 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST | ||
| 108 | select GPIOLIB | 109 | select GPIOLIB |
| 109 | help | 110 | help |
| 110 | This driver is for the General Purpose Memory Controller (GPMC) | 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 | of_node_put(smi_com_node); | 404 | of_node_put(smi_com_node); |
| 405 | if (smi_com_pdev) { | 405 | if (smi_com_pdev) { |
| 406 | /* smi common is the supplier, Make sure it is ready before */ | 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 | return -EPROBE_DEFER; | 409 | return -EPROBE_DEFER; |
| 410 | } | ||
| 409 | smi_com_dev = &smi_com_pdev->dev; | 411 | smi_com_dev = &smi_com_pdev->dev; |
| 410 | link = device_link_add(dev, smi_com_dev, | 412 | link = device_link_add(dev, smi_com_dev, |
| 411 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); | 413 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); |
| 412 | if (!link) { | 414 | if (!link) { |
| 413 | dev_err(dev, "Unable to link smi-common dev\n"); | 415 | dev_err(dev, "Unable to link smi-common dev\n"); |
| 416 | put_device(&smi_com_pdev->dev); | ||
| 414 | return -ENODEV; | 417 | return -ENODEV; |
| 415 | } | 418 | } |
| 416 | *com_dev = smi_com_dev; | 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 | dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT, | 1188 | dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT, |
| 1189 | sizeof(u32), GFP_KERNEL); | 1189 | sizeof(u32), GFP_KERNEL); |
| 1190 | if (!dmc->timing_row) | 1190 | if (!dmc->timing_row) { |
| 1191 | return -ENOMEM; | 1191 | ret = -ENOMEM; |
| 1192 | goto put_node; | ||
| 1193 | } | ||
| 1192 | 1194 | ||
| 1193 | dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT, | 1195 | dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT, |
| 1194 | sizeof(u32), GFP_KERNEL); | 1196 | sizeof(u32), GFP_KERNEL); |
| 1195 | if (!dmc->timing_data) | 1197 | if (!dmc->timing_data) { |
| 1196 | return -ENOMEM; | 1198 | ret = -ENOMEM; |
| 1199 | goto put_node; | ||
| 1200 | } | ||
| 1197 | 1201 | ||
| 1198 | dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT, | 1202 | dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT, |
| 1199 | sizeof(u32), GFP_KERNEL); | 1203 | sizeof(u32), GFP_KERNEL); |
| 1200 | if (!dmc->timing_power) | 1204 | if (!dmc->timing_power) { |
| 1201 | return -ENOMEM; | 1205 | ret = -ENOMEM; |
| 1206 | goto put_node; | ||
| 1207 | } | ||
| 1202 | 1208 | ||
| 1203 | dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev, | 1209 | dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev, |
| 1204 | DDR_TYPE_LPDDR3, | 1210 | DDR_TYPE_LPDDR3, |
| 1205 | &dmc->timings_arr_size); | 1211 | &dmc->timings_arr_size); |
| 1206 | if (!dmc->timings) { | 1212 | if (!dmc->timings) { |
| 1207 | of_node_put(np_ddr); | ||
| 1208 | dev_warn(dmc->dev, "could not get timings from DT\n"); | 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 | dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev); | 1218 | dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev); |
| 1213 | if (!dmc->min_tck) { | 1219 | if (!dmc->min_tck) { |
| 1214 | of_node_put(np_ddr); | ||
| 1215 | dev_warn(dmc->dev, "could not get tck from DT\n"); | 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 | /* Sorted array of OPPs with frequency ascending */ | 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 | clk_period_ps); | 1233 | clk_period_ps); |
| 1228 | } | 1234 | } |
| 1229 | 1235 | ||
| 1230 | of_node_put(np_ddr); | ||
| 1231 | 1236 | ||
| 1232 | /* Take the highest frequency's timings as 'bypass' */ | 1237 | /* Take the highest frequency's timings as 'bypass' */ |
| 1233 | dmc->bypass_timing_row = dmc->timing_row[idx - 1]; | 1238 | dmc->bypass_timing_row = dmc->timing_row[idx - 1]; |
| 1234 | dmc->bypass_timing_data = dmc->timing_data[idx - 1]; | 1239 | dmc->bypass_timing_data = dmc->timing_data[idx - 1]; |
| 1235 | dmc->bypass_timing_power = dmc->timing_power[idx - 1]; | 1240 | dmc->bypass_timing_power = dmc->timing_power[idx - 1]; |
| 1236 | 1241 | ||
| 1242 | put_node: | ||
| 1243 | of_node_put(np_ddr); | ||
| 1237 | return ret; | 1244 | return ret; |
| 1238 | } | 1245 | } |
| 1239 | 1246 | ||
| @@ -232,9 +232,9 @@ static int ssc_probe(struct platform_device *pdev) · 231 unmodified lines | |||
| 232 | clk_disable_unprepare(ssc->clk); | 232 | clk_disable_unprepare(ssc->clk); |
| 233 | 233 | ||
| 234 | ssc->irq = platform_get_irq(pdev, 0); | 234 | ssc->irq = platform_get_irq(pdev, 0); |
| 235 | if (!ssc->irq) { | 235 | if (ssc->irq < 0) { |
| 236 | dev_dbg(&pdev->dev, "could not get irq\n"); | 236 | dev_dbg(&pdev->dev, "could not get irq\n"); |
| 237 | return -ENXIO; | 237 | return ssc->irq; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | mutex_lock(&user_lock); | 240 | mutex_lock(&user_lock); |
| @@ -407,6 +407,8 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr) · 406 unmodified lines | |||
| 407 | // default | 407 | // default |
| 408 | setting_reg1 = PCR_SETTING_REG1; | 408 | setting_reg1 = PCR_SETTING_REG1; |
| 409 | setting_reg2 = PCR_SETTING_REG2; | 409 | setting_reg2 = PCR_SETTING_REG2; |
| 410 | } else { | ||
| 411 | return; | ||
| 410 | } | 412 | } |
| 411 | 413 | ||
| 412 | pci_read_config_dword(pdev, setting_reg2, &lval2); | 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 | struct at25_data *at25 = priv; | 80 | struct at25_data *at25 = priv; |
| 81 | char *buf = val; | 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 | u8 *cp; | 87 | u8 *cp; |
| 83 | ssize_t status; | 88 | ssize_t status; |
| 84 | struct spi_transfer t[2]; | 89 | struct spi_transfer t[2]; |
| @@ -92,54 +97,59 @@ static int at25_ee_read(void *priv, unsigned int offset, · 7 unmodified lines | |||
| 92 | if (unlikely(!count)) | 97 | if (unlikely(!count)) |
| 93 | return -EINVAL; | 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; | 105 | instr = AT25_READ; |
| 98 | if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) | 106 | if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) |
| 99 | if (offset >= BIT(at25->addrlen * 8)) | 107 | if (msg_offset >= BIT(at25->addrlen * 8)) |
| 100 | instr |= AT25_INSTR_BIT3; | 108 | instr |= AT25_INSTR_BIT3; |
| 101 | 109 | ||
| 102 | mutex_lock(&at25->lock); | 110 | mutex_lock(&at25->lock); |
| 103 | 111 | ||
| 104 | *cp++ = instr; | 112 | *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 | } | ||
| 118 | 113 | ||
| 119 | spi_message_init(&m); | 114 | /* 8/16/24-bit address is written MSB first */ |
| 120 | memset(t, 0, sizeof(t)); | 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; | 127 | spi_message_init(&m); |
| 123 | t[0].len = at25->addrlen + 1; | 128 | memset(t, 0, sizeof(t)); |
| 124 | spi_message_add_tail(&t[0], &m); | ||
| 125 | 129 | ||
| 126 | t[1].rx_buf = buf; | 130 | t[0].tx_buf = at25->command; |
| 127 | t[1].len = count; | 131 | t[0].len = at25->addrlen + 1; |
| 128 | spi_message_add_tail(&t[1], &m); | 132 | spi_message_add_tail(&t[0], &m); |
| 129 | 133 | ||
| 130 | /* | 134 | t[1].rx_buf = buf + nr_bytes; |
| 131 | * Read it all at once. | 135 | t[1].len = msg_count; |
| 132 | * | 136 | spi_message_add_tail(&t[1], &m); |
| 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); | ||
| 140 | 137 | ||
| 141 | mutex_unlock(&at25->lock); | 138 | status = spi_sync(at25->spi, &m); |
| 142 | return status; | 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 | /* Read extra registers as ID or serial number */ | 155 | /* Read extra registers as ID or serial number */ |
| @@ -190,6 +200,7 @@ ATTRIBUTE_GROUPS(sernum); · 44 unmodified lines | |||
| 190 | static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) | 200 | static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) |
| 191 | { | 201 | { |
| 192 | struct at25_data *at25 = priv; | 202 | struct at25_data *at25 = priv; |
| 203 | size_t maxsz = spi_max_transfer_size(at25->spi); | ||
| 193 | const char *buf = val; | 204 | const char *buf = val; |
| 194 | int status = 0; | 205 | int status = 0; |
| 195 | unsigned buf_size; | 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 | segment = buf_size - (offset % buf_size); | 264 | segment = buf_size - (offset % buf_size); |
| 254 | if (segment > count) | 265 | if (segment > count) |
| 255 | segment = count; | 266 | segment = count; |
| 267 | if (segment > maxsz) | ||
| 268 | segment = maxsz; | ||
| 256 | memcpy(cp, buf, segment); | 269 | memcpy(cp, buf, segment); |
| 257 | status = spi_write(at25->spi, bounce, | 270 | status = spi_write(at25->spi, bounce, |
| 258 | segment + at25->addrlen + 1); | 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 | if (dev->dev_state != MEI_DEV_INIT_CLIENTS || | 1352 | if (dev->dev_state != MEI_DEV_INIT_CLIENTS || |
| 1353 | dev->hbm_state != MEI_HBM_CAP_SETUP) { | 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 | dev_dbg(dev->dev, "hbm: capabilities response: on shutdown, ignoring\n"); | 1356 | dev_dbg(dev->dev, "hbm: capabilities response: on shutdown, ignoring\n"); |
| 1356 | return 0; | 1357 | return 0; |
| 1357 | } | 1358 | } |
| @@ -109,6 +109,8 @@ · 108 unmodified lines | |||
| 109 | #define MEI_DEV_ID_ADP_P 0x51E0 /* Alder Lake Point P */ | 109 | #define MEI_DEV_ID_ADP_P 0x51E0 /* Alder Lake Point P */ |
| 110 | #define MEI_DEV_ID_ADP_N 0x54E0 /* Alder Lake Point N */ | 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 | * MEI HW Section | 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 | ret = mei_me_d0i3_exit_sync(dev); | 1154 | ret = mei_me_d0i3_exit_sync(dev); |
| 1155 | if (ret) | 1155 | if (ret) |
| 1156 | return ret; | 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 | {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)}, | 116 | {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)}, |
| 117 | {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)}, | 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 | /* required last entry */ | 121 | /* required last entry */ |
| 120 | {0, } | 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 | msdc_request_done(host, mrq); | 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 | struct mmc_request *mrq, struct mmc_data *data) | 1360 | struct mmc_request *mrq, struct mmc_data *data) |
| 1361 | { | 1361 | { |
| 1362 | struct mmc_command *stop; | 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 | spin_unlock_irqrestore(&host->lock, flags); | 1376 | spin_unlock_irqrestore(&host->lock, flags); |
| 1377 | 1377 | ||
| 1378 | if (done) | 1378 | if (done) |
| 1379 | return true; | 1379 | return; |
| 1380 | stop = data->stop; | 1380 | stop = data->stop; |
| 1381 | 1381 | ||
| 1382 | if (check_data || (stop && stop->error)) { | 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 | sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, | 1385 | sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, |
| 1386 | 1); | 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 | ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val, | 1393 | ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val, |
| 1389 | !(val & MSDC_DMA_CFG_STS), 1, 20000); | 1394 | !(val & MSDC_DMA_CFG_STS), 1, 20000); |
| 1390 | if (ret) { | 1395 | if (ret) |
| 1391 | dev_dbg(host->dev, "DMA stop timed out\n"); | 1396 | dev_dbg(host->dev, "DMA inactive timed out\n"); |
| 1392 | return false; | ||
| 1393 | } | ||
| 1394 | 1397 | ||
| 1395 | sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask); | 1398 | sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask); |
| 1396 | dev_dbg(host->dev, "DMA stop\n"); | 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 | msdc_data_xfer_next(host, mrq); | 1420 | msdc_data_xfer_next(host, mrq); |
| 1418 | done = true; | ||
| 1419 | } | 1421 | } |
| 1420 | return done; | ||
| 1421 | } | 1422 | } |
| 1422 | 1423 | ||
| 1423 | static void msdc_set_buswidth(struct msdc_host *host, u32 width) | 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 | if (recovery) { | 2417 | if (recovery) { |
| 2417 | sdr_set_field(host->base + MSDC_DMA_CTRL, | 2418 | sdr_set_field(host->base + MSDC_DMA_CTRL, |
| 2418 | MSDC_DMA_CTRL_STOP, 1); | 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 | if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CFG, val, | 2423 | if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CFG, val, |
| 2420 | !(val & MSDC_DMA_CFG_STS), 1, 3000))) | 2424 | !(val & MSDC_DMA_CFG_STS), 1, 3000))) |
| 2421 | return; | 2425 | return; |
| @@ -152,6 +152,8 @@ static int sdhci_o2_get_cd(struct mmc_host *mmc) · 151 unmodified lines | |||
| 152 | 152 | ||
| 153 | if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS)) | 153 | if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS)) |
| 154 | sdhci_o2_enable_internal_clock(host); | 154 | sdhci_o2_enable_internal_clock(host); |
| 155 | else | ||
| 156 | sdhci_o2_wait_card_detect_stable(host); | ||
| 155 | 157 | ||
| 156 | return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); | 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 | hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) | | 890 | hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) | |
| 891 | BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) | | 891 | BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) | |
| 892 | BF_GPMI_TIMING0_DATA_SETUP(data_setup_cycles); | 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 | * Derive NFC ideal delay from {3}: | 896 | * Derive NFC ideal delay from {3}: |
| @@ -29,9 +29,6 @@ struct nand_flash_dev nand_flash_ids[] = { · 28 unmodified lines | |||
| 29 | {"TC58NVG0S3E 1G 3.3V 8-bit", | 29 | {"TC58NVG0S3E 1G 3.3V 8-bit", |
| 30 | { .id = {0x98, 0xd1, 0x90, 0x15, 0x76, 0x14, 0x01, 0x00} }, | 30 | { .id = {0x98, 0xd1, 0x90, 0x15, 0x76, 0x14, 0x01, 0x00} }, |
| 31 | SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512), }, | 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 | {"TC58NVG2S0F 4G 3.3V 8-bit", | 32 | {"TC58NVG2S0F 4G 3.3V 8-bit", |
| 36 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, | 33 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, |
| 37 | SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, | 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 | if (!rtnl_trylock()) | 3684 | if (!rtnl_trylock()) |
| 3685 | return; | 3685 | return; |
| 3686 | 3686 | ||
| 3687 | if (should_notify_peers) | 3687 | if (should_notify_peers) { |
| 3688 | bond->send_peer_notif--; | ||
| 3688 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, | 3689 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, |
| 3689 | bond->dev); | 3690 | bond->dev); |
| 3691 | } | ||
| 3690 | if (should_notify_rtnl) { | 3692 | if (should_notify_rtnl) { |
| 3691 | bond_slave_state_notify(bond); | 3693 | bond_slave_state_notify(bond); |
| 3692 | bond_slave_link_notify(bond); | 3694 | bond_slave_link_notify(bond); |
| @@ -2334,6 +2334,7 @@ static int · 2333 unmodified lines | |||
| 2334 | qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) | 2334 | qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) |
| 2335 | { | 2335 | { |
| 2336 | struct qca8k_priv *priv = ds->priv; | 2336 | struct qca8k_priv *priv = ds->priv; |
| 2337 | int ret; | ||
| 2337 | 2338 | ||
| 2338 | /* We have only have a general MTU setting. | 2339 | /* We have only have a general MTU setting. |
| 2339 | * DSA always set the CPU port's MTU to the largest MTU of the slave | 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 | if (!dsa_is_cpu_port(ds, port)) | 2345 | if (!dsa_is_cpu_port(ds, port)) |
| 2345 | return 0; | 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 | /* Include L2 header / FCS length */ | 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 | static int | 2371 | static int |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | #define QCA8K_ETHERNET_MDIO_PRIORITY 7 | 16 | #define QCA8K_ETHERNET_MDIO_PRIORITY 7 |
| 17 | #define QCA8K_ETHERNET_PHY_PRIORITY 6 | 17 | #define QCA8K_ETHERNET_PHY_PRIORITY 6 |
| 18 | #define QCA8K_ETHERNET_TIMEOUT 100 | 18 | #define QCA8K_ETHERNET_TIMEOUT 5 |
| 19 | 19 | ||
| 20 | #define QCA8K_NUM_PORTS 7 | 20 | #define QCA8K_NUM_PORTS 7 |
| 21 | #define QCA8K_NUM_CPU_PORTS 2 | 21 | #define QCA8K_NUM_CPU_PORTS 2 |
| @@ -338,7 +338,7 @@ static int xgbe_platform_probe(struct platform_device *pdev) · 337 unmodified lines | |||
| 338 | * the PHY resources listed last | 338 | * the PHY resources listed last |
| 339 | */ | 339 | */ |
| 340 | phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3; | 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 | dma_irqnum = 1; | 342 | dma_irqnum = 1; |
| 343 | dma_irqend = phy_irqnum; | 343 | dma_irqend = phy_irqnum; |
| 344 | } else { | 344 | } else { |
| @@ -348,7 +348,7 @@ static int xgbe_platform_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 348 | phy_memnum = 0; | 348 | phy_memnum = 0; |
| 349 | phy_irqnum = 0; | 349 | phy_irqnum = 0; |
| 350 | dma_irqnum = 1; | 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 | /* Obtain the mmio areas for the device */ | 354 | /* Obtain the mmio areas for the device */ |
| @@ -332,7 +332,6 @@ static void bgmac_remove(struct bcma_device *core) · 331 unmodified lines | |||
| 332 | bcma_mdio_mii_unregister(bgmac->mii_bus); | 332 | bcma_mdio_mii_unregister(bgmac->mii_bus); |
| 333 | bgmac_enet_remove(bgmac); | 333 | bgmac_enet_remove(bgmac); |
| 334 | bcma_set_drvdata(core, NULL); | 334 | bcma_set_drvdata(core, NULL); |
| 335 | kfree(bgmac); | ||
| 336 | } | 335 | } |
| 337 | 336 | ||
| 338 | static struct bcma_driver bgmac_bcma_driver = { | 337 | static struct bcma_driver bgmac_bcma_driver = { |
| @@ -769,6 +769,7 @@ struct hnae3_tc_info { · 768 unmodified lines | |||
| 769 | u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */ | 769 | u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */ |
| 770 | u16 tqp_count[HNAE3_MAX_TC]; | 770 | u16 tqp_count[HNAE3_MAX_TC]; |
| 771 | u16 tqp_offset[HNAE3_MAX_TC]; | 771 | u16 tqp_offset[HNAE3_MAX_TC]; |
| 772 | u8 max_tc; /* Total number of TCs */ | ||
| 772 | u8 num_tc; /* Total number of enabled TCs */ | 773 | u8 num_tc; /* Total number of enabled TCs */ |
| 773 | bool mqprio_active; | 774 | bool mqprio_active; |
| 774 | }; | 775 | }; |
| @@ -1129,7 +1129,7 @@ hns3_is_ringparam_changed(struct net_device *ndev, · 1128 unmodified lines | |||
| 1129 | if (old_ringparam->tx_desc_num == new_ringparam->tx_desc_num && | 1129 | if (old_ringparam->tx_desc_num == new_ringparam->tx_desc_num && |
| 1130 | old_ringparam->rx_desc_num == new_ringparam->rx_desc_num && | 1130 | old_ringparam->rx_desc_num == new_ringparam->rx_desc_num && |
| 1131 | old_ringparam->rx_buf_len == new_ringparam->rx_buf_len) { | 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 | return false; | 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 | static int hclge_update_port_info(struct hclge_dev *hdev) | 3268 | static int hclge_update_port_info(struct hclge_dev *hdev) |
| 3269 | { | 3269 | { |
| 3270 | struct hclge_mac *mac = &hdev->hw.mac; | 3270 | struct hclge_mac *mac = &hdev->hw.mac; |
| 3271 | int speed = HCLGE_MAC_SPEED_UNKNOWN; | 3271 | int speed; |
| 3272 | int ret; | 3272 | int ret; |
| 3273 | 3273 | ||
| 3274 | /* get the port info from SFP cmd if not copper port */ | 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 | if (!hdev->support_sfp_query) | 3279 | if (!hdev->support_sfp_query) |
| 3280 | return 0; | 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 | ret = hclge_get_sfp_info(hdev, mac); | 3284 | ret = hclge_get_sfp_info(hdev, mac); |
| 3284 | else | 3285 | } else { |
| 3286 | speed = HCLGE_MAC_SPEED_UNKNOWN; | ||
| 3285 | ret = hclge_get_sfp_speed(hdev, &speed); | 3287 | ret = hclge_get_sfp_speed(hdev, &speed); |
| 3288 | } | ||
| 3286 | 3289 | ||
| 3287 | if (ret == -EOPNOTSUPP) { | 3290 | if (ret == -EOPNOTSUPP) { |
| 3288 | hdev->support_sfp_query = false; | 3291 | hdev->support_sfp_query = false; |
| @@ -3294,6 +3297,8 @@ static int hclge_update_port_info(struct hclge_dev *hdev) · 5 unmodified lines | |||
| 3294 | if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { | 3297 | if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { |
| 3295 | if (mac->speed_type == QUERY_ACTIVE_SPEED) { | 3298 | if (mac->speed_type == QUERY_ACTIVE_SPEED) { |
| 3296 | hclge_update_port_capability(hdev, mac); | 3299 | hclge_update_port_capability(hdev, mac); |
| 3300 | if (mac->speed != speed) | ||
| 3301 | (void)hclge_tm_port_shaper_cfg(hdev); | ||
| 3297 | return 0; | 3302 | return 0; |
| 3298 | } | 3303 | } |
| 3299 | return hclge_cfg_mac_speed_dup(hdev, mac->speed, | 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 | link_state_old = vport->vf_info.link_state; | 3381 | link_state_old = vport->vf_info.link_state; |
| 3377 | vport->vf_info.link_state = link_state; | 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 | ret = hclge_push_vf_link_status(vport); | 3390 | ret = hclge_push_vf_link_status(vport); |
| 3380 | if (ret) { | 3391 | if (ret) { |
| 3381 | vport->vf_info.link_state = link_state_old; | 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 | if (ret) | 10128 | if (ret) |
| 10118 | return ret; | 10129 | return ret; |
| 10119 | 10130 | ||
| 10131 | vport->port_base_vlan_cfg.tbl_sta = false; | ||
| 10120 | /* remove old VLAN tag */ | 10132 | /* remove old VLAN tag */ |
| 10121 | if (old_info->vlan_tag == 0) | 10133 | if (old_info->vlan_tag == 0) |
| 10122 | ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, | 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 | return hclge_cmd_send(&hdev->hw, &desc, 1); | 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, | 285 | static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, u16 qs_id, u8 pri, |
| 286 | u16 qs_id, u8 pri) | 286 | bool link_vld) |
| 287 | { | 287 | { |
| 288 | struct hclge_qs_to_pri_link_cmd *map; | 288 | struct hclge_qs_to_pri_link_cmd *map; |
| 289 | struct hclge_desc desc; | 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 | map->qs_id = cpu_to_le16(qs_id); | 295 | map->qs_id = cpu_to_le16(qs_id); |
| 296 | map->priority = pri; | 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 | return hclge_cmd_send(&hdev->hw, &desc, 1); | 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 | return hclge_cmd_send(&hdev->hw, &desc, 1); | 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 | struct hclge_port_shapping_cmd *shap_cfg_cmd; | 425 | struct hclge_port_shapping_cmd *shap_cfg_cmd; |
| 426 | struct hclge_shaper_ir_para ir_para; | 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 | * one tc for VF for simplicity. VF's vport_id is non zero. | 642 | * one tc for VF for simplicity. VF's vport_id is non zero. |
| 643 | */ | 643 | */ |
| 644 | if (vport->vport_id) { | 644 | if (vport->vport_id) { |
| 645 | kinfo->tc_info.max_tc = 1; | ||
| 645 | kinfo->tc_info.num_tc = 1; | 646 | kinfo->tc_info.num_tc = 1; |
| 646 | vport->qs_offset = HNAE3_MAX_TC + | 647 | vport->qs_offset = HNAE3_MAX_TC + |
| 647 | vport->vport_id - HCLGE_VF_VPORT_START_NUM; | 648 | vport->vport_id - HCLGE_VF_VPORT_START_NUM; |
| 648 | vport_max_rss_size = hdev->vf_rss_size_max; | 649 | vport_max_rss_size = hdev->vf_rss_size_max; |
| 649 | } else { | 650 | } else { |
| 651 | kinfo->tc_info.max_tc = hdev->tc_max; | ||
| 650 | kinfo->tc_info.num_tc = | 652 | kinfo->tc_info.num_tc = |
| 651 | min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); | 653 | min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); |
| 652 | vport->qs_offset = 0; | 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 | kinfo->num_tqps = hclge_vport_get_tqp_num(vport); | 681 | kinfo->num_tqps = hclge_vport_get_tqp_num(vport); |
| 680 | vport->dwrr = 100; /* 100 percent as init */ | 682 | vport->dwrr = 100; /* 100 percent as init */ |
| 681 | vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit; | 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 | /* when enable mqprio, the tc_info has been updated. */ | 688 | /* when enable mqprio, the tc_info has been updated. */ |
| 685 | if (kinfo->tc_info.mqprio_active) | 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 | static void hclge_tm_tc_info_init(struct hclge_dev *hdev) | 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 | hdev->tm_info.tc_info[i].tc_id = i; | 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 | hdev->tm_info.tc_info[i].pgid = 0; | 735 | hdev->tm_info.tc_info[i].pgid = 0; |
| 723 | hdev->tm_info.tc_info[i].bw_limit = | 736 | hdev->tm_info.tc_info[i].bw_limit = bw_limit; |
| 724 | hdev->tm_info.pg_info[0].bw_limit; | ||
| 725 | } | 737 | } |
| 726 | 738 | ||
| 727 | for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) | 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 | for (k = 0; k < hdev->num_alloc_vport; k++) { | 938 | for (k = 0; k < hdev->num_alloc_vport; k++) { |
| 927 | struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo; | 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 | ret = hclge_tm_qs_to_pri_map_cfg(hdev, | 945 | ret = hclge_tm_qs_to_pri_map_cfg(hdev, |
| 931 | vport[k].qs_offset + i, | 946 | vport[k].qs_offset + i, |
| 932 | i); | 947 | pri, link_vld); |
| 933 | if (ret) | 948 | if (ret) |
| 934 | return ret; | 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 | for (i = 0; i < HNAE3_MAX_TC; i++) { | 964 | for (i = 0; i < HNAE3_MAX_TC; i++) { |
| 950 | ret = hclge_tm_qs_to_pri_map_cfg(hdev, | 965 | ret = hclge_tm_qs_to_pri_map_cfg(hdev, |
| 951 | vport[k].qs_offset + i, | 966 | vport[k].qs_offset + i, |
| 952 | k); | 967 | k, true); |
| 953 | if (ret) | 968 | if (ret) |
| 954 | return ret; | 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 | u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; | 1005 | u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; |
| 991 | struct hclge_shaper_ir_para ir_para; | 1006 | struct hclge_shaper_ir_para ir_para; |
| 992 | u32 shaper_para; | 1007 | u32 shaper_para_c, shaper_para_p; |
| 993 | int ret; | 1008 | int ret; |
| 994 | u32 i; | 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 | u32 rate = hdev->tm_info.tc_info[i].bw_limit; | 1012 | u32 rate = hdev->tm_info.tc_info[i].bw_limit; |
| 998 | 1013 | ||
| 999 | ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI, | 1014 | if (rate) { |
| 1000 | &ir_para, max_tm_rate); | 1015 | ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI, |
| 1001 | if (ret) | 1016 | &ir_para, max_tm_rate); |
| 1002 | return ret; | 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 | ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i, | 1033 | ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i, |
| 1008 | shaper_para, rate); | 1034 | shaper_para_c, rate); |
| 1009 | if (ret) | 1035 | if (ret) |
| 1010 | return ret; | 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 | ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, | 1038 | ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, |
| 1018 | shaper_para, rate); | 1039 | shaper_para_p, rate); |
| 1019 | if (ret) | 1040 | if (ret) |
| 1020 | return ret; | 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 | int ret; | 1146 | int ret; |
| 1126 | u32 i, k; | 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 | pg_info = | 1150 | pg_info = |
| 1130 | &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; | 1151 | &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; |
| 1131 | dwrr = pg_info->tc_dwrr[i]; | 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 | return ret; | 1156 | return ret; |
| 1136 | 1157 | ||
| 1137 | for (k = 0; k < hdev->num_alloc_vport; k++) { | 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 | ret = hclge_tm_qs_weight_cfg( | 1165 | ret = hclge_tm_qs_weight_cfg( |
| 1139 | hdev, vport[k].qs_offset + i, | 1166 | hdev, vport[k].qs_offset + i, |
| 1140 | vport[k].dwrr); | 1167 | dwrr); |
| 1141 | if (ret) | 1168 | if (ret) |
| 1142 | return ret; | 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 | struct hclge_vport *vport = hdev->vport; | 1331 | struct hclge_vport *vport = hdev->vport; |
| 1305 | int ret; | 1332 | int ret; |
| 1333 | u8 mode; | ||
| 1306 | u16 i; | 1334 | u16 i; |
| 1307 | 1335 | ||
| 1308 | ret = hclge_tm_pri_schd_mode_cfg(hdev, pri_id); | 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 | return ret; | 1338 | return ret; |
| 1311 | 1339 | ||
| 1312 | for (i = 0; i < hdev->num_alloc_vport; i++) { | 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 | ret = hclge_tm_qs_schd_mode_cfg(hdev, | 1348 | ret = hclge_tm_qs_schd_mode_cfg(hdev, |
| 1314 | vport[i].qs_offset + pri_id, | 1349 | vport[i].qs_offset + pri_id, |
| 1315 | HCLGE_SCH_MODE_DWRR); | 1350 | mode); |
| 1316 | if (ret) | 1351 | if (ret) |
| 1317 | return ret; | 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 | u8 i; | 1388 | u8 i; |
| 1354 | 1389 | ||
| 1355 | if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { | 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 | ret = hclge_tm_schd_mode_tc_base_cfg(hdev, i); | 1392 | ret = hclge_tm_schd_mode_tc_base_cfg(hdev, i); |
| 1358 | if (ret) | 1393 | if (ret) |
| 1359 | return ret; | 1394 | return ret; |
| @@ -237,6 +237,7 @@ int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); · 236 unmodified lines | |||
| 237 | void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); | 237 | void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); |
| 238 | void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); | 238 | void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); |
| 239 | int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); | 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 | int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num); | 241 | int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num); |
| 241 | int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num); | 242 | int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num); |
| 242 | int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority, | 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 | for (i = 0; i < fw_image->fw_info.fw_section_cnt; i++) { | 44 | for (i = 0; i < fw_image->fw_info.fw_section_cnt; i++) { |
| 45 | len += fw_image->fw_section_info[i].fw_section_len; | 45 | len += fw_image->fw_section_info[i].fw_section_len; |
| 46 | memcpy(&host_image->image_section_info[i], | 46 | host_image->image_section_info[i] = fw_image->fw_section_info[i]; |
| 47 | &fw_image->fw_section_info[i], | ||
| 48 | sizeof(struct fw_section_info_st)); | ||
| 49 | } | 47 | } |
| 50 | 48 | ||
| 51 | if (len != fw_image->fw_len || | 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 | set_bit(__I40E_TESTING, pf->state); | 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 | if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) { | 2596 | if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) { |
| 2590 | dev_warn(&pf->pdev->dev, | 2597 | dev_warn(&pf->pdev->dev, |
| 2591 | "Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n"); | 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 | goto skip_ol_tests; | 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 | data[I40E_ETH_TEST_INTR] = 0; | 2642 | data[I40E_ETH_TEST_INTR] = 0; |
| 2642 | } | 2643 | } |
| 2643 | 2644 | ||
| 2644 | skip_ol_tests: | ||
| 2645 | |||
| 2646 | netif_info(pf, drv, netdev, "testing finished\n"); | 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 | static void i40e_get_wol(struct net_device *netdev, | 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 | return -EOPNOTSUPP; | 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 | if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || | 8550 | if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || |
| 8546 | test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) | 8551 | test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) |
| 8547 | return -EBUSY; | 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 | if (vf->adq_enabled) { | 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 | num_qps_all += vf->ch[i].num_qps; | 2286 | num_qps_all += vf->ch[i].num_qps; |
| 2287 | if (num_qps_all != qci->num_queue_pairs) { | 2287 | if (num_qps_all != qci->num_queue_pairs) { |
| 2288 | aq_ret = I40E_ERR_PARAM; | 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 | list_add_tail(&f->list, &adapter->mac_filter_list); | 984 | list_add_tail(&f->list, &adapter->mac_filter_list); |
| 985 | f->add = true; | 985 | f->add = true; |
| 986 | f->is_new_mac = true; | 986 | f->is_new_mac = true; |
| 987 | f->is_primary = false; | 987 | f->is_primary = ether_addr_equal(macaddr, adapter->hw.mac.addr); |
| 988 | adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; | 988 | adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; |
| 989 | } else { | 989 | } else { |
| 990 | f->remove = false; | 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 | return err; | 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 | * ice_set_link_ksettings - Set Speed and Duplex | 2229 | * ice_set_link_ksettings - Set Speed and Duplex |
| 2194 | * @netdev: network interface device structure | 2230 | * @netdev: network interface device structure |
| @@ -2320,7 +2356,8 @@ ice_set_link_ksettings(struct net_device *netdev, · 125 unmodified lines | |||
| 2320 | adv_link_speed = curr_link_speed; | 2356 | adv_link_speed = curr_link_speed; |
| 2321 | 2357 | ||
| 2322 | /* Convert the advertise link speeds to their corresponded PHY_TYPE */ | 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 | if (!autoneg_changed && adv_link_speed == curr_link_speed) { | 2362 | if (!autoneg_changed && adv_link_speed == curr_link_speed) { |
| 2326 | netdev_info(netdev, "Nothing changed, exiting without setting anything.\n"); | 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 | new_rx = ch->combined_count + ch->rx_count; | 3507 | new_rx = ch->combined_count + ch->rx_count; |
| 3471 | new_tx = ch->combined_count + ch->tx_count; | 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 | if (new_rx > ice_get_max_rxq(pf)) { | 3520 | if (new_rx > ice_get_max_rxq(pf)) { |
| 3474 | netdev_err(dev, "Maximum allowed Rx channels is %d\n", | 3521 | netdev_err(dev, "Maximum allowed Rx channels is %d\n", |
| 3475 | ice_get_max_rxq(pf)); | 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 | * @vsi: the VSI being configured | 909 | * @vsi: the VSI being configured |
| 910 | * @ctxt: VSI context structure | 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 | u16 offset = 0, qmap = 0, tx_count = 0, pow = 0; | 914 | u16 offset = 0, qmap = 0, tx_count = 0, pow = 0; |
| 915 | u16 num_txq_per_tc, num_rxq_per_tc; | 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 | else | 982 | else |
| 983 | vsi->num_rxq = num_rxq_per_tc; | 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 | vsi->num_txq = tx_count; | 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 | if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) { | 998 | if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) { |
| 988 | dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n"); | 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 | ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]); | 1012 | ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]); |
| 1002 | ctxt->info.q_mapping[1] = cpu_to_le16(vsi->num_rxq); | 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 | if (vsi->type == ICE_VSI_CHNL) { | 1200 | if (vsi->type == ICE_VSI_CHNL) { |
| 1188 | ice_chnl_vsi_setup_q_map(vsi, ctxt); | 1201 | ice_chnl_vsi_setup_q_map(vsi, ctxt); |
| 1189 | } else { | 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 | if (!init_vsi) /* means VSI being updated */ | 1207 | if (!init_vsi) /* means VSI being updated */ |
| 1192 | /* must to indicate which section of VSI context are | 1208 | /* must to indicate which section of VSI context are |
| 1193 | * being modified | 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 | * Prepares VSI tc_config to have queue configurations based on MQPRIO options. | 3481 | * Prepares VSI tc_config to have queue configurations based on MQPRIO options. |
| 3466 | */ | 3482 | */ |
| 3467 | static void | 3483 | static int |
| 3468 | ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt, | 3484 | ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt, |
| 3469 | u8 ena_tc) | 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 | /* Set actual Tx/Rx queue pairs */ | 3530 | /* Set actual Tx/Rx queue pairs */ |
| 3515 | vsi->num_txq = offset + qcount_tx; | 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 | vsi->num_rxq = offset + qcount_rx; | 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 | /* Setup queue TC[0].qmap for given VSI context */ | 3545 | /* Setup queue TC[0].qmap for given VSI context */ |
| 3519 | ctxt->info.tc_mapping[0] = cpu_to_le16(qmap); | 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 | dev_dbg(ice_pf_to_dev(vsi->back), "vsi->num_rxq = %d\n", vsi->num_rxq); | 3558 | dev_dbg(ice_pf_to_dev(vsi->back), "vsi->num_rxq = %d\n", vsi->num_rxq); |
| 3532 | dev_dbg(ice_pf_to_dev(vsi->back), "all_numtc %u, all_enatc: 0x%04x, tc_cfg.numtc %u\n", | 3559 | dev_dbg(ice_pf_to_dev(vsi->back), "all_numtc %u, all_enatc: 0x%04x, tc_cfg.numtc %u\n", |
| 3533 | vsi->all_numtc, vsi->all_enatc, vsi->tc_cfg.numtc); | 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 | if (vsi->type == ICE_VSI_PF && | 3610 | if (vsi->type == ICE_VSI_PF && |
| 3582 | test_bit(ICE_FLAG_TC_MQPRIO, pf->flags)) | 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 | else | 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 | /* must to indicate which section of VSI context are being modified */ | 3619 | /* must to indicate which section of VSI context are being modified */ |
| 3588 | ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID); | 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 | ice_fix_features(struct net_device *netdev, netdev_features_t features) | 5763 | ice_fix_features(struct net_device *netdev, netdev_features_t features) |
| 5764 | { | 5764 | { |
| 5765 | struct ice_netdev_priv *np = netdev_priv(netdev); | 5765 | struct ice_netdev_priv *np = netdev_priv(netdev); |
| 5766 | netdev_features_t supported_vlan_filtering; | 5766 | netdev_features_t req_vlan_fltr, cur_vlan_fltr; |
| 5767 | netdev_features_t requested_vlan_filtering; | 5767 | bool cur_ctag, cur_stag, req_ctag, req_stag; |
| 5768 | struct ice_vsi *vsi = np->vsi; | 5768 | |
| 5769 | 5769 | cur_vlan_fltr = netdev->features & NETIF_VLAN_FILTERING_FEATURES; | |
| 5770 | requested_vlan_filtering = features & NETIF_VLAN_FILTERING_FEATURES; | 5770 | cur_ctag = cur_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER; |
| 5771 | 5771 | cur_stag = cur_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER; | |
| 5772 | /* make sure supported_vlan_filtering works for both SVM and DVM */ | 5772 | |
| 5773 | supported_vlan_filtering = NETIF_F_HW_VLAN_CTAG_FILTER; | 5773 | req_vlan_fltr = features & NETIF_VLAN_FILTERING_FEATURES; |
| 5774 | if (ice_is_dvm_ena(&vsi->back->hw)) | 5774 | req_ctag = req_vlan_fltr & NETIF_F_HW_VLAN_CTAG_FILTER; |
| 5775 | supported_vlan_filtering |= NETIF_F_HW_VLAN_STAG_FILTER; | 5775 | req_stag = req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER; |
| 5776 | 5776 | ||
| 5777 | if (requested_vlan_filtering && | 5777 | if (req_vlan_fltr != cur_vlan_fltr) { |
| 5778 | requested_vlan_filtering != supported_vlan_filtering) { | 5778 | if (ice_is_dvm_ena(&np->vsi->back->hw)) { |
| 5779 | if (requested_vlan_filtering & NETIF_F_HW_VLAN_CTAG_FILTER) { | 5779 | if (req_ctag && req_stag) { |
| 5780 | netdev_warn(netdev, "cannot support requested VLAN filtering settings, enabling all supported VLAN filtering settings\n"); | 5780 | features |= NETIF_VLAN_FILTERING_FEATURES; |
| 5781 | features |= supported_vlan_filtering; | 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 | } else { | 5792 | } else { |
| 5783 | netdev_warn(netdev, "cannot support requested VLAN filtering settings, clearing all supported VLAN filtering settings\n"); | 5793 | if (req_vlan_fltr & NETIF_F_HW_VLAN_STAG_FILTER) |
| 5784 | features &= ~supported_vlan_filtering; | 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 | ice_ptp_init_tx_e822(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port) | 2271 | ice_ptp_init_tx_e822(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port) |
| 2272 | { | 2272 | { |
| 2273 | tx->quad = port / ICE_PORTS_PER_QUAD; | 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 | tx->len = INDEX_PER_PORT; | 2275 | tx->len = INDEX_PER_PORT; |
| 2276 | 2276 | ||
| 2277 | return ice_ptp_alloc_tx_tracker(tx); | 2277 | return ice_ptp_alloc_tx_tracker(tx); |
| @@ -49,6 +49,37 @@ struct ice_perout_channel { · 48 unmodified lines | |||
| 49 | * To allow multiple ports to access the shared register block independently, | 49 | * To allow multiple ports to access the shared register block independently, |
| 50 | * the blocks are split up so that indexes are assigned to each port based on | 50 | * the blocks are split up so that indexes are assigned to each port based on |
| 51 | * hardware logical port number. | 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 | fltr->rid = rule_added.rid; | 525 | fltr->rid = rule_added.rid; |
| 526 | fltr->rule_id = rule_added.rule_id; | 526 | fltr->rule_id = rule_added.rule_id; |
| 527 | fltr->dest_id = rule_added.vsi_handle; | ||
| 527 | 528 | ||
| 528 | exit: | 529 | exit: |
| 529 | kfree(list); | 530 | kfree(list); |
| @@ -993,7 +994,9 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi, · 463 unmodified lines | |||
| 993 | n_proto_key = ntohs(match.key->n_proto); | 994 | n_proto_key = ntohs(match.key->n_proto); |
| 994 | n_proto_mask = ntohs(match.mask->n_proto); | 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 | n_proto_key = 0; | 1000 | n_proto_key = 0; |
| 998 | n_proto_mask = 0; | 1001 | n_proto_mask = 0; |
| 999 | } else { | 1002 | } else { |
| @@ -504,6 +504,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) · 503 unmodified lines | |||
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | if (ice_is_vf_disabled(vf)) { | 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 | dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n", | 512 | dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n", |
| 508 | vf->vf_id); | 513 | vf->vf_id); |
| 509 | return 0; | 514 | return 0; |
| @@ -1569,35 +1569,27 @@ error_param: · 1568 unmodified lines | |||
| 1569 | */ | 1569 | */ |
| 1570 | static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) | 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 | struct virtchnl_vsi_queue_config_info *qci = | 1572 | struct virtchnl_vsi_queue_config_info *qci = |
| 1574 | (struct virtchnl_vsi_queue_config_info *)msg; | 1573 | (struct virtchnl_vsi_queue_config_info *)msg; |
| 1575 | struct virtchnl_queue_pair_info *qpi; | 1574 | struct virtchnl_queue_pair_info *qpi; |
| 1576 | struct ice_pf *pf = vf->pf; | 1575 | struct ice_pf *pf = vf->pf; |
| 1577 | struct ice_vsi *vsi; | 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)) { | 1579 | if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) |
| 1581 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1582 | goto error_param; | 1580 | goto error_param; |
| 1583 | } | ||
| 1584 | 1581 | ||
| 1585 | if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) { | 1582 | if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id)) |
| 1586 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1587 | goto error_param; | 1583 | goto error_param; |
| 1588 | } | ||
| 1589 | 1584 | ||
| 1590 | vsi = ice_get_vf_vsi(vf); | 1585 | vsi = ice_get_vf_vsi(vf); |
| 1591 | if (!vsi) { | 1586 | if (!vsi) |
| 1592 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1593 | goto error_param; | 1587 | goto error_param; |
| 1594 | } | ||
| 1595 | 1588 | ||
| 1596 | if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF || | 1589 | if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF || |
| 1597 | qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { | 1590 | qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) { |
| 1598 | dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n", | 1591 | dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n", |
| 1599 | vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); | 1592 | vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)); |
| 1600 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1601 | goto error_param; | 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 | !ice_vc_isvalid_ring_len(qpi->txq.ring_len) || | 1602 | !ice_vc_isvalid_ring_len(qpi->txq.ring_len) || |
| 1611 | !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) || | 1603 | !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) || |
| 1612 | !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) { | 1604 | !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) { |
| 1613 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1614 | goto error_param; | 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 | * for selected "vsi" | 1611 | * for selected "vsi" |
| 1621 | */ | 1612 | */ |
| 1622 | if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) { | 1613 | if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) { |
| 1623 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1624 | goto error_param; | 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 | vsi->tx_rings[i]->count = qpi->txq.ring_len; | 1620 | vsi->tx_rings[i]->count = qpi->txq.ring_len; |
| 1631 | 1621 | ||
| 1632 | /* Disable any existing queue first */ | 1622 | /* Disable any existing queue first */ |
| 1633 | if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) { | 1623 | if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) |
| 1634 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1635 | goto error_param; | 1624 | goto error_param; |
| 1636 | } | ||
| 1637 | 1625 | ||
| 1638 | /* Configure a queue with the requested settings */ | 1626 | /* Configure a queue with the requested settings */ |
| 1639 | if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { | 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 | goto error_param; | 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 | if (qpi->rxq.databuffer_size != 0 && | 1641 | if (qpi->rxq.databuffer_size != 0 && |
| 1653 | (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || | 1642 | (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || |
| 1654 | qpi->rxq.databuffer_size < 1024)) { | 1643 | qpi->rxq.databuffer_size < 1024)) |
| 1655 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1656 | goto error_param; | 1644 | goto error_param; |
| 1657 | } | ||
| 1658 | vsi->rx_buf_len = qpi->rxq.databuffer_size; | 1645 | vsi->rx_buf_len = qpi->rxq.databuffer_size; |
| 1659 | vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len; | 1646 | vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len; |
| 1660 | if (qpi->rxq.max_pkt_size > max_frame_size || | 1647 | if (qpi->rxq.max_pkt_size > max_frame_size || |
| 1661 | qpi->rxq.max_pkt_size < 64) { | 1648 | qpi->rxq.max_pkt_size < 64) |
| 1662 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1663 | goto error_param; | 1649 | goto error_param; |
| 1664 | } | ||
| 1665 | 1650 | ||
| 1666 | vsi->max_frame = qpi->rxq.max_pkt_size; | 1651 | vsi->max_frame = qpi->rxq.max_pkt_size; |
| 1667 | /* add space for the port VLAN since the VF driver is | 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 | vsi->max_frame += VLAN_HLEN; | 1657 | vsi->max_frame += VLAN_HLEN; |
| 1673 | 1658 | ||
| 1674 | if (ice_vsi_cfg_single_rxq(vsi, q_idx)) { | 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 | goto error_param; | 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 | error_param: | 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 | /* send the response to the VF */ | 1681 | /* send the response to the VF */ |
| 1683 | return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, v_ret, | 1682 | return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, |
| 1684 | NULL, 0); | 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 | while (i != tx_ring->next_to_use) { | 4819 | while (i != tx_ring->next_to_use) { |
| 4820 | union e1000_adv_tx_desc *eop_desc, *tx_desc; | 4820 | union e1000_adv_tx_desc *eop_desc, *tx_desc; |
| 4821 | 4821 | ||
| 4822 | /* Free all the Tx ring sk_buffs */ | 4822 | /* Free all the Tx ring sk_buffs or xdp frames */ |
| 4823 | dev_kfree_skb_any(tx_buffer->skb); | 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 | /* unmap skb header data */ | 4828 | /* unmap skb header data */ |
| 4826 | dma_unmap_single(tx_ring->dev, | 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 | struct e1000_hw *hw = &adapter->hw; | 9901 | struct e1000_hw *hw = &adapter->hw; |
| 9899 | u32 dmac_thr; | 9902 | u32 dmac_thr; |
| 9900 | u16 hwm; | 9903 | u16 hwm; |
| 9904 | u32 reg; | ||
| 9901 | 9905 | ||
| 9902 | if (hw->mac.type > e1000_82580) { | 9906 | if (hw->mac.type > e1000_82580) { |
| 9903 | if (adapter->flags & IGB_FLAG_DMAC) { | 9907 | if (adapter->flags & IGB_FLAG_DMAC) { |
| 9904 | u32 reg; | ||
| 9905 | |||
| 9906 | /* force threshold to 0. */ | 9908 | /* force threshold to 0. */ |
| 9907 | wr32(E1000_DMCTXTH, 0); | 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 | /* Disable BMC-to-OS Watchdog Enable */ | 9937 | /* Disable BMC-to-OS Watchdog Enable */ |
| 9936 | if (hw->mac.type != e1000_i354) | 9938 | if (hw->mac.type != e1000_i354) |
| 9937 | reg &= ~E1000_DMACR_DC_BMC2OSW_EN; | 9939 | reg &= ~E1000_DMACR_DC_BMC2OSW_EN; |
| 9938 | |||
| 9939 | wr32(E1000_DMACR, reg); | 9940 | wr32(E1000_DMACR, reg); |
| 9940 | 9941 | ||
| 9941 | /* no lower threshold to disable | 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 | wr32(E1000_DMCTXTH, (IGB_MIN_TXPBSIZE - | 9954 | wr32(E1000_DMCTXTH, (IGB_MIN_TXPBSIZE - |
| 9954 | (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6); | 9955 | (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6); |
| 9956 | } | ||
| 9955 | 9957 | ||
| 9956 | /* make low power state decision controlled | 9958 | if (hw->mac.type >= e1000_i210 || |
| 9957 | * by DMA coal | 9959 | (adapter->flags & IGB_FLAG_DMAC)) { |
| 9958 | */ | ||
| 9959 | reg = rd32(E1000_PCIEMISC); | 9960 | reg = rd32(E1000_PCIEMISC); |
| 9960 | reg &= ~E1000_PCIEMISC_LX_DECISION; | 9961 | reg |= E1000_PCIEMISC_LX_DECISION; |
| 9961 | wr32(E1000_PCIEMISC, reg); | 9962 | wr32(E1000_PCIEMISC, reg); |
| 9962 | } /* endif adapter->dmac is not disabled */ | 9963 | } /* endif adapter->dmac is not disabled */ |
| 9963 | } else if (hw->mac.type == e1000_82580) { | 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 | static const struct ethtool_ops otx2vf_ethtool_ops = { | 1391 | static const struct ethtool_ops otx2vf_ethtool_ops = { |
| 1392 | .supported_coalesce_params = ETHTOOL_COALESCE_USECS | | 1392 | .supported_coalesce_params = ETHTOOL_COALESCE_USECS | |
| 1393 | ETHTOOL_COALESCE_MAX_FRAMES, | 1393 | ETHTOOL_COALESCE_MAX_FRAMES | |
| 1394 | ETHTOOL_COALESCE_USE_ADAPTIVE, | ||
| 1394 | .supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN | | 1395 | .supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN | |
| 1395 | ETHTOOL_RING_USE_CQE_SIZE, | 1396 | ETHTOOL_RING_USE_CQE_SIZE, |
| 1396 | .get_link = otx2_get_link, | 1397 | .get_link = otx2_get_link, |
| @@ -8,8 +8,8 @@ · 7 unmodified lines | |||
| 8 | #include "spectrum.h" | 8 | #include "spectrum.h" |
| 9 | 9 | ||
| 10 | enum mlxsw_sp_counter_sub_pool_id { | 10 | enum mlxsw_sp_counter_sub_pool_id { |
| 11 | MLXSW_SP_COUNTER_SUB_POOL_FLOW, | ||
| 12 | MLXSW_SP_COUNTER_SUB_POOL_RIF, | 11 | MLXSW_SP_COUNTER_SUB_POOL_RIF, |
| 12 | MLXSW_SP_COUNTER_SUB_POOL_FLOW, | ||
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| 15 | int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp, | 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 | iowrite32(value, lp->regs + offset); | 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 | /* Function prototypes visible in xilinx_axienet_mdio.c for other files */ | 601 | /* Function prototypes visible in xilinx_axienet_mdio.c for other files */ |
| 551 | int axienet_mdio_enable(struct axienet_local *lp); | 602 | int axienet_mdio_enable(struct axienet_local *lp); |
| 552 | void axienet_mdio_disable(struct axienet_local *lp); | 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 | return ioread32(lp->dma_regs + reg); | 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 | static void desc_set_phys_addr(struct axienet_local *lp, dma_addr_t addr, | 136 | static void desc_set_phys_addr(struct axienet_local *lp, dma_addr_t addr, |
| 161 | struct axidma_bd *desc) | 137 | struct axidma_bd *desc) |
| 162 | { | 138 | { |
| @@ -2061,6 +2037,11 @@ static int axienet_probe(struct platform_device *pdev) · 1898 unmodified lines | |||
| 2061 | iowrite32(0x0, desc); | 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 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); | 2046 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); |
| 2066 | if (ret) { | 2047 | if (ret) { |
| @@ -99,6 +99,7 @@ struct sixpack { · 98 unmodified lines | |||
| 99 | 99 | ||
| 100 | unsigned int rx_count; | 100 | unsigned int rx_count; |
| 101 | unsigned int rx_count_cooked; | 101 | unsigned int rx_count_cooked; |
| 102 | spinlock_t rxlock; | ||
| 102 | 103 | ||
| 103 | int mtu; /* Our mtu (to spot changes!) */ | 104 | int mtu; /* Our mtu (to spot changes!) */ |
| 104 | int buffsize; /* Max buffers sizes */ | 105 | int buffsize; /* Max buffers sizes */ |
| @@ -565,6 +566,7 @@ static int sixpack_open(struct tty_struct *tty) · 460 unmodified lines | |||
| 565 | sp->dev = dev; | 566 | sp->dev = dev; |
| 566 | 567 | ||
| 567 | spin_lock_init(&sp->lock); | 568 | spin_lock_init(&sp->lock); |
| 569 | spin_lock_init(&sp->rxlock); | ||
| 568 | refcount_set(&sp->refcnt, 1); | 570 | refcount_set(&sp->refcnt, 1); |
| 569 | init_completion(&sp->dead); | 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 | sp->led_state = 0x60; | 915 | sp->led_state = 0x60; |
| 914 | /* fill trailing bytes with zeroes */ | 916 | /* fill trailing bytes with zeroes */ |
| 915 | sp->tty->ops->write(sp->tty, &sp->led_state, 1); | 917 | sp->tty->ops->write(sp->tty, &sp->led_state, 1); |
| 918 | spin_lock_bh(&sp->rxlock); | ||
| 916 | rest = sp->rx_count; | 919 | rest = sp->rx_count; |
| 917 | if (rest != 0) | 920 | if (rest != 0) |
| 918 | for (i = rest; i <= 3; i++) | 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 | sp_bump(sp, 0); | 933 | sp_bump(sp, 0); |
| 931 | } | 934 | } |
| 932 | sp->rx_count_cooked = 0; | 935 | sp->rx_count_cooked = 0; |
| 936 | spin_unlock_bh(&sp->rxlock); | ||
| 933 | } | 937 | } |
| 934 | break; | 938 | break; |
| 935 | case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n"); | 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 | decode_prio_command(sp, inbyte); | 963 | decode_prio_command(sp, inbyte); |
| 960 | else if ((inbyte & SIXP_STD_CMD_MASK) != 0) | 964 | else if ((inbyte & SIXP_STD_CMD_MASK) != 0) |
| 961 | decode_std_command(sp, inbyte); | 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 | decode_data(sp, inbyte); | 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 | #define MDIO_AN_VEND_PROV 0xc400 | 34 | #define MDIO_AN_VEND_PROV 0xc400 |
| 35 | #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) | 35 | #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) |
| 36 | #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) | 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 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) | 39 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) |
| 38 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) | 40 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) |
| 39 | #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 | 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 | phydev->advertising)) | 233 | phydev->advertising)) |
| 232 | reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; | 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 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, | 245 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, |
| 235 | MDIO_AN_VEND_PROV_1000BASET_HALF | | 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 | if (ret < 0) | 250 | if (ret < 0) |
| 238 | return ret; | 251 | return ret; |
| 239 | if (ret > 0) | 252 | if (ret > 0) |
| @@ -2072,6 +2072,8 @@ static struct phy_driver at803x_driver[] = { · 2071 unmodified lines | |||
| 2072 | /* ATHEROS AR9331 */ | 2072 | /* ATHEROS AR9331 */ |
| 2073 | PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), | 2073 | PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), |
| 2074 | .name = "Qualcomm Atheros AR9331 built-in PHY", | 2074 | .name = "Qualcomm Atheros AR9331 built-in PHY", |
| 2075 | .probe = at803x_probe, | ||
| 2076 | .remove = at803x_remove, | ||
| 2075 | .suspend = at803x_suspend, | 2077 | .suspend = at803x_suspend, |
| 2076 | .resume = at803x_resume, | 2078 | .resume = at803x_resume, |
| 2077 | .flags = PHY_POLL_CABLE_TEST, | 2079 | .flags = PHY_POLL_CABLE_TEST, |
| @@ -2087,6 +2089,8 @@ static struct phy_driver at803x_driver[] = { · 9 unmodified lines | |||
| 2087 | /* Qualcomm Atheros QCA9561 */ | 2089 | /* Qualcomm Atheros QCA9561 */ |
| 2088 | PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), | 2090 | PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), |
| 2089 | .name = "Qualcomm Atheros QCA9561 built-in PHY", | 2091 | .name = "Qualcomm Atheros QCA9561 built-in PHY", |
| 2092 | .probe = at803x_probe, | ||
| 2093 | .remove = at803x_remove, | ||
| 2090 | .suspend = at803x_suspend, | 2094 | .suspend = at803x_suspend, |
| 2091 | .resume = at803x_resume, | 2095 | .resume = at803x_resume, |
| 2092 | .flags = PHY_POLL_CABLE_TEST, | 2096 | .flags = PHY_POLL_CABLE_TEST, |
| @@ -2151,6 +2155,8 @@ static struct phy_driver at803x_driver[] = { · 58 unmodified lines | |||
| 2151 | PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), | 2155 | PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), |
| 2152 | .name = "Qualcomm QCA8081", | 2156 | .name = "Qualcomm QCA8081", |
| 2153 | .flags = PHY_POLL_CABLE_TEST, | 2157 | .flags = PHY_POLL_CABLE_TEST, |
| 2158 | .probe = at803x_probe, | ||
| 2159 | .remove = at803x_remove, | ||
| 2154 | .config_intr = at803x_config_intr, | 2160 | .config_intr = at803x_config_intr, |
| 2155 | .handle_interrupt = at803x_handle_interrupt, | 2161 | .handle_interrupt = at803x_handle_interrupt, |
| 2156 | .get_tunable = at803x_get_tunable, | 2162 | .get_tunable = at803x_get_tunable, |
| @@ -110,7 +110,7 @@ static int smsc_phy_config_init(struct phy_device *phydev) · 109 unmodified lines | |||
| 110 | struct smsc_phy_priv *priv = phydev->priv; | 110 | struct smsc_phy_priv *priv = phydev->priv; |
| 111 | int rc; | 111 | int rc; |
| 112 | 112 | ||
| 113 | if (!priv->energy_enable) | 113 | if (!priv->energy_enable || phydev->irq != PHY_POLL) |
| 114 | return 0; | 114 | return 0; |
| 115 | 115 | ||
| 116 | rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); | 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 | * response on link pulses to detect presence of plugged Ethernet cable. | 210 | * response on link pulses to detect presence of plugged Ethernet cable. |
| 211 | * The Energy Detect Power-Down mode is enabled again in the end of procedure to | 211 | * The Energy Detect Power-Down mode is enabled again in the end of procedure to |
| 212 | * save approximately 220 mW of power if cable is unplugged. | 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 | static int lan87xx_read_status(struct phy_device *phydev) | 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 | int err = genphy_read_status(phydev); | 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 | /* Disable EDPD to wake up PHY */ | 223 | /* Disable EDPD to wake up PHY */ |
| 222 | int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); | 224 | int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); |
| 223 | if (rc < 0) | 225 | if (rc < 0) |
| @@ -1750,7 +1750,7 @@ static const struct driver_info ax88179_info = { · 1749 unmodified lines | |||
| 1750 | .link_reset = ax88179_link_reset, | 1750 | .link_reset = ax88179_link_reset, |
| 1751 | .reset = ax88179_reset, | 1751 | .reset = ax88179_reset, |
| 1752 | .stop = ax88179_stop, | 1752 | .stop = ax88179_stop, |
| 1753 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1753 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1754 | .rx_fixup = ax88179_rx_fixup, | 1754 | .rx_fixup = ax88179_rx_fixup, |
| 1755 | .tx_fixup = ax88179_tx_fixup, | 1755 | .tx_fixup = ax88179_tx_fixup, |
| 1756 | }; | 1756 | }; |
| @@ -1763,7 +1763,7 @@ static const struct driver_info ax88178a_info = { · 6 unmodified lines | |||
| 1763 | .link_reset = ax88179_link_reset, | 1763 | .link_reset = ax88179_link_reset, |
| 1764 | .reset = ax88179_reset, | 1764 | .reset = ax88179_reset, |
| 1765 | .stop = ax88179_stop, | 1765 | .stop = ax88179_stop, |
| 1766 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1766 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1767 | .rx_fixup = ax88179_rx_fixup, | 1767 | .rx_fixup = ax88179_rx_fixup, |
| 1768 | .tx_fixup = ax88179_tx_fixup, | 1768 | .tx_fixup = ax88179_tx_fixup, |
| 1769 | }; | 1769 | }; |
| @@ -1776,7 +1776,7 @@ static const struct driver_info cypress_GX3_info = { · 6 unmodified lines | |||
| 1776 | .link_reset = ax88179_link_reset, | 1776 | .link_reset = ax88179_link_reset, |
| 1777 | .reset = ax88179_reset, | 1777 | .reset = ax88179_reset, |
| 1778 | .stop = ax88179_stop, | 1778 | .stop = ax88179_stop, |
| 1779 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1779 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1780 | .rx_fixup = ax88179_rx_fixup, | 1780 | .rx_fixup = ax88179_rx_fixup, |
| 1781 | .tx_fixup = ax88179_tx_fixup, | 1781 | .tx_fixup = ax88179_tx_fixup, |
| 1782 | }; | 1782 | }; |
| @@ -1789,7 +1789,7 @@ static const struct driver_info dlink_dub1312_info = { · 6 unmodified lines | |||
| 1789 | .link_reset = ax88179_link_reset, | 1789 | .link_reset = ax88179_link_reset, |
| 1790 | .reset = ax88179_reset, | 1790 | .reset = ax88179_reset, |
| 1791 | .stop = ax88179_stop, | 1791 | .stop = ax88179_stop, |
| 1792 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1792 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1793 | .rx_fixup = ax88179_rx_fixup, | 1793 | .rx_fixup = ax88179_rx_fixup, |
| 1794 | .tx_fixup = ax88179_tx_fixup, | 1794 | .tx_fixup = ax88179_tx_fixup, |
| 1795 | }; | 1795 | }; |
| @@ -1802,7 +1802,7 @@ static const struct driver_info sitecom_info = { · 6 unmodified lines | |||
| 1802 | .link_reset = ax88179_link_reset, | 1802 | .link_reset = ax88179_link_reset, |
| 1803 | .reset = ax88179_reset, | 1803 | .reset = ax88179_reset, |
| 1804 | .stop = ax88179_stop, | 1804 | .stop = ax88179_stop, |
| 1805 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1805 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1806 | .rx_fixup = ax88179_rx_fixup, | 1806 | .rx_fixup = ax88179_rx_fixup, |
| 1807 | .tx_fixup = ax88179_tx_fixup, | 1807 | .tx_fixup = ax88179_tx_fixup, |
| 1808 | }; | 1808 | }; |
| @@ -1815,7 +1815,7 @@ static const struct driver_info samsung_info = { · 6 unmodified lines | |||
| 1815 | .link_reset = ax88179_link_reset, | 1815 | .link_reset = ax88179_link_reset, |
| 1816 | .reset = ax88179_reset, | 1816 | .reset = ax88179_reset, |
| 1817 | .stop = ax88179_stop, | 1817 | .stop = ax88179_stop, |
| 1818 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1818 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1819 | .rx_fixup = ax88179_rx_fixup, | 1819 | .rx_fixup = ax88179_rx_fixup, |
| 1820 | .tx_fixup = ax88179_tx_fixup, | 1820 | .tx_fixup = ax88179_tx_fixup, |
| 1821 | }; | 1821 | }; |
| @@ -1828,7 +1828,7 @@ static const struct driver_info lenovo_info = { · 6 unmodified lines | |||
| 1828 | .link_reset = ax88179_link_reset, | 1828 | .link_reset = ax88179_link_reset, |
| 1829 | .reset = ax88179_reset, | 1829 | .reset = ax88179_reset, |
| 1830 | .stop = ax88179_stop, | 1830 | .stop = ax88179_stop, |
| 1831 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1831 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1832 | .rx_fixup = ax88179_rx_fixup, | 1832 | .rx_fixup = ax88179_rx_fixup, |
| 1833 | .tx_fixup = ax88179_tx_fixup, | 1833 | .tx_fixup = ax88179_tx_fixup, |
| 1834 | }; | 1834 | }; |
| @@ -1841,7 +1841,7 @@ static const struct driver_info belkin_info = { · 6 unmodified lines | |||
| 1841 | .link_reset = ax88179_link_reset, | 1841 | .link_reset = ax88179_link_reset, |
| 1842 | .reset = ax88179_reset, | 1842 | .reset = ax88179_reset, |
| 1843 | .stop = ax88179_stop, | 1843 | .stop = ax88179_stop, |
| 1844 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1844 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1845 | .rx_fixup = ax88179_rx_fixup, | 1845 | .rx_fixup = ax88179_rx_fixup, |
| 1846 | .tx_fixup = ax88179_tx_fixup, | 1846 | .tx_fixup = ax88179_tx_fixup, |
| 1847 | }; | 1847 | }; |
| @@ -1854,7 +1854,7 @@ static const struct driver_info toshiba_info = { · 6 unmodified lines | |||
| 1854 | .link_reset = ax88179_link_reset, | 1854 | .link_reset = ax88179_link_reset, |
| 1855 | .reset = ax88179_reset, | 1855 | .reset = ax88179_reset, |
| 1856 | .stop = ax88179_stop, | 1856 | .stop = ax88179_stop, |
| 1857 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1857 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1858 | .rx_fixup = ax88179_rx_fixup, | 1858 | .rx_fixup = ax88179_rx_fixup, |
| 1859 | .tx_fixup = ax88179_tx_fixup, | 1859 | .tx_fixup = ax88179_tx_fixup, |
| 1860 | }; | 1860 | }; |
| @@ -1867,7 +1867,7 @@ static const struct driver_info mct_info = { · 6 unmodified lines | |||
| 1867 | .link_reset = ax88179_link_reset, | 1867 | .link_reset = ax88179_link_reset, |
| 1868 | .reset = ax88179_reset, | 1868 | .reset = ax88179_reset, |
| 1869 | .stop = ax88179_stop, | 1869 | .stop = ax88179_stop, |
| 1870 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1870 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1871 | .rx_fixup = ax88179_rx_fixup, | 1871 | .rx_fixup = ax88179_rx_fixup, |
| 1872 | .tx_fixup = ax88179_tx_fixup, | 1872 | .tx_fixup = ax88179_tx_fixup, |
| 1873 | }; | 1873 | }; |
| @@ -1880,7 +1880,7 @@ static const struct driver_info at_umc2000_info = { · 6 unmodified lines | |||
| 1880 | .link_reset = ax88179_link_reset, | 1880 | .link_reset = ax88179_link_reset, |
| 1881 | .reset = ax88179_reset, | 1881 | .reset = ax88179_reset, |
| 1882 | .stop = ax88179_stop, | 1882 | .stop = ax88179_stop, |
| 1883 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1883 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1884 | .rx_fixup = ax88179_rx_fixup, | 1884 | .rx_fixup = ax88179_rx_fixup, |
| 1885 | .tx_fixup = ax88179_tx_fixup, | 1885 | .tx_fixup = ax88179_tx_fixup, |
| 1886 | }; | 1886 | }; |
| @@ -1893,7 +1893,7 @@ static const struct driver_info at_umc200_info = { · 6 unmodified lines | |||
| 1893 | .link_reset = ax88179_link_reset, | 1893 | .link_reset = ax88179_link_reset, |
| 1894 | .reset = ax88179_reset, | 1894 | .reset = ax88179_reset, |
| 1895 | .stop = ax88179_stop, | 1895 | .stop = ax88179_stop, |
| 1896 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1896 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1897 | .rx_fixup = ax88179_rx_fixup, | 1897 | .rx_fixup = ax88179_rx_fixup, |
| 1898 | .tx_fixup = ax88179_tx_fixup, | 1898 | .tx_fixup = ax88179_tx_fixup, |
| 1899 | }; | 1899 | }; |
| @@ -1906,7 +1906,7 @@ static const struct driver_info at_umc2000sp_info = { · 6 unmodified lines | |||
| 1906 | .link_reset = ax88179_link_reset, | 1906 | .link_reset = ax88179_link_reset, |
| 1907 | .reset = ax88179_reset, | 1907 | .reset = ax88179_reset, |
| 1908 | .stop = ax88179_stop, | 1908 | .stop = ax88179_stop, |
| 1909 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1909 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, |
| 1910 | .rx_fixup = ax88179_rx_fixup, | 1910 | .rx_fixup = ax88179_rx_fixup, |
| 1911 | .tx_fixup = ax88179_tx_fixup, | 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 | static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) | 312 | static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) |
| 313 | { | 313 | { |
| 314 | struct veth_priv *rcv_priv, *priv = netdev_priv(dev); | 314 | struct veth_priv *rcv_priv, *priv = netdev_priv(dev); |
| 315 | struct netdev_queue *queue = NULL; | ||
| 315 | struct veth_rq *rq = NULL; | 316 | struct veth_rq *rq = NULL; |
| 316 | struct net_device *rcv; | 317 | struct net_device *rcv; |
| 317 | int length = skb->len; | 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 | rxq = skb_get_queue_mapping(skb); | 330 | rxq = skb_get_queue_mapping(skb); |
| 330 | if (rxq < rcv->real_num_rx_queues) { | 331 | if (rxq < rcv->real_num_rx_queues) { |
| 331 | rq = &rcv_priv->rq[rxq]; | 332 | rq = &rcv_priv->rq[rxq]; |
| 333 | queue = netdev_get_tx_queue(dev, rxq); | ||
| 332 | 334 | ||
| 333 | /* The napi pointer is available when an XDP program is | 335 | /* The napi pointer is available when an XDP program is |
| 334 | * attached or when GRO is enabled | 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 | skb_tx_timestamp(skb); | 343 | skb_tx_timestamp(skb); |
| 342 | if (likely(veth_forward_skb(rcv, skb, rq, use_napi) == NET_RX_SUCCESS)) { | 344 | if (likely(veth_forward_skb(rcv, skb, rq, use_napi) == NET_RX_SUCCESS)) { |
| 345 | if (queue) | ||
| 346 | txq_trans_cond_update(queue); | ||
| 343 | if (!use_napi) | 347 | if (!use_napi) |
| 344 | dev_lstats_add(dev, length); | 348 | dev_lstats_add(dev, length); |
| 345 | } else { | 349 | } else { |
| @@ -2768,7 +2768,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = { · 2767 unmodified lines | |||
| 2768 | static void virtnet_freeze_down(struct virtio_device *vdev) | 2768 | static void virtnet_freeze_down(struct virtio_device *vdev) |
| 2769 | { | 2769 | { |
| 2770 | struct virtnet_info *vi = vdev->priv; | 2770 | struct virtnet_info *vi = vdev->priv; |
| 2771 | int i; | ||
| 2772 | 2771 | ||
| 2773 | /* Make sure no work handler is accessing the device */ | 2772 | /* Make sure no work handler is accessing the device */ |
| 2774 | flush_work(&vi->config_work); | 2773 | flush_work(&vi->config_work); |
| @@ -2776,14 +2775,8 @@ static void virtnet_freeze_down(struct virtio_device *vdev) · 1 unmodified line | |||
| 2776 | netif_tx_lock_bh(vi->dev); | 2775 | netif_tx_lock_bh(vi->dev); |
| 2777 | netif_device_detach(vi->dev); | 2776 | netif_device_detach(vi->dev); |
| 2778 | netif_tx_unlock_bh(vi->dev); | 2777 | netif_tx_unlock_bh(vi->dev); |
| 2779 | cancel_delayed_work_sync(&vi->refill); | 2778 | if (netif_running(vi->dev)) |
| 2780 | 2779 | virtnet_close(vi->dev); | |
| 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 | } | ||
| 2787 | } | 2780 | } |
| 2788 | 2781 | ||
| 2789 | static int init_vqs(struct virtnet_info *vi); | 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 | static int virtnet_restore_up(struct virtio_device *vdev) | 2784 | static int virtnet_restore_up(struct virtio_device *vdev) |
| 2792 | { | 2785 | { |
| 2793 | struct virtnet_info *vi = vdev->priv; | 2786 | struct virtnet_info *vi = vdev->priv; |
| 2794 | int err, i; | 2787 | int err; |
| 2795 | 2788 | ||
| 2796 | err = init_vqs(vi); | 2789 | err = init_vqs(vi); |
| 2797 | if (err) | 2790 | if (err) |
| @@ -2800,15 +2793,9 @@ static int virtnet_restore_up(struct virtio_device *vdev) · 2 unmodified lines | |||
| 2800 | virtio_device_ready(vdev); | 2793 | virtio_device_ready(vdev); |
| 2801 | 2794 | ||
| 2802 | if (netif_running(vi->dev)) { | 2795 | if (netif_running(vi->dev)) { |
| 2803 | for (i = 0; i < vi->curr_queue_pairs; i++) | 2796 | err = virtnet_open(vi->dev); |
| 2804 | if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL)) | 2797 | if (err) |
| 2805 | schedule_delayed_work(&vi->refill, 0); | 2798 | return err; |
| 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 | } | ||
| 2812 | } | 2799 | } |
| 2813 | 2800 | ||
| 2814 | netif_tx_lock_bh(vi->dev); | 2801 | netif_tx_lock_bh(vi->dev); |
| @@ -2546,6 +2546,20 @@ static const struct nvme_core_quirk_entry core_quirks[] = { · 2545 unmodified lines | |||
| 2546 | .vid = 0x1e0f, | 2546 | .vid = 0x1e0f, |
| 2547 | .mn = "KCD6XVUL6T40", | 2547 | .mn = "KCD6XVUL6T40", |
| 2548 | .quirks = NVME_QUIRK_NO_APST, | 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 | * we have no UUID set | 3299 | * we have no UUID set |
| 3286 | */ | 3300 | */ |
| 3287 | if (uuid_is_null(&ids->uuid)) { | 3301 | if (uuid_is_null(&ids->uuid)) { |
| 3288 | printk_ratelimited(KERN_WARNING | 3302 | dev_warn_ratelimited(dev, |
| 3289 | "No UUID available providing old NGUID\n"); | 3303 | "No UUID available providing old NGUID\n"); |
| 3290 | return sysfs_emit(buf, "%pU\n", ids->nguid); | 3304 | return sysfs_emit(buf, "%pU\n", ids->nguid); |
| 3291 | } | 3305 | } |
| 3292 | return sysfs_emit(buf, "%pU\n", &ids->uuid); | 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 | if (ret) { | 3877 | if (ret) { |
| 3864 | dev_err(ctrl->device, | 3878 | dev_err(ctrl->device, |
| 3865 | "globally duplicate IDs for nsid %d\n", nsid); | 3879 | "globally duplicate IDs for nsid %d\n", nsid); |
| 3880 | nvme_print_device_info(ctrl); | ||
| 3866 | return ret; | 3881 | return ret; |
| 3867 | } | 3882 | } |
| 3868 | 3883 | ||
| @@ -503,6 +503,7 @@ struct nvme_ctrl_ops { · 502 unmodified lines | |||
| 503 | void (*submit_async_event)(struct nvme_ctrl *ctrl); | 503 | void (*submit_async_event)(struct nvme_ctrl *ctrl); |
| 504 | void (*delete_ctrl)(struct nvme_ctrl *ctrl); | 504 | void (*delete_ctrl)(struct nvme_ctrl *ctrl); |
| 505 | int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); | 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 | return blk_mq_tag_to_rq(tags, nvme_tag_from_cid(command_id)); | 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 | #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS | 579 | #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS |
| 552 | void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, | 580 | void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, |
| 553 | const char *dev_name); | 581 | const char *dev_name); |
| @@ -1334,6 +1334,14 @@ static void nvme_warn_reset(struct nvme_dev *dev, u32 csts) · 1333 unmodified lines | |||
| 1334 | dev_warn(dev->ctrl.device, | 1334 | dev_warn(dev->ctrl.device, |
| 1335 | "controller is down; will reset: CSTS=0x%x, PCI_STATUS read failed (%d)\n", | 1335 | "controller is down; will reset: CSTS=0x%x, PCI_STATUS read failed (%d)\n", |
| 1336 | csts, result); | 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 | static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | 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 | return snprintf(buf, size, "%s\n", dev_name(&pdev->dev)); | 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 | static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { | 3002 | static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { |
| 2980 | .name = "pcie", | 3003 | .name = "pcie", |
| 2981 | .module = THIS_MODULE, | 3004 | .module = THIS_MODULE, |
| @@ -2987,6 +3010,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { · 5 unmodified lines | |||
| 2987 | .free_ctrl = nvme_pci_free_ctrl, | 3010 | .free_ctrl = nvme_pci_free_ctrl, |
| 2988 | .submit_async_event = nvme_pci_submit_async_event, | 3011 | .submit_async_event = nvme_pci_submit_async_event, |
| 2989 | .get_address = nvme_pci_get_address, | 3012 | .get_address = nvme_pci_get_address, |
| 3013 | .print_device_info = nvme_pci_print_device_info, | ||
| 2990 | }; | 3014 | }; |
| 2991 | 3015 | ||
| 2992 | static int nvme_dev_map(struct nvme_dev *dev) | 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 | { PCI_VDEVICE(REDHAT, 0x0010), /* Qemu emulated controller */ | 3445 | { PCI_VDEVICE(REDHAT, 0x0010), /* Qemu emulated controller */ |
| 3422 | .driver_data = NVME_QUIRK_BOGUS_NID, }, | 3446 | .driver_data = NVME_QUIRK_BOGUS_NID, }, |
| 3423 | { PCI_DEVICE(0x126f, 0x2263), /* Silicon Motion unidentified */ | 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 | { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ | 3450 | { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ |
| 3426 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | | 3451 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
| 3427 | NVME_QUIRK_NO_NS_DESC_LIST, }, | 3452 | NVME_QUIRK_NO_NS_DESC_LIST, }, |
| @@ -3437,6 +3462,8 @@ static const struct pci_device_id nvme_id_table[] = { · 9 unmodified lines | |||
| 3437 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | | 3462 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
| 3438 | NVME_QUIRK_DISABLE_WRITE_ZEROES| | 3463 | NVME_QUIRK_DISABLE_WRITE_ZEROES| |
| 3439 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 3464 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3465 | { PCI_DEVICE(0x1987, 0x5012), /* Phison E12 */ | ||
| 3466 | .driver_data = NVME_QUIRK_BOGUS_NID, }, | ||
| 3440 | { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ | 3467 | { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ |
| 3441 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 3468 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3442 | { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ | 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 | { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ | 3474 | { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ |
| 3448 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | | 3475 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | |
| 3449 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 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 | { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */ | 3479 | { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */ |
| 3451 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | 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 | { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ | 3483 | { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ |
| 3453 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | 3484 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, |
| 3454 | { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ | 3485 | { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ |
| 3455 | .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | 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 | { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ | 3495 | { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ |
| 3457 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, | 3496 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, |
| 3458 | { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ | 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 | .driver_data = NVME_QUIRK_BOGUS_NID, }, | 3502 | .driver_data = NVME_QUIRK_BOGUS_NID, }, |
| 3464 | { PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */ | 3503 | { PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */ |
| 3465 | .driver_data = NVME_QUIRK_BOGUS_NID, }, | 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 | { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0061), | 3509 | { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0061), |
| 3467 | .driver_data = NVME_QUIRK_DMA_ADDRESS_BITS_48, }, | 3510 | .driver_data = NVME_QUIRK_DMA_ADDRESS_BITS_48, }, |
| 3468 | { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0065), | 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 | NVME_QUIRK_128_BYTES_SQES | | 3526 | NVME_QUIRK_128_BYTES_SQES | |
| 3484 | NVME_QUIRK_SHARED_TAGS | | 3527 | NVME_QUIRK_SHARED_TAGS | |
| 3485 | NVME_QUIRK_SKIP_CID_GEN }, | 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 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, | 3529 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, |
| 3491 | { 0, } | 3530 | { 0, } |
| 3492 | }; | 3531 | }; |
| @@ -723,19 +723,19 @@ static const struct regulator_desc pms405_pldo600 = { · 722 unmodified lines | |||
| 723 | 723 | ||
| 724 | static const struct regulator_desc mp5496_smpa2 = { | 724 | static const struct regulator_desc mp5496_smpa2 = { |
| 725 | .linear_ranges = (struct linear_range[]) { | 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 | .n_linear_ranges = 1, | 728 | .n_linear_ranges = 1, |
| 729 | .n_voltages = 28, | 729 | .n_voltages = 128, |
| 730 | .ops = &rpm_mp5496_ops, | 730 | .ops = &rpm_mp5496_ops, |
| 731 | }; | 731 | }; |
| 732 | 732 | ||
| 733 | static const struct regulator_desc mp5496_ldoa2 = { | 733 | static const struct regulator_desc mp5496_ldoa2 = { |
| 734 | .linear_ranges = (struct linear_range[]) { | 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 | .n_linear_ranges = 1, | 737 | .n_linear_ranges = 1, |
| 738 | .n_voltages = 61, | 738 | .n_voltages = 128, |
| 739 | .ops = &rpm_mp5496_ops, | 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 | static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *); | 160 | static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *); |
| 161 | static void ibmvfc_tgt_move_login(struct ibmvfc_target *); | 161 | static void ibmvfc_tgt_move_login(struct ibmvfc_target *); |
| 162 | 162 | ||
| 163 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *); | 163 | static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *); |
| 164 | static void ibmvfc_init_sub_crqs(struct ibmvfc_host *); | 164 | static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *); |
| 165 | 165 | ||
| 166 | static const char *unknown_error = "unknown error"; | 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 | struct vio_dev *vdev = to_vio_dev(vhost->dev); | 917 | struct vio_dev *vdev = to_vio_dev(vhost->dev); |
| 918 | unsigned long flags; | 918 | unsigned long flags; |
| 919 | 919 | ||
| 920 | ibmvfc_release_sub_crqs(vhost); | 920 | ibmvfc_dereg_sub_crqs(vhost); |
| 921 | 921 | ||
| 922 | /* Re-enable the CRQ */ | 922 | /* Re-enable the CRQ */ |
| 923 | do { | 923 | do { |
| @@ -936,7 +936,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) · 12 unmodified lines | |||
| 936 | spin_unlock(vhost->crq.q_lock); | 936 | spin_unlock(vhost->crq.q_lock); |
| 937 | spin_unlock_irqrestore(vhost->host->host_lock, flags); | 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 | return rc; | 941 | return rc; |
| 942 | } | 942 | } |
| @@ -955,7 +955,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 12 unmodified lines | |||
| 955 | struct vio_dev *vdev = to_vio_dev(vhost->dev); | 955 | struct vio_dev *vdev = to_vio_dev(vhost->dev); |
| 956 | struct ibmvfc_queue *crq = &vhost->crq; | 956 | struct ibmvfc_queue *crq = &vhost->crq; |
| 957 | 957 | ||
| 958 | ibmvfc_release_sub_crqs(vhost); | 958 | ibmvfc_dereg_sub_crqs(vhost); |
| 959 | 959 | ||
| 960 | /* Close the CRQ */ | 960 | /* Close the CRQ */ |
| 961 | do { | 961 | do { |
| @@ -988,7 +988,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 26 unmodified lines | |||
| 988 | spin_unlock(vhost->crq.q_lock); | 988 | spin_unlock(vhost->crq.q_lock); |
| 989 | spin_unlock_irqrestore(vhost->host->host_lock, flags); | 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 | return rc; | 993 | return rc; |
| 994 | } | 994 | } |
| @@ -5682,6 +5682,8 @@ static int ibmvfc_alloc_queue(struct ibmvfc_host *vhost, · 4687 unmodified lines | |||
| 5682 | queue->cur = 0; | 5682 | queue->cur = 0; |
| 5683 | queue->fmt = fmt; | 5683 | queue->fmt = fmt; |
| 5684 | queue->size = PAGE_SIZE / fmt_size; | 5684 | queue->size = PAGE_SIZE / fmt_size; |
| 5685 | |||
| 5686 | queue->vhost = vhost; | ||
| 5685 | return 0; | 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 | ENTER; | 5760 | ENTER; |
| 5759 | 5761 | ||
| 5760 | if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT)) | ||
| 5761 | return -ENOMEM; | ||
| 5762 | |||
| 5763 | rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE, | 5762 | rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE, |
| 5764 | &scrq->cookie, &scrq->hw_irq); | 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 | scrq->hwq_id = index; | 5791 | scrq->hwq_id = index; |
| 5793 | scrq->vhost = vhost; | ||
| 5794 | 5792 | ||
| 5795 | LEAVE; | 5793 | LEAVE; |
| 5796 | return 0; | 5794 | return 0; |
| @@ -5800,7 +5798,6 @@ irq_failed: · 3 unmodified lines | |||
| 5800 | rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); | 5798 | rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); |
| 5801 | } while (rtas_busy_delay(rc)); | 5799 | } while (rtas_busy_delay(rc)); |
| 5802 | reg_failed: | 5800 | reg_failed: |
| 5803 | ibmvfc_free_queue(vhost, scrq); | ||
| 5804 | LEAVE; | 5801 | LEAVE; |
| 5805 | return rc; | 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 | if (rc) | 5823 | if (rc) |
| 5827 | dev_err(dev, "Failed to free sub-crq[%d]: rc=%ld\n", index, rc); | 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 | LEAVE; | 5864 | LEAVE; |
| 5831 | } | 5865 | } |
| 5832 | 5866 | ||
| 5833 | static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) | 5867 | static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) |
| 5834 | { | 5868 | { |
| 5869 | struct ibmvfc_queue *scrq; | ||
| 5835 | int i, j; | 5870 | int i, j; |
| 5836 | 5871 | ||
| 5837 | ENTER; | 5872 | ENTER; |
| @@ -5847,30 +5882,41 @@ static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) · 9 unmodified lines | |||
| 5847 | } | 5882 | } |
| 5848 | 5883 | ||
| 5849 | for (i = 0; i < nr_scsi_hw_queues; i++) { | 5884 | for (i = 0; i < nr_scsi_hw_queues; i++) { |
| 5850 | if (ibmvfc_register_scsi_channel(vhost, i)) { | 5885 | scrq = &vhost->scsi_scrqs.scrqs[i]; |
| 5851 | for (j = i; j > 0; j--) | 5886 | if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT)) { |
| 5852 | ibmvfc_deregister_scsi_channel(vhost, j - 1); | 5887 | for (j = i; j > 0; j--) { |
| 5888 | scrq = &vhost->scsi_scrqs.scrqs[j - 1]; | ||
| 5889 | ibmvfc_free_queue(vhost, scrq); | ||
| 5890 | } | ||
| 5853 | kfree(vhost->scsi_scrqs.scrqs); | 5891 | kfree(vhost->scsi_scrqs.scrqs); |
| 5854 | vhost->scsi_scrqs.scrqs = NULL; | 5892 | vhost->scsi_scrqs.scrqs = NULL; |
| 5855 | vhost->scsi_scrqs.active_queues = 0; | 5893 | vhost->scsi_scrqs.active_queues = 0; |
| 5856 | vhost->do_enquiry = 0; | 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 | LEAVE; | 5902 | LEAVE; |
| 5862 | } | 5903 | } |
| 5863 | 5904 | ||
| 5864 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost) | 5905 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost) |
| 5865 | { | 5906 | { |
| 5907 | struct ibmvfc_queue *scrq; | ||
| 5866 | int i; | 5908 | int i; |
| 5867 | 5909 | ||
| 5868 | ENTER; | 5910 | ENTER; |
| 5869 | if (!vhost->scsi_scrqs.scrqs) | 5911 | if (!vhost->scsi_scrqs.scrqs) |
| 5870 | return; | 5912 | return; |
| 5871 | 5913 | ||
| 5872 | for (i = 0; i < nr_scsi_hw_queues; i++) | 5914 | ibmvfc_dereg_sub_crqs(vhost); |
| 5873 | ibmvfc_deregister_scsi_channel(vhost, i); | 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 | kfree(vhost->scsi_scrqs.scrqs); | 5921 | kfree(vhost->scsi_scrqs.scrqs); |
| 5876 | vhost->scsi_scrqs.scrqs = NULL; | 5922 | vhost->scsi_scrqs.scrqs = NULL; |
| @@ -789,6 +789,7 @@ struct ibmvfc_queue { · 788 unmodified lines | |||
| 789 | spinlock_t _lock; | 789 | spinlock_t _lock; |
| 790 | spinlock_t *q_lock; | 790 | spinlock_t *q_lock; |
| 791 | 791 | ||
| 792 | struct ibmvfc_host *vhost; | ||
| 792 | struct ibmvfc_event_pool evt_pool; | 793 | struct ibmvfc_event_pool evt_pool; |
| 793 | struct list_head sent; | 794 | struct list_head sent; |
| 794 | struct list_head free; | 795 | struct list_head free; |
| @@ -797,7 +798,6 @@ struct ibmvfc_queue { · 2 unmodified lines | |||
| 797 | union ibmvfc_iu cancel_rsp; | 798 | union ibmvfc_iu cancel_rsp; |
| 798 | 799 | ||
| 799 | /* Sub-CRQ fields */ | 800 | /* Sub-CRQ fields */ |
| 800 | struct ibmvfc_host *vhost; | ||
| 801 | unsigned long cookie; | 801 | unsigned long cookie; |
| 802 | unsigned long vios_cookie; | 802 | unsigned long vios_cookie; |
| 803 | unsigned long hw_irq; | 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 | static void zbc_inc_wp(struct sdebug_dev_info *devip, | 2847 | static void zbc_inc_wp(struct sdebug_dev_info *devip, |
| 2830 | unsigned long long lba, unsigned int num) | 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 | if (zsp->z_type == ZBC_ZTYPE_SWR) { | 2856 | if (zsp->z_type == ZBC_ZTYPE_SWR) { |
| 2839 | zsp->z_wp += num; | 2857 | zsp->z_wp += num; |
| 2840 | if (zsp->z_wp >= zend) | 2858 | if (zsp->z_wp >= zend) |
| 2841 | zsp->z_cond = ZC5_FULL; | 2859 | zbc_set_zone_full(devip, zsp); |
| 2842 | return; | 2860 | return; |
| 2843 | } | 2861 | } |
| 2844 | 2862 | ||
| @@ -2857,7 +2875,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip, · 12 unmodified lines | |||
| 2857 | n = num; | 2875 | n = num; |
| 2858 | } | 2876 | } |
| 2859 | if (zsp->z_wp >= zend) | 2877 | if (zsp->z_wp >= zend) |
| 2860 | zsp->z_cond = ZC5_FULL; | 2878 | zbc_set_zone_full(devip, zsp); |
| 2861 | 2879 | ||
| 2862 | num -= n; | 2880 | num -= n; |
| 2863 | lba += n; | 2881 | lba += n; |
| @@ -212,7 +212,12 @@ iscsi_create_endpoint(int dd_size) · 211 unmodified lines | |||
| 212 | return NULL; | 212 | return NULL; |
| 213 | 213 | ||
| 214 | mutex_lock(&iscsi_ep_idr_mutex); | 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 | if (id < 0) { | 221 | if (id < 0) { |
| 217 | mutex_unlock(&iscsi_ep_idr_mutex); | 222 | mutex_unlock(&iscsi_ep_idr_mutex); |
| 218 | printk(KERN_ERR "Could not allocate endpoint ID. Error %d.\n", | 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 | .cmd_per_lun = 2048, | 1844 | .cmd_per_lun = 2048, |
| 1845 | .this_id = -1, | 1845 | .this_id = -1, |
| 1846 | /* Ensure there are no gaps in presented sgls */ | 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 | .no_write_same = 1, | 1848 | .no_write_same = 1, |
| 1849 | .track_queue_depth = 1, | 1849 | .track_queue_depth = 1, |
| 1850 | .change_queue_depth = storvsc_change_queue_depth, | 1850 | .change_queue_depth = storvsc_change_queue_depth, |
| @@ -1895,6 +1895,7 @@ static int storvsc_probe(struct hv_device *device, · 44 unmodified lines | |||
| 1895 | int target = 0; | 1895 | int target = 0; |
| 1896 | struct storvsc_device *stor_device; | 1896 | struct storvsc_device *stor_device; |
| 1897 | int max_sub_channels = 0; | 1897 | int max_sub_channels = 0; |
| 1898 | u32 max_xfer_bytes; | ||
| 1898 | 1899 | ||
| 1899 | /* | 1900 | /* |
| 1900 | * We support sub-channels for storage on SCSI and FC controllers. | 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 | /* max cmd length */ | 1970 | /* max cmd length */ |
| 1970 | host->max_cmd_len = STORVSC_MAX_CMD_LEN; | 1971 | host->max_cmd_len = STORVSC_MAX_CMD_LEN; |
| 1971 | |||
| 1972 | /* | 1972 | /* |
| 1973 | * set the table size based on the info we got | 1973 | * Any reasonable Hyper-V configuration should provide |
| 1974 | * from the host. | 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 | * For non-IDE disks, the host supports multiple channels. | 1995 | * For non-IDE disks, the host supports multiple channels. |
| 1979 | * Set the number of HW queues we are supporting. | 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 | ret = brcmstb_init_sram(dn); | 785 | ret = brcmstb_init_sram(dn); |
| 786 | of_node_put(dn); | ||
| 786 | if (ret) { | 787 | if (ret) { |
| 787 | pr_err("error setting up SRAM for PM\n"); | 788 | pr_err("error setting up SRAM for PM\n"); |
| 788 | return ret; | 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 | [IMX8MP_MEDIABLK_PD_LCDIF_2] = { | 668 | [IMX8MP_MEDIABLK_PD_LCDIF_2] = { |
| 669 | .name = "mediablk-lcdif-2", | 669 | .name = "mediablk-lcdif-2", |
| 670 | .clk_names = (const char *[]){ "disp1", "apb", "axi", }, | 670 | .clk_names = (const char *[]){ "disp2", "apb", "axi", }, |
| 671 | .num_clks = 3, | 671 | .num_clks = 3, |
| 672 | .gpc_name = "lcdif2", | 672 | .gpc_name = "lcdif2", |
| 673 | .rst_mask = BIT(11) | BIT(12) | BIT(24), | 673 | .rst_mask = BIT(11) | BIT(12) | BIT(24), |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | |||
| 69 | #define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */ | 69 | #define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */ |
| 70 | #define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */ | 70 | #define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */ |
| 71 | #define CDNS_SPI_SS0 0x1 /* Slave Select zero */ | 71 | #define CDNS_SPI_SS0 0x1 /* Slave Select zero */ |
| 72 | #define CDNS_SPI_NOSS 0x3C /* No Slave select */ | ||
| 72 | 73 | ||
| 73 | /* | 74 | /* |
| 74 | * SPI Interrupt Registers bit Masks | 75 | * SPI Interrupt Registers bit Masks |
| @@ -92,9 +93,6 @@ · 17 unmodified lines | |||
| 92 | #define CDNS_SPI_ER_ENABLE 0x00000001 /* SPI Enable Bit Mask */ | 93 | #define CDNS_SPI_ER_ENABLE 0x00000001 /* SPI Enable Bit Mask */ |
| 93 | #define CDNS_SPI_ER_DISABLE 0x0 /* SPI Disable Bit Mask */ | 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 | /* Default number of chip select lines */ | 96 | /* Default number of chip select lines */ |
| 99 | #define CDNS_SPI_DEFAULT_NUM_CS 4 | 97 | #define CDNS_SPI_DEFAULT_NUM_CS 4 |
| 100 | 98 | ||
| @@ -110,6 +108,7 @@ · 9 unmodified lines | |||
| 110 | * @rx_bytes: Number of bytes requested | 108 | * @rx_bytes: Number of bytes requested |
| 111 | * @dev_busy: Device busy flag | 109 | * @dev_busy: Device busy flag |
| 112 | * @is_decoded_cs: Flag for decoder property set or not | 110 | * @is_decoded_cs: Flag for decoder property set or not |
| 111 | * @tx_fifo_depth: Depth of the TX FIFO | ||
| 113 | */ | 112 | */ |
| 114 | struct cdns_spi { | 113 | struct cdns_spi { |
| 115 | void __iomem *regs; | 114 | void __iomem *regs; |
| @@ -123,6 +122,7 @@ struct cdns_spi { · 7 unmodified lines | |||
| 123 | int rx_bytes; | 122 | int rx_bytes; |
| 124 | u8 dev_busy; | 123 | u8 dev_busy; |
| 125 | u32 is_decoded_cs; | 124 | u32 is_decoded_cs; |
| 125 | unsigned int tx_fifo_depth; | ||
| 126 | }; | 126 | }; |
| 127 | 127 | ||
| 128 | /* Macros for the SPI controller read/write */ | 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 | unsigned long trans_cnt = 0; | 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 | (xspi->tx_bytes > 0)) { | 308 | (xspi->tx_bytes > 0)) { |
| 309 | 309 | ||
| 310 | /* When xspi in busy condition, bytes may send failed, | 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 | * @master: Pointer to the spi_master structure which provides | 450 | * @master: Pointer to the spi_master structure which provides |
| 451 | * information about the controller. | 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 | * Return: 0 always | 455 | * Return: 0 always |
| 456 | */ | 456 | */ |
| 457 | static int cdns_unprepare_transfer_hardware(struct spi_master *master) | 457 | static int cdns_unprepare_transfer_hardware(struct spi_master *master) |
| 458 | { | 458 | { |
| 459 | struct cdns_spi *xspi = spi_master_get_devdata(master); | 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 | return 0; | 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 | * cdns_spi_probe - Probe method for the SPI driver | 490 | * cdns_spi_probe - Probe method for the SPI driver |
| 468 | * @pdev: Pointer to the platform_device structure | 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 | if (ret < 0) | 558 | if (ret < 0) |
| 536 | xspi->is_decoded_cs = 0; | 559 | xspi->is_decoded_cs = 0; |
| 537 | 560 | ||
| 561 | cdns_spi_detect_fifo_depth(xspi); | ||
| 562 | |||
| 538 | /* SPI controller initializations */ | 563 | /* SPI controller initializations */ |
| 539 | cdns_spi_init_hw(xspi); | 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 | op->data.dir != SPI_MEM_DATA_IN) | 808 | op->data.dir != SPI_MEM_DATA_IN) |
| 809 | return -EINVAL; | 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 | ret = spi_mem_access_start(mem); | 812 | ret = spi_mem_access_start(mem); |
| 813 | if (ret) | 813 | if (ret) |
| 814 | return ret; | 814 | return ret; |
| @@ -381,15 +381,18 @@ static int rockchip_spi_prepare_irq(struct rockchip_spi *rs, · 380 unmodified lines | |||
| 381 | rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0; | 381 | rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0; |
| 382 | rs->rx_left = xfer->len / rs->n_bytes; | 382 | rs->rx_left = xfer->len / rs->n_bytes; |
| 383 | 383 | ||
| 384 | if (rs->cs_inactive) | 384 | writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR); |
| 385 | writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR); | 385 | |
| 386 | else | ||
| 387 | writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR); | ||
| 388 | spi_enable_chip(rs, true); | 386 | spi_enable_chip(rs, true); |
| 389 | 387 | ||
| 390 | if (rs->tx_left) | 388 | if (rs->tx_left) |
| 391 | rockchip_spi_pio_writer(rs); | 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 | /* 1 means the transfer is in progress */ | 396 | /* 1 means the transfer is in progress */ |
| 394 | return 1; | 397 | return 1; |
| 395 | } | 398 | } |
| @@ -1,7 +1,7 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | config FB_OLPC_DCON | 2 | config FB_OLPC_DCON |
| 3 | tristate "One Laptop Per Child Display CONtroller support" | 3 | tristate "One Laptop Per Child Display CONtroller support" |
| 4 | depends on OLPC && FB | 4 | depends on OLPC && FB && BROKEN |
| 5 | depends on I2C | 5 | depends on I2C |
| 6 | depends on GPIO_CS5535 && ACPI | 6 | depends on GPIO_CS5535 && ACPI |
| 7 | select BACKLIGHT_CLASS_DEVICE | 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 | pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; | 179 | pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; |
| 180 | 180 | ||
| 181 | res = rtw_alloc_hwxmits(padapter); | 181 | if (rtw_alloc_hwxmits(padapter)) { |
| 182 | if (res) { | ||
| 183 | res = _FAIL; | 182 | res = _FAIL; |
| 184 | goto exit; | 183 | goto exit; |
| 185 | } | 184 | } |
| @@ -1483,19 +1482,10 @@ int rtw_alloc_hwxmits(struct adapter *padapter) · 1297 unmodified lines | |||
| 1483 | 1482 | ||
| 1484 | hwxmits = pxmitpriv->hwxmits; | 1483 | hwxmits = pxmitpriv->hwxmits; |
| 1485 | 1484 | ||
| 1486 | if (pxmitpriv->hwxmit_entry == 5) { | 1485 | hwxmits[0].sta_queue = &pxmitpriv->vo_pending; |
| 1487 | hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; | 1486 | hwxmits[1].sta_queue = &pxmitpriv->vi_pending; |
| 1488 | hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; | 1487 | hwxmits[2].sta_queue = &pxmitpriv->be_pending; |
| 1489 | hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; | 1488 | hwxmits[3].sta_queue = &pxmitpriv->bk_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 | } | ||
| 1499 | 1489 | ||
| 1500 | return 0; | 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 | if (wep_key_len > 0) { | 404 | if (wep_key_len > 0) { |
| 405 | wep_key_len = wep_key_len <= 5 ? 5 : 13; | 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 | pwep = kzalloc(wep_total_len, GFP_KERNEL); | 407 | pwep = kzalloc(wep_total_len, GFP_KERNEL); |
| 408 | if (!pwep) | 408 | if (!pwep) |
| 409 | goto exit; | 409 | goto exit; |
| @@ -90,7 +90,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, · 89 unmodified lines | |||
| 90 | if (wep_key_len > 0) { | 90 | if (wep_key_len > 0) { |
| 91 | wep_key_len = wep_key_len <= 5 ? 5 : 13; | 91 | wep_key_len = wep_key_len <= 5 ? 5 : 13; |
| 92 | wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material); | 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 | if (!pwep) { | 95 | if (!pwep) { |
| 95 | ret = -ENOMEM; | 96 | ret = -ENOMEM; |
| 96 | goto exit; | 97 | goto exit; |
| @@ -582,7 +583,8 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, · 485 unmodified lines | |||
| 582 | if (wep_key_len > 0) { | 583 | if (wep_key_len > 0) { |
| 583 | wep_key_len = wep_key_len <= 5 ? 5 : 13; | 584 | wep_key_len = wep_key_len <= 5 ? 5 : 13; |
| 584 | wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material); | 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 | if (!pwep) | 588 | if (!pwep) |
| 587 | goto exit; | 589 | goto exit; |
| 588 | 590 | ||
| @@ -426,7 +426,7 @@ static int goldfish_tty_remove(struct platform_device *pdev) · 425 unmodified lines | |||
| 426 | tty_unregister_device(goldfish_tty_driver, qtty->console.index); | 426 | tty_unregister_device(goldfish_tty_driver, qtty->console.index); |
| 427 | iounmap(qtty->base); | 427 | iounmap(qtty->base); |
| 428 | qtty->base = NULL; | 428 | qtty->base = NULL; |
| 429 | free_irq(qtty->irq, pdev); | 429 | free_irq(qtty->irq, qtty); |
| 430 | tty_port_destroy(&qtty->port); | 430 | tty_port_destroy(&qtty->port); |
| 431 | goldfish_tty_current_line_count--; | 431 | goldfish_tty_current_line_count--; |
| 432 | if (goldfish_tty_current_line_count == 0) | 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 | return; | 455 | return; |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | prefix = kasprintf(GFP_KERNEL, "%s: ", fname); | 458 | prefix = kasprintf(GFP_ATOMIC, "%s: ", fname); |
| 459 | if (!prefix) | 459 | if (!prefix) |
| 460 | return; | 460 | return; |
| 461 | print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, data, len, | 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 | unsigned char lsr = serial_in(p, UART_LSR); | 1517 | unsigned char lsr = serial_in(p, UART_LSR); |
| 1518 | u64 stop_delay = 0; | 1518 | u64 stop_delay = 0; |
| 1519 | 1519 | ||
| 1520 | p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
| 1521 | |||
| 1520 | if (!(lsr & UART_LSR_THRE)) | 1522 | if (!(lsr & UART_LSR_THRE)) |
| 1521 | return; | 1523 | return; |
| 1522 | /* | 1524 | /* |
| @@ -1306,6 +1306,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 1305 unmodified lines | |||
| 1306 | .stop_tx = qcom_geni_serial_stop_tx, | 1306 | .stop_tx = qcom_geni_serial_stop_tx, |
| 1307 | .start_tx = qcom_geni_serial_start_tx, | 1307 | .start_tx = qcom_geni_serial_start_tx, |
| 1308 | .stop_rx = qcom_geni_serial_stop_rx, | 1308 | .stop_rx = qcom_geni_serial_stop_rx, |
| 1309 | .start_rx = qcom_geni_serial_start_rx, | ||
| 1309 | .set_termios = qcom_geni_serial_set_termios, | 1310 | .set_termios = qcom_geni_serial_set_termios, |
| 1310 | .startup = qcom_geni_serial_startup, | 1311 | .startup = qcom_geni_serial_startup, |
| 1311 | .request_port = qcom_geni_serial_request_port, | 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 | * Nothing to do if the console is not suspending | 2215 | * Nothing to do if the console is not suspending |
| 2216 | * except stop_rx to prevent any asynchronous data | 2216 | * except stop_rx to prevent any asynchronous data |
| 2217 | * over RX line. Re-start_rx, when required, is | 2217 | * over RX line. However ensure that we will be |
| 2218 | * done by set_termios in resume sequence | 2218 | * able to Re-start_rx later. |
| 2219 | */ | 2219 | */ |
| 2220 | if (!console_suspend_enabled && uart_console(uport)) { | 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 | goto unlock; | 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 | if (console_suspend_enabled) | 2311 | if (console_suspend_enabled) |
| 2311 | uart_change_pm(state, UART_PM_STATE_ON); | 2312 | uart_change_pm(state, UART_PM_STATE_ON); |
| 2312 | uport->ops->set_termios(uport, &termios, NULL); | 2313 | uport->ops->set_termios(uport, &termios, NULL); |
| 2314 | if (!console_suspend_enabled && uport->ops->start_rx) | ||
| 2315 | uport->ops->start_rx(uport); | ||
| 2313 | if (console_suspend_enabled) | 2316 | if (console_suspend_enabled) |
| 2314 | console_start(uport->cons); | 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 | rcu_sysrq_start(); | 582 | rcu_sysrq_start(); |
| 583 | rcu_read_lock(); | 583 | rcu_read_lock(); |
| 584 | printk_prefer_direct_enter(); | ||
| 585 | /* | 584 | /* |
| 586 | * Raise the apparent loglevel to maximum so that the sysrq header | 585 | * Raise the apparent loglevel to maximum so that the sysrq header |
| 587 | * is shown to provide the user with positive feedback. We do not | 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 | pr_cont("\n"); | 622 | pr_cont("\n"); |
| 624 | console_loglevel = orig_log_level; | 623 | console_loglevel = orig_log_level; |
| 625 | } | 624 | } |
| 626 | printk_prefer_direct_exit(); | ||
| 627 | rcu_read_unlock(); | 625 | rcu_read_unlock(); |
| 628 | rcu_sysrq_end(); | 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 | * @hba: per adapter instance | 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 | if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR) | 757 | if (hba->quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR) |
| 758 | ufshcd_writel(hba, (1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR); | 758 | mask = ~mask; |
| 759 | else | 759 | /* |
| 760 | ufshcd_writel(hba, ~(1 << pos), | 760 | * From the UFSHCI specification: "UTP Transfer Request List CLear |
| 761 | REG_UTP_TRANSFER_REQ_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 | return ufshcd_compose_devman_upiu(hba, lrbp); | 2874 | return ufshcd_compose_devman_upiu(hba, lrbp); |
| 2864 | } | 2875 | } |
| 2865 | 2876 | ||
| 2866 | static int | 2877 | /* |
| 2867 | ufshcd_clear_cmd(struct ufs_hba *hba, int tag) | 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 | unsigned long flags; | 2884 | unsigned long flags; |
| 2871 | u32 mask = 1 << tag; | ||
| 2872 | 2885 | ||
| 2873 | /* clear outstanding transaction before retry */ | 2886 | /* clear outstanding transaction before retry */ |
| 2874 | spin_lock_irqsave(hba->host->host_lock, flags); | 2887 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 2875 | ufshcd_utrl_clear(hba, tag); | 2888 | ufshcd_utrl_clear(hba, mask); |
| 2876 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 2889 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 2877 | 2890 | ||
| 2878 | /* | 2891 | /* |
| 2879 | * wait for h/w to clear corresponding bit in door-bell. | 2892 | * wait for h/w to clear corresponding bit in door-bell. |
| 2880 | * max. wait is 1 sec. | 2893 | * max. wait is 1 sec. |
| 2881 | */ | 2894 | */ |
| 2882 | err = ufshcd_wait_for_register(hba, | 2895 | return ufshcd_wait_for_register(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL, |
| 2883 | REG_UTP_TRANSFER_REQ_DOOR_BELL, | 2896 | mask, ~mask, 1000, 1000); |
| 2884 | mask, ~mask, 1000, 1000); | ||
| 2885 | |||
| 2886 | return err; | ||
| 2887 | } | 2897 | } |
| 2888 | 2898 | ||
| 2889 | static int | 2899 | static int |
| @@ -2963,7 +2973,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, · 73 unmodified lines | |||
| 2963 | err = -ETIMEDOUT; | 2973 | err = -ETIMEDOUT; |
| 2964 | dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n", | 2974 | dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n", |
| 2965 | __func__, lrbp->task_tag); | 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 | /* successfully cleared the command, retry if needed */ | 2977 | /* successfully cleared the command, retry if needed */ |
| 2968 | err = -EAGAIN; | 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 | 6971 | * ufshcd_eh_device_reset_handler() - Reset a single logical unit. |
| 6962 | * scsi layer. | ||
| 6963 | * @cmd: SCSI command pointer | 6972 | * @cmd: SCSI command pointer |
| 6964 | * | 6973 | * |
| 6965 | * Returns SUCCESS/FAILED | 6974 | * Returns SUCCESS/FAILED |
| 6966 | */ | 6975 | */ |
| 6967 | static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) | 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 | struct Scsi_Host *host; | 6979 | struct Scsi_Host *host; |
| 6970 | struct ufs_hba *hba; | 6980 | struct ufs_hba *hba; |
| 6971 | u32 pos; | 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 | /* clear the commands that were pending for corresponding LUN */ | 6996 | /* clear the commands that were pending for corresponding LUN */ |
| 6987 | for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) { | 6997 | spin_lock_irqsave(&hba->outstanding_lock, flags); |
| 6988 | if (hba->lrb[pos].lun == lun) { | 6998 | for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) |
| 6989 | err = ufshcd_clear_cmd(hba, pos); | 6999 | if (hba->lrb[pos].lun == lun) |
| 6990 | if (err) | 7000 | __set_bit(pos, &pending_reqs); |
| 6991 | break; | 7001 | hba->outstanding_reqs &= ~pending_reqs; |
| 6992 | __ufshcd_transfer_req_compl(hba, 1U << pos); | 7002 | spin_unlock_irqrestore(&hba->outstanding_lock, flags); |
| 6993 | } | 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 | out: | 7016 | out: |
| 6997 | hba->req_abort_count = 0; | 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 | goto out; | 7108 | goto out; |
| 7089 | } | 7109 | } |
| 7090 | 7110 | ||
| 7091 | err = ufshcd_clear_cmd(hba, tag); | 7111 | err = ufshcd_clear_cmds(hba, 1U << tag); |
| 7092 | if (err) | 7112 | if (err) |
| 7093 | dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n", | 7113 | dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n", |
| 7094 | __func__, tag, err); | 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 | if (enqd_len + trb_buff_len >= full_len) { | 1943 | if (enqd_len + trb_buff_len >= full_len) { |
| 1944 | if (need_zero_pkt) | 1944 | if (need_zero_pkt && !zero_len_trb) { |
| 1945 | zero_len_trb = !zero_len_trb; | 1945 | zero_len_trb = true; |
| 1946 | 1946 | } else { | |
| 1947 | field &= ~TRB_CHAIN; | 1947 | zero_len_trb = false; |
| 1948 | field |= TRB_IOC; | 1948 | field &= ~TRB_CHAIN; |
| 1949 | more_trbs_coming = false; | 1949 | field |= TRB_IOC; |
| 1950 | preq->td.last_trb = ring->enqueue; | 1950 | more_trbs_coming = false; |
| 1951 | need_zero_pkt = false; | ||
| 1952 | preq->td.last_trb = ring->enqueue; | ||
| 1953 | } | ||
| 1951 | } | 1954 | } |
| 1952 | 1955 | ||
| 1953 | /* Only set interrupt on short packet for OUT endpoints. */ | 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 | length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) | | 1965 | length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) | |
| 1963 | TRB_INTR_TARGET(0); | 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 | lower_32_bits(send_addr), | 1969 | lower_32_bits(send_addr), |
| 1967 | upper_32_bits(send_addr), | 1970 | upper_32_bits(send_addr), |
| 1968 | length_field, | 1971 | length_field, |
| @@ -1048,6 +1048,9 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) · 1047 unmodified lines | |||
| 1048 | struct ci_hdrc *ci = req->context; | 1048 | struct ci_hdrc *ci = req->context; |
| 1049 | unsigned long flags; | 1049 | unsigned long flags; |
| 1050 | 1050 | ||
| 1051 | if (req->status < 0) | ||
| 1052 | return; | ||
| 1053 | |||
| 1051 | if (ci->setaddr) { | 1054 | if (ci->setaddr) { |
| 1052 | hw_usb_set_address(ci, ci->address); | 1055 | hw_usb_set_address(ci, ci->address); |
| 1053 | ci->setaddr = false; | 1056 | ci->setaddr = false; |
| @@ -5190,7 +5190,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg) · 5189 unmodified lines | |||
| 5190 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 5190 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 5191 | if (!res) { | 5191 | if (!res) { |
| 5192 | retval = -EINVAL; | 5192 | retval = -EINVAL; |
| 5193 | goto error1; | 5193 | goto error2; |
| 5194 | } | 5194 | } |
| 5195 | hcd->rsrc_start = res->start; | 5195 | hcd->rsrc_start = res->start; |
| 5196 | hcd->rsrc_len = resource_size(res); | 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 | * This device property is for kernel internal use only and | 1644 | * This device property is for kernel internal use only and |
| 1645 | * is expected to be set by the glue code. | 1645 | * is expected to be set by the glue code. |
| 1646 | */ | 1646 | */ |
| 1647 | if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) { | 1647 | if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) |
| 1648 | edev = extcon_get_extcon_dev(name); | 1648 | return extcon_get_extcon_dev(name); |
| 1649 | if (!edev) | ||
| 1650 | return ERR_PTR(-EPROBE_DEFER); | ||
| 1651 | |||
| 1652 | return edev; | ||
| 1653 | } | ||
| 1654 | 1649 | ||
| 1655 | /* | 1650 | /* |
| 1656 | * Try to get an extcon device from the USB PHY controller's "port" | 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 | PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), | 127 | PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), |
| 128 | PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), | 128 | PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), |
| 129 | PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"), | 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 | struct dwc3 *dwc = dep->dwc; | 2976 | struct dwc3 *dwc = dep->dwc; |
| 2977 | u32 mdwidth; | 2977 | u32 mdwidth; |
| 2978 | int size; | 2978 | int size; |
| 2979 | int maxpacket; | ||
| 2979 | 2980 | ||
| 2980 | mdwidth = dwc3_mdwidth(dwc); | 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 | else | 2989 | else |
| 2989 | size = DWC31_GTXFIFOSIZ_TXFDEP(size); | 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 | 2993 | * maxpacket size is determined as part of the following, after assuming |
| 2996 | * MaxPacketSize is recommended for endpoints that support burst and a | 2994 | * a mult value of one maxpacket: |
| 2997 | * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't | 2995 | * DWC3 revision 280A and prior: |
| 2998 | * support burst. Use those numbers and we can calculate the max packet | 2996 | * fifo_size = mult * (max_packet / mdwidth) + 1; |
| 2999 | * limit as below. | 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) | 3003 | if (DWC3_VER_IS_PRIOR(DWC3, 290A)) |
| 3002 | size /= 3; | 3004 | maxpacket = mdwidth * (size - 1); |
| 3003 | else | 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 | usb_ep_set_maxpacket_limit(&dep->endpoint, size); | 3010 | usb_ep_set_maxpacket_limit(&dep->endpoint, size); |
| 3007 | 3011 | ||
| 3008 | dep->endpoint.max_streams = 16; | 3012 | dep->endpoint.max_streams = 16; |
| @@ -122,8 +122,6 @@ struct ffs_ep { · 121 unmodified lines | |||
| 122 | struct usb_endpoint_descriptor *descs[3]; | 122 | struct usb_endpoint_descriptor *descs[3]; |
| 123 | 123 | ||
| 124 | u8 num; | 124 | u8 num; |
| 125 | |||
| 126 | int status; /* P: epfile->mutex */ | ||
| 127 | }; | 125 | }; |
| 128 | 126 | ||
| 129 | struct ffs_epfile { | 127 | struct ffs_epfile { |
| @@ -227,6 +225,9 @@ struct ffs_io_data { · 97 unmodified lines | |||
| 227 | bool use_sg; | 225 | bool use_sg; |
| 228 | 226 | ||
| 229 | struct ffs_data *ffs; | 227 | struct ffs_data *ffs; |
| 228 | |||
| 229 | int status; | ||
| 230 | struct completion done; | ||
| 230 | }; | 231 | }; |
| 231 | 232 | ||
| 232 | struct ffs_desc_helper { | 233 | struct ffs_desc_helper { |
| @@ -707,12 +708,15 @@ static const struct file_operations ffs_ep0_operations = { · 474 unmodified lines | |||
| 707 | 708 | ||
| 708 | static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) | 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 | ENTER(); | 713 | ENTER(); |
| 711 | if (req->context) { | 714 | if (req->status) |
| 712 | struct ffs_ep *ep = _ep->driver_data; | 715 | io_data->status = req->status; |
| 713 | ep->status = req->status ? req->status : req->actual; | 716 | else |
| 714 | complete(req->context); | 717 | io_data->status = req->actual; |
| 715 | } | 718 | |
| 719 | complete(&io_data->done); | ||
| 716 | } | 720 | } |
| 717 | 721 | ||
| 718 | static ssize_t ffs_copy_to_iter(void *data, int data_len, struct iov_iter *iter) | 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 | WARN(1, "%s: data_len == -EINVAL\n", __func__); | 1054 | WARN(1, "%s: data_len == -EINVAL\n", __func__); |
| 1051 | ret = -EINVAL; | 1055 | ret = -EINVAL; |
| 1052 | } else if (!io_data->aio) { | 1056 | } else if (!io_data->aio) { |
| 1053 | DECLARE_COMPLETION_ONSTACK(done); | ||
| 1054 | bool interrupted = false; | 1057 | bool interrupted = false; |
| 1055 | 1058 | ||
| 1056 | req = ep->req; | 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 | io_data->buf = data; | 1070 | io_data->buf = data; |
| 1068 | 1071 | ||
| 1069 | req->context = &done; | 1072 | init_completion(&io_data->done); |
| 1073 | req->context = io_data; | ||
| 1070 | req->complete = ffs_epfile_io_complete; | 1074 | req->complete = ffs_epfile_io_complete; |
| 1071 | 1075 | ||
| 1072 | ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); | 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 | spin_unlock_irq(&epfile->ffs->eps_lock); | 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 | * To avoid race condition with ffs_epfile_io_complete, | 1089 | * To avoid race condition with ffs_epfile_io_complete, |
| 1081 | * dequeue the request first then check | 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 | * condition with req->complete callback. | 1092 | * condition with req->complete callback. |
| 1084 | */ | 1093 | */ |
| 1085 | usb_ep_dequeue(ep->ep, req); | 1094 | usb_ep_dequeue(ep->ep, req); |
| 1086 | wait_for_completion(&done); | 1095 | spin_unlock_irq(&epfile->ffs->eps_lock); |
| 1087 | interrupted = ep->status < 0; | 1096 | wait_for_completion(&io_data->done); |
| 1097 | interrupted = io_data->status < 0; | ||
| 1088 | } | 1098 | } |
| 1089 | 1099 | ||
| 1090 | if (interrupted) | 1100 | if (interrupted) |
| 1091 | ret = -EINTR; | 1101 | ret = -EINTR; |
| 1092 | else if (io_data->read && ep->status > 0) | 1102 | else if (io_data->read && io_data->status > 0) |
| 1093 | ret = __ffs_epfile_read_data(epfile, data, ep->status, | 1103 | ret = __ffs_epfile_read_data(epfile, data, io_data->status, |
| 1094 | &io_data->data); | 1104 | &io_data->data); |
| 1095 | else | 1105 | else |
| 1096 | ret = ep->status; | 1106 | ret = io_data->status; |
| 1097 | goto error_mutex; | 1107 | goto error_mutex; |
| 1098 | } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) { | 1108 | } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) { |
| 1099 | ret = -ENOMEM; | 1109 | ret = -ENOMEM; |
| @@ -775,9 +775,13 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, · 774 unmodified lines | |||
| 775 | dev->qmult = qmult; | 775 | dev->qmult = qmult; |
| 776 | snprintf(net->name, sizeof(net->name), "%s%%d", netname); | 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 | dev_warn(&g->dev, | 780 | dev_warn(&g->dev, |
| 780 | "using random %s ethernet address\n", "self"); | 781 | "using random %s ethernet address\n", "self"); |
| 782 | } else { | ||
| 783 | net->addr_assign_type = NET_ADDR_SET; | ||
| 784 | } | ||
| 781 | eth_hw_addr_set(net, addr); | 785 | eth_hw_addr_set(net, addr); |
| 782 | if (get_ether_addr(host_addr, dev->host_mac)) | 786 | if (get_ether_addr(host_addr, dev->host_mac)) |
| 783 | dev_warn(&g->dev, | 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 | eth_random_addr(dev->dev_mac); | 849 | eth_random_addr(dev->dev_mac); |
| 846 | pr_warn("using random %s ethernet address\n", "self"); | 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 | eth_random_addr(dev->host_mac); | 855 | eth_random_addr(dev->host_mac); |
| 848 | pr_warn("using random %s ethernet address\n", "host"); | 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 | dev = netdev_priv(net); | 879 | dev = netdev_priv(net); |
| 872 | g = dev->gadget; | 880 | g = dev->gadget; |
| 873 | 881 | ||
| 874 | net->addr_assign_type = NET_ADDR_RANDOM; | ||
| 875 | eth_hw_addr_set(net, dev->dev_mac); | 882 | eth_hw_addr_set(net, dev->dev_mac); |
| 876 | 883 | ||
| 877 | status = register_netdev(net); | 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 | if (get_ether_addr(dev_addr, new_addr)) | 919 | if (get_ether_addr(dev_addr, new_addr)) |
| 913 | return -EINVAL; | 920 | return -EINVAL; |
| 914 | memcpy(dev->dev_mac, new_addr, ETH_ALEN); | 921 | memcpy(dev->dev_mac, new_addr, ETH_ALEN); |
| 922 | net->addr_assign_type = NET_ADDR_SET; | ||
| 915 | return 0; | 923 | return 0; |
| 916 | } | 924 | } |
| 917 | EXPORT_SYMBOL_GPL(gether_set_dev_addr); | 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 | uvcg_queue_cancel(queue, 0); | 424 | uvcg_queue_cancel(queue, 0); |
| 425 | break; | 425 | break; |
| 426 | } | 426 | } |
| 427 | |||
| 428 | /* Endpoint now owns the request */ | ||
| 429 | req = NULL; | ||
| 427 | video->req_int_count++; | 430 | video->req_int_count++; |
| 428 | } | 431 | } |
| 429 | 432 | ||
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/ctype.h> | 11 | #include <linux/ctype.h> |
| 12 | #include <linux/debugfs.h> | 12 | #include <linux/debugfs.h> |
| 13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 14 | #include <linux/idr.h> | ||
| 14 | #include <linux/kref.h> | 15 | #include <linux/kref.h> |
| 15 | #include <linux/miscdevice.h> | 16 | #include <linux/miscdevice.h> |
| 16 | #include <linux/module.h> | 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 | #define RAW_EVENT_QUEUE_SIZE 16 | 43 | #define RAW_EVENT_QUEUE_SIZE 16 |
| 40 | 44 | ||
| 41 | struct raw_event_queue { | 45 | struct raw_event_queue { |
| @@ -161,6 +165,9 @@ struct raw_dev { · 119 unmodified lines | |||
| 161 | /* Reference to misc device: */ | 165 | /* Reference to misc device: */ |
| 162 | struct device *dev; | 166 | struct device *dev; |
| 163 | 167 | ||
| 168 | /* Make driver names unique */ | ||
| 169 | int driver_id_number; | ||
| 170 | |||
| 164 | /* Protected by lock: */ | 171 | /* Protected by lock: */ |
| 165 | enum dev_state state; | 172 | enum dev_state state; |
| 166 | bool gadget_registered; | 173 | bool gadget_registered; |
| @@ -189,6 +196,7 @@ static struct raw_dev *dev_new(void) · 22 unmodified lines | |||
| 189 | spin_lock_init(&dev->lock); | 196 | spin_lock_init(&dev->lock); |
| 190 | init_completion(&dev->ep0_done); | 197 | init_completion(&dev->ep0_done); |
| 191 | raw_event_queue_init(&dev->queue); | 198 | raw_event_queue_init(&dev->queue); |
| 199 | dev->driver_id_number = -1; | ||
| 192 | return dev; | 200 | return dev; |
| 193 | } | 201 | } |
| 194 | 202 | ||
| @@ -199,6 +207,9 @@ static void dev_free(struct kref *kref) · 4 unmodified lines | |||
| 199 | 207 | ||
| 200 | kfree(dev->udc_name); | 208 | kfree(dev->udc_name); |
| 201 | kfree(dev->driver.udc_name); | 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 | if (dev->req) { | 213 | if (dev->req) { |
| 203 | if (dev->ep0_urb_queued) | 214 | if (dev->ep0_urb_queued) |
| 204 | usb_ep_dequeue(dev->gadget->ep0, dev->req); | 215 | usb_ep_dequeue(dev->gadget->ep0, dev->req); |
| @@ -419,9 +430,11 @@ out_put: · 214 unmodified lines | |||
| 419 | static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) | 430 | static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) |
| 420 | { | 431 | { |
| 421 | int ret = 0; | 432 | int ret = 0; |
| 433 | int driver_id_number; | ||
| 422 | struct usb_raw_init arg; | 434 | struct usb_raw_init arg; |
| 423 | char *udc_driver_name; | 435 | char *udc_driver_name; |
| 424 | char *udc_device_name; | 436 | char *udc_device_name; |
| 437 | char *driver_driver_name; | ||
| 425 | unsigned long flags; | 438 | unsigned long flags; |
| 426 | 439 | ||
| 427 | if (copy_from_user(&arg, (void __user *)value, sizeof(arg))) | 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 | return -EINVAL; | 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 | udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); | 468 | udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); |
| 444 | if (!udc_driver_name) | 469 | if (!udc_driver_name) { |
| 445 | return -ENOMEM; | 470 | ret = -ENOMEM; |
| 471 | goto out_free_driver_driver_name; | ||
| 472 | } | ||
| 446 | ret = strscpy(udc_driver_name, &arg.driver_name[0], | 473 | ret = strscpy(udc_driver_name, &arg.driver_name[0], |
| 447 | UDC_NAME_LENGTH_MAX); | 474 | UDC_NAME_LENGTH_MAX); |
| 448 | if (ret < 0) { | 475 | if (ret < 0) |
| 449 | kfree(udc_driver_name); | 476 | goto out_free_udc_driver_name; |
| 450 | return ret; | ||
| 451 | } | ||
| 452 | ret = 0; | 477 | ret = 0; |
| 453 | 478 | ||
| 454 | udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); | 479 | udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); |
| 455 | if (!udc_device_name) { | 480 | if (!udc_device_name) { |
| 456 | kfree(udc_driver_name); | 481 | ret = -ENOMEM; |
| 457 | return -ENOMEM; | 482 | goto out_free_udc_driver_name; |
| 458 | } | 483 | } |
| 459 | ret = strscpy(udc_device_name, &arg.device_name[0], | 484 | ret = strscpy(udc_device_name, &arg.device_name[0], |
| 460 | UDC_NAME_LENGTH_MAX); | 485 | UDC_NAME_LENGTH_MAX); |
| 461 | if (ret < 0) { | 486 | if (ret < 0) |
| 462 | kfree(udc_driver_name); | 487 | goto out_free_udc_device_name; |
| 463 | kfree(udc_device_name); | ||
| 464 | return ret; | ||
| 465 | } | ||
| 466 | ret = 0; | 488 | ret = 0; |
| 467 | 489 | ||
| 468 | spin_lock_irqsave(&dev->lock, flags); | 490 | spin_lock_irqsave(&dev->lock, flags); |
| 469 | if (dev->state != STATE_DEV_OPENED) { | 491 | if (dev->state != STATE_DEV_OPENED) { |
| 470 | dev_dbg(dev->dev, "fail, device is not opened\n"); | 492 | dev_dbg(dev->dev, "fail, device is not opened\n"); |
| 471 | kfree(udc_driver_name); | ||
| 472 | kfree(udc_device_name); | ||
| 473 | ret = -EINVAL; | 493 | ret = -EINVAL; |
| 474 | goto out_unlock; | 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 | dev->driver.suspend = gadget_suspend; | 504 | dev->driver.suspend = gadget_suspend; |
| 485 | dev->driver.resume = gadget_resume; | 505 | dev->driver.resume = gadget_resume; |
| 486 | dev->driver.reset = gadget_reset; | 506 | dev->driver.reset = gadget_reset; |
| 487 | dev->driver.driver.name = DRIVER_NAME; | 507 | dev->driver.driver.name = driver_driver_name; |
| 488 | dev->driver.udc_name = udc_device_name; | 508 | dev->driver.udc_name = udc_device_name; |
| 489 | dev->driver.match_existing_only = 1; | 509 | dev->driver.match_existing_only = 1; |
| 510 | dev->driver_id_number = driver_id_number; | ||
| 490 | 511 | ||
| 491 | dev->state = STATE_DEV_INITIALIZED; | 512 | dev->state = STATE_DEV_INITIALIZED; |
| 513 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 514 | return ret; | ||
| 492 | 515 | ||
| 493 | out_unlock: | 516 | out_unlock: |
| 494 | spin_unlock_irqrestore(&dev->lock, flags); | 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 | return ret; | 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 | udc->isp1301_i2c_client = isp1301_get_client(isp1301_node); | 3018 | udc->isp1301_i2c_client = isp1301_get_client(isp1301_node); |
| 3019 | of_node_put(isp1301_node); | ||
| 3019 | if (!udc->isp1301_i2c_client) { | 3020 | if (!udc->isp1301_i2c_client) { |
| 3020 | return -EPROBE_DEFER; | 3021 | return -EPROBE_DEFER; |
| 3021 | } | 3022 | } |
| @@ -652,7 +652,7 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd) · 651 unmodified lines | |||
| 652 | * It will release and re-aquire the lock while calling ACPI | 652 | * It will release and re-aquire the lock while calling ACPI |
| 653 | * method. | 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 | u16 index, bool on, unsigned long *flags) | 656 | u16 index, bool on, unsigned long *flags) |
| 657 | __must_hold(&xhci->lock) | 657 | __must_hold(&xhci->lock) |
| 658 | { | 658 | { |
| @@ -61,6 +61,8 @@ · 60 unmodified lines | |||
| 61 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e | 61 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e |
| 62 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI 0x464e | 62 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI 0x464e |
| 63 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed | 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 | #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 | 67 | #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 |
| 66 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 | 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 | pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || | 271 | pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || |
| 270 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI || | 272 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI || |
| 271 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI || | 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 | xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; | 277 | xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; |
| 274 | 278 | ||
| 275 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 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 | static int xhci_run_finished(struct xhci_hcd *xhci) | 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 | if (xhci_start(xhci)) { | 632 | if (xhci_start(xhci)) { |
| 615 | xhci_halt(xhci); | 633 | xhci_halt(xhci); |
| 634 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 616 | return -ENODEV; | 635 | return -ENODEV; |
| 617 | } | 636 | } |
| 637 | |||
| 618 | xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; | 638 | xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; |
| 619 | 639 | ||
| 620 | if (xhci->quirks & XHCI_NEC_HOST) | 640 | if (xhci->quirks & XHCI_NEC_HOST) |
| 621 | xhci_ring_cmd_db(xhci); | 641 | xhci_ring_cmd_db(xhci); |
| 622 | 642 | ||
| 643 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 644 | |||
| 623 | return 0; | 645 | return 0; |
| 624 | } | 646 | } |
| 625 | 647 | ||
| @@ -668,19 +690,6 @@ int xhci_run(struct usb_hcd *hcd) · 42 unmodified lines | |||
| 668 | temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK; | 690 | temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK; |
| 669 | writel(temp, &xhci->ir_set->irq_control); | 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 | if (xhci->quirks & XHCI_NEC_HOST) { | 693 | if (xhci->quirks & XHCI_NEC_HOST) { |
| 685 | struct xhci_command *command; | 694 | struct xhci_command *command; |
| 686 | 695 | ||
| @@ -782,6 +791,8 @@ static void xhci_stop(struct usb_hcd *hcd) · 95 unmodified lines | |||
| 782 | void xhci_shutdown(struct usb_hcd *hcd) | 791 | void xhci_shutdown(struct usb_hcd *hcd) |
| 783 | { | 792 | { |
| 784 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 793 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 794 | unsigned long flags; | ||
| 795 | int i; | ||
| 785 | 796 | ||
| 786 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) | 797 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) |
| 787 | usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); | 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 | del_timer_sync(&xhci->shared_hcd->rh_timer); | 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 | xhci_halt(xhci); | 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 | /* Workaround for spurious wakeups at shutdown with HSW */ | 822 | /* Workaround for spurious wakeups at shutdown with HSW */ |
| 803 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | 823 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) |
| 804 | xhci_reset(xhci, XHCI_RESET_SHORT_USEC); | 824 | xhci_reset(xhci, XHCI_RESET_SHORT_USEC); |
| 805 | spin_unlock_irq(&xhci->lock); | 825 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 806 | 826 | ||
| 807 | xhci_cleanup_msix(xhci); | 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 | u32 command, temp = 0; | 1128 | u32 command, temp = 0; |
| 1109 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 1129 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
| 1110 | struct usb_hcd *secondary_hcd; | ||
| 1111 | int retval = 0; | 1130 | int retval = 0; |
| 1112 | bool comp_timer_running = false; | 1131 | bool comp_timer_running = false; |
| 1113 | bool pending_portevent = false; | 1132 | bool pending_portevent = false; |
| @@ -1214,23 +1233,19 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) · 100 unmodified lines | |||
| 1214 | * first with the primary HCD, and then with the secondary HCD. | 1233 | * first with the primary HCD, and then with the secondary HCD. |
| 1215 | * If we don't do the same, the host will never be started. | 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 | xhci_dbg(xhci, "Initialize the xhci_hcd\n"); | 1236 | xhci_dbg(xhci, "Initialize the xhci_hcd\n"); |
| 1223 | retval = xhci_init(hcd->primary_hcd); | 1237 | retval = xhci_init(hcd); |
| 1224 | if (retval) | 1238 | if (retval) |
| 1225 | return retval; | 1239 | return retval; |
| 1226 | comp_timer_running = true; | 1240 | comp_timer_running = true; |
| 1227 | 1241 | ||
| 1228 | xhci_dbg(xhci, "Start the primary HCD\n"); | 1242 | xhci_dbg(xhci, "Start the primary HCD\n"); |
| 1229 | retval = xhci_run(hcd->primary_hcd); | 1243 | retval = xhci_run(hcd); |
| 1230 | if (!retval && secondary_hcd) { | 1244 | if (!retval && xhci->shared_hcd) { |
| 1231 | xhci_dbg(xhci, "Start the secondary HCD\n"); | 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 | hcd->state = HC_STATE_SUSPENDED; | 1249 | hcd->state = HC_STATE_SUSPENDED; |
| 1235 | if (xhci->shared_hcd) | 1250 | if (xhci->shared_hcd) |
| 1236 | xhci->shared_hcd->state = HC_STATE_SUSPENDED; | 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 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); | 2196 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); |
| 2197 | int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); | 2197 | int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); |
| 2198 | struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); | 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 | void xhci_hc_died(struct xhci_hcd *xhci); | 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 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, | 166 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, |
| 167 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, | 167 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, |
| 168 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, | 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 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, | 205 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, |
| 205 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, | 206 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, |
| 206 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, | 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 | // Definitions for other product IDs | 213 | // Definitions for other product IDs |
| 214 | #define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device | 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 | #define GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId) \ | 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 | #define QUECTEL_PRODUCT_EG95 0x0195 | 252 | #define QUECTEL_PRODUCT_EG95 0x0195 |
| 253 | #define QUECTEL_PRODUCT_BG96 0x0296 | 253 | #define QUECTEL_PRODUCT_BG96 0x0296 |
| 254 | #define QUECTEL_PRODUCT_EP06 0x0306 | 254 | #define QUECTEL_PRODUCT_EP06 0x0306 |
| 255 | #define QUECTEL_PRODUCT_EM05G 0x030a | ||
| 255 | #define QUECTEL_PRODUCT_EM12 0x0512 | 256 | #define QUECTEL_PRODUCT_EM12 0x0512 |
| 256 | #define QUECTEL_PRODUCT_RM500Q 0x0800 | 257 | #define QUECTEL_PRODUCT_RM500Q 0x0800 |
| 257 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 | 258 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 |
| 258 | #define QUECTEL_PRODUCT_EC200T 0x6026 | 259 | #define QUECTEL_PRODUCT_EC200T 0x6026 |
| 260 | #define QUECTEL_PRODUCT_RM500K 0x7001 | ||
| 259 | 261 | ||
| 260 | #define CMOTECH_VENDOR_ID 0x16d8 | 262 | #define CMOTECH_VENDOR_ID 0x16d8 |
| 261 | #define CMOTECH_PRODUCT_6001 0x6001 | 263 | #define CMOTECH_PRODUCT_6001 0x6001 |
| @@ -432,6 +434,8 @@ static void option_instat_callback(struct urb *urb); · 170 unmodified lines | |||
| 432 | #define CINTERION_PRODUCT_CLS8 0x00b0 | 434 | #define CINTERION_PRODUCT_CLS8 0x00b0 |
| 433 | #define CINTERION_PRODUCT_MV31_MBIM 0x00b3 | 435 | #define CINTERION_PRODUCT_MV31_MBIM 0x00b3 |
| 434 | #define CINTERION_PRODUCT_MV31_RMNET 0x00b7 | 436 | #define CINTERION_PRODUCT_MV31_RMNET 0x00b7 |
| 437 | #define CINTERION_PRODUCT_MV31_2_MBIM 0x00b8 | ||
| 438 | #define CINTERION_PRODUCT_MV31_2_RMNET 0x00b9 | ||
| 435 | #define CINTERION_PRODUCT_MV32_WA 0x00f1 | 439 | #define CINTERION_PRODUCT_MV32_WA 0x00f1 |
| 436 | #define CINTERION_PRODUCT_MV32_WB 0x00f2 | 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 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), | 1136 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), |
| 1133 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, | 1137 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1134 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, | 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 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), | 1141 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1136 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, | 1142 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1137 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, | 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 | .driver_info = ZLP }, | 1151 | .driver_info = ZLP }, |
| 1146 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, | 1152 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, |
| 1147 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, | 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 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, | 1156 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
| 1150 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, | 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 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | 1284 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1278 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */ | 1285 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */ |
| 1279 | .driver_info = NCTRL(2) | RSVD(3) }, | 1286 | .driver_info = NCTRL(2) | RSVD(3) }, |
| 1287 | { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) }, /* Telit LE910Cx (rmnet) */ | ||
| 1280 | { USB_DEVICE(TELIT_VENDOR_ID, 0x1260), | 1288 | { USB_DEVICE(TELIT_VENDOR_ID, 0x1260), |
| 1281 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | 1289 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1282 | { USB_DEVICE(TELIT_VENDOR_ID, 0x1261), | 1290 | { USB_DEVICE(TELIT_VENDOR_ID, 0x1261), |
| @@ -1979,6 +1987,10 @@ static const struct usb_device_id option_ids[] = { · 696 unmodified lines | |||
| 1979 | .driver_info = RSVD(3)}, | 1987 | .driver_info = RSVD(3)}, |
| 1980 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), | 1988 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), |
| 1981 | .driver_info = RSVD(0)}, | 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 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), | 1994 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), |
| 1983 | .driver_info = RSVD(3)}, | 1995 | .driver_info = RSVD(3)}, |
| 1984 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), | 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 | break; | 436 | break; |
| 437 | case 0x200: | 437 | case 0x200: |
| 438 | switch (bcdDevice) { | 438 | switch (bcdDevice) { |
| 439 | case 0x100: | 439 | case 0x100: /* GC */ |
| 440 | case 0x105: | 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 | case 0x305: | 446 | case 0x305: |
| 447 | case 0x400: /* GL */ | ||
| 442 | case 0x405: | 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 | case 0x605: | 456 | case 0x605: |
| 444 | /* | 457 | case 0x700: /* GR */ |
| 445 | * Assume it's an HXN-type if the device doesn't | 458 | case 0x705: |
| 446 | * support the old read request value. | 459 | return TYPE_HXN; |
| 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; | ||
| 455 | } | 460 | } |
| 456 | break; | 461 | break; |
| 457 | } | 462 | } |
| @@ -56,7 +56,6 @@ config TYPEC_WCOVE · 55 unmodified lines | |||
| 56 | tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver" | 56 | tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver" |
| 57 | depends on ACPI | 57 | depends on ACPI |
| 58 | depends on MFD_INTEL_PMC_BXT | 58 | depends on MFD_INTEL_PMC_BXT |
| 59 | depends on INTEL_SOC_PMIC | ||
| 60 | depends on BXT_WC_PMIC_OPREGION | 59 | depends on BXT_WC_PMIC_OPREGION |
| 61 | help | 60 | help |
| 62 | This driver adds support for USB Type-C on Intel Broxton platforms | 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 | return ret; | 1148 | return ret; |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | #if defined(CONFIG_FB_STI) | ||
| 1151 | /* check if given fb_info is the primary device */ | 1152 | /* check if given fb_info is the primary device */ |
| 1152 | int fb_is_primary_device(struct fb_info *info) | 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 | return (sti->info == info); | 1164 | return (sti->info == info); |
| 1164 | } | 1165 | } |
| 1165 | EXPORT_SYMBOL(fb_is_primary_device); | 1166 | EXPORT_SYMBOL(fb_is_primary_device); |
| 1167 | #endif | ||
| 1166 | 1168 | ||
| 1167 | MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); | 1169 | MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); |
| 1168 | MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); | 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 | /* Blank the LCD */ | 560 | /* Blank the LCD */ |
| 561 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); | 561 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); |
| 562 | 562 | ||
| 563 | if (fbdev->lcdclk) | 563 | clk_disable(fbdev->lcdclk); |
| 564 | clk_disable(fbdev->lcdclk); | ||
| 565 | 564 | ||
| 566 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); | 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 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); | 577 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); |
| 579 | 578 | ||
| 580 | if (fbdev->lcdclk) | 579 | clk_enable(fbdev->lcdclk); |
| 581 | clk_enable(fbdev->lcdclk); | ||
| 582 | 580 | ||
| 583 | /* Unblank the LCD */ | 581 | /* Unblank the LCD */ |
| 584 | au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); | 582 | au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); |
| @@ -2184,12 +2184,6 @@ static struct pci_driver cirrusfb_pci_driver = { · 2183 unmodified lines | |||
| 2184 | .id_table = cirrusfb_pci_table, | 2184 | .id_table = cirrusfb_pci_table, |
| 2185 | .probe = cirrusfb_pci_register, | 2185 | .probe = cirrusfb_pci_register, |
| 2186 | .remove = cirrusfb_pci_unregister, | 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 | #endif /* CONFIG_PCI */ | 2188 | #endif /* CONFIG_PCI */ |
| 2195 | 2189 | ||
| @@ -472,7 +472,7 @@ static int intelfb_pci_register(struct pci_dev *pdev, · 471 unmodified lines | |||
| 472 | struct fb_info *info; | 472 | struct fb_info *info; |
| 473 | struct intelfb_info *dinfo; | 473 | struct intelfb_info *dinfo; |
| 474 | int i, err, dvo; | 474 | int i, err, dvo; |
| 475 | int aperture_size, stolen_size; | 475 | int aperture_size, stolen_size = 0; |
| 476 | struct agp_kern_info gtt_info; | 476 | struct agp_kern_info gtt_info; |
| 477 | int agp_memtype; | 477 | int agp_memtype; |
| 478 | const char *s; | 478 | const char *s; |
| @@ -571,7 +571,7 @@ static int intelfb_pci_register(struct pci_dev *pdev, · 92 unmodified lines | |||
| 571 | return -ENODEV; | 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 | cleanup(dinfo); | 575 | cleanup(dinfo); |
| 576 | return -ENODEV; | 576 | return -ENODEV; |
| 577 | } | 577 | } |
| @@ -201,13 +201,11 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, · 200 unmodified lines | |||
| 201 | case PCI_DEVICE_ID_INTEL_945GME: | 201 | case PCI_DEVICE_ID_INTEL_945GME: |
| 202 | case PCI_DEVICE_ID_INTEL_965G: | 202 | case PCI_DEVICE_ID_INTEL_965G: |
| 203 | case PCI_DEVICE_ID_INTEL_965GM: | 203 | case PCI_DEVICE_ID_INTEL_965GM: |
| 204 | /* 915, 945 and 965 chipsets support a 256MB aperture. | 204 | /* |
| 205 | Aperture size is determined by inspected the | 205 | * 915, 945 and 965 chipsets support 64MB, 128MB or 256MB |
| 206 | base address of the aperture. */ | 206 | * aperture. Determine size from PCI resource length. |
| 207 | if (pci_resource_start(pdev, 2) & 0x08000000) | 207 | */ |
| 208 | *aperture_size = MB(128); | 208 | *aperture_size = pci_resource_len(pdev, 2); |
| 209 | else | ||
| 210 | *aperture_size = MB(256); | ||
| 211 | break; | 209 | break; |
| 212 | default: | 210 | default: |
| 213 | if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) | 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 | int bus_pick_count, bus_pick_width; | 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 | * with remapping/reordering disabled it will be calculated by HW | 363 | * with remapping/reordering disabled it will be calculated by HW |
| 364 | * as (32 / bus_pick_width). | 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 | * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the | 144 | * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the |
| 145 | * HDMI_PHYPWRCMD_LDOON command. | 145 | * HDMI_PHYPWRCMD_LDOON command. |
| 146 | */ | 146 | */ |
| 147 | if (phy_feat->bist_ctrl) | 147 | if (phy_feat->bist_ctrl) |
| 148 | REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); | 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 | struct pxa3xx_gcu_batch *buffer; | 381 | struct pxa3xx_gcu_batch *buffer; |
| 382 | struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file); | 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 | /* Does not need to be atomic. There's a lock in user space, | 386 | /* Does not need to be atomic. There's a lock in user space, |
| 387 | * but anyhow, this is just for statistics. */ | 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 | if (IS_ERR(clock)) { | 237 | if (IS_ERR(clock)) { |
| 238 | if (PTR_ERR(clock) == -EPROBE_DEFER) { | 238 | if (PTR_ERR(clock) == -EPROBE_DEFER) { |
| 239 | while (--i >= 0) { | 239 | while (--i >= 0) { |
| 240 | if (par->clks[i]) | 240 | clk_put(par->clks[i]); |
| 241 | clk_put(par->clks[i]); | ||
| 242 | } | 241 | } |
| 243 | kfree(par->clks); | 242 | kfree(par->clks); |
| 244 | return -EPROBE_DEFER; | 243 | return -EPROBE_DEFER; |
| @@ -96,7 +96,7 @@ static const struct fb_fix_screeninfo xxxfb_fix = { · 95 unmodified lines | |||
| 96 | 96 | ||
| 97 | /* | 97 | /* |
| 98 | * Modern graphical hardware not only supports pipelines but some | 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 | * its own unique data. In this case each display could be | 100 | * its own unique data. In this case each display could be |
| 101 | * represented by a separate framebuffer device thus a separate | 101 | * represented by a separate framebuffer device thus a separate |
| 102 | * struct fb_info. Now the struct xxx_par represents the graphics | 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 | * See Documentation/driver-api/pm/devices.rst for more information | 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 | struct xxxfb_par *par = info->par; | 844 | struct xxxfb_par *par = info->par; |
| 845 | 845 | ||
| 846 | /* suspend here */ | 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 | * See Documentation/driver-api/pm/devices.rst for more information | 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 | struct xxxfb_par *par = info->par; | 859 | struct xxxfb_par *par = info->par; |
| 860 | 860 | ||
| 861 | /* resume here */ | 861 | /* resume here */ |
| @@ -873,14 +873,15 @@ static const struct pci_device_id xxxfb_id_table[] = { · 11 unmodified lines | |||
| 873 | { 0, } | 873 | { 0, } |
| 874 | }; | 874 | }; |
| 875 | 875 | ||
| 876 | static SIMPLE_DEV_PM_OPS(xxxfb_pm_ops, xxxfb_suspend, xxxfb_resume); | ||
| 877 | |||
| 876 | /* For PCI drivers */ | 878 | /* For PCI drivers */ |
| 877 | static struct pci_driver xxxfb_driver = { | 879 | static struct pci_driver xxxfb_driver = { |
| 878 | .name = "xxxfb", | 880 | .name = "xxxfb", |
| 879 | .id_table = xxxfb_id_table, | 881 | .id_table = xxxfb_id_table, |
| 880 | .probe = xxxfb_probe, | 882 | .probe = xxxfb_probe, |
| 881 | .remove = xxxfb_remove, | 883 | .remove = xxxfb_remove, |
| 882 | .suspend = xxxfb_suspend, /* optional but recommended */ | 884 | .driver.pm = xxxfb_pm_ops, /* optional but recommended */ |
| 883 | .resume = xxxfb_resume, /* optional but recommended */ | ||
| 884 | }; | 885 | }; |
| 885 | 886 | ||
| 886 | MODULE_DEVICE_TABLE(pci, xxxfb_id_table); | 887 | MODULE_DEVICE_TABLE(pci, xxxfb_id_table); |
| @@ -172,3 +172,4 @@ module_platform_driver(gxp_wdt_driver); · 171 unmodified lines | |||
| 172 | MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>"); | 172 | MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>"); |
| 173 | MODULE_AUTHOR("Jean-Marie Verdun <verdun@hpe.com>"); | 173 | MODULE_AUTHOR("Jean-Marie Verdun <verdun@hpe.com>"); |
| 174 | MODULE_DESCRIPTION("Driver for GXP watchdog timer"); | 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 | if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) | 42 | if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) |
| 43 | break; | 43 | break; |
| 44 | for (j = 0; j < 32; j++) | 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 | if (xen_pv_domain()) { | 48 | if (xen_pv_domain()) { |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <linux/mmu_notifier.h> | 16 | #include <linux/mmu_notifier.h> |
| 17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 18 | #include <xen/interface/event_channel.h> | 18 | #include <xen/interface/event_channel.h> |
| 19 | #include <xen/grant_table.h> | ||
| 19 | 20 | ||
| 20 | struct gntdev_dmabuf_priv; | 21 | struct gntdev_dmabuf_priv; |
| 21 | 22 | ||
| @@ -56,6 +57,7 @@ struct gntdev_grant_map { · 34 unmodified lines | |||
| 56 | struct gnttab_unmap_grant_ref *unmap_ops; | 57 | struct gnttab_unmap_grant_ref *unmap_ops; |
| 57 | struct gnttab_map_grant_ref *kmap_ops; | 58 | struct gnttab_map_grant_ref *kmap_ops; |
| 58 | struct gnttab_unmap_grant_ref *kunmap_ops; | 59 | struct gnttab_unmap_grant_ref *kunmap_ops; |
| 60 | bool *being_removed; | ||
| 59 | struct page **pages; | 61 | struct page **pages; |
| 60 | unsigned long pages_vm_start; | 62 | unsigned long pages_vm_start; |
| 61 | 63 | ||
| @@ -73,6 +75,11 @@ struct gntdev_grant_map { · 11 unmodified lines | |||
| 73 | /* Needed to avoid allocation in gnttab_dma_free_pages(). */ | 75 | /* Needed to avoid allocation in gnttab_dma_free_pages(). */ |
| 74 | xen_pfn_t *frames; | 76 | xen_pfn_t *frames; |
| 75 | #endif | 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 | struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, | 85 | struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/highmem.h> | 36 | #include <linux/highmem.h> |
| 37 | #include <linux/refcount.h> | 37 | #include <linux/refcount.h> |
| 38 | #include <linux/workqueue.h> | ||
| 38 | 39 | ||
| 39 | #include <xen/xen.h> | 40 | #include <xen/xen.h> |
| 40 | #include <xen/grant_table.h> | 41 | #include <xen/grant_table.h> |
| @@ -60,10 +61,11 @@ module_param(limit, uint, 0644); · 19 unmodified lines | |||
| 60 | MODULE_PARM_DESC(limit, | 61 | MODULE_PARM_DESC(limit, |
| 61 | "Maximum number of grants that may be mapped by one mapping request"); | 62 | "Maximum number of grants that may be mapped by one mapping request"); |
| 62 | 63 | ||
| 64 | /* True in PV mode, false otherwise */ | ||
| 63 | static int use_ptemod; | 65 | static int use_ptemod; |
| 64 | 66 | ||
| 65 | static int unmap_grant_pages(struct gntdev_grant_map *map, | 67 | static void unmap_grant_pages(struct gntdev_grant_map *map, |
| 66 | int offset, int pages); | 68 | int offset, int pages); |
| 67 | 69 | ||
| 68 | static struct miscdevice gntdev_miscdev; | 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 | kvfree(map->unmap_ops); | 122 | kvfree(map->unmap_ops); |
| 121 | kvfree(map->kmap_ops); | 123 | kvfree(map->kmap_ops); |
| 122 | kvfree(map->kunmap_ops); | 124 | kvfree(map->kunmap_ops); |
| 125 | kvfree(map->being_removed); | ||
| 123 | kfree(map); | 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 | add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]), | 143 | add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]), |
| 141 | GFP_KERNEL); | 144 | GFP_KERNEL); |
| 142 | add->pages = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); | 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 | if (NULL == add->grants || | 148 | if (NULL == add->grants || |
| 144 | NULL == add->map_ops || | 149 | NULL == add->map_ops || |
| 145 | NULL == add->unmap_ops || | 150 | NULL == add->unmap_ops || |
| 146 | NULL == add->pages) | 151 | NULL == add->pages || |
| 152 | NULL == add->being_removed) | ||
| 147 | goto err; | 153 | goto err; |
| 148 | if (use_ptemod) { | 154 | if (use_ptemod) { |
| 149 | add->kmap_ops = kvmalloc_array(count, sizeof(add->kmap_ops[0]), | 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 | if (!refcount_dec_and_test(&map->users)) | 256 | if (!refcount_dec_and_test(&map->users)) |
| 251 | return; | 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 | unmap_grant_pages(map, 0, map->count); | 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 | if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { | 289 | if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { |
| 257 | notify_remote_via_evtchn(map->notify.event); | 290 | notify_remote_via_evtchn(map->notify.event); |
| 258 | evtchn_put(map->notify.event); | 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 | int gntdev_map_grant_pages(struct gntdev_grant_map *map) | 317 | int gntdev_map_grant_pages(struct gntdev_grant_map *map) |
| 285 | { | 318 | { |
| 319 | size_t alloced = 0; | ||
| 286 | int i, err = 0; | 320 | int i, err = 0; |
| 287 | 321 | ||
| 288 | if (!use_ptemod) { | 322 | if (!use_ptemod) { |
| @@ -331,97 +365,116 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) · 42 unmodified lines | |||
| 331 | map->count); | 365 | map->count); |
| 332 | 366 | ||
| 333 | for (i = 0; i < map->count; i++) { | 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 | map->unmap_ops[i].handle = map->map_ops[i].handle; | 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 | err = -EINVAL; | 373 | err = -EINVAL; |
| 338 | 374 | ||
| 339 | if (map->flags & GNTMAP_device_map) | 375 | if (map->flags & GNTMAP_device_map) |
| 340 | map->unmap_ops[i].dev_bus_addr = map->map_ops[i].dev_bus_addr; | 376 | map->unmap_ops[i].dev_bus_addr = map->map_ops[i].dev_bus_addr; |
| 341 | 377 | ||
| 342 | if (use_ptemod) { | 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 | map->kunmap_ops[i].handle = map->kmap_ops[i].handle; | 382 | map->kunmap_ops[i].handle = map->kmap_ops[i].handle; |
| 345 | else if (!err) | 383 | } else if (!err) |
| 346 | err = -EINVAL; | 384 | err = -EINVAL; |
| 347 | } | 385 | } |
| 348 | } | 386 | } |
| 387 | atomic_add(alloced, &map->live_grants); | ||
| 349 | return err; | 388 | return err; |
| 350 | } | 389 | } |
| 351 | 390 | ||
| 352 | static int __unmap_grant_pages(struct gntdev_grant_map *map, int offset, | 391 | static void __unmap_grant_pages_done(int result, |
| 353 | int pages) | 392 | struct gntab_unmap_queue_data *data) |
| 354 | { | 393 | { |
| 355 | int i, err = 0; | 394 | unsigned int i; |
| 356 | struct gntab_unmap_queue_data unmap_data; | 395 | struct gntdev_grant_map *map = data->data; |
| 357 | 396 | unsigned int offset = data->unmap_ops - map->unmap_ops; | |
| 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; | ||
| 376 | 397 | ||
| 377 | for (i = 0; i < pages; i++) { | 398 | for (i = 0; i < data->count; i++) { |
| 378 | if (map->unmap_ops[offset+i].status) | 399 | WARN_ON(map->unmap_ops[offset+i].status); |
| 379 | err = -EINVAL; | ||
| 380 | pr_debug("unmap handle=%d st=%d\n", | 400 | pr_debug("unmap handle=%d st=%d\n", |
| 381 | map->unmap_ops[offset+i].handle, | 401 | map->unmap_ops[offset+i].handle, |
| 382 | map->unmap_ops[offset+i].status); | 402 | map->unmap_ops[offset+i].status); |
| 383 | map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; | 403 | map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; |
| 384 | if (use_ptemod) { | 404 | if (use_ptemod) { |
| 385 | if (map->kunmap_ops[offset+i].status) | 405 | WARN_ON(map->kunmap_ops[offset+i].status); |
| 386 | err = -EINVAL; | ||
| 387 | pr_debug("kunmap handle=%u st=%d\n", | 406 | pr_debug("kunmap handle=%u st=%d\n", |
| 388 | map->kunmap_ops[offset+i].handle, | 407 | map->kunmap_ops[offset+i].handle, |
| 389 | map->kunmap_ops[offset+i].status); | 408 | map->kunmap_ops[offset+i].status); |
| 390 | map->kunmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; | 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, | 448 | static void unmap_grant_pages(struct gntdev_grant_map *map, int offset, |
| 397 | int pages) | 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 | pr_debug("unmap %d+%d [%d+%d]\n", map->index, map->count, offset, pages); | 456 | pr_debug("unmap %d+%d [%d+%d]\n", map->index, map->count, offset, pages); |
| 402 | 457 | ||
| 403 | /* It is possible the requested range will have a "hole" where we | 458 | /* It is possible the requested range will have a "hole" where we |
| 404 | * already unmapped some of the grants. Only unmap valid ranges. | 459 | * already unmapped some of the grants. Only unmap valid ranges. |
| 405 | */ | 460 | */ |
| 406 | while (pages && !err) { | 461 | while (pages) { |
| 407 | while (pages && | 462 | while (pages && map->being_removed[offset]) { |
| 408 | map->unmap_ops[offset].handle == INVALID_GRANT_HANDLE) { | ||
| 409 | offset++; | 463 | offset++; |
| 410 | pages--; | 464 | pages--; |
| 411 | } | 465 | } |
| 412 | range = 0; | 466 | range = 0; |
| 413 | while (range < pages) { | 467 | while (range < pages) { |
| 414 | if (map->unmap_ops[offset + range].handle == | 468 | if (map->being_removed[offset + range]) |
| 415 | INVALID_GRANT_HANDLE) | ||
| 416 | break; | 469 | break; |
| 470 | map->being_removed[offset + range] = true; | ||
| 417 | range++; | 471 | range++; |
| 418 | } | 472 | } |
| 419 | err = __unmap_grant_pages(map, offset, range); | 473 | if (range) |
| 474 | __unmap_grant_pages(map, offset, range); | ||
| 420 | offset += range; | 475 | offset += range; |
| 421 | pages -= range; | 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 | struct gntdev_grant_map *map = | 526 | struct gntdev_grant_map *map = |
| 474 | container_of(mn, struct gntdev_grant_map, notifier); | 527 | container_of(mn, struct gntdev_grant_map, notifier); |
| 475 | unsigned long mstart, mend; | 528 | unsigned long mstart, mend; |
| 476 | int err; | ||
| 477 | 529 | ||
| 478 | if (!mmu_notifier_range_blockable(range)) | 530 | if (!mmu_notifier_range_blockable(range)) |
| 479 | return false; | 531 | return false; |
| @@ -494,10 +546,9 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn, · 14 unmodified lines | |||
| 494 | map->index, map->count, | 546 | map->index, map->count, |
| 495 | map->vma->vm_start, map->vma->vm_end, | 547 | map->vma->vm_start, map->vma->vm_end, |
| 496 | range->start, range->end, mstart, mend); | 548 | range->start, range->end, mstart, mend); |
| 497 | err = unmap_grant_pages(map, | 549 | unmap_grant_pages(map, |
| 498 | (mstart - map->vma->vm_start) >> PAGE_SHIFT, | 550 | (mstart - map->vma->vm_start) >> PAGE_SHIFT, |
| 499 | (mend - mstart) >> PAGE_SHIFT); | 551 | (mend - mstart) >> PAGE_SHIFT); |
| 500 | WARN_ON(err); | ||
| 501 | 552 | ||
| 502 | return true; | 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 | goto unlock_out; | 1036 | goto unlock_out; |
| 986 | if (use_ptemod && map->vma) | 1037 | if (use_ptemod && map->vma) |
| 987 | goto unlock_out; | 1038 | goto unlock_out; |
| 1039 | if (atomic_read(&map->live_grants)) { | ||
| 1040 | err = -EAGAIN; | ||
| 1041 | goto unlock_out; | ||
| 1042 | } | ||
| 988 | refcount_inc(&map->users); | 1043 | refcount_inc(&map->users); |
| 989 | 1044 | ||
| 990 | vma->vm_ops = &gntdev_vmops; | 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 | const unsigned char **wnames, *uname; | 152 | const unsigned char **wnames, *uname; |
| 153 | int i, n, l, clone, access; | 153 | int i, n, l, clone, access; |
| 154 | struct v9fs_session_info *v9ses; | 154 | struct v9fs_session_info *v9ses; |
| 155 | struct p9_fid *fid, *old_fid = NULL; | 155 | struct p9_fid *fid, *old_fid; |
| 156 | 156 | ||
| 157 | v9ses = v9fs_dentry2v9ses(dentry); | 157 | v9ses = v9fs_dentry2v9ses(dentry); |
| 158 | access = v9ses->flags & V9FS_ACCESS_MASK; | 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 | if (IS_ERR(fid)) | 194 | if (IS_ERR(fid)) |
| 195 | return fid; | 195 | return fid; |
| 196 | 196 | ||
| 197 | refcount_inc(&fid->count); | ||
| 197 | v9fs_fid_add(dentry->d_sb->s_root, fid); | 198 | v9fs_fid_add(dentry->d_sb->s_root, fid); |
| 198 | } | 199 | } |
| 199 | /* If we are root ourself just return that */ | 200 | /* If we are root ourself just return that */ |
| 200 | if (dentry->d_sb->s_root == dentry) { | 201 | if (dentry->d_sb->s_root == dentry) |
| 201 | refcount_inc(&fid->count); | ||
| 202 | return fid; | 202 | return fid; |
| 203 | } | ||
| 204 | /* | 203 | /* |
| 205 | * Do a multipath walk with attached root. | 204 | * Do a multipath walk with attached root. |
| 206 | * When walking parent we need to make sure we | 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 | fid = ERR_PTR(n); | 211 | fid = ERR_PTR(n); |
| 213 | goto err_out; | 212 | goto err_out; |
| 214 | } | 213 | } |
| 214 | old_fid = fid; | ||
| 215 | clone = 1; | 215 | clone = 1; |
| 216 | i = 0; | 216 | i = 0; |
| 217 | while (i < n) { | 217 | while (i < n) { |
| @@ -221,19 +221,15 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, · 3 unmodified lines | |||
| 221 | * walk to ensure none of the patch component change | 221 | * walk to ensure none of the patch component change |
| 222 | */ | 222 | */ |
| 223 | fid = p9_client_walk(fid, l, &wnames[i], clone); | 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 | if (IS_ERR(fid)) { | 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 | kfree(wnames); | 230 | kfree(wnames); |
| 234 | goto err_out; | 231 | goto err_out; |
| 235 | } | 232 | } |
| 236 | old_fid = fid; | ||
| 237 | i += l; | 233 | i += l; |
| 238 | clone = 0; | 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 | static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) | 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 | struct p9_fid *fid = file->private_data; | 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 | refcount_inc(&fid->count); | 76 | refcount_inc(&fid->count); |
| 64 | rreq->netfs_priv = fid; | 77 | rreq->netfs_priv = fid; |
| 65 | return 0; | 78 | return 0; |
| @@ -1251,15 +1251,15 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry, · 1250 unmodified lines | |||
| 1251 | return ERR_PTR(-ECHILD); | 1251 | return ERR_PTR(-ECHILD); |
| 1252 | 1252 | ||
| 1253 | v9ses = v9fs_dentry2v9ses(dentry); | 1253 | v9ses = v9fs_dentry2v9ses(dentry); |
| 1254 | fid = v9fs_fid_lookup(dentry); | 1254 | if (!v9fs_proto_dotu(v9ses)) |
| 1255 | return ERR_PTR(-EBADF); | ||
| 1256 | |||
| 1255 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); | 1257 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
| 1258 | fid = v9fs_fid_lookup(dentry); | ||
| 1256 | 1259 | ||
| 1257 | if (IS_ERR(fid)) | 1260 | if (IS_ERR(fid)) |
| 1258 | return ERR_CAST(fid); | 1261 | return ERR_CAST(fid); |
| 1259 | 1262 | ||
| 1260 | if (!v9fs_proto_dotu(v9ses)) | ||
| 1261 | return ERR_PTR(-EBADF); | ||
| 1262 | |||
| 1263 | st = p9_client_stat(fid); | 1263 | st = p9_client_stat(fid); |
| 1264 | p9_client_clunk(fid); | 1264 | p9_client_clunk(fid); |
| 1265 | if (IS_ERR(st)) | 1265 | if (IS_ERR(st)) |
| @@ -274,6 +274,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, · 273 unmodified lines | |||
| 274 | if (IS_ERR(ofid)) { | 274 | if (IS_ERR(ofid)) { |
| 275 | err = PTR_ERR(ofid); | 275 | err = PTR_ERR(ofid); |
| 276 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | 276 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); |
| 277 | p9_client_clunk(dfid); | ||
| 277 | goto out; | 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 | if (err) { | 286 | if (err) { |
| 286 | p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n", | 287 | p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n", |
| 287 | err); | 288 | err); |
| 289 | p9_client_clunk(dfid); | ||
| 288 | goto error; | 290 | goto error; |
| 289 | } | 291 | } |
| 290 | err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), | 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 | if (err < 0) { | 294 | if (err < 0) { |
| 293 | p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n", | 295 | p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n", |
| 294 | err); | 296 | err); |
| 297 | p9_client_clunk(dfid); | ||
| 295 | goto error; | 298 | goto error; |
| 296 | } | 299 | } |
| 297 | v9fs_invalidate_inode_attr(dir); | 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 | _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation); | 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 | !test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { | 750 | !test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { |
| 750 | key = afs_request_key(vnode->volume->cell); | 751 | key = afs_request_key(vnode->volume->cell); |
| 751 | if (IS_ERR(key)) | 752 | if (IS_ERR(key)) |
| @@ -61,9 +61,15 @@ static bool chgrp_ok(struct user_namespace *mnt_userns, · 60 unmodified lines | |||
| 61 | const struct inode *inode, kgid_t gid) | 61 | const struct inode *inode, kgid_t gid) |
| 62 | { | 62 | { |
| 63 | kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); | 63 | kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); |
| 64 | if (uid_eq(current_fsuid(), i_uid_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))) | 65 | kgid_t mapped_gid; |
| 66 | return true; | 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 | if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) | 73 | if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) |
| 68 | return true; | 74 | return true; |
| 69 | if (gid_eq(kgid, INVALID_GID) && | 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 | /* Make sure a caller can chmod. */ | 130 | /* Make sure a caller can chmod. */ |
| 125 | if (ia_valid & ATTR_MODE) { | 131 | if (ia_valid & ATTR_MODE) { |
| 132 | kgid_t mapped_gid; | ||
| 133 | |||
| 126 | if (!inode_owner_or_capable(mnt_userns, inode)) | 134 | if (!inode_owner_or_capable(mnt_userns, inode)) |
| 127 | return -EPERM; | 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 | /* Also check the setgid bit! */ | 143 | /* Also check the setgid bit! */ |
| 129 | if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : | 144 | if (!in_group_p(mapped_gid) && |
| 130 | i_gid_into_mnt(mnt_userns, inode)) && | 145 | !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) |
| 131 | !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) | ||
| 132 | attr->ia_mode &= ~S_ISGID; | 146 | attr->ia_mode &= ~S_ISGID; |
| 133 | } | 147 | } |
| 134 | 148 | ||
| @@ -104,6 +104,7 @@ struct btrfs_block_group { · 103 unmodified lines | |||
| 104 | unsigned int relocating_repair:1; | 104 | unsigned int relocating_repair:1; |
| 105 | unsigned int chunk_item_inserted:1; | 105 | unsigned int chunk_item_inserted:1; |
| 106 | unsigned int zone_is_active:1; | 106 | unsigned int zone_is_active:1; |
| 107 | unsigned int zoned_data_reloc_ongoing:1; | ||
| 107 | 108 | ||
| 108 | int disk_cache_state; | 109 | int disk_cache_state; |
| 109 | 110 | ||
| @@ -1330,6 +1330,8 @@ struct btrfs_replace_extent_info { · 1329 unmodified lines | |||
| 1330 | * existing extent into a file range. | 1330 | * existing extent into a file range. |
| 1331 | */ | 1331 | */ |
| 1332 | bool is_new_extent; | 1332 | bool is_new_extent; |
| 1333 | /* Indicate if we should update the inode's mtime and ctime. */ | ||
| 1334 | bool update_times; | ||
| 1333 | /* Meaningful only if is_new_extent is true. */ | 1335 | /* Meaningful only if is_new_extent is true. */ |
| 1334 | int qgroup_reserved; | 1336 | int qgroup_reserved; |
| 1335 | /* | 1337 | /* |
| @@ -4632,6 +4632,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) · 4631 unmodified lines | |||
| 4632 | int ret; | 4632 | int ret; |
| 4633 | 4633 | ||
| 4634 | set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags); | 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 | * We don't want the cleaner to start new transactions, add more delayed | 4647 | * We don't want the cleaner to start new transactions, add more delayed |
| 4637 | * iputs, etc. while we're closing. We can't use kthread_stop() yet | 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 | cancel_work_sync(&fs_info->async_data_reclaim_work); | 4683 | cancel_work_sync(&fs_info->async_data_reclaim_work); |
| 4673 | cancel_work_sync(&fs_info->preempt_reclaim_work); | 4684 | cancel_work_sync(&fs_info->preempt_reclaim_work); |
| 4674 | 4685 | ||
| 4675 | cancel_work_sync(&fs_info->reclaim_bgs_work); | ||
| 4676 | |||
| 4677 | /* Cancel or finish ongoing discard work */ | 4686 | /* Cancel or finish ongoing discard work */ |
| 4678 | btrfs_discard_cleanup(fs_info); | 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 | block_group->start == fs_info->data_reloc_bg || | 3832 | block_group->start == fs_info->data_reloc_bg || |
| 3833 | fs_info->data_reloc_bg == 0); | 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 | ret = 1; | 3836 | ret = 1; |
| 3837 | goto out; | 3837 | goto out; |
| 3838 | } | 3838 | } |
| @@ -3894,8 +3894,24 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, · 55 unmodified lines | |||
| 3894 | out: | 3894 | out: |
| 3895 | if (ret && ffe_ctl->for_treelog) | 3895 | if (ret && ffe_ctl->for_treelog) |
| 3896 | fs_info->treelog_bg = 0; | 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 | fs_info->data_reloc_bg = 0; | 3913 | fs_info->data_reloc_bg = 0; |
| 3914 | } | ||
| 3899 | spin_unlock(&fs_info->relocation_bg_lock); | 3915 | spin_unlock(&fs_info->relocation_bg_lock); |
| 3900 | spin_unlock(&fs_info->treelog_bg_lock); | 3916 | spin_unlock(&fs_info->treelog_bg_lock); |
| 3901 | spin_unlock(&block_group->lock); | 3917 | spin_unlock(&block_group->lock); |
| @@ -5241,13 +5241,14 @@ int extent_writepages(struct address_space *mapping, · 5240 unmodified lines | |||
| 5241 | */ | 5241 | */ |
| 5242 | btrfs_zoned_data_reloc_lock(BTRFS_I(inode)); | 5242 | btrfs_zoned_data_reloc_lock(BTRFS_I(inode)); |
| 5243 | ret = extent_write_cache_pages(mapping, wbc, &epd); | 5243 | ret = extent_write_cache_pages(mapping, wbc, &epd); |
| 5244 | btrfs_zoned_data_reloc_unlock(BTRFS_I(inode)); | ||
| 5245 | ASSERT(ret <= 0); | 5244 | ASSERT(ret <= 0); |
| 5246 | if (ret < 0) { | 5245 | if (ret < 0) { |
| 5246 | btrfs_zoned_data_reloc_unlock(BTRFS_I(inode)); | ||
| 5247 | end_write_bio(&epd, ret); | 5247 | end_write_bio(&epd, ret); |
| 5248 | return ret; | 5248 | return ret; |
| 5249 | } | 5249 | } |
| 5250 | flush_write_bio(&epd); | 5250 | flush_write_bio(&epd); |
| 5251 | btrfs_zoned_data_reloc_unlock(BTRFS_I(inode)); | ||
| 5251 | return ret; | 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 | btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP); | 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 | if (!ret) { | 2334 | if (!ret) { |
| 2328 | ret = btrfs_sync_log(trans, root, &ctx); | 2335 | ret = btrfs_end_transaction(trans); |
| 2329 | if (!ret) { | 2336 | goto out; |
| 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 | } | ||
| 2340 | } | 2337 | } |
| 2341 | ret = btrfs_commit_transaction(trans); | 2338 | } |
| 2342 | } else { | 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 | ret = btrfs_end_transaction(trans); | 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 | out: | 2382 | out: |
| 2346 | ASSERT(list_empty(&ctx.list)); | 2383 | ASSERT(list_empty(&ctx.list)); |
| 2347 | err = file_check_and_advance_wb_err(file); | 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 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv, | 2757 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv, |
| 2721 | min_size, false); | 2758 | min_size, false); |
| 2722 | BUG_ON(ret); | 2759 | if (WARN_ON(ret)) |
| 2760 | goto out_trans; | ||
| 2723 | trans->block_rsv = rsv; | 2761 | trans->block_rsv = rsv; |
| 2724 | 2762 | ||
| 2725 | cur_offset = start; | 2763 | cur_offset = start; |
| @@ -2803,6 +2841,25 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, · 77 unmodified lines | |||
| 2803 | extent_info->file_offset += replace_len; | 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 | ret = btrfs_update_inode(trans, root, inode); | 2863 | ret = btrfs_update_inode(trans, root, inode); |
| 2807 | if (ret) | 2864 | if (ret) |
| 2808 | break; | 2865 | break; |
| @@ -2819,7 +2876,8 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, · 10 unmodified lines | |||
| 2819 | 2876 | ||
| 2820 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, | 2877 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, |
| 2821 | rsv, min_size, false); | 2878 | rsv, min_size, false); |
| 2822 | BUG_ON(ret); /* shouldn't happen */ | 2879 | if (WARN_ON(ret)) |
| 2880 | break; | ||
| 2823 | trans->block_rsv = rsv; | 2881 | trans->block_rsv = rsv; |
| 2824 | 2882 | ||
| 2825 | cur_offset = drop_args.drop_end; | 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 | ordered_extent->file_offset, | 3195 | ordered_extent->file_offset, |
| 3196 | ordered_extent->file_offset + | 3196 | ordered_extent->file_offset + |
| 3197 | logical_len); | 3197 | logical_len); |
| 3198 | btrfs_zoned_release_data_reloc_bg(fs_info, ordered_extent->disk_bytenr, | ||
| 3199 | ordered_extent->disk_num_bytes); | ||
| 3198 | } else { | 3200 | } else { |
| 3199 | BUG_ON(root == fs_info->tree_root); | 3201 | BUG_ON(root == fs_info->tree_root); |
| 3200 | ret = insert_ordered_extent_file_extent(trans, ordered_extent); | 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 | extent_info.file_offset = file_offset; | 9899 | extent_info.file_offset = file_offset; |
| 9898 | extent_info.extent_buf = (char *)&stack_fi; | 9900 | extent_info.extent_buf = (char *)&stack_fi; |
| 9899 | extent_info.is_new_extent = true; | 9901 | extent_info.is_new_extent = true; |
| 9902 | extent_info.update_times = true; | ||
| 9900 | extent_info.qgroup_reserved = qgroup_released; | 9903 | extent_info.qgroup_reserved = qgroup_released; |
| 9901 | extent_info.insertions = 0; | 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 | start_ns = ktime_get_ns(); | 45 | start_ns = ktime_get_ns(); |
| 46 | 46 | ||
| 47 | down_read_nested(&eb->lock, nest); | 47 | down_read_nested(&eb->lock, nest); |
| 48 | eb->lock_owner = current->pid; | ||
| 49 | trace_btrfs_tree_read_lock(eb, start_ns); | 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 | int btrfs_try_tree_read_lock(struct extent_buffer *eb) | 61 | int btrfs_try_tree_read_lock(struct extent_buffer *eb) |
| 63 | { | 62 | { |
| 64 | if (down_read_trylock(&eb->lock)) { | 63 | if (down_read_trylock(&eb->lock)) { |
| 65 | eb->lock_owner = current->pid; | ||
| 66 | trace_btrfs_try_tree_read_lock(eb); | 64 | trace_btrfs_try_tree_read_lock(eb); |
| 67 | return 1; | 65 | return 1; |
| 68 | } | 66 | } |
| @@ -90,7 +88,6 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) · 21 unmodified lines | |||
| 90 | void btrfs_tree_read_unlock(struct extent_buffer *eb) | 88 | void btrfs_tree_read_unlock(struct extent_buffer *eb) |
| 91 | { | 89 | { |
| 92 | trace_btrfs_tree_read_unlock(eb); | 90 | trace_btrfs_tree_read_unlock(eb); |
| 93 | eb->lock_owner = 0; | ||
| 94 | up_read(&eb->lock); | 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 | int ret; | 344 | int ret; |
| 345 | const u64 len = olen_aligned; | 345 | const u64 len = olen_aligned; |
| 346 | u64 last_dest_end = destoff; | 346 | u64 last_dest_end = destoff; |
| 347 | u64 prev_extent_end = off; | ||
| 347 | 348 | ||
| 348 | ret = -ENOMEM; | 349 | ret = -ENOMEM; |
| 349 | buf = kvmalloc(fs_info->nodesize, GFP_KERNEL); | 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 | key.offset = off; | 364 | key.offset = off; |
| 364 | 365 | ||
| 365 | while (1) { | 366 | while (1) { |
| 366 | u64 next_key_min_offset = key.offset + 1; | ||
| 367 | struct btrfs_file_extent_item *extent; | 367 | struct btrfs_file_extent_item *extent; |
| 368 | u64 extent_gen; | 368 | u64 extent_gen; |
| 369 | int type; | 369 | int type; |
| @@ -431,14 +431,21 @@ process_slot: · 61 unmodified lines | |||
| 431 | * The first search might have left us at an extent item that | 431 | * The first search might have left us at an extent item that |
| 432 | * ends before our target range's start, can happen if we have | 432 | * ends before our target range's start, can happen if we have |
| 433 | * holes and NO_HOLES feature enabled. | 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 | path->slots[0]++; | 442 | path->slots[0]++; |
| 437 | goto process_slot; | 443 | goto process_slot; |
| 438 | } else if (key.offset >= off + len) { | 444 | } else if (key.offset >= off + len) { |
| 439 | break; | 445 | break; |
| 440 | } | 446 | } |
| 441 | next_key_min_offset = key.offset + datal; | 447 | |
| 448 | prev_extent_end = key.offset + datal; | ||
| 442 | size = btrfs_item_size(leaf, slot); | 449 | size = btrfs_item_size(leaf, slot); |
| 443 | read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, slot), | 450 | read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, slot), |
| 444 | size); | 451 | size); |
| @@ -489,6 +496,7 @@ process_slot: · 44 unmodified lines | |||
| 489 | clone_info.file_offset = new_key.offset; | 496 | clone_info.file_offset = new_key.offset; |
| 490 | clone_info.extent_buf = buf; | 497 | clone_info.extent_buf = buf; |
| 491 | clone_info.is_new_extent = false; | 498 | clone_info.is_new_extent = false; |
| 499 | clone_info.update_times = !no_time_update; | ||
| 492 | ret = btrfs_replace_file_extents(BTRFS_I(inode), path, | 500 | ret = btrfs_replace_file_extents(BTRFS_I(inode), path, |
| 493 | drop_start, new_key.offset + datal - 1, | 501 | drop_start, new_key.offset + datal - 1, |
| 494 | &clone_info, &trans); | 502 | &clone_info, &trans); |
| @@ -550,7 +558,7 @@ process_slot: · 55 unmodified lines | |||
| 550 | break; | 558 | break; |
| 551 | 559 | ||
| 552 | btrfs_release_path(path); | 560 | btrfs_release_path(path); |
| 553 | key.offset = next_key_min_offset; | 561 | key.offset = prev_extent_end; |
| 554 | 562 | ||
| 555 | if (fatal_signal_pending(current)) { | 563 | if (fatal_signal_pending(current)) { |
| 556 | ret = -EINTR; | 564 | ret = -EINTR; |
| @@ -763,6 +763,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 762 unmodified lines | |||
| 763 | compress_force = false; | 763 | compress_force = false; |
| 764 | no_compress++; | 764 | no_compress++; |
| 765 | } else { | 765 | } else { |
| 766 | btrfs_err(info, "unrecognized compression value %s", | ||
| 767 | args[0].from); | ||
| 766 | ret = -EINVAL; | 768 | ret = -EINVAL; |
| 767 | goto out; | 769 | goto out; |
| 768 | } | 770 | } |
| @@ -821,8 +823,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 52 unmodified lines | |||
| 821 | case Opt_thread_pool: | 823 | case Opt_thread_pool: |
| 822 | ret = match_int(&args[0], &intarg); | 824 | ret = match_int(&args[0], &intarg); |
| 823 | if (ret) { | 825 | if (ret) { |
| 826 | btrfs_err(info, "unrecognized thread_pool value %s", | ||
| 827 | args[0].from); | ||
| 824 | goto out; | 828 | goto out; |
| 825 | } else if (intarg == 0) { | 829 | } else if (intarg == 0) { |
| 830 | btrfs_err(info, "invalid value 0 for thread_pool"); | ||
| 826 | ret = -EINVAL; | 831 | ret = -EINVAL; |
| 827 | goto out; | 832 | goto out; |
| 828 | } | 833 | } |
| @@ -883,8 +888,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 54 unmodified lines | |||
| 883 | break; | 888 | break; |
| 884 | case Opt_ratio: | 889 | case Opt_ratio: |
| 885 | ret = match_int(&args[0], &intarg); | 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 | goto out; | 894 | goto out; |
| 895 | } | ||
| 888 | info->metadata_ratio = intarg; | 896 | info->metadata_ratio = intarg; |
| 889 | btrfs_info(info, "metadata ratio %u", | 897 | btrfs_info(info, "metadata ratio %u", |
| 890 | info->metadata_ratio); | 898 | info->metadata_ratio); |
| @@ -901,6 +909,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 10 unmodified lines | |||
| 901 | btrfs_set_and_info(info, DISCARD_ASYNC, | 909 | btrfs_set_and_info(info, DISCARD_ASYNC, |
| 902 | "turning on async discard"); | 910 | "turning on async discard"); |
| 903 | } else { | 911 | } else { |
| 912 | btrfs_err(info, "unrecognized discard mode value %s", | ||
| 913 | args[0].from); | ||
| 904 | ret = -EINVAL; | 914 | ret = -EINVAL; |
| 905 | goto out; | 915 | goto out; |
| 906 | } | 916 | } |
| @@ -933,6 +943,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 26 unmodified lines | |||
| 933 | btrfs_set_and_info(info, FREE_SPACE_TREE, | 943 | btrfs_set_and_info(info, FREE_SPACE_TREE, |
| 934 | "enabling free space tree"); | 944 | "enabling free space tree"); |
| 935 | } else { | 945 | } else { |
| 946 | btrfs_err(info, "unrecognized space_cache value %s", | ||
| 947 | args[0].from); | ||
| 936 | ret = -EINVAL; | 948 | ret = -EINVAL; |
| 937 | goto out; | 949 | goto out; |
| 938 | } | 950 | } |
| @@ -1014,8 +1026,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 75 unmodified lines | |||
| 1014 | break; | 1026 | break; |
| 1015 | case Opt_check_integrity_print_mask: | 1027 | case Opt_check_integrity_print_mask: |
| 1016 | ret = match_int(&args[0], &intarg); | 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 | goto out; | 1033 | goto out; |
| 1034 | } | ||
| 1019 | info->check_integrity_print_mask = intarg; | 1035 | info->check_integrity_print_mask = intarg; |
| 1020 | btrfs_info(info, "check_integrity_print_mask 0x%x", | 1036 | btrfs_info(info, "check_integrity_print_mask 0x%x", |
| 1021 | info->check_integrity_print_mask); | 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 | goto out; | 1046 | goto out; |
| 1031 | #endif | 1047 | #endif |
| 1032 | case Opt_fatal_errors: | 1048 | case Opt_fatal_errors: |
| 1033 | if (strcmp(args[0].from, "panic") == 0) | 1049 | if (strcmp(args[0].from, "panic") == 0) { |
| 1034 | btrfs_set_opt(info->mount_opt, | 1050 | btrfs_set_opt(info->mount_opt, |
| 1035 | PANIC_ON_FATAL_ERROR); | 1051 | PANIC_ON_FATAL_ERROR); |
| 1036 | else if (strcmp(args[0].from, "bug") == 0) | 1052 | } else if (strcmp(args[0].from, "bug") == 0) { |
| 1037 | btrfs_clear_opt(info->mount_opt, | 1053 | btrfs_clear_opt(info->mount_opt, |
| 1038 | PANIC_ON_FATAL_ERROR); | 1054 | PANIC_ON_FATAL_ERROR); |
| 1039 | else { | 1055 | } else { |
| 1056 | btrfs_err(info, "unrecognized fatal_errors value %s", | ||
| 1057 | args[0].from); | ||
| 1040 | ret = -EINVAL; | 1058 | ret = -EINVAL; |
| 1041 | goto out; | 1059 | goto out; |
| 1042 | } | 1060 | } |
| @@ -1044,8 +1062,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, · 1 unmodified line | |||
| 1044 | case Opt_commit_interval: | 1062 | case Opt_commit_interval: |
| 1045 | intarg = 0; | 1063 | intarg = 0; |
| 1046 | ret = match_int(&args[0], &intarg); | 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 | goto out; | 1069 | goto out; |
| 1070 | } | ||
| 1049 | if (intarg == 0) { | 1071 | if (intarg == 0) { |
| 1050 | btrfs_info(info, | 1072 | btrfs_info(info, |
| 1051 | "using default commit interval %us", | 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 | break; | 1081 | break; |
| 1060 | case Opt_rescue: | 1082 | case Opt_rescue: |
| 1061 | ret = parse_rescue_options(info, args[0].from); | 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 | goto out; | 1087 | goto out; |
| 1088 | } | ||
| 1064 | break; | 1089 | break; |
| 1065 | #ifdef CONFIG_BTRFS_DEBUG | 1090 | #ifdef CONFIG_BTRFS_DEBUG |
| 1066 | case Opt_fragment_all: | 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 | if (ret) | 2010 | if (ret) |
| 1986 | goto restore; | 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 | btrfs_remount_begin(fs_info, old_opts, *flags); | 2021 | btrfs_remount_begin(fs_info, old_opts, *flags); |
| 1989 | btrfs_resize_thread_pool(fs_info, | 2022 | btrfs_resize_thread_pool(fs_info, |
| 1990 | fs_info->thread_pool_size, old_thread_pool_size); | 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 | factor = div64_u64(used * 100, total); | 2139 | factor = div64_u64(used * 100, total); |
| 2140 | return factor >= fs_info->bg_reclaim_threshold; | 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 | void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg); | 77 | void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg); |
| 78 | void btrfs_free_zone_cache(struct btrfs_fs_info *fs_info); | 78 | void btrfs_free_zone_cache(struct btrfs_fs_info *fs_info); |
| 79 | bool btrfs_zoned_should_reclaim(struct btrfs_fs_info *fs_info); | 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 | #else /* CONFIG_BLK_DEV_ZONED */ | 82 | #else /* CONFIG_BLK_DEV_ZONED */ |
| 81 | static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, | 83 | static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, |
| 82 | struct blk_zone *zone) | 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 | return false; | 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 | #endif | 251 | #endif |
| 247 | 252 | ||
| 248 | static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos) | 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 | seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr); | 162 | seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr); |
| 163 | else if (iface->sockaddr.ss_family == AF_INET6) | 163 | else if (iface->sockaddr.ss_family == AF_INET6) |
| 164 | seq_printf(m, "\t\tIPv6: %pI6\n", &ipv6->sin6_addr); | 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 | static int cifs_debug_files_proc_show(struct seq_file *m, void *v) | 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 | struct TCP_Server_Info *server; | 223 | struct TCP_Server_Info *server; |
| 222 | struct cifs_ses *ses; | 224 | struct cifs_ses *ses; |
| 223 | struct cifs_tcon *tcon; | 225 | struct cifs_tcon *tcon; |
| 226 | struct cifs_server_iface *iface; | ||
| 224 | int c, i, j; | 227 | int c, i, j; |
| 225 | 228 | ||
| 226 | seq_puts(m, | 229 | seq_puts(m, |
| @@ -456,11 +459,10 @@ skip_rdma: · 229 unmodified lines | |||
| 456 | if (ses->iface_count) | 459 | if (ses->iface_count) |
| 457 | seq_printf(m, "\n\n\tServer interfaces: %zu", | 460 | seq_printf(m, "\n\n\tServer interfaces: %zu", |
| 458 | ses->iface_count); | 461 | ses->iface_count); |
| 459 | for (j = 0; j < ses->iface_count; j++) { | 462 | j = 0; |
| 460 | struct cifs_server_iface *iface; | 463 | list_for_each_entry(iface, &ses->iface_list, |
| 461 | 464 | iface_head) { | |
| 462 | iface = &ses->iface_list[j]; | 465 | seq_printf(m, "\n\t%d)", ++j); |
| 463 | seq_printf(m, "\n\t%d)", j+1); | ||
| 464 | cifs_dump_iface(m, iface); | 466 | cifs_dump_iface(m, iface); |
| 465 | if (is_ses_using_iface(ses, iface)) | 467 | if (is_ses_using_iface(ses, iface)) |
| 466 | seq_puts(m, "\t\t[CONNECTED]\n"); | 468 | seq_puts(m, "\t\t[CONNECTED]\n"); |
| @@ -80,6 +80,9 @@ · 79 unmodified lines | |||
| 80 | #define SMB_DNS_RESOLVE_INTERVAL_MIN 120 | 80 | #define SMB_DNS_RESOLVE_INTERVAL_MIN 120 |
| 81 | #define SMB_DNS_RESOLVE_INTERVAL_DEFAULT 600 | 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 | /* maximum number of PDUs in one compound */ | 86 | /* maximum number of PDUs in one compound */ |
| 84 | #define MAX_COMPOUND 5 | 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 | #endif | 936 | #endif |
| 934 | 937 | ||
| 935 | struct cifs_server_iface { | 938 | struct cifs_server_iface { |
| 939 | struct list_head iface_head; | ||
| 940 | struct kref refcount; | ||
| 936 | size_t speed; | 941 | size_t speed; |
| 937 | unsigned int rdma_capable : 1; | 942 | unsigned int rdma_capable : 1; |
| 938 | unsigned int rss_capable : 1; | 943 | unsigned int rss_capable : 1; |
| 944 | unsigned int is_active : 1; /* unset if non existent */ | ||
| 939 | struct sockaddr_storage sockaddr; | 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 | struct cifs_chan { | 996 | struct cifs_chan { |
| 943 | unsigned int in_reconnect : 1; /* if session setup in progress for this channel */ | 997 | unsigned int in_reconnect : 1; /* if session setup in progress for this channel */ |
| 944 | struct TCP_Server_Info *server; | 998 | struct TCP_Server_Info *server; |
| 999 | struct cifs_server_iface *iface; /* interface in use */ | ||
| 945 | __u8 signkey[SMB3_SIGN_KEY_SIZE]; | 1000 | __u8 signkey[SMB3_SIGN_KEY_SIZE]; |
| 946 | }; | 1001 | }; |
| 947 | 1002 | ||
| @@ -993,7 +1048,7 @@ struct cifs_ses { · 45 unmodified lines | |||
| 993 | */ | 1048 | */ |
| 994 | spinlock_t iface_lock; | 1049 | spinlock_t iface_lock; |
| 995 | /* ========= begin: protected by iface_lock ======== */ | 1050 | /* ========= begin: protected by iface_lock ======== */ |
| 996 | struct cifs_server_iface *iface_list; | 1051 | struct list_head iface_list; |
| 997 | size_t iface_count; | 1052 | size_t iface_count; |
| 998 | unsigned long iface_last_update; /* jiffies */ | 1053 | unsigned long iface_last_update; /* jiffies */ |
| 999 | /* ========= end: protected by iface_lock ======== */ | 1054 | /* ========= end: protected by iface_lock ======== */ |
| @@ -1203,6 +1258,7 @@ struct cifs_tcon { · 203 unmodified lines | |||
| 1203 | #ifdef CONFIG_CIFS_DFS_UPCALL | 1258 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 1204 | struct list_head ulist; /* cache update list */ | 1259 | struct list_head ulist; /* cache update list */ |
| 1205 | #endif | 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 | bool | 636 | bool |
| 637 | cifs_chan_needs_reconnect(struct cifs_ses *ses, | 637 | cifs_chan_needs_reconnect(struct cifs_ses *ses, |
| 638 | struct TCP_Server_Info *server); | 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 | void extract_unc_hostname(const char *unc, const char **h, size_t *len); | 647 | void extract_unc_hostname(const char *unc, const char **h, size_t *len); |
| 641 | int copy_path_name(char *dst, const char *src); | 648 | int copy_path_name(char *dst, const char *src); |
| @@ -145,6 +145,25 @@ requeue_resolve: · 144 unmodified lines | |||
| 145 | return rc; | 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 | static void cifs_resolve_server(struct work_struct *work) | 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 | bool mark_smb_session) | 236 | bool mark_smb_session) |
| 218 | { | 237 | { |
| 219 | struct TCP_Server_Info *pserver; | 238 | struct TCP_Server_Info *pserver; |
| 220 | struct cifs_ses *ses; | 239 | struct cifs_ses *ses, *nses; |
| 221 | struct cifs_tcon *tcon; | 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 | spin_lock(&cifs_tcp_ses_lock); | 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 | spin_lock(&ses->chan_lock); | 267 | spin_lock(&ses->chan_lock); |
| 236 | if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) | 268 | if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) |
| 237 | goto next_session; | 269 | goto next_session; |
| @@ -1894,9 +1926,11 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 1656 unmodified lines | |||
| 1894 | int i; | 1926 | int i; |
| 1895 | 1927 | ||
| 1896 | for (i = 1; i < chan_count; i++) { | 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 | cifs_put_tcp_session(ses->chans[i].server, 0); | 1933 | cifs_put_tcp_session(ses->chans[i].server, 0); |
| 1899 | spin_lock(&ses->chan_lock); | ||
| 1900 | ses->chans[i].server = NULL; | 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 | list_del_init(&tcon->tcon_list); | 2304 | list_del_init(&tcon->tcon_list); |
| 2271 | spin_unlock(&cifs_tcp_ses_lock); | 2305 | spin_unlock(&cifs_tcp_ses_lock); |
| 2272 | 2306 | ||
| 2307 | /* cancel polling of interfaces */ | ||
| 2308 | cancel_delayed_work_sync(&tcon->query_interfaces); | ||
| 2309 | |||
| 2273 | if (tcon->use_witness) { | 2310 | if (tcon->use_witness) { |
| 2274 | int rc; | 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 | tcon->local_lease = ctx->local_lease; | 2544 | tcon->local_lease = ctx->local_lease; |
| 2508 | INIT_LIST_HEAD(&tcon->pending_opens); | 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 | spin_lock(&cifs_tcp_ses_lock); | 2553 | spin_lock(&cifs_tcp_ses_lock); |
| 2511 | list_add(&tcon->tcon_list, &ses->tcon_list); | 2554 | list_add(&tcon->tcon_list, &ses->tcon_list); |
| 2512 | spin_unlock(&cifs_tcp_ses_lock); | 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 | struct nls_table *nls_info) | 4025 | struct nls_table *nls_info) |
| 3983 | { | 4026 | { |
| 3984 | int rc = -ENOSYS; | 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 | bool is_binding = false; | 4030 | bool is_binding = false; |
| 3986 | 4031 | ||
| 3987 | |||
| 3988 | spin_lock(&cifs_tcp_ses_lock); | 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 | if (ses->ses_status != SES_GOOD && | 4038 | if (ses->ses_status != SES_GOOD && |
| 3990 | ses->ses_status != SES_NEW && | 4039 | ses->ses_status != SES_NEW && |
| 3991 | ses->ses_status != SES_NEED_RECON) { | 4040 | ses->ses_status != SES_NEED_RECON) { |
| @@ -75,6 +75,7 @@ sesInfoAlloc(void) · 74 unmodified lines | |||
| 75 | INIT_LIST_HEAD(&ret_buf->tcon_list); | 75 | INIT_LIST_HEAD(&ret_buf->tcon_list); |
| 76 | mutex_init(&ret_buf->session_mutex); | 76 | mutex_init(&ret_buf->session_mutex); |
| 77 | spin_lock_init(&ret_buf->iface_lock); | 77 | spin_lock_init(&ret_buf->iface_lock); |
| 78 | INIT_LIST_HEAD(&ret_buf->iface_list); | ||
| 78 | spin_lock_init(&ret_buf->chan_lock); | 79 | spin_lock_init(&ret_buf->chan_lock); |
| 79 | } | 80 | } |
| 80 | return ret_buf; | 81 | return ret_buf; |
| @@ -83,6 +84,8 @@ sesInfoAlloc(void) · 2 unmodified lines | |||
| 83 | void | 84 | void |
| 84 | sesInfoFree(struct cifs_ses *buf_to_free) | 85 | sesInfoFree(struct cifs_ses *buf_to_free) |
| 85 | { | 86 | { |
| 87 | struct cifs_server_iface *iface = NULL, *niface = NULL; | ||
| 88 | |||
| 86 | if (buf_to_free == NULL) { | 89 | if (buf_to_free == NULL) { |
| 87 | cifs_dbg(FYI, "Null buffer passed to sesInfoFree\n"); | 90 | cifs_dbg(FYI, "Null buffer passed to sesInfoFree\n"); |
| 88 | return; | 91 | return; |
| @@ -96,7 +99,11 @@ sesInfoFree(struct cifs_ses *buf_to_free) · 7 unmodified lines | |||
| 96 | kfree(buf_to_free->user_name); | 99 | kfree(buf_to_free->user_name); |
| 97 | kfree(buf_to_free->domainName); | 100 | kfree(buf_to_free->domainName); |
| 98 | kfree_sensitive(buf_to_free->auth_key.response); | 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 | kfree_sensitive(buf_to_free); | 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 | spin_lock(&ses->chan_lock); | 59 | spin_lock(&ses->chan_lock); |
| 60 | for (i = 0; i < ses->chan_count; i++) { | 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 | spin_unlock(&ses->chan_lock); | 62 | spin_unlock(&ses->chan_lock); |
| 63 | return true; | 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 | /* If we didn't find the channel, it is likely a bug */ | 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 | WARN_ON(1); | 87 | WARN_ON(1); |
| 85 | return 0; | 88 | return 0; |
| 86 | } | 89 | } |
| @@ -143,16 +146,24 @@ cifs_chan_needs_reconnect(struct cifs_ses *ses, · 56 unmodified lines | |||
| 143 | return CIFS_CHAN_NEEDS_RECONNECT(ses, chan_index); | 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 | /* returns number of channels added */ | 159 | /* returns number of channels added */ |
| 147 | int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) | 160 | int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) |
| 148 | { | 161 | { |
| 149 | int old_chan_count, new_chan_count; | 162 | int old_chan_count, new_chan_count; |
| 150 | int left; | 163 | int left; |
| 151 | int i = 0; | ||
| 152 | int rc = 0; | 164 | int rc = 0; |
| 153 | int tries = 0; | 165 | int tries = 0; |
| 154 | struct cifs_server_iface *ifaces = NULL; | 166 | struct cifs_server_iface *iface = NULL, *niface = NULL; |
| 155 | size_t iface_count; | ||
| 156 | 167 | ||
| 157 | spin_lock(&ses->chan_lock); | 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 | spin_unlock(&ses->chan_lock); | 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 | * Keep connecting to same, fastest, iface for all channels as | 196 | * Keep connecting to same, fastest, iface for all channels as |
| 206 | * long as its RSS. Try next fastest one if not RSS or channel | 197 | * long as its RSS. Try next fastest one if not RSS or channel |
| 207 | * creation fails. | 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 | while (left > 0) { | 205 | while (left > 0) { |
| 210 | struct cifs_server_iface *iface; | ||
| 211 | 206 | ||
| 212 | tries++; | 207 | tries++; |
| 213 | if (tries > 3*ses->chan_max) { | 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 | break; | 211 | break; |
| 217 | } | 212 | } |
| 218 | 213 | ||
| 219 | iface = &ifaces[i]; | 214 | spin_lock(&ses->iface_lock); |
| 220 | if (is_ses_using_iface(ses, iface) && !iface->rss_capable) { | 215 | if (!ses->iface_count) { |
| 221 | i = (i+1) % iface_count; | 216 | spin_unlock(&ses->iface_lock); |
| 222 | continue; | 217 | break; |
| 223 | } | 218 | } |
| 224 | 219 | ||
| 225 | rc = cifs_ses_add_channel(cifs_sb, ses, iface); | 220 | list_for_each_entry_safe_from(iface, niface, &ses->iface_list, |
| 226 | if (rc) { | 221 | iface_head) { |
| 227 | cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n", | 222 | /* skip ifaces that are unusable */ |
| 228 | i, rc); | 223 | if (!iface->is_active || |
| 229 | i = (i+1) % iface_count; | 224 | (is_ses_using_iface(ses, iface) && |
| 230 | continue; | 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 | left--; | 250 | left--; |
| 236 | new_chan_count++; | 251 | new_chan_count++; |
| 237 | } | 252 | } |
| 238 | 253 | ||
| 239 | kfree(ifaces); | ||
| 240 | return new_chan_count - old_chan_count; | 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 | * If server is a channel of ses, return the corresponding enclosing | 336 | * If server is a channel of ses, return the corresponding enclosing |
| 245 | * cifs_chan otherwise return NULL. | 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 | spin_unlock(&ses->chan_lock); | 444 | spin_unlock(&ses->chan_lock); |
| 353 | goto out; | 445 | goto out; |
| 354 | } | 446 | } |
| 447 | chan->iface = iface; | ||
| 355 | ses->chan_count++; | 448 | ses->chan_count++; |
| 356 | atomic_set(&ses->chan_seq, 0); | 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 | static int | 512 | static int |
| 513 | parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, | 513 | parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, |
| 514 | size_t buf_len, | 514 | size_t buf_len, |
| 515 | struct cifs_server_iface **iface_list, | 515 | struct cifs_ses *ses) |
| 516 | size_t *iface_count) | ||
| 517 | { | 516 | { |
| 518 | struct network_interface_info_ioctl_rsp *p; | 517 | struct network_interface_info_ioctl_rsp *p; |
| 519 | struct sockaddr_in *addr4; | 518 | struct sockaddr_in *addr4; |
| 520 | struct sockaddr_in6 *addr6; | 519 | struct sockaddr_in6 *addr6; |
| 521 | struct iface_info_ipv4 *p4; | 520 | struct iface_info_ipv4 *p4; |
| 522 | struct iface_info_ipv6 *p6; | 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 | ssize_t bytes_left; | 524 | ssize_t bytes_left; |
| 525 | size_t next = 0; | 525 | size_t next = 0; |
| 526 | int nb_iface = 0; | 526 | int nb_iface = 0; |
| 527 | int rc = 0; | 527 | int rc = 0, ret = 0; |
| 528 | |||
| 529 | *iface_list = NULL; | ||
| 530 | *iface_count = 0; | ||
| 531 | |||
| 532 | /* | ||
| 533 | * Fist pass: count and sanity check | ||
| 534 | */ | ||
| 535 | 528 | ||
| 536 | bytes_left = buf_len; | 529 | bytes_left = buf_len; |
| 537 | p = buf; | 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 | 538 | list_for_each_entry_safe(iface, niface, &ses->iface_list, | |
| 564 | *iface_list = kcalloc(nb_iface, sizeof(**iface_list), GFP_KERNEL); | 539 | iface_head) { |
| 565 | if (!*iface_list) { | 540 | iface->is_active = 0; |
| 566 | rc = -ENOMEM; | 541 | kref_put(&iface->refcount, release_iface); |
| 567 | goto out; | ||
| 568 | } | 542 | } |
| 543 | spin_unlock(&ses->iface_lock); | ||
| 569 | 544 | ||
| 570 | info = *iface_list; | ||
| 571 | bytes_left = buf_len; | ||
| 572 | p = buf; | ||
| 573 | while (bytes_left >= sizeof(*p)) { | 545 | while (bytes_left >= sizeof(*p)) { |
| 574 | info->speed = le64_to_cpu(p->LinkSpeed); | 546 | memset(&tmp_iface, 0, sizeof(tmp_iface)); |
| 575 | info->rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0; | 547 | tmp_iface.speed = le64_to_cpu(p->LinkSpeed); |
| 576 | info->rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0; | 548 | tmp_iface.rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0; |
| 577 | 549 | tmp_iface.rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0; | |
| 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)); | ||
| 582 | 550 | ||
| 583 | switch (p->Family) { | 551 | switch (p->Family) { |
| 584 | /* | 552 | /* |
| @@ -587,7 +555,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, · 2 unmodified lines | |||
| 587 | * conversion explicit in case either one changes. | 555 | * conversion explicit in case either one changes. |
| 588 | */ | 556 | */ |
| 589 | case INTERNETWORK: | 557 | case INTERNETWORK: |
| 590 | addr4 = (struct sockaddr_in *)&info->sockaddr; | 558 | addr4 = (struct sockaddr_in *)&tmp_iface.sockaddr; |
| 591 | p4 = (struct iface_info_ipv4 *)p->Buffer; | 559 | p4 = (struct iface_info_ipv4 *)p->Buffer; |
| 592 | addr4->sin_family = AF_INET; | 560 | addr4->sin_family = AF_INET; |
| 593 | memcpy(&addr4->sin_addr, &p4->IPv4Address, 4); | 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 | &addr4->sin_addr); | 567 | &addr4->sin_addr); |
| 600 | break; | 568 | break; |
| 601 | case INTERNETWORKV6: | 569 | case INTERNETWORKV6: |
| 602 | addr6 = (struct sockaddr_in6 *)&info->sockaddr; | 570 | addr6 = (struct sockaddr_in6 *)&tmp_iface.sockaddr; |
| 603 | p6 = (struct iface_info_ipv6 *)p->Buffer; | 571 | p6 = (struct iface_info_ipv6 *)p->Buffer; |
| 604 | addr6->sin6_family = AF_INET6; | 572 | addr6->sin6_family = AF_INET6; |
| 605 | memcpy(&addr6->sin6_addr, &p6->IPv6Address, 16); | 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 | goto next_iface; | 587 | goto next_iface; |
| 620 | } | 588 | } |
| 621 | 589 | ||
| 622 | (*iface_count)++; | 590 | /* |
| 623 | info++; | 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 | next_iface: | 643 | next_iface: |
| 644 | nb_iface++; | ||
| 625 | next = le32_to_cpu(p->Next); | 645 | next = le32_to_cpu(p->Next); |
| 626 | if (!next) | 646 | if (!next) { |
| 647 | bytes_left -= sizeof(*p); | ||
| 627 | break; | 648 | break; |
| 649 | } | ||
| 628 | p = (struct network_interface_info_ioctl_rsp *)((u8 *)p+next); | 650 | p = (struct network_interface_info_ioctl_rsp *)((u8 *)p+next); |
| 629 | bytes_left -= next; | 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 | rc = -EINVAL; | 656 | rc = -EINVAL; |
| 634 | goto out; | 657 | goto out; |
| 635 | } | 658 | } |
| 636 | 659 | ||
| 637 | out: | 660 | /* Azure rounds the buffer size up 8, to a 16 byte boundary */ |
| 638 | if (rc) { | 661 | if ((bytes_left > 8) || p->Next) |
| 639 | kfree(*iface_list); | 662 | cifs_dbg(VFS, "%s: incomplete interface info\n", __func__); |
| 640 | *iface_count = 0; | ||
| 641 | *iface_list = NULL; | ||
| 642 | } | ||
| 643 | return rc; | ||
| 644 | } | ||
| 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 | SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) | 675 | SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) |
| 656 | { | 676 | { |
| 657 | int rc; | 677 | int rc; |
| 658 | unsigned int ret_data_len = 0; | 678 | unsigned int ret_data_len = 0; |
| 659 | struct network_interface_info_ioctl_rsp *out_buf = NULL; | 679 | struct network_interface_info_ioctl_rsp *out_buf = NULL; |
| 660 | struct cifs_server_iface *iface_list; | ||
| 661 | size_t iface_count; | ||
| 662 | struct cifs_ses *ses = tcon->ses; | 680 | struct cifs_ses *ses = tcon->ses; |
| 663 | 681 | ||
| 664 | rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, | 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 | goto out; | 692 | goto out; |
| 675 | } | 693 | } |
| 676 | 694 | ||
| 677 | rc = parse_server_interfaces(out_buf, ret_data_len, | 695 | rc = parse_server_interfaces(out_buf, ret_data_len, ses); |
| 678 | &iface_list, &iface_count); | ||
| 679 | if (rc) | 696 | if (rc) |
| 680 | goto out; | 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 | out: | 699 | out: |
| 693 | kfree(out_buf); | 700 | kfree(out_buf); |
| 694 | return rc; | 701 | return rc; |
| @@ -543,6 +543,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 542 unmodified lines | |||
| 543 | struct TCP_Server_Info *server, unsigned int *total_len) | 543 | struct TCP_Server_Info *server, unsigned int *total_len) |
| 544 | { | 544 | { |
| 545 | char *pneg_ctxt; | 545 | char *pneg_ctxt; |
| 546 | char *hostname = NULL; | ||
| 546 | unsigned int ctxt_len, neg_context_count; | 547 | unsigned int ctxt_len, neg_context_count; |
| 547 | 548 | ||
| 548 | if (*total_len > 200) { | 549 | if (*total_len > 200) { |
| @@ -570,16 +571,24 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 21 unmodified lines | |||
| 570 | *total_len += ctxt_len; | 571 | *total_len += ctxt_len; |
| 571 | pneg_ctxt += ctxt_len; | 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 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); | 574 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); |
| 579 | *total_len += sizeof(struct smb2_posix_neg_context); | 575 | *total_len += sizeof(struct smb2_posix_neg_context); |
| 580 | pneg_ctxt += sizeof(struct smb2_posix_neg_context); | 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 | if (server->compress_algorithm) { | 593 | if (server->compress_algorithm) { |
| 585 | build_compression_ctxt((struct smb2_compression_capabilities_context *) | 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 | data = &info; | 5163 | data = &info; |
| 5155 | size = sizeof(struct smb2_file_eof_info); | 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 | return send_set_info(xid, tcon, persistent_fid, volatile_fid, | 5168 | return send_set_info(xid, tcon, persistent_fid, volatile_fid, |
| 5158 | pid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE, | 5169 | pid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE, |
| 5159 | 0, 1, &data, &size); | 5170 | 0, 1, &data, &size); |
| @@ -121,6 +121,44 @@ DEFINE_SMB3_RW_DONE_EVENT(query_dir_done); · 120 unmodified lines | |||
| 121 | DEFINE_SMB3_RW_DONE_EVENT(zero_done); | 121 | DEFINE_SMB3_RW_DONE_EVENT(zero_done); |
| 122 | DEFINE_SMB3_RW_DONE_EVENT(falloc_done); | 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 | * For handle based calls other than read and write, and get/set info | 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 | return -ENOENT; | 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 | dentry = ei->entry; | 1204 | dentry = ei->entry; |
| 1203 | 1205 | ||
| 1204 | ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh); | 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 | void *page_addr = NULL; | 672 | void *page_addr = NULL; |
| 673 | struct page *page = NULL; | 673 | struct page *page = NULL; |
| 674 | unsigned long i, npages = dir_pages(inode); | 674 | unsigned long i, npages = dir_pages(inode); |
| 675 | int dir_has_error = 0; | ||
| 676 | 675 | ||
| 677 | for (i = 0; i < npages; i++) { | 676 | for (i = 0; i < npages; i++) { |
| 678 | char *kaddr; | 677 | char *kaddr; |
| 679 | ext2_dirent * de; | 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)) { | 681 | if (IS_ERR(page)) |
| 683 | dir_has_error = 1; | 682 | goto not_empty; |
| 684 | continue; | ||
| 685 | } | ||
| 686 | 683 | ||
| 687 | kaddr = page_addr; | 684 | kaddr = page_addr; |
| 688 | de = (ext2_dirent *)kaddr; | 685 | de = (ext2_dirent *)kaddr; |
| @@ -829,7 +829,7 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, · 828 unmodified lines | |||
| 829 | ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n", | 829 | ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n", |
| 830 | inode->i_ino, create); | 830 | inode->i_ino, create); |
| 831 | return _ext4_get_block(inode, iblock, bh_result, | 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 | /* Maximum number of blocks we map for direct IO at once. */ | 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 | size = size >> bsbits; | 4104 | size = size >> bsbits; |
| 4105 | start = start_off >> bsbits; | 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 | /* don't cover already allocated blocks in selected range */ | 4116 | /* don't cover already allocated blocks in selected range */ |
| 4108 | if (ar->pleft && start <= ar->lleft) { | 4117 | if (ar->pleft && start <= ar->lleft) { |
| 4109 | size -= ar->lleft + 1 - start; | 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 | rcu_read_unlock(); | 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 | start > ac->ac_o_ex.fe_logical) { | 4204 | start > ac->ac_o_ex.fe_logical) { |
| 4181 | ext4_msg(ac->ac_sb, KERN_ERR, | 4205 | ext4_msg(ac->ac_sb, KERN_ERR, |
| 4182 | "start %lu, size %lu, fe_logical %lu", | 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 | * Worst case we can touch the allocation bitmaps and a block | 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 | * credits for modifying the quota inode. | 442 | * credits for modifying the quota inode. |
| 443 | */ | 443 | */ |
| 444 | handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, | 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 | struct dx_hash_info *hinfo) | 1929 | struct dx_hash_info *hinfo) |
| 1930 | { | 1930 | { |
| 1931 | unsigned blocksize = dir->i_sb->s_blocksize; | 1931 | unsigned blocksize = dir->i_sb->s_blocksize; |
| 1932 | unsigned count, continued; | 1932 | unsigned continued; |
| 1933 | int count; | ||
| 1933 | struct buffer_head *bh2; | 1934 | struct buffer_head *bh2; |
| 1934 | ext4_lblk_t newblock; | 1935 | ext4_lblk_t newblock; |
| 1935 | u32 hash2; | 1936 | u32 hash2; |
| @@ -465,7 +465,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, · 464 unmodified lines | |||
| 465 | /* | 465 | /* |
| 466 | * In the first loop we prepare and mark buffers to submit. We have to | 466 | * In the first loop we prepare and mark buffers to submit. We have to |
| 467 | * mark all buffers in the page before submitting so that | 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 | * on the first buffer finishes and we are still working on submitting | 469 | * on the first buffer finishes and we are still working on submitting |
| 470 | * the second buffer. | 470 | * the second buffer. |
| 471 | */ | 471 | */ |
| @@ -53,6 +53,16 @@ int ext4_resize_begin(struct super_block *sb) · 52 unmodified lines | |||
| 53 | if (!capable(CAP_SYS_RESOURCE)) | 53 | if (!capable(CAP_SYS_RESOURCE)) |
| 54 | return -EPERM; | 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 | * If we are not using the primary superblock/GDT copy don't resize, | 67 | * If we are not using the primary superblock/GDT copy don't resize, |
| 58 | * because the user tools have no way of handling this. Probably a | 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 | static int ext4_validate_options(struct fs_context *fc); | 87 | static int ext4_validate_options(struct fs_context *fc); |
| 88 | static int ext4_check_opt_consistency(struct fs_context *fc, | 88 | static int ext4_check_opt_consistency(struct fs_context *fc, |
| 89 | struct super_block *sb); | 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 | static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param); | 91 | static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param); |
| 92 | static int ext4_get_tree(struct fs_context *fc); | 92 | static int ext4_get_tree(struct fs_context *fc); |
| 93 | static int ext4_reconfigure(struct fs_context *fc); | 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 | #endif | 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 | #define EXT4_SPEC_JQUOTA (1 << 0) | 1873 | #define EXT4_SPEC_JQUOTA (1 << 0) |
| 1892 | #define EXT4_SPEC_JQFMT (1 << 1) | 1874 | #define EXT4_SPEC_JQFMT (1 << 1) |
| 1893 | #define EXT4_SPEC_DATAJ (1 << 2) | 1875 | #define EXT4_SPEC_DATAJ (1 << 2) |
| 1894 | #define EXT4_SPEC_SB_BLOCK (1 << 3) | 1876 | #define EXT4_SPEC_SB_BLOCK (1 << 3) |
| 1895 | #define EXT4_SPEC_JOURNAL_DEV (1 << 4) | 1877 | #define EXT4_SPEC_JOURNAL_DEV (1 << 4) |
| 1896 | #define EXT4_SPEC_JOURNAL_IOPRIO (1 << 5) | 1878 | #define EXT4_SPEC_JOURNAL_IOPRIO (1 << 5) |
| 1897 | #define EXT4_SPEC_DUMMY_ENCRYPTION (1 << 6) | ||
| 1898 | #define EXT4_SPEC_s_want_extra_isize (1 << 7) | 1879 | #define EXT4_SPEC_s_want_extra_isize (1 << 7) |
| 1899 | #define EXT4_SPEC_s_max_batch_time (1 << 8) | 1880 | #define EXT4_SPEC_s_max_batch_time (1 << 8) |
| 1900 | #define EXT4_SPEC_s_min_batch_time (1 << 9) | 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 | struct ext4_fs_context { | 1893 | struct ext4_fs_context { |
| 1913 | char *s_qf_names[EXT4_MAXQUOTAS]; | 1894 | char *s_qf_names[EXT4_MAXQUOTAS]; |
| 1914 | char *test_dummy_enc_arg; | 1895 | struct fscrypt_dummy_policy dummy_enc_policy; |
| 1915 | int s_jquota_fmt; /* Format of quota to use */ | 1896 | int s_jquota_fmt; /* Format of quota to use */ |
| 1916 | #ifdef CONFIG_EXT4_DEBUG | 1897 | #ifdef CONFIG_EXT4_DEBUG |
| 1917 | int s_fc_debug_max_replay; | 1898 | int s_fc_debug_max_replay; |
| @@ -1953,7 +1934,7 @@ static void ext4_fc_free(struct fs_context *fc) · 35 unmodified lines | |||
| 1953 | for (i = 0; i < EXT4_MAXQUOTAS; i++) | 1934 | for (i = 0; i < EXT4_MAXQUOTAS; i++) |
| 1954 | kfree(ctx->s_qf_names[i]); | 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 | kfree(ctx); | 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 | #endif | 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 | #define EXT4_SET_CTX(name) \ | 2036 | #define EXT4_SET_CTX(name) \ |
| 2033 | static inline void ctx_set_##name(struct ext4_fs_context *ctx, \ | 2037 | static inline void ctx_set_##name(struct ext4_fs_context *ctx, \ |
| 2034 | unsigned long flag) \ | 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 | ctx->spec |= EXT4_SPEC_JOURNAL_IOPRIO; | 2295 | ctx->spec |= EXT4_SPEC_JOURNAL_IOPRIO; |
| 2292 | return 0; | 2296 | return 0; |
| 2293 | case Opt_test_dummy_encryption: | 2297 | case Opt_test_dummy_encryption: |
| 2294 | #ifdef CONFIG_FS_ENCRYPTION | 2298 | return ext4_parse_test_dummy_encryption(param, ctx); |
| 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 | ||
| 2317 | case Opt_dax: | 2299 | case Opt_dax: |
| 2318 | case Opt_dax_type: | 2300 | case Opt_dax_type: |
| 2319 | #ifdef CONFIG_FS_DAX | 2301 | #ifdef CONFIG_FS_DAX |
| @@ -2504,7 +2486,8 @@ parse_failed: · 184 unmodified lines | |||
| 2504 | if (s_ctx->spec & EXT4_SPEC_JOURNAL_IOPRIO) | 2486 | if (s_ctx->spec & EXT4_SPEC_JOURNAL_IOPRIO) |
| 2505 | m_ctx->journal_ioprio = s_ctx->journal_ioprio; | 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 | out_free: | 2492 | out_free: |
| 2510 | if (fc) { | 2493 | if (fc) { |
| @@ -2673,11 +2656,11 @@ err_jquota_specified: · 162 unmodified lines | |||
| 2673 | static int ext4_check_test_dummy_encryption(const struct fs_context *fc, | 2656 | static int ext4_check_test_dummy_encryption(const struct fs_context *fc, |
| 2674 | struct super_block *sb) | 2657 | struct super_block *sb) |
| 2675 | { | 2658 | { |
| 2676 | #ifdef CONFIG_FS_ENCRYPTION | ||
| 2677 | const struct ext4_fs_context *ctx = fc->fs_private; | 2659 | const struct ext4_fs_context *ctx = fc->fs_private; |
| 2678 | const struct ext4_sb_info *sbi = EXT4_SB(sb); | 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 | return 0; | 2664 | return 0; |
| 2682 | 2665 | ||
| 2683 | if (!ext4_has_feature_encrypt(sb)) { | 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 | * needed to allow it to be set or changed during remount. We do allow | 2674 | * needed to allow it to be set or changed during remount. We do allow |
| 2692 | * it to be specified during remount, but only if there is no change. | 2675 | * it to be specified during remount, but only if there is no change. |
| 2693 | */ | 2676 | */ |
| 2694 | if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE && | 2677 | if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { |
| 2695 | !sbi->s_dummy_enc_policy.policy) { | 2678 | if (fscrypt_dummy_policies_equal(&sbi->s_dummy_enc_policy, |
| 2679 | &ctx->dummy_enc_policy)) | ||
| 2680 | return 0; | ||
| 2696 | ext4_msg(NULL, KERN_WARNING, | 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 | return -EINVAL; | 2683 | return -EINVAL; |
| 2699 | } | 2684 | } |
| 2700 | #endif /* CONFIG_FS_ENCRYPTION */ | 2685 | /* Also make sure s_mount_opts didn't contain a conflicting value. */ |
| 2701 | return 0; | 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 | static int ext4_check_opt_consistency(struct fs_context *fc, | 2719 | static int ext4_check_opt_consistency(struct fs_context *fc, |
| @@ -2785,11 +2800,10 @@ fail_dax_change_remount: · 80 unmodified lines | |||
| 2785 | return ext4_check_quota_consistency(fc, sb); | 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 | struct ext4_fs_context *ctx = fc->fs_private; | 2805 | struct ext4_fs_context *ctx = fc->fs_private; |
| 2791 | struct ext4_sb_info *sbi = fc->s_fs_info; | 2806 | struct ext4_sb_info *sbi = fc->s_fs_info; |
| 2792 | int ret = 0; | ||
| 2793 | 2807 | ||
| 2794 | sbi->s_mount_opt &= ~ctx->mask_s_mount_opt; | 2808 | sbi->s_mount_opt &= ~ctx->mask_s_mount_opt; |
| 2795 | sbi->s_mount_opt |= ctx->vals_s_mount_opt; | 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 | #endif | 2839 | #endif |
| 2826 | 2840 | ||
| 2827 | ext4_apply_quota_options(fc, sb); | 2841 | ext4_apply_quota_options(fc, sb); |
| 2828 | 2842 | ext4_apply_test_dummy_encryption(ctx, sb); | |
| 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; | ||
| 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 | if (err < 0) | 4562 | if (err < 0) |
| 4553 | goto failed_mount; | 4563 | goto failed_mount; |
| 4554 | 4564 | ||
| 4555 | err = ext4_apply_options(fc, sb); | 4565 | ext4_apply_options(fc, sb); |
| 4556 | if (err < 0) | ||
| 4557 | goto failed_mount; | ||
| 4558 | 4566 | ||
| 4559 | #if IS_ENABLED(CONFIG_UNICODE) | 4567 | #if IS_ENABLED(CONFIG_UNICODE) |
| 4560 | if (ext4_has_feature_casefold(sb) && !sb->s_encoding) { | 4568 | if (ext4_has_feature_casefold(sb) && !sb->s_encoding) { |
| @@ -5302,14 +5310,6 @@ no_journal: · 741 unmodified lines | |||
| 5302 | err = percpu_counter_init(&sbi->s_freeinodes_counter, freei, | 5310 | err = percpu_counter_init(&sbi->s_freeinodes_counter, freei, |
| 5303 | GFP_KERNEL); | 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 | if (!err) | 5313 | if (!err) |
| 5314 | err = percpu_counter_init(&sbi->s_dirs_counter, | 5314 | err = percpu_counter_init(&sbi->s_dirs_counter, |
| 5315 | ext4_count_dirs(sb), GFP_KERNEL); | 5315 | ext4_count_dirs(sb), GFP_KERNEL); |
| @@ -5367,6 +5367,14 @@ no_journal: · 51 unmodified lines | |||
| 5367 | EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; | 5367 | EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; |
| 5368 | ext4_orphan_cleanup(sb, es); | 5368 | ext4_orphan_cleanup(sb, es); |
| 5369 | EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; | 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 | if (needs_recovery) { | 5378 | if (needs_recovery) { |
| 5371 | ext4_msg(sb, KERN_INFO, "recovery complete"); | 5379 | ext4_msg(sb, KERN_INFO, "recovery complete"); |
| 5372 | err = ext4_mark_recovery_complete(sb, es); | 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 | static int ext4_commit_super(struct super_block *sb) | 5906 | static int ext4_commit_super(struct super_block *sb) |
| 5899 | { | 5907 | { |
| 5900 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; | 5908 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; |
| 5901 | int error = 0; | ||
| 5902 | 5909 | ||
| 5903 | if (!sbh) | 5910 | if (!sbh) |
| 5904 | return -EINVAL; | 5911 | return -EINVAL; |
| @@ -5907,6 +5914,13 @@ static int ext4_commit_super(struct super_block *sb) · 2 unmodified lines | |||
| 5907 | 5914 | ||
| 5908 | ext4_update_super(sb); | 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 | if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) { | 5924 | if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) { |
| 5911 | /* | 5925 | /* |
| 5912 | * Oh, dear. A previous attempt to write the | 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 | clear_buffer_write_io_error(sbh); | 5935 | clear_buffer_write_io_error(sbh); |
| 5922 | set_buffer_uptodate(sbh); | 5936 | set_buffer_uptodate(sbh); |
| 5923 | } | 5937 | } |
| 5924 | BUFFER_TRACE(sbh, "marking dirty"); | 5938 | get_bh(sbh); |
| 5925 | mark_buffer_dirty(sbh); | 5939 | /* Clear potential dirty bit if it was journalled update */ |
| 5926 | error = __sync_dirty_buffer(sbh, | 5940 | clear_buffer_dirty(sbh); |
| 5927 | REQ_SYNC | (test_opt(sb, BARRIER) ? REQ_FUA : 0)); | 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 | if (buffer_write_io_error(sbh)) { | 5945 | if (buffer_write_io_error(sbh)) { |
| 5929 | ext4_msg(sb, KERN_ERR, "I/O error while writing " | 5946 | ext4_msg(sb, KERN_ERR, "I/O error while writing " |
| 5930 | "superblock"); | 5947 | "superblock"); |
| 5931 | clear_buffer_write_io_error(sbh); | 5948 | clear_buffer_write_io_error(sbh); |
| 5932 | set_buffer_uptodate(sbh); | 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 | unlock_buffer(bs->bh); | 1896 | unlock_buffer(bs->bh); |
| 1897 | ea_bdebug(bs->bh, "cloning"); | 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 | error = -ENOMEM; | 1899 | error = -ENOMEM; |
| 1900 | if (s->base == NULL) | 1900 | if (s->base == NULL) |
| 1901 | goto cleanup; | 1901 | goto cleanup; |
| 1902 | memcpy(s->base, BHDR(bs->bh), bs->bh->b_size); | ||
| 1903 | s->first = ENTRY(header(s->base)+1); | 1902 | s->first = ENTRY(header(s->base)+1); |
| 1904 | header(s->base)->h_refcount = cpu_to_le32(1); | 1903 | header(s->base)->h_refcount = cpu_to_le32(1); |
| 1905 | s->here = ENTRY(s->base + offset); | 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 | unsigned int cnt; | 91 | unsigned int cnt; |
| 92 | struct f2fs_iostat_latency iostat_lat[MAX_IO_TYPE][NR_PAGE_TYPE]; | 92 | struct f2fs_iostat_latency iostat_lat[MAX_IO_TYPE][NR_PAGE_TYPE]; |
| 93 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; | 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 | for (idx = 0; idx < MAX_IO_TYPE; idx++) { | 97 | for (idx = 0; idx < MAX_IO_TYPE; idx++) { |
| 97 | for (io = 0; io < NR_PAGE_TYPE; io++) { | 98 | for (io = 0; io < NR_PAGE_TYPE; io++) { |
| 98 | cnt = io_lat->bio_cnt[idx][io]; | 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 | io_lat->bio_cnt[idx][io] = 0; | 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 | trace_f2fs_iostat_latency(sbi, iostat_lat); | 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 | unsigned long long iostat_diff[NR_IO_TYPE]; | 117 | unsigned long long iostat_diff[NR_IO_TYPE]; |
| 117 | int i; | 118 | int i; |
| 119 | unsigned long flags; | ||
| 118 | 120 | ||
| 119 | if (time_is_after_jiffies(sbi->iostat_next_period)) | 121 | if (time_is_after_jiffies(sbi->iostat_next_period)) |
| 120 | return; | 122 | return; |
| 121 | 123 | ||
| 122 | /* Need double check under the lock */ | 124 | /* Need double check under the lock */ |
| 123 | spin_lock_bh(&sbi->iostat_lock); | 125 | spin_lock_irqsave(&sbi->iostat_lock, flags); |
| 124 | if (time_is_after_jiffies(sbi->iostat_next_period)) { | 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 | return; | 128 | return; |
| 127 | } | 129 | } |
| 128 | sbi->iostat_next_period = jiffies + | 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 | sbi->prev_rw_iostat[i]; | 135 | sbi->prev_rw_iostat[i]; |
| 134 | sbi->prev_rw_iostat[i] = sbi->rw_iostat[i]; | 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 | trace_f2fs_iostat(sbi, iostat_diff); | 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 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; | 147 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; |
| 146 | int i; | 148 | int i; |
| 147 | 149 | ||
| 148 | spin_lock_bh(&sbi->iostat_lock); | 150 | spin_lock_irq(&sbi->iostat_lock); |
| 149 | for (i = 0; i < NR_IO_TYPE; i++) { | 151 | for (i = 0; i < NR_IO_TYPE; i++) { |
| 150 | sbi->rw_iostat[i] = 0; | 152 | sbi->rw_iostat[i] = 0; |
| 151 | sbi->prev_rw_iostat[i] = 0; | 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 | memset(io_lat, 0, sizeof(struct iostat_lat_info)); | 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 | void f2fs_update_iostat(struct f2fs_sb_info *sbi, | 162 | void f2fs_update_iostat(struct f2fs_sb_info *sbi, |
| 161 | enum iostat_type type, unsigned long long io_bytes) | 163 | enum iostat_type type, unsigned long long io_bytes) |
| 162 | { | 164 | { |
| 165 | unsigned long flags; | ||
| 166 | |||
| 163 | if (!sbi->iostat_enable) | 167 | if (!sbi->iostat_enable) |
| 164 | return; | 168 | return; |
| 165 | 169 | ||
| 166 | spin_lock_bh(&sbi->iostat_lock); | 170 | spin_lock_irqsave(&sbi->iostat_lock, flags); |
| 167 | sbi->rw_iostat[type] += io_bytes; | 171 | sbi->rw_iostat[type] += io_bytes; |
| 168 | 172 | ||
| 169 | if (type == APP_BUFFERED_IO || type == APP_DIRECT_IO) | 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 | if (type == APP_BUFFERED_READ_IO || type == APP_DIRECT_READ_IO) | 176 | if (type == APP_BUFFERED_READ_IO || type == APP_DIRECT_READ_IO) |
| 173 | sbi->rw_iostat[APP_READ_IO] += io_bytes; | 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 | f2fs_record_iostat(sbi); | 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 | struct f2fs_sb_info *sbi = iostat_ctx->sbi; | 189 | struct f2fs_sb_info *sbi = iostat_ctx->sbi; |
| 186 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; | 190 | struct iostat_lat_info *io_lat = sbi->iostat_io_lat; |
| 187 | int idx; | 191 | int idx; |
| 192 | unsigned long flags; | ||
| 188 | 193 | ||
| 189 | if (!sbi->iostat_enable) | 194 | if (!sbi->iostat_enable) |
| 190 | return; | 195 | return; |
| @@ -202,12 +207,12 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx, · 11 unmodified lines | |||
| 202 | idx = WRITE_ASYNC_IO; | 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 | io_lat->sum_lat[idx][iotype] += ts_diff; | 211 | io_lat->sum_lat[idx][iotype] += ts_diff; |
| 207 | io_lat->bio_cnt[idx][iotype]++; | 212 | io_lat->bio_cnt[idx][iotype]++; |
| 208 | if (ts_diff > io_lat->peak_lat[idx][iotype]) | 213 | if (ts_diff > io_lat->peak_lat[idx][iotype]) |
| 209 | io_lat->peak_lat[idx][iotype] = ts_diff; | 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 | void iostat_update_and_unbind_ctx(struct bio *bio, int rw) | 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 | if (test_opt(sbi, INLINE_XATTR)) | 89 | if (test_opt(sbi, INLINE_XATTR)) |
| 90 | set_inode_flag(inode, FI_INLINE_XATTR); | 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 | if (f2fs_may_inline_dentry(inode)) | 92 | if (f2fs_may_inline_dentry(inode)) |
| 95 | set_inode_flag(inode, FI_INLINE_DENTRY); | 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 | f2fs_init_extent_tree(inode, NULL); | 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 | F2FS_I(inode)->i_flags = | 108 | F2FS_I(inode)->i_flags = |
| 115 | f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED); | 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 | set_compress_context(inode); | 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 | f2fs_set_inode_flags(inode); | 132 | f2fs_set_inode_flags(inode); |
| 131 | 133 | ||
| 132 | trace_f2fs_new_inode(inode, 0); | 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 | if (!is_extension_exist(name, ext[i], false)) | 327 | if (!is_extension_exist(name, ext[i], false)) |
| 326 | continue; | 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 | set_compress_context(inode); | 333 | set_compress_context(inode); |
| 329 | return; | 334 | return; |
| 330 | } | 335 | } |
| @@ -1450,7 +1450,9 @@ page_hit: · 1449 unmodified lines | |||
| 1450 | out_err: | 1450 | out_err: |
| 1451 | ClearPageUptodate(page); | 1451 | ClearPageUptodate(page); |
| 1452 | out_put_err: | 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 | f2fs_put_page(page, 1); | 1456 | f2fs_put_page(page, 1); |
| 1455 | return ERR_PTR(err); | 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 | remove_inode_hugepages(inode, offset, LLONG_MAX); | 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 | static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) | 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 | struct hstate *h = hstate_inode(inode); | 630 | struct hstate *h = hstate_inode(inode); |
| 606 | loff_t hpage_size = huge_page_size(h); | 631 | loff_t hpage_size = huge_page_size(h); |
| 607 | loff_t hole_start, hole_end; | 632 | loff_t hole_start, hole_end; |
| 608 | 633 | ||
| 609 | /* | 634 | /* |
| 610 | * For hole punch round up the beginning offset of the hole and | 635 | * hole_start and hole_end indicate the full pages within the hole. |
| 611 | * round down the end. | ||
| 612 | */ | 636 | */ |
| 613 | hole_start = round_up(offset, hpage_size); | 637 | hole_start = round_up(offset, hpage_size); |
| 614 | hole_end = round_down(offset + len, hpage_size); | 638 | hole_end = round_down(offset + len, hpage_size); |
| 615 | 639 | ||
| 616 | if (hole_end > hole_start) { | 640 | inode_lock(inode); |
| 617 | struct address_space *mapping = inode->i_mapping; | ||
| 618 | struct hugetlbfs_inode_info *info = HUGETLBFS_I(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.