Unified · Split
| @@ -143,6 +143,9 @@ x509.genkey · 142 unmodified lines | ||
| 143 | 143 | /allrandom.config |
| 144 | 144 | /allyes.config |
| 145 | 145 | |
| 146 | +# Kconfig savedefconfig output | |
| 147 | +/defconfig | |
| 148 | + | |
| 146 | 149 | # Kdevelop4 |
| 147 | 150 | *.kdev4 |
| 148 | 151 | |
| @@ -56,11 +56,6 @@ Description: The /dev/kmsg character device node provides userspace access · 55 unmodified lines | ||
| 56 | 56 | seek after the last record available at the time |
| 57 | 57 | the last SYSLOG_ACTION_CLEAR was issued. |
| 58 | 58 | |
| 59 | − Due to the record nature of this interface with a "read all" | |
| 60 | − behavior and the specific positions each seek operation sets, | |
| 61 | − SEEK_CUR is not supported, returning -ESPIPE (invalid seek) to | |
| 62 | − errno whenever requested. | |
| 63 | − | |
| 64 | 59 | The output format consists of a prefix carrying the syslog |
| 65 | 60 | prefix including priority and facility, the 64 bit message |
| 66 | 61 | sequence number and the monotonic timestamp in microseconds, |
| @@ -0,0 +1,27 @@ | ||
| 1 | +What: /sys/bus/nd/devices/nmemX/papr/flags | |
| 2 | +Date: Apr, 2020 | |
| 3 | +KernelVersion: v5.8 | |
| 4 | +Contact: linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, linux-nvdimm@lists.01.org, | |
| 5 | +Description: | |
| 6 | + (RO) Report flags indicating various states of a | |
| 7 | + papr-pmem NVDIMM device. Each flag maps to a one or | |
| 8 | + more bits set in the dimm-health-bitmap retrieved in | |
| 9 | + response to H_SCM_HEALTH hcall. The details of the bit | |
| 10 | + flags returned in response to this hcall is available | |
| 11 | + at 'Documentation/powerpc/papr_hcalls.rst' . Below are | |
| 12 | + the flags reported in this sysfs file: | |
| 13 | + | |
| 14 | + * "not_armed" : Indicates that NVDIMM contents will not | |
| 15 | + survive a power cycle. | |
| 16 | + * "flush_fail" : Indicates that NVDIMM contents | |
| 17 | + couldn't be flushed during last | |
| 18 | + shut-down event. | |
| 19 | + * "restore_fail": Indicates that NVDIMM contents | |
| 20 | + couldn't be restored during NVDIMM | |
| 21 | + initialization. | |
| 22 | + * "encrypted" : NVDIMM contents are encrypted. | |
| 23 | + * "smart_notify": There is health event for the NVDIMM. | |
| 24 | + * "scrubbed" : Indicating that contents of the | |
| 25 | + NVDIMM have been scrubbed. | |
| 26 | + * "locked" : Indicating that NVDIMM contents cant | |
| 27 | + be modified until next power cycle. | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req |
| 2 | 2 | Date: Feb 2014 |
| 3 | −Contact: Li Jun <b47624@freescale.com> | |
| 3 | +Contact: Li Jun <jun.li@nxp.com> | |
| 4 | 4 | Description: |
| 5 | 5 | Can be set and read. |
| 6 | 6 | Set a_bus_req(A-device bus request) input to be 1 if |
| @@ -17,7 +17,7 @@ Description: · 10 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop |
| 19 | 19 | Date: Feb 2014 |
| 20 | −Contact: Li Jun <b47624@freescale.com> | |
| 20 | +Contact: Li Jun <jun.li@nxp.com> | |
| 21 | 21 | Description: |
| 22 | 22 | Can be set and read |
| 23 | 23 | The a_bus_drop(A-device bus drop) input is 1 when the |
| @@ -32,7 +32,7 @@ Description: · 8 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | What: /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req |
| 34 | 34 | Date: Feb 2014 |
| 35 | −Contact: Li Jun <b47624@freescale.com> | |
| 35 | +Contact: Li Jun <jun.li@nxp.com> | |
| 36 | 36 | Description: |
| 37 | 37 | Can be set and read. |
| 38 | 38 | The b_bus_req(B-device bus request) input is 1 during the time |
| @@ -47,7 +47,7 @@ Description: · 8 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_clr_err |
| 49 | 49 | Date: Feb 2014 |
| 50 | −Contact: Li Jun <b47624@freescale.com> | |
| 50 | +Contact: Li Jun <jun.li@nxp.com> | |
| 51 | 51 | Description: |
| 52 | 52 | Only can be set. |
| 53 | 53 | The a_clr_err(A-device Vbus error clear) input is used to clear |
| @@ -1356,8 +1356,8 @@ PAGE_SIZE multiple when read back. · 1355 unmodified lines | ||
| 1356 | 1356 | |
| 1357 | 1357 | thp_fault_alloc |
| 1358 | 1358 | Number of transparent hugepages which were allocated to satisfy |
| 1359 | − a page fault, including COW faults. This counter is not present | |
| 1360 | − when CONFIG_TRANSPARENT_HUGEPAGE is not set. | |
| 1359 | + a page fault. This counter is not present when CONFIG_TRANSPARENT_HUGEPAGE | |
| 1360 | + is not set. | |
| 1361 | 1361 | |
| 1362 | 1362 | thp_collapse_alloc |
| 1363 | 1363 | Number of transparent hugepages which were allocated to allow |
| @@ -11,6 +11,7 @@ Device Mapper · 10 unmodified lines | ||
| 11 | 11 | dm-clone |
| 12 | 12 | dm-crypt |
| 13 | 13 | dm-dust |
| 14 | + dm-ebs | |
| 14 | 15 | dm-flakey |
| 15 | 16 | dm-init |
| 16 | 17 | dm-integrity |
| @@ -305,8 +305,7 @@ monitor how successfully the system is providing huge pages for use. · 304 unmodified lines | ||
| 305 | 305 | |
| 306 | 306 | thp_fault_alloc |
| 307 | 307 | is incremented every time a huge page is successfully |
| 308 | − allocated to handle a page fault. This applies to both the | |
| 309 | − first time a page is faulted and for COW faults. | |
| 308 | + allocated to handle a page fault. | |
| 310 | 309 | |
| 311 | 310 | thp_collapse_alloc |
| 312 | 311 | is incremented by khugepaged when it has found |
| @@ -147,6 +147,14 @@ stable kernels. · 146 unmodified lines | ||
| 147 | 147 | +----------------+-----------------+-----------------+-----------------------------+ |
| 148 | 148 | | Qualcomm Tech. | Falkor v{1,2} | E1041 | QCOM_FALKOR_ERRATUM_1041 | |
| 149 | 149 | +----------------+-----------------+-----------------+-----------------------------+ |
| 150 | +| Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1463225 | | |
| 151 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 152 | +| Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1418040 | | |
| 153 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 154 | +| Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1530923 | | |
| 155 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 156 | +| Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1024718 | | |
| 157 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 150 | 158 | +----------------+-----------------+-----------------+-----------------------------+ |
| 151 | 159 | | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | |
| 152 | 160 | +----------------+-----------------+-----------------+-----------------------------+ |
| @@ -186,7 +186,7 @@ prctl(PR_SVE_SET_VL, unsigned long arg) · 185 unmodified lines | ||
| 186 | 186 | |
| 187 | 187 | flags: |
| 188 | 188 | |
| 189 | − PR_SVE_SET_VL_INHERIT | |
| 189 | + PR_SVE_VL_INHERIT | |
| 190 | 190 | |
| 191 | 191 | Inherit the current vector length across execve(). Otherwise, the |
| 192 | 192 | vector length is reset to the system default at execve(). (See |
| @@ -247,7 +247,7 @@ prctl(PR_SVE_GET_VL) · 54 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | The following flag may be OR-ed into the result: |
| 249 | 249 | |
| 250 | − PR_SVE_SET_VL_INHERIT | |
| 250 | + PR_SVE_VL_INHERIT | |
| 251 | 251 | |
| 252 | 252 | Vector length will be inherited across execve(). |
| 253 | 253 | |
| @@ -393,7 +393,7 @@ The regset data starts with struct user_sve_header, containing: · 139 unmodified lines | ||
| 393 | 393 | * At every execve() call, the new vector length of the new process is set to |
| 394 | 394 | the system default vector length, unless |
| 395 | 395 | |
| 396 | − * PR_SVE_SET_VL_INHERIT (or equivalently SVE_PT_VL_INHERIT) is set for the | |
| 396 | + * PR_SVE_VL_INHERIT (or equivalently SVE_PT_VL_INHERIT) is set for the | |
| 397 | 397 | calling thread, or |
| 398 | 398 | |
| 399 | 399 | * a deferred vector length change is pending, established via the |
| @@ -86,6 +86,20 @@ then the next program in the chain (A) will see those changes, · 85 unmodified lines | ||
| 86 | 86 | *not* the original input ``setsockopt`` arguments. The potentially |
| 87 | 87 | modified values will be then passed down to the kernel. |
| 88 | 88 | |
| 89 | +Large optval | |
| 90 | +============ | |
| 91 | +When the ``optval`` is greater than the ``PAGE_SIZE``, the BPF program | |
| 92 | +can access only the first ``PAGE_SIZE`` of that data. So it has to options: | |
| 93 | + | |
| 94 | +* Set ``optlen`` to zero, which indicates that the kernel should | |
| 95 | + use the original buffer from the userspace. Any modifications | |
| 96 | + done by the BPF program to the ``optval`` are ignored. | |
| 97 | +* Set ``optlen`` to the value less than ``PAGE_SIZE``, which | |
| 98 | + indicates that the kernel should use BPF's trimmed ``optval``. | |
| 99 | + | |
| 100 | +When the BPF program returns with the ``optlen`` greater than | |
| 101 | +``PAGE_SIZE``, the userspace will receive ``EFAULT`` errno. | |
| 102 | + | |
| 89 | 103 | Example |
| 90 | 104 | ======= |
| 91 | 105 | |
| @@ -33,7 +33,7 @@ all combinations of get*(), pin*(), FOLL_LONGTERM, and more. Also, the · 32 unmodified lines | ||
| 33 | 33 | pin_user_pages*() APIs are clearly distinct from the get_user_pages*() APIs, so |
| 34 | 34 | that's a natural dividing line, and a good point to make separate wrapper calls. |
| 35 | 35 | In other words, use pin_user_pages*() for DMA-pinned pages, and |
| 36 | −get_user_pages*() for other cases. There are four cases described later on in | |
| 36 | +get_user_pages*() for other cases. There are five cases described later on in | |
| 37 | 37 | this document, to further clarify that concept. |
| 38 | 38 | |
| 39 | 39 | FOLL_PIN and FOLL_GET are mutually exclusive for a given gup call. However, |
| @@ -114,12 +114,6 @@ the below options are available: · 113 unmodified lines | ||
| 114 | 114 | To dynamically limit for which functions to generate reports, see the |
| 115 | 115 | `DebugFS interface`_ blacklist/whitelist feature. |
| 116 | 116 | |
| 117 | − For ``__always_inline`` functions, replace ``__always_inline`` with | |
| 118 | − ``__no_kcsan_or_inline`` (which implies ``__always_inline``):: | |
| 119 | − | |
| 120 | − static __no_kcsan_or_inline void foo(void) { | |
| 121 | − ... | |
| 122 | − | |
| 123 | 117 | * To disable data race detection for a particular compilation unit, add to the |
| 124 | 118 | ``Makefile``:: |
| 125 | 119 | |
| @@ -61,3 +61,43 @@ test, or an end-to-end test. · 60 unmodified lines | ||
| 61 | 61 | kernel by installing a production configuration of the kernel on production |
| 62 | 62 | hardware with a production userspace and then trying to exercise some behavior |
| 63 | 63 | that depends on interactions between the hardware, the kernel, and userspace. |
| 64 | + | |
| 65 | +KUnit isn't working, what should I do? | |
| 66 | +====================================== | |
| 67 | + | |
| 68 | +Unfortunately, there are a number of things which can break, but here are some | |
| 69 | +things to try. | |
| 70 | + | |
| 71 | +1. Try running ``./tools/testing/kunit/kunit.py run`` with the ``--raw_output`` | |
| 72 | + parameter. This might show details or error messages hidden by the kunit_tool | |
| 73 | + parser. | |
| 74 | +2. Instead of running ``kunit.py run``, try running ``kunit.py config``, | |
| 75 | + ``kunit.py build``, and ``kunit.py exec`` independently. This can help track | |
| 76 | + down where an issue is occurring. (If you think the parser is at fault, you | |
| 77 | + can run it manually against stdin or a file with ``kunit.py parse``.) | |
| 78 | +3. Running the UML kernel directly can often reveal issues or error messages | |
| 79 | + kunit_tool ignores. This should be as simple as running ``./vmlinux`` after | |
| 80 | + building the UML kernel (e.g., by using ``kunit.py build``). Note that UML | |
| 81 | + has some unusual requirements (such as the host having a tmpfs filesystem | |
| 82 | + mounted), and has had issues in the past when built statically and the host | |
| 83 | + has KASLR enabled. (On older host kernels, you may need to run ``setarch | |
| 84 | + `uname -m` -R ./vmlinux`` to disable KASLR.) | |
| 85 | +4. Make sure the kernel .config has ``CONFIG_KUNIT=y`` and at least one test | |
| 86 | + (e.g. ``CONFIG_KUNIT_EXAMPLE_TEST=y``). kunit_tool will keep its .config | |
| 87 | + around, so you can see what config was used after running ``kunit.py run``. | |
| 88 | + It also preserves any config changes you might make, so you can | |
| 89 | + enable/disable things with ``make ARCH=um menuconfig`` or similar, and then | |
| 90 | + re-run kunit_tool. | |
| 91 | +5. Try to run ``make ARCH=um defconfig`` before running ``kunit.py run``. This | |
| 92 | + may help clean up any residual config items which could be causing problems. | |
| 93 | +6. Finally, try running KUnit outside UML. KUnit and KUnit tests can run be | |
| 94 | + built into any kernel, or can be built as a module and loaded at runtime. | |
| 95 | + Doing so should allow you to determine if UML is causing the issue you're | |
| 96 | + seeing. When tests are built-in, they will execute when the kernel boots, and | |
| 97 | + modules will automatically execute associated tests when loaded. Test results | |
| 98 | + can be collected from ``/sys/kernel/debug/kunit/<test suite>/results``, and | |
| 99 | + can be parsed with ``kunit.py parse``. For more details, see "KUnit on | |
| 100 | + non-UML architectures" in :doc:`usage`. | |
| 101 | + | |
| 102 | +If none of the above tricks help, you are always welcome to email any issues to | |
| 103 | +kunit-dev@googlegroups.com. | |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | DT_DOC_CHECKER ?= dt-doc-validate |
| 3 | 3 | DT_EXTRACT_EX ?= dt-extract-example |
| 4 | 4 | DT_MK_SCHEMA ?= dt-mk-schema |
| 5 | −DT_MK_SCHEMA_USERONLY_FLAG := $(if $(DT_SCHEMA_FILES), -u) | |
| 6 | 5 | |
| 7 | 6 | DT_SCHEMA_MIN_VERSION = 2020.5 |
| 8 | 7 | |
| @@ -35,21 +34,40 @@ quiet_cmd_mk_schema = SCHEMA $@ · 26 unmodified lines | ||
| 35 | 34 | |
| 36 | 35 | DT_DOCS = $(shell $(find_cmd) | sed -e 's|^$(srctree)/||') |
| 37 | 36 | |
| 38 | −DT_SCHEMA_FILES ?= $(DT_DOCS) | |
| 39 | − | |
| 40 | −extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) | |
| 41 | −extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) | |
| 42 | −extra-$(CHECK_DT_BINDING) += processed-schema-examples.yaml | |
| 43 | − | |
| 44 | 37 | override DTC_FLAGS := \ |
| 45 | 38 | -Wno-avoid_unnecessary_addr_size \ |
| 46 | − -Wno-graph_child_address | |
| 39 | + -Wno-graph_child_address \ | |
| 40 | + -Wno-interrupt_provider | |
| 47 | 41 | |
| 48 | 42 | $(obj)/processed-schema-examples.yaml: $(DT_DOCS) check_dtschema_version FORCE |
| 49 | 43 | $(call if_changed,mk_schema) |
| 50 | 44 | |
| 51 | −$(obj)/processed-schema.yaml: DT_MK_SCHEMA_FLAGS := $(DT_MK_SCHEMA_USERONLY_FLAG) | |
| 45 | +ifeq ($(DT_SCHEMA_FILES),) | |
| 46 | + | |
| 47 | +# Unless DT_SCHEMA_FILES is specified, use the full schema for dtbs_check too. | |
| 48 | +# Just copy processed-schema-examples.yaml | |
| 49 | + | |
| 50 | +$(obj)/processed-schema.yaml: $(obj)/processed-schema-examples.yaml FORCE | |
| 51 | + $(call if_changed,copy) | |
| 52 | + | |
| 53 | +DT_SCHEMA_FILES = $(DT_DOCS) | |
| 54 | + | |
| 55 | +else | |
| 56 | + | |
| 57 | +# If DT_SCHEMA_FILES is specified, use it for processed-schema.yaml | |
| 58 | + | |
| 59 | +$(obj)/processed-schema.yaml: DT_MK_SCHEMA_FLAGS := -u | |
| 52 | 60 | $(obj)/processed-schema.yaml: $(DT_SCHEMA_FILES) check_dtschema_version FORCE |
| 53 | 61 | $(call if_changed,mk_schema) |
| 54 | 62 | |
| 55 | −extra-y += processed-schema.yaml | |
| 63 | +endif | |
| 64 | + | |
| 65 | +extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) | |
| 66 | +extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) | |
| 67 | +extra-$(CHECK_DT_BINDING) += processed-schema-examples.yaml | |
| 68 | +extra-$(CHECK_DTBS) += processed-schema.yaml | |
| 69 | + | |
| 70 | +# Hack: avoid 'Argument list too long' error for 'make clean'. Remove most of | |
| 71 | +# build artifacts here before they are processed by scripts/Makefile.clean | |
| 72 | +clean-files = $(shell find $(obj) \( -name '*.example.dts' -o \ | |
| 73 | + -name '*.example.dt.yaml' \) -delete 2>/dev/null) | |
| @@ -47,7 +47,7 @@ Required properties: · 46 unmodified lines | ||
| 47 | 47 | &lsio_mu1 1 2 |
| 48 | 48 | &lsio_mu1 1 3 |
| 49 | 49 | &lsio_mu1 3 3>; |
| 50 | − See Documentation/devicetree/bindings/mailbox/fsl,mu.txt | |
| 50 | + See Documentation/devicetree/bindings/mailbox/fsl,mu.yaml | |
| 51 | 51 | for detailed mailbox binding. |
| 52 | 52 | |
| 53 | 53 | Note: Each mu which supports general interrupt should have an alias correctly |
| @@ -80,14 +80,14 @@ examples: · 79 unmodified lines | ||
| 80 | 80 | ranges = <1 0x00000000 0x42000000 0x02000000>, |
| 81 | 81 | <5 0x00000000 0x46000000 0x01000000>; |
| 82 | 82 | |
| 83 | − ethernet@1,01f00000 { | |
| 83 | + ethernet@1,1f00000 { | |
| 84 | 84 | compatible = "smsc,lan9115"; |
| 85 | 85 | reg = <1 0x01f00000 0x1000>; |
| 86 | 86 | interrupts = <0 48 4>; |
| 87 | 87 | phy-mode = "mii"; |
| 88 | 88 | }; |
| 89 | 89 | |
| 90 | − uart@5,00200000 { | |
| 90 | + serial@5,200000 { | |
| 91 | 91 | compatible = "ns16550a"; |
| 92 | 92 | reg = <5 0x00200000 0x20>; |
| 93 | 93 | interrupts = <0 49 4>; |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Clock bindings for Freescale i.MX27 |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Fabio Estevam <fabio.estevam@freescale.com> | |
| 10 | + - Fabio Estevam <fabio.estevam@nxp.com> | |
| 11 | 11 | |
| 12 | 12 | description: | |
| 13 | 13 | The clock consumer should specify the desired clock by having the clock |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Clock bindings for Freescale i.MX31 |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Fabio Estevam <fabio.estevam@freescale.com> | |
| 10 | + - Fabio Estevam <fabio.estevam@nxp.com> | |
| 11 | 11 | |
| 12 | 12 | description: | |
| 13 | 13 | The clock consumer should specify the desired clock by having the clock |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Clock bindings for Freescale i.MX5 |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Fabio Estevam <fabio.estevam@freescale.com> | |
| 10 | + - Fabio Estevam <fabio.estevam@nxp.com> | |
| 11 | 11 | |
| 12 | 12 | description: | |
| 13 | 13 | The clock consumer should specify the desired clock by having the clock |
| @@ -37,7 +37,7 @@ Optional properties: · 36 unmodified lines | ||
| 37 | 37 | simple-card or audio-graph-card binding. See their binding |
| 38 | 38 | documents on how to describe the way the sii902x device is |
| 39 | 39 | connected to the rest of the audio system: |
| 40 | − Documentation/devicetree/bindings/sound/simple-card.txt | |
| 40 | + Documentation/devicetree/bindings/sound/simple-card.yaml | |
| 41 | 41 | Documentation/devicetree/bindings/sound/audio-graph-card.txt |
| 42 | 42 | Note: In case of the audio-graph-card binding the used port |
| 43 | 43 | index should be 3. |
| @@ -68,7 +68,7 @@ Required properties: · 67 unmodified lines | ||
| 68 | 68 | datasheet |
| 69 | 69 | - clocks : phandle to the PRE axi clock input, as described |
| 70 | 70 | in Documentation/devicetree/bindings/clock/clock-bindings.txt and |
| 71 | − Documentation/devicetree/bindings/clock/imx6q-clock.txt. | |
| 71 | + Documentation/devicetree/bindings/clock/imx6q-clock.yaml. | |
| 72 | 72 | - clock-names: should be "axi" |
| 73 | 73 | - interrupts: should contain the PRE interrupt |
| 74 | 74 | - fsl,iram: phandle pointing to the mmio-sram device node, that should be |
| @@ -94,7 +94,7 @@ Required properties: · 19 unmodified lines | ||
| 94 | 94 | datasheet |
| 95 | 95 | - clocks : phandles to the PRG ipg and axi clock inputs, as described |
| 96 | 96 | in Documentation/devicetree/bindings/clock/clock-bindings.txt and |
| 97 | − Documentation/devicetree/bindings/clock/imx6q-clock.txt. | |
| 97 | + Documentation/devicetree/bindings/clock/imx6q-clock.yaml. | |
| 98 | 98 | - clock-names: should be "ipg" and "axi" |
| 99 | 99 | - fsl,pres: phandles to the PRE units attached to this PRG, with the fixed |
| 100 | 100 | PRE as the first entry and the muxable PREs following. |
| @@ -30,8 +30,8 @@ Required properties: · 29 unmodified lines | ||
| 30 | 30 | "di2_sel" - IPU2 DI0 mux |
| 31 | 31 | "di3_sel" - IPU2 DI1 mux |
| 32 | 32 | The needed clock numbers for each are documented in |
| 33 | − Documentation/devicetree/bindings/clock/imx5-clock.txt, and in | |
| 34 | − Documentation/devicetree/bindings/clock/imx6q-clock.txt. | |
| 33 | + Documentation/devicetree/bindings/clock/imx5-clock.yaml, and in | |
| 34 | + Documentation/devicetree/bindings/clock/imx6q-clock.yaml. | |
| 35 | 35 | |
| 36 | 36 | Optional properties: |
| 37 | 37 | - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q |
| @@ -33,7 +33,7 @@ additionalProperties: false · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | examples: |
| 35 | 35 | - | |
| 36 | − sysreg { | |
| 36 | + sysreg@0 { | |
| 37 | 37 | compatible = "arm,versatile-sysreg", "syscon", "simple-mfd"; |
| 38 | 38 | reg = <0x00000 0x1000>; |
| 39 | 39 | |
| @@ -24,7 +24,7 @@ properties: · 23 unmodified lines | ||
| 24 | 24 | description: | |
| 25 | 25 | Should contain a list of phandles pointing to display interface port |
| 26 | 26 | of vop devices. vop definitions as defined in |
| 27 | − Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | |
| 27 | + Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml | |
| 28 | 28 | |
| 29 | 29 | required: |
| 30 | 30 | - compatible |
| @@ -12,7 +12,7 @@ Required properties for the top level node: · 11 unmodified lines | ||
| 12 | 12 | Only the GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported. |
| 13 | 13 | - #interrupt-cells : Specifies the number of cells needed to encode an |
| 14 | 14 | interrupt. Should be 2. The first cell defines the interrupt number, |
| 15 | − the second encodes the triger flags encoded as described in | |
| 15 | + the second encodes the trigger flags encoded as described in | |
| 16 | 16 | Documentation/devicetree/bindings/interrupt-controller/interrupts.txt |
| 17 | 17 | - compatible: |
| 18 | 18 | - "mediatek,mt7621-gpio" for Mediatek controllers |
| @@ -10,7 +10,7 @@ Interrupt number definition: · 9 unmodified lines | ||
| 10 | 10 | 16-31 : private irq, and we use 16 as the co-processor timer. |
| 11 | 11 | 31-1024: common irq for soc ip. |
| 12 | 12 | |
| 13 | −Interrupt triger mode: (Defined in dt-bindings/interrupt-controller/irq.h) | |
| 13 | +Interrupt trigger mode: (Defined in dt-bindings/interrupt-controller/irq.h) | |
| 14 | 14 | IRQ_TYPE_LEVEL_HIGH (default) |
| 15 | 15 | IRQ_TYPE_LEVEL_LOW |
| 16 | 16 | IRQ_TYPE_EDGE_RISING |
| @@ -87,7 +87,7 @@ Example: · 86 unmodified lines | ||
| 87 | 87 | ranges; |
| 88 | 88 | |
| 89 | 89 | /* APU<->RPU0 IPI mailbox controller */ |
| 90 | − ipi_mailbox_rpu0: mailbox@ff90400 { | |
| 90 | + ipi_mailbox_rpu0: mailbox@ff990400 { | |
| 91 | 91 | reg = <0xff990400 0x20>, |
| 92 | 92 | <0xff990420 0x20>, |
| 93 | 93 | <0xff990080 0x20>, |
| @@ -8,7 +8,7 @@ The embedded controller requires the SPI controller driver to signal readiness · 7 unmodified lines | ||
| 8 | 8 | to receive a transfer (that is, when TX FIFO contains the response data) by |
| 9 | 9 | strobing the ACK pin with the ready signal. See the "ready-gpios" property of the |
| 10 | 10 | SSP binding as documented in: |
| 11 | −<Documentation/devicetree/bindings/spi/spi-pxa2xx.txt>. | |
| 11 | +<Documentation/devicetree/bindings/spi/marvell,mmp2-ssp.yaml>. | |
| 12 | 12 | |
| 13 | 13 | Example: |
| 14 | 14 | &ssp3 { |
| @@ -3,7 +3,7 @@ MediaTek SoC built-in Bluetooth Devices · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | This device is a serial attached device to BTIF device and thus it must be a |
| 5 | 5 | child node of the serial node with BTIF. The dt-bindings details for BTIF |
| 6 | −device can be known via Documentation/devicetree/bindings/serial/8250.txt. | |
| 6 | +device can be known via Documentation/devicetree/bindings/serial/8250.yaml. | |
| 7 | 7 | |
| 8 | 8 | Required properties: |
| 9 | 9 | |
| @@ -114,7 +114,7 @@ with values derived from the SoC user manual. · 113 unmodified lines | ||
| 114 | 114 | [flags]> |
| 115 | 115 | |
| 116 | 116 | On other mach-shmobile platforms GPIO is handled by the gpio-rcar driver. |
| 117 | −Please refer to Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt | |
| 117 | +Please refer to Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml | |
| 118 | 118 | for documentation of the GPIO device tree bindings on those platforms. |
| 119 | 119 | |
| 120 | 120 | |
| @@ -5,7 +5,7 @@ It is based on common bindings for device graphs. · 4 unmodified lines | ||
| 5 | 5 | see ${LINUX}/Documentation/devicetree/bindings/graph.txt |
| 6 | 6 | |
| 7 | 7 | Basically, Audio Graph Card property is same as Simple Card. |
| 8 | −see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt | |
| 8 | +see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.yaml | |
| 9 | 9 | |
| 10 | 10 | Below are same as Simple-Card. |
| 11 | 11 | |
| @@ -5,7 +5,7 @@ codec or external codecs. · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | sti sound drivers allows to expose sti SoC audio interface through the |
| 7 | 7 | generic ASoC simple card. For details about sound card declaration please refer to |
| 8 | −Documentation/devicetree/bindings/sound/simple-card.txt. | |
| 8 | +Documentation/devicetree/bindings/sound/simple-card.yaml. | |
| 9 | 9 | |
| 10 | 10 | 1) sti-uniperiph-dai: audio dai device. |
| 11 | 11 | --------------------------------------- |
| @@ -34,12 +34,15 @@ properties: · 33 unmodified lines | ||
| 34 | 34 | maxItems: 1 |
| 35 | 35 | |
| 36 | 36 | clocks: |
| 37 | − maxItems: 1 | |
| 37 | + minItems: 1 | |
| 38 | + maxItems: 2 | |
| 39 | + items: | |
| 40 | + - description: controller register bus clock | |
| 41 | + - description: baud rate generator and delay control clock | |
| 38 | 42 | |
| 39 | 43 | clock-names: |
| 40 | − description: input clock for the baud rate generator | |
| 41 | − items: | |
| 42 | − - const: core | |
| 44 | + minItems: 1 | |
| 45 | + maxItems: 2 | |
| 43 | 46 | |
| 44 | 47 | if: |
| 45 | 48 | properties: |
| @@ -51,17 +54,22 @@ if: · 5 unmodified lines | ||
| 51 | 54 | then: |
| 52 | 55 | properties: |
| 53 | 56 | clocks: |
| 54 | − contains: | |
| 55 | − items: | |
| 56 | − - description: controller register bus clock | |
| 57 | − - description: baud rate generator and delay control clock | |
| 57 | + minItems: 2 | |
| 58 | 58 | |
| 59 | 59 | clock-names: |
| 60 | − minItems: 2 | |
| 61 | 60 | items: |
| 62 | 61 | - const: core |
| 63 | 62 | - const: pclk |
| 64 | 63 | |
| 64 | +else: | |
| 65 | + properties: | |
| 66 | + clocks: | |
| 67 | + maxItems: 1 | |
| 68 | + | |
| 69 | + clock-names: | |
| 70 | + items: | |
| 71 | + - const: core | |
| 72 | + | |
| 65 | 73 | required: |
| 66 | 74 | - compatible |
| 67 | 75 | - reg |
| @@ -19,7 +19,7 @@ Required properties: · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | SPI Controller nodes must be child of GENI based Qualcomm Universal |
| 21 | 21 | Peripharal. Please refer GENI based QUP wrapper controller node bindings |
| 22 | −described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt. | |
| 22 | +described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml. | |
| 23 | 23 | |
| 24 | 24 | SPI slave nodes must be children of the SPI master node and conform to SPI bus |
| 25 | 25 | binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt. |
| @@ -41,7 +41,7 @@ examples: · 40 unmodified lines | ||
| 41 | 41 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
| 42 | 42 | |
| 43 | 43 | // Example 1: SDM845 TSENS |
| 44 | − soc: soc@0 { | |
| 44 | + soc: soc { | |
| 45 | 45 | #address-cells = <2>; |
| 46 | 46 | #size-cells = <2>; |
| 47 | 47 | |
| @@ -224,7 +224,7 @@ examples: · 223 unmodified lines | ||
| 224 | 224 | #include <dt-bindings/thermal/thermal.h> |
| 225 | 225 | |
| 226 | 226 | // Example 1: SDM845 TSENS |
| 227 | − soc: soc@0 { | |
| 227 | + soc { | |
| 228 | 228 | #address-cells = <2>; |
| 229 | 229 | #size-cells = <2>; |
| 230 | 230 | |
| @@ -35,7 +35,7 @@ examples: · 34 unmodified lines | ||
| 35 | 35 | #include <dt-bindings/soc/ti,sci_pm_domain.h> |
| 36 | 36 | vtm: thermal@42050000 { |
| 37 | 37 | compatible = "ti,am654-vtm"; |
| 38 | − reg = <0x0 0x42050000 0x0 0x25c>; | |
| 38 | + reg = <0x42050000 0x25c>; | |
| 39 | 39 | power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>; |
| 40 | 40 | #thermal-sensor-cells = <1>; |
| 41 | 41 | }; |
| @@ -8,7 +8,7 @@ regs is accessed by cpu co-processor 4 registers with mtcr/mfcr. · 7 unmodified lines | ||
| 8 | 8 | - PTIM_CTLR "cr<0, 14>" Control reg to start reset timer. |
| 9 | 9 | - PTIM_TSR "cr<1, 14>" Interrupt cleanup status reg. |
| 10 | 10 | - PTIM_CCVR "cr<3, 14>" Current counter value reg. |
| 11 | − - PTIM_LVR "cr<6, 14>" Window value reg to triger next event. | |
| 11 | + - PTIM_LVR "cr<6, 14>" Window value reg to trigger next event. | |
| 12 | 12 | |
| 13 | 13 | ============================== |
| 14 | 14 | timer node bindings definition |
| @@ -127,8 +127,8 @@ examples: · 126 unmodified lines | ||
| 127 | 127 | #address-cells = <1>; |
| 128 | 128 | #size-cells = <0>; |
| 129 | 129 | |
| 130 | − string@0409 { | |
| 131 | − reg = <0x0409>; | |
| 130 | + string@409 { | |
| 131 | + reg = <0x409>; | |
| 132 | 132 | manufacturer = "ASPEED"; |
| 133 | 133 | product = "USB Virtual Hub"; |
| 134 | 134 | serial-number = "0000"; |
| @@ -1,4 +1,4 @@ | ||
| 1 | −:orphan: | |
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | 2 | |
| 3 | 3 | Writing DeviceTree Bindings in json-schema |
| 4 | 4 | ========================================== |
| @@ -124,9 +124,12 @@ dtc must also be built with YAML output support enabled. This requires that · 119 unmodified lines | ||
| 124 | 124 | libyaml and its headers be installed on the host system. For some distributions |
| 125 | 125 | that involves installing the development package, such as: |
| 126 | 126 | |
| 127 | −Debian: | |
| 127 | +Debian:: | |
| 128 | + | |
| 128 | 129 | apt-get install libyaml-dev |
| 129 | −Fedora: | |
| 130 | + | |
| 131 | +Fedora:: | |
| 132 | + | |
| 130 | 133 | dnf -y install libyaml-devel |
| 131 | 134 | |
| 132 | 135 | Running checks |
| @@ -451,7 +451,7 @@ The bridge driver also has some helper functions it can use: · 450 unmodified lines | ||
| 451 | 451 | "module_foo", "chipid", 0x36, NULL); |
| 452 | 452 | |
| 453 | 453 | This loads the given module (can be ``NULL`` if no module needs to be loaded) |
| 454 | −and calls :c:func:`i2c_new_device` with the given ``i2c_adapter`` and | |
| 454 | +and calls :c:func:`i2c_new_client_device` with the given ``i2c_adapter`` and | |
| 455 | 455 | chip/address arguments. If all goes well, then it registers the subdev with |
| 456 | 456 | the v4l2_device. |
| 457 | 457 | |
| @@ -25,7 +25,7 @@ size when creating the filesystem. · 24 unmodified lines | ||
| 25 | 25 | Currently 3 filesystems support DAX: ext2, ext4 and xfs. Enabling DAX on them |
| 26 | 26 | is different. |
| 27 | 27 | |
| 28 | −Enabling DAX on ext4 and ext2 | |
| 28 | +Enabling DAX on ext2 | |
| 29 | 29 | ----------------------------- |
| 30 | 30 | |
| 31 | 31 | When mounting the filesystem, use the "-o dax" option on the command line or |
| @@ -33,8 +33,8 @@ add 'dax' to the options in /etc/fstab. This works to enable DAX on all files · 1 unmodified line | ||
| 33 | 33 | within the filesystem. It is equivalent to the '-o dax=always' behavior below. |
| 34 | 34 | |
| 35 | 35 | |
| 36 | −Enabling DAX on xfs | |
| 37 | −------------------- | |
| 36 | +Enabling DAX on xfs and ext4 | |
| 37 | +---------------------------- | |
| 38 | 38 | |
| 39 | 39 | Summary |
| 40 | 40 | ------- |
| @@ -39,3 +39,6 @@ is encrypted as well as the data itself. · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | Verity files cannot have blocks allocated past the end of the verity |
| 41 | 41 | metadata. |
| 42 | + | |
| 43 | +Verity and DAX are not compatible and attempts to set both of these flags | |
| 44 | +on a file will fail. | |
| @@ -197,11 +197,14 @@ pp_power_profile_mode · 196 unmodified lines | ||
| 197 | 197 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c |
| 198 | 198 | :doc: pp_power_profile_mode |
| 199 | 199 | |
| 200 | −busy_percent | |
| 201 | −~~~~~~~~~~~~ | |
| 200 | +*_busy_percent | |
| 201 | +~~~~~~~~~~~~~~ | |
| 202 | 202 | |
| 203 | 203 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c |
| 204 | − :doc: busy_percent | |
| 204 | + :doc: gpu_busy_percent | |
| 205 | + | |
| 206 | +.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |
| 207 | + :doc: mem_busy_percent | |
| 205 | 208 | |
| 206 | 209 | GPU Product Information |
| 207 | 210 | ======================= |
| @@ -1,14 +1,26 @@ | ||
| 1 | 1 | ============================== |
| 2 | −Linux I2C slave eeprom backend | |
| 2 | +Linux I2C slave EEPROM backend | |
| 3 | 3 | ============================== |
| 4 | 4 | |
| 5 | −by Wolfram Sang <wsa@sang-engineering.com> in 2014-15 | |
| 5 | +by Wolfram Sang <wsa@sang-engineering.com> in 2014-20 | |
| 6 | 6 | |
| 7 | −This is a proof-of-concept backend which acts like an EEPROM on the connected | |
| 8 | −I2C bus. The memory contents can be modified from userspace via this file | |
| 9 | −located in sysfs:: | |
| 7 | +This backend simulates an EEPROM on the connected I2C bus. Its memory contents | |
| 8 | +can be accessed from userspace via this file located in sysfs:: | |
| 10 | 9 | |
| 11 | 10 | /sys/bus/i2c/devices/<device-directory>/slave-eeprom |
| 12 | 11 | |
| 12 | +The following types are available: 24c02, 24c32, 24c64, and 24c512. Read-only | |
| 13 | +variants are also supported. The name needed for instantiating has the form | |
| 14 | +'slave-<type>[ro]'. Examples follow: | |
| 15 | + | |
| 16 | +24c02, read/write, address 0x64: | |
| 17 | + # echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-1/new_device | |
| 18 | + | |
| 19 | +24c512, read-only, address 0x42: | |
| 20 | + # echo slave-24c512ro 0x1042 > /sys/bus/i2c/devices/i2c-1/new_device | |
| 21 | + | |
| 22 | +You can also preload data during boot if a device-property named | |
| 23 | +'firmware-name' contains a valid filename (DT or ACPI only). | |
| 24 | + | |
| 13 | 25 | As of 2015, Linux doesn't support poll on binary sysfs files, so there is no |
| 14 | 26 | notification when another master changed the content. |
| @@ -57,7 +57,7 @@ SMBus Quick Command · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | This sends a single bit to the device, at the place of the Rd/Wr bit:: |
| 59 | 59 | |
| 60 | − A Addr Rd/Wr [A] P | |
| 60 | + S Addr Rd/Wr [A] P | |
| 61 | 61 | |
| 62 | 62 | Functionality flag: I2C_FUNC_SMBUS_QUICK |
| 63 | 63 | |
| @@ -182,7 +182,8 @@ module 8123.ko, which is built from the following files:: · 181 unmodified lines | ||
| 182 | 182 | 8123_pci.c |
| 183 | 183 | 8123_bin.o_shipped <= Binary blob |
| 184 | 184 | |
| 185 | −--- 3.1 Shared Makefile | |
| 185 | +3.1 Shared Makefile | |
| 186 | +------------------- | |
| 186 | 187 | |
| 187 | 188 | An external module always includes a wrapper makefile that |
| 188 | 189 | supports building the module using "make" with no arguments. |
| @@ -470,9 +471,9 @@ build. · 281 unmodified lines | ||
| 470 | 471 | |
| 471 | 472 | The syntax of the Module.symvers file is:: |
| 472 | 473 | |
| 473 | − <CRC> <Symbol> <Module> <Export Type> <Namespace> | |
| 474 | + <CRC> <Symbol> <Module> <Export Type> <Namespace> | |
| 474 | 475 | |
| 475 | − 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE | |
| 476 | + 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE | |
| 476 | 477 | |
| 477 | 478 | The fields are separated by tabs and values may be empty (e.g. |
| 478 | 479 | if no namespace is defined for an exported symbol). |
| @@ -101,7 +101,7 @@ Structure randomisation · 100 unmodified lines | ||
| 101 | 101 | |
| 102 | 102 | If you enable ``CONFIG_GCC_PLUGIN_RANDSTRUCT``, you will need to |
| 103 | 103 | pre-generate the random seed in |
| 104 | −``scripts/gcc-plgins/randomize_layout_seed.h`` so the same value | |
| 104 | +``scripts/gcc-plugins/randomize_layout_seed.h`` so the same value | |
| 105 | 105 | is used in rebuilds. |
| 106 | 106 | |
| 107 | 107 | Debug info conflicts |
| @@ -68,4 +68,4 @@ and frameworks can be controlled from the same registers, all of these · 67 unmodified lines | ||
| 68 | 68 | drivers access their registers through the same regmap. |
| 69 | 69 | |
| 70 | 70 | For more information regarding the devicetree bindings of the TCU drivers, |
| 71 | −have a look at Documentation/devicetree/bindings/timer/ingenic,tcu.txt. | |
| 71 | +have a look at Documentation/devicetree/bindings/timer/ingenic,tcu.yaml. | |
| @@ -30,8 +30,8 @@ Socket API · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | The address family, socket addresses etc. are defined in the |
| 32 | 32 | include/net/af_ieee802154.h header or in the special header |
| 33 | −in the userspace package (see either http://wpan.cakelab.org/ or the | |
| 34 | −git tree at https://github.com/linux-wpan/wpan-tools). | |
| 33 | +in the userspace package (see either https://linux-wpan.org/wpan-tools.html | |
| 34 | +or the git tree at https://github.com/linux-wpan/wpan-tools). | |
| 35 | 35 | |
| 36 | 36 | 6LoWPAN Linux implementation |
| 37 | 37 | ============================ |
| @@ -220,13 +220,51 @@ from the LPAR memory. · 219 unmodified lines | ||
| 220 | 220 | **H_SCM_HEALTH** |
| 221 | 221 | |
| 222 | 222 | | Input: drcIndex |
| 223 | −| Out: *health-bitmap, health-bit-valid-bitmap* | |
| 223 | +| Out: *health-bitmap (r4), health-bit-valid-bitmap (r5)* | |
| 224 | 224 | | Return Value: *H_Success, H_Parameter, H_Hardware* |
| 225 | 225 | |
| 226 | 226 | Given a DRC Index return the info on predictive failure and overall health of |
| 227 | −the NVDIMM. The asserted bits in the health-bitmap indicate a single predictive | |
| 228 | −failure and health-bit-valid-bitmap indicate which bits in health-bitmap are | |
| 229 | −valid. | |
| 227 | +the PMEM device. The asserted bits in the health-bitmap indicate one or more states | |
| 228 | +(described in table below) of the PMEM device and health-bit-valid-bitmap indicate | |
| 229 | +which bits in health-bitmap are valid. The bits are reported in | |
| 230 | +reverse bit ordering for example a value of 0xC400000000000000 | |
| 231 | +indicates bits 0, 1, and 5 are valid. | |
| 232 | + | |
| 233 | +Health Bitmap Flags: | |
| 234 | + | |
| 235 | ++------+-----------------------------------------------------------------------+ | |
| 236 | +| Bit | Definition | | |
| 237 | ++======+=======================================================================+ | |
| 238 | +| 00 | PMEM device is unable to persist memory contents. | | |
| 239 | +| | If the system is powered down, nothing will be saved. | | |
| 240 | ++------+-----------------------------------------------------------------------+ | |
| 241 | +| 01 | PMEM device failed to persist memory contents. Either contents were | | |
| 242 | +| | not saved successfully on power down or were not restored properly on | | |
| 243 | +| | power up. | | |
| 244 | ++------+-----------------------------------------------------------------------+ | |
| 245 | +| 02 | PMEM device contents are persisted from previous IPL. The data from | | |
| 246 | +| | the last boot were successfully restored. | | |
| 247 | ++------+-----------------------------------------------------------------------+ | |
| 248 | +| 03 | PMEM device contents are not persisted from previous IPL. There was no| | |
| 249 | +| | data to restore from the last boot. | | |
| 250 | ++------+-----------------------------------------------------------------------+ | |
| 251 | +| 04 | PMEM device memory life remaining is critically low | | |
| 252 | ++------+-----------------------------------------------------------------------+ | |
| 253 | +| 05 | PMEM device will be garded off next IPL due to failure | | |
| 254 | ++------+-----------------------------------------------------------------------+ | |
| 255 | +| 06 | PMEM device contents cannot persist due to current platform health | | |
| 256 | +| | status. A hardware failure may prevent data from being saved or | | |
| 257 | +| | restored. | | |
| 258 | ++------+-----------------------------------------------------------------------+ | |
| 259 | +| 07 | PMEM device is unable to persist memory contents in certain conditions| | |
| 260 | ++------+-----------------------------------------------------------------------+ | |
| 261 | +| 08 | PMEM device is encrypted | | |
| 262 | ++------+-----------------------------------------------------------------------+ | |
| 263 | +| 09 | PMEM device has successfully completed a requested erase or secure | | |
| 264 | +| | erase procedure. | | |
| 265 | ++------+-----------------------------------------------------------------------+ | |
| 266 | +|10:63 | Reserved / Unused | | |
| 267 | ++------+-----------------------------------------------------------------------+ | |
| 230 | 268 | |
| 231 | 269 | **H_SCM_PERFORMANCE_STATS** |
| 232 | 270 | |
| @@ -16,18 +16,6 @@ Store Queue API · 15 unmodified lines | ||
| 16 | 16 | .. kernel-doc:: arch/sh/kernel/cpu/sh4/sq.c |
| 17 | 17 | :export: |
| 18 | 18 | |
| 19 | −SH-5 | |
| 20 | −---- | |
| 21 | − | |
| 22 | −TLB Interfaces | |
| 23 | −~~~~~~~~~~~~~~ | |
| 24 | − | |
| 25 | −.. kernel-doc:: arch/sh/mm/tlb-sh5.c | |
| 26 | − :internal: | |
| 27 | − | |
| 28 | −.. kernel-doc:: arch/sh/include/asm/tlb_64.h | |
| 29 | − :internal: | |
| 30 | − | |
| 31 | 19 | Machine Specific Interfaces |
| 32 | 20 | =========================== |
| 33 | 21 | |
| @@ -27,7 +27,7 @@ nitpick_ignore = [ · 26 unmodified lines | ||
| 27 | 27 | ("c:func", "copy_to_user"), |
| 28 | 28 | ("c:func", "determine_valid_ioctls"), |
| 29 | 29 | ("c:func", "ERR_PTR"), |
| 30 | − ("c:func", "i2c_new_device"), | |
| 30 | + ("c:func", "i2c_new_client_device"), | |
| 31 | 31 | ("c:func", "ioctl"), |
| 32 | 32 | ("c:func", "IS_ERR"), |
| 33 | 33 | ("c:func", "KERNEL_VERSION"), |
| @@ -3946,7 +3946,7 @@ L: linux-crypto@vger.kernel.org · 3945 unmodified lines | ||
| 3946 | 3946 | S: Supported |
| 3947 | 3947 | F: drivers/char/hw_random/cctrng.c |
| 3948 | 3948 | F: drivers/char/hw_random/cctrng.h |
| 3949 | −F: Documentation/devicetree/bindings/rng/arm-cctrng.txt | |
| 3949 | +F: Documentation/devicetree/bindings/rng/arm-cctrng.yaml | |
| 3950 | 3950 | W: https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family |
| 3951 | 3951 | |
| 3952 | 3952 | CEC FRAMEWORK |
| @@ -5490,7 +5490,7 @@ F: include/uapi/drm/r128_drm.h · 1537 unmodified lines | ||
| 5490 | 5490 | DRM DRIVER FOR RAYDIUM RM67191 PANELS |
| 5491 | 5491 | M: Robert Chiras <robert.chiras@nxp.com> |
| 5492 | 5492 | S: Maintained |
| 5493 | −F: Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt | |
| 5493 | +F: Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml | |
| 5494 | 5494 | F: drivers/gpu/drm/panel/panel-raydium-rm67191.c |
| 5495 | 5495 | |
| 5496 | 5496 | DRM DRIVER FOR ROCKTECH JH057N00900 PANELS |
| @@ -8333,7 +8333,7 @@ M: Alexander Aring <alex.aring@gmail.com> · 2836 unmodified lines | ||
| 8333 | 8333 | M: Stefan Schmidt <stefan@datenfreihafen.org> |
| 8334 | 8334 | L: linux-wpan@vger.kernel.org |
| 8335 | 8335 | S: Maintained |
| 8336 | −W: http://wpan.cakelab.org/ | |
| 8336 | +W: https://linux-wpan.org/ | |
| 8337 | 8337 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan.git |
| 8338 | 8338 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git |
| 8339 | 8339 | F: Documentation/networking/ieee802154.rst |
| @@ -10808,7 +10808,7 @@ F: Documentation/devicetree/bindings/dma/mtk-* · 2468 unmodified lines | ||
| 10808 | 10808 | F: drivers/dma/mediatek/ |
| 10809 | 10809 | |
| 10810 | 10810 | MEDIATEK ETHERNET DRIVER |
| 10811 | −M: Felix Fietkau <nbd@openwrt.org> | |
| 10811 | +M: Felix Fietkau <nbd@nbd.name> | |
| 10812 | 10812 | M: John Crispin <john@phrozen.org> |
| 10813 | 10813 | M: Sean Wang <sean.wang@mediatek.com> |
| 10814 | 10814 | M: Mark Lee <Mark-MC.Lee@mediatek.com> |
| @@ -11369,14 +11369,6 @@ L: dmaengine@vger.kernel.org · 554 unmodified lines | ||
| 11369 | 11369 | S: Supported |
| 11370 | 11370 | F: drivers/dma/at_xdmac.c |
| 11371 | 11371 | |
| 11372 | −MICROSEMI ETHERNET SWITCH DRIVER | |
| 11373 | −M: Alexandre Belloni <alexandre.belloni@bootlin.com> | |
| 11374 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11375 | −L: netdev@vger.kernel.org | |
| 11376 | −S: Supported | |
| 11377 | −F: drivers/net/ethernet/mscc/ | |
| 11378 | −F: include/soc/mscc/ocelot* | |
| 11379 | − | |
| 11380 | 11372 | MICROSEMI MIPS SOCS |
| 11381 | 11373 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 11382 | 11374 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> |
| @@ -12335,6 +12327,18 @@ M: Peter Zijlstra <peterz@infradead.org> · 952 unmodified lines | ||
| 12335 | 12327 | S: Supported |
| 12336 | 12328 | F: tools/objtool/ |
| 12337 | 12329 | |
| 12330 | +OCELOT ETHERNET SWITCH DRIVER | |
| 12331 | +M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 12332 | +M: Vladimir Oltean <vladimir.oltean@nxp.com> | |
| 12333 | +M: Claudiu Manoil <claudiu.manoil@nxp.com> | |
| 12334 | +M: Alexandre Belloni <alexandre.belloni@bootlin.com> | |
| 12335 | +L: netdev@vger.kernel.org | |
| 12336 | +S: Supported | |
| 12337 | +F: drivers/net/dsa/ocelot/* | |
| 12338 | +F: drivers/net/ethernet/mscc/ | |
| 12339 | +F: include/soc/mscc/ocelot* | |
| 12340 | +F: net/dsa/tag_ocelot.c | |
| 12341 | + | |
| 12338 | 12342 | OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER |
| 12339 | 12343 | M: Frederic Barrat <fbarrat@linux.ibm.com> |
| 12340 | 12344 | M: Andrew Donnellan <ajd@linux.ibm.com> |
| @@ -12691,13 +12695,13 @@ F: arch/mips/boot/dts/ralink/omega2p.dts · 350 unmodified lines | ||
| 12691 | 12695 | |
| 12692 | 12696 | OP-TEE DRIVER |
| 12693 | 12697 | M: Jens Wiklander <jens.wiklander@linaro.org> |
| 12694 | −L: tee-dev@lists.linaro.org | |
| 12698 | +L: op-tee@lists.trustedfirmware.org | |
| 12695 | 12699 | S: Maintained |
| 12696 | 12700 | F: drivers/tee/optee/ |
| 12697 | 12701 | |
| 12698 | 12702 | OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER |
| 12699 | 12703 | M: Sumit Garg <sumit.garg@linaro.org> |
| 12700 | −L: tee-dev@lists.linaro.org | |
| 12704 | +L: op-tee@lists.trustedfirmware.org | |
| 12701 | 12705 | S: Maintained |
| 12702 | 12706 | F: drivers/char/hw_random/optee-rng.c |
| 12703 | 12707 | |
| @@ -14192,6 +14196,15 @@ L: dmaengine@vger.kernel.org · 1488 unmodified lines | ||
| 14192 | 14196 | S: Supported |
| 14193 | 14197 | F: drivers/dma/qcom/hidma* |
| 14194 | 14198 | |
| 14199 | +QUALCOMM I2C CCI DRIVER | |
| 14200 | +M: Loic Poulain <loic.poulain@linaro.org> | |
| 14201 | +M: Robert Foss <robert.foss@linaro.org> | |
| 14202 | +L: linux-i2c@vger.kernel.org | |
| 14203 | +L: linux-arm-msm@vger.kernel.org | |
| 14204 | +S: Maintained | |
| 14205 | +F: Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt | |
| 14206 | +F: drivers/i2c/busses/i2c-qcom-cci.c | |
| 14207 | + | |
| 14195 | 14208 | QUALCOMM IOMMU |
| 14196 | 14209 | M: Rob Clark <robdclark@gmail.com> |
| 14197 | 14210 | L: iommu@lists.linux-foundation.org |
| @@ -14534,7 +14547,7 @@ F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt · 336 unmodified lines | ||
| 14534 | 14547 | F: drivers/i2c/busses/i2c-emev2.c |
| 14535 | 14548 | |
| 14536 | 14549 | RENESAS ETHERNET DRIVERS |
| 14537 | −R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> | |
| 14550 | +R: Sergei Shtylyov <sergei.shtylyov@gmail.com> | |
| 14538 | 14551 | L: netdev@vger.kernel.org |
| 14539 | 14552 | L: linux-renesas-soc@vger.kernel.org |
| 14540 | 14553 | F: Documentation/devicetree/bindings/net/renesas,*.txt |
| @@ -14561,8 +14574,8 @@ RENESAS R-CAR THERMAL DRIVERS · 20 unmodified lines | ||
| 14561 | 14574 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 14562 | 14575 | L: linux-renesas-soc@vger.kernel.org |
| 14563 | 14576 | S: Supported |
| 14564 | −F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt | |
| 14565 | −F: Documentation/devicetree/bindings/thermal/rcar-thermal.txt | |
| 14577 | +F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml | |
| 14578 | +F: Documentation/devicetree/bindings/thermal/rcar-thermal.yaml | |
| 14566 | 14579 | F: drivers/thermal/rcar_gen3_thermal.c |
| 14567 | 14580 | F: drivers/thermal/rcar_thermal.c |
| 14568 | 14581 | |
| @@ -16045,8 +16058,10 @@ SPARSE CHECKER · 1476 unmodified lines | ||
| 16045 | 16058 | M: "Luc Van Oostenryck" <luc.vanoostenryck@gmail.com> |
| 16046 | 16059 | L: linux-sparse@vger.kernel.org |
| 16047 | 16060 | S: Maintained |
| 16048 | −W: https://sparse.wiki.kernel.org/ | |
| 16061 | +W: https://sparse.docs.kernel.org/ | |
| 16049 | 16062 | T: git git://git.kernel.org/pub/scm/devel/sparse/sparse.git |
| 16063 | +Q: https://patchwork.kernel.org/project/linux-sparse/list/ | |
| 16064 | +B: https://bugzilla.kernel.org/enter_bug.cgi?component=Sparse&product=Tools | |
| 16050 | 16065 | F: include/linux/compiler.h |
| 16051 | 16066 | |
| 16052 | 16067 | SPEAR CLOCK FRAMEWORK SUPPORT |
| @@ -16759,7 +16774,7 @@ F: include/media/i2c/tw9910.h · 706 unmodified lines | ||
| 16759 | 16774 | |
| 16760 | 16775 | TEE SUBSYSTEM |
| 16761 | 16776 | M: Jens Wiklander <jens.wiklander@linaro.org> |
| 16762 | −L: tee-dev@lists.linaro.org | |
| 16777 | +L: op-tee@lists.trustedfirmware.org | |
| 16763 | 16778 | S: Maintained |
| 16764 | 16779 | F: Documentation/tee.txt |
| 16765 | 16780 | F: drivers/tee/ |
| @@ -18254,14 +18269,6 @@ S: Maintained · 1488 unmodified lines | ||
| 18254 | 18269 | F: drivers/input/serio/userio.c |
| 18255 | 18270 | F: include/uapi/linux/userio.h |
| 18256 | 18271 | |
| 18257 | −VITESSE FELIX ETHERNET SWITCH DRIVER | |
| 18258 | −M: Vladimir Oltean <vladimir.oltean@nxp.com> | |
| 18259 | −M: Claudiu Manoil <claudiu.manoil@nxp.com> | |
| 18260 | −L: netdev@vger.kernel.org | |
| 18261 | −S: Maintained | |
| 18262 | −F: drivers/net/dsa/ocelot/* | |
| 18263 | −F: net/dsa/tag_ocelot.c | |
| 18264 | − | |
| 18265 | 18272 | VIVID VIRTUAL VIDEO DRIVER |
| 18266 | 18273 | M: Hans Verkuil <hverkuil@xs4all.nl> |
| 18267 | 18274 | L: linux-media@vger.kernel.org |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 8 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -828,7 +828,7 @@ endif · 819 unmodified lines | ||
| 828 | 828 | |
| 829 | 829 | ifdef CONFIG_DEBUG_INFO_COMPRESSED |
| 830 | 830 | DEBUG_CFLAGS += -gz=zlib |
| 831 | −KBUILD_AFLAGS += -Wa,--compress-debug-sections=zlib | |
| 831 | +KBUILD_AFLAGS += -gz=zlib | |
| 832 | 832 | KBUILD_LDFLAGS += --compress-debug-sections=zlib |
| 833 | 833 | endif |
| 834 | 834 | |
| @@ -970,8 +970,8 @@ LDFLAGS_vmlinux += --pack-dyn-relocs=relr · 135 unmodified lines | ||
| 970 | 970 | endif |
| 971 | 971 | |
| 972 | 972 | # Align the bit size of userspace programs with the kernel |
| 973 | −KBUILD_USERCFLAGS += $(filter -m32 -m64, $(KBUILD_CFLAGS)) | |
| 974 | −KBUILD_USERLDFLAGS += $(filter -m32 -m64, $(KBUILD_CFLAGS)) | |
| 973 | +KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) | |
| 974 | +KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) | |
| 975 | 975 | |
| 976 | 976 | # make the checker run with the right architecture |
| 977 | 977 | CHECKFLAGS += --arch=$(ARCH) |
| @@ -1336,16 +1336,6 @@ dt_binding_check: scripts_dtc · 358 unmodified lines | ||
| 1336 | 1336 | # --------------------------------------------------------------------------- |
| 1337 | 1337 | # Modules |
| 1338 | 1338 | |
| 1339 | −# install modules.builtin regardless of CONFIG_MODULES | |
| 1340 | −PHONY += _builtin_inst_ | |
| 1341 | −_builtin_inst_: | |
| 1342 | − @mkdir -p $(MODLIB)/ | |
| 1343 | − @cp -f modules.builtin $(MODLIB)/ | |
| 1344 | − @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/ | |
| 1345 | − | |
| 1346 | −PHONY += install | |
| 1347 | −install: _builtin_inst_ | |
| 1348 | − | |
| 1349 | 1339 | ifdef CONFIG_MODULES |
| 1350 | 1340 | |
| 1351 | 1341 | # By default, build modules as well |
| @@ -1389,7 +1379,7 @@ PHONY += modules_install · 37 unmodified lines | ||
| 1389 | 1379 | modules_install: _modinst_ _modinst_post |
| 1390 | 1380 | |
| 1391 | 1381 | PHONY += _modinst_ |
| 1392 | −_modinst_: _builtin_inst_ | |
| 1382 | +_modinst_: | |
| 1393 | 1383 | @rm -rf $(MODLIB)/kernel |
| 1394 | 1384 | @rm -f $(MODLIB)/source |
| 1395 | 1385 | @mkdir -p $(MODLIB)/kernel |
| @@ -1399,6 +1389,8 @@ _modinst_: _builtin_inst_ · 3 unmodified lines | ||
| 1399 | 1389 | ln -s $(CURDIR) $(MODLIB)/build ; \ |
| 1400 | 1390 | fi |
| 1401 | 1391 | @sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order |
| 1392 | + @cp -f modules.builtin $(MODLIB)/ | |
| 1393 | + @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/ | |
| 1402 | 1394 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst |
| 1403 | 1395 | |
| 1404 | 1396 | # This depmod is only for convenience to give the initial |
| @@ -369,7 +369,7 @@ · 368 unmodified lines | ||
| 369 | 369 | &mmc2 { |
| 370 | 370 | status = "okay"; |
| 371 | 371 | vmmc-supply = <&wl12xx_vmmc>; |
| 372 | − ti,non-removable; | |
| 372 | + non-removable; | |
| 373 | 373 | bus-width = <4>; |
| 374 | 374 | cap-power-off-card; |
| 375 | 375 | pinctrl-names = "default"; |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | pinctrl-0 = <&emmc_pins>; |
| 23 | 23 | bus-width = <8>; |
| 24 | 24 | status = "okay"; |
| 25 | + non-removable; | |
| 25 | 26 | }; |
| 26 | 27 | |
| 27 | 28 | &am33xx_pinmux { |
| @@ -75,7 +75,6 @@ · 74 unmodified lines | ||
| 75 | 75 | bus-width = <4>; |
| 76 | 76 | non-removable; |
| 77 | 77 | cap-power-off-card; |
| 78 | − ti,needs-special-hs-handling; | |
| 79 | 78 | keep-power-in-suspend; |
| 80 | 79 | pinctrl-names = "default"; |
| 81 | 80 | pinctrl-0 = <&mmc3_pins &wl18xx_pins>; |
| @@ -367,7 +367,6 @@ · 366 unmodified lines | ||
| 367 | 367 | bus-width = <4>; |
| 368 | 368 | non-removable; |
| 369 | 369 | cap-power-off-card; |
| 370 | − ti,needs-special-hs-handling; | |
| 371 | 370 | keep-power-in-suspend; |
| 372 | 371 | pinctrl-names = "default"; |
| 373 | 372 | pinctrl-0 = <&mmc3_pins &wl18xx_pins>; |
| @@ -75,7 +75,6 @@ · 74 unmodified lines | ||
| 75 | 75 | bus-width = <4>; |
| 76 | 76 | non-removable; |
| 77 | 77 | cap-power-off-card; |
| 78 | − ti,needs-special-hs-handling; | |
| 79 | 78 | keep-power-in-suspend; |
| 80 | 79 | pinctrl-names = "default"; |
| 81 | 80 | pinctrl-0 = <&mmc3_pins &wl18xx_pins>; |
| @@ -743,8 +743,7 @@ · 742 unmodified lines | ||
| 743 | 743 | bus-width = <4>; |
| 744 | 744 | pinctrl-names = "default"; |
| 745 | 745 | pinctrl-0 = <&mmc3_pins &wlan_pins>; |
| 746 | − ti,non-removable; | |
| 747 | − ti,needs-special-hs-handling; | |
| 746 | + non-removable; | |
| 748 | 747 | cap-power-off-card; |
| 749 | 748 | keep-power-in-suspend; |
| 750 | 749 | |
| @@ -655,7 +655,7 @@ · 654 unmodified lines | ||
| 655 | 655 | &mmc2 { |
| 656 | 656 | status = "okay"; |
| 657 | 657 | vmmc-supply = <&wl12xx_vmmc>; |
| 658 | − ti,non-removable; | |
| 658 | + non-removable; | |
| 659 | 659 | bus-width = <4>; |
| 660 | 660 | cap-power-off-card; |
| 661 | 661 | keep-power-in-suspend; |
| @@ -339,7 +339,7 @@ · 338 unmodified lines | ||
| 339 | 339 | pinctrl-0 = <&emmc_pins>; |
| 340 | 340 | vmmc-supply = <&vmmcsd_fixed>; |
| 341 | 341 | bus-width = <8>; |
| 342 | − ti,non-removable; | |
| 342 | + non-removable; | |
| 343 | 343 | status = "okay"; |
| 344 | 344 | }; |
| 345 | 345 | |
| @@ -159,7 +159,7 @@ · 158 unmodified lines | ||
| 159 | 159 | vmmc-supply = <&vmmcsd_fixed>; |
| 160 | 160 | bus-width = <8>; |
| 161 | 161 | pinctrl-0 = <&mmc1_pins_default>; |
| 162 | − ti,non-removable; | |
| 162 | + non-removable; | |
| 163 | 163 | status = "okay"; |
| 164 | 164 | }; |
| 165 | 165 | |
| @@ -451,7 +451,7 @@ · 450 unmodified lines | ||
| 451 | 451 | vmmc-supply = <&vmmcsd_fixed>; |
| 452 | 452 | bus-width = <8>; |
| 453 | 453 | pinctrl-0 = <&mmc2_pins_default>; |
| 454 | − ti,non-removable; | |
| 454 | + non-removable; | |
| 455 | 455 | status = "okay"; |
| 456 | 456 | }; |
| 457 | 457 | |
| @@ -341,7 +341,7 @@ · 340 unmodified lines | ||
| 341 | 341 | pinctrl-0 = <&emmc_pins>; |
| 342 | 342 | vmmc-supply = <&ldo3_reg>; |
| 343 | 343 | bus-width = <8>; |
| 344 | − ti,non-removable; | |
| 344 | + non-removable; | |
| 345 | 345 | }; |
| 346 | 346 | |
| 347 | 347 | &mmc3 { |
| @@ -351,7 +351,7 @@ · 3 unmodified lines | ||
| 351 | 351 | pinctrl-0 = <&wireless_pins>; |
| 352 | 352 | vmmmc-supply = <&v3v3c_reg>; |
| 353 | 353 | bus-width = <4>; |
| 354 | − ti,non-removable; | |
| 354 | + non-removable; | |
| 355 | 355 | dmas = <&edma_xbar 12 0 1 |
| 356 | 356 | &edma_xbar 13 0 2>; |
| 357 | 357 | dma-names = "tx", "rx"; |
| @@ -69,7 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | pinctrl-0 = <&emmc_pins>; |
| 70 | 70 | vmmc-supply = <&vmmc_reg>; |
| 71 | 71 | bus-width = <8>; |
| 72 | − ti,non-removable; | |
| 72 | + non-removable; | |
| 73 | 73 | status = "disabled"; |
| 74 | 74 | }; |
| 75 | 75 | |
| @@ -88,7 +88,6 @@ · 87 unmodified lines | ||
| 88 | 88 | AM33XX_PADCONF(AM335X_PIN_MMC0_DAT3, PIN_INPUT_PULLUP, MUX_MODE0) |
| 89 | 89 | AM33XX_PADCONF(AM335X_PIN_MMC0_CMD, PIN_INPUT_PULLUP, MUX_MODE0) |
| 90 | 90 | AM33XX_PADCONF(AM335X_PIN_MMC0_CLK, PIN_INPUT_PULLUP, MUX_MODE0) |
| 91 | − AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKR, PIN_INPUT, MUX_MODE4) /* (B12) mcasp0_aclkr.mmc0_sdwp */ | |
| 92 | 91 | >; |
| 93 | 92 | }; |
| 94 | 93 | |
| @@ -1335,10 +1335,8 @@ · 1334 unmodified lines | ||
| 1335 | 1335 | ranges = <0x0 0x60000 0x1000>; |
| 1336 | 1336 | |
| 1337 | 1337 | mmc1: mmc@0 { |
| 1338 | − compatible = "ti,omap4-hsmmc"; | |
| 1339 | − ti,dual-volt; | |
| 1338 | + compatible = "ti,am335-sdhci"; | |
| 1340 | 1339 | ti,needs-special-reset; |
| 1341 | − ti,needs-special-hs-handling; | |
| 1342 | 1340 | dmas = <&edma_xbar 24 0 0 |
| 1343 | 1341 | &edma_xbar 25 0 0>; |
| 1344 | 1342 | dma-names = "tx", "rx"; |
| @@ -1816,7 +1814,7 @@ · 471 unmodified lines | ||
| 1816 | 1814 | ranges = <0x0 0xd8000 0x1000>; |
| 1817 | 1815 | |
| 1818 | 1816 | mmc2: mmc@0 { |
| 1819 | − compatible = "ti,omap4-hsmmc"; | |
| 1817 | + compatible = "ti,am335-sdhci"; | |
| 1820 | 1818 | ti,needs-special-reset; |
| 1821 | 1819 | dmas = <&edma 2 0 |
| 1822 | 1820 | &edma 3 0>; |
| @@ -322,10 +322,11 @@ · 321 unmodified lines | ||
| 322 | 322 | ranges = <0x0 0x47810000 0x1000>; |
| 323 | 323 | |
| 324 | 324 | mmc3: mmc@0 { |
| 325 | − compatible = "ti,omap4-hsmmc"; | |
| 325 | + compatible = "ti,am335-sdhci"; | |
| 326 | 326 | ti,needs-special-reset; |
| 327 | 327 | interrupts = <29>; |
| 328 | 328 | reg = <0x0 0x1000>; |
| 329 | + status = "disabled"; | |
| 329 | 330 | }; |
| 330 | 331 | }; |
| 331 | 332 | |
| @@ -335,7 +336,7 @@ · 3 unmodified lines | ||
| 335 | 336 | <0x47400010 0x4>; |
| 336 | 337 | reg-names = "rev", "sysc"; |
| 337 | 338 | ti,sysc-mask = <(SYSC_OMAP4_FREEEMU | |
| 338 | − SYSC_OMAP2_SOFTRESET)>; | |
| 339 | + SYSC_OMAP4_SOFTRESET)>; | |
| 339 | 340 | ti,sysc-midle = <SYSC_IDLE_FORCE>, |
| 340 | 341 | <SYSC_IDLE_NO>, |
| 341 | 342 | <SYSC_IDLE_SMART>; |
| @@ -347,7 +348,7 @@ · 5 unmodified lines | ||
| 347 | 348 | clock-names = "fck"; |
| 348 | 349 | #address-cells = <1>; |
| 349 | 350 | #size-cells = <1>; |
| 350 | − ranges = <0x0 0x47400000 0x5000>; | |
| 351 | + ranges = <0x0 0x47400000 0x8000>; | |
| 351 | 352 | |
| 352 | 353 | usb0_phy: usb-phy@1300 { |
| 353 | 354 | compatible = "ti,am335x-usb-phy"; |
| @@ -316,10 +316,11 @@ · 315 unmodified lines | ||
| 316 | 316 | ranges = <0x0 0x47810000 0x1000>; |
| 317 | 317 | |
| 318 | 318 | mmc3: mmc@0 { |
| 319 | − compatible = "ti,omap4-hsmmc"; | |
| 319 | + compatible = "ti,am437-sdhci"; | |
| 320 | 320 | ti,needs-special-reset; |
| 321 | 321 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; |
| 322 | 322 | reg = <0x0 0x1000>; |
| 323 | + status = "disabled"; | |
| 323 | 324 | }; |
| 324 | 325 | }; |
| 325 | 326 | |
| @@ -291,7 +291,7 @@ · 290 unmodified lines | ||
| 291 | 291 | pinctrl-0 = <&emmc_pins>; |
| 292 | 292 | vmmc-supply = <&vmmc_3v3>; |
| 293 | 293 | bus-width = <8>; |
| 294 | − ti,non-removable; | |
| 294 | + non-removable; | |
| 295 | 295 | }; |
| 296 | 296 | |
| 297 | 297 | &spi0 { |
| @@ -91,22 +91,6 @@ · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | backlight = <&lcd_bl>; |
| 93 | 93 | |
| 94 | − panel-timing { | |
| 95 | − clock-frequency = <33000000>; | |
| 96 | − hactive = <800>; | |
| 97 | − vactive = <480>; | |
| 98 | − hfront-porch = <210>; | |
| 99 | − hback-porch = <16>; | |
| 100 | − hsync-len = <30>; | |
| 101 | − vback-porch = <10>; | |
| 102 | − vfront-porch = <22>; | |
| 103 | − vsync-len = <13>; | |
| 104 | − hsync-active = <0>; | |
| 105 | − vsync-active = <0>; | |
| 106 | − de-active = <1>; | |
| 107 | − pixelclk-active = <1>; | |
| 108 | − }; | |
| 109 | − | |
| 110 | 94 | port { |
| 111 | 95 | lcd_in: endpoint { |
| 112 | 96 | remote-endpoint = <&dpi_out>; |
| @@ -869,7 +853,7 @@ · 756 unmodified lines | ||
| 869 | 853 | pinctrl-names = "default", "sleep"; |
| 870 | 854 | pinctrl-0 = <&emmc_pins_default>; |
| 871 | 855 | pinctrl-1 = <&emmc_pins_sleep>; |
| 872 | − ti,non-removable; | |
| 856 | + non-removable; | |
| 873 | 857 | }; |
| 874 | 858 | |
| 875 | 859 | &mmc3 { |
| @@ -886,7 +870,7 @@ · 10 unmodified lines | ||
| 886 | 870 | pinctrl-1 = <&mmc3_pins_sleep>; |
| 887 | 871 | cap-power-off-card; |
| 888 | 872 | keep-power-in-suspend; |
| 889 | − ti,non-removable; | |
| 873 | + non-removable; | |
| 890 | 874 | |
| 891 | 875 | #address-cells = <1>; |
| 892 | 876 | #size-cells = <0>; |
| @@ -1083,9 +1083,8 @@ · 1082 unmodified lines | ||
| 1083 | 1083 | ranges = <0x0 0x60000 0x1000>; |
| 1084 | 1084 | |
| 1085 | 1085 | mmc1: mmc@0 { |
| 1086 | − compatible = "ti,omap4-hsmmc"; | |
| 1086 | + compatible = "ti,am437-sdhci"; | |
| 1087 | 1087 | reg = <0x0 0x1000>; |
| 1088 | − ti,dual-volt; | |
| 1089 | 1088 | ti,needs-special-reset; |
| 1090 | 1089 | dmas = <&edma 24 0>, |
| 1091 | 1090 | <&edma 25 0>; |
| @@ -1598,7 +1597,7 @@ · 506 unmodified lines | ||
| 1598 | 1597 | ranges = <0x0 0xd8000 0x1000>; |
| 1599 | 1598 | |
| 1600 | 1599 | mmc2: mmc@0 { |
| 1601 | − compatible = "ti,omap4-hsmmc"; | |
| 1600 | + compatible = "ti,am437-sdhci"; | |
| 1602 | 1601 | reg = <0x0 0x1000>; |
| 1603 | 1602 | ti,needs-special-reset; |
| 1604 | 1603 | dmas = <&edma 2 0>, |
| @@ -134,22 +134,6 @@ · 133 unmodified lines | ||
| 134 | 134 | |
| 135 | 135 | enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; |
| 136 | 136 | |
| 137 | − panel-timing { | |
| 138 | − clock-frequency = <9000000>; | |
| 139 | − hactive = <480>; | |
| 140 | − vactive = <272>; | |
| 141 | − hfront-porch = <2>; | |
| 142 | − hback-porch = <2>; | |
| 143 | − hsync-len = <41>; | |
| 144 | − vfront-porch = <2>; | |
| 145 | − vback-porch = <2>; | |
| 146 | − vsync-len = <10>; | |
| 147 | − hsync-active = <0>; | |
| 148 | − vsync-active = <0>; | |
| 149 | − de-active = <1>; | |
| 150 | − pixelclk-active = <1>; | |
| 151 | − }; | |
| 152 | − | |
| 153 | 137 | port { |
| 154 | 138 | lcd_in: endpoint { |
| 155 | 139 | remote-endpoint = <&dpi_out>; |
| @@ -719,7 +703,7 @@ · 563 unmodified lines | ||
| 719 | 703 | pinctrl-1 = <&mmc3_pins_sleep>; |
| 720 | 704 | cap-power-off-card; |
| 721 | 705 | keep-power-in-suspend; |
| 722 | − ti,non-removable; | |
| 706 | + non-removable; | |
| 723 | 707 | |
| 724 | 708 | #address-cells = <1>; |
| 725 | 709 | #size-cells = <0>; |
| @@ -47,22 +47,6 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | backlight = <&lcd_bl>; |
| 49 | 49 | |
| 50 | − panel-timing { | |
| 51 | − clock-frequency = <33000000>; | |
| 52 | − hactive = <800>; | |
| 53 | − vactive = <480>; | |
| 54 | − hfront-porch = <210>; | |
| 55 | − hback-porch = <16>; | |
| 56 | − hsync-len = <30>; | |
| 57 | − vback-porch = <10>; | |
| 58 | − vfront-porch = <22>; | |
| 59 | − vsync-len = <13>; | |
| 60 | − hsync-active = <0>; | |
| 61 | − vsync-active = <0>; | |
| 62 | − de-active = <1>; | |
| 63 | − pixelclk-active = <1>; | |
| 64 | − }; | |
| 65 | − | |
| 66 | 50 | port { |
| 67 | 51 | lcd_in: endpoint { |
| 68 | 52 | remote-endpoint = <&dpi_out>; |
| @@ -505,7 +505,7 @@ · 504 unmodified lines | ||
| 505 | 505 | |
| 506 | 506 | &cpsw_emac0 { |
| 507 | 507 | phy-handle = <&phy0>; |
| 508 | − phy-mode = "rgmii"; | |
| 508 | + phy-mode = "rgmii-rxid"; | |
| 509 | 509 | }; |
| 510 | 510 | |
| 511 | 511 | &ocp { |
| @@ -200,7 +200,7 @@ · 199 unmodified lines | ||
| 200 | 200 | status = "disabled"; |
| 201 | 201 | }; |
| 202 | 202 | |
| 203 | − dma@20000 { | |
| 203 | + dma: dma@20000 { | |
| 204 | 204 | compatible = "arm,pl330", "arm,primecell"; |
| 205 | 205 | reg = <0x20000 0x1000>; |
| 206 | 206 | interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>, |
| @@ -215,6 +215,8 @@ · 8 unmodified lines | ||
| 215 | 215 | clocks = <&iprocslow>; |
| 216 | 216 | clock-names = "apb_pclk"; |
| 217 | 217 | #dma-cells = <1>; |
| 218 | + dma-coherent; | |
| 219 | + status = "disabled"; | |
| 218 | 220 | }; |
| 219 | 221 | |
| 220 | 222 | sdio: sdhci@21000 { |
| @@ -257,10 +259,10 @@ · 36 unmodified lines | ||
| 257 | 259 | status = "disabled"; |
| 258 | 260 | }; |
| 259 | 261 | |
| 260 | − mailbox: mailbox@25000 { | |
| 262 | + mailbox: mailbox@25c00 { | |
| 261 | 263 | compatible = "brcm,iproc-fa2-mbox"; |
| 262 | − reg = <0x25000 0x445>; | |
| 263 | − interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; | |
| 264 | + reg = <0x25c00 0x400>; | |
| 265 | + interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; | |
| 264 | 266 | #mbox-cells = <1>; |
| 265 | 267 | brcm,rx-status-len = <32>; |
| 266 | 268 | brcm,use-bcm-hdr; |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | memory { |
| 20 | + device_type = "memory"; | |
| 20 | 21 | reg = <0x00000000 0x08000000 |
| 21 | 22 | 0x88000000 0x18000000>; |
| 22 | 23 | }; |
| @@ -58,6 +58,10 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | /* USB 3 support needed to be complete */ |
| 60 | 60 | |
| 61 | +&dma { | |
| 62 | + status = "okay"; | |
| 63 | +}; | |
| 64 | + | |
| 61 | 65 | &amac0 { |
| 62 | 66 | status = "okay"; |
| 63 | 67 | }; |
| @@ -58,6 +58,10 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | /* USB 3 support needed to be complete */ |
| 60 | 60 | |
| 61 | +&dma { | |
| 62 | + status = "okay"; | |
| 63 | +}; | |
| 64 | + | |
| 61 | 65 | &amac0 { |
| 62 | 66 | status = "okay"; |
| 63 | 67 | }; |
| @@ -58,6 +58,10 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | /* XHCI support needed to be complete */ |
| 60 | 60 | |
| 61 | +&dma { | |
| 62 | + status = "okay"; | |
| 63 | +}; | |
| 64 | + | |
| 61 | 65 | &amac0 { |
| 62 | 66 | status = "okay"; |
| 63 | 67 | }; |
| @@ -58,6 +58,10 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | /* USB 3 and SLIC support needed to be complete */ |
| 60 | 60 | |
| 61 | +&dma { | |
| 62 | + status = "okay"; | |
| 63 | +}; | |
| 64 | + | |
| 61 | 65 | &amac0 { |
| 62 | 66 | status = "okay"; |
| 63 | 67 | }; |
| @@ -58,6 +58,10 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | /* USB 3 and SLIC support needed to be complete */ |
| 60 | 60 | |
| 61 | +&dma { | |
| 62 | + status = "okay"; | |
| 63 | +}; | |
| 64 | + | |
| 61 | 65 | &amac0 { |
| 62 | 66 | status = "okay"; |
| 63 | 67 | }; |
| @@ -69,6 +69,10 @@ · 68 unmodified lines | ||
| 69 | 69 | status = "okay"; |
| 70 | 70 | }; |
| 71 | 71 | |
| 72 | +&dma { | |
| 73 | + status = "okay"; | |
| 74 | +}; | |
| 75 | + | |
| 72 | 76 | &amac0 { |
| 73 | 77 | status = "okay"; |
| 74 | 78 | }; |
| @@ -48,6 +48,10 @@ · 47 unmodified lines | ||
| 48 | 48 | }; |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | +&dma { | |
| 52 | + status = "okay"; | |
| 53 | +}; | |
| 54 | + | |
| 51 | 55 | &amac0 { |
| 52 | 56 | status = "okay"; |
| 53 | 57 | }; |
| @@ -245,26 +245,6 @@ · 244 unmodified lines | ||
| 245 | 245 | rx-num-evt = <32>; |
| 246 | 246 | }; |
| 247 | 247 | |
| 248 | −&mailbox5 { | |
| 249 | − status = "okay"; | |
| 250 | − mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { | |
| 251 | − status = "okay"; | |
| 252 | − }; | |
| 253 | − mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { | |
| 254 | − status = "okay"; | |
| 255 | − }; | |
| 256 | −}; | |
| 257 | − | |
| 258 | −&mailbox6 { | |
| 259 | − status = "okay"; | |
| 260 | − mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { | |
| 261 | − status = "okay"; | |
| 262 | − }; | |
| 263 | − mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { | |
| 264 | − status = "okay"; | |
| 265 | − }; | |
| 266 | −}; | |
| 267 | − | |
| 268 | 248 | &pcie1_rc { |
| 269 | 249 | status = "okay"; |
| 270 | 250 | }; |
| @@ -1207,9 +1207,8 @@ · 1206 unmodified lines | ||
| 1207 | 1207 | <SYSC_IDLE_SMART>, |
| 1208 | 1208 | <SYSC_IDLE_SMART_WKUP>; |
| 1209 | 1209 | /* Domains (P, C): l4per_pwrdm, l4per_clkdm */ |
| 1210 | − clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 0>, | |
| 1211 | − <&timer_sys_clk_div>; | |
| 1212 | − clock-names = "fck", "timer_sys_ck"; | |
| 1210 | + clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 0>; | |
| 1211 | + clock-names = "fck"; | |
| 1213 | 1212 | #address-cells = <1>; |
| 1214 | 1213 | #size-cells = <1>; |
| 1215 | 1214 | ranges = <0x0 0x36000 0x1000>; |
| @@ -3352,8 +3351,8 @@ · 2136 unmodified lines | ||
| 3352 | 3351 | <SYSC_IDLE_SMART>, |
| 3353 | 3352 | <SYSC_IDLE_SMART_WKUP>; |
| 3354 | 3353 | /* Domains (P, C): ipu_pwrdm, ipu_clkdm */ |
| 3355 | − clocks = <&ipu_clkctrl DRA7_IPU_TIMER5_CLKCTRL 0>, <&timer_sys_clk_div>; | |
| 3356 | − clock-names = "fck", "timer_sys_ck"; | |
| 3354 | + clocks = <&ipu_clkctrl DRA7_IPU_TIMER5_CLKCTRL 0>; | |
| 3355 | + clock-names = "fck"; | |
| 3357 | 3356 | #address-cells = <1>; |
| 3358 | 3357 | #size-cells = <1>; |
| 3359 | 3358 | ranges = <0x0 0x20000 0x1000>; |
| @@ -3361,8 +3360,8 @@ · 1 unmodified line | ||
| 3361 | 3360 | timer5: timer@0 { |
| 3362 | 3361 | compatible = "ti,omap5430-timer"; |
| 3363 | 3362 | reg = <0x0 0x80>; |
| 3364 | − clocks = <&ipu_clkctrl DRA7_IPU_TIMER5_CLKCTRL 24>; | |
| 3365 | − clock-names = "fck"; | |
| 3363 | + clocks = <&ipu_clkctrl DRA7_IPU_TIMER5_CLKCTRL 24>, <&timer_sys_clk_div>; | |
| 3364 | + clock-names = "fck", "timer_sys_ck"; | |
| 3366 | 3365 | interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; |
| 3367 | 3366 | }; |
| 3368 | 3367 | }; |
| @@ -3379,9 +3378,8 @@ · 10 unmodified lines | ||
| 3379 | 3378 | <SYSC_IDLE_SMART>, |
| 3380 | 3379 | <SYSC_IDLE_SMART_WKUP>; |
| 3381 | 3380 | /* Domains (P, C): ipu_pwrdm, ipu_clkdm */ |
| 3382 | − clocks = <&ipu_clkctrl DRA7_IPU_TIMER6_CLKCTRL 0>, | |
| 3383 | − <&timer_sys_clk_div>; | |
| 3384 | − clock-names = "fck", "timer_sys_ck"; | |
| 3381 | + clocks = <&ipu_clkctrl DRA7_IPU_TIMER6_CLKCTRL 0>; | |
| 3382 | + clock-names = "fck"; | |
| 3385 | 3383 | #address-cells = <1>; |
| 3386 | 3384 | #size-cells = <1>; |
| 3387 | 3385 | ranges = <0x0 0x22000 0x1000>; |
| @@ -3389,8 +3387,8 @@ · 1 unmodified line | ||
| 3389 | 3387 | timer6: timer@0 { |
| 3390 | 3388 | compatible = "ti,omap5430-timer"; |
| 3391 | 3389 | reg = <0x0 0x80>; |
| 3392 | − clocks = <&ipu_clkctrl DRA7_IPU_TIMER6_CLKCTRL 24>; | |
| 3393 | − clock-names = "fck"; | |
| 3390 | + clocks = <&ipu_clkctrl DRA7_IPU_TIMER6_CLKCTRL 24>, <&timer_sys_clk_div>; | |
| 3391 | + clock-names = "fck", "timer_sys_ck"; | |
| 3394 | 3392 | interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; |
| 3395 | 3393 | }; |
| 3396 | 3394 | }; |
| @@ -3498,8 +3496,8 @@ · 101 unmodified lines | ||
| 3498 | 3496 | timer14: timer@0 { |
| 3499 | 3497 | compatible = "ti,omap5430-timer"; |
| 3500 | 3498 | reg = <0x0 0x80>; |
| 3501 | − clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER14_CLKCTRL 24>; | |
| 3502 | − clock-names = "fck"; | |
| 3499 | + clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER14_CLKCTRL 24>, <&timer_sys_clk_div>; | |
| 3500 | + clock-names = "fck", "timer_sys_ck"; | |
| 3503 | 3501 | interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>; |
| 3504 | 3502 | ti,timer-pwm; |
| 3505 | 3503 | }; |
| @@ -3526,8 +3524,8 @@ · 20 unmodified lines | ||
| 3526 | 3524 | timer15: timer@0 { |
| 3527 | 3525 | compatible = "ti,omap5430-timer"; |
| 3528 | 3526 | reg = <0x0 0x80>; |
| 3529 | − clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>; | |
| 3530 | − clock-names = "fck"; | |
| 3527 | + clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>, <&timer_sys_clk_div>; | |
| 3528 | + clock-names = "fck", "timer_sys_ck"; | |
| 3531 | 3529 | interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>; |
| 3532 | 3530 | ti,timer-pwm; |
| 3533 | 3531 | }; |
| @@ -3554,8 +3552,8 @@ · 20 unmodified lines | ||
| 3554 | 3552 | timer16: timer@0 { |
| 3555 | 3553 | compatible = "ti,omap5430-timer"; |
| 3556 | 3554 | reg = <0x0 0x80>; |
| 3557 | − clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>; | |
| 3558 | − clock-names = "fck"; | |
| 3555 | + clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>, <&timer_sys_clk_div>; | |
| 3556 | + clock-names = "fck", "timer_sys_ck"; | |
| 3559 | 3557 | interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>; |
| 3560 | 3558 | ti,timer-pwm; |
| 3561 | 3559 | }; |
| @@ -232,13 +232,6 @@ · 231 unmodified lines | ||
| 232 | 232 | status = "okay"; |
| 233 | 233 | }; |
| 234 | 234 | |
| 235 | −&wdog1 { | |
| 236 | − pinctrl-names = "default"; | |
| 237 | − pinctrl-0 = <&pinctrl_wdog>; | |
| 238 | − fsl,ext-reset-output; | |
| 239 | − status = "okay"; | |
| 240 | −}; | |
| 241 | − | |
| 242 | 235 | &iomuxc { |
| 243 | 236 | pinctrl-0 = <&pinctrl_reset_out &pinctrl_gpio>; |
| 244 | 237 | |
| @@ -409,10 +402,4 @@ · 164 unmodified lines | ||
| 409 | 402 | MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9 |
| 410 | 403 | >; |
| 411 | 404 | }; |
| 412 | − | |
| 413 | − pinctrl_wdog: wdoggrp { | |
| 414 | − fsl,pins = < | |
| 415 | − MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY 0x30b0 | |
| 416 | − >; | |
| 417 | − }; | |
| 418 | 405 | }; |
| @@ -57,6 +57,13 @@ · 56 unmodified lines | ||
| 57 | 57 | status = "okay"; |
| 58 | 58 | }; |
| 59 | 59 | |
| 60 | +&wdog1 { | |
| 61 | + pinctrl-names = "default"; | |
| 62 | + pinctrl-0 = <&pinctrl_wdog>; | |
| 63 | + fsl,ext-reset-output; | |
| 64 | + status = "okay"; | |
| 65 | +}; | |
| 66 | + | |
| 60 | 67 | &iomuxc { |
| 61 | 68 | pinctrl-names = "default"; |
| 62 | 69 | pinctrl-0 = <&pinctrl_reset_out>; |
| @@ -106,4 +113,10 @@ · 43 unmodified lines | ||
| 106 | 113 | MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x1b0b0 |
| 107 | 114 | >; |
| 108 | 115 | }; |
| 116 | + | |
| 117 | + pinctrl_wdog: wdoggrp { | |
| 118 | + fsl,pins = < | |
| 119 | + MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY 0x18b0 | |
| 120 | + >; | |
| 121 | + }; | |
| 109 | 122 | }; |
| @@ -13,8 +13,10 @@ · 12 unmodified lines | ||
| 13 | 13 | #interrupt-cells = <2>; |
| 14 | 14 | #address-cells = <1>; |
| 15 | 15 | #size-cells = <0>; |
| 16 | − spi-max-frequency = <3000000>; | |
| 16 | + spi-max-frequency = <9600000>; | |
| 17 | 17 | spi-cs-high; |
| 18 | + spi-cpol; | |
| 19 | + spi-cpha; | |
| 18 | 20 | |
| 19 | 21 | cpcap_adc: adc { |
| 20 | 22 | compatible = "motorola,mapphone-cpcap-adc"; |
| @@ -139,7 +139,7 @@ · 138 unmodified lines | ||
| 139 | 139 | ethernet@gpmc { |
| 140 | 140 | reg = <5 0 0xff>; |
| 141 | 141 | interrupt-parent = <&gpio2>; |
| 142 | − interrupts = <12 IRQ_TYPE_EDGE_FALLING>; /* gpio_44 */ | |
| 142 | + interrupts = <12 IRQ_TYPE_LEVEL_LOW>; /* gpio_44 */ | |
| 143 | 143 | |
| 144 | 144 | phy-mode = "mii"; |
| 145 | 145 | |
| @@ -662,6 +662,6 @@ · 661 unmodified lines | ||
| 662 | 662 | ti,no-idle; |
| 663 | 663 | timer@0 { |
| 664 | 664 | assigned-clocks = <&l4_wkup_clkctrl OMAP4_TIMER1_CLKCTRL 24>; |
| 665 | − assigned-clock-parents = <&sys_clkin_ck>; | |
| 665 | + assigned-clock-parents = <&sys_32k_ck>; | |
| 666 | 666 | }; |
| 667 | 667 | }; |
| @@ -100,79 +100,6 @@ · 99 unmodified lines | ||
| 100 | 100 | }; |
| 101 | 101 | }; |
| 102 | 102 | |
| 103 | − mcc { | |
| 104 | − compatible = "arm,vexpress,config-bus"; | |
| 105 | − arm,vexpress,config-bridge = <&v2m_sysreg>; | |
| 106 | − | |
| 107 | − oscclk0 { | |
| 108 | − /* MCC static memory clock */ | |
| 109 | − compatible = "arm,vexpress-osc"; | |
| 110 | − arm,vexpress-sysreg,func = <1 0>; | |
| 111 | − freq-range = <25000000 60000000>; | |
| 112 | − #clock-cells = <0>; | |
| 113 | − clock-output-names = "v2m:oscclk0"; | |
| 114 | − }; | |
| 115 | − | |
| 116 | − v2m_oscclk1: oscclk1 { | |
| 117 | − /* CLCD clock */ | |
| 118 | − compatible = "arm,vexpress-osc"; | |
| 119 | − arm,vexpress-sysreg,func = <1 1>; | |
| 120 | − freq-range = <23750000 65000000>; | |
| 121 | − #clock-cells = <0>; | |
| 122 | − clock-output-names = "v2m:oscclk1"; | |
| 123 | − }; | |
| 124 | − | |
| 125 | − v2m_oscclk2: oscclk2 { | |
| 126 | − /* IO FPGA peripheral clock */ | |
| 127 | − compatible = "arm,vexpress-osc"; | |
| 128 | − arm,vexpress-sysreg,func = <1 2>; | |
| 129 | − freq-range = <24000000 24000000>; | |
| 130 | − #clock-cells = <0>; | |
| 131 | − clock-output-names = "v2m:oscclk2"; | |
| 132 | − }; | |
| 133 | − | |
| 134 | − volt-vio { | |
| 135 | − /* Logic level voltage */ | |
| 136 | − compatible = "arm,vexpress-volt"; | |
| 137 | − arm,vexpress-sysreg,func = <2 0>; | |
| 138 | − regulator-name = "VIO"; | |
| 139 | − regulator-always-on; | |
| 140 | − label = "VIO"; | |
| 141 | − }; | |
| 142 | − | |
| 143 | − temp-mcc { | |
| 144 | − /* MCC internal operating temperature */ | |
| 145 | − compatible = "arm,vexpress-temp"; | |
| 146 | − arm,vexpress-sysreg,func = <4 0>; | |
| 147 | − label = "MCC"; | |
| 148 | − }; | |
| 149 | − | |
| 150 | − reset { | |
| 151 | − compatible = "arm,vexpress-reset"; | |
| 152 | − arm,vexpress-sysreg,func = <5 0>; | |
| 153 | − }; | |
| 154 | − | |
| 155 | − muxfpga { | |
| 156 | − compatible = "arm,vexpress-muxfpga"; | |
| 157 | − arm,vexpress-sysreg,func = <7 0>; | |
| 158 | − }; | |
| 159 | − | |
| 160 | − shutdown { | |
| 161 | − compatible = "arm,vexpress-shutdown"; | |
| 162 | − arm,vexpress-sysreg,func = <8 0>; | |
| 163 | − }; | |
| 164 | − | |
| 165 | − reboot { | |
| 166 | − compatible = "arm,vexpress-reboot"; | |
| 167 | − arm,vexpress-sysreg,func = <9 0>; | |
| 168 | − }; | |
| 169 | − | |
| 170 | − dvimode { | |
| 171 | − compatible = "arm,vexpress-dvimode"; | |
| 172 | − arm,vexpress-sysreg,func = <11 0>; | |
| 173 | − }; | |
| 174 | − }; | |
| 175 | − | |
| 176 | 103 | bus@8000000 { |
| 177 | 104 | motherboard-bus { |
| 178 | 105 | model = "V2M-P1"; |
| @@ -435,6 +362,79 @@ · 256 unmodified lines | ||
| 435 | 362 | }; |
| 436 | 363 | }; |
| 437 | 364 | }; |
| 365 | + | |
| 366 | + mcc { | |
| 367 | + compatible = "arm,vexpress,config-bus"; | |
| 368 | + arm,vexpress,config-bridge = <&v2m_sysreg>; | |
| 369 | + | |
| 370 | + oscclk0 { | |
| 371 | + /* MCC static memory clock */ | |
| 372 | + compatible = "arm,vexpress-osc"; | |
| 373 | + arm,vexpress-sysreg,func = <1 0>; | |
| 374 | + freq-range = <25000000 60000000>; | |
| 375 | + #clock-cells = <0>; | |
| 376 | + clock-output-names = "v2m:oscclk0"; | |
| 377 | + }; | |
| 378 | + | |
| 379 | + v2m_oscclk1: oscclk1 { | |
| 380 | + /* CLCD clock */ | |
| 381 | + compatible = "arm,vexpress-osc"; | |
| 382 | + arm,vexpress-sysreg,func = <1 1>; | |
| 383 | + freq-range = <23750000 65000000>; | |
| 384 | + #clock-cells = <0>; | |
| 385 | + clock-output-names = "v2m:oscclk1"; | |
| 386 | + }; | |
| 387 | + | |
| 388 | + v2m_oscclk2: oscclk2 { | |
| 389 | + /* IO FPGA peripheral clock */ | |
| 390 | + compatible = "arm,vexpress-osc"; | |
| 391 | + arm,vexpress-sysreg,func = <1 2>; | |
| 392 | + freq-range = <24000000 24000000>; | |
| 393 | + #clock-cells = <0>; | |
| 394 | + clock-output-names = "v2m:oscclk2"; | |
| 395 | + }; | |
| 396 | + | |
| 397 | + volt-vio { | |
| 398 | + /* Logic level voltage */ | |
| 399 | + compatible = "arm,vexpress-volt"; | |
| 400 | + arm,vexpress-sysreg,func = <2 0>; | |
| 401 | + regulator-name = "VIO"; | |
| 402 | + regulator-always-on; | |
| 403 | + label = "VIO"; | |
| 404 | + }; | |
| 405 | + | |
| 406 | + temp-mcc { | |
| 407 | + /* MCC internal operating temperature */ | |
| 408 | + compatible = "arm,vexpress-temp"; | |
| 409 | + arm,vexpress-sysreg,func = <4 0>; | |
| 410 | + label = "MCC"; | |
| 411 | + }; | |
| 412 | + | |
| 413 | + reset { | |
| 414 | + compatible = "arm,vexpress-reset"; | |
| 415 | + arm,vexpress-sysreg,func = <5 0>; | |
| 416 | + }; | |
| 417 | + | |
| 418 | + muxfpga { | |
| 419 | + compatible = "arm,vexpress-muxfpga"; | |
| 420 | + arm,vexpress-sysreg,func = <7 0>; | |
| 421 | + }; | |
| 422 | + | |
| 423 | + shutdown { | |
| 424 | + compatible = "arm,vexpress-shutdown"; | |
| 425 | + arm,vexpress-sysreg,func = <8 0>; | |
| 426 | + }; | |
| 427 | + | |
| 428 | + reboot { | |
| 429 | + compatible = "arm,vexpress-reboot"; | |
| 430 | + arm,vexpress-sysreg,func = <9 0>; | |
| 431 | + }; | |
| 432 | + | |
| 433 | + dvimode { | |
| 434 | + compatible = "arm,vexpress-dvimode"; | |
| 435 | + arm,vexpress-sysreg,func = <11 0>; | |
| 436 | + }; | |
| 437 | + }; | |
| 438 | 438 | }; |
| 439 | 439 | }; |
| 440 | 440 | }; |
| @@ -87,4 +87,11 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, · 86 unmodified lines | ||
| 87 | 87 | return dram_base + SZ_512M; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | +struct efi_arm_entry_state { | |
| 91 | + u32 cpsr_before_ebs; | |
| 92 | + u32 sctlr_before_ebs; | |
| 93 | + u32 cpsr_after_ebs; | |
| 94 | + u32 sctlr_after_ebs; | |
| 95 | +}; | |
| 96 | + | |
| 90 | 97 | #endif /* _ASM_ARM_EFI_H */ |
| @@ -84,7 +84,8 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, · 83 unmodified lines | ||
| 84 | 84 | old = __opcode_to_mem_arm(old); |
| 85 | 85 | |
| 86 | 86 | if (validate) { |
| 87 | − if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) | |
| 87 | + if (copy_from_kernel_nofault(&replaced, (void *)pc, | |
| 88 | + MCOUNT_INSN_SIZE)) | |
| 88 | 89 | return -EFAULT; |
| 89 | 90 | |
| 90 | 91 | if (replaced != old) |
| @@ -236,7 +236,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) · 235 unmodified lines | ||
| 236 | 236 | /* patch_text() only supports int-sized breakpoints */ |
| 237 | 237 | BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE); |
| 238 | 238 | |
| 239 | − err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, | |
| 239 | + err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr, | |
| 240 | 240 | BREAK_INSTR_SIZE); |
| 241 | 241 | if (err) |
| 242 | 242 | return err; |
| @@ -396,7 +396,7 @@ int is_valid_bugaddr(unsigned long pc) · 395 unmodified lines | ||
| 396 | 396 | u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE); |
| 397 | 397 | #endif |
| 398 | 398 | |
| 399 | − if (probe_kernel_address((unsigned *)pc, bkpt)) | |
| 399 | + if (get_kernel_nofault(bkpt, (void *)pc)) | |
| 400 | 400 | return 0; |
| 401 | 401 | |
| 402 | 402 | return bkpt == insn; |
| @@ -53,6 +53,7 @@ config ARCH_BCM_NSP · 52 unmodified lines | ||
| 53 | 53 | select ARM_ERRATA_754322 |
| 54 | 54 | select ARM_ERRATA_775420 |
| 55 | 55 | select ARM_ERRATA_764369 if SMP |
| 56 | + select ARM_TIMER_SP804 | |
| 56 | 57 | select THERMAL |
| 57 | 58 | select THERMAL_OF |
| 58 | 59 | help |
| @@ -295,14 +295,14 @@ static int __init imx_suspend_alloc_ocram( · 294 unmodified lines | ||
| 295 | 295 | if (!ocram_pool) { |
| 296 | 296 | pr_warn("%s: ocram pool unavailable!\n", __func__); |
| 297 | 297 | ret = -ENODEV; |
| 298 | − goto put_node; | |
| 298 | + goto put_device; | |
| 299 | 299 | } |
| 300 | 300 | |
| 301 | 301 | ocram_base = gen_pool_alloc(ocram_pool, size); |
| 302 | 302 | if (!ocram_base) { |
| 303 | 303 | pr_warn("%s: unable to alloc ocram!\n", __func__); |
| 304 | 304 | ret = -ENOMEM; |
| 305 | − goto put_node; | |
| 305 | + goto put_device; | |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | 308 | phys = gen_pool_virt_to_phys(ocram_pool, ocram_base); |
| @@ -312,6 +312,8 @@ static int __init imx_suspend_alloc_ocram( · 3 unmodified lines | ||
| 312 | 312 | if (virt_out) |
| 313 | 313 | *virt_out = virt; |
| 314 | 314 | |
| 315 | +put_device: | |
| 316 | + put_device(&pdev->dev); | |
| 315 | 317 | put_node: |
| 316 | 318 | of_node_put(node); |
| 317 | 319 | |
| @@ -493,14 +493,14 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) · 492 unmodified lines | ||
| 493 | 493 | if (!ocram_pool) { |
| 494 | 494 | pr_warn("%s: ocram pool unavailable!\n", __func__); |
| 495 | 495 | ret = -ENODEV; |
| 496 | − goto put_node; | |
| 496 | + goto put_device; | |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | 499 | ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE); |
| 500 | 500 | if (!ocram_base) { |
| 501 | 501 | pr_warn("%s: unable to alloc ocram!\n", __func__); |
| 502 | 502 | ret = -ENOMEM; |
| 503 | − goto put_node; | |
| 503 | + goto put_device; | |
| 504 | 504 | } |
| 505 | 505 | |
| 506 | 506 | ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base); |
| @@ -523,7 +523,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) · 16 unmodified lines | ||
| 523 | 523 | ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat); |
| 524 | 524 | if (ret) { |
| 525 | 525 | pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret); |
| 526 | − goto put_node; | |
| 526 | + goto put_device; | |
| 527 | 527 | } |
| 528 | 528 | |
| 529 | 529 | ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat); |
| @@ -570,7 +570,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) · 40 unmodified lines | ||
| 570 | 570 | &imx6_suspend, |
| 571 | 571 | MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info)); |
| 572 | 572 | |
| 573 | − goto put_node; | |
| 573 | + goto put_device; | |
| 574 | 574 | |
| 575 | 575 | pl310_cache_map_failed: |
| 576 | 576 | iounmap(pm_info->gpc_base.vbase); |
| @@ -580,6 +580,8 @@ iomuxc_map_failed: · 3 unmodified lines | ||
| 580 | 580 | iounmap(pm_info->src_base.vbase); |
| 581 | 581 | src_map_failed: |
| 582 | 582 | iounmap(pm_info->mmdc_base.vbase); |
| 583 | +put_device: | |
| 584 | + put_device(&pdev->dev); | |
| 583 | 585 | put_node: |
| 584 | 586 | of_node_put(node); |
| 585 | 587 | |
| @@ -3489,7 +3489,7 @@ static const struct omap_hwmod_reset dra7_reset_quirks[] = { · 3488 unmodified lines | ||
| 3489 | 3489 | }; |
| 3490 | 3490 | |
| 3491 | 3491 | static const struct omap_hwmod_reset omap_reset_quirks[] = { |
| 3492 | − { .match = "dss", .len = 3, .reset = omap_dss_reset, }, | |
| 3492 | + { .match = "dss_core", .len = 8, .reset = omap_dss_reset, }, | |
| 3493 | 3493 | { .match = "hdq1w", .len = 5, .reset = omap_hdq1w_reset, }, |
| 3494 | 3494 | { .match = "i2c", .len = 3, .reset = omap_i2c_reset, }, |
| 3495 | 3495 | { .match = "wd_timer", .len = 8, .reset = omap2_wd_timer_reset, }, |
| @@ -20,14 +20,6 @@ static const char *const stih41x_dt_match[] __initconst = { · 19 unmodified lines | ||
| 20 | 20 | NULL |
| 21 | 21 | }; |
| 22 | 22 | |
| 23 | −static void sti_l2_write_sec(unsigned long val, unsigned reg) | |
| 24 | −{ | |
| 25 | − /* | |
| 26 | − * We can't write to secure registers as we are in non-secure | |
| 27 | − * mode, until we have some SMI service available. | |
| 28 | − */ | |
| 29 | −} | |
| 30 | − | |
| 31 | 23 | DT_MACHINE_START(STM, "STi SoC with Flattened Device Tree") |
| 32 | 24 | .dt_compat = stih41x_dt_match, |
| 33 | 25 | .l2c_aux_val = L2C_AUX_CTRL_SHARED_OVERRIDE | |
| @@ -36,5 +28,4 @@ DT_MACHINE_START(STM, "STi SoC with Flattened Device Tree") · 2 unmodified lines | ||
| 36 | 28 | L2C_AUX_CTRL_WAY_SIZE(4), |
| 37 | 29 | .l2c_aux_mask = 0xc0000fff, |
| 38 | 30 | .smp = smp_ops(sti_smp_ops), |
| 39 | − .l2c_write_sec = sti_l2_write_sec, | |
| 40 | 31 | MACHINE_END |
| @@ -774,7 +774,7 @@ static int alignment_get_arm(struct pt_regs *regs, u32 *ip, u32 *inst) · 773 unmodified lines | ||
| 774 | 774 | if (user_mode(regs)) |
| 775 | 775 | fault = get_user(instr, ip); |
| 776 | 776 | else |
| 777 | − fault = probe_kernel_address(ip, instr); | |
| 777 | + fault = get_kernel_nofault(instr, ip); | |
| 778 | 778 | |
| 779 | 779 | *inst = __mem_to_opcode_arm(instr); |
| 780 | 780 | |
| @@ -789,7 +789,7 @@ static int alignment_get_thumb(struct pt_regs *regs, u16 *ip, u16 *inst) · 8 unmodified lines | ||
| 789 | 789 | if (user_mode(regs)) |
| 790 | 790 | fault = get_user(instr, ip); |
| 791 | 791 | else |
| 792 | − fault = probe_kernel_address(ip, instr); | |
| 792 | + fault = get_kernel_nofault(instr, ip); | |
| 793 | 793 | |
| 794 | 794 | *inst = __mem_to_opcode_thumb16(instr); |
| 795 | 795 | |
| @@ -241,7 +241,6 @@ static int __init fdt_find_hyper_node(unsigned long node, const char *uname, · 240 unmodified lines | ||
| 241 | 241 | * see Documentation/devicetree/bindings/arm/xen.txt for the |
| 242 | 242 | * documentation of the Xen Device Tree format. |
| 243 | 243 | */ |
| 244 | −#define GRANT_TABLE_PHYSADDR 0 | |
| 245 | 244 | void __init xen_early_init(void) |
| 246 | 245 | { |
| 247 | 246 | of_scan_flat_dt(fdt_find_hyper_node, NULL); |
| @@ -1518,9 +1518,9 @@ config ARM64_PTR_AUTH · 1517 unmodified lines | ||
| 1518 | 1518 | default y |
| 1519 | 1519 | depends on !KVM || ARM64_VHE |
| 1520 | 1520 | depends on (CC_HAS_SIGN_RETURN_ADDRESS || CC_HAS_BRANCH_PROT_PAC_RET) && AS_HAS_PAC |
| 1521 | − # GCC 9.1 and later inserts a .note.gnu.property section note for PAC | |
| 1521 | + # Modern compilers insert a .note.gnu.property section note for PAC | |
| 1522 | 1522 | # which is only understood by binutils starting with version 2.33.1. |
| 1523 | − depends on !CC_IS_GCC || GCC_VERSION < 90100 || LD_VERSION >= 233010000 | |
| 1523 | + depends on LD_IS_LLD || LD_VERSION >= 233010000 || (CC_IS_GCC && GCC_VERSION < 90100) | |
| 1524 | 1524 | depends on !CC_IS_CLANG || AS_HAS_CFI_NEGATE_RA_STATE |
| 1525 | 1525 | depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS) |
| 1526 | 1526 | help |
| @@ -1564,7 +1564,7 @@ config CC_HAS_SIGN_RETURN_ADDRESS · 37 unmodified lines | ||
| 1564 | 1564 | def_bool $(cc-option,-msign-return-address=all) |
| 1565 | 1565 | |
| 1566 | 1566 | config AS_HAS_PAC |
| 1567 | − def_bool $(as-option,-Wa$(comma)-march=armv8.3-a) | |
| 1567 | + def_bool $(cc-option,-Wa$(comma)-march=armv8.3-a) | |
| 1568 | 1568 | |
| 1569 | 1569 | config AS_HAS_CFI_NEGATE_RA_STATE |
| 1570 | 1570 | def_bool $(as-instr,.cfi_startproc\n.cfi_negate_ra_state\n.cfi_endproc\n) |
| @@ -1630,6 +1630,8 @@ config ARM64_BTI_KERNEL · 59 unmodified lines | ||
| 1630 | 1630 | depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI |
| 1631 | 1631 | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697 |
| 1632 | 1632 | depends on !CC_IS_GCC || GCC_VERSION >= 100100 |
| 1633 | + # https://reviews.llvm.org/rGb8ae3fdfa579dbf366b1bb1cbfdbf8c51db7fa55 | |
| 1634 | + depends on !CC_IS_CLANG || CLANG_VERSION >= 100001 | |
| 1633 | 1635 | depends on !(CC_IS_CLANG && GCOV_KERNEL) |
| 1634 | 1636 | depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS) |
| 1635 | 1637 | help |
| @@ -8,21 +8,6 @@ config PID_IN_CONTEXTIDR · 7 unmodified lines | ||
| 8 | 8 | instructions during context switch. Say Y here only if you are |
| 9 | 9 | planning to use hardware trace tools with this kernel. |
| 10 | 10 | |
| 11 | −config ARM64_RANDOMIZE_TEXT_OFFSET | |
| 12 | − bool "Randomize TEXT_OFFSET at build time" | |
| 13 | − help | |
| 14 | − Say Y here if you want the image load offset (AKA TEXT_OFFSET) | |
| 15 | − of the kernel to be randomized at build-time. When selected, | |
| 16 | − this option will cause TEXT_OFFSET to be randomized upon any | |
| 17 | − build of the kernel, and the offset will be reflected in the | |
| 18 | − text_offset field of the resulting Image. This can be used to | |
| 19 | − fuzz-test bootloaders which respect text_offset. | |
| 20 | − | |
| 21 | − This option is intended for bootloader and/or kernel testing | |
| 22 | − only. Bootloaders must make no assumptions regarding the value | |
| 23 | − of TEXT_OFFSET and platforms must not require a specific | |
| 24 | − value. | |
| 25 | − | |
| 26 | 11 | config DEBUG_EFI |
| 27 | 12 | depends on EFI && DEBUG_INFO |
| 28 | 13 | bool "UEFI debugging" |
| @@ -121,13 +121,7 @@ endif · 120 unmodified lines | ||
| 121 | 121 | head-y := arch/arm64/kernel/head.o |
| 122 | 122 | |
| 123 | 123 | # The byte offset of the kernel image in RAM from the start of RAM. |
| 124 | −ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) | |
| 125 | −TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \ | |
| 126 | − int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \ | |
| 127 | − rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}") | |
| 128 | −else | |
| 129 | 124 | TEXT_OFFSET := 0x0 |
| 130 | −endif | |
| 131 | 125 | |
| 132 | 126 | ifeq ($(CONFIG_KASAN_SW_TAGS), y) |
| 133 | 127 | KASAN_SHADOW_SCALE_SHIFT := 4 |
| @@ -136,7 +136,7 @@ · 135 unmodified lines | ||
| 136 | 136 | |
| 137 | 137 | ldo1_reg: LDO1 { |
| 138 | 138 | regulator-name = "LDO1"; |
| 139 | − regulator-min-microvolt = <3000000>; | |
| 139 | + regulator-min-microvolt = <1600000>; | |
| 140 | 140 | regulator-max-microvolt = <3300000>; |
| 141 | 141 | regulator-boot-on; |
| 142 | 142 | regulator-always-on; |
| @@ -144,7 +144,7 @@ · 1 unmodified line | ||
| 144 | 144 | |
| 145 | 145 | ldo2_reg: LDO2 { |
| 146 | 146 | regulator-name = "LDO2"; |
| 147 | − regulator-min-microvolt = <900000>; | |
| 147 | + regulator-min-microvolt = <800000>; | |
| 148 | 148 | regulator-max-microvolt = <900000>; |
| 149 | 149 | regulator-boot-on; |
| 150 | 150 | regulator-always-on; |
| @@ -208,7 +208,7 @@ · 207 unmodified lines | ||
| 208 | 208 | |
| 209 | 209 | ldo1_reg: LDO1 { |
| 210 | 210 | regulator-name = "LDO1"; |
| 211 | − regulator-min-microvolt = <3000000>; | |
| 211 | + regulator-min-microvolt = <1600000>; | |
| 212 | 212 | regulator-max-microvolt = <3300000>; |
| 213 | 213 | regulator-boot-on; |
| 214 | 214 | regulator-always-on; |
| @@ -216,7 +216,7 @@ · 1 unmodified line | ||
| 216 | 216 | |
| 217 | 217 | ldo2_reg: LDO2 { |
| 218 | 218 | regulator-name = "LDO2"; |
| 219 | − regulator-min-microvolt = <900000>; | |
| 219 | + regulator-min-microvolt = <800000>; | |
| 220 | 220 | regulator-max-microvolt = <900000>; |
| 221 | 221 | regulator-boot-on; |
| 222 | 222 | regulator-always-on; |
| @@ -113,7 +113,7 @@ · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | ldo1_reg: LDO1 { |
| 115 | 115 | regulator-name = "LDO1"; |
| 116 | − regulator-min-microvolt = <3000000>; | |
| 116 | + regulator-min-microvolt = <1600000>; | |
| 117 | 117 | regulator-max-microvolt = <3300000>; |
| 118 | 118 | regulator-boot-on; |
| 119 | 119 | regulator-always-on; |
| @@ -121,7 +121,7 @@ · 1 unmodified line | ||
| 121 | 121 | |
| 122 | 122 | ldo2_reg: LDO2 { |
| 123 | 123 | regulator-name = "LDO2"; |
| 124 | − regulator-min-microvolt = <900000>; | |
| 124 | + regulator-min-microvolt = <800000>; | |
| 125 | 125 | regulator-max-microvolt = <900000>; |
| 126 | 126 | regulator-boot-on; |
| 127 | 127 | regulator-always-on; |
| @@ -73,11 +73,11 @@ static inline void apply_alternatives_module(void *start, size_t length) { } · 72 unmodified lines | ||
| 73 | 73 | ".pushsection .altinstructions,\"a\"\n" \ |
| 74 | 74 | ALTINSTR_ENTRY(feature) \ |
| 75 | 75 | ".popsection\n" \ |
| 76 | − ".pushsection .altinstr_replacement, \"a\"\n" \ | |
| 76 | + ".subsection 1\n" \ | |
| 77 | 77 | "663:\n\t" \ |
| 78 | 78 | newinstr "\n" \ |
| 79 | 79 | "664:\n\t" \ |
| 80 | − ".popsection\n\t" \ | |
| 80 | + ".previous\n\t" \ | |
| 81 | 81 | ".org . - (664b-663b) + (662b-661b)\n\t" \ |
| 82 | 82 | ".org . - (662b-661b) + (664b-663b)\n" \ |
| 83 | 83 | ".endif\n" |
| @@ -117,9 +117,9 @@ static inline void apply_alternatives_module(void *start, size_t length) { } · 33 unmodified lines | ||
| 117 | 117 | 662: .pushsection .altinstructions, "a" |
| 118 | 118 | altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f |
| 119 | 119 | .popsection |
| 120 | − .pushsection .altinstr_replacement, "ax" | |
| 120 | + .subsection 1 | |
| 121 | 121 | 663: \insn2 |
| 122 | −664: .popsection | |
| 122 | +664: .previous | |
| 123 | 123 | .org . - (664b-663b) + (662b-661b) |
| 124 | 124 | .org . - (662b-661b) + (664b-663b) |
| 125 | 125 | .endif |
| @@ -160,7 +160,7 @@ static inline void apply_alternatives_module(void *start, size_t length) { } · 34 unmodified lines | ||
| 160 | 160 | .pushsection .altinstructions, "a" |
| 161 | 161 | altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f |
| 162 | 162 | .popsection |
| 163 | − .pushsection .altinstr_replacement, "ax" | |
| 163 | + .subsection 1 | |
| 164 | 164 | .align 2 /* So GAS knows label 661 is suitably aligned */ |
| 165 | 165 | 661: |
| 166 | 166 | .endm |
| @@ -179,9 +179,9 @@ static inline void apply_alternatives_module(void *start, size_t length) { } · 12 unmodified lines | ||
| 179 | 179 | .macro alternative_else |
| 180 | 180 | 662: |
| 181 | 181 | .if .Lasm_alt_mode==0 |
| 182 | − .pushsection .altinstr_replacement, "ax" | |
| 182 | + .subsection 1 | |
| 183 | 183 | .else |
| 184 | − .popsection | |
| 184 | + .previous | |
| 185 | 185 | .endif |
| 186 | 186 | 663: |
| 187 | 187 | .endm |
| @@ -192,7 +192,7 @@ static inline void apply_alternatives_module(void *start, size_t length) { } · 4 unmodified lines | ||
| 192 | 192 | .macro alternative_endif |
| 193 | 193 | 664: |
| 194 | 194 | .if .Lasm_alt_mode==0 |
| 195 | − .popsection | |
| 195 | + .previous | |
| 196 | 196 | .endif |
| 197 | 197 | .org . - (664b-663b) + (662b-661b) |
| 198 | 198 | .org . - (662b-661b) + (664b-663b) |
| @@ -86,6 +86,7 @@ · 85 unmodified lines | ||
| 86 | 86 | #define QCOM_CPU_PART_FALKOR 0xC00 |
| 87 | 87 | #define QCOM_CPU_PART_KRYO 0x200 |
| 88 | 88 | #define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803 |
| 89 | +#define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804 | |
| 89 | 90 | #define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805 |
| 90 | 91 | |
| 91 | 92 | #define NVIDIA_CPU_PART_DENVER 0x003 |
| @@ -114,6 +115,7 @@ · 22 unmodified lines | ||
| 114 | 115 | #define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) |
| 115 | 116 | #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) |
| 116 | 117 | #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER) |
| 118 | +#define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD) | |
| 117 | 119 | #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER) |
| 118 | 120 | #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER) |
| 119 | 121 | #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | * instead. |
| 13 | 13 | */ |
| 14 | 14 | #define BTI_C hint 34 ; |
| 15 | −#define BTI_J hint 36 ; | |
| 16 | 15 | |
| 17 | 16 | /* |
| 18 | 17 | * When using in-kernel BTI we need to ensure that PCS-conformant assembly |
| @@ -43,11 +42,6 @@ · 24 unmodified lines | ||
| 43 | 42 | SYM_START(name, SYM_L_WEAK, SYM_A_NONE) \ |
| 44 | 43 | BTI_C |
| 45 | 44 | |
| 46 | −#define SYM_INNER_LABEL(name, linkage) \ | |
| 47 | − .type name SYM_T_NONE ASM_NL \ | |
| 48 | − SYM_ENTRY(name, linkage, SYM_A_NONE) \ | |
| 49 | − BTI_J | |
| 50 | − | |
| 51 | 45 | #endif |
| 52 | 46 | |
| 53 | 47 | /* |
| @@ -19,6 +19,9 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | typedef struct { |
| 21 | 21 | atomic64_t id; |
| 22 | +#ifdef CONFIG_COMPAT | |
| 23 | + void *sigpage; | |
| 24 | +#endif | |
| 22 | 25 | void *vdso; |
| 23 | 26 | unsigned long flags; |
| 24 | 27 | } mm_context_t; |
| @@ -416,7 +416,7 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd) · 415 unmodified lines | ||
| 416 | 416 | __pgprot((pgprot_val(prot) & ~(mask)) | (bits)) |
| 417 | 417 | |
| 418 | 418 | #define pgprot_nx(prot) \ |
| 419 | − __pgprot_modify(prot, 0, PTE_PXN) | |
| 419 | + __pgprot_modify(prot, PTE_MAYBE_GP, PTE_PXN) | |
| 420 | 420 | |
| 421 | 421 | /* |
| 422 | 422 | * Mark the prot value as uncacheable and unbufferable. |
| @@ -29,9 +29,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ |
| 31 | 31 | sys_compat.o |
| 32 | −ifneq ($(CONFIG_COMPAT_VDSO), y) | |
| 33 | 32 | obj-$(CONFIG_COMPAT) += sigreturn32.o |
| 34 | −endif | |
| 35 | 33 | obj-$(CONFIG_KUSER_HELPERS) += kuser32.o |
| 36 | 34 | obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o |
| 37 | 35 | obj-$(CONFIG_MODULES) += module.o |
| @@ -460,6 +460,8 @@ static const struct midr_range arm64_ssb_cpus[] = { · 459 unmodified lines | ||
| 460 | 460 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), |
| 461 | 461 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), |
| 462 | 462 | MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), |
| 463 | + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), | |
| 464 | + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), | |
| 463 | 465 | {}, |
| 464 | 466 | }; |
| 465 | 467 | |
| @@ -470,12 +472,7 @@ static bool · 4 unmodified lines | ||
| 470 | 472 | has_cortex_a76_erratum_1463225(const struct arm64_cpu_capabilities *entry, |
| 471 | 473 | int scope) |
| 472 | 474 | { |
| 473 | − u32 midr = read_cpuid_id(); | |
| 474 | − /* Cortex-A76 r0p0 - r3p1 */ | |
| 475 | − struct midr_range range = MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1); | |
| 476 | − | |
| 477 | − WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); | |
| 478 | − return is_midr_in_range(midr, &range) && is_kernel_in_hyp_mode(); | |
| 475 | + return is_affected_midr_range_list(entry, scope) && is_kernel_in_hyp_mode(); | |
| 479 | 476 | } |
| 480 | 477 | #endif |
| 481 | 478 | |
| @@ -726,6 +723,8 @@ static const struct midr_range erratum_1418040_list[] = { · 244 unmodified lines | ||
| 726 | 723 | MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1), |
| 727 | 724 | /* Neoverse-N1 r0p0 to r3p1 */ |
| 728 | 725 | MIDR_RANGE(MIDR_NEOVERSE_N1, 0, 0, 3, 1), |
| 726 | + /* Kryo4xx Gold (rcpe to rfpf) => (r0p0 to r3p1) */ | |
| 727 | + MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xf), | |
| 729 | 728 | {}, |
| 730 | 729 | }; |
| 731 | 730 | #endif |
| @@ -770,11 +769,22 @@ static const struct midr_range erratum_speculative_at_list[] = { · 38 unmodified lines | ||
| 770 | 769 | #ifdef CONFIG_ARM64_ERRATUM_1530923 |
| 771 | 770 | /* Cortex A55 r0p0 to r2p0 */ |
| 772 | 771 | MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 2, 0), |
| 772 | + /* Kryo4xx Silver (rdpe => r1p0) */ | |
| 773 | + MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe), | |
| 773 | 774 | #endif |
| 774 | 775 | {}, |
| 775 | 776 | }; |
| 776 | 777 | #endif |
| 777 | 778 | |
| 779 | +#ifdef CONFIG_ARM64_ERRATUM_1463225 | |
| 780 | +static const struct midr_range erratum_1463225[] = { | |
| 781 | + /* Cortex-A76 r0p0 - r3p1 */ | |
| 782 | + MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1), | |
| 783 | + /* Kryo4xx Gold (rcpe to rfpf) => (r0p0 to r3p1) */ | |
| 784 | + MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xf), | |
| 785 | +}; | |
| 786 | +#endif | |
| 787 | + | |
| 778 | 788 | const struct arm64_cpu_capabilities arm64_errata[] = { |
| 779 | 789 | #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE |
| 780 | 790 | { |
| @@ -914,6 +924,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { · 133 unmodified lines | ||
| 914 | 924 | .capability = ARM64_WORKAROUND_1463225, |
| 915 | 925 | .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, |
| 916 | 926 | .matches = has_cortex_a76_erratum_1463225, |
| 927 | + .midr_range_list = erratum_1463225, | |
| 917 | 928 | }, |
| 918 | 929 | #endif |
| 919 | 930 | #ifdef CONFIG_CAVIUM_TX2_ERRATUM_219 |
| @@ -1290,6 +1290,8 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, · 1289 unmodified lines | ||
| 1290 | 1290 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), |
| 1291 | 1291 | MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), |
| 1292 | 1292 | MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL), |
| 1293 | + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), | |
| 1294 | + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), | |
| 1293 | 1295 | { /* sentinel */ } |
| 1294 | 1296 | }; |
| 1295 | 1297 | char const *str = "kpti command line option"; |
| @@ -1406,6 +1408,8 @@ static bool cpu_has_broken_dbm(void) · 110 unmodified lines | ||
| 1406 | 1408 | static const struct midr_range cpus[] = { |
| 1407 | 1409 | #ifdef CONFIG_ARM64_ERRATUM_1024718 |
| 1408 | 1410 | MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 1, 0), // A55 r0p0 -r1p0 |
| 1411 | + /* Kryo4xx Silver (rdpe => r1p0) */ | |
| 1412 | + MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe), | |
| 1409 | 1413 | #endif |
| 1410 | 1414 | {}, |
| 1411 | 1415 | }; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/bug.h> |
| 13 | 13 | #include <linux/cache.h> |
| 14 | 14 | #include <linux/compat.h> |
| 15 | +#include <linux/compiler.h> | |
| 15 | 16 | #include <linux/cpu.h> |
| 16 | 17 | #include <linux/cpu_pm.h> |
| 17 | 18 | #include <linux/kernel.h> |
| @@ -119,10 +120,20 @@ struct fpsimd_last_state_struct { · 101 unmodified lines | ||
| 119 | 120 | static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state); |
| 120 | 121 | |
| 121 | 122 | /* Default VL for tasks that don't set it explicitly: */ |
| 122 | −static int sve_default_vl = -1; | |
| 123 | +static int __sve_default_vl = -1; | |
| 124 | + | |
| 125 | +static int get_sve_default_vl(void) | |
| 126 | +{ | |
| 127 | + return READ_ONCE(__sve_default_vl); | |
| 128 | +} | |
| 123 | 129 | |
| 124 | 130 | #ifdef CONFIG_ARM64_SVE |
| 125 | 131 | |
| 132 | +static void set_sve_default_vl(int val) | |
| 133 | +{ | |
| 134 | + WRITE_ONCE(__sve_default_vl, val); | |
| 135 | +} | |
| 136 | + | |
| 126 | 137 | /* Maximum supported vector length across all CPUs (initially poisoned) */ |
| 127 | 138 | int __ro_after_init sve_max_vl = SVE_VL_MIN; |
| 128 | 139 | int __ro_after_init sve_max_virtualisable_vl = SVE_VL_MIN; |
| @@ -338,13 +349,13 @@ static unsigned int find_supported_vector_length(unsigned int vl) · 209 unmodified lines | ||
| 338 | 349 | return sve_vl_from_vq(__bit_to_vq(bit)); |
| 339 | 350 | } |
| 340 | 351 | |
| 341 | −#ifdef CONFIG_SYSCTL | |
| 352 | +#if defined(CONFIG_ARM64_SVE) && defined(CONFIG_SYSCTL) | |
| 342 | 353 | |
| 343 | 354 | static int sve_proc_do_default_vl(struct ctl_table *table, int write, |
| 344 | 355 | void *buffer, size_t *lenp, loff_t *ppos) |
| 345 | 356 | { |
| 346 | 357 | int ret; |
| 347 | − int vl = sve_default_vl; | |
| 358 | + int vl = get_sve_default_vl(); | |
| 348 | 359 | struct ctl_table tmp_table = { |
| 349 | 360 | .data = &vl, |
| 350 | 361 | .maxlen = sizeof(vl), |
| @@ -361,7 +372,7 @@ static int sve_proc_do_default_vl(struct ctl_table *table, int write, · 10 unmodified lines | ||
| 361 | 372 | if (!sve_vl_valid(vl)) |
| 362 | 373 | return -EINVAL; |
| 363 | 374 | |
| 364 | − sve_default_vl = find_supported_vector_length(vl); | |
| 375 | + set_sve_default_vl(find_supported_vector_length(vl)); | |
| 365 | 376 | return 0; |
| 366 | 377 | } |
| 367 | 378 | |
| @@ -383,9 +394,9 @@ static int __init sve_sysctl_init(void) · 15 unmodified lines | ||
| 383 | 394 | return 0; |
| 384 | 395 | } |
| 385 | 396 | |
| 386 | −#else /* ! CONFIG_SYSCTL */ | |
| 397 | +#else /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */ | |
| 387 | 398 | static int __init sve_sysctl_init(void) { return 0; } |
| 388 | −#endif /* ! CONFIG_SYSCTL */ | |
| 399 | +#endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */ | |
| 389 | 400 | |
| 390 | 401 | #define ZREG(sve_state, vq, n) ((char *)(sve_state) + \ |
| 391 | 402 | (SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET)) |
| @@ -868,7 +879,7 @@ void __init sve_setup(void) · 476 unmodified lines | ||
| 868 | 879 | * For the default VL, pick the maximum supported value <= 64. |
| 869 | 880 | * VL == 64 is guaranteed not to grow the signal frame. |
| 870 | 881 | */ |
| 871 | − sve_default_vl = find_supported_vector_length(64); | |
| 882 | + set_sve_default_vl(find_supported_vector_length(64)); | |
| 872 | 883 | |
| 873 | 884 | bitmap_andnot(tmp_map, sve_vq_partial_map, sve_vq_map, |
| 874 | 885 | SVE_VQ_MAX); |
| @@ -889,7 +900,7 @@ void __init sve_setup(void) · 14 unmodified lines | ||
| 889 | 900 | pr_info("SVE: maximum available vector length %u bytes per vector\n", |
| 890 | 901 | sve_max_vl); |
| 891 | 902 | pr_info("SVE: default vector length %u bytes per vector\n", |
| 892 | − sve_default_vl); | |
| 903 | + get_sve_default_vl()); | |
| 893 | 904 | |
| 894 | 905 | /* KVM decides whether to support mismatched systems. Just warn here: */ |
| 895 | 906 | if (sve_max_virtualisable_vl < sve_max_vl) |
| @@ -1029,13 +1040,13 @@ void fpsimd_flush_thread(void) · 133 unmodified lines | ||
| 1029 | 1040 | * vector length configured: no kernel task can become a user |
| 1030 | 1041 | * task without an exec and hence a call to this function. |
| 1031 | 1042 | * By the time the first call to this function is made, all |
| 1032 | − * early hardware probing is complete, so sve_default_vl | |
| 1043 | + * early hardware probing is complete, so __sve_default_vl | |
| 1033 | 1044 | * should be valid. |
| 1034 | 1045 | * If a bug causes this to go wrong, we make some noise and |
| 1035 | 1046 | * try to fudge thread.sve_vl to a safe value here. |
| 1036 | 1047 | */ |
| 1037 | 1048 | vl = current->thread.sve_vl_onexec ? |
| 1038 | − current->thread.sve_vl_onexec : sve_default_vl; | |
| 1049 | + current->thread.sve_vl_onexec : get_sve_default_vl(); | |
| 1039 | 1050 | |
| 1040 | 1051 | if (WARN_ON(!sve_vl_valid(vl))) |
| 1041 | 1052 | vl = SVE_VL_MIN; |
| @@ -730,6 +730,27 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val, · 729 unmodified lines | ||
| 730 | 730 | return 0; |
| 731 | 731 | } |
| 732 | 732 | |
| 733 | +static int watchpoint_report(struct perf_event *wp, unsigned long addr, | |
| 734 | + struct pt_regs *regs) | |
| 735 | +{ | |
| 736 | + int step = is_default_overflow_handler(wp); | |
| 737 | + struct arch_hw_breakpoint *info = counter_arch_bp(wp); | |
| 738 | + | |
| 739 | + info->trigger = addr; | |
| 740 | + | |
| 741 | + /* | |
| 742 | + * If we triggered a user watchpoint from a uaccess routine, then | |
| 743 | + * handle the stepping ourselves since userspace really can't help | |
| 744 | + * us with this. | |
| 745 | + */ | |
| 746 | + if (!user_mode(regs) && info->ctrl.privilege == AARCH64_BREAKPOINT_EL0) | |
| 747 | + step = 1; | |
| 748 | + else | |
| 749 | + perf_bp_event(wp, regs); | |
| 750 | + | |
| 751 | + return step; | |
| 752 | +} | |
| 753 | + | |
| 733 | 754 | static int watchpoint_handler(unsigned long addr, unsigned int esr, |
| 734 | 755 | struct pt_regs *regs) |
| 735 | 756 | { |
| @@ -739,7 +760,6 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, · 3 unmodified lines | ||
| 739 | 760 | u64 val; |
| 740 | 761 | struct perf_event *wp, **slots; |
| 741 | 762 | struct debug_info *debug_info; |
| 742 | − struct arch_hw_breakpoint *info; | |
| 743 | 763 | struct arch_hw_breakpoint_ctrl ctrl; |
| 744 | 764 | |
| 745 | 765 | slots = this_cpu_ptr(wp_on_reg); |
| @@ -777,25 +797,13 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, · 31 unmodified lines | ||
| 777 | 797 | if (dist != 0) |
| 778 | 798 | continue; |
| 779 | 799 | |
| 780 | − info = counter_arch_bp(wp); | |
| 781 | − info->trigger = addr; | |
| 782 | − perf_bp_event(wp, regs); | |
| 783 | − | |
| 784 | − /* Do we need to handle the stepping? */ | |
| 785 | − if (is_default_overflow_handler(wp)) | |
| 786 | − step = 1; | |
| 800 | + step = watchpoint_report(wp, addr, regs); | |
| 787 | 801 | } |
| 788 | − if (min_dist > 0 && min_dist != -1) { | |
| 789 | − /* No exact match found. */ | |
| 790 | − wp = slots[closest_match]; | |
| 791 | − info = counter_arch_bp(wp); | |
| 792 | − info->trigger = addr; | |
| 793 | − perf_bp_event(wp, regs); | |
| 794 | 802 | |
| 795 | − /* Do we need to handle the stepping? */ | |
| 796 | − if (is_default_overflow_handler(wp)) | |
| 797 | − step = 1; | |
| 798 | − } | |
| 803 | + /* No exact match found? */ | |
| 804 | + if (min_dist > 0 && min_dist != -1) | |
| 805 | + step = watchpoint_report(slots[closest_match], addr, regs); | |
| 806 | + | |
| 799 | 807 | rcu_read_unlock(); |
| 800 | 808 | |
| 801 | 809 | if (!step) |
| @@ -135,7 +135,7 @@ int __kprobes aarch64_insn_read(void *addr, u32 *insnp) · 134 unmodified lines | ||
| 135 | 135 | int ret; |
| 136 | 136 | __le32 val; |
| 137 | 137 | |
| 138 | − ret = probe_kernel_read(&val, addr, AARCH64_INSN_SIZE); | |
| 138 | + ret = copy_from_kernel_nofault(&val, addr, AARCH64_INSN_SIZE); | |
| 139 | 139 | if (!ret) |
| 140 | 140 | *insnp = le32_to_cpu(val); |
| 141 | 141 | |
| @@ -151,7 +151,7 @@ static int __kprobes __aarch64_insn_write(void *addr, __le32 insn) · 9 unmodified lines | ||
| 151 | 151 | raw_spin_lock_irqsave(&patch_lock, flags); |
| 152 | 152 | waddr = patch_map(addr, FIX_TEXT_POKE0); |
| 153 | 153 | |
| 154 | − ret = probe_kernel_write(waddr, &insn, AARCH64_INSN_SIZE); | |
| 154 | + ret = copy_to_kernel_nofault(waddr, &insn, AARCH64_INSN_SIZE); | |
| 155 | 155 | |
| 156 | 156 | patch_unmap(FIX_TEXT_POKE0); |
| 157 | 157 | raw_spin_unlock_irqrestore(&patch_lock, flags); |
| @@ -219,8 +219,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) · 218 unmodified lines | ||
| 219 | 219 | MEMBLOCK_NONE, &start, &end, NULL) |
| 220 | 220 | nr_ranges++; |
| 221 | 221 | |
| 222 | − cmem = kmalloc(sizeof(struct crash_mem) + | |
| 223 | − sizeof(struct crash_mem_range) * nr_ranges, GFP_KERNEL); | |
| 222 | + cmem = kmalloc(struct_size(cmem, ranges, nr_ranges), GFP_KERNEL); | |
| 224 | 223 | if (!cmem) |
| 225 | 224 | return -ENOMEM; |
| 226 | 225 | |
| @@ -15,15 +15,34 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) · 14 unmodified lines | ||
| 15 | 15 | return 0; |
| 16 | 16 | |
| 17 | 17 | /* |
| 18 | − * Compat (i.e. 32 bit) mode: | |
| 19 | − * - PC has been set in the pt_regs struct in kernel_entry, | |
| 20 | − * - Handle SP and LR here. | |
| 18 | + * Our handling of compat tasks (PERF_SAMPLE_REGS_ABI_32) is weird, but | |
| 19 | + * we're stuck with it for ABI compatability reasons. | |
| 20 | + * | |
| 21 | + * For a 32-bit consumer inspecting a 32-bit task, then it will look at | |
| 22 | + * the first 16 registers (see arch/arm/include/uapi/asm/perf_regs.h). | |
| 23 | + * These correspond directly to a prefix of the registers saved in our | |
| 24 | + * 'struct pt_regs', with the exception of the PC, so we copy that down | |
| 25 | + * (x15 corresponds to SP_hyp in the architecture). | |
| 26 | + * | |
| 27 | + * So far, so good. | |
| 28 | + * | |
| 29 | + * The oddity arises when a 64-bit consumer looks at a 32-bit task and | |
| 30 | + * asks for registers beyond PERF_REG_ARM_MAX. In this case, we return | |
| 31 | + * SP_usr, LR_usr and PC in the positions where the AArch64 SP, LR and | |
| 32 | + * PC registers would normally live. The initial idea was to allow a | |
| 33 | + * 64-bit unwinder to unwind a 32-bit task and, although it's not clear | |
| 34 | + * how well that works in practice, somebody might be relying on it. | |
| 35 | + * | |
| 36 | + * At the time we make a sample, we don't know whether the consumer is | |
| 37 | + * 32-bit or 64-bit, so we have to cater for both possibilities. | |
| 21 | 38 | */ |
| 22 | 39 | if (compat_user_mode(regs)) { |
| 23 | 40 | if ((u32)idx == PERF_REG_ARM64_SP) |
| 24 | 41 | return regs->compat_sp; |
| 25 | 42 | if ((u32)idx == PERF_REG_ARM64_LR) |
| 26 | 43 | return regs->compat_lr; |
| 44 | + if (idx == 15) | |
| 45 | + return regs->pc; | |
| 27 | 46 | } |
| 28 | 47 | |
| 29 | 48 | if ((u32)idx == PERF_REG_ARM64_SP) |
| @@ -120,15 +120,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | void *alloc_insn_page(void) |
| 122 | 122 | { |
| 123 | − void *page; | |
| 124 | − | |
| 125 | − page = vmalloc_exec(PAGE_SIZE); | |
| 126 | − if (page) { | |
| 127 | − set_memory_ro((unsigned long)page, 1); | |
| 128 | − set_vm_flush_reset_perms(page); | |
| 129 | − } | |
| 130 | − | |
| 131 | − return page; | |
| 123 | + return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END, | |
| 124 | + GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS, | |
| 125 | + NUMA_NO_NODE, __builtin_return_address(0)); | |
| 132 | 126 | } |
| 133 | 127 | |
| 134 | 128 | /* arm kprobe: install breakpoint in text */ |
| @@ -342,38 +342,13 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, · 341 unmodified lines | ||
| 342 | 342 | retcode = ptr_to_compat(ka->sa.sa_restorer); |
| 343 | 343 | } else { |
| 344 | 344 | /* Set up sigreturn pointer */ |
| 345 | −#ifdef CONFIG_COMPAT_VDSO | |
| 346 | − void *vdso_base = current->mm->context.vdso; | |
| 347 | − void *vdso_trampoline; | |
| 348 | − | |
| 349 | − if (ka->sa.sa_flags & SA_SIGINFO) { | |
| 350 | − if (thumb) { | |
| 351 | − vdso_trampoline = VDSO_SYMBOL(vdso_base, | |
| 352 | − compat_rt_sigreturn_thumb); | |
| 353 | − } else { | |
| 354 | − vdso_trampoline = VDSO_SYMBOL(vdso_base, | |
| 355 | − compat_rt_sigreturn_arm); | |
| 356 | − } | |
| 357 | − } else { | |
| 358 | − if (thumb) { | |
| 359 | − vdso_trampoline = VDSO_SYMBOL(vdso_base, | |
| 360 | − compat_sigreturn_thumb); | |
| 361 | − } else { | |
| 362 | − vdso_trampoline = VDSO_SYMBOL(vdso_base, | |
| 363 | − compat_sigreturn_arm); | |
| 364 | − } | |
| 365 | − } | |
| 366 | − | |
| 367 | − retcode = ptr_to_compat(vdso_trampoline) + thumb; | |
| 368 | −#else | |
| 369 | 345 | unsigned int idx = thumb << 1; |
| 370 | 346 | |
| 371 | 347 | if (ka->sa.sa_flags & SA_SIGINFO) |
| 372 | 348 | idx += 3; |
| 373 | 349 | |
| 374 | − retcode = (unsigned long)current->mm->context.vdso + | |
| 350 | + retcode = (unsigned long)current->mm->context.sigpage + | |
| 375 | 351 | (idx << 2) + thumb; |
| 376 | −#endif | |
| 377 | 352 | } |
| 378 | 353 | |
| 379 | 354 | regs->regs[0] = usig; |
| @@ -376,7 +376,7 @@ static int call_undef_hook(struct pt_regs *regs) · 375 unmodified lines | ||
| 376 | 376 | |
| 377 | 377 | if (!user_mode(regs)) { |
| 378 | 378 | __le32 instr_le; |
| 379 | − if (probe_kernel_address((__force __le32 *)pc, instr_le)) | |
| 379 | + if (get_kernel_nofault(instr_le, (__force __le32 *)pc)) | |
| 380 | 380 | goto exit; |
| 381 | 381 | instr = le32_to_cpu(instr_le); |
| 382 | 382 | } else if (compat_thumb_mode(regs)) { |
| @@ -813,6 +813,7 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) · 430 unmodified lines | ||
| 813 | 813 | handler[reason], smp_processor_id(), esr, |
| 814 | 814 | esr_get_class_string(esr)); |
| 815 | 815 | |
| 816 | + __show_regs(regs); | |
| 816 | 817 | local_daif_mask(); |
| 817 | 818 | panic("bad mode"); |
| 818 | 819 | } |
| @@ -191,15 +191,12 @@ enum aarch32_map { · 190 unmodified lines | ||
| 191 | 191 | #ifdef CONFIG_COMPAT_VDSO |
| 192 | 192 | AA32_MAP_VVAR, |
| 193 | 193 | AA32_MAP_VDSO, |
| 194 | −#else | |
| 195 | − AA32_MAP_SIGPAGE | |
| 196 | 194 | #endif |
| 195 | + AA32_MAP_SIGPAGE | |
| 197 | 196 | }; |
| 198 | 197 | |
| 199 | 198 | static struct page *aarch32_vectors_page __ro_after_init; |
| 200 | −#ifndef CONFIG_COMPAT_VDSO | |
| 201 | 199 | static struct page *aarch32_sig_page __ro_after_init; |
| 202 | −#endif | |
| 203 | 200 | |
| 204 | 201 | static struct vm_special_mapping aarch32_vdso_maps[] = { |
| 205 | 202 | [AA32_MAP_VECTORS] = { |
| @@ -214,12 +211,11 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { · 8 unmodified lines | ||
| 214 | 211 | .name = "[vdso]", |
| 215 | 212 | .mremap = aarch32_vdso_mremap, |
| 216 | 213 | }, |
| 217 | −#else | |
| 214 | +#endif /* CONFIG_COMPAT_VDSO */ | |
| 218 | 215 | [AA32_MAP_SIGPAGE] = { |
| 219 | 216 | .name = "[sigpage]", /* ABI */ |
| 220 | 217 | .pages = &aarch32_sig_page, |
| 221 | 218 | }, |
| 222 | −#endif /* CONFIG_COMPAT_VDSO */ | |
| 223 | 219 | }; |
| 224 | 220 | |
| 225 | 221 | static int aarch32_alloc_kuser_vdso_page(void) |
| @@ -242,27 +238,11 @@ static int aarch32_alloc_kuser_vdso_page(void) · 16 unmodified lines | ||
| 242 | 238 | return 0; |
| 243 | 239 | } |
| 244 | 240 | |
| 245 | −#ifdef CONFIG_COMPAT_VDSO | |
| 246 | −static int __aarch32_alloc_vdso_pages(void) | |
| 247 | −{ | |
| 248 | − int ret; | |
| 249 | − | |
| 250 | − vdso_info[VDSO_ABI_AA32].dm = &aarch32_vdso_maps[AA32_MAP_VVAR]; | |
| 251 | − vdso_info[VDSO_ABI_AA32].cm = &aarch32_vdso_maps[AA32_MAP_VDSO]; | |
| 252 | − | |
| 253 | − ret = __vdso_init(VDSO_ABI_AA32); | |
| 254 | − if (ret) | |
| 255 | − return ret; | |
| 256 | − | |
| 257 | − return aarch32_alloc_kuser_vdso_page(); | |
| 258 | −} | |
| 259 | −#else | |
| 260 | −static int __aarch32_alloc_vdso_pages(void) | |
| 241 | +static int aarch32_alloc_sigpage(void) | |
| 261 | 242 | { |
| 262 | 243 | extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[]; |
| 263 | 244 | int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start; |
| 264 | 245 | unsigned long sigpage; |
| 265 | − int ret; | |
| 266 | 246 | |
| 267 | 247 | sigpage = get_zeroed_page(GFP_ATOMIC); |
| 268 | 248 | if (!sigpage) |
| @@ -271,18 +251,34 @@ static int __aarch32_alloc_vdso_pages(void) · 2 unmodified lines | ||
| 271 | 251 | memcpy((void *)sigpage, __aarch32_sigret_code_start, sigret_sz); |
| 272 | 252 | aarch32_sig_page = virt_to_page(sigpage); |
| 273 | 253 | flush_dcache_page(aarch32_sig_page); |
| 254 | + return 0; | |
| 255 | +} | |
| 274 | 256 | |
| 275 | − ret = aarch32_alloc_kuser_vdso_page(); | |
| 276 | − if (ret) | |
| 277 | − free_page(sigpage); | |
| 257 | +#ifdef CONFIG_COMPAT_VDSO | |
| 258 | +static int __aarch32_alloc_vdso_pages(void) | |
| 259 | +{ | |
| 260 | + vdso_info[VDSO_ABI_AA32].dm = &aarch32_vdso_maps[AA32_MAP_VVAR]; | |
| 261 | + vdso_info[VDSO_ABI_AA32].cm = &aarch32_vdso_maps[AA32_MAP_VDSO]; | |
| 278 | 262 | |
| 279 | − return ret; | |
| 263 | + return __vdso_init(VDSO_ABI_AA32); | |
| 280 | 264 | } |
| 281 | 265 | #endif /* CONFIG_COMPAT_VDSO */ |
| 282 | 266 | |
| 283 | 267 | static int __init aarch32_alloc_vdso_pages(void) |
| 284 | 268 | { |
| 285 | − return __aarch32_alloc_vdso_pages(); | |
| 269 | + int ret; | |
| 270 | + | |
| 271 | +#ifdef CONFIG_COMPAT_VDSO | |
| 272 | + ret = __aarch32_alloc_vdso_pages(); | |
| 273 | + if (ret) | |
| 274 | + return ret; | |
| 275 | +#endif | |
| 276 | + | |
| 277 | + ret = aarch32_alloc_sigpage(); | |
| 278 | + if (ret) | |
| 279 | + return ret; | |
| 280 | + | |
| 281 | + return aarch32_alloc_kuser_vdso_page(); | |
| 286 | 282 | } |
| 287 | 283 | arch_initcall(aarch32_alloc_vdso_pages); |
| 288 | 284 | |
| @@ -305,7 +301,6 @@ static int aarch32_kuser_helpers_setup(struct mm_struct *mm) · 16 unmodified lines | ||
| 305 | 301 | return PTR_ERR_OR_ZERO(ret); |
| 306 | 302 | } |
| 307 | 303 | |
| 308 | −#ifndef CONFIG_COMPAT_VDSO | |
| 309 | 304 | static int aarch32_sigreturn_setup(struct mm_struct *mm) |
| 310 | 305 | { |
| 311 | 306 | unsigned long addr; |
| @@ -328,12 +323,11 @@ static int aarch32_sigreturn_setup(struct mm_struct *mm) · 16 unmodified lines | ||
| 328 | 323 | if (IS_ERR(ret)) |
| 329 | 324 | goto out; |
| 330 | 325 | |
| 331 | − mm->context.vdso = (void *)addr; | |
| 326 | + mm->context.sigpage = (void *)addr; | |
| 332 | 327 | |
| 333 | 328 | out: |
| 334 | 329 | return PTR_ERR_OR_ZERO(ret); |
| 335 | 330 | } |
| 336 | −#endif /* !CONFIG_COMPAT_VDSO */ | |
| 337 | 331 | |
| 338 | 332 | int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) |
| 339 | 333 | { |
| @@ -352,10 +346,11 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) · 12 unmodified lines | ||
| 352 | 346 | mm, |
| 353 | 347 | bprm, |
| 354 | 348 | uses_interp); |
| 355 | −#else | |
| 356 | − ret = aarch32_sigreturn_setup(mm); | |
| 349 | + if (ret) | |
| 350 | + goto out; | |
| 357 | 351 | #endif /* CONFIG_COMPAT_VDSO */ |
| 358 | 352 | |
| 353 | + ret = aarch32_sigreturn_setup(mm); | |
| 359 | 354 | out: |
| 360 | 355 | mmap_write_unlock(mm); |
| 361 | 356 | return ret; |
| @@ -23,13 +23,14 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti · 22 unmodified lines | ||
| 23 | 23 | # potential future proofing if we end up with internal calls to the exported |
| 24 | 24 | # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so |
| 25 | 25 | # preparation in build-time C")). |
| 26 | −ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ | |
| 27 | − -Bsymbolic --eh-frame-hdr --build-id -n $(btildflags-y) -T | |
| 26 | +ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ | |
| 27 | + -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id -n \ | |
| 28 | + $(btildflags-y) -T | |
| 28 | 29 | |
| 29 | 30 | ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 |
| 30 | 31 | ccflags-y += -DDISABLE_BRANCH_PROFILING |
| 31 | 32 | |
| 32 | −CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) | |
| 33 | +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) | |
| 33 | 34 | KBUILD_CFLAGS += $(DISABLE_LTO) |
| 34 | 35 | KASAN_SANITIZE := n |
| 35 | 36 | UBSAN_SANITIZE := n |
| @@ -18,29 +18,40 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | .text |
| 20 | 20 | |
| 21 | +/* | |
| 22 | + * NOTE!!! You may notice that all of the .cfi directives in this file have | |
| 23 | + * been commented out. This is because they have been shown to trigger segfaults | |
| 24 | + * in libgcc when unwinding out of a SIGCANCEL handler to invoke pthread | |
| 25 | + * cleanup handlers during the thread cancellation dance. By omitting the | |
| 26 | + * directives, we trigger an arm64-specific fallback path in the unwinder which | |
| 27 | + * recognises the signal frame and restores many of the registers directly from | |
| 28 | + * the sigcontext. Re-enabling the cfi directives here therefore needs to be | |
| 29 | + * much more comprehensive to reduce the risk of further regressions. | |
| 30 | + */ | |
| 31 | + | |
| 21 | 32 | /* Ensure that the mysterious NOP can be associated with a function. */ |
| 22 | − .cfi_startproc | |
| 33 | +// .cfi_startproc | |
| 23 | 34 | |
| 24 | 35 | /* |
| 25 | − * .cfi_signal_frame causes the corresponding Frame Description Entry in the | |
| 26 | − * .eh_frame section to be annotated as a signal frame. This allows DWARF | |
| 27 | − * unwinders (e.g. libstdc++) to implement _Unwind_GetIPInfo(), which permits | |
| 28 | − * unwinding out of the signal trampoline without the need for the mysterious | |
| 29 | − * NOP. | |
| 36 | + * .cfi_signal_frame causes the corresponding Frame Description Entry (FDE) in | |
| 37 | + * the .eh_frame section to be annotated as a signal frame. This allows DWARF | |
| 38 | + * unwinders (e.g. libstdc++) to implement _Unwind_GetIPInfo() and identify | |
| 39 | + * the next frame using the unmodified return address instead of subtracting 1, | |
| 40 | + * which may yield the wrong FDE. | |
| 30 | 41 | */ |
| 31 | − .cfi_signal_frame | |
| 42 | +// .cfi_signal_frame | |
| 32 | 43 | |
| 33 | 44 | /* |
| 34 | 45 | * Tell the unwinder where to locate the frame record linking back to the |
| 35 | − * interrupted context. We don't provide unwind info for registers other | |
| 36 | − * than the frame pointer and the link register here; in practice, this | |
| 37 | − * is sufficient for unwinding in C/C++ based runtimes and the values in | |
| 38 | − * the sigcontext may have been modified by this point anyway. Debuggers | |
| 46 | + * interrupted context. We don't provide unwind info for registers other than | |
| 47 | + * the frame pointer and the link register here; in practice, this is likely to | |
| 48 | + * be insufficient for unwinding in C/C++ based runtimes, especially without a | |
| 49 | + * means to restore the stack pointer. Thankfully, unwinders and debuggers | |
| 39 | 50 | * already have baked-in strategies for attempting to unwind out of signals. |
| 40 | 51 | */ |
| 41 | − .cfi_def_cfa x29, 0 | |
| 42 | − .cfi_offset x29, 0 * 8 | |
| 43 | − .cfi_offset x30, 1 * 8 | |
| 52 | +// .cfi_def_cfa x29, 0 | |
| 53 | +// .cfi_offset x29, 0 * 8 | |
| 54 | +// .cfi_offset x30, 1 * 8 | |
| 44 | 55 | |
| 45 | 56 | /* |
| 46 | 57 | * This mysterious NOP is required for some unwinders (e.g. libc++) that |
| @@ -51,16 +62,19 @@ · 4 unmodified lines | ||
| 51 | 62 | nop // Mysterious NOP |
| 52 | 63 | |
| 53 | 64 | /* |
| 54 | − * GDB relies on being able to identify the sigreturn instruction sequence to | |
| 55 | − * unwind from signal handlers. We cannot, therefore, use SYM_FUNC_START() | |
| 56 | − * here, as it will emit a BTI C instruction and break the unwinder. Thankfully, | |
| 57 | − * this function is only ever called from a RET and so omitting the landing pad | |
| 58 | − * is perfectly fine. | |
| 65 | + * GDB, libgcc and libunwind rely on being able to identify the sigreturn | |
| 66 | + * instruction sequence to unwind from signal handlers. We cannot, therefore, | |
| 67 | + * use SYM_FUNC_START() here, as it will emit a BTI C instruction and break the | |
| 68 | + * unwinder. Thankfully, this function is only ever called from a RET and so | |
| 69 | + * omitting the landing pad is perfectly fine. | |
| 59 | 70 | */ |
| 60 | 71 | SYM_CODE_START(__kernel_rt_sigreturn) |
| 72 | +// PLEASE DO NOT MODIFY | |
| 61 | 73 | mov x8, #__NR_rt_sigreturn |
| 74 | +// PLEASE DO NOT MODIFY | |
| 62 | 75 | svc #0 |
| 63 | − .cfi_endproc | |
| 76 | +// PLEASE DO NOT MODIFY | |
| 77 | +// .cfi_endproc | |
| 64 | 78 | SYM_CODE_END(__kernel_rt_sigreturn) |
| 65 | 79 | |
| 66 | 80 | emit_aarch64_feature_1_and |
| @@ -140,7 +140,6 @@ hostprogs := $(munge) · 139 unmodified lines | ||
| 140 | 140 | |
| 141 | 141 | c-obj-vdso := note.o |
| 142 | 142 | c-obj-vdso-gettimeofday := vgettimeofday.o |
| 143 | −asm-obj-vdso := sigreturn.o | |
| 144 | 143 | |
| 145 | 144 | ifneq ($(c-gettimeofday-y),) |
| 146 | 145 | VDSO_CFLAGS_gettimeofday_o += -include $(c-gettimeofday-y) |
| @@ -1,58 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | −/* | |
| 3 | − * This file provides both A32 and T32 versions, in accordance with the | |
| 4 | − * arm sigreturn code. | |
| 5 | − * | |
| 6 | − * Please read the comments in arch/arm64/kernel/vdso/sigreturn.S to | |
| 7 | − * understand some of the craziness in here. | |
| 8 | − * | |
| 9 | − * Copyright (C) 2018 ARM Limited | |
| 10 | − */ | |
| 11 | − | |
| 12 | −#include <linux/linkage.h> | |
| 13 | −#include <asm/asm-offsets.h> | |
| 14 | −#include <asm/unistd.h> | |
| 15 | − | |
| 16 | − .text | |
| 17 | − | |
| 18 | − .arm | |
| 19 | − .fnstart | |
| 20 | − .save {r0-r15} | |
| 21 | − .pad #COMPAT_SIGFRAME_REGS_OFFSET | |
| 22 | − nop | |
| 23 | −SYM_CODE_START(__kernel_sigreturn_arm) | |
| 24 | − mov r7, #__NR_compat_sigreturn | |
| 25 | − svc #0 | |
| 26 | − .fnend | |
| 27 | −SYM_CODE_END(__kernel_sigreturn_arm) | |
| 28 | − | |
| 29 | − .fnstart | |
| 30 | − .save {r0-r15} | |
| 31 | − .pad #COMPAT_RT_SIGFRAME_REGS_OFFSET | |
| 32 | − nop | |
| 33 | −SYM_CODE_START(__kernel_rt_sigreturn_arm) | |
| 34 | − mov r7, #__NR_compat_rt_sigreturn | |
| 35 | − svc #0 | |
| 36 | − .fnend | |
| 37 | −SYM_CODE_END(__kernel_rt_sigreturn_arm) | |
| 38 | − | |
| 39 | − .thumb | |
| 40 | − .fnstart | |
| 41 | − .save {r0-r15} | |
| 42 | − .pad #COMPAT_SIGFRAME_REGS_OFFSET | |
| 43 | − nop | |
| 44 | −SYM_CODE_START(__kernel_sigreturn_thumb) | |
| 45 | − mov r7, #__NR_compat_sigreturn | |
| 46 | − svc #0 | |
| 47 | − .fnend | |
| 48 | −SYM_CODE_END(__kernel_sigreturn_thumb) | |
| 49 | − | |
| 50 | − .fnstart | |
| 51 | − .save {r0-r15} | |
| 52 | − .pad #COMPAT_RT_SIGFRAME_REGS_OFFSET | |
| 53 | − nop | |
| 54 | −SYM_CODE_START(__kernel_rt_sigreturn_thumb) | |
| 55 | − mov r7, #__NR_compat_rt_sigreturn | |
| 56 | − svc #0 | |
| 57 | − .fnend | |
| 58 | −SYM_CODE_END(__kernel_rt_sigreturn_thumb) | |
| @@ -64,19 +64,7 @@ VERSION · 63 unmodified lines | ||
| 64 | 64 | __vdso_clock_gettime; |
| 65 | 65 | __vdso_gettimeofday; |
| 66 | 66 | __vdso_clock_getres; |
| 67 | − __kernel_sigreturn_arm; | |
| 68 | − __kernel_sigreturn_thumb; | |
| 69 | − __kernel_rt_sigreturn_arm; | |
| 70 | − __kernel_rt_sigreturn_thumb; | |
| 71 | 67 | __vdso_clock_gettime64; |
| 72 | 68 | local: *; |
| 73 | 69 | }; |
| 74 | 70 | } |
| 75 | − | |
| 76 | −/* | |
| 77 | − * Make the sigreturn code visible to the kernel. | |
| 78 | − */ | |
| 79 | −VDSO_compat_sigreturn_arm = __kernel_sigreturn_arm; | |
| 80 | −VDSO_compat_sigreturn_thumb = __kernel_sigreturn_thumb; | |
| 81 | −VDSO_compat_rt_sigreturn_arm = __kernel_rt_sigreturn_arm; | |
| 82 | −VDSO_compat_rt_sigreturn_thumb = __kernel_rt_sigreturn_thumb; | |
| @@ -165,9 +165,6 @@ SECTIONS · 164 unmodified lines | ||
| 165 | 165 | *(.altinstructions) |
| 166 | 166 | __alt_instructions_end = .; |
| 167 | 167 | } |
| 168 | − .altinstr_replacement : { | |
| 169 | − *(.altinstr_replacement) | |
| 170 | − } | |
| 171 | 168 | |
| 172 | 169 | . = ALIGN(SEGMENT_ALIGN); |
| 173 | 170 | __inittext_end = .; |
| @@ -404,11 +404,6 @@ void __init arm64_memblock_init(void) · 403 unmodified lines | ||
| 404 | 404 | high_memory = __va(memblock_end_of_DRAM() - 1) + 1; |
| 405 | 405 | |
| 406 | 406 | dma_contiguous_reserve(arm64_dma32_phys_limit); |
| 407 | − | |
| 408 | −#ifdef CONFIG_ARM64_4K_PAGES | |
| 409 | − hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); | |
| 410 | −#endif | |
| 411 | − | |
| 412 | 407 | } |
| 413 | 408 | |
| 414 | 409 | void __init bootmem_init(void) |
| @@ -424,6 +419,16 @@ void __init bootmem_init(void) · 9 unmodified lines | ||
| 424 | 419 | min_low_pfn = min; |
| 425 | 420 | |
| 426 | 421 | arm64_numa_init(); |
| 422 | + | |
| 423 | + /* | |
| 424 | + * must be done after arm64_numa_init() which calls numa_init() to | |
| 425 | + * initialize node_online_map that gets used in hugetlb_cma_reserve() | |
| 426 | + * while allocating required CMA size across online nodes. | |
| 427 | + */ | |
| 428 | +#ifdef CONFIG_ARM64_4K_PAGES | |
| 429 | + hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); | |
| 430 | +#endif | |
| 431 | + | |
| 427 | 432 | /* |
| 428 | 433 | * Sparsemem tries to allocate bootmem in memory_present(), so must be |
| 429 | 434 | * done after the fixed reservations. |
| @@ -723,6 +723,7 @@ int kern_addr_valid(unsigned long addr) · 722 unmodified lines | ||
| 723 | 723 | pmd_t *pmdp, pmd; |
| 724 | 724 | pte_t *ptep, pte; |
| 725 | 725 | |
| 726 | + addr = arch_kasan_reset_tag(addr); | |
| 726 | 727 | if ((((long)addr) >> VA_BITS) != -1UL) |
| 727 | 728 | return 0; |
| 728 | 729 | |
| @@ -72,7 +72,8 @@ static int ftrace_check_current_nop(unsigned long hook) · 71 unmodified lines | ||
| 72 | 72 | uint16_t olds[7]; |
| 73 | 73 | unsigned long hook_pos = hook - 2; |
| 74 | 74 | |
| 75 | − if (probe_kernel_read((void *)olds, (void *)hook_pos, sizeof(nops))) | |
| 75 | + if (copy_from_kernel_nofault((void *)olds, (void *)hook_pos, | |
| 76 | + sizeof(nops))) | |
| 76 | 77 | return -EFAULT; |
| 77 | 78 | |
| 78 | 79 | if (memcmp((void *)nops, (void *)olds, sizeof(nops))) { |
| @@ -97,7 +98,7 @@ static int ftrace_modify_code(unsigned long hook, unsigned long target, · 18 unmodified lines | ||
| 97 | 98 | |
| 98 | 99 | make_jbsr(target, hook, call, nolr); |
| 99 | 100 | |
| 100 | − ret = probe_kernel_write((void *)hook_pos, enable ? call : nops, | |
| 101 | + ret = copy_to_kernel_nofault((void *)hook_pos, enable ? call : nops, | |
| 101 | 102 | sizeof(nops)); |
| 102 | 103 | if (ret) |
| 103 | 104 | return -EPERM; |
| @@ -35,7 +35,7 @@ static inline void *dereference_function_descriptor(void *ptr) · 34 unmodified lines | ||
| 35 | 35 | struct fdesc *desc = ptr; |
| 36 | 36 | void *p; |
| 37 | 37 | |
| 38 | − if (!probe_kernel_address(&desc->ip, p)) | |
| 38 | + if (!get_kernel_nofault(p, (void *)&desc->ip)) | |
| 39 | 39 | ptr = p; |
| 40 | 40 | return ptr; |
| 41 | 41 | } |
| @@ -108,7 +108,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, · 107 unmodified lines | ||
| 108 | 108 | goto skip_check; |
| 109 | 109 | |
| 110 | 110 | /* read the text we want to modify */ |
| 111 | − if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 111 | + if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 112 | 112 | return -EFAULT; |
| 113 | 113 | |
| 114 | 114 | /* Make sure it is what we expect it to be */ |
| @@ -117,7 +117,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, · 2 unmodified lines | ||
| 117 | 117 | |
| 118 | 118 | skip_check: |
| 119 | 119 | /* replace the text with the new text */ |
| 120 | − if (probe_kernel_write(((void *)ip), new_code, MCOUNT_INSN_SIZE)) | |
| 120 | + if (copy_to_kernel_nofault(((void *)ip), new_code, MCOUNT_INSN_SIZE)) | |
| 121 | 121 | return -EPERM; |
| 122 | 122 | flush_icache_range(ip, ip + MCOUNT_INSN_SIZE); |
| 123 | 123 | |
| @@ -129,7 +129,7 @@ static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr) · 5 unmodified lines | ||
| 129 | 129 | unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE]; |
| 130 | 130 | unsigned long ip = rec->ip; |
| 131 | 131 | |
| 132 | − if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 132 | + if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 133 | 133 | return -EFAULT; |
| 134 | 134 | if (rec->flags & FTRACE_FL_CONVERTED) { |
| 135 | 135 | struct ftrace_call_insn *call_insn, *tmp_call; |
| @@ -42,7 +42,7 @@ enum unw_register_index { · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | struct unw_info_block { |
| 44 | 44 | u64 header; |
| 45 | − u64 desc[0]; /* unwind descriptors */ | |
| 45 | + u64 desc[]; /* unwind descriptors */ | |
| 46 | 46 | /* personality routine and language-specific data follow behind descriptors */ |
| 47 | 47 | }; |
| 48 | 48 | |
| @@ -138,7 +138,8 @@ void __init setup_arch(char **cmdline_p) · 137 unmodified lines | ||
| 138 | 138 | pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ", |
| 139 | 139 | __bss_stop, memory_start, memory_start, memory_end); |
| 140 | 140 | |
| 141 | − memblock_add(memory_start, memory_end - memory_start); | |
| 141 | + memblock_add(_rambase, memory_end - _rambase); | |
| 142 | + memblock_reserve(_rambase, memory_start - _rambase); | |
| 142 | 143 | |
| 143 | 144 | /* Keep a copy of command line */ |
| 144 | 145 | *cmdline_p = &command_line[0]; |
| @@ -174,7 +174,7 @@ void __init cf_bootmem_alloc(void) · 173 unmodified lines | ||
| 174 | 174 | m68k_memory[0].addr = _rambase; |
| 175 | 175 | m68k_memory[0].size = _ramend - _rambase; |
| 176 | 176 | |
| 177 | − memblock_add(m68k_memory[0].addr, m68k_memory[0].size); | |
| 177 | + memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0); | |
| 178 | 178 | |
| 179 | 179 | /* compute total pages in system */ |
| 180 | 180 | num_pages = PFN_DOWN(_ramend - _rambase); |
| @@ -92,7 +92,7 @@ · 91 unmodified lines | ||
| 92 | 92 | "MIC1N", "Built-in Mic"; |
| 93 | 93 | simple-audio-card,pin-switches = "Speaker", "Headphones"; |
| 94 | 94 | |
| 95 | − simple-audio-card,hp-det-gpio = <&gpf 21 GPIO_ACTIVE_HIGH>; | |
| 95 | + simple-audio-card,hp-det-gpio = <&gpf 21 GPIO_ACTIVE_LOW>; | |
| 96 | 96 | simple-audio-card,aux-devs = <&speaker_amp>, <&headphones_amp>; |
| 97 | 97 | |
| 98 | 98 | simple-audio-card,bitclock-master = <&dai_codec>; |
| @@ -86,9 +86,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) · 85 unmodified lines | ||
| 86 | 86 | goto out; |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | − if ((probe_kernel_read(&prev_insn, p->addr - 1, | |
| 90 | − sizeof(mips_instruction)) == 0) && | |
| 91 | − insn_has_delayslot(prev_insn)) { | |
| 89 | + if (copy_from_kernel_nofault(&prev_insn, p->addr - 1, | |
| 90 | + sizeof(mips_instruction)) == 0 && | |
| 91 | + insn_has_delayslot(prev_insn)) { | |
| 92 | 92 | pr_notice("Kprobes for branch delayslot are not supported\n"); |
| 93 | 93 | ret = -EINVAL; |
| 94 | 94 | goto out; |
| @@ -723,12 +723,14 @@ static int simulate_loongson3_cpucfg(struct pt_regs *regs, · 722 unmodified lines | ||
| 723 | 723 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); |
| 724 | 724 | |
| 725 | 725 | /* Do not emulate on unsupported core models. */ |
| 726 | − if (!loongson3_cpucfg_emulation_enabled(¤t_cpu_data)) | |
| 726 | + preempt_disable(); | |
| 727 | + if (!loongson3_cpucfg_emulation_enabled(¤t_cpu_data)) { | |
| 728 | + preempt_enable(); | |
| 727 | 729 | return -1; |
| 728 | − | |
| 730 | + } | |
| 729 | 731 | regs->regs[rd] = loongson3_cpucfg_read_synthesized( |
| 730 | 732 | ¤t_cpu_data, sel); |
| 731 | − | |
| 733 | + preempt_enable(); | |
| 732 | 734 | return 0; |
| 733 | 735 | } |
| 734 | 736 | |
| @@ -2169,6 +2171,7 @@ static void configure_status(void) · 1434 unmodified lines | ||
| 2169 | 2171 | |
| 2170 | 2172 | change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, |
| 2171 | 2173 | status_set); |
| 2174 | + back_to_back_c0_hazard(); | |
| 2172 | 2175 | } |
| 2173 | 2176 | |
| 2174 | 2177 | unsigned int hwrena; |
| @@ -67,7 +67,9 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { · 66 unmodified lines | ||
| 67 | 67 | VCPU_STAT("vz_ghfc", vz_ghfc_exits), |
| 68 | 68 | VCPU_STAT("vz_gpa", vz_gpa_exits), |
| 69 | 69 | VCPU_STAT("vz_resvd", vz_resvd_exits), |
| 70 | +#ifdef CONFIG_CPU_LOONGSON64 | |
| 70 | 71 | VCPU_STAT("vz_cpucfg", vz_cpucfg_exits), |
| 72 | +#endif | |
| 71 | 73 | #endif |
| 72 | 74 | VCPU_STAT("halt_successful_poll", halt_successful_poll), |
| 73 | 75 | VCPU_STAT("halt_attempted_poll", halt_attempted_poll), |
| @@ -514,8 +514,8 @@ void __init ltq_soc_init(void) · 513 unmodified lines | ||
| 514 | 514 | clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | |
| 515 | 515 | PMU_PPE_DP | PMU_PPE_TC); |
| 516 | 516 | clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); |
| 517 | − clkdev_add_pmu("1e108000.gswip", "gphy0", 0, 0, PMU_GPHY); | |
| 518 | − clkdev_add_pmu("1e108000.gswip", "gphy1", 0, 0, PMU_GPHY); | |
| 517 | + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); | |
| 518 | + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); | |
| 519 | 519 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); |
| 520 | 520 | clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); |
| 521 | 521 | clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); |
| @@ -538,8 +538,8 @@ void __init ltq_soc_init(void) · 16 unmodified lines | ||
| 538 | 538 | PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | |
| 539 | 539 | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | |
| 540 | 540 | PMU_PPE_QSB | PMU_PPE_TOP); |
| 541 | − clkdev_add_pmu("1e108000.gswip", "gphy0", 0, 0, PMU_GPHY); | |
| 542 | − clkdev_add_pmu("1e108000.gswip", "gphy1", 0, 0, PMU_GPHY); | |
| 541 | + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); | |
| 542 | + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); | |
| 543 | 543 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); |
| 544 | 544 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); |
| 545 | 545 | clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); |
| @@ -131,13 +131,14 @@ static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn, · 130 unmodified lines | ||
| 131 | 131 | unsigned long orig_insn[3]; |
| 132 | 132 | |
| 133 | 133 | if (validate) { |
| 134 | − if (probe_kernel_read(orig_insn, (void *)pc, MCOUNT_INSN_SIZE)) | |
| 134 | + if (copy_from_kernel_nofault(orig_insn, (void *)pc, | |
| 135 | + MCOUNT_INSN_SIZE)) | |
| 135 | 136 | return -EFAULT; |
| 136 | 137 | if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE)) |
| 137 | 138 | return -EINVAL; |
| 138 | 139 | } |
| 139 | 140 | |
| 140 | − if (probe_kernel_write((void *)pc, new_insn, MCOUNT_INSN_SIZE)) | |
| 141 | + if (copy_to_kernel_nofault((void *)pc, new_insn, MCOUNT_INSN_SIZE)) | |
| 141 | 142 | return -EPERM; |
| 142 | 143 | |
| 143 | 144 | return 0; |
| @@ -74,8 +74,11 @@ void *arch_dma_set_uncached(void *cpu_addr, size_t size) · 73 unmodified lines | ||
| 74 | 74 | * We need to iterate through the pages, clearing the dcache for |
| 75 | 75 | * them and setting the cache-inhibit bit. |
| 76 | 76 | */ |
| 77 | + mmap_read_lock(&init_mm); | |
| 77 | 78 | error = walk_page_range(&init_mm, va, va + size, &set_nocache_walk_ops, |
| 78 | 79 | NULL); |
| 80 | + mmap_read_unlock(&init_mm); | |
| 81 | + | |
| 79 | 82 | if (error) |
| 80 | 83 | return ERR_PTR(error); |
| 81 | 84 | return cpu_addr; |
| @@ -85,9 +88,11 @@ void arch_dma_clear_uncached(void *cpu_addr, size_t size) · 3 unmodified lines | ||
| 85 | 88 | { |
| 86 | 89 | unsigned long va = (unsigned long)cpu_addr; |
| 87 | 90 | |
| 91 | + mmap_read_lock(&init_mm); | |
| 88 | 92 | /* walk_page_range shouldn't be able to fail here */ |
| 89 | 93 | WARN_ON(walk_page_range(&init_mm, va, va + size, |
| 90 | 94 | &clear_nocache_walk_ops, NULL)); |
| 95 | + mmap_read_unlock(&init_mm); | |
| 91 | 96 | } |
| 92 | 97 | |
| 93 | 98 | void arch_sync_dma_for_device(phys_addr_t addr, size_t size, |
| @@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 171 unmodified lines | ||
| 172 | 172 | |
| 173 | 173 | ip = (void *)(rec->ip + 4 - size); |
| 174 | 174 | |
| 175 | − ret = probe_kernel_read(insn, ip, size); | |
| 175 | + ret = copy_from_kernel_nofault(insn, ip, size); | |
| 176 | 176 | if (ret) |
| 177 | 177 | return ret; |
| 178 | 178 | |
| @@ -154,8 +154,8 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) · 153 unmodified lines | ||
| 154 | 154 | |
| 155 | 155 | int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) |
| 156 | 156 | { |
| 157 | − int ret = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, | |
| 158 | − BREAK_INSTR_SIZE); | |
| 157 | + int ret = copy_from_kernel_nofault(bpt->saved_instr, | |
| 158 | + (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); | |
| 159 | 159 | if (ret) |
| 160 | 160 | return ret; |
| 161 | 161 | |
| @@ -293,7 +293,7 @@ void *dereference_function_descriptor(void *ptr) · 292 unmodified lines | ||
| 293 | 293 | Elf64_Fdesc *desc = ptr; |
| 294 | 294 | void *p; |
| 295 | 295 | |
| 296 | − if (!probe_kernel_address(&desc->addr, p)) | |
| 296 | + if (!get_kernel_nofault(p, (void *)&desc->addr)) | |
| 297 | 297 | ptr = p; |
| 298 | 298 | return ptr; |
| 299 | 299 | } |
| @@ -57,7 +57,7 @@ void * memcpy(void * dst,const void *src, size_t count) · 56 unmodified lines | ||
| 57 | 57 | EXPORT_SYMBOL(raw_copy_in_user); |
| 58 | 58 | EXPORT_SYMBOL(memcpy); |
| 59 | 59 | |
| 60 | −bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) | |
| 60 | +bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) | |
| 61 | 61 | { |
| 62 | 62 | if ((unsigned long)unsafe_src < PAGE_SIZE) |
| 63 | 63 | return false; |
| @@ -205,10 +205,6 @@ static inline void pmd_clear(pmd_t *pmdp) · 204 unmodified lines | ||
| 205 | 205 | *pmdp = __pmd(0); |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | −/* to find an entry in a page-table-directory */ | |
| 209 | −#define pgd_index(address) ((address) >> PGDIR_SHIFT) | |
| 210 | −#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) | |
| 211 | − | |
| 212 | 208 | /* |
| 213 | 209 | * PTE updates. This function is called whenever an existing |
| 214 | 210 | * valid PTE is updated. This does -not- include set_pte_at() |
| @@ -230,6 +226,8 @@ static inline void pmd_clear(pmd_t *pmdp) · 15 unmodified lines | ||
| 230 | 226 | * For other page sizes, we have a single entry in the table. |
| 231 | 227 | */ |
| 232 | 228 | #ifdef CONFIG_PPC_8xx |
| 229 | +static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr); | |
| 230 | + | |
| 233 | 231 | static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p, |
| 234 | 232 | unsigned long clr, unsigned long set, int huge) |
| 235 | 233 | { |
| @@ -237,7 +235,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p · 1 unmodified line | ||
| 237 | 235 | pte_basic_t old = pte_val(*p); |
| 238 | 236 | pte_basic_t new = (old & ~(pte_basic_t)clr) | set; |
| 239 | 237 | int num, i; |
| 240 | − pmd_t *pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(mm, addr), addr), addr), addr); | |
| 238 | + pmd_t *pmd = pmd_off(mm, addr); | |
| 241 | 239 | |
| 242 | 240 | if (!huge) |
| 243 | 241 | num = PAGE_SIZE / SZ_4K; |
| @@ -286,6 +284,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, · 42 unmodified lines | ||
| 286 | 284 | return __pte(pte_update(mm, addr, ptep, ~0, 0, 0)); |
| 287 | 285 | } |
| 288 | 286 | |
| 287 | +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES) | |
| 288 | +#define __HAVE_ARCH_PTEP_GET | |
| 289 | +static inline pte_t ptep_get(pte_t *ptep) | |
| 290 | +{ | |
| 291 | + pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0}; | |
| 292 | + | |
| 293 | + return pte; | |
| 294 | +} | |
| 295 | +#endif | |
| 296 | + | |
| 289 | 297 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT |
| 290 | 298 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, |
| 291 | 299 | pte_t *ptep) |
| @@ -85,7 +85,7 @@ static inline void *dereference_function_descriptor(void *ptr) · 84 unmodified lines | ||
| 85 | 85 | struct ppc64_opd_entry *desc = ptr; |
| 86 | 86 | void *p; |
| 87 | 87 | |
| 88 | − if (!probe_kernel_address(&desc->funcaddr, p)) | |
| 88 | + if (!get_kernel_nofault(p, (void *)&desc->funcaddr)) | |
| 89 | 89 | ptr = p; |
| 90 | 90 | return ptr; |
| 91 | 91 | } |
| @@ -0,0 +1,132 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | |
| 2 | +/* | |
| 3 | + * PAPR nvDimm Specific Methods (PDSM) and structs for libndctl | |
| 4 | + * | |
| 5 | + * (C) Copyright IBM 2020 | |
| 6 | + * | |
| 7 | + * Author: Vaibhav Jain <vaibhav at linux.ibm.com> | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#ifndef _UAPI_ASM_POWERPC_PAPR_PDSM_H_ | |
| 11 | +#define _UAPI_ASM_POWERPC_PAPR_PDSM_H_ | |
| 12 | + | |
| 13 | +#include <linux/types.h> | |
| 14 | +#include <linux/ndctl.h> | |
| 15 | + | |
| 16 | +/* | |
| 17 | + * PDSM Envelope: | |
| 18 | + * | |
| 19 | + * The ioctl ND_CMD_CALL exchange data between user-space and kernel via | |
| 20 | + * envelope which consists of 2 headers sections and payload sections as | |
| 21 | + * illustrated below: | |
| 22 | + * +-----------------+---------------+---------------------------+ | |
| 23 | + * | 64-Bytes | 8-Bytes | Max 184-Bytes | | |
| 24 | + * +-----------------+---------------+---------------------------+ | |
| 25 | + * | ND-HEADER | PDSM-HEADER | PDSM-PAYLOAD | | |
| 26 | + * +-----------------+---------------+---------------------------+ | |
| 27 | + * | nd_family | | | | |
| 28 | + * | nd_size_out | cmd_status | | | |
| 29 | + * | nd_size_in | reserved | nd_pdsm_payload | | |
| 30 | + * | nd_command | payload --> | | | |
| 31 | + * | nd_fw_size | | | | |
| 32 | + * | nd_payload ---> | | | | |
| 33 | + * +---------------+-----------------+---------------------------+ | |
| 34 | + * | |
| 35 | + * ND Header: | |
| 36 | + * This is the generic libnvdimm header described as 'struct nd_cmd_pkg' | |
| 37 | + * which is interpreted by libnvdimm before passed on to papr_scm. Important | |
| 38 | + * member fields used are: | |
| 39 | + * 'nd_family' : (In) NVDIMM_FAMILY_PAPR_SCM | |
| 40 | + * 'nd_size_in' : (In) PDSM-HEADER + PDSM-IN-PAYLOAD (usually 0) | |
| 41 | + * 'nd_size_out' : (In) PDSM-HEADER + PDSM-RETURN-PAYLOAD | |
| 42 | + * 'nd_command' : (In) One of PAPR_PDSM_XXX | |
| 43 | + * 'nd_fw_size' : (Out) PDSM-HEADER + size of actual payload returned | |
| 44 | + * | |
| 45 | + * PDSM Header: | |
| 46 | + * This is papr-scm specific header that precedes the payload. This is defined | |
| 47 | + * as nd_cmd_pdsm_pkg. Following fields aare available in this header: | |
| 48 | + * | |
| 49 | + * 'cmd_status' : (Out) Errors if any encountered while servicing PDSM. | |
| 50 | + * 'reserved' : Not used, reserved for future and should be set to 0. | |
| 51 | + * 'payload' : A union of all the possible payload structs | |
| 52 | + * | |
| 53 | + * PDSM Payload: | |
| 54 | + * | |
| 55 | + * The layout of the PDSM Payload is defined by various structs shared between | |
| 56 | + * papr_scm and libndctl so that contents of payload can be interpreted. As such | |
| 57 | + * its defined as a union of all possible payload structs as | |
| 58 | + * 'union nd_pdsm_payload'. Based on the value of 'nd_cmd_pkg.nd_command' | |
| 59 | + * appropriate member of the union is accessed. | |
| 60 | + */ | |
| 61 | + | |
| 62 | +/* Max payload size that we can handle */ | |
| 63 | +#define ND_PDSM_PAYLOAD_MAX_SIZE 184 | |
| 64 | + | |
| 65 | +/* Max payload size that we can handle */ | |
| 66 | +#define ND_PDSM_HDR_SIZE \ | |
| 67 | + (sizeof(struct nd_pkg_pdsm) - ND_PDSM_PAYLOAD_MAX_SIZE) | |
| 68 | + | |
| 69 | +/* Various nvdimm health indicators */ | |
| 70 | +#define PAPR_PDSM_DIMM_HEALTHY 0 | |
| 71 | +#define PAPR_PDSM_DIMM_UNHEALTHY 1 | |
| 72 | +#define PAPR_PDSM_DIMM_CRITICAL 2 | |
| 73 | +#define PAPR_PDSM_DIMM_FATAL 3 | |
| 74 | + | |
| 75 | +/* | |
| 76 | + * Struct exchanged between kernel & ndctl in for PAPR_PDSM_HEALTH | |
| 77 | + * Various flags indicate the health status of the dimm. | |
| 78 | + * | |
| 79 | + * extension_flags : Any extension fields present in the struct. | |
| 80 | + * dimm_unarmed : Dimm not armed. So contents wont persist. | |
| 81 | + * dimm_bad_shutdown : Previous shutdown did not persist contents. | |
| 82 | + * dimm_bad_restore : Contents from previous shutdown werent restored. | |
| 83 | + * dimm_scrubbed : Contents of the dimm have been scrubbed. | |
| 84 | + * dimm_locked : Contents of the dimm cant be modified until CEC reboot | |
| 85 | + * dimm_encrypted : Contents of dimm are encrypted. | |
| 86 | + * dimm_health : Dimm health indicator. One of PAPR_PDSM_DIMM_XXXX | |
| 87 | + */ | |
| 88 | +struct nd_papr_pdsm_health { | |
| 89 | + union { | |
| 90 | + struct { | |
| 91 | + __u32 extension_flags; | |
| 92 | + __u8 dimm_unarmed; | |
| 93 | + __u8 dimm_bad_shutdown; | |
| 94 | + __u8 dimm_bad_restore; | |
| 95 | + __u8 dimm_scrubbed; | |
| 96 | + __u8 dimm_locked; | |
| 97 | + __u8 dimm_encrypted; | |
| 98 | + __u16 dimm_health; | |
| 99 | + }; | |
| 100 | + __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE]; | |
| 101 | + }; | |
| 102 | +}; | |
| 103 | + | |
| 104 | +/* | |
| 105 | + * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel | |
| 106 | + * via 'nd_cmd_pkg.nd_command' member of the ioctl struct | |
| 107 | + */ | |
| 108 | +enum papr_pdsm { | |
| 109 | + PAPR_PDSM_MIN = 0x0, | |
| 110 | + PAPR_PDSM_HEALTH, | |
| 111 | + PAPR_PDSM_MAX, | |
| 112 | +}; | |
| 113 | + | |
| 114 | +/* Maximal union that can hold all possible payload types */ | |
| 115 | +union nd_pdsm_payload { | |
| 116 | + struct nd_papr_pdsm_health health; | |
| 117 | + __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE]; | |
| 118 | +} __packed; | |
| 119 | + | |
| 120 | +/* | |
| 121 | + * PDSM-header + payload expected with ND_CMD_CALL ioctl from libnvdimm | |
| 122 | + * Valid member of union 'payload' is identified via 'nd_cmd_pkg.nd_command' | |
| 123 | + * that should always precede this struct when sent to papr_scm via CMD_CALL | |
| 124 | + * interface. | |
| 125 | + */ | |
| 126 | +struct nd_pkg_pdsm { | |
| 127 | + __s32 cmd_status; /* Out: Sub-cmd status returned back */ | |
| 128 | + __u16 reserved[2]; /* Ignored and to be set as '0' */ | |
| 129 | + union nd_pdsm_payload payload; | |
| 130 | +} __packed; | |
| 131 | + | |
| 132 | +#endif /* _UAPI_ASM_POWERPC_PAPR_PDSM_H_ */ | |
| @@ -270,7 +270,7 @@ BEGIN_FTR_SECTION · 269 unmodified lines | ||
| 270 | 270 | END_FTR_SECTION_IFSET(CPU_FTR_CFAR) |
| 271 | 271 | .endif |
| 272 | 272 | |
| 273 | − ld r10,PACA_EXGEN+EX_CTR(r13) | |
| 273 | + ld r10,IAREA+EX_CTR(r13) | |
| 274 | 274 | mtctr r10 |
| 275 | 275 | BEGIN_FTR_SECTION |
| 276 | 276 | ld r10,IAREA+EX_PPR(r13) |
| @@ -298,7 +298,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) · 21 unmodified lines | ||
| 298 | 298 | |
| 299 | 299 | .if IKVM_SKIP |
| 300 | 300 | 89: mtocrf 0x80,r9 |
| 301 | − ld r10,PACA_EXGEN+EX_CTR(r13) | |
| 301 | + ld r10,IAREA+EX_CTR(r13) | |
| 302 | 302 | mtctr r10 |
| 303 | 303 | ld r9,IAREA+EX_R9(r13) |
| 304 | 304 | ld r10,IAREA+EX_R10(r13) |
| @@ -421,7 +421,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) · 420 unmodified lines | ||
| 421 | 421 | unsigned int instr; |
| 422 | 422 | struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr; |
| 423 | 423 | |
| 424 | − err = probe_kernel_address(addr, instr); | |
| 424 | + err = get_kernel_nofault(instr, (unsigned *) addr); | |
| 425 | 425 | if (err) |
| 426 | 426 | return err; |
| 427 | 427 | |
| @@ -289,7 +289,7 @@ int kprobe_handler(struct pt_regs *regs) · 288 unmodified lines | ||
| 289 | 289 | if (!p) { |
| 290 | 290 | unsigned int instr; |
| 291 | 291 | |
| 292 | − if (probe_kernel_address(addr, instr)) | |
| 292 | + if (get_kernel_nofault(instr, addr)) | |
| 293 | 293 | goto no_kprobe; |
| 294 | 294 | |
| 295 | 295 | if (instr != BREAKPOINT_INSTRUCTION) { |
| @@ -756,7 +756,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr, · 755 unmodified lines | ||
| 756 | 756 | |
| 757 | 757 | stub = (struct ppc64_stub_entry *)addr; |
| 758 | 758 | |
| 759 | − if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) { | |
| 759 | + if (copy_from_kernel_nofault(&magic, &stub->magic, | |
| 760 | + sizeof(magic))) { | |
| 760 | 761 | pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name); |
| 761 | 762 | return -EFAULT; |
| 762 | 763 | } |
| @@ -766,7 +767,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr, · 3 unmodified lines | ||
| 766 | 767 | return -EFAULT; |
| 767 | 768 | } |
| 768 | 769 | |
| 769 | − if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) { | |
| 770 | + if (copy_from_kernel_nofault(&funcdata, &stub->funcdata, | |
| 771 | + sizeof(funcdata))) { | |
| 770 | 772 | pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name); |
| 771 | 773 | return -EFAULT; |
| 772 | 774 | } |
| @@ -1252,29 +1252,31 @@ struct task_struct *__switch_to(struct task_struct *prev, · 1251 unmodified lines | ||
| 1252 | 1252 | static void show_instructions(struct pt_regs *regs) |
| 1253 | 1253 | { |
| 1254 | 1254 | int i; |
| 1255 | + unsigned long nip = regs->nip; | |
| 1255 | 1256 | unsigned long pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int)); |
| 1256 | 1257 | |
| 1257 | 1258 | printk("Instruction dump:"); |
| 1258 | 1259 | |
| 1260 | + /* | |
| 1261 | + * If we were executing with the MMU off for instructions, adjust pc | |
| 1262 | + * rather than printing XXXXXXXX. | |
| 1263 | + */ | |
| 1264 | + if (!IS_ENABLED(CONFIG_BOOKE) && !(regs->msr & MSR_IR)) { | |
| 1265 | + pc = (unsigned long)phys_to_virt(pc); | |
| 1266 | + nip = (unsigned long)phys_to_virt(regs->nip); | |
| 1267 | + } | |
| 1268 | + | |
| 1259 | 1269 | for (i = 0; i < NR_INSN_TO_PRINT; i++) { |
| 1260 | 1270 | int instr; |
| 1261 | 1271 | |
| 1262 | 1272 | if (!(i % 8)) |
| 1263 | 1273 | pr_cont("\n"); |
| 1264 | 1274 | |
| 1265 | −#if !defined(CONFIG_BOOKE) | |
| 1266 | − /* If executing with the IMMU off, adjust pc rather | |
| 1267 | − * than print XXXXXXXX. | |
| 1268 | − */ | |
| 1269 | − if (!(regs->msr & MSR_IR)) | |
| 1270 | − pc = (unsigned long)phys_to_virt(pc); | |
| 1271 | −#endif | |
| 1272 | − | |
| 1273 | 1275 | if (!__kernel_text_address(pc) || |
| 1274 | − probe_kernel_address((const void *)pc, instr)) { | |
| 1276 | + get_kernel_nofault(instr, (const void *)pc)) { | |
| 1275 | 1277 | pr_cont("XXXXXXXX "); |
| 1276 | 1278 | } else { |
| 1277 | − if (regs->nip == pc) | |
| 1279 | + if (nip == pc) | |
| 1278 | 1280 | pr_cont("<%08x> ", instr); |
| 1279 | 1281 | else |
| 1280 | 1282 | pr_cont("%08x ", instr); |
| @@ -1305,7 +1307,8 @@ void show_user_instructions(struct pt_regs *regs) · 24 unmodified lines | ||
| 1305 | 1307 | for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) { |
| 1306 | 1308 | int instr; |
| 1307 | 1309 | |
| 1308 | − if (probe_user_read(&instr, (void __user *)pc, sizeof(instr))) { | |
| 1310 | + if (copy_from_user_nofault(&instr, (void __user *)pc, | |
| 1311 | + sizeof(instr))) { | |
| 1309 | 1312 | seq_buf_printf(&s, "XXXXXXXX "); |
| 1310 | 1313 | continue; |
| 1311 | 1314 | } |
| @@ -226,7 +226,7 @@ __ftrace_make_nop(struct module *mod, · 225 unmodified lines | ||
| 226 | 226 | unsigned long ip = rec->ip; |
| 227 | 227 | unsigned long tramp; |
| 228 | 228 | |
| 229 | − if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 229 | + if (copy_from_kernel_nofault(&op, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 230 | 230 | return -EFAULT; |
| 231 | 231 | |
| 232 | 232 | /* Make sure that that this is still a 24bit jump */ |
| @@ -249,7 +249,7 @@ __ftrace_make_nop(struct module *mod, · 16 unmodified lines | ||
| 249 | 249 | pr_devel("ip:%lx jumps to %lx", ip, tramp); |
| 250 | 250 | |
| 251 | 251 | /* Find where the trampoline jumps to */ |
| 252 | − if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { | |
| 252 | + if (copy_from_kernel_nofault(jmp, (void *)tramp, sizeof(jmp))) { | |
| 253 | 253 | pr_err("Failed to read %lx\n", tramp); |
| 254 | 254 | return -EFAULT; |
| 255 | 255 | } |
| @@ -40,7 +40,8 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid, · 39 unmodified lines | ||
| 40 | 40 | /* Can't access quadrants 1 or 2 in non-HV mode, call the HV to do it */ |
| 41 | 41 | if (kvmhv_on_pseries()) |
| 42 | 42 | return plpar_hcall_norets(H_COPY_TOFROM_GUEST, lpid, pid, eaddr, |
| 43 | − __pa(to), __pa(from), n); | |
| 43 | + (to != NULL) ? __pa(to): 0, | |
| 44 | + (from != NULL) ? __pa(from): 0, n); | |
| 44 | 45 | |
| 45 | 46 | quadrant = 1; |
| 46 | 47 | if (!pid) |
| @@ -64,9 +65,9 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid, · 17 unmodified lines | ||
| 64 | 65 | isync(); |
| 65 | 66 | |
| 66 | 67 | if (is_load) |
| 67 | − ret = probe_user_read(to, (const void __user *)from, n); | |
| 68 | + ret = copy_from_user_nofault(to, (const void __user *)from, n); | |
| 68 | 69 | else |
| 69 | − ret = probe_user_write((void __user *)to, from, n); | |
| 70 | + ret = copy_to_user_nofault((void __user *)to, from, n); | |
| 70 | 71 | |
| 71 | 72 | /* switch the pid first to avoid running host with unallocated pid */ |
| 72 | 73 | if (quadrant == 1 && pid != old_pid) |
| @@ -15,11 +15,11 @@ int probe_user_read_inst(struct ppc_inst *inst, · 14 unmodified lines | ||
| 15 | 15 | unsigned int val, suffix; |
| 16 | 16 | int err; |
| 17 | 17 | |
| 18 | − err = probe_user_read(&val, nip, sizeof(val)); | |
| 18 | + err = copy_from_user_nofault(&val, nip, sizeof(val)); | |
| 19 | 19 | if (err) |
| 20 | 20 | return err; |
| 21 | 21 | if (get_op(val) == OP_PREFIX) { |
| 22 | − err = probe_user_read(&suffix, (void __user *)nip + 4, 4); | |
| 22 | + err = copy_from_user_nofault(&suffix, (void __user *)nip + 4, 4); | |
| 23 | 23 | *inst = ppc_inst_prefix(val, suffix); |
| 24 | 24 | } else { |
| 25 | 25 | *inst = ppc_inst(val); |
| @@ -33,11 +33,11 @@ int probe_kernel_read_inst(struct ppc_inst *inst, · 7 unmodified lines | ||
| 33 | 33 | unsigned int val, suffix; |
| 34 | 34 | int err; |
| 35 | 35 | |
| 36 | − err = probe_kernel_read(&val, src, sizeof(val)); | |
| 36 | + err = copy_from_kernel_nofault(&val, src, sizeof(val)); | |
| 37 | 37 | if (err) |
| 38 | 38 | return err; |
| 39 | 39 | if (get_op(val) == OP_PREFIX) { |
| 40 | − err = probe_kernel_read(&suffix, (void *)src + 4, 4); | |
| 40 | + err = copy_from_kernel_nofault(&suffix, (void *)src + 4, 4); | |
| 41 | 41 | *inst = ppc_inst_prefix(val, suffix); |
| 42 | 42 | } else { |
| 43 | 43 | *inst = ppc_inst(val); |
| @@ -51,7 +51,7 @@ int probe_user_read_inst(struct ppc_inst *inst, · 7 unmodified lines | ||
| 51 | 51 | unsigned int val; |
| 52 | 52 | int err; |
| 53 | 53 | |
| 54 | − err = probe_user_read(&val, nip, sizeof(val)); | |
| 54 | + err = copy_from_user_nofault(&val, nip, sizeof(val)); | |
| 55 | 55 | if (!err) |
| 56 | 56 | *inst = ppc_inst(val); |
| 57 | 57 | |
| @@ -64,7 +64,7 @@ int probe_kernel_read_inst(struct ppc_inst *inst, · 6 unmodified lines | ||
| 64 | 64 | unsigned int val; |
| 65 | 65 | int err; |
| 66 | 66 | |
| 67 | − err = probe_kernel_read(&val, src, sizeof(val)); | |
| 67 | + err = copy_from_kernel_nofault(&val, src, sizeof(val)); | |
| 68 | 68 | if (!err) |
| 69 | 69 | *inst = ppc_inst(val); |
| 70 | 70 | |
| @@ -353,9 +353,6 @@ static bool pkey_access_permitted(int pkey, bool write, bool execute) · 352 unmodified lines | ||
| 353 | 353 | int pkey_shift; |
| 354 | 354 | u64 amr; |
| 355 | 355 | |
| 356 | − if (!is_pkey_enabled(pkey)) | |
| 357 | − return true; | |
| 358 | − | |
| 359 | 356 | pkey_shift = pkeyshift(pkey); |
| 360 | 357 | if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift))) |
| 361 | 358 | return true; |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/memblock.h> |
| 15 | 15 | #include <linux/libfdt.h> |
| 16 | 16 | #include <linux/crash_core.h> |
| 17 | +#include <asm/cacheflush.h> | |
| 17 | 18 | #include <asm/pgalloc.h> |
| 18 | 19 | #include <asm/prom.h> |
| 19 | 20 | #include <asm/kdump.h> |
| @@ -33,7 +33,8 @@ static unsigned int user_getsp32(unsigned int sp, int is_first) · 32 unmodified lines | ||
| 33 | 33 | * which means that we've done all that we can do from |
| 34 | 34 | * interrupt context. |
| 35 | 35 | */ |
| 36 | − if (probe_user_read(stack_frame, (void __user *)p, sizeof(stack_frame))) | |
| 36 | + if (copy_from_user_nofault(stack_frame, (void __user *)p, | |
| 37 | + sizeof(stack_frame))) | |
| 37 | 38 | return 0; |
| 38 | 39 | |
| 39 | 40 | if (!is_first) |
| @@ -51,7 +52,8 @@ static unsigned long user_getsp64(unsigned long sp, int is_first) · 11 unmodified lines | ||
| 51 | 52 | { |
| 52 | 53 | unsigned long stack_frame[3]; |
| 53 | 54 | |
| 54 | − if (probe_user_read(stack_frame, (void __user *)sp, sizeof(stack_frame))) | |
| 55 | + if (copy_from_user_nofault(stack_frame, (void __user *)sp, | |
| 56 | + sizeof(stack_frame))) | |
| 55 | 57 | return 0; |
| 56 | 58 | |
| 57 | 59 | if (!is_first) |
| @@ -44,7 +44,7 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) · 43 unmodified lines | ||
| 44 | 44 | ((unsigned long)ptr & 3)) |
| 45 | 45 | return -EFAULT; |
| 46 | 46 | |
| 47 | − rc = probe_user_read(ret, ptr, sizeof(*ret)); | |
| 47 | + rc = copy_from_user_nofault(ret, ptr, sizeof(*ret)); | |
| 48 | 48 | |
| 49 | 49 | if (IS_ENABLED(CONFIG_PPC64) && rc) |
| 50 | 50 | return read_user_stack_slow(ptr, ret, 4); |
| @@ -50,7 +50,7 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) · 49 unmodified lines | ||
| 50 | 50 | ((unsigned long)ptr & 7)) |
| 51 | 51 | return -EFAULT; |
| 52 | 52 | |
| 53 | − if (!probe_user_read(ret, ptr, sizeof(*ret))) | |
| 53 | + if (!copy_from_user_nofault(ret, ptr, sizeof(*ret))) | |
| 54 | 54 | return 0; |
| 55 | 55 | |
| 56 | 56 | return read_user_stack_slow(ptr, ret, 8); |
| @@ -418,14 +418,16 @@ static __u64 power_pmu_bhrb_to(u64 addr) · 417 unmodified lines | ||
| 418 | 418 | __u64 target; |
| 419 | 419 | |
| 420 | 420 | if (is_kernel_addr(addr)) { |
| 421 | − if (probe_kernel_read(&instr, (void *)addr, sizeof(instr))) | |
| 421 | + if (copy_from_kernel_nofault(&instr, (void *)addr, | |
| 422 | + sizeof(instr))) | |
| 422 | 423 | return 0; |
| 423 | 424 | |
| 424 | 425 | return branch_target((struct ppc_inst *)&instr); |
| 425 | 426 | } |
| 426 | 427 | |
| 427 | 428 | /* Userspace: need copy instruction here then translate it */ |
| 428 | − if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr))) | |
| 429 | + if (copy_from_user_nofault(&instr, (unsigned int __user *)addr, | |
| 430 | + sizeof(instr))) | |
| 429 | 431 | return 0; |
| 430 | 432 | |
| 431 | 433 | target = branch_target((struct ppc_inst *)&instr); |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | */ |
| 36 | 36 | |
| 37 | 37 | static void *spu_syscall_table[] = { |
| 38 | −#define __SYSCALL(nr, entry) entry, | |
| 38 | +#define __SYSCALL(nr, entry) [nr] = entry, | |
| 39 | 39 | #include <asm/syscall_table_spu.h> |
| 40 | 40 | #undef __SYSCALL |
| 41 | 41 | }; |
| @@ -12,16 +12,57 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/libnvdimm.h> |
| 13 | 13 | #include <linux/platform_device.h> |
| 14 | 14 | #include <linux/delay.h> |
| 15 | +#include <linux/seq_buf.h> | |
| 15 | 16 | |
| 16 | 17 | #include <asm/plpar_wrappers.h> |
| 18 | +#include <asm/papr_pdsm.h> | |
| 17 | 19 | |
| 18 | 20 | #define BIND_ANY_ADDR (~0ul) |
| 19 | 21 | |
| 20 | 22 | #define PAPR_SCM_DIMM_CMD_MASK \ |
| 21 | 23 | ((1ul << ND_CMD_GET_CONFIG_SIZE) | \ |
| 22 | 24 | (1ul << ND_CMD_GET_CONFIG_DATA) | \ |
| 23 | − (1ul << ND_CMD_SET_CONFIG_DATA)) | |
| 24 | − | |
| 25 | + (1ul << ND_CMD_SET_CONFIG_DATA) | \ | |
| 26 | + (1ul << ND_CMD_CALL)) | |
| 27 | + | |
| 28 | +/* DIMM health bitmap bitmap indicators */ | |
| 29 | +/* SCM device is unable to persist memory contents */ | |
| 30 | +#define PAPR_PMEM_UNARMED (1ULL << (63 - 0)) | |
| 31 | +/* SCM device failed to persist memory contents */ | |
| 32 | +#define PAPR_PMEM_SHUTDOWN_DIRTY (1ULL << (63 - 1)) | |
| 33 | +/* SCM device contents are persisted from previous IPL */ | |
| 34 | +#define PAPR_PMEM_SHUTDOWN_CLEAN (1ULL << (63 - 2)) | |
| 35 | +/* SCM device contents are not persisted from previous IPL */ | |
| 36 | +#define PAPR_PMEM_EMPTY (1ULL << (63 - 3)) | |
| 37 | +/* SCM device memory life remaining is critically low */ | |
| 38 | +#define PAPR_PMEM_HEALTH_CRITICAL (1ULL << (63 - 4)) | |
| 39 | +/* SCM device will be garded off next IPL due to failure */ | |
| 40 | +#define PAPR_PMEM_HEALTH_FATAL (1ULL << (63 - 5)) | |
| 41 | +/* SCM contents cannot persist due to current platform health status */ | |
| 42 | +#define PAPR_PMEM_HEALTH_UNHEALTHY (1ULL << (63 - 6)) | |
| 43 | +/* SCM device is unable to persist memory contents in certain conditions */ | |
| 44 | +#define PAPR_PMEM_HEALTH_NON_CRITICAL (1ULL << (63 - 7)) | |
| 45 | +/* SCM device is encrypted */ | |
| 46 | +#define PAPR_PMEM_ENCRYPTED (1ULL << (63 - 8)) | |
| 47 | +/* SCM device has been scrubbed and locked */ | |
| 48 | +#define PAPR_PMEM_SCRUBBED_AND_LOCKED (1ULL << (63 - 9)) | |
| 49 | + | |
| 50 | +/* Bits status indicators for health bitmap indicating unarmed dimm */ | |
| 51 | +#define PAPR_PMEM_UNARMED_MASK (PAPR_PMEM_UNARMED | \ | |
| 52 | + PAPR_PMEM_HEALTH_UNHEALTHY) | |
| 53 | + | |
| 54 | +/* Bits status indicators for health bitmap indicating unflushed dimm */ | |
| 55 | +#define PAPR_PMEM_BAD_SHUTDOWN_MASK (PAPR_PMEM_SHUTDOWN_DIRTY) | |
| 56 | + | |
| 57 | +/* Bits status indicators for health bitmap indicating unrestored dimm */ | |
| 58 | +#define PAPR_PMEM_BAD_RESTORE_MASK (PAPR_PMEM_EMPTY) | |
| 59 | + | |
| 60 | +/* Bit status indicators for smart event notification */ | |
| 61 | +#define PAPR_PMEM_SMART_EVENT_MASK (PAPR_PMEM_HEALTH_CRITICAL | \ | |
| 62 | + PAPR_PMEM_HEALTH_FATAL | \ | |
| 63 | + PAPR_PMEM_HEALTH_UNHEALTHY) | |
| 64 | + | |
| 65 | +/* private struct associated with each region */ | |
| 25 | 66 | struct papr_scm_priv { |
| 26 | 67 | struct platform_device *pdev; |
| 27 | 68 | struct device_node *dn; |
| @@ -39,6 +80,15 @@ struct papr_scm_priv { · 11 unmodified lines | ||
| 39 | 80 | struct resource res; |
| 40 | 81 | struct nd_region *region; |
| 41 | 82 | struct nd_interleave_set nd_set; |
| 83 | + | |
| 84 | + /* Protect dimm health data from concurrent read/writes */ | |
| 85 | + struct mutex health_mutex; | |
| 86 | + | |
| 87 | + /* Last time the health information of the dimm was updated */ | |
| 88 | + unsigned long lasthealth_jiffies; | |
| 89 | + | |
| 90 | + /* Health information for the dimm */ | |
| 91 | + u64 health_bitmap; | |
| 42 | 92 | }; |
| 43 | 93 | |
| 44 | 94 | static int drc_pmem_bind(struct papr_scm_priv *p) |
| @@ -144,6 +194,61 @@ err_out: · 99 unmodified lines | ||
| 144 | 194 | return drc_pmem_bind(p); |
| 145 | 195 | } |
| 146 | 196 | |
| 197 | +/* | |
| 198 | + * Issue hcall to retrieve dimm health info and populate papr_scm_priv with the | |
| 199 | + * health information. | |
| 200 | + */ | |
| 201 | +static int __drc_pmem_query_health(struct papr_scm_priv *p) | |
| 202 | +{ | |
| 203 | + unsigned long ret[PLPAR_HCALL_BUFSIZE]; | |
| 204 | + long rc; | |
| 205 | + | |
| 206 | + /* issue the hcall */ | |
| 207 | + rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index); | |
| 208 | + if (rc != H_SUCCESS) { | |
| 209 | + dev_err(&p->pdev->dev, | |
| 210 | + "Failed to query health information, Err:%ld\n", rc); | |
| 211 | + return -ENXIO; | |
| 212 | + } | |
| 213 | + | |
| 214 | + p->lasthealth_jiffies = jiffies; | |
| 215 | + p->health_bitmap = ret[0] & ret[1]; | |
| 216 | + | |
| 217 | + dev_dbg(&p->pdev->dev, | |
| 218 | + "Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n", | |
| 219 | + ret[0], ret[1]); | |
| 220 | + | |
| 221 | + return 0; | |
| 222 | +} | |
| 223 | + | |
| 224 | +/* Min interval in seconds for assuming stable dimm health */ | |
| 225 | +#define MIN_HEALTH_QUERY_INTERVAL 60 | |
| 226 | + | |
| 227 | +/* Query cached health info and if needed call drc_pmem_query_health */ | |
| 228 | +static int drc_pmem_query_health(struct papr_scm_priv *p) | |
| 229 | +{ | |
| 230 | + unsigned long cache_timeout; | |
| 231 | + int rc; | |
| 232 | + | |
| 233 | + /* Protect concurrent modifications to papr_scm_priv */ | |
| 234 | + rc = mutex_lock_interruptible(&p->health_mutex); | |
| 235 | + if (rc) | |
| 236 | + return rc; | |
| 237 | + | |
| 238 | + /* Jiffies offset for which the health data is assumed to be same */ | |
| 239 | + cache_timeout = p->lasthealth_jiffies + | |
| 240 | + msecs_to_jiffies(MIN_HEALTH_QUERY_INTERVAL * 1000); | |
| 241 | + | |
| 242 | + /* Fetch new health info is its older than MIN_HEALTH_QUERY_INTERVAL */ | |
| 243 | + if (time_after(jiffies, cache_timeout)) | |
| 244 | + rc = __drc_pmem_query_health(p); | |
| 245 | + else | |
| 246 | + /* Assume cached health data is valid */ | |
| 247 | + rc = 0; | |
| 248 | + | |
| 249 | + mutex_unlock(&p->health_mutex); | |
| 250 | + return rc; | |
| 251 | +} | |
| 147 | 252 | |
| 148 | 253 | static int papr_scm_meta_get(struct papr_scm_priv *p, |
| 149 | 254 | struct nd_cmd_get_config_data_hdr *hdr) |
| @@ -246,16 +351,250 @@ static int papr_scm_meta_set(struct papr_scm_priv *p, · 96 unmodified lines | ||
| 246 | 351 | return 0; |
| 247 | 352 | } |
| 248 | 353 | |
| 354 | +/* | |
| 355 | + * Do a sanity checks on the inputs args to dimm-control function and return | |
| 356 | + * '0' if valid. Validation of PDSM payloads happens later in | |
| 357 | + * papr_scm_service_pdsm. | |
| 358 | + */ | |
| 359 | +static int is_cmd_valid(struct nvdimm *nvdimm, unsigned int cmd, void *buf, | |
| 360 | + unsigned int buf_len) | |
| 361 | +{ | |
| 362 | + unsigned long cmd_mask = PAPR_SCM_DIMM_CMD_MASK; | |
| 363 | + struct nd_cmd_pkg *nd_cmd; | |
| 364 | + struct papr_scm_priv *p; | |
| 365 | + enum papr_pdsm pdsm; | |
| 366 | + | |
| 367 | + /* Only dimm-specific calls are supported atm */ | |
| 368 | + if (!nvdimm) | |
| 369 | + return -EINVAL; | |
| 370 | + | |
| 371 | + /* get the provider data from struct nvdimm */ | |
| 372 | + p = nvdimm_provider_data(nvdimm); | |
| 373 | + | |
| 374 | + if (!test_bit(cmd, &cmd_mask)) { | |
| 375 | + dev_dbg(&p->pdev->dev, "Unsupported cmd=%u\n", cmd); | |
| 376 | + return -EINVAL; | |
| 377 | + } | |
| 378 | + | |
| 379 | + /* For CMD_CALL verify pdsm request */ | |
| 380 | + if (cmd == ND_CMD_CALL) { | |
| 381 | + /* Verify the envelope and envelop size */ | |
| 382 | + if (!buf || | |
| 383 | + buf_len < (sizeof(struct nd_cmd_pkg) + ND_PDSM_HDR_SIZE)) { | |
| 384 | + dev_dbg(&p->pdev->dev, "Invalid pkg size=%u\n", | |
| 385 | + buf_len); | |
| 386 | + return -EINVAL; | |
| 387 | + } | |
| 388 | + | |
| 389 | + /* Verify that the nd_cmd_pkg.nd_family is correct */ | |
| 390 | + nd_cmd = (struct nd_cmd_pkg *)buf; | |
| 391 | + | |
| 392 | + if (nd_cmd->nd_family != NVDIMM_FAMILY_PAPR) { | |
| 393 | + dev_dbg(&p->pdev->dev, "Invalid pkg family=0x%llx\n", | |
| 394 | + nd_cmd->nd_family); | |
| 395 | + return -EINVAL; | |
| 396 | + } | |
| 397 | + | |
| 398 | + pdsm = (enum papr_pdsm)nd_cmd->nd_command; | |
| 399 | + | |
| 400 | + /* Verify if the pdsm command is valid */ | |
| 401 | + if (pdsm <= PAPR_PDSM_MIN || pdsm >= PAPR_PDSM_MAX) { | |
| 402 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Invalid PDSM\n", | |
| 403 | + pdsm); | |
| 404 | + return -EINVAL; | |
| 405 | + } | |
| 406 | + | |
| 407 | + /* Have enough space to hold returned 'nd_pkg_pdsm' header */ | |
| 408 | + if (nd_cmd->nd_size_out < ND_PDSM_HDR_SIZE) { | |
| 409 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Invalid payload\n", | |
| 410 | + pdsm); | |
| 411 | + return -EINVAL; | |
| 412 | + } | |
| 413 | + } | |
| 414 | + | |
| 415 | + /* Let the command be further processed */ | |
| 416 | + return 0; | |
| 417 | +} | |
| 418 | + | |
| 419 | +/* Fetch the DIMM health info and populate it in provided package. */ | |
| 420 | +static int papr_pdsm_health(struct papr_scm_priv *p, | |
| 421 | + union nd_pdsm_payload *payload) | |
| 422 | +{ | |
| 423 | + int rc; | |
| 424 | + | |
| 425 | + /* Ensure dimm health mutex is taken preventing concurrent access */ | |
| 426 | + rc = mutex_lock_interruptible(&p->health_mutex); | |
| 427 | + if (rc) | |
| 428 | + goto out; | |
| 429 | + | |
| 430 | + /* Always fetch upto date dimm health data ignoring cached values */ | |
| 431 | + rc = __drc_pmem_query_health(p); | |
| 432 | + if (rc) { | |
| 433 | + mutex_unlock(&p->health_mutex); | |
| 434 | + goto out; | |
| 435 | + } | |
| 436 | + | |
| 437 | + /* update health struct with various flags derived from health bitmap */ | |
| 438 | + payload->health = (struct nd_papr_pdsm_health) { | |
| 439 | + .extension_flags = 0, | |
| 440 | + .dimm_unarmed = !!(p->health_bitmap & PAPR_PMEM_UNARMED_MASK), | |
| 441 | + .dimm_bad_shutdown = !!(p->health_bitmap & PAPR_PMEM_BAD_SHUTDOWN_MASK), | |
| 442 | + .dimm_bad_restore = !!(p->health_bitmap & PAPR_PMEM_BAD_RESTORE_MASK), | |
| 443 | + .dimm_scrubbed = !!(p->health_bitmap & PAPR_PMEM_SCRUBBED_AND_LOCKED), | |
| 444 | + .dimm_locked = !!(p->health_bitmap & PAPR_PMEM_SCRUBBED_AND_LOCKED), | |
| 445 | + .dimm_encrypted = !!(p->health_bitmap & PAPR_PMEM_ENCRYPTED), | |
| 446 | + .dimm_health = PAPR_PDSM_DIMM_HEALTHY, | |
| 447 | + }; | |
| 448 | + | |
| 449 | + /* Update field dimm_health based on health_bitmap flags */ | |
| 450 | + if (p->health_bitmap & PAPR_PMEM_HEALTH_FATAL) | |
| 451 | + payload->health.dimm_health = PAPR_PDSM_DIMM_FATAL; | |
| 452 | + else if (p->health_bitmap & PAPR_PMEM_HEALTH_CRITICAL) | |
| 453 | + payload->health.dimm_health = PAPR_PDSM_DIMM_CRITICAL; | |
| 454 | + else if (p->health_bitmap & PAPR_PMEM_HEALTH_UNHEALTHY) | |
| 455 | + payload->health.dimm_health = PAPR_PDSM_DIMM_UNHEALTHY; | |
| 456 | + | |
| 457 | + /* struct populated hence can release the mutex now */ | |
| 458 | + mutex_unlock(&p->health_mutex); | |
| 459 | + rc = sizeof(struct nd_papr_pdsm_health); | |
| 460 | + | |
| 461 | +out: | |
| 462 | + return rc; | |
| 463 | +} | |
| 464 | + | |
| 465 | +/* | |
| 466 | + * 'struct pdsm_cmd_desc' | |
| 467 | + * Identifies supported PDSMs' expected length of in/out payloads | |
| 468 | + * and pdsm service function. | |
| 469 | + * | |
| 470 | + * size_in : Size of input payload if any in the PDSM request. | |
| 471 | + * size_out : Size of output payload if any in the PDSM request. | |
| 472 | + * service : Service function for the PDSM request. Return semantics: | |
| 473 | + * rc < 0 : Error servicing PDSM and rc indicates the error. | |
| 474 | + * rc >=0 : Serviced successfully and 'rc' indicate number of | |
| 475 | + * bytes written to payload. | |
| 476 | + */ | |
| 477 | +struct pdsm_cmd_desc { | |
| 478 | + u32 size_in; | |
| 479 | + u32 size_out; | |
| 480 | + int (*service)(struct papr_scm_priv *dimm, | |
| 481 | + union nd_pdsm_payload *payload); | |
| 482 | +}; | |
| 483 | + | |
| 484 | +/* Holds all supported PDSMs' command descriptors */ | |
| 485 | +static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = { | |
| 486 | + [PAPR_PDSM_MIN] = { | |
| 487 | + .size_in = 0, | |
| 488 | + .size_out = 0, | |
| 489 | + .service = NULL, | |
| 490 | + }, | |
| 491 | + /* New PDSM command descriptors to be added below */ | |
| 492 | + | |
| 493 | + [PAPR_PDSM_HEALTH] = { | |
| 494 | + .size_in = 0, | |
| 495 | + .size_out = sizeof(struct nd_papr_pdsm_health), | |
| 496 | + .service = papr_pdsm_health, | |
| 497 | + }, | |
| 498 | + /* Empty */ | |
| 499 | + [PAPR_PDSM_MAX] = { | |
| 500 | + .size_in = 0, | |
| 501 | + .size_out = 0, | |
| 502 | + .service = NULL, | |
| 503 | + }, | |
| 504 | +}; | |
| 505 | + | |
| 506 | +/* Given a valid pdsm cmd return its command descriptor else return NULL */ | |
| 507 | +static inline const struct pdsm_cmd_desc *pdsm_cmd_desc(enum papr_pdsm cmd) | |
| 508 | +{ | |
| 509 | + if (cmd >= 0 || cmd < ARRAY_SIZE(__pdsm_cmd_descriptors)) | |
| 510 | + return &__pdsm_cmd_descriptors[cmd]; | |
| 511 | + | |
| 512 | + return NULL; | |
| 513 | +} | |
| 514 | + | |
| 515 | +/* | |
| 516 | + * For a given pdsm request call an appropriate service function. | |
| 517 | + * Returns errors if any while handling the pdsm command package. | |
| 518 | + */ | |
| 519 | +static int papr_scm_service_pdsm(struct papr_scm_priv *p, | |
| 520 | + struct nd_cmd_pkg *pkg) | |
| 521 | +{ | |
| 522 | + /* Get the PDSM header and PDSM command */ | |
| 523 | + struct nd_pkg_pdsm *pdsm_pkg = (struct nd_pkg_pdsm *)pkg->nd_payload; | |
| 524 | + enum papr_pdsm pdsm = (enum papr_pdsm)pkg->nd_command; | |
| 525 | + const struct pdsm_cmd_desc *pdsc; | |
| 526 | + int rc; | |
| 527 | + | |
| 528 | + /* Fetch corresponding pdsm descriptor for validation and servicing */ | |
| 529 | + pdsc = pdsm_cmd_desc(pdsm); | |
| 530 | + | |
| 531 | + /* Validate pdsm descriptor */ | |
| 532 | + /* Ensure that reserved fields are 0 */ | |
| 533 | + if (pdsm_pkg->reserved[0] || pdsm_pkg->reserved[1]) { | |
| 534 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Invalid reserved field\n", | |
| 535 | + pdsm); | |
| 536 | + return -EINVAL; | |
| 537 | + } | |
| 538 | + | |
| 539 | + /* If pdsm expects some input, then ensure that the size_in matches */ | |
| 540 | + if (pdsc->size_in && | |
| 541 | + pkg->nd_size_in != (pdsc->size_in + ND_PDSM_HDR_SIZE)) { | |
| 542 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Mismatched size_in=%d\n", | |
| 543 | + pdsm, pkg->nd_size_in); | |
| 544 | + return -EINVAL; | |
| 545 | + } | |
| 546 | + | |
| 547 | + /* If pdsm wants to return data, then ensure that size_out matches */ | |
| 548 | + if (pdsc->size_out && | |
| 549 | + pkg->nd_size_out != (pdsc->size_out + ND_PDSM_HDR_SIZE)) { | |
| 550 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Mismatched size_out=%d\n", | |
| 551 | + pdsm, pkg->nd_size_out); | |
| 552 | + return -EINVAL; | |
| 553 | + } | |
| 554 | + | |
| 555 | + /* Service the pdsm */ | |
| 556 | + if (pdsc->service) { | |
| 557 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Servicing..\n", pdsm); | |
| 558 | + | |
| 559 | + rc = pdsc->service(p, &pdsm_pkg->payload); | |
| 560 | + | |
| 561 | + if (rc < 0) { | |
| 562 | + /* error encountered while servicing pdsm */ | |
| 563 | + pdsm_pkg->cmd_status = rc; | |
| 564 | + pkg->nd_fw_size = ND_PDSM_HDR_SIZE; | |
| 565 | + } else { | |
| 566 | + /* pdsm serviced and 'rc' bytes written to payload */ | |
| 567 | + pdsm_pkg->cmd_status = 0; | |
| 568 | + pkg->nd_fw_size = ND_PDSM_HDR_SIZE + rc; | |
| 569 | + } | |
| 570 | + } else { | |
| 571 | + dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Unsupported PDSM request\n", | |
| 572 | + pdsm); | |
| 573 | + pdsm_pkg->cmd_status = -ENOENT; | |
| 574 | + pkg->nd_fw_size = ND_PDSM_HDR_SIZE; | |
| 575 | + } | |
| 576 | + | |
| 577 | + return pdsm_pkg->cmd_status; | |
| 578 | +} | |
| 579 | + | |
| 249 | 580 | static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, |
| 250 | 581 | struct nvdimm *nvdimm, unsigned int cmd, void *buf, |
| 251 | 582 | unsigned int buf_len, int *cmd_rc) |
| 252 | 583 | { |
| 253 | 584 | struct nd_cmd_get_config_size *get_size_hdr; |
| 585 | + struct nd_cmd_pkg *call_pkg = NULL; | |
| 254 | 586 | struct papr_scm_priv *p; |
| 587 | + int rc; | |
| 255 | 588 | |
| 256 | − /* Only dimm-specific calls are supported atm */ | |
| 257 | − if (!nvdimm) | |
| 258 | − return -EINVAL; | |
| 589 | + rc = is_cmd_valid(nvdimm, cmd, buf, buf_len); | |
| 590 | + if (rc) { | |
| 591 | + pr_debug("Invalid cmd=0x%x. Err=%d\n", cmd, rc); | |
| 592 | + return rc; | |
| 593 | + } | |
| 594 | + | |
| 595 | + /* Use a local variable in case cmd_rc pointer is NULL */ | |
| 596 | + if (!cmd_rc) | |
| 597 | + cmd_rc = &rc; | |
| 259 | 598 | |
| 260 | 599 | p = nvdimm_provider_data(nvdimm); |
| 261 | 600 | |
| @@ -277,7 +616,13 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, · 15 unmodified lines | ||
| 277 | 616 | *cmd_rc = papr_scm_meta_set(p, buf); |
| 278 | 617 | break; |
| 279 | 618 | |
| 619 | + case ND_CMD_CALL: | |
| 620 | + call_pkg = (struct nd_cmd_pkg *)buf; | |
| 621 | + *cmd_rc = papr_scm_service_pdsm(p, call_pkg); | |
| 622 | + break; | |
| 623 | + | |
| 280 | 624 | default: |
| 625 | + dev_dbg(&p->pdev->dev, "Unknown command = %d\n", cmd); | |
| 281 | 626 | return -EINVAL; |
| 282 | 627 | } |
| 283 | 628 | |
| @@ -286,6 +631,64 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, · 2 unmodified lines | ||
| 286 | 631 | return 0; |
| 287 | 632 | } |
| 288 | 633 | |
| 634 | +static ssize_t flags_show(struct device *dev, | |
| 635 | + struct device_attribute *attr, char *buf) | |
| 636 | +{ | |
| 637 | + struct nvdimm *dimm = to_nvdimm(dev); | |
| 638 | + struct papr_scm_priv *p = nvdimm_provider_data(dimm); | |
| 639 | + struct seq_buf s; | |
| 640 | + u64 health; | |
| 641 | + int rc; | |
| 642 | + | |
| 643 | + rc = drc_pmem_query_health(p); | |
| 644 | + if (rc) | |
| 645 | + return rc; | |
| 646 | + | |
| 647 | + /* Copy health_bitmap locally, check masks & update out buffer */ | |
| 648 | + health = READ_ONCE(p->health_bitmap); | |
| 649 | + | |
| 650 | + seq_buf_init(&s, buf, PAGE_SIZE); | |
| 651 | + if (health & PAPR_PMEM_UNARMED_MASK) | |
| 652 | + seq_buf_printf(&s, "not_armed "); | |
| 653 | + | |
| 654 | + if (health & PAPR_PMEM_BAD_SHUTDOWN_MASK) | |
| 655 | + seq_buf_printf(&s, "flush_fail "); | |
| 656 | + | |
| 657 | + if (health & PAPR_PMEM_BAD_RESTORE_MASK) | |
| 658 | + seq_buf_printf(&s, "restore_fail "); | |
| 659 | + | |
| 660 | + if (health & PAPR_PMEM_ENCRYPTED) | |
| 661 | + seq_buf_printf(&s, "encrypted "); | |
| 662 | + | |
| 663 | + if (health & PAPR_PMEM_SMART_EVENT_MASK) | |
| 664 | + seq_buf_printf(&s, "smart_notify "); | |
| 665 | + | |
| 666 | + if (health & PAPR_PMEM_SCRUBBED_AND_LOCKED) | |
| 667 | + seq_buf_printf(&s, "scrubbed locked "); | |
| 668 | + | |
| 669 | + if (seq_buf_used(&s)) | |
| 670 | + seq_buf_printf(&s, "\n"); | |
| 671 | + | |
| 672 | + return seq_buf_used(&s); | |
| 673 | +} | |
| 674 | +DEVICE_ATTR_RO(flags); | |
| 675 | + | |
| 676 | +/* papr_scm specific dimm attributes */ | |
| 677 | +static struct attribute *papr_nd_attributes[] = { | |
| 678 | + &dev_attr_flags.attr, | |
| 679 | + NULL, | |
| 680 | +}; | |
| 681 | + | |
| 682 | +static struct attribute_group papr_nd_attribute_group = { | |
| 683 | + .name = "papr", | |
| 684 | + .attrs = papr_nd_attributes, | |
| 685 | +}; | |
| 686 | + | |
| 687 | +static const struct attribute_group *papr_nd_attr_groups[] = { | |
| 688 | + &papr_nd_attribute_group, | |
| 689 | + NULL, | |
| 690 | +}; | |
| 691 | + | |
| 289 | 692 | static int papr_scm_nvdimm_init(struct papr_scm_priv *p) |
| 290 | 693 | { |
| 291 | 694 | struct device *dev = &p->pdev->dev; |
| @@ -312,8 +715,8 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) · 20 unmodified lines | ||
| 312 | 715 | dimm_flags = 0; |
| 313 | 716 | set_bit(NDD_LABELING, &dimm_flags); |
| 314 | 717 | |
| 315 | − p->nvdimm = nvdimm_create(p->bus, p, NULL, dimm_flags, | |
| 316 | − PAPR_SCM_DIMM_CMD_MASK, 0, NULL); | |
| 718 | + p->nvdimm = nvdimm_create(p->bus, p, papr_nd_attr_groups, | |
| 719 | + dimm_flags, PAPR_SCM_DIMM_CMD_MASK, 0, NULL); | |
| 317 | 720 | if (!p->nvdimm) { |
| 318 | 721 | dev_err(dev, "Error creating DIMM object for %pOF\n", p->dn); |
| 319 | 722 | goto err; |
| @@ -399,6 +802,9 @@ static int papr_scm_probe(struct platform_device *pdev) · 79 unmodified lines | ||
| 399 | 802 | if (!p) |
| 400 | 803 | return -ENOMEM; |
| 401 | 804 | |
| 805 | + /* Initialize the dimm mutex */ | |
| 806 | + mutex_init(&p->health_mutex); | |
| 807 | + | |
| 402 | 808 | /* optional DT properties */ |
| 403 | 809 | of_property_read_u32(dn, "ibm,metadata-size", &metadata_size); |
| 404 | 810 | |
| @@ -1066,10 +1066,10 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs) · 1065 unmodified lines | ||
| 1066 | 1066 | |
| 1067 | 1067 | if (is_in_pci_mem_space(addr)) { |
| 1068 | 1068 | if (user_mode(regs)) |
| 1069 | − ret = probe_user_read(&inst, (void __user *)regs->nip, | |
| 1070 | − sizeof(inst)); | |
| 1069 | + ret = copy_from_user_nofault(&inst, | |
| 1070 | + (void __user *)regs->nip, sizeof(inst)); | |
| 1071 | 1071 | else |
| 1072 | − ret = probe_kernel_address((void *)regs->nip, inst); | |
| 1072 | + ret = get_kernel_nofault(inst, (void *)regs->nip); | |
| 1073 | 1073 | |
| 1074 | 1074 | if (!ret && mcheck_handle_load(regs, inst)) { |
| 1075 | 1075 | regs->nip += 4; |
| @@ -179,7 +179,7 @@ · 178 unmodified lines | ||
| 179 | 179 | " bnez %1, 0b\n" \ |
| 180 | 180 | "1:\n" \ |
| 181 | 181 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 182 | − : "rJ" (__old), "rJ" (__new) \ | |
| 182 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 183 | 183 | : "memory"); \ |
| 184 | 184 | break; \ |
| 185 | 185 | case 8: \ |
| @@ -224,7 +224,7 @@ · 38 unmodified lines | ||
| 224 | 224 | RISCV_ACQUIRE_BARRIER \ |
| 225 | 225 | "1:\n" \ |
| 226 | 226 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 227 | − : "rJ" (__old), "rJ" (__new) \ | |
| 227 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 228 | 228 | : "memory"); \ |
| 229 | 229 | break; \ |
| 230 | 230 | case 8: \ |
| @@ -270,7 +270,7 @@ · 39 unmodified lines | ||
| 270 | 270 | " bnez %1, 0b\n" \ |
| 271 | 271 | "1:\n" \ |
| 272 | 272 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 273 | − : "rJ" (__old), "rJ" (__new) \ | |
| 273 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 274 | 274 | : "memory"); \ |
| 275 | 275 | break; \ |
| 276 | 276 | case 8: \ |
| @@ -316,7 +316,7 @@ · 39 unmodified lines | ||
| 316 | 316 | " fence rw, rw\n" \ |
| 317 | 317 | "1:\n" \ |
| 318 | 318 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 319 | − : "rJ" (__old), "rJ" (__new) \ | |
| 319 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 320 | 320 | : "memory"); \ |
| 321 | 321 | break; \ |
| 322 | 322 | case 8: \ |
| @@ -38,7 +38,8 @@ static int ftrace_check_current_call(unsigned long hook_pos, · 37 unmodified lines | ||
| 38 | 38 | * Read the text we want to modify; |
| 39 | 39 | * return must be -EFAULT on read error |
| 40 | 40 | */ |
| 41 | − if (probe_kernel_read(replaced, (void *)hook_pos, MCOUNT_INSN_SIZE)) | |
| 41 | + if (copy_from_kernel_nofault(replaced, (void *)hook_pos, | |
| 42 | + MCOUNT_INSN_SIZE)) | |
| 42 | 43 | return -EFAULT; |
| 43 | 44 | |
| 44 | 45 | /* |
| @@ -62,7 +62,7 @@ int get_step_address(struct pt_regs *regs, unsigned long *next_addr) · 61 unmodified lines | ||
| 62 | 62 | unsigned int rs1_num, rs2_num; |
| 63 | 63 | int op_code; |
| 64 | 64 | |
| 65 | − if (probe_kernel_address((void *)pc, op_code)) | |
| 65 | + if (get_kernel_nofault(op_code, (void *)pc)) | |
| 66 | 66 | return -EINVAL; |
| 67 | 67 | if ((op_code & __INSN_LENGTH_MASK) != __INSN_LENGTH_GE_32) { |
| 68 | 68 | if (is_c_jalr_insn(op_code) || is_c_jr_insn(op_code)) { |
| @@ -146,14 +146,14 @@ int do_single_step(struct pt_regs *regs) · 77 unmodified lines | ||
| 146 | 146 | return error; |
| 147 | 147 | |
| 148 | 148 | /* Store the op code in the stepped address */ |
| 149 | − error = probe_kernel_address((void *)addr, stepped_opcode); | |
| 149 | + error = get_kernel_nofault(stepped_opcode, (void *)addr); | |
| 150 | 150 | if (error) |
| 151 | 151 | return error; |
| 152 | 152 | |
| 153 | 153 | stepped_address = addr; |
| 154 | 154 | |
| 155 | 155 | /* Replace the op code with the break instruction */ |
| 156 | − error = probe_kernel_write((void *)stepped_address, | |
| 156 | + error = copy_to_kernel_nofault((void *)stepped_address, | |
| 157 | 157 | arch_kgdb_ops.gdb_bpt_instr, |
| 158 | 158 | BREAK_INSTR_SIZE); |
| 159 | 159 | /* Flush and return */ |
| @@ -173,7 +173,7 @@ int do_single_step(struct pt_regs *regs) · 13 unmodified lines | ||
| 173 | 173 | static void undo_single_step(struct pt_regs *regs) |
| 174 | 174 | { |
| 175 | 175 | if (stepped_opcode != 0) { |
| 176 | − probe_kernel_write((void *)stepped_address, | |
| 176 | + copy_to_kernel_nofault((void *)stepped_address, | |
| 177 | 177 | (void *)&stepped_opcode, BREAK_INSTR_SIZE); |
| 178 | 178 | flush_icache_range(stepped_address, |
| 179 | 179 | stepped_address + BREAK_INSTR_SIZE); |
| @@ -63,7 +63,7 @@ static int patch_insn_write(void *addr, const void *insn, size_t len) · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | waddr = patch_map(addr, FIX_TEXT_POKE0); |
| 65 | 65 | |
| 66 | − ret = probe_kernel_write(waddr, insn, len); | |
| 66 | + ret = copy_to_kernel_nofault(waddr, insn, len); | |
| 67 | 67 | |
| 68 | 68 | patch_unmap(FIX_TEXT_POKE0); |
| 69 | 69 | |
| @@ -76,7 +76,7 @@ NOKPROBE_SYMBOL(patch_insn_write); · 6 unmodified lines | ||
| 76 | 76 | #else |
| 77 | 77 | static int patch_insn_write(void *addr, const void *insn, size_t len) |
| 78 | 78 | { |
| 79 | − return probe_kernel_write(addr, insn, len); | |
| 79 | + return copy_to_kernel_nofault(addr, insn, len); | |
| 80 | 80 | } |
| 81 | 81 | NOKPROBE_SYMBOL(patch_insn_write); |
| 82 | 82 | #endif /* CONFIG_MMU */ |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/syscalls.h> |
| 9 | 9 | #include <asm/unistd.h> |
| 10 | 10 | #include <asm/cacheflush.h> |
| 11 | +#include <asm-generic/mman-common.h> | |
| 11 | 12 | |
| 12 | 13 | static long riscv_sys_mmap(unsigned long addr, unsigned long len, |
| 13 | 14 | unsigned long prot, unsigned long flags, |
| @@ -16,6 +17,11 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, · 2 unmodified lines | ||
| 16 | 17 | { |
| 17 | 18 | if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) |
| 18 | 19 | return -EINVAL; |
| 20 | + | |
| 21 | + if ((prot & PROT_WRITE) && (prot & PROT_EXEC)) | |
| 22 | + if (unlikely(!(prot & PROT_READ))) | |
| 23 | + return -EINVAL; | |
| 24 | + | |
| 19 | 25 | return ksys_mmap_pgoff(addr, len, prot, flags, fd, |
| 20 | 26 | offset >> (PAGE_SHIFT - page_shift_offset)); |
| 21 | 27 | } |
| @@ -137,7 +137,7 @@ static inline unsigned long get_break_insn_length(unsigned long pc) · 136 unmodified lines | ||
| 137 | 137 | { |
| 138 | 138 | bug_insn_t insn; |
| 139 | 139 | |
| 140 | − if (probe_kernel_address((bug_insn_t *)pc, insn)) | |
| 140 | + if (get_kernel_nofault(insn, (bug_insn_t *)pc)) | |
| 141 | 141 | return 0; |
| 142 | 142 | |
| 143 | 143 | return GET_INSN_LENGTH(insn); |
| @@ -165,7 +165,7 @@ int is_valid_bugaddr(unsigned long pc) · 21 unmodified lines | ||
| 165 | 165 | |
| 166 | 166 | if (pc < VMALLOC_START) |
| 167 | 167 | return 0; |
| 168 | − if (probe_kernel_address((bug_insn_t *)pc, insn)) | |
| 168 | + if (get_kernel_nofault(insn, (bug_insn_t *)pc)) | |
| 169 | 169 | return 0; |
| 170 | 170 | if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) |
| 171 | 171 | return (insn == __BUG_INSN_32); |
| @@ -17,7 +17,7 @@ vdso-syms += flush_icache · 16 unmodified lines | ||
| 17 | 17 | obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o |
| 18 | 18 | |
| 19 | 19 | ifneq ($(c-gettimeofday-y),) |
| 20 | − CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) | |
| 20 | + CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) | |
| 21 | 21 | endif |
| 22 | 22 | |
| 23 | 23 | # Build rules |
| @@ -27,6 +27,9 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) · 3 unmodified lines | ||
| 27 | 27 | obj-y += vdso.o vdso-syms.o |
| 28 | 28 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
| 29 | 29 | |
| 30 | +# Disable -pg to prevent insert call site | |
| 31 | +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os | |
| 32 | + | |
| 30 | 33 | # Disable gcov profiling for VDSO code |
| 31 | 34 | GCOV_PROFILE := n |
| 32 | 35 | |
| @@ -9,16 +9,22 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/time.h> |
| 10 | 10 | #include <linux/types.h> |
| 11 | 11 | |
| 12 | +extern | |
| 13 | +int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts); | |
| 12 | 14 | int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) |
| 13 | 15 | { |
| 14 | 16 | return __cvdso_clock_gettime(clock, ts); |
| 15 | 17 | } |
| 16 | 18 | |
| 19 | +extern | |
| 20 | +int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz); | |
| 17 | 21 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) |
| 18 | 22 | { |
| 19 | 23 | return __cvdso_gettimeofday(tv, tz); |
| 20 | 24 | } |
| 21 | 25 | |
| 26 | +extern | |
| 27 | +int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res); | |
| 22 | 28 | int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res) |
| 23 | 29 | { |
| 24 | 30 | return __cvdso_clock_getres(clock_id, res); |
| @@ -151,6 +151,7 @@ int set_memory_nx(unsigned long addr, int numpages) · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | int set_direct_map_invalid_noflush(struct page *page) |
| 153 | 153 | { |
| 154 | + int ret; | |
| 154 | 155 | unsigned long start = (unsigned long)page_address(page); |
| 155 | 156 | unsigned long end = start + PAGE_SIZE; |
| 156 | 157 | struct pageattr_masks masks = { |
| @@ -158,11 +159,16 @@ int set_direct_map_invalid_noflush(struct page *page) · 1 unmodified line | ||
| 158 | 159 | .clear_mask = __pgprot(_PAGE_PRESENT) |
| 159 | 160 | }; |
| 160 | 161 | |
| 161 | − return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 162 | + mmap_read_lock(&init_mm); | |
| 163 | + ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 164 | + mmap_read_unlock(&init_mm); | |
| 165 | + | |
| 166 | + return ret; | |
| 162 | 167 | } |
| 163 | 168 | |
| 164 | 169 | int set_direct_map_default_noflush(struct page *page) |
| 165 | 170 | { |
| 171 | + int ret; | |
| 166 | 172 | unsigned long start = (unsigned long)page_address(page); |
| 167 | 173 | unsigned long end = start + PAGE_SIZE; |
| 168 | 174 | struct pageattr_masks masks = { |
| @@ -170,7 +176,11 @@ int set_direct_map_default_noflush(struct page *page) · 1 unmodified line | ||
| 170 | 176 | .clear_mask = __pgprot(0) |
| 171 | 177 | }; |
| 172 | 178 | |
| 173 | − return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 179 | + mmap_read_lock(&init_mm); | |
| 180 | + ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 181 | + mmap_read_unlock(&init_mm); | |
| 182 | + | |
| 183 | + return ret; | |
| 174 | 184 | } |
| 175 | 185 | |
| 176 | 186 | void __kernel_map_pages(struct page *page, int numpages, int enable) |
| @@ -462,6 +462,7 @@ config NUMA · 461 unmodified lines | ||
| 462 | 462 | |
| 463 | 463 | config NODES_SHIFT |
| 464 | 464 | int |
| 465 | + depends on NEED_MULTIPLE_NODES | |
| 465 | 466 | default "1" |
| 466 | 467 | |
| 467 | 468 | config SCHED_SMT |
| @@ -693,7 +693,7 @@ static ssize_t prng_chunksize_show(struct device *dev, · 692 unmodified lines | ||
| 693 | 693 | struct device_attribute *attr, |
| 694 | 694 | char *buf) |
| 695 | 695 | { |
| 696 | − return snprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size); | |
| 696 | + return scnprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size); | |
| 697 | 697 | } |
| 698 | 698 | static DEVICE_ATTR(chunksize, 0444, prng_chunksize_show, NULL); |
| 699 | 699 | |
| @@ -712,7 +712,7 @@ static ssize_t prng_counter_show(struct device *dev, · 12 unmodified lines | ||
| 712 | 712 | counter = prng_data->prngws.byte_counter; |
| 713 | 713 | mutex_unlock(&prng_data->mutex); |
| 714 | 714 | |
| 715 | − return snprintf(buf, PAGE_SIZE, "%llu\n", counter); | |
| 715 | + return scnprintf(buf, PAGE_SIZE, "%llu\n", counter); | |
| 716 | 716 | } |
| 717 | 717 | static DEVICE_ATTR(byte_counter, 0444, prng_counter_show, NULL); |
| 718 | 718 | |
| @@ -721,7 +721,7 @@ static ssize_t prng_errorflag_show(struct device *dev, · 2 unmodified lines | ||
| 721 | 721 | struct device_attribute *attr, |
| 722 | 722 | char *buf) |
| 723 | 723 | { |
| 724 | − return snprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag); | |
| 724 | + return scnprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag); | |
| 725 | 725 | } |
| 726 | 726 | static DEVICE_ATTR(errorflag, 0444, prng_errorflag_show, NULL); |
| 727 | 727 | |
| @@ -731,9 +731,9 @@ static ssize_t prng_mode_show(struct device *dev, · 3 unmodified lines | ||
| 731 | 731 | char *buf) |
| 732 | 732 | { |
| 733 | 733 | if (prng_mode == PRNG_MODE_TDES) |
| 734 | − return snprintf(buf, PAGE_SIZE, "TDES\n"); | |
| 734 | + return scnprintf(buf, PAGE_SIZE, "TDES\n"); | |
| 735 | 735 | else |
| 736 | − return snprintf(buf, PAGE_SIZE, "SHA512\n"); | |
| 736 | + return scnprintf(buf, PAGE_SIZE, "SHA512\n"); | |
| 737 | 737 | } |
| 738 | 738 | static DEVICE_ATTR(mode, 0444, prng_mode_show, NULL); |
| 739 | 739 | |
| @@ -756,7 +756,7 @@ static ssize_t prng_reseed_limit_show(struct device *dev, · 16 unmodified lines | ||
| 756 | 756 | struct device_attribute *attr, |
| 757 | 757 | char *buf) |
| 758 | 758 | { |
| 759 | − return snprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit); | |
| 759 | + return scnprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit); | |
| 760 | 760 | } |
| 761 | 761 | static ssize_t prng_reseed_limit_store(struct device *dev, |
| 762 | 762 | struct device_attribute *attr, |
| @@ -787,7 +787,7 @@ static ssize_t prng_strength_show(struct device *dev, · 24 unmodified lines | ||
| 787 | 787 | struct device_attribute *attr, |
| 788 | 788 | char *buf) |
| 789 | 789 | { |
| 790 | − return snprintf(buf, PAGE_SIZE, "256\n"); | |
| 790 | + return scnprintf(buf, PAGE_SIZE, "256\n"); | |
| 791 | 791 | } |
| 792 | 792 | static DEVICE_ATTR(strength, 0444, prng_strength_show, NULL); |
| 793 | 793 | |
| @@ -33,7 +33,17 @@ static inline void syscall_rollback(struct task_struct *task, · 32 unmodified lines | ||
| 33 | 33 | static inline long syscall_get_error(struct task_struct *task, |
| 34 | 34 | struct pt_regs *regs) |
| 35 | 35 | { |
| 36 | − return IS_ERR_VALUE(regs->gprs[2]) ? regs->gprs[2] : 0; | |
| 36 | + unsigned long error = regs->gprs[2]; | |
| 37 | +#ifdef CONFIG_COMPAT | |
| 38 | + if (test_tsk_thread_flag(task, TIF_31BIT)) { | |
| 39 | + /* | |
| 40 | + * Sign-extend the value so (int)-EFOO becomes (long)-EFOO | |
| 41 | + * and will match correctly in comparisons. | |
| 42 | + */ | |
| 43 | + error = (long)(int)error; | |
| 44 | + } | |
| 45 | +#endif | |
| 46 | + return IS_ERR_VALUE(error) ? error : 0; | |
| 37 | 47 | } |
| 38 | 48 | |
| 39 | 49 | static inline long syscall_get_return_value(struct task_struct *task, |
| @@ -36,6 +36,7 @@ struct vdso_data { · 35 unmodified lines | ||
| 36 | 36 | __u32 tk_shift; /* Shift used for xtime_nsec 0x60 */ |
| 37 | 37 | __u32 ts_dir; /* TOD steering direction 0x64 */ |
| 38 | 38 | __u64 ts_end; /* TOD steering end 0x68 */ |
| 39 | + __u32 hrtimer_res; /* hrtimer resolution 0x70 */ | |
| 39 | 40 | }; |
| 40 | 41 | |
| 41 | 42 | struct vdso_per_cpu_data { |
| @@ -76,6 +76,7 @@ int main(void) · 75 unmodified lines | ||
| 76 | 76 | OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); |
| 77 | 77 | OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir); |
| 78 | 78 | OFFSET(__VDSO_TS_END, vdso_data, ts_end); |
| 79 | + OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res); | |
| 79 | 80 | OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); |
| 80 | 81 | OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); |
| 81 | 82 | OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); |
| @@ -86,7 +87,6 @@ int main(void) · 4 unmodified lines | ||
| 86 | 87 | DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); |
| 87 | 88 | DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); |
| 88 | 89 | DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID); |
| 89 | − DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); | |
| 90 | 90 | DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC); |
| 91 | 91 | BLANK(); |
| 92 | 92 | /* idle data offsets */ |
| @@ -198,9 +198,10 @@ static debug_entry_t ***debug_areas_alloc(int pages_per_area, int nr_areas) · 197 unmodified lines | ||
| 198 | 198 | if (!areas) |
| 199 | 199 | goto fail_malloc_areas; |
| 200 | 200 | for (i = 0; i < nr_areas; i++) { |
| 201 | + /* GFP_NOWARN to avoid user triggerable WARN, we handle fails */ | |
| 201 | 202 | areas[i] = kmalloc_array(pages_per_area, |
| 202 | 203 | sizeof(debug_entry_t *), |
| 203 | − GFP_KERNEL); | |
| 204 | + GFP_KERNEL | __GFP_NOWARN); | |
| 204 | 205 | if (!areas[i]) |
| 205 | 206 | goto fail_malloc_areas2; |
| 206 | 207 | for (j = 0; j < pages_per_area; j++) { |
| @@ -170,6 +170,8 @@ static noinline __init void setup_lowcore_early(void) · 169 unmodified lines | ||
| 170 | 170 | psw_t psw; |
| 171 | 171 | |
| 172 | 172 | psw.mask = PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA; |
| 173 | + if (IS_ENABLED(CONFIG_KASAN)) | |
| 174 | + psw.mask |= PSW_MASK_DAT; | |
| 173 | 175 | psw.addr = (unsigned long) s390_base_ext_handler; |
| 174 | 176 | S390_lowcore.external_new_psw = psw; |
| 175 | 177 | psw.addr = (unsigned long) s390_base_pgm_handler; |
| @@ -378,9 +378,9 @@ ENTRY(system_call) · 377 unmodified lines | ||
| 378 | 378 | stmg %r8,%r15,__LC_SAVE_AREA_SYNC |
| 379 | 379 | BPOFF |
| 380 | 380 | lg %r12,__LC_CURRENT |
| 381 | − lghi %r13,__TASK_thread | |
| 382 | 381 | lghi %r14,_PIF_SYSCALL |
| 383 | 382 | .Lsysc_per: |
| 383 | + lghi %r13,__TASK_thread | |
| 384 | 384 | lg %r15,__LC_KERNEL_STACK |
| 385 | 385 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs |
| 386 | 386 | UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER |
| @@ -401,9 +401,9 @@ ENTRY(system_call) · 14 unmodified lines | ||
| 401 | 401 | jnz .Lsysc_nr_ok |
| 402 | 402 | # svc 0: system call number in %r1 |
| 403 | 403 | llgfr %r1,%r1 # clear high word in r1 |
| 404 | + sth %r1,__PT_INT_CODE+2(%r11) | |
| 404 | 405 | cghi %r1,NR_syscalls |
| 405 | 406 | jnl .Lsysc_nr_ok |
| 406 | − sth %r1,__PT_INT_CODE+2(%r11) | |
| 407 | 407 | slag %r8,%r1,3 |
| 408 | 408 | .Lsysc_nr_ok: |
| 409 | 409 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
| @@ -83,7 +83,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, · 82 unmodified lines | ||
| 83 | 83 | { |
| 84 | 84 | struct ftrace_insn orig, new, old; |
| 85 | 85 | |
| 86 | − if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) | |
| 86 | + if (copy_from_kernel_nofault(&old, (void *) rec->ip, sizeof(old))) | |
| 87 | 87 | return -EFAULT; |
| 88 | 88 | if (addr == MCOUNT_ADDR) { |
| 89 | 89 | /* Initial code replacement */ |
| @@ -105,7 +105,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 15 unmodified lines | ||
| 105 | 105 | { |
| 106 | 106 | struct ftrace_insn orig, new, old; |
| 107 | 107 | |
| 108 | − if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) | |
| 108 | + if (copy_from_kernel_nofault(&old, (void *) rec->ip, sizeof(old))) | |
| 109 | 109 | return -EFAULT; |
| 110 | 110 | /* Replace nop with an ftrace call. */ |
| 111 | 111 | ftrace_generate_nop_insn(&orig); |
| @@ -181,7 +181,7 @@ static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \ · 180 unmodified lines | ||
| 181 | 181 | struct kobj_attribute *attr, \ |
| 182 | 182 | char *page) \ |
| 183 | 183 | { \ |
| 184 | − return snprintf(page, PAGE_SIZE, _format, ##args); \ | |
| 184 | + return scnprintf(page, PAGE_SIZE, _format, ##args); \ | |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | #define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk) \ |
| @@ -323,6 +323,25 @@ static inline void __poke_user_per(struct task_struct *child, · 322 unmodified lines | ||
| 323 | 323 | child->thread.per_user.end = data; |
| 324 | 324 | } |
| 325 | 325 | |
| 326 | +static void fixup_int_code(struct task_struct *child, addr_t data) | |
| 327 | +{ | |
| 328 | + struct pt_regs *regs = task_pt_regs(child); | |
| 329 | + int ilc = regs->int_code >> 16; | |
| 330 | + u16 insn; | |
| 331 | + | |
| 332 | + if (ilc > 6) | |
| 333 | + return; | |
| 334 | + | |
| 335 | + if (ptrace_access_vm(child, regs->psw.addr - (regs->int_code >> 16), | |
| 336 | + &insn, sizeof(insn), FOLL_FORCE) != sizeof(insn)) | |
| 337 | + return; | |
| 338 | + | |
| 339 | + /* double check that tracee stopped on svc instruction */ | |
| 340 | + if ((insn >> 8) != 0xa) | |
| 341 | + return; | |
| 342 | + | |
| 343 | + regs->int_code = 0x20000 | (data & 0xffff); | |
| 344 | +} | |
| 326 | 345 | /* |
| 327 | 346 | * Write a word to the user area of a process at location addr. This |
| 328 | 347 | * operation does have an additional problem compared to peek_user. |
| @@ -334,7 +353,9 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) · 5 unmodified lines | ||
| 334 | 353 | struct user *dummy = NULL; |
| 335 | 354 | addr_t offset; |
| 336 | 355 | |
| 356 | + | |
| 337 | 357 | if (addr < (addr_t) &dummy->regs.acrs) { |
| 358 | + struct pt_regs *regs = task_pt_regs(child); | |
| 338 | 359 | /* |
| 339 | 360 | * psw and gprs are stored on the stack |
| 340 | 361 | */ |
| @@ -352,7 +373,11 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) · 11 unmodified lines | ||
| 352 | 373 | /* Invalid addressing mode bits */ |
| 353 | 374 | return -EINVAL; |
| 354 | 375 | } |
| 355 | − *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; | |
| 376 | + | |
| 377 | + if (test_pt_regs_flag(regs, PIF_SYSCALL) && | |
| 378 | + addr == offsetof(struct user, regs.gprs[2])) | |
| 379 | + fixup_int_code(child, data); | |
| 380 | + *(addr_t *)((addr_t) ®s->psw + addr) = data; | |
| 356 | 381 | |
| 357 | 382 | } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { |
| 358 | 383 | /* |
| @@ -718,6 +743,10 @@ static int __poke_user_compat(struct task_struct *child, · 359 unmodified lines | ||
| 718 | 743 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | |
| 719 | 744 | (__u64)(tmp & PSW32_ADDR_AMODE); |
| 720 | 745 | } else { |
| 746 | + | |
| 747 | + if (test_pt_regs_flag(regs, PIF_SYSCALL) && | |
| 748 | + addr == offsetof(struct compat_user, regs.gprs[2])) | |
| 749 | + fixup_int_code(child, data); | |
| 721 | 750 | /* gpr 0-15 */ |
| 722 | 751 | *(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp; |
| 723 | 752 | } |
| @@ -837,40 +866,66 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, · 113 unmodified lines | ||
| 837 | 866 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) |
| 838 | 867 | { |
| 839 | 868 | unsigned long mask = -1UL; |
| 869 | + long ret = -1; | |
| 870 | + | |
| 871 | + if (is_compat_task()) | |
| 872 | + mask = 0xffffffff; | |
| 840 | 873 | |
| 841 | 874 | /* |
| 842 | 875 | * The sysc_tracesys code in entry.S stored the system |
| 843 | 876 | * call number to gprs[2]. |
| 844 | 877 | */ |
| 845 | 878 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
| 846 | − (tracehook_report_syscall_entry(regs) || | |
| 847 | − regs->gprs[2] >= NR_syscalls)) { | |
| 879 | + tracehook_report_syscall_entry(regs)) { | |
| 848 | 880 | /* |
| 849 | − * Tracing decided this syscall should not happen or the | |
| 850 | − * debugger stored an invalid system call number. Skip | |
| 881 | + * Tracing decided this syscall should not happen. Skip | |
| 851 | 882 | * the system call and the system call restart handling. |
| 852 | 883 | */ |
| 853 | − clear_pt_regs_flag(regs, PIF_SYSCALL); | |
| 854 | − return -1; | |
| 884 | + goto skip; | |
| 855 | 885 | } |
| 856 | 886 | |
| 887 | +#ifdef CONFIG_SECCOMP | |
| 857 | 888 | /* Do the secure computing check after ptrace. */ |
| 858 | − if (secure_computing()) { | |
| 859 | − /* seccomp failures shouldn't expose any additional code. */ | |
| 860 | − return -1; | |
| 889 | + if (unlikely(test_thread_flag(TIF_SECCOMP))) { | |
| 890 | + struct seccomp_data sd; | |
| 891 | + | |
| 892 | + if (is_compat_task()) { | |
| 893 | + sd.instruction_pointer = regs->psw.addr & 0x7fffffff; | |
| 894 | + sd.arch = AUDIT_ARCH_S390; | |
| 895 | + } else { | |
| 896 | + sd.instruction_pointer = regs->psw.addr; | |
| 897 | + sd.arch = AUDIT_ARCH_S390X; | |
| 898 | + } | |
| 899 | + | |
| 900 | + sd.nr = regs->int_code & 0xffff; | |
| 901 | + sd.args[0] = regs->orig_gpr2 & mask; | |
| 902 | + sd.args[1] = regs->gprs[3] & mask; | |
| 903 | + sd.args[2] = regs->gprs[4] & mask; | |
| 904 | + sd.args[3] = regs->gprs[5] & mask; | |
| 905 | + sd.args[4] = regs->gprs[6] & mask; | |
| 906 | + sd.args[5] = regs->gprs[7] & mask; | |
| 907 | + | |
| 908 | + if (__secure_computing(&sd) == -1) | |
| 909 | + goto skip; | |
| 861 | 910 | } |
| 911 | +#endif /* CONFIG_SECCOMP */ | |
| 862 | 912 | |
| 863 | 913 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 864 | − trace_sys_enter(regs, regs->gprs[2]); | |
| 914 | + trace_sys_enter(regs, regs->int_code & 0xffff); | |
| 865 | 915 | |
| 866 | − if (is_compat_task()) | |
| 867 | − mask = 0xffffffff; | |
| 868 | 916 | |
| 869 | − audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask, | |
| 917 | + audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask, | |
| 870 | 918 | regs->gprs[3] &mask, regs->gprs[4] &mask, |
| 871 | 919 | regs->gprs[5] &mask); |
| 872 | 920 | |
| 921 | + if ((signed long)regs->gprs[2] >= NR_syscalls) { | |
| 922 | + regs->gprs[2] = -ENOSYS; | |
| 923 | + ret = -ENOSYS; | |
| 924 | + } | |
| 873 | 925 | return regs->gprs[2]; |
| 926 | +skip: | |
| 927 | + clear_pt_regs_flag(regs, PIF_SYSCALL); | |
| 928 | + return ret; | |
| 874 | 929 | } |
| 875 | 930 | |
| 876 | 931 | asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) |
| @@ -301,6 +301,7 @@ void update_vsyscall(struct timekeeper *tk) · 300 unmodified lines | ||
| 301 | 301 | |
| 302 | 302 | vdso_data->tk_mult = tk->tkr_mono.mult; |
| 303 | 303 | vdso_data->tk_shift = tk->tkr_mono.shift; |
| 304 | + vdso_data->hrtimer_res = hrtimer_resolution; | |
| 304 | 305 | smp_wmb(); |
| 305 | 306 | ++vdso_data->tb_update_count; |
| 306 | 307 | } |
| @@ -331,7 +331,7 @@ EXPORT_SYMBOL_GPL(arch_make_page_accessible); · 330 unmodified lines | ||
| 331 | 331 | static ssize_t uv_query_facilities(struct kobject *kobj, |
| 332 | 332 | struct kobj_attribute *attr, char *page) |
| 333 | 333 | { |
| 334 | − return snprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n", | |
| 334 | + return scnprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n", | |
| 335 | 335 | uv_info.inst_calls_list[0], |
| 336 | 336 | uv_info.inst_calls_list[1], |
| 337 | 337 | uv_info.inst_calls_list[2], |
| @@ -344,7 +344,7 @@ static struct kobj_attribute uv_query_facilities_attr = · 6 unmodified lines | ||
| 344 | 344 | static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, |
| 345 | 345 | struct kobj_attribute *attr, char *page) |
| 346 | 346 | { |
| 347 | − return snprintf(page, PAGE_SIZE, "%d\n", | |
| 347 | + return scnprintf(page, PAGE_SIZE, "%d\n", | |
| 348 | 348 | uv_info.max_guest_cpus); |
| 349 | 349 | } |
| 350 | 350 | |
| @@ -354,7 +354,7 @@ static struct kobj_attribute uv_query_max_guest_cpus_attr = · 3 unmodified lines | ||
| 354 | 354 | static ssize_t uv_query_max_guest_vms(struct kobject *kobj, |
| 355 | 355 | struct kobj_attribute *attr, char *page) |
| 356 | 356 | { |
| 357 | − return snprintf(page, PAGE_SIZE, "%d\n", | |
| 357 | + return scnprintf(page, PAGE_SIZE, "%d\n", | |
| 358 | 358 | uv_info.max_num_sec_conf); |
| 359 | 359 | } |
| 360 | 360 | |
| @@ -364,7 +364,7 @@ static struct kobj_attribute uv_query_max_guest_vms_attr = · 3 unmodified lines | ||
| 364 | 364 | static ssize_t uv_query_max_guest_addr(struct kobject *kobj, |
| 365 | 365 | struct kobj_attribute *attr, char *page) |
| 366 | 366 | { |
| 367 | − return snprintf(page, PAGE_SIZE, "%lx\n", | |
| 367 | + return scnprintf(page, PAGE_SIZE, "%lx\n", | |
| 368 | 368 | uv_info.max_sec_stor_addr); |
| 369 | 369 | } |
| 370 | 370 | |
| @@ -18,8 +18,8 @@ KBUILD_AFLAGS_64 += -m64 -s · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) |
| 20 | 20 | KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin |
| 21 | −KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ | |
| 22 | − -Wl,--hash-style=both | |
| 21 | +ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \ | |
| 22 | + --hash-style=both --build-id -T | |
| 23 | 23 | |
| 24 | 24 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) |
| 25 | 25 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) |
| @@ -37,8 +37,8 @@ KASAN_SANITIZE := n · 11 unmodified lines | ||
| 37 | 37 | $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so |
| 38 | 38 | |
| 39 | 39 | # link rule for the .so file, .lds has to be first |
| 40 | −$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE | |
| 41 | − $(call if_changed,vdso64ld) | |
| 40 | +$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) FORCE | |
| 41 | + $(call if_changed,ld) | |
| 42 | 42 | |
| 43 | 43 | # strip rule for the .so file |
| 44 | 44 | $(obj)/%.so: OBJCOPYFLAGS := -S |
| @@ -50,8 +50,6 @@ $(obj-vdso64): %.o: %.S FORCE · 5 unmodified lines | ||
| 50 | 50 | $(call if_changed_dep,vdso64as) |
| 51 | 51 | |
| 52 | 52 | # actual build commands |
| 53 | −quiet_cmd_vdso64ld = VDSO64L $@ | |
| 54 | − cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@ | |
| 55 | 53 | quiet_cmd_vdso64as = VDSO64A $@ |
| 56 | 54 | cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $< |
| 57 | 55 | |
| @@ -17,12 +17,14 @@ · 16 unmodified lines | ||
| 17 | 17 | .type __kernel_clock_getres,@function |
| 18 | 18 | __kernel_clock_getres: |
| 19 | 19 | CFI_STARTPROC |
| 20 | − larl %r1,4f | |
| 20 | + larl %r1,3f | |
| 21 | + lg %r0,0(%r1) | |
| 21 | 22 | cghi %r2,__CLOCK_REALTIME_COARSE |
| 22 | 23 | je 0f |
| 23 | 24 | cghi %r2,__CLOCK_MONOTONIC_COARSE |
| 24 | 25 | je 0f |
| 25 | − larl %r1,3f | |
| 26 | + larl %r1,_vdso_data | |
| 27 | + llgf %r0,__VDSO_CLOCK_REALTIME_RES(%r1) | |
| 26 | 28 | cghi %r2,__CLOCK_REALTIME |
| 27 | 29 | je 0f |
| 28 | 30 | cghi %r2,__CLOCK_MONOTONIC |
| @@ -36,7 +38,6 @@ __kernel_clock_getres: · 7 unmodified lines | ||
| 36 | 38 | jz 2f |
| 37 | 39 | 0: ltgr %r3,%r3 |
| 38 | 40 | jz 1f /* res == NULL */ |
| 39 | − lg %r0,0(%r1) | |
| 40 | 41 | xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */ |
| 41 | 42 | stg %r0,8(%r3) /* store tp->tv_usec */ |
| 42 | 43 | 1: lghi %r2,0 |
| @@ -45,6 +46,5 @@ __kernel_clock_getres: · 2 unmodified lines | ||
| 45 | 46 | svc 0 |
| 46 | 47 | br %r14 |
| 47 | 48 | CFI_ENDPROC |
| 48 | −3: .quad __CLOCK_REALTIME_RES | |
| 49 | −4: .quad __CLOCK_COARSE_RES | |
| 49 | +3: .quad __CLOCK_COARSE_RES | |
| 50 | 50 | .size __kernel_clock_getres,.-__kernel_clock_getres |
| @@ -105,7 +105,7 @@ static int bad_address(void *p) · 104 unmodified lines | ||
| 105 | 105 | { |
| 106 | 106 | unsigned long dummy; |
| 107 | 107 | |
| 108 | − return probe_kernel_address((unsigned long *)p, dummy); | |
| 108 | + return get_kernel_nofault(dummy, (unsigned long *)p); | |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | 111 | static void dump_pagetable(unsigned long asce, unsigned long address) |
| @@ -119,7 +119,7 @@ static void ftrace_mod_code(void) · 118 unmodified lines | ||
| 119 | 119 | * But if one were to fail, then they all should, and if one were |
| 120 | 120 | * to succeed, then they all should. |
| 121 | 121 | */ |
| 122 | − mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, | |
| 122 | + mod_code_status = copy_to_kernel_nofault(mod_code_ip, mod_code_newcode, | |
| 123 | 123 | MCOUNT_INSN_SIZE); |
| 124 | 124 | |
| 125 | 125 | /* if we fail, then kill any new writers */ |
| @@ -203,7 +203,7 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code, · 77 unmodified lines | ||
| 203 | 203 | */ |
| 204 | 204 | |
| 205 | 205 | /* read the text we want to modify */ |
| 206 | − if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 206 | + if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 207 | 207 | return -EFAULT; |
| 208 | 208 | |
| 209 | 209 | /* Make sure it is what we expect it to be */ |
| @@ -268,7 +268,7 @@ static int ftrace_mod(unsigned long ip, unsigned long old_addr, · 58 unmodified lines | ||
| 268 | 268 | { |
| 269 | 269 | unsigned char code[MCOUNT_INSN_SIZE]; |
| 270 | 270 | |
| 271 | − if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 271 | + if (copy_from_kernel_nofault(code, (void *)ip, MCOUNT_INSN_SIZE)) | |
| 272 | 272 | return -EFAULT; |
| 273 | 273 | |
| 274 | 274 | if (old_addr != __raw_readl((unsigned long *)code)) |
| @@ -118,7 +118,7 @@ int is_valid_bugaddr(unsigned long addr) · 117 unmodified lines | ||
| 118 | 118 | |
| 119 | 119 | if (addr < PAGE_OFFSET) |
| 120 | 120 | return 0; |
| 121 | − if (probe_kernel_address((insn_size_t *)addr, opcode)) | |
| 121 | + if (get_kernel_nofault(opcode, (insn_size_t *)addr)) | |
| 122 | 122 | return 0; |
| 123 | 123 | if (opcode == TRAPA_BUG_OPCODE) |
| 124 | 124 | return 1; |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/kernel.h> |
| 8 | 8 | #include <os.h> |
| 9 | 9 | |
| 10 | −bool probe_kernel_read_allowed(const void *src, size_t size) | |
| 10 | +bool copy_from_kernel_nofault_allowed(const void *src, size_t size) | |
| 11 | 11 | { |
| 12 | 12 | void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE); |
| 13 | 13 | |
| @@ -67,7 +67,7 @@ config X86 · 66 unmodified lines | ||
| 67 | 67 | select ARCH_HAS_FILTER_PGPROT |
| 68 | 68 | select ARCH_HAS_FORTIFY_SOURCE |
| 69 | 69 | select ARCH_HAS_GCOV_PROFILE_ALL |
| 70 | − select ARCH_HAS_KCOV if X86_64 | |
| 70 | + select ARCH_HAS_KCOV if X86_64 && STACK_VALIDATION | |
| 71 | 71 | select ARCH_HAS_MEM_ENCRYPT |
| 72 | 72 | select ARCH_HAS_MEMBARRIER_SYNC_CORE |
| 73 | 73 | select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE |
| @@ -213,7 +213,6 @@ SYM_FUNC_START(startup_32) · 212 unmodified lines | ||
| 213 | 213 | * We place all of the values on our mini stack so lret can |
| 214 | 214 | * used to perform that far jump. |
| 215 | 215 | */ |
| 216 | − pushl $__KERNEL_CS | |
| 217 | 216 | leal startup_64(%ebp), %eax |
| 218 | 217 | #ifdef CONFIG_EFI_MIXED |
| 219 | 218 | movl efi32_boot_args(%ebp), %edi |
| @@ -224,11 +223,20 @@ SYM_FUNC_START(startup_32) · 4 unmodified lines | ||
| 224 | 223 | movl efi32_boot_args+8(%ebp), %edx // saved bootparams pointer |
| 225 | 224 | cmpl $0, %edx |
| 226 | 225 | jnz 1f |
| 226 | + /* | |
| 227 | + * efi_pe_entry uses MS calling convention, which requires 32 bytes of | |
| 228 | + * shadow space on the stack even if all arguments are passed in | |
| 229 | + * registers. We also need an additional 8 bytes for the space that | |
| 230 | + * would be occupied by the return address, and this also results in | |
| 231 | + * the correct stack alignment for entry. | |
| 232 | + */ | |
| 233 | + subl $40, %esp | |
| 227 | 234 | leal efi_pe_entry(%ebp), %eax |
| 228 | 235 | movl %edi, %ecx // MS calling convention |
| 229 | 236 | movl %esi, %edx |
| 230 | 237 | 1: |
| 231 | 238 | #endif |
| 239 | + pushl $__KERNEL_CS | |
| 232 | 240 | pushl %eax |
| 233 | 241 | |
| 234 | 242 | /* Enter paged protected Mode, activating Long Mode */ |
| @@ -784,6 +792,7 @@ SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0) · 549 unmodified lines | ||
| 784 | 792 | |
| 785 | 793 | SYM_DATA_START_LOCAL(boot_stack) |
| 786 | 794 | .fill BOOT_STACK_SIZE, 1, 0 |
| 795 | + .balign 16 | |
| 787 | 796 | SYM_DATA_END_LABEL(boot_stack, SYM_L_LOCAL, boot_stack_end) |
| 788 | 797 | |
| 789 | 798 | /* |
| @@ -45,6 +45,32 @@ · 44 unmodified lines | ||
| 45 | 45 | #define CREATE_TRACE_POINTS |
| 46 | 46 | #include <trace/events/syscalls.h> |
| 47 | 47 | |
| 48 | +/* Check that the stack and regs on entry from user mode are sane. */ | |
| 49 | +static void check_user_regs(struct pt_regs *regs) | |
| 50 | +{ | |
| 51 | + if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) { | |
| 52 | + /* | |
| 53 | + * Make sure that the entry code gave us a sensible EFLAGS | |
| 54 | + * register. Native because we want to check the actual CPU | |
| 55 | + * state, not the interrupt state as imagined by Xen. | |
| 56 | + */ | |
| 57 | + unsigned long flags = native_save_fl(); | |
| 58 | + WARN_ON_ONCE(flags & (X86_EFLAGS_AC | X86_EFLAGS_DF | | |
| 59 | + X86_EFLAGS_NT)); | |
| 60 | + | |
| 61 | + /* We think we came from user mode. Make sure pt_regs agrees. */ | |
| 62 | + WARN_ON_ONCE(!user_mode(regs)); | |
| 63 | + | |
| 64 | + /* | |
| 65 | + * All entries from user mode (except #DF) should be on the | |
| 66 | + * normal thread stack and should have user pt_regs in the | |
| 67 | + * correct location. | |
| 68 | + */ | |
| 69 | + WARN_ON_ONCE(!on_thread_stack()); | |
| 70 | + WARN_ON_ONCE(regs != task_pt_regs(current)); | |
| 71 | + } | |
| 72 | +} | |
| 73 | + | |
| 48 | 74 | #ifdef CONFIG_CONTEXT_TRACKING |
| 49 | 75 | /** |
| 50 | 76 | * enter_from_user_mode - Establish state when coming from user mode |
| @@ -127,9 +153,6 @@ static long syscall_trace_enter(struct pt_regs *regs) · 76 unmodified lines | ||
| 127 | 153 | unsigned long ret = 0; |
| 128 | 154 | u32 work; |
| 129 | 155 | |
| 130 | − if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) | |
| 131 | − BUG_ON(regs != task_pt_regs(current)); | |
| 132 | − | |
| 133 | 156 | work = READ_ONCE(ti->flags); |
| 134 | 157 | |
| 135 | 158 | if (work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) { |
| @@ -346,6 +369,8 @@ __visible noinstr void do_syscall_64(unsigned long nr, struct pt_regs *regs) · 210 unmodified lines | ||
| 346 | 369 | { |
| 347 | 370 | struct thread_info *ti; |
| 348 | 371 | |
| 372 | + check_user_regs(regs); | |
| 373 | + | |
| 349 | 374 | enter_from_user_mode(); |
| 350 | 375 | instrumentation_begin(); |
| 351 | 376 | |
| @@ -409,6 +434,8 @@ static void do_syscall_32_irqs_on(struct pt_regs *regs) · 57 unmodified lines | ||
| 409 | 434 | /* Handles int $0x80 */ |
| 410 | 435 | __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) |
| 411 | 436 | { |
| 437 | + check_user_regs(regs); | |
| 438 | + | |
| 412 | 439 | enter_from_user_mode(); |
| 413 | 440 | instrumentation_begin(); |
| 414 | 441 | |
| @@ -460,6 +487,8 @@ __visible noinstr long do_fast_syscall_32(struct pt_regs *regs) · 45 unmodified lines | ||
| 460 | 487 | vdso_image_32.sym_int80_landing_pad; |
| 461 | 488 | bool success; |
| 462 | 489 | |
| 490 | + check_user_regs(regs); | |
| 491 | + | |
| 463 | 492 | /* |
| 464 | 493 | * SYSENTER loses EIP, and even SYSCALL32 needs us to skip forward |
| 465 | 494 | * so that 'regs->ip -= 2' lands back on an int $0x80 instruction. |
| @@ -510,6 +539,18 @@ __visible noinstr long do_fast_syscall_32(struct pt_regs *regs) · 44 unmodified lines | ||
| 510 | 539 | (regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF | X86_EFLAGS_VM)) == 0; |
| 511 | 540 | #endif |
| 512 | 541 | } |
| 542 | + | |
| 543 | +/* Returns 0 to return using IRET or 1 to return using SYSEXIT/SYSRETL. */ | |
| 544 | +__visible noinstr long do_SYSENTER_32(struct pt_regs *regs) | |
| 545 | +{ | |
| 546 | + /* SYSENTER loses RSP, but the vDSO saved it in RBP. */ | |
| 547 | + regs->sp = regs->bp; | |
| 548 | + | |
| 549 | + /* SYSENTER clobbers EFLAGS.IF. Assume it was set in usermode. */ | |
| 550 | + regs->flags |= X86_EFLAGS_IF; | |
| 551 | + | |
| 552 | + return do_fast_syscall_32(regs); | |
| 553 | +} | |
| 513 | 554 | #endif |
| 514 | 555 | |
| 515 | 556 | SYSCALL_DEFINE0(ni_syscall) |
| @@ -553,6 +594,7 @@ SYSCALL_DEFINE0(ni_syscall) · 37 unmodified lines | ||
| 553 | 594 | bool noinstr idtentry_enter_cond_rcu(struct pt_regs *regs) |
| 554 | 595 | { |
| 555 | 596 | if (user_mode(regs)) { |
| 597 | + check_user_regs(regs); | |
| 556 | 598 | enter_from_user_mode(); |
| 557 | 599 | return false; |
| 558 | 600 | } |
| @@ -686,6 +728,7 @@ void noinstr idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit) · 127 unmodified lines | ||
| 686 | 728 | */ |
| 687 | 729 | void noinstr idtentry_enter_user(struct pt_regs *regs) |
| 688 | 730 | { |
| 731 | + check_user_regs(regs); | |
| 689 | 732 | enter_from_user_mode(); |
| 690 | 733 | } |
| 691 | 734 | |
| @@ -933,9 +933,8 @@ SYM_FUNC_START(entry_SYSENTER_32) · 932 unmodified lines | ||
| 933 | 933 | |
| 934 | 934 | .Lsysenter_past_esp: |
| 935 | 935 | pushl $__USER_DS /* pt_regs->ss */ |
| 936 | − pushl %ebp /* pt_regs->sp (stashed in bp) */ | |
| 936 | + pushl $0 /* pt_regs->sp (placeholder) */ | |
| 937 | 937 | pushfl /* pt_regs->flags (except IF = 0) */ |
| 938 | − orl $X86_EFLAGS_IF, (%esp) /* Fix IF */ | |
| 939 | 938 | pushl $__USER_CS /* pt_regs->cs */ |
| 940 | 939 | pushl $0 /* pt_regs->ip = 0 (placeholder) */ |
| 941 | 940 | pushl %eax /* pt_regs->orig_ax */ |
| @@ -965,7 +964,7 @@ SYM_FUNC_START(entry_SYSENTER_32) · 23 unmodified lines | ||
| 965 | 964 | .Lsysenter_flags_fixed: |
| 966 | 965 | |
| 967 | 966 | movl %esp, %eax |
| 968 | − call do_fast_syscall_32 | |
| 967 | + call do_SYSENTER_32 | |
| 969 | 968 | /* XEN PV guests always use IRET path */ |
| 970 | 969 | ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \ |
| 971 | 970 | "jmp .Lsyscall_32_done", X86_FEATURE_XENPV |
| @@ -57,29 +57,30 @@ SYM_CODE_START(entry_SYSENTER_compat) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| 59 | 59 | |
| 60 | − /* | |
| 61 | − * User tracing code (ptrace or signal handlers) might assume that | |
| 62 | − * the saved RAX contains a 32-bit number when we're invoking a 32-bit | |
| 63 | − * syscall. Just in case the high bits are nonzero, zero-extend | |
| 64 | − * the syscall number. (This could almost certainly be deleted | |
| 65 | − * with no ill effects.) | |
| 66 | − */ | |
| 67 | − movl %eax, %eax | |
| 68 | − | |
| 69 | 60 | /* Construct struct pt_regs on stack */ |
| 70 | 61 | pushq $__USER32_DS /* pt_regs->ss */ |
| 71 | − pushq %rbp /* pt_regs->sp (stashed in bp) */ | |
| 62 | + pushq $0 /* pt_regs->sp = 0 (placeholder) */ | |
| 72 | 63 | |
| 73 | 64 | /* |
| 74 | 65 | * Push flags. This is nasty. First, interrupts are currently |
| 75 | − * off, but we need pt_regs->flags to have IF set. Second, even | |
| 76 | − * if TF was set when SYSENTER started, it's clear by now. We fix | |
| 77 | − * that later using TIF_SINGLESTEP. | |
| 66 | + * off, but we need pt_regs->flags to have IF set. Second, if TS | |
| 67 | + * was set in usermode, it's still set, and we're singlestepping | |
| 68 | + * through this code. do_SYSENTER_32() will fix up IF. | |
| 78 | 69 | */ |
| 79 | 70 | pushfq /* pt_regs->flags (except IF = 0) */ |
| 80 | − orl $X86_EFLAGS_IF, (%rsp) /* Fix saved flags */ | |
| 81 | 71 | pushq $__USER32_CS /* pt_regs->cs */ |
| 82 | 72 | pushq $0 /* pt_regs->ip = 0 (placeholder) */ |
| 73 | +SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL) | |
| 74 | + | |
| 75 | + /* | |
| 76 | + * User tracing code (ptrace or signal handlers) might assume that | |
| 77 | + * the saved RAX contains a 32-bit number when we're invoking a 32-bit | |
| 78 | + * syscall. Just in case the high bits are nonzero, zero-extend | |
| 79 | + * the syscall number. (This could almost certainly be deleted | |
| 80 | + * with no ill effects.) | |
| 81 | + */ | |
| 82 | + movl %eax, %eax | |
| 83 | + | |
| 83 | 84 | pushq %rax /* pt_regs->orig_ax */ |
| 84 | 85 | pushq %rdi /* pt_regs->di */ |
| 85 | 86 | pushq %rsi /* pt_regs->si */ |
| @@ -135,7 +136,7 @@ SYM_CODE_START(entry_SYSENTER_compat) · 49 unmodified lines | ||
| 135 | 136 | .Lsysenter_flags_fixed: |
| 136 | 137 | |
| 137 | 138 | movq %rsp, %rdi |
| 138 | − call do_fast_syscall_32 | |
| 139 | + call do_SYSENTER_32 | |
| 139 | 140 | /* XEN PV guests always use IRET path */ |
| 140 | 141 | ALTERNATIVE "testl %eax, %eax; jz swapgs_restore_regs_and_return_to_usermode", \ |
| 141 | 142 | "jmp swapgs_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | obj-y += core.o probe.o |
| 3 | −obj-$(PERF_EVENTS_INTEL_RAPL) += rapl.o | |
| 3 | +obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += rapl.o | |
| 4 | 4 | obj-y += amd/ |
| 5 | 5 | obj-$(CONFIG_X86_LOCAL_APIC) += msr.o |
| 6 | 6 | obj-$(CONFIG_CPU_SUP_INTEL) += intel/ |
| @@ -375,7 +375,10 @@ void __init hyperv_init(void) · 374 unmodified lines | ||
| 375 | 375 | guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); |
| 376 | 376 | wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id); |
| 377 | 377 | |
| 378 | − hv_hypercall_pg = vmalloc_exec(PAGE_SIZE); | |
| 378 | + hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, | |
| 379 | + VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX, | |
| 380 | + VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, | |
| 381 | + __builtin_return_address(0)); | |
| 379 | 382 | if (hv_hypercall_pg == NULL) { |
| 380 | 383 | wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); |
| 381 | 384 | goto remove_cpuhp_state; |
| @@ -201,12 +201,8 @@ arch_test_and_change_bit(long nr, volatile unsigned long *addr) · 200 unmodified lines | ||
| 201 | 201 | return GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btc), *addr, c, "Ir", nr); |
| 202 | 202 | } |
| 203 | 203 | |
| 204 | −static __no_kcsan_or_inline bool constant_test_bit(long nr, const volatile unsigned long *addr) | |
| 204 | +static __always_inline bool constant_test_bit(long nr, const volatile unsigned long *addr) | |
| 205 | 205 | { |
| 206 | − /* | |
| 207 | − * Because this is a plain access, we need to disable KCSAN here to | |
| 208 | − * avoid double instrumentation via instrumented bitops. | |
| 209 | − */ | |
| 210 | 206 | return ((1UL << (nr & (BITS_PER_LONG-1))) & |
| 211 | 207 | (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; |
| 212 | 208 | } |
| @@ -75,6 +75,12 @@ do { \ · 74 unmodified lines | ||
| 75 | 75 | unreachable(); \ |
| 76 | 76 | } while (0) |
| 77 | 77 | |
| 78 | +/* | |
| 79 | + * This instrumentation_begin() is strictly speaking incorrect; but it | |
| 80 | + * suppresses the complaints from WARN()s in noinstr code. If such a WARN() | |
| 81 | + * were to trigger, we'd rather wreck the machine in an attempt to get the | |
| 82 | + * message out than not know about it. | |
| 83 | + */ | |
| 78 | 84 | #define __WARN_FLAGS(flags) \ |
| 79 | 85 | do { \ |
| 80 | 86 | instrumentation_begin(); \ |
| @@ -58,4 +58,9 @@ static inline bool handle_guest_split_lock(unsigned long ip) · 57 unmodified lines | ||
| 58 | 58 | return false; |
| 59 | 59 | } |
| 60 | 60 | #endif |
| 61 | +#ifdef CONFIG_IA32_FEAT_CTL | |
| 62 | +void init_ia32_feat_ctl(struct cpuinfo_x86 *c); | |
| 63 | +#else | |
| 64 | +static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {} | |
| 65 | +#endif | |
| 61 | 66 | #endif /* _ASM_X86_CPU_H */ |
| @@ -11,5 +11,23 @@ extern cpumask_var_t cpu_sibling_setup_mask; · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | extern void setup_cpu_local_masks(void); |
| 13 | 13 | |
| 14 | +/* | |
| 15 | + * NMI and MCE exceptions need cpu_is_offline() _really_ early, | |
| 16 | + * provide an arch_ special for them to avoid instrumentation. | |
| 17 | + */ | |
| 18 | +#if NR_CPUS > 1 | |
| 19 | +static __always_inline bool arch_cpu_online(int cpu) | |
| 20 | +{ | |
| 21 | + return arch_test_bit(cpu, cpumask_bits(cpu_online_mask)); | |
| 22 | +} | |
| 23 | +#else | |
| 24 | +static __always_inline bool arch_cpu_online(int cpu) | |
| 25 | +{ | |
| 26 | + return cpu == 0; | |
| 27 | +} | |
| 28 | +#endif | |
| 29 | + | |
| 30 | +#define arch_cpu_is_offline(cpu) unlikely(!arch_cpu_online(cpu)) | |
| 31 | + | |
| 14 | 32 | #endif /* __ASSEMBLY__ */ |
| 15 | 33 | #endif /* _ASM_X86_CPUMASK_H */ |
| @@ -623,6 +623,11 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) · 622 unmodified lines | ||
| 623 | 623 | * MXCSR and XCR definitions: |
| 624 | 624 | */ |
| 625 | 625 | |
| 626 | +static inline void ldmxcsr(u32 mxcsr) | |
| 627 | +{ | |
| 628 | + asm volatile("ldmxcsr %0" :: "m" (mxcsr)); | |
| 629 | +} | |
| 630 | + | |
| 626 | 631 | extern unsigned int mxcsr_feature_mask; |
| 627 | 632 | |
| 628 | 633 | #define XCR_XFEATURE_ENABLED_MASK 0x00000000 |
| @@ -353,10 +353,6 @@ static __always_inline void __##func(struct pt_regs *regs) · 352 unmodified lines | ||
| 353 | 353 | |
| 354 | 354 | #else /* CONFIG_X86_64 */ |
| 355 | 355 | |
| 356 | −/* Maps to a regular IDTENTRY on 32bit for now */ | |
| 357 | −# define DECLARE_IDTENTRY_IST DECLARE_IDTENTRY | |
| 358 | −# define DEFINE_IDTENTRY_IST DEFINE_IDTENTRY | |
| 359 | − | |
| 360 | 356 | /** |
| 361 | 357 | * DECLARE_IDTENTRY_DF - Declare functions for double fault 32bit variant |
| 362 | 358 | * @vector: Vector number (ignored for C) |
| @@ -387,28 +383,18 @@ __visible noinstr void func(struct pt_regs *regs, \ · 24 unmodified lines | ||
| 387 | 383 | #endif /* !CONFIG_X86_64 */ |
| 388 | 384 | |
| 389 | 385 | /* C-Code mapping */ |
| 386 | +#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW | |
| 387 | +#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW | |
| 388 | + | |
| 389 | +#ifdef CONFIG_X86_64 | |
| 390 | 390 | #define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST |
| 391 | 391 | #define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST |
| 392 | 392 | #define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST |
| 393 | 393 | |
| 394 | −#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW | |
| 395 | −#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW | |
| 396 | − | |
| 397 | 394 | #define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST |
| 398 | 395 | #define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST |
| 399 | 396 | #define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST |
| 400 | − | |
| 401 | −/** | |
| 402 | − * DECLARE_IDTENTRY_XEN - Declare functions for XEN redirect IDT entry points | |
| 403 | − * @vector: Vector number (ignored for C) | |
| 404 | − * @func: Function name of the entry point | |
| 405 | − * | |
| 406 | − * Used for xennmi and xendebug redirections. No DEFINE as this is all ASM | |
| 407 | − * indirection magic. | |
| 408 | − */ | |
| 409 | −#define DECLARE_IDTENTRY_XEN(vector, func) \ | |
| 410 | − asmlinkage void xen_asm_exc_xen##func(void); \ | |
| 411 | − asmlinkage void asm_exc_xen##func(void) | |
| 397 | +#endif | |
| 412 | 398 | |
| 413 | 399 | #else /* !__ASSEMBLY__ */ |
| 414 | 400 | |
| @@ -455,9 +441,6 @@ __visible noinstr void func(struct pt_regs *regs, \ · 40 unmodified lines | ||
| 455 | 441 | # define DECLARE_IDTENTRY_MCE(vector, func) \ |
| 456 | 442 | DECLARE_IDTENTRY(vector, func) |
| 457 | 443 | |
| 458 | −# define DECLARE_IDTENTRY_DEBUG(vector, func) \ | |
| 459 | − DECLARE_IDTENTRY(vector, func) | |
| 460 | − | |
| 461 | 444 | /* No ASM emitted for DF as this goes through a C shim */ |
| 462 | 445 | # define DECLARE_IDTENTRY_DF(vector, func) |
| 463 | 446 | |
| @@ -469,10 +452,6 @@ __visible noinstr void func(struct pt_regs *regs, \ · 5 unmodified lines | ||
| 469 | 452 | /* No ASM code emitted for NMI */ |
| 470 | 453 | #define DECLARE_IDTENTRY_NMI(vector, func) |
| 471 | 454 | |
| 472 | −/* XEN NMI and DB wrapper */ | |
| 473 | −#define DECLARE_IDTENTRY_XEN(vector, func) \ | |
| 474 | − idtentry vector asm_exc_xen##func exc_##func has_error_code=0 | |
| 475 | − | |
| 476 | 455 | /* |
| 477 | 456 | * ASM code to emit the common vector entry stubs where each stub is |
| 478 | 457 | * packed into 8 bytes. |
| @@ -565,16 +544,28 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); · 86 unmodified lines | ||
| 565 | 544 | DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault); |
| 566 | 545 | |
| 567 | 546 | #ifdef CONFIG_X86_MCE |
| 547 | +#ifdef CONFIG_X86_64 | |
| 568 | 548 | DECLARE_IDTENTRY_MCE(X86_TRAP_MC, exc_machine_check); |
| 549 | +#else | |
| 550 | +DECLARE_IDTENTRY_RAW(X86_TRAP_MC, exc_machine_check); | |
| 551 | +#endif | |
| 569 | 552 | #endif |
| 570 | 553 | |
| 571 | 554 | /* NMI */ |
| 572 | 555 | DECLARE_IDTENTRY_NMI(X86_TRAP_NMI, exc_nmi); |
| 573 | −DECLARE_IDTENTRY_XEN(X86_TRAP_NMI, nmi); | |
| 556 | +#ifdef CONFIG_XEN_PV | |
| 557 | +DECLARE_IDTENTRY_RAW(X86_TRAP_NMI, xenpv_exc_nmi); | |
| 558 | +#endif | |
| 574 | 559 | |
| 575 | 560 | /* #DB */ |
| 561 | +#ifdef CONFIG_X86_64 | |
| 576 | 562 | DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB, exc_debug); |
| 577 | −DECLARE_IDTENTRY_XEN(X86_TRAP_DB, debug); | |
| 563 | +#else | |
| 564 | +DECLARE_IDTENTRY_RAW(X86_TRAP_DB, exc_debug); | |
| 565 | +#endif | |
| 566 | +#ifdef CONFIG_XEN_PV | |
| 567 | +DECLARE_IDTENTRY_RAW(X86_TRAP_DB, xenpv_exc_debug); | |
| 568 | +#endif | |
| 578 | 569 | |
| 579 | 570 | /* #DF */ |
| 580 | 571 | DECLARE_IDTENTRY_DF(X86_TRAP_DF, exc_double_fault); |
| @@ -943,7 +943,7 @@ struct kvm_arch { · 942 unmodified lines | ||
| 943 | 943 | atomic_t vapics_in_nmi_mode; |
| 944 | 944 | struct mutex apic_map_lock; |
| 945 | 945 | struct kvm_apic_map *apic_map; |
| 946 | − bool apic_map_dirty; | |
| 946 | + atomic_t apic_map_dirty; | |
| 947 | 947 | |
| 948 | 948 | bool apic_access_page_done; |
| 949 | 949 | unsigned long apicv_inhibit_reasons; |
| @@ -1220,7 +1220,7 @@ struct kvm_x86_ops { · 270 unmodified lines | ||
| 1220 | 1220 | void (*enable_log_dirty_pt_masked)(struct kvm *kvm, |
| 1221 | 1221 | struct kvm_memory_slot *slot, |
| 1222 | 1222 | gfn_t offset, unsigned long mask); |
| 1223 | − int (*write_log_dirty)(struct kvm_vcpu *vcpu); | |
| 1223 | + int (*write_log_dirty)(struct kvm_vcpu *vcpu, gpa_t l2_gpa); | |
| 1224 | 1224 | |
| 1225 | 1225 | /* pmu operations of sub-arch */ |
| 1226 | 1226 | const struct kvm_pmu_ops *pmu_ops; |
| @@ -25,8 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | #define TPAUSE_C01_STATE 1 |
| 26 | 26 | #define TPAUSE_C02_STATE 0 |
| 27 | 27 | |
| 28 | −u32 get_umwait_control_msr(void); | |
| 29 | − | |
| 30 | 28 | static inline void __monitor(const void *eax, unsigned long ecx, |
| 31 | 29 | unsigned long edx) |
| 32 | 30 | { |
| @@ -194,6 +194,7 @@ enum page_cache_mode { · 193 unmodified lines | ||
| 194 | 194 | #define _PAGE_TABLE_NOENC (__PP|__RW|_USR|___A| 0|___D| 0| 0) |
| 195 | 195 | #define _PAGE_TABLE (__PP|__RW|_USR|___A| 0|___D| 0| 0| _ENC) |
| 196 | 196 | #define __PAGE_KERNEL_RO (__PP| 0| 0|___A|__NX|___D| 0|___G) |
| 197 | +#define __PAGE_KERNEL_ROX (__PP| 0| 0|___A| 0|___D| 0|___G) | |
| 197 | 198 | #define __PAGE_KERNEL_NOCACHE (__PP|__RW| 0|___A|__NX|___D| 0|___G| __NC) |
| 198 | 199 | #define __PAGE_KERNEL_VVAR (__PP| 0|_USR|___A|__NX|___D| 0|___G) |
| 199 | 200 | #define __PAGE_KERNEL_LARGE (__PP|__RW| 0|___A|__NX|___D|_PSE|___G) |
| @@ -219,6 +220,7 @@ enum page_cache_mode { · 19 unmodified lines | ||
| 219 | 220 | #define PAGE_KERNEL_RO __pgprot_mask(__PAGE_KERNEL_RO | _ENC) |
| 220 | 221 | #define PAGE_KERNEL_EXEC __pgprot_mask(__PAGE_KERNEL_EXEC | _ENC) |
| 221 | 222 | #define PAGE_KERNEL_EXEC_NOENC __pgprot_mask(__PAGE_KERNEL_EXEC | 0) |
| 223 | +#define PAGE_KERNEL_ROX __pgprot_mask(__PAGE_KERNEL_ROX | _ENC) | |
| 222 | 224 | #define PAGE_KERNEL_NOCACHE __pgprot_mask(__PAGE_KERNEL_NOCACHE | _ENC) |
| 223 | 225 | #define PAGE_KERNEL_LARGE __pgprot_mask(__PAGE_KERNEL_LARGE | _ENC) |
| 224 | 226 | #define PAGE_KERNEL_LARGE_EXEC __pgprot_mask(__PAGE_KERNEL_LARGE_EXEC | _ENC) |
| @@ -370,7 +370,7 @@ struct x86_hw_tss { · 369 unmodified lines | ||
| 370 | 370 | #define IO_BITMAP_OFFSET_INVALID (__KERNEL_TSS_LIMIT + 1) |
| 371 | 371 | |
| 372 | 372 | struct entry_stack { |
| 373 | − unsigned long words[64]; | |
| 373 | + char stack[PAGE_SIZE]; | |
| 374 | 374 | }; |
| 375 | 375 | |
| 376 | 376 | struct entry_stack_page { |
| @@ -278,7 +278,7 @@ static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs · 277 unmodified lines | ||
| 278 | 278 | } |
| 279 | 279 | |
| 280 | 280 | /* To avoid include hell, we can't include uaccess.h */ |
| 281 | −extern long probe_kernel_read(void *dst, const void *src, size_t size); | |
| 281 | +extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size); | |
| 282 | 282 | |
| 283 | 283 | /** |
| 284 | 284 | * regs_get_kernel_stack_nth() - get Nth entry of the stack |
| @@ -298,7 +298,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, · 13 unmodified lines | ||
| 298 | 298 | |
| 299 | 299 | addr = regs_get_kernel_stack_nth_addr(regs, n); |
| 300 | 300 | if (addr) { |
| 301 | − ret = probe_kernel_read(&val, addr, sizeof(val)); | |
| 301 | + ret = copy_from_kernel_nofault(&val, addr, sizeof(val)); | |
| 302 | 302 | if (!ret) |
| 303 | 303 | return val; |
| 304 | 304 | } |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/sched.h> |
| 4 | 4 | #include <linux/sched/clock.h> |
| 5 | 5 | |
| 6 | +#include <asm/cpu.h> | |
| 6 | 7 | #include <asm/cpufeature.h> |
| 7 | 8 | #include <asm/e820/api.h> |
| 8 | 9 | #include <asm/mtrr.h> |
| @@ -347,6 +347,9 @@ out: · 346 unmodified lines | ||
| 347 | 347 | cr4_clear_bits(X86_CR4_UMIP); |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | +/* These bits should not change their value after CPU init is finished. */ | |
| 351 | +static const unsigned long cr4_pinned_mask = | |
| 352 | + X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | X86_CR4_FSGSBASE; | |
| 350 | 353 | static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); |
| 351 | 354 | static unsigned long cr4_pinned_bits __ro_after_init; |
| 352 | 355 | |
| @@ -371,20 +374,20 @@ EXPORT_SYMBOL(native_write_cr0); · 18 unmodified lines | ||
| 371 | 374 | |
| 372 | 375 | void native_write_cr4(unsigned long val) |
| 373 | 376 | { |
| 374 | − unsigned long bits_missing = 0; | |
| 377 | + unsigned long bits_changed = 0; | |
| 375 | 378 | |
| 376 | 379 | set_register: |
| 377 | 380 | asm volatile("mov %0,%%cr4": "+r" (val), "+m" (cr4_pinned_bits)); |
| 378 | 381 | |
| 379 | 382 | if (static_branch_likely(&cr_pinning)) { |
| 380 | − if (unlikely((val & cr4_pinned_bits) != cr4_pinned_bits)) { | |
| 381 | − bits_missing = ~val & cr4_pinned_bits; | |
| 382 | − val |= bits_missing; | |
| 383 | + if (unlikely((val & cr4_pinned_mask) != cr4_pinned_bits)) { | |
| 384 | + bits_changed = (val & cr4_pinned_mask) ^ cr4_pinned_bits; | |
| 385 | + val = (val & ~cr4_pinned_mask) | cr4_pinned_bits; | |
| 383 | 386 | goto set_register; |
| 384 | 387 | } |
| 385 | − /* Warn after we've set the missing bits. */ | |
| 386 | − WARN_ONCE(bits_missing, "CR4 bits went missing: %lx!?\n", | |
| 387 | − bits_missing); | |
| 388 | + /* Warn after we've corrected the changed bits. */ | |
| 389 | + WARN_ONCE(bits_changed, "pinned CR4 bits changed: 0x%lx!?\n", | |
| 390 | + bits_changed); | |
| 388 | 391 | } |
| 389 | 392 | } |
| 390 | 393 | #if IS_MODULE(CONFIG_LKDTM) |
| @@ -419,7 +422,7 @@ void cr4_init(void) · 28 unmodified lines | ||
| 419 | 422 | if (boot_cpu_has(X86_FEATURE_PCID)) |
| 420 | 423 | cr4 |= X86_CR4_PCIDE; |
| 421 | 424 | if (static_branch_likely(&cr_pinning)) |
| 422 | − cr4 |= cr4_pinned_bits; | |
| 425 | + cr4 = (cr4 & ~cr4_pinned_mask) | cr4_pinned_bits; | |
| 423 | 426 | |
| 424 | 427 | __write_cr4(cr4); |
| 425 | 428 | |
| @@ -434,10 +437,7 @@ void cr4_init(void) · 8 unmodified lines | ||
| 434 | 437 | */ |
| 435 | 438 | static void __init setup_cr_pinning(void) |
| 436 | 439 | { |
| 437 | − unsigned long mask; | |
| 438 | − | |
| 439 | − mask = (X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP); | |
| 440 | − cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & mask; | |
| 440 | + cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & cr4_pinned_mask; | |
| 441 | 441 | static_key_enable(&cr_pinning.key); |
| 442 | 442 | } |
| 443 | 443 | |
| @@ -81,8 +81,4 @@ extern void update_srbds_msr(void); · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | extern u64 x86_read_arch_cap_msr(void); |
| 83 | 83 | |
| 84 | −#ifdef CONFIG_IA32_FEAT_CTL | |
| 85 | −void init_ia32_feat_ctl(struct cpuinfo_x86 *c); | |
| 86 | −#endif | |
| 87 | − | |
| 88 | 84 | #endif /* ARCH_X86_CPU_H */ |
| @@ -49,6 +49,13 @@ enum split_lock_detect_state { · 48 unmodified lines | ||
| 49 | 49 | static enum split_lock_detect_state sld_state __ro_after_init = sld_off; |
| 50 | 50 | static u64 msr_test_ctrl_cache __ro_after_init; |
| 51 | 51 | |
| 52 | +/* | |
| 53 | + * With a name like MSR_TEST_CTL it should go without saying, but don't touch | |
| 54 | + * MSR_TEST_CTL unless the CPU is one of the whitelisted models. Writing it | |
| 55 | + * on CPUs that do not support SLD can cause fireworks, even when writing '0'. | |
| 56 | + */ | |
| 57 | +static bool cpu_model_supports_sld __ro_after_init; | |
| 58 | + | |
| 52 | 59 | /* |
| 53 | 60 | * Processors which have self-snooping capability can handle conflicting |
| 54 | 61 | * memory type across CPUs by snooping its own cache. However, there exists |
| @@ -1071,7 +1078,8 @@ static void sld_update_msr(bool on) · 1016 unmodified lines | ||
| 1071 | 1078 | |
| 1072 | 1079 | static void split_lock_init(void) |
| 1073 | 1080 | { |
| 1074 | − split_lock_verify_msr(sld_state != sld_off); | |
| 1081 | + if (cpu_model_supports_sld) | |
| 1082 | + split_lock_verify_msr(sld_state != sld_off); | |
| 1075 | 1083 | } |
| 1076 | 1084 | |
| 1077 | 1085 | static void split_lock_warn(unsigned long ip) |
| @@ -1177,5 +1185,6 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) · 99 unmodified lines | ||
| 1177 | 1185 | return; |
| 1178 | 1186 | } |
| 1179 | 1187 | |
| 1188 | + cpu_model_supports_sld = true; | |
| 1180 | 1189 | split_lock_setup(); |
| 1181 | 1190 | } |
| @@ -1083,7 +1083,7 @@ static noinstr bool mce_check_crashing_cpu(void) · 1082 unmodified lines | ||
| 1083 | 1083 | { |
| 1084 | 1084 | unsigned int cpu = smp_processor_id(); |
| 1085 | 1085 | |
| 1086 | − if (cpu_is_offline(cpu) || | |
| 1086 | + if (arch_cpu_is_offline(cpu) || | |
| 1087 | 1087 | (crashing_cpu != -1 && crashing_cpu != cpu)) { |
| 1088 | 1088 | u64 mcgstatus; |
| 1089 | 1089 | |
| @@ -1901,6 +1901,8 @@ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check; · 811 unmodified lines | ||
| 1901 | 1901 | |
| 1902 | 1902 | static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) |
| 1903 | 1903 | { |
| 1904 | + WARN_ON_ONCE(user_mode(regs)); | |
| 1905 | + | |
| 1904 | 1906 | /* |
| 1905 | 1907 | * Only required when from kernel mode. See |
| 1906 | 1908 | * mce_check_crashing_cpu() for details. |
| @@ -1954,7 +1956,7 @@ DEFINE_IDTENTRY_MCE_USER(exc_machine_check) · 47 unmodified lines | ||
| 1954 | 1956 | } |
| 1955 | 1957 | #else |
| 1956 | 1958 | /* 32bit unified entry point */ |
| 1957 | −DEFINE_IDTENTRY_MCE(exc_machine_check) | |
| 1959 | +DEFINE_IDTENTRY_RAW(exc_machine_check) | |
| 1958 | 1960 | { |
| 1959 | 1961 | unsigned long dr7; |
| 1960 | 1962 | |
| @@ -981,10 +981,10 @@ void resctrl_cpu_detect(struct cpuinfo_x86 *c) · 980 unmodified lines | ||
| 981 | 981 | |
| 982 | 982 | c->x86_cache_max_rmid = ecx; |
| 983 | 983 | c->x86_cache_occ_scale = ebx; |
| 984 | − if (c->x86_vendor == X86_VENDOR_INTEL) | |
| 985 | − c->x86_cache_mbm_width_offset = eax & 0xff; | |
| 986 | − else | |
| 987 | − c->x86_cache_mbm_width_offset = -1; | |
| 984 | + c->x86_cache_mbm_width_offset = eax & 0xff; | |
| 985 | + | |
| 986 | + if (c->x86_vendor == X86_VENDOR_AMD && !c->x86_cache_mbm_width_offset) | |
| 987 | + c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_AMD; | |
| 988 | 988 | } |
| 989 | 989 | } |
| 990 | 990 | |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #define MBA_IS_LINEAR 0x4 |
| 38 | 38 | #define MBA_MAX_MBPS U32_MAX |
| 39 | 39 | #define MAX_MBA_BW_AMD 0x800 |
| 40 | +#define MBM_CNTR_WIDTH_OFFSET_AMD 20 | |
| 40 | 41 | |
| 41 | 42 | #define RMID_VAL_ERROR BIT_ULL(63) |
| 42 | 43 | #define RMID_VAL_UNAVAIL BIT_ULL(62) |
| @@ -1117,6 +1117,7 @@ static int rdt_cdp_peer_get(struct rdt_resource *r, struct rdt_domain *d, · 1116 unmodified lines | ||
| 1117 | 1117 | _d_cdp = rdt_find_domain(_r_cdp, d->id, NULL); |
| 1118 | 1118 | if (WARN_ON(IS_ERR_OR_NULL(_d_cdp))) { |
| 1119 | 1119 | _r_cdp = NULL; |
| 1120 | + _d_cdp = NULL; | |
| 1120 | 1121 | ret = -EINVAL; |
| 1121 | 1122 | } |
| 1122 | 1123 | |
| @@ -18,12 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | */ |
| 19 | 19 | static u32 umwait_control_cached = UMWAIT_CTRL_VAL(100000, UMWAIT_C02_ENABLE); |
| 20 | 20 | |
| 21 | −u32 get_umwait_control_msr(void) | |
| 22 | −{ | |
| 23 | − return umwait_control_cached; | |
| 24 | −} | |
| 25 | −EXPORT_SYMBOL_GPL(get_umwait_control_msr); | |
| 26 | − | |
| 27 | 21 | /* |
| 28 | 22 | * Cache the original IA32_UMWAIT_CONTROL MSR value which is configured by |
| 29 | 23 | * hardware or BIOS before kernel boot. |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #include <linux/sched.h> |
| 3 | 3 | #include <linux/sched/clock.h> |
| 4 | 4 | |
| 5 | +#include <asm/cpu.h> | |
| 5 | 6 | #include <asm/cpufeature.h> |
| 6 | 7 | |
| 7 | 8 | #include "cpu.h" |
| @@ -106,7 +106,7 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) · 105 unmodified lines | ||
| 106 | 106 | bad_ip = user_mode(regs) && |
| 107 | 107 | __chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX); |
| 108 | 108 | |
| 109 | − if (bad_ip || probe_kernel_read(opcodes, (u8 *)prologue, | |
| 109 | + if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue, | |
| 110 | 110 | OPCODE_BUFSIZE)) { |
| 111 | 111 | printk("%sCode: Bad RIP value.\n", loglvl); |
| 112 | 112 | } else { |
| @@ -101,6 +101,12 @@ void kernel_fpu_begin(void) · 100 unmodified lines | ||
| 101 | 101 | copy_fpregs_to_fpstate(¤t->thread.fpu); |
| 102 | 102 | } |
| 103 | 103 | __cpu_invalidate_fpregs_state(); |
| 104 | + | |
| 105 | + if (boot_cpu_has(X86_FEATURE_XMM)) | |
| 106 | + ldmxcsr(MXCSR_DEFAULT); | |
| 107 | + | |
| 108 | + if (boot_cpu_has(X86_FEATURE_FPU)) | |
| 109 | + asm volatile ("fninit"); | |
| 104 | 110 | } |
| 105 | 111 | EXPORT_SYMBOL_GPL(kernel_fpu_begin); |
| 106 | 112 | |
| @@ -86,7 +86,7 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code) · 85 unmodified lines | ||
| 86 | 86 | * sure what we read is what we expected it to be before modifying it. |
| 87 | 87 | */ |
| 88 | 88 | /* read the text we want to modify */ |
| 89 | − if (probe_kernel_read(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) { | |
| 89 | + if (copy_from_kernel_nofault(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) { | |
| 90 | 90 | WARN_ON(1); |
| 91 | 91 | return -EFAULT; |
| 92 | 92 | } |
| @@ -355,7 +355,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 262 unmodified lines | ||
| 355 | 355 | npages = DIV_ROUND_UP(*tramp_size, PAGE_SIZE); |
| 356 | 356 | |
| 357 | 357 | /* Copy ftrace_caller onto the trampoline memory */ |
| 358 | − ret = probe_kernel_read(trampoline, (void *)start_offset, size); | |
| 358 | + ret = copy_from_kernel_nofault(trampoline, (void *)start_offset, size); | |
| 359 | 359 | if (WARN_ON(ret < 0)) |
| 360 | 360 | goto fail; |
| 361 | 361 | |
| @@ -363,13 +363,13 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 1 unmodified line | ||
| 363 | 363 | |
| 364 | 364 | /* The trampoline ends with ret(q) */ |
| 365 | 365 | retq = (unsigned long)ftrace_stub; |
| 366 | − ret = probe_kernel_read(ip, (void *)retq, RET_SIZE); | |
| 366 | + ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE); | |
| 367 | 367 | if (WARN_ON(ret < 0)) |
| 368 | 368 | goto fail; |
| 369 | 369 | |
| 370 | 370 | if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { |
| 371 | 371 | ip = trampoline + (ftrace_regs_caller_ret - ftrace_regs_caller); |
| 372 | − ret = probe_kernel_read(ip, (void *)retq, RET_SIZE); | |
| 372 | + ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE); | |
| 373 | 373 | if (WARN_ON(ret < 0)) |
| 374 | 374 | goto fail; |
| 375 | 375 | } |
| @@ -506,7 +506,7 @@ static void *addr_from_call(void *ptr) · 130 unmodified lines | ||
| 506 | 506 | union text_poke_insn call; |
| 507 | 507 | int ret; |
| 508 | 508 | |
| 509 | − ret = probe_kernel_read(&call, ptr, CALL_INSN_SIZE); | |
| 509 | + ret = copy_from_kernel_nofault(&call, ptr, CALL_INSN_SIZE); | |
| 510 | 510 | if (WARN_ON_ONCE(ret < 0)) |
| 511 | 511 | return NULL; |
| 512 | 512 | |
| @@ -732,11 +732,11 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) · 731 unmodified lines | ||
| 732 | 732 | int err; |
| 733 | 733 | |
| 734 | 734 | bpt->type = BP_BREAKPOINT; |
| 735 | − err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, | |
| 735 | + err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr, | |
| 736 | 736 | BREAK_INSTR_SIZE); |
| 737 | 737 | if (err) |
| 738 | 738 | return err; |
| 739 | − err = probe_kernel_write((char *)bpt->bpt_addr, | |
| 739 | + err = copy_to_kernel_nofault((char *)bpt->bpt_addr, | |
| 740 | 740 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); |
| 741 | 741 | if (!err) |
| 742 | 742 | return err; |
| @@ -768,7 +768,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) · 25 unmodified lines | ||
| 768 | 768 | return 0; |
| 769 | 769 | |
| 770 | 770 | knl_write: |
| 771 | − return probe_kernel_write((char *)bpt->bpt_addr, | |
| 771 | + return copy_to_kernel_nofault((char *)bpt->bpt_addr, | |
| 772 | 772 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); |
| 773 | 773 | } |
| 774 | 774 | |
| @@ -243,7 +243,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) · 242 unmodified lines | ||
| 243 | 243 | * Fortunately, we know that the original code is the ideal 5-byte |
| 244 | 244 | * long NOP. |
| 245 | 245 | */ |
| 246 | − if (probe_kernel_read(buf, (void *)addr, | |
| 246 | + if (copy_from_kernel_nofault(buf, (void *)addr, | |
| 247 | 247 | MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) |
| 248 | 248 | return 0UL; |
| 249 | 249 | |
| @@ -346,7 +346,8 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn) · 96 unmodified lines | ||
| 346 | 346 | return 0; |
| 347 | 347 | |
| 348 | 348 | /* This can access kernel text if given address is not recovered */ |
| 349 | − if (probe_kernel_read(dest, (void *)recovered_insn, MAX_INSN_SIZE)) | |
| 349 | + if (copy_from_kernel_nofault(dest, (void *)recovered_insn, | |
| 350 | + MAX_INSN_SIZE)) | |
| 350 | 351 | return 0; |
| 351 | 352 | |
| 352 | 353 | kernel_insn_init(insn, dest, MAX_INSN_SIZE); |
| @@ -753,16 +754,11 @@ asm( · 400 unmodified lines | ||
| 753 | 754 | NOKPROBE_SYMBOL(kretprobe_trampoline); |
| 754 | 755 | STACK_FRAME_NON_STANDARD(kretprobe_trampoline); |
| 755 | 756 | |
| 756 | −static struct kprobe kretprobe_kprobe = { | |
| 757 | − .addr = (void *)kretprobe_trampoline, | |
| 758 | −}; | |
| 759 | − | |
| 760 | 757 | /* |
| 761 | 758 | * Called from kretprobe_trampoline |
| 762 | 759 | */ |
| 763 | 760 | __used __visible void *trampoline_handler(struct pt_regs *regs) |
| 764 | 761 | { |
| 765 | − struct kprobe_ctlblk *kcb; | |
| 766 | 762 | struct kretprobe_instance *ri = NULL; |
| 767 | 763 | struct hlist_head *head, empty_rp; |
| 768 | 764 | struct hlist_node *tmp; |
| @@ -772,16 +768,12 @@ __used __visible void *trampoline_handler(struct pt_regs *regs) · 3 unmodified lines | ||
| 772 | 768 | void *frame_pointer; |
| 773 | 769 | bool skipped = false; |
| 774 | 770 | |
| 775 | − preempt_disable(); | |
| 776 | − | |
| 777 | 771 | /* |
| 778 | 772 | * Set a dummy kprobe for avoiding kretprobe recursion. |
| 779 | 773 | * Since kretprobe never run in kprobe handler, kprobe must not |
| 780 | 774 | * be running at this point. |
| 781 | 775 | */ |
| 782 | − kcb = get_kprobe_ctlblk(); | |
| 783 | − __this_cpu_write(current_kprobe, &kretprobe_kprobe); | |
| 784 | − kcb->kprobe_status = KPROBE_HIT_ACTIVE; | |
| 776 | + kprobe_busy_begin(); | |
| 785 | 777 | |
| 786 | 778 | INIT_HLIST_HEAD(&empty_rp); |
| 787 | 779 | kretprobe_hash_lock(current, &head, &flags); |
| @@ -857,7 +849,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs) · 69 unmodified lines | ||
| 857 | 849 | __this_cpu_write(current_kprobe, &ri->rp->kp); |
| 858 | 850 | ri->ret_addr = correct_ret_addr; |
| 859 | 851 | ri->rp->handler(ri, regs); |
| 860 | − __this_cpu_write(current_kprobe, &kretprobe_kprobe); | |
| 852 | + __this_cpu_write(current_kprobe, &kprobe_busy); | |
| 861 | 853 | } |
| 862 | 854 | |
| 863 | 855 | recycle_rp_inst(ri, &empty_rp); |
| @@ -873,8 +865,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs) · 9 unmodified lines | ||
| 873 | 865 | |
| 874 | 866 | kretprobe_hash_unlock(current, &flags); |
| 875 | 867 | |
| 876 | − __this_cpu_write(current_kprobe, NULL); | |
| 877 | − preempt_enable(); | |
| 868 | + kprobe_busy_end(); | |
| 878 | 869 | |
| 879 | 870 | hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
| 880 | 871 | hlist_del(&ri->hlist); |
| @@ -56,7 +56,7 @@ found: · 55 unmodified lines | ||
| 56 | 56 | * overwritten by jump destination address. In this case, original |
| 57 | 57 | * bytes must be recovered from op->optinsn.copied_insn buffer. |
| 58 | 58 | */ |
| 59 | − if (probe_kernel_read(buf, (void *)addr, | |
| 59 | + if (copy_from_kernel_nofault(buf, (void *)addr, | |
| 60 | 60 | MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) |
| 61 | 61 | return 0UL; |
| 62 | 62 | |
| @@ -29,6 +29,8 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <asm/mmu_context.h> |
| 30 | 30 | #include <asm/pgtable_areas.h> |
| 31 | 31 | |
| 32 | +#include <xen/xen.h> | |
| 33 | + | |
| 32 | 34 | /* This is a multiple of PAGE_SIZE. */ |
| 33 | 35 | #define LDT_SLOT_STRIDE (LDT_ENTRIES * LDT_ENTRY_SIZE) |
| 34 | 36 | |
| @@ -543,6 +545,28 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount) · 508 unmodified lines | ||
| 543 | 545 | return bytecount; |
| 544 | 546 | } |
| 545 | 547 | |
| 548 | +static bool allow_16bit_segments(void) | |
| 549 | +{ | |
| 550 | + if (!IS_ENABLED(CONFIG_X86_16BIT)) | |
| 551 | + return false; | |
| 552 | + | |
| 553 | +#ifdef CONFIG_XEN_PV | |
| 554 | + /* | |
| 555 | + * Xen PV does not implement ESPFIX64, which means that 16-bit | |
| 556 | + * segments will not work correctly. Until either Xen PV implements | |
| 557 | + * ESPFIX64 and can signal this fact to the guest or unless someone | |
| 558 | + * provides compelling evidence that allowing broken 16-bit segments | |
| 559 | + * is worthwhile, disallow 16-bit segments under Xen PV. | |
| 560 | + */ | |
| 561 | + if (xen_pv_domain()) { | |
| 562 | + pr_info_once("Warning: 16-bit segments do not work correctly in a Xen PV guest\n"); | |
| 563 | + return false; | |
| 564 | + } | |
| 565 | +#endif | |
| 566 | + | |
| 567 | + return true; | |
| 568 | +} | |
| 569 | + | |
| 546 | 570 | static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) |
| 547 | 571 | { |
| 548 | 572 | struct mm_struct *mm = current->mm; |
| @@ -574,7 +598,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) · 25 unmodified lines | ||
| 574 | 598 | /* The user wants to clear the entry. */ |
| 575 | 599 | memset(&ldt, 0, sizeof(ldt)); |
| 576 | 600 | } else { |
| 577 | − if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) { | |
| 601 | + if (!ldt_info.seg_32bit && !allow_16bit_segments()) { | |
| 578 | 602 | error = -EINVAL; |
| 579 | 603 | goto out; |
| 580 | 604 | } |
| @@ -478,7 +478,7 @@ static DEFINE_PER_CPU(unsigned long, nmi_dr7); · 477 unmodified lines | ||
| 478 | 478 | |
| 479 | 479 | DEFINE_IDTENTRY_RAW(exc_nmi) |
| 480 | 480 | { |
| 481 | − if (IS_ENABLED(CONFIG_SMP) && cpu_is_offline(smp_processor_id())) | |
| 481 | + if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id())) | |
| 482 | 482 | return; |
| 483 | 483 | |
| 484 | 484 | if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) { |
| @@ -94,12 +94,12 @@ static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short · 93 unmodified lines | ||
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | static bool probe_list(struct pci_dev *pdev, unsigned short vendor, |
| 97 | − const unsigned char *rom_list) | |
| 97 | + const void *rom_list) | |
| 98 | 98 | { |
| 99 | 99 | unsigned short device; |
| 100 | 100 | |
| 101 | 101 | do { |
| 102 | − if (probe_kernel_address(rom_list, device) != 0) | |
| 102 | + if (get_kernel_nofault(device, rom_list) != 0) | |
| 103 | 103 | device = 0; |
| 104 | 104 | |
| 105 | 105 | if (device && match_id(pdev, vendor, device)) |
| @@ -119,19 +119,19 @@ static struct resource *find_oprom(struct pci_dev *pdev) · 13 unmodified lines | ||
| 119 | 119 | for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) { |
| 120 | 120 | struct resource *res = &adapter_rom_resources[i]; |
| 121 | 121 | unsigned short offset, vendor, device, list, rev; |
| 122 | − const unsigned char *rom; | |
| 122 | + const void *rom; | |
| 123 | 123 | |
| 124 | 124 | if (res->end == 0) |
| 125 | 125 | break; |
| 126 | 126 | |
| 127 | 127 | rom = isa_bus_to_virt(res->start); |
| 128 | − if (probe_kernel_address(rom + 0x18, offset) != 0) | |
| 128 | + if (get_kernel_nofault(offset, rom + 0x18) != 0) | |
| 129 | 129 | continue; |
| 130 | 130 | |
| 131 | − if (probe_kernel_address(rom + offset + 0x4, vendor) != 0) | |
| 131 | + if (get_kernel_nofault(vendor, rom + offset + 0x4) != 0) | |
| 132 | 132 | continue; |
| 133 | 133 | |
| 134 | − if (probe_kernel_address(rom + offset + 0x6, device) != 0) | |
| 134 | + if (get_kernel_nofault(device, rom + offset + 0x6) != 0) | |
| 135 | 135 | continue; |
| 136 | 136 | |
| 137 | 137 | if (match_id(pdev, vendor, device)) { |
| @@ -139,8 +139,8 @@ static struct resource *find_oprom(struct pci_dev *pdev) · 1 unmodified line | ||
| 139 | 139 | break; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | − if (probe_kernel_address(rom + offset + 0x8, list) == 0 && | |
| 143 | − probe_kernel_address(rom + offset + 0xc, rev) == 0 && | |
| 142 | + if (get_kernel_nofault(list, rom + offset + 0x8) == 0 && | |
| 143 | + get_kernel_nofault(rev, rom + offset + 0xc) == 0 && | |
| 144 | 144 | rev >= 3 && list && |
| 145 | 145 | probe_list(pdev, vendor, rom + offset + list)) { |
| 146 | 146 | oprom = res; |
| @@ -183,14 +183,14 @@ static int __init romsignature(const unsigned char *rom) · 36 unmodified lines | ||
| 183 | 183 | const unsigned short * const ptr = (const unsigned short *)rom; |
| 184 | 184 | unsigned short sig; |
| 185 | 185 | |
| 186 | − return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; | |
| 186 | + return get_kernel_nofault(sig, ptr) == 0 && sig == ROMSIGNATURE; | |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | static int __init romchecksum(const unsigned char *rom, unsigned long length) |
| 190 | 190 | { |
| 191 | 191 | unsigned char sum, c; |
| 192 | 192 | |
| 193 | − for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) | |
| 193 | + for (sum = 0; length && get_kernel_nofault(c, rom++) == 0; length--) | |
| 194 | 194 | sum += c; |
| 195 | 195 | return !length && !sum; |
| 196 | 196 | } |
| @@ -211,7 +211,7 @@ void __init probe_roms(void) · 14 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | video_rom_resource.start = start; |
| 213 | 213 | |
| 214 | − if (probe_kernel_address(rom + 2, c) != 0) | |
| 214 | + if (get_kernel_nofault(c, rom + 2) != 0) | |
| 215 | 215 | continue; |
| 216 | 216 | |
| 217 | 217 | /* 0 < length <= 0x7f * 512, historically */ |
| @@ -249,7 +249,7 @@ void __init probe_roms(void) · 31 unmodified lines | ||
| 249 | 249 | if (!romsignature(rom)) |
| 250 | 250 | continue; |
| 251 | 251 | |
| 252 | − if (probe_kernel_address(rom + 2, c) != 0) | |
| 252 | + if (get_kernel_nofault(c, rom + 2) != 0) | |
| 253 | 253 | continue; |
| 254 | 254 | |
| 255 | 255 | /* 0 < length <= 0x7f * 512, historically */ |
| @@ -84,17 +84,16 @@ static inline void cond_local_irq_disable(struct pt_regs *regs) · 83 unmodified lines | ||
| 84 | 84 | local_irq_disable(); |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | −int is_valid_bugaddr(unsigned long addr) | |
| 87 | +__always_inline int is_valid_bugaddr(unsigned long addr) | |
| 88 | 88 | { |
| 89 | − unsigned short ud; | |
| 90 | − | |
| 91 | 89 | if (addr < TASK_SIZE_MAX) |
| 92 | 90 | return 0; |
| 93 | 91 | |
| 94 | − if (probe_kernel_address((unsigned short *)addr, ud)) | |
| 95 | − return 0; | |
| 96 | − | |
| 97 | − return ud == INSN_UD0 || ud == INSN_UD2; | |
| 92 | + /* | |
| 93 | + * We got #UD, if the text isn't readable we'd have gotten | |
| 94 | + * a different exception. | |
| 95 | + */ | |
| 96 | + return *(unsigned short *)addr == INSN_UD2; | |
| 98 | 97 | } |
| 99 | 98 | |
| 100 | 99 | static nokprobe_inline int |
| @@ -216,40 +215,45 @@ static inline void handle_invalid_op(struct pt_regs *regs) · 115 unmodified lines | ||
| 216 | 215 | ILL_ILLOPN, error_get_trap_addr(regs)); |
| 217 | 216 | } |
| 218 | 217 | |
| 219 | −DEFINE_IDTENTRY_RAW(exc_invalid_op) | |
| 218 | +static noinstr bool handle_bug(struct pt_regs *regs) | |
| 220 | 219 | { |
| 221 | − bool rcu_exit; | |
| 220 | + bool handled = false; | |
| 221 | + | |
| 222 | + if (!is_valid_bugaddr(regs->ip)) | |
| 223 | + return handled; | |
| 222 | 224 | |
| 223 | 225 | /* |
| 224 | − * Handle BUG/WARN like NMIs instead of like normal idtentries: | |
| 225 | − * if we bugged/warned in a bad RCU context, for example, the last | |
| 226 | − * thing we want is to BUG/WARN again in the idtentry code, ad | |
| 227 | − * infinitum. | |
| 226 | + * All lies, just get the WARN/BUG out. | |
| 227 | + */ | |
| 228 | + instrumentation_begin(); | |
| 229 | + /* | |
| 230 | + * Since we're emulating a CALL with exceptions, restore the interrupt | |
| 231 | + * state to what it was at the exception site. | |
| 228 | 232 | */ |
| 229 | − if (!user_mode(regs) && is_valid_bugaddr(regs->ip)) { | |
| 230 | − enum bug_trap_type type; | |
| 233 | + if (regs->flags & X86_EFLAGS_IF) | |
| 234 | + raw_local_irq_enable(); | |
| 235 | + if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) { | |
| 236 | + regs->ip += LEN_UD2; | |
| 237 | + handled = true; | |
| 238 | + } | |
| 239 | + if (regs->flags & X86_EFLAGS_IF) | |
| 240 | + raw_local_irq_disable(); | |
| 241 | + instrumentation_end(); | |
| 231 | 242 | |
| 232 | − nmi_enter(); | |
| 233 | − instrumentation_begin(); | |
| 234 | − trace_hardirqs_off_finish(); | |
| 235 | − type = report_bug(regs->ip, regs); | |
| 236 | − if (regs->flags & X86_EFLAGS_IF) | |
| 237 | − trace_hardirqs_on_prepare(); | |
| 238 | − instrumentation_end(); | |
| 239 | − nmi_exit(); | |
| 243 | + return handled; | |
| 244 | +} | |
| 240 | 245 | |
| 241 | − if (type == BUG_TRAP_TYPE_WARN) { | |
| 242 | − /* Skip the ud2. */ | |
| 243 | − regs->ip += LEN_UD2; | |
| 244 | − return; | |
| 245 | − } | |
| 246 | +DEFINE_IDTENTRY_RAW(exc_invalid_op) | |
| 247 | +{ | |
| 248 | + bool rcu_exit; | |
| 246 | 249 | |
| 247 | − /* | |
| 248 | − * Else, if this was a BUG and report_bug returns or if this | |
| 249 | − * was just a normal #UD, we want to continue onward and | |
| 250 | − * crash. | |
| 251 | − */ | |
| 252 | − } | |
| 250 | + /* | |
| 251 | + * We use UD2 as a short encoding for 'CALL __WARN', as such | |
| 252 | + * handle it before exception entry to avoid recursive WARN | |
| 253 | + * in case exception entry is the one triggering WARNs. | |
| 254 | + */ | |
| 255 | + if (!user_mode(regs) && handle_bug(regs)) | |
| 256 | + return; | |
| 253 | 257 | |
| 254 | 258 | rcu_exit = idtentry_enter_cond_rcu(regs); |
| 255 | 259 | instrumentation_begin(); |
| @@ -488,7 +492,8 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs, · 232 unmodified lines | ||
| 488 | 492 | u8 insn_buf[MAX_INSN_SIZE]; |
| 489 | 493 | struct insn insn; |
| 490 | 494 | |
| 491 | − if (probe_kernel_read(insn_buf, (void *)regs->ip, MAX_INSN_SIZE)) | |
| 495 | + if (copy_from_kernel_nofault(insn_buf, (void *)regs->ip, | |
| 496 | + MAX_INSN_SIZE)) | |
| 492 | 497 | return GP_NO_HINT; |
| 493 | 498 | |
| 494 | 499 | kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE); |
| @@ -690,13 +695,13 @@ struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s) · 195 unmodified lines | ||
| 690 | 695 | (struct bad_iret_stack *)__this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1; |
| 691 | 696 | |
| 692 | 697 | /* Copy the IRET target to the temporary storage. */ |
| 693 | − memcpy(&tmp.regs.ip, (void *)s->regs.sp, 5*8); | |
| 698 | + __memcpy(&tmp.regs.ip, (void *)s->regs.sp, 5*8); | |
| 694 | 699 | |
| 695 | 700 | /* Copy the remainder of the stack from the current stack. */ |
| 696 | − memcpy(&tmp, s, offsetof(struct bad_iret_stack, regs.ip)); | |
| 701 | + __memcpy(&tmp, s, offsetof(struct bad_iret_stack, regs.ip)); | |
| 697 | 702 | |
| 698 | 703 | /* Update the entry stack */ |
| 699 | − memcpy(new_stack, &tmp, sizeof(tmp)); | |
| 704 | + __memcpy(new_stack, &tmp, sizeof(tmp)); | |
| 700 | 705 | |
| 701 | 706 | BUG_ON(!user_mode(&new_stack->regs)); |
| 702 | 707 | return new_stack; |
| @@ -864,6 +869,12 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, · 161 unmodified lines | ||
| 864 | 869 | instrumentation_begin(); |
| 865 | 870 | trace_hardirqs_off_finish(); |
| 866 | 871 | |
| 872 | + /* | |
| 873 | + * If something gets miswired and we end up here for a user mode | |
| 874 | + * #DB, we will malfunction. | |
| 875 | + */ | |
| 876 | + WARN_ON_ONCE(user_mode(regs)); | |
| 877 | + | |
| 867 | 878 | /* |
| 868 | 879 | * Catch SYSENTER with TF set and clear DR_STEP. If this hit a |
| 869 | 880 | * watchpoint at the same time then that will still be handled. |
| @@ -882,6 +893,12 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, · 12 unmodified lines | ||
| 882 | 893 | static __always_inline void exc_debug_user(struct pt_regs *regs, |
| 883 | 894 | unsigned long dr6) |
| 884 | 895 | { |
| 896 | + /* | |
| 897 | + * If something gets miswired and we end up here for a kernel mode | |
| 898 | + * #DB, we will malfunction. | |
| 899 | + */ | |
| 900 | + WARN_ON_ONCE(!user_mode(regs)); | |
| 901 | + | |
| 885 | 902 | idtentry_enter_user(regs); |
| 886 | 903 | instrumentation_begin(); |
| 887 | 904 | |
| @@ -912,7 +929,7 @@ DEFINE_IDTENTRY_DEBUG_USER(exc_debug) · 24 unmodified lines | ||
| 912 | 929 | } |
| 913 | 930 | #else |
| 914 | 931 | /* 32 bit does not have separate entry points. */ |
| 915 | −DEFINE_IDTENTRY_DEBUG(exc_debug) | |
| 932 | +DEFINE_IDTENTRY_RAW(exc_debug) | |
| 916 | 933 | { |
| 917 | 934 | unsigned long dr6, dr7; |
| 918 | 935 | |
| @@ -169,6 +169,18 @@ static void kvm_apic_map_free(struct rcu_head *rcu) · 168 unmodified lines | ||
| 169 | 169 | kvfree(map); |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | +/* | |
| 173 | + * CLEAN -> DIRTY and UPDATE_IN_PROGRESS -> DIRTY changes happen without a lock. | |
| 174 | + * | |
| 175 | + * DIRTY -> UPDATE_IN_PROGRESS and UPDATE_IN_PROGRESS -> CLEAN happen with | |
| 176 | + * apic_map_lock_held. | |
| 177 | + */ | |
| 178 | +enum { | |
| 179 | + CLEAN, | |
| 180 | + UPDATE_IN_PROGRESS, | |
| 181 | + DIRTY | |
| 182 | +}; | |
| 183 | + | |
| 172 | 184 | void kvm_recalculate_apic_map(struct kvm *kvm) |
| 173 | 185 | { |
| 174 | 186 | struct kvm_apic_map *new, *old = NULL; |
| @@ -176,17 +188,17 @@ void kvm_recalculate_apic_map(struct kvm *kvm) · 1 unmodified line | ||
| 176 | 188 | int i; |
| 177 | 189 | u32 max_id = 255; /* enough space for any xAPIC ID */ |
| 178 | 190 | |
| 179 | − if (!kvm->arch.apic_map_dirty) { | |
| 180 | − /* | |
| 181 | − * Read kvm->arch.apic_map_dirty before | |
| 182 | − * kvm->arch.apic_map | |
| 183 | − */ | |
| 184 | − smp_rmb(); | |
| 191 | + /* Read kvm->arch.apic_map_dirty before kvm->arch.apic_map. */ | |
| 192 | + if (atomic_read_acquire(&kvm->arch.apic_map_dirty) == CLEAN) | |
| 185 | 193 | return; |
| 186 | − } | |
| 187 | 194 | |
| 188 | 195 | mutex_lock(&kvm->arch.apic_map_lock); |
| 189 | − if (!kvm->arch.apic_map_dirty) { | |
| 196 | + /* | |
| 197 | + * Read kvm->arch.apic_map_dirty before kvm->arch.apic_map | |
| 198 | + * (if clean) or the APIC registers (if dirty). | |
| 199 | + */ | |
| 200 | + if (atomic_cmpxchg_acquire(&kvm->arch.apic_map_dirty, | |
| 201 | + DIRTY, UPDATE_IN_PROGRESS) == CLEAN) { | |
| 190 | 202 | /* Someone else has updated the map. */ |
| 191 | 203 | mutex_unlock(&kvm->arch.apic_map_lock); |
| 192 | 204 | return; |
| @@ -256,11 +268,11 @@ out: · 63 unmodified lines | ||
| 256 | 268 | lockdep_is_held(&kvm->arch.apic_map_lock)); |
| 257 | 269 | rcu_assign_pointer(kvm->arch.apic_map, new); |
| 258 | 270 | /* |
| 259 | − * Write kvm->arch.apic_map before | |
| 260 | − * clearing apic->apic_map_dirty | |
| 271 | + * Write kvm->arch.apic_map before clearing apic->apic_map_dirty. | |
| 272 | + * If another update has come in, leave it DIRTY. | |
| 261 | 273 | */ |
| 262 | − smp_wmb(); | |
| 263 | − kvm->arch.apic_map_dirty = false; | |
| 274 | + atomic_cmpxchg_release(&kvm->arch.apic_map_dirty, | |
| 275 | + UPDATE_IN_PROGRESS, CLEAN); | |
| 264 | 276 | mutex_unlock(&kvm->arch.apic_map_lock); |
| 265 | 277 | |
| 266 | 278 | if (old) |
| @@ -282,20 +294,20 @@ static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) · 15 unmodified lines | ||
| 282 | 294 | else |
| 283 | 295 | static_key_slow_inc(&apic_sw_disabled.key); |
| 284 | 296 | |
| 285 | − apic->vcpu->kvm->arch.apic_map_dirty = true; | |
| 297 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 286 | 298 | } |
| 287 | 299 | } |
| 288 | 300 | |
| 289 | 301 | static inline void kvm_apic_set_xapic_id(struct kvm_lapic *apic, u8 id) |
| 290 | 302 | { |
| 291 | 303 | kvm_lapic_set_reg(apic, APIC_ID, id << 24); |
| 292 | − apic->vcpu->kvm->arch.apic_map_dirty = true; | |
| 304 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 293 | 305 | } |
| 294 | 306 | |
| 295 | 307 | static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id) |
| 296 | 308 | { |
| 297 | 309 | kvm_lapic_set_reg(apic, APIC_LDR, id); |
| 298 | − apic->vcpu->kvm->arch.apic_map_dirty = true; | |
| 310 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 299 | 311 | } |
| 300 | 312 | |
| 301 | 313 | static inline u32 kvm_apic_calc_x2apic_ldr(u32 id) |
| @@ -311,7 +323,7 @@ static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id) · 9 unmodified lines | ||
| 311 | 323 | |
| 312 | 324 | kvm_lapic_set_reg(apic, APIC_ID, id); |
| 313 | 325 | kvm_lapic_set_reg(apic, APIC_LDR, ldr); |
| 314 | − apic->vcpu->kvm->arch.apic_map_dirty = true; | |
| 326 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 315 | 327 | } |
| 316 | 328 | |
| 317 | 329 | static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type) |
| @@ -1976,7 +1988,7 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) · 1658 unmodified lines | ||
| 1976 | 1988 | case APIC_DFR: |
| 1977 | 1989 | if (!apic_x2apic_mode(apic)) { |
| 1978 | 1990 | kvm_lapic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); |
| 1979 | − apic->vcpu->kvm->arch.apic_map_dirty = true; | |
| 1991 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 1980 | 1992 | } else |
| 1981 | 1993 | ret = 1; |
| 1982 | 1994 | break; |
| @@ -2232,7 +2244,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) · 249 unmodified lines | ||
| 2232 | 2244 | static_key_slow_dec_deferred(&apic_hw_disabled); |
| 2233 | 2245 | } else { |
| 2234 | 2246 | static_key_slow_inc(&apic_hw_disabled.key); |
| 2235 | − vcpu->kvm->arch.apic_map_dirty = true; | |
| 2247 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 2236 | 2248 | } |
| 2237 | 2249 | } |
| 2238 | 2250 | |
| @@ -2273,7 +2285,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) · 34 unmodified lines | ||
| 2273 | 2285 | if (!apic) |
| 2274 | 2286 | return; |
| 2275 | 2287 | |
| 2276 | − vcpu->kvm->arch.apic_map_dirty = false; | |
| 2277 | 2288 | /* Stop the timer in case it's a reset to an active apic */ |
| 2278 | 2289 | hrtimer_cancel(&apic->lapic_timer.timer); |
| 2279 | 2290 | |
| @@ -2567,6 +2578,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) · 287 unmodified lines | ||
| 2567 | 2578 | } |
| 2568 | 2579 | memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s)); |
| 2569 | 2580 | |
| 2581 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); | |
| 2570 | 2582 | kvm_recalculate_apic_map(vcpu->kvm); |
| 2571 | 2583 | kvm_apic_set_version(vcpu); |
| 2572 | 2584 | |
| @@ -222,7 +222,7 @@ void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn); · 221 unmodified lines | ||
| 222 | 222 | void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn); |
| 223 | 223 | bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, |
| 224 | 224 | struct kvm_memory_slot *slot, u64 gfn); |
| 225 | −int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu); | |
| 225 | +int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu, gpa_t l2_gpa); | |
| 226 | 226 | |
| 227 | 227 | int kvm_mmu_post_init_vm(struct kvm *kvm); |
| 228 | 228 | void kvm_mmu_pre_destroy_vm(struct kvm *kvm); |
| @@ -1745,10 +1745,10 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm, · 1744 unmodified lines | ||
| 1745 | 1745 | * Emulate arch specific page modification logging for the |
| 1746 | 1746 | * nested hypervisor |
| 1747 | 1747 | */ |
| 1748 | −int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu) | |
| 1748 | +int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu, gpa_t l2_gpa) | |
| 1749 | 1749 | { |
| 1750 | 1750 | if (kvm_x86_ops.write_log_dirty) |
| 1751 | − return kvm_x86_ops.write_log_dirty(vcpu); | |
| 1751 | + return kvm_x86_ops.write_log_dirty(vcpu, l2_gpa); | |
| 1752 | 1752 | |
| 1753 | 1753 | return 0; |
| 1754 | 1754 | } |
| @@ -235,7 +235,7 @@ static inline unsigned FNAME(gpte_access)(u64 gpte) · 234 unmodified lines | ||
| 235 | 235 | static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, |
| 236 | 236 | struct kvm_mmu *mmu, |
| 237 | 237 | struct guest_walker *walker, |
| 238 | − int write_fault) | |
| 238 | + gpa_t addr, int write_fault) | |
| 239 | 239 | { |
| 240 | 240 | unsigned level, index; |
| 241 | 241 | pt_element_t pte, orig_pte; |
| @@ -260,7 +260,7 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, · 18 unmodified lines | ||
| 260 | 260 | !(pte & PT_GUEST_DIRTY_MASK)) { |
| 261 | 261 | trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); |
| 262 | 262 | #if PTTYPE == PTTYPE_EPT |
| 263 | − if (kvm_arch_write_log_dirty(vcpu)) | |
| 263 | + if (kvm_arch_write_log_dirty(vcpu, addr)) | |
| 264 | 264 | return -EINVAL; |
| 265 | 265 | #endif |
| 266 | 266 | pte |= PT_GUEST_DIRTY_MASK; |
| @@ -360,7 +360,6 @@ retry_walk: · 93 unmodified lines | ||
| 360 | 360 | ++walker->level; |
| 361 | 361 | |
| 362 | 362 | do { |
| 363 | − gfn_t real_gfn; | |
| 364 | 363 | unsigned long host_addr; |
| 365 | 364 | |
| 366 | 365 | pt_access = pte_access; |
| @@ -375,7 +374,7 @@ retry_walk: · 8 unmodified lines | ||
| 375 | 374 | walker->table_gfn[walker->level - 1] = table_gfn; |
| 376 | 375 | walker->pte_gpa[walker->level - 1] = pte_gpa; |
| 377 | 376 | |
| 378 | − real_gfn = mmu->translate_gpa(vcpu, gfn_to_gpa(table_gfn), | |
| 377 | + real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(table_gfn), | |
| 379 | 378 | nested_access, |
| 380 | 379 | &walker->fault); |
| 381 | 380 | |
| @@ -389,12 +388,10 @@ retry_walk: · 7 unmodified lines | ||
| 389 | 388 | * information to fix the exit_qualification or exit_info_1 |
| 390 | 389 | * fields. |
| 391 | 390 | */ |
| 392 | − if (unlikely(real_gfn == UNMAPPED_GVA)) | |
| 391 | + if (unlikely(real_gpa == UNMAPPED_GVA)) | |
| 393 | 392 | return 0; |
| 394 | 393 | |
| 395 | − real_gfn = gpa_to_gfn(real_gfn); | |
| 396 | − | |
| 397 | − host_addr = kvm_vcpu_gfn_to_hva_prot(vcpu, real_gfn, | |
| 394 | + host_addr = kvm_vcpu_gfn_to_hva_prot(vcpu, gpa_to_gfn(real_gpa), | |
| 398 | 395 | &walker->pte_writable[walker->level - 1]); |
| 399 | 396 | if (unlikely(kvm_is_error_hva(host_addr))) |
| 400 | 397 | goto error; |
| @@ -457,7 +454,8 @@ retry_walk: · 56 unmodified lines | ||
| 457 | 454 | (PT_GUEST_DIRTY_SHIFT - PT_GUEST_ACCESSED_SHIFT); |
| 458 | 455 | |
| 459 | 456 | if (unlikely(!accessed_dirty)) { |
| 460 | − ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, write_fault); | |
| 457 | + ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, | |
| 458 | + addr, write_fault); | |
| 461 | 459 | if (unlikely(ret < 0)) |
| 462 | 460 | goto error; |
| 463 | 461 | else if (ret) |
| @@ -3344,7 +3344,7 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) · 3343 unmodified lines | ||
| 3344 | 3344 | |
| 3345 | 3345 | void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); |
| 3346 | 3346 | |
| 3347 | −static fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) | |
| 3347 | +static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) | |
| 3348 | 3348 | { |
| 3349 | 3349 | fastpath_t exit_fastpath; |
| 3350 | 3350 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -72,11 +72,24 @@ struct loaded_vmcs { · 71 unmodified lines | ||
| 72 | 72 | struct vmcs_controls_shadow controls_shadow; |
| 73 | 73 | }; |
| 74 | 74 | |
| 75 | +static inline bool is_intr_type(u32 intr_info, u32 type) | |
| 76 | +{ | |
| 77 | + const u32 mask = INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK; | |
| 78 | + | |
| 79 | + return (intr_info & mask) == (INTR_INFO_VALID_MASK | type); | |
| 80 | +} | |
| 81 | + | |
| 82 | +static inline bool is_intr_type_n(u32 intr_info, u32 type, u8 vector) | |
| 83 | +{ | |
| 84 | + const u32 mask = INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK | | |
| 85 | + INTR_INFO_VECTOR_MASK; | |
| 86 | + | |
| 87 | + return (intr_info & mask) == (INTR_INFO_VALID_MASK | type | vector); | |
| 88 | +} | |
| 89 | + | |
| 75 | 90 | static inline bool is_exception_n(u32 intr_info, u8 vector) |
| 76 | 91 | { |
| 77 | − return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | | |
| 78 | − INTR_INFO_VALID_MASK)) == | |
| 79 | − (INTR_TYPE_HARD_EXCEPTION | vector | INTR_INFO_VALID_MASK); | |
| 92 | + return is_intr_type_n(intr_info, INTR_TYPE_HARD_EXCEPTION, vector); | |
| 80 | 93 | } |
| 81 | 94 | |
| 82 | 95 | static inline bool is_debug(u32 intr_info) |
| @@ -106,28 +119,23 @@ static inline bool is_gp_fault(u32 intr_info) · 23 unmodified lines | ||
| 106 | 119 | |
| 107 | 120 | static inline bool is_machine_check(u32 intr_info) |
| 108 | 121 | { |
| 109 | − return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | | |
| 110 | − INTR_INFO_VALID_MASK)) == | |
| 111 | − (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK); | |
| 122 | + return is_exception_n(intr_info, MC_VECTOR); | |
| 112 | 123 | } |
| 113 | 124 | |
| 114 | 125 | /* Undocumented: icebp/int1 */ |
| 115 | 126 | static inline bool is_icebp(u32 intr_info) |
| 116 | 127 | { |
| 117 | − return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | |
| 118 | − == (INTR_TYPE_PRIV_SW_EXCEPTION | INTR_INFO_VALID_MASK); | |
| 128 | + return is_intr_type(intr_info, INTR_TYPE_PRIV_SW_EXCEPTION); | |
| 119 | 129 | } |
| 120 | 130 | |
| 121 | 131 | static inline bool is_nmi(u32 intr_info) |
| 122 | 132 | { |
| 123 | − return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | |
| 124 | − == (INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK); | |
| 133 | + return is_intr_type(intr_info, INTR_TYPE_NMI_INTR); | |
| 125 | 134 | } |
| 126 | 135 | |
| 127 | 136 | static inline bool is_external_intr(u32 intr_info) |
| 128 | 137 | { |
| 129 | − return (intr_info & (INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK)) | |
| 130 | − == (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR); | |
| 138 | + return is_intr_type(intr_info, INTR_TYPE_EXT_INTR); | |
| 131 | 139 | } |
| 132 | 140 | |
| 133 | 141 | enum vmcs_field_width { |
| @@ -6606,23 +6606,6 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx) · 6605 unmodified lines | ||
| 6606 | 6606 | msrs[i].host, false); |
| 6607 | 6607 | } |
| 6608 | 6608 | |
| 6609 | −static void atomic_switch_umwait_control_msr(struct vcpu_vmx *vmx) | |
| 6610 | −{ | |
| 6611 | − u32 host_umwait_control; | |
| 6612 | − | |
| 6613 | − if (!vmx_has_waitpkg(vmx)) | |
| 6614 | − return; | |
| 6615 | − | |
| 6616 | − host_umwait_control = get_umwait_control_msr(); | |
| 6617 | − | |
| 6618 | − if (vmx->msr_ia32_umwait_control != host_umwait_control) | |
| 6619 | − add_atomic_switch_msr(vmx, MSR_IA32_UMWAIT_CONTROL, | |
| 6620 | − vmx->msr_ia32_umwait_control, | |
| 6621 | − host_umwait_control, false); | |
| 6622 | − else | |
| 6623 | − clear_atomic_switch_msr(vmx, MSR_IA32_UMWAIT_CONTROL); | |
| 6624 | −} | |
| 6625 | − | |
| 6626 | 6609 | static void vmx_update_hv_timer(struct kvm_vcpu *vcpu) |
| 6627 | 6610 | { |
| 6628 | 6611 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| @@ -6728,9 +6711,7 @@ reenter_guest: · 99 unmodified lines | ||
| 6728 | 6711 | |
| 6729 | 6712 | pt_guest_enter(vmx); |
| 6730 | 6713 | |
| 6731 | − if (vcpu_to_pmu(vcpu)->version) | |
| 6732 | − atomic_switch_perf_msrs(vmx); | |
| 6733 | − atomic_switch_umwait_control_msr(vmx); | |
| 6714 | + atomic_switch_perf_msrs(vmx); | |
| 6734 | 6715 | |
| 6735 | 6716 | if (enable_preemption_timer) |
| 6736 | 6717 | vmx_update_hv_timer(vcpu); |
| @@ -7501,11 +7482,11 @@ static void vmx_flush_log_dirty(struct kvm *kvm) · 764 unmodified lines | ||
| 7501 | 7482 | kvm_flush_pml_buffers(kvm); |
| 7502 | 7483 | } |
| 7503 | 7484 | |
| 7504 | −static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu) | |
| 7485 | +static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu, gpa_t gpa) | |
| 7505 | 7486 | { |
| 7506 | 7487 | struct vmcs12 *vmcs12; |
| 7507 | 7488 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 7508 | − gpa_t gpa, dst; | |
| 7489 | + gpa_t dst; | |
| 7509 | 7490 | |
| 7510 | 7491 | if (is_guest_mode(vcpu)) { |
| 7511 | 7492 | WARN_ON_ONCE(vmx->nested.pml_full); |
| @@ -7524,7 +7505,7 @@ static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu) · 12 unmodified lines | ||
| 7524 | 7505 | return 1; |
| 7525 | 7506 | } |
| 7526 | 7507 | |
| 7527 | − gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS) & ~0xFFFull; | |
| 7508 | + gpa &= ~0xFFFull; | |
| 7528 | 7509 | dst = vmcs12->pml_address + sizeof(u64) * vmcs12->guest_pml_index; |
| 7529 | 7510 | |
| 7530 | 7511 | if (kvm_write_guest_page(vcpu->kvm, gpa_to_gfn(dst), &gpa, |
| @@ -288,8 +288,6 @@ struct vcpu_vmx { · 287 unmodified lines | ||
| 288 | 288 | |
| 289 | 289 | u64 current_tsc_ratio; |
| 290 | 290 | |
| 291 | − u32 host_pkru; | |
| 292 | − | |
| 293 | 291 | unsigned long host_debugctlmsr; |
| 294 | 292 | |
| 295 | 293 | /* |
| @@ -2856,7 +2856,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 2855 unmodified lines | ||
| 2856 | 2856 | return kvm_mtrr_set_msr(vcpu, msr, data); |
| 2857 | 2857 | case MSR_IA32_APICBASE: |
| 2858 | 2858 | return kvm_set_apic_base(vcpu, msr_info); |
| 2859 | − case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff: | |
| 2859 | + case APIC_BASE_MSR ... APIC_BASE_MSR + 0xff: | |
| 2860 | 2860 | return kvm_x2apic_msr_write(vcpu, msr, data); |
| 2861 | 2861 | case MSR_IA32_TSCDEADLINE: |
| 2862 | 2862 | kvm_set_lapic_tscdeadline_msr(vcpu, data); |
| @@ -3196,7 +3196,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 333 unmodified lines | ||
| 3196 | 3196 | case MSR_IA32_APICBASE: |
| 3197 | 3197 | msr_info->data = kvm_get_apic_base(vcpu); |
| 3198 | 3198 | break; |
| 3199 | − case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff: | |
| 3199 | + case APIC_BASE_MSR ... APIC_BASE_MSR + 0xff: | |
| 3200 | 3200 | return kvm_x2apic_msr_read(vcpu, msr_info->index, &msr_info->data); |
| 3201 | 3201 | case MSR_IA32_TSCDEADLINE: |
| 3202 | 3202 | msr_info->data = kvm_get_lapic_tscdeadline_msr(vcpu); |
| @@ -4603,7 +4603,8 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 1400 unmodified lines | ||
| 4603 | 4603 | r = -EINVAL; |
| 4604 | 4604 | user_tsc_khz = (u32)arg; |
| 4605 | 4605 | |
| 4606 | − if (user_tsc_khz >= kvm_max_guest_tsc_khz) | |
| 4606 | + if (kvm_has_tsc_control && | |
| 4607 | + user_tsc_khz >= kvm_max_guest_tsc_khz) | |
| 4607 | 4608 | goto out; |
| 4608 | 4609 | |
| 4609 | 4610 | if (user_tsc_khz == 0) |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <asm/alternative-asm.h> |
| 9 | 9 | #include <asm/export.h> |
| 10 | 10 | |
| 11 | +.pushsection .noinstr.text, "ax" | |
| 12 | + | |
| 11 | 13 | /* |
| 12 | 14 | * We build a jump to memcpy_orig by default which gets NOPped out on |
| 13 | 15 | * the majority of x86 CPUs which set REP_GOOD. In addition, CPUs which |
| @@ -184,6 +186,8 @@ SYM_FUNC_START_LOCAL(memcpy_orig) · 170 unmodified lines | ||
| 184 | 186 | retq |
| 185 | 187 | SYM_FUNC_END(memcpy_orig) |
| 186 | 188 | |
| 189 | +.popsection | |
| 190 | + | |
| 187 | 191 | #ifndef CONFIG_UML |
| 188 | 192 | |
| 189 | 193 | MCSAFE_TEST_CTL |
| @@ -24,6 +24,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size) · 23 unmodified lines | ||
| 24 | 24 | asm volatile( |
| 25 | 25 | " testq %[size8],%[size8]\n" |
| 26 | 26 | " jz 4f\n" |
| 27 | + " .align 16\n" | |
| 27 | 28 | "0: movq $0,(%[dst])\n" |
| 28 | 29 | " addq $8,%[dst]\n" |
| 29 | 30 | " decl %%ecx ; jnz 0b\n" |
| @@ -99,7 +99,7 @@ check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr, · 98 unmodified lines | ||
| 99 | 99 | return !instr_lo || (instr_lo>>1) == 1; |
| 100 | 100 | case 0x00: |
| 101 | 101 | /* Prefetch instruction is 0x0F0D or 0x0F18 */ |
| 102 | − if (probe_kernel_address(instr, opcode)) | |
| 102 | + if (get_kernel_nofault(opcode, instr)) | |
| 103 | 103 | return 0; |
| 104 | 104 | |
| 105 | 105 | *prefetch = (instr_lo == 0xF) && |
| @@ -133,7 +133,7 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) · 27 unmodified lines | ||
| 133 | 133 | while (instr < max_instr) { |
| 134 | 134 | unsigned char opcode; |
| 135 | 135 | |
| 136 | − if (probe_kernel_address(instr, opcode)) | |
| 136 | + if (get_kernel_nofault(opcode, instr)) | |
| 137 | 137 | break; |
| 138 | 138 | |
| 139 | 139 | instr++; |
| @@ -301,7 +301,7 @@ static int bad_address(void *p) · 161 unmodified lines | ||
| 301 | 301 | { |
| 302 | 302 | unsigned long dummy; |
| 303 | 303 | |
| 304 | − return probe_kernel_address((unsigned long *)p, dummy); | |
| 304 | + return get_kernel_nofault(dummy, (unsigned long *)p); | |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | 307 | static void dump_pagetable(unsigned long address) |
| @@ -442,7 +442,7 @@ static void show_ldttss(const struct desc_ptr *gdt, const char *name, u16 index) · 134 unmodified lines | ||
| 442 | 442 | return; |
| 443 | 443 | } |
| 444 | 444 | |
| 445 | − if (probe_kernel_read(&desc, (void *)(gdt->address + offset), | |
| 445 | + if (copy_from_kernel_nofault(&desc, (void *)(gdt->address + offset), | |
| 446 | 446 | sizeof(struct ldttss_desc))) { |
| 447 | 447 | pr_alert("%s: 0x%hx -- GDT entry is not readable\n", |
| 448 | 448 | name, index); |
| @@ -737,7 +737,7 @@ static void __init test_wp_bit(void) · 736 unmodified lines | ||
| 737 | 737 | |
| 738 | 738 | __set_fixmap(FIX_WP_TEST, __pa_symbol(empty_zero_page), PAGE_KERNEL_RO); |
| 739 | 739 | |
| 740 | − if (probe_kernel_write((char *)fix_to_virt(FIX_WP_TEST), &z, 1)) { | |
| 740 | + if (copy_to_kernel_nofault((char *)fix_to_virt(FIX_WP_TEST), &z, 1)) { | |
| 741 | 741 | clear_fixmap(FIX_WP_TEST); |
| 742 | 742 | printk(KERN_CONT "Ok.\n"); |
| 743 | 743 | return; |
| @@ -9,7 +9,7 @@ static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits) · 8 unmodified lines | ||
| 9 | 9 | return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | −bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) | |
| 12 | +bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) | |
| 13 | 13 | { |
| 14 | 14 | unsigned long vaddr = (unsigned long)unsafe_src; |
| 15 | 15 | |
| @@ -22,7 +22,7 @@ bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) · 6 unmodified lines | ||
| 22 | 22 | canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr; |
| 23 | 23 | } |
| 24 | 24 | #else |
| 25 | −bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) | |
| 25 | +bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) | |
| 26 | 26 | { |
| 27 | 27 | return (unsigned long)unsafe_src >= TASK_SIZE_MAX; |
| 28 | 28 | } |
| @@ -302,7 +302,7 @@ static const struct pci_raw_ops *__init pci_find_bios(void) · 301 unmodified lines | ||
| 302 | 302 | check <= (union bios32 *) __va(0xffff0); |
| 303 | 303 | ++check) { |
| 304 | 304 | long sig; |
| 305 | − if (probe_kernel_address(&check->fields.signature, sig)) | |
| 305 | + if (get_kernel_nofault(sig, &check->fields.signature)) | |
| 306 | 306 | continue; |
| 307 | 307 | |
| 308 | 308 | if (check->fields.signature != BIOS32_SIGNATURE) |
| @@ -287,8 +287,8 @@ void intel_scu_devices_create(void) · 286 unmodified lines | ||
| 287 | 287 | |
| 288 | 288 | adapter = i2c_get_adapter(i2c_bus[i]); |
| 289 | 289 | if (adapter) { |
| 290 | − client = i2c_new_device(adapter, i2c_devs[i]); | |
| 291 | − if (!client) | |
| 290 | + client = i2c_new_client_device(adapter, i2c_devs[i]); | |
| 291 | + if (IS_ERR(client)) | |
| 292 | 292 | pr_err("can't create i2c device %s\n", |
| 293 | 293 | i2c_devs[i]->type); |
| 294 | 294 | } else |
| @@ -193,6 +193,8 @@ static void fix_processor_context(void) · 192 unmodified lines | ||
| 193 | 193 | */ |
| 194 | 194 | static void notrace __restore_processor_state(struct saved_context *ctxt) |
| 195 | 195 | { |
| 196 | + struct cpuinfo_x86 *c; | |
| 197 | + | |
| 196 | 198 | if (ctxt->misc_enable_saved) |
| 197 | 199 | wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable); |
| 198 | 200 | /* |
| @@ -263,6 +265,10 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) · 64 unmodified lines | ||
| 263 | 265 | mtrr_bp_restore(); |
| 264 | 266 | perf_restore_debug_store(); |
| 265 | 267 | msr_restore_context(ctxt); |
| 268 | + | |
| 269 | + c = &cpu_data(smp_processor_id()); | |
| 270 | + if (cpu_has(c, X86_FEATURE_MSR_IA32_FEAT_CTL)) | |
| 271 | + init_ia32_feat_ctl(c); | |
| 266 | 272 | } |
| 267 | 273 | |
| 268 | 274 | /* Needed by apm.c */ |
| @@ -34,6 +34,7 @@ KCOV_INSTRUMENT := n · 33 unmodified lines | ||
| 34 | 34 | PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel |
| 35 | 35 | PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss |
| 36 | 36 | PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING |
| 37 | +PURGATORY_CFLAGS += $(call cc-option,-fno-stack-protector) | |
| 37 | 38 | |
| 38 | 39 | # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That |
| 39 | 40 | # in turn leaves some undefined symbols like __fentry__ in purgatory and not |
| @@ -386,7 +386,7 @@ static void set_aliased_prot(void *v, pgprot_t prot) · 385 unmodified lines | ||
| 386 | 386 | |
| 387 | 387 | preempt_disable(); |
| 388 | 388 | |
| 389 | − probe_kernel_read(&dummy, v, 1); | |
| 389 | + copy_from_kernel_nofault(&dummy, v, 1); | |
| 390 | 390 | |
| 391 | 391 | if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0)) |
| 392 | 392 | BUG(); |
| @@ -598,6 +598,26 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum, · 205 unmodified lines | ||
| 598 | 598 | } |
| 599 | 599 | |
| 600 | 600 | #ifdef CONFIG_X86_64 |
| 601 | +void noist_exc_debug(struct pt_regs *regs); | |
| 602 | + | |
| 603 | +DEFINE_IDTENTRY_RAW(xenpv_exc_nmi) | |
| 604 | +{ | |
| 605 | + /* On Xen PV, NMI doesn't use IST. The C part is the sane as native. */ | |
| 606 | + exc_nmi(regs); | |
| 607 | +} | |
| 608 | + | |
| 609 | +DEFINE_IDTENTRY_RAW(xenpv_exc_debug) | |
| 610 | +{ | |
| 611 | + /* | |
| 612 | + * There's no IST on Xen PV, but we still need to dispatch | |
| 613 | + * to the correct handler. | |
| 614 | + */ | |
| 615 | + if (user_mode(regs)) | |
| 616 | + noist_exc_debug(regs); | |
| 617 | + else | |
| 618 | + exc_debug(regs); | |
| 619 | +} | |
| 620 | + | |
| 601 | 621 | struct trap_array_entry { |
| 602 | 622 | void (*orig)(void); |
| 603 | 623 | void (*xen)(void); |
| @@ -609,18 +629,18 @@ struct trap_array_entry { · 5 unmodified lines | ||
| 609 | 629 | .xen = xen_asm_##func, \ |
| 610 | 630 | .ist_okay = ist_ok } |
| 611 | 631 | |
| 612 | −#define TRAP_ENTRY_REDIR(func, xenfunc, ist_ok) { \ | |
| 632 | +#define TRAP_ENTRY_REDIR(func, ist_ok) { \ | |
| 613 | 633 | .orig = asm_##func, \ |
| 614 | − .xen = xen_asm_##xenfunc, \ | |
| 634 | + .xen = xen_asm_xenpv_##func, \ | |
| 615 | 635 | .ist_okay = ist_ok } |
| 616 | 636 | |
| 617 | 637 | static struct trap_array_entry trap_array[] = { |
| 618 | − TRAP_ENTRY_REDIR(exc_debug, exc_xendebug, true ), | |
| 638 | + TRAP_ENTRY_REDIR(exc_debug, true ), | |
| 619 | 639 | TRAP_ENTRY(exc_double_fault, true ), |
| 620 | 640 | #ifdef CONFIG_X86_MCE |
| 621 | 641 | TRAP_ENTRY(exc_machine_check, true ), |
| 622 | 642 | #endif |
| 623 | − TRAP_ENTRY_REDIR(exc_nmi, exc_xennmi, true ), | |
| 643 | + TRAP_ENTRY_REDIR(exc_nmi, true ), | |
| 624 | 644 | TRAP_ENTRY(exc_int3, false ), |
| 625 | 645 | TRAP_ENTRY(exc_overflow, false ), |
| 626 | 646 | #ifdef CONFIG_IA32_EMULATION |
| @@ -29,10 +29,9 @@ _ASM_NOKPROBE(xen_\name) · 28 unmodified lines | ||
| 29 | 29 | .endm |
| 30 | 30 | |
| 31 | 31 | xen_pv_trap asm_exc_divide_error |
| 32 | −xen_pv_trap asm_exc_debug | |
| 33 | −xen_pv_trap asm_exc_xendebug | |
| 32 | +xen_pv_trap asm_xenpv_exc_debug | |
| 34 | 33 | xen_pv_trap asm_exc_int3 |
| 35 | −xen_pv_trap asm_exc_xennmi | |
| 34 | +xen_pv_trap asm_xenpv_exc_nmi | |
| 36 | 35 | xen_pv_trap asm_exc_overflow |
| 37 | 36 | xen_pv_trap asm_exc_bounds |
| 38 | 37 | xen_pv_trap asm_exc_invalid_op |
| @@ -161,10 +160,22 @@ SYM_FUNC_END(xen_syscall32_target) · 122 unmodified lines | ||
| 161 | 160 | |
| 162 | 161 | /* 32-bit compat sysenter target */ |
| 163 | 162 | SYM_FUNC_START(xen_sysenter_target) |
| 164 | − mov 0*8(%rsp), %rcx | |
| 165 | − mov 1*8(%rsp), %r11 | |
| 166 | − mov 5*8(%rsp), %rsp | |
| 167 | − jmp entry_SYSENTER_compat | |
| 163 | + /* | |
| 164 | + * NB: Xen is polite and clears TF from EFLAGS for us. This means | |
| 165 | + * that we don't need to guard against single step exceptions here. | |
| 166 | + */ | |
| 167 | + popq %rcx | |
| 168 | + popq %r11 | |
| 169 | + | |
| 170 | + /* | |
| 171 | + * Neither Xen nor the kernel really knows what the old SS and | |
| 172 | + * CS were. The kernel expects __USER32_DS and __USER32_CS, so | |
| 173 | + * report those values even though Xen will guess its own values. | |
| 174 | + */ | |
| 175 | + movq $__USER32_DS, 4*8(%rsp) | |
| 176 | + movq $__USER32_CS, 1*8(%rsp) | |
| 177 | + | |
| 178 | + jmp entry_SYSENTER_compat_after_hwframe | |
| 168 | 179 | SYM_FUNC_END(xen_sysenter_target) |
| 169 | 180 | |
| 170 | 181 | #else /* !CONFIG_IA32_EMULATION */ |
| @@ -24,6 +24,19 @@ void blk_flush_integrity(void) · 23 unmodified lines | ||
| 24 | 24 | flush_workqueue(kintegrityd_wq); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | +static void __bio_integrity_free(struct bio_set *bs, | |
| 28 | + struct bio_integrity_payload *bip) | |
| 29 | +{ | |
| 30 | + if (bs && mempool_initialized(&bs->bio_integrity_pool)) { | |
| 31 | + if (bip->bip_vec) | |
| 32 | + bvec_free(&bs->bvec_integrity_pool, bip->bip_vec, | |
| 33 | + bip->bip_slab); | |
| 34 | + mempool_free(bip, &bs->bio_integrity_pool); | |
| 35 | + } else { | |
| 36 | + kfree(bip); | |
| 37 | + } | |
| 38 | +} | |
| 39 | + | |
| 27 | 40 | /** |
| 28 | 41 | * bio_integrity_alloc - Allocate integrity payload and attach it to bio |
| 29 | 42 | * @bio: bio to attach integrity metadata to |
| @@ -78,7 +91,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, · 48 unmodified lines | ||
| 78 | 91 | |
| 79 | 92 | return bip; |
| 80 | 93 | err: |
| 81 | − mempool_free(bip, &bs->bio_integrity_pool); | |
| 94 | + __bio_integrity_free(bs, bip); | |
| 82 | 95 | return ERR_PTR(-ENOMEM); |
| 83 | 96 | } |
| 84 | 97 | EXPORT_SYMBOL(bio_integrity_alloc); |
| @@ -99,14 +112,7 @@ void bio_integrity_free(struct bio *bio) · 14 unmodified lines | ||
| 99 | 112 | kfree(page_address(bip->bip_vec->bv_page) + |
| 100 | 113 | bip->bip_vec->bv_offset); |
| 101 | 114 | |
| 102 | − if (bs && mempool_initialized(&bs->bio_integrity_pool)) { | |
| 103 | − bvec_free(&bs->bvec_integrity_pool, bip->bip_vec, bip->bip_slab); | |
| 104 | − | |
| 105 | − mempool_free(bip, &bs->bio_integrity_pool); | |
| 106 | − } else { | |
| 107 | − kfree(bip); | |
| 108 | − } | |
| 109 | − | |
| 115 | + __bio_integrity_free(bs, bip); | |
| 110 | 116 | bio->bi_integrity = NULL; |
| 111 | 117 | bio->bi_opf &= ~REQ_INTEGRITY; |
| 112 | 118 | } |
| @@ -125,6 +125,9 @@ static const char *const blk_queue_flag_name[] = { · 124 unmodified lines | ||
| 125 | 125 | QUEUE_FLAG_NAME(REGISTERED), |
| 126 | 126 | QUEUE_FLAG_NAME(SCSI_PASSTHROUGH), |
| 127 | 127 | QUEUE_FLAG_NAME(QUIESCED), |
| 128 | + QUEUE_FLAG_NAME(PCI_P2PDMA), | |
| 129 | + QUEUE_FLAG_NAME(ZONE_RESETALL), | |
| 130 | + QUEUE_FLAG_NAME(RQ_ALLOC_TIME), | |
| 128 | 131 | }; |
| 129 | 132 | #undef QUEUE_FLAG_NAME |
| 130 | 133 | |
| @@ -376,7 +376,7 @@ static void __blk_mq_all_tag_iter(struct blk_mq_tags *tags, · 375 unmodified lines | ||
| 376 | 376 | void blk_mq_all_tag_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn, |
| 377 | 377 | void *priv) |
| 378 | 378 | { |
| 379 | − return __blk_mq_all_tag_iter(tags, fn, priv, BT_TAG_ITER_STATIC_RQS); | |
| 379 | + __blk_mq_all_tag_iter(tags, fn, priv, BT_TAG_ITER_STATIC_RQS); | |
| 380 | 380 | } |
| 381 | 381 | |
| 382 | 382 | /** |
| @@ -3479,7 +3479,9 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 3478 unmodified lines | ||
| 3479 | 3479 | |
| 3480 | 3480 | if (set->nr_maps == 1 && nr_hw_queues > nr_cpu_ids) |
| 3481 | 3481 | nr_hw_queues = nr_cpu_ids; |
| 3482 | − if (nr_hw_queues < 1 || nr_hw_queues == set->nr_hw_queues) | |
| 3482 | + if (nr_hw_queues < 1) | |
| 3483 | + return; | |
| 3484 | + if (set->nr_maps == 1 && nr_hw_queues == set->nr_hw_queues) | |
| 3483 | 3485 | return; |
| 3484 | 3486 | |
| 3485 | 3487 | list_for_each_entry(q, &set->tag_list, tag_set_list) |
| @@ -374,8 +374,7 @@ void blk_ksm_destroy(struct blk_keyslot_manager *ksm) · 373 unmodified lines | ||
| 374 | 374 | if (!ksm) |
| 375 | 375 | return; |
| 376 | 376 | kvfree(ksm->slot_hashtable); |
| 377 | − memzero_explicit(ksm->slots, sizeof(ksm->slots[0]) * ksm->num_slots); | |
| 378 | − kvfree(ksm->slots); | |
| 377 | + kvfree_sensitive(ksm->slots, sizeof(ksm->slots[0]) * ksm->num_slots); | |
| 379 | 378 | memzero_explicit(ksm, sizeof(*ksm)); |
| 380 | 379 | } |
| 381 | 380 | EXPORT_SYMBOL_GPL(blk_ksm_destroy); |
| @@ -910,7 +910,7 @@ static bool ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) · 909 unmodified lines | ||
| 910 | 910 | return false; |
| 911 | 911 | |
| 912 | 912 | disk = &vb->vblk.disk; |
| 913 | − uuid_copy(&disk->disk_id, (uuid_t *)(buffer + 0x18 + r_name)); | |
| 913 | + import_uuid(&disk->disk_id, buffer + 0x18 + r_name); | |
| 914 | 914 | return true; |
| 915 | 915 | } |
| 916 | 916 | |
| @@ -93,7 +93,7 @@ struct frag { /* VBLK Fragment handling */ · 92 unmodified lines | ||
| 93 | 93 | u8 num; /* Total number of records */ |
| 94 | 94 | u8 rec; /* This is record number n */ |
| 95 | 95 | u8 map; /* Which portions are in use */ |
| 96 | − u8 data[0]; | |
| 96 | + u8 data[]; | |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | 99 | /* In memory LDM database structures. */ |
| @@ -128,21 +128,15 @@ EXPORT_SYMBOL_GPL(af_alg_release); · 127 unmodified lines | ||
| 128 | 128 | void af_alg_release_parent(struct sock *sk) |
| 129 | 129 | { |
| 130 | 130 | struct alg_sock *ask = alg_sk(sk); |
| 131 | − unsigned int nokey = ask->nokey_refcnt; | |
| 132 | − bool last = nokey && !ask->refcnt; | |
| 131 | + unsigned int nokey = atomic_read(&ask->nokey_refcnt); | |
| 133 | 132 | |
| 134 | 133 | sk = ask->parent; |
| 135 | 134 | ask = alg_sk(sk); |
| 136 | 135 | |
| 137 | − local_bh_disable(); | |
| 138 | − bh_lock_sock(sk); | |
| 139 | − ask->nokey_refcnt -= nokey; | |
| 140 | − if (!last) | |
| 141 | − last = !--ask->refcnt; | |
| 142 | − bh_unlock_sock(sk); | |
| 143 | − local_bh_enable(); | |
| 136 | + if (nokey) | |
| 137 | + atomic_dec(&ask->nokey_refcnt); | |
| 144 | 138 | |
| 145 | − if (last) | |
| 139 | + if (atomic_dec_and_test(&ask->refcnt)) | |
| 146 | 140 | sock_put(sk); |
| 147 | 141 | } |
| 148 | 142 | EXPORT_SYMBOL_GPL(af_alg_release_parent); |
| @@ -187,7 +181,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) · 38 unmodified lines | ||
| 187 | 181 | |
| 188 | 182 | err = -EBUSY; |
| 189 | 183 | lock_sock(sk); |
| 190 | − if (ask->refcnt | ask->nokey_refcnt) | |
| 184 | + if (atomic_read(&ask->refcnt)) | |
| 191 | 185 | goto unlock; |
| 192 | 186 | |
| 193 | 187 | swap(ask->type, type); |
| @@ -236,7 +230,7 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, · 42 unmodified lines | ||
| 236 | 230 | int err = -EBUSY; |
| 237 | 231 | |
| 238 | 232 | lock_sock(sk); |
| 239 | − if (ask->refcnt) | |
| 233 | + if (atomic_read(&ask->refcnt) != atomic_read(&ask->nokey_refcnt)) | |
| 240 | 234 | goto unlock; |
| 241 | 235 | |
| 242 | 236 | type = ask->type; |
| @@ -301,12 +295,14 @@ int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern) · 58 unmodified lines | ||
| 301 | 295 | if (err) |
| 302 | 296 | goto unlock; |
| 303 | 297 | |
| 304 | − if (nokey || !ask->refcnt++) | |
| 298 | + if (atomic_inc_return_relaxed(&ask->refcnt) == 1) | |
| 305 | 299 | sock_hold(sk); |
| 306 | − ask->nokey_refcnt += nokey; | |
| 300 | + if (nokey) { | |
| 301 | + atomic_inc(&ask->nokey_refcnt); | |
| 302 | + atomic_set(&alg_sk(sk2)->nokey_refcnt, 1); | |
| 303 | + } | |
| 307 | 304 | alg_sk(sk2)->parent = sk; |
| 308 | 305 | alg_sk(sk2)->type = type; |
| 309 | − alg_sk(sk2)->nokey_refcnt = nokey; | |
| 310 | 306 | |
| 311 | 307 | newsock->ops = type->ops; |
| 312 | 308 | newsock->state = SS_CONNECTED; |
| @@ -178,8 +178,6 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) · 177 unmodified lines | ||
| 178 | 178 | if (IS_ERR(thread)) |
| 179 | 179 | goto err_put_larval; |
| 180 | 180 | |
| 181 | − wait_for_completion_interruptible(&larval->completion); | |
| 182 | − | |
| 183 | 181 | return NOTIFY_STOP; |
| 184 | 182 | |
| 185 | 183 | err_put_larval: |
| @@ -384,7 +384,7 @@ static int aead_check_key(struct socket *sock) · 383 unmodified lines | ||
| 384 | 384 | struct alg_sock *ask = alg_sk(sk); |
| 385 | 385 | |
| 386 | 386 | lock_sock(sk); |
| 387 | − if (ask->refcnt) | |
| 387 | + if (!atomic_read(&ask->nokey_refcnt)) | |
| 388 | 388 | goto unlock_child; |
| 389 | 389 | |
| 390 | 390 | psk = ask->parent; |
| @@ -396,11 +396,8 @@ static int aead_check_key(struct socket *sock) · 5 unmodified lines | ||
| 396 | 396 | if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY) |
| 397 | 397 | goto unlock; |
| 398 | 398 | |
| 399 | − if (!pask->refcnt++) | |
| 400 | − sock_hold(psk); | |
| 401 | − | |
| 402 | − ask->refcnt = 1; | |
| 403 | − sock_put(psk); | |
| 399 | + atomic_dec(&pask->nokey_refcnt); | |
| 400 | + atomic_set(&ask->nokey_refcnt, 0); | |
| 404 | 401 | |
| 405 | 402 | err = 0; |
| 406 | 403 | |
| @@ -301,7 +301,7 @@ static int hash_check_key(struct socket *sock) · 300 unmodified lines | ||
| 301 | 301 | struct alg_sock *ask = alg_sk(sk); |
| 302 | 302 | |
| 303 | 303 | lock_sock(sk); |
| 304 | − if (ask->refcnt) | |
| 304 | + if (!atomic_read(&ask->nokey_refcnt)) | |
| 305 | 305 | goto unlock_child; |
| 306 | 306 | |
| 307 | 307 | psk = ask->parent; |
| @@ -313,11 +313,8 @@ static int hash_check_key(struct socket *sock) · 5 unmodified lines | ||
| 313 | 313 | if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) |
| 314 | 314 | goto unlock; |
| 315 | 315 | |
| 316 | − if (!pask->refcnt++) | |
| 317 | − sock_hold(psk); | |
| 318 | − | |
| 319 | − ask->refcnt = 1; | |
| 320 | − sock_put(psk); | |
| 316 | + atomic_dec(&pask->nokey_refcnt); | |
| 317 | + atomic_set(&ask->nokey_refcnt, 0); | |
| 321 | 318 | |
| 322 | 319 | err = 0; |
| 323 | 320 | |
| @@ -74,14 +74,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, · 73 unmodified lines | ||
| 74 | 74 | return PTR_ERR(areq); |
| 75 | 75 | |
| 76 | 76 | /* convert iovecs of output buffers into RX SGL */ |
| 77 | − err = af_alg_get_rsgl(sk, msg, flags, areq, -1, &len); | |
| 77 | + err = af_alg_get_rsgl(sk, msg, flags, areq, ctx->used, &len); | |
| 78 | 78 | if (err) |
| 79 | 79 | goto free; |
| 80 | 80 | |
| 81 | − /* Process only as much RX buffers for which we have TX data */ | |
| 82 | − if (len > ctx->used) | |
| 83 | − len = ctx->used; | |
| 84 | − | |
| 85 | 81 | /* |
| 86 | 82 | * If more buffers are to be expected to be processed, process only |
| 87 | 83 | * full block size buffers. |
| @@ -215,7 +211,7 @@ static int skcipher_check_key(struct socket *sock) · 127 unmodified lines | ||
| 215 | 211 | struct alg_sock *ask = alg_sk(sk); |
| 216 | 212 | |
| 217 | 213 | lock_sock(sk); |
| 218 | − if (ask->refcnt) | |
| 214 | + if (!atomic_read(&ask->nokey_refcnt)) | |
| 219 | 215 | goto unlock_child; |
| 220 | 216 | |
| 221 | 217 | psk = ask->parent; |
| @@ -227,11 +223,8 @@ static int skcipher_check_key(struct socket *sock) · 5 unmodified lines | ||
| 227 | 223 | if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) |
| 228 | 224 | goto unlock; |
| 229 | 225 | |
| 230 | − if (!pask->refcnt++) | |
| 231 | − sock_hold(psk); | |
| 232 | − | |
| 233 | − ask->refcnt = 1; | |
| 234 | − sock_put(psk); | |
| 226 | + atomic_dec(&pask->nokey_refcnt); | |
| 227 | + atomic_set(&ask->nokey_refcnt, 0); | |
| 235 | 228 | |
| 236 | 229 | err = 0; |
| 237 | 230 | |
| @@ -1631,10 +1631,12 @@ static int drbg_uninstantiate(struct drbg_state *drbg) · 1630 unmodified lines | ||
| 1631 | 1631 | if (drbg->random_ready.func) { |
| 1632 | 1632 | del_random_ready_callback(&drbg->random_ready); |
| 1633 | 1633 | cancel_work_sync(&drbg->seed_work); |
| 1634 | − crypto_free_rng(drbg->jent); | |
| 1635 | − drbg->jent = NULL; | |
| 1636 | 1634 | } |
| 1637 | 1635 | |
| 1636 | + if (!IS_ERR_OR_NULL(drbg->jent)) | |
| 1637 | + crypto_free_rng(drbg->jent); | |
| 1638 | + drbg->jent = NULL; | |
| 1639 | + | |
| 1638 | 1640 | if (drbg->d_ops) |
| 1639 | 1641 | drbg->d_ops->crypto_fini(drbg); |
| 1640 | 1642 | drbg_dealloc_state(drbg); |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/module.h> |
| 12 | 12 | #include <linux/configfs.h> |
| 13 | 13 | #include <linux/acpi.h> |
| 14 | +#include <linux/security.h> | |
| 14 | 15 | |
| 15 | 16 | #include "acpica/accommon.h" |
| 16 | 17 | #include "acpica/actables.h" |
| @@ -28,7 +29,10 @@ static ssize_t acpi_table_aml_write(struct config_item *cfg, · 11 unmodified lines | ||
| 28 | 29 | { |
| 29 | 30 | const struct acpi_table_header *header = data; |
| 30 | 31 | struct acpi_table *table; |
| 31 | − int ret; | |
| 32 | + int ret = security_locked_down(LOCKDOWN_ACPI_TABLES); | |
| 33 | + | |
| 34 | + if (ret) | |
| 35 | + return ret; | |
| 32 | 36 | |
| 33 | 37 | table = container_of(cfg, struct acpi_table, cfg); |
| 34 | 38 | |
| @@ -228,6 +228,7 @@ static const struct acpi_device_id int3407_device_ids[] = { · 227 unmodified lines | ||
| 228 | 228 | {"INT3407", 0}, |
| 229 | 229 | {"INT3532", 0}, |
| 230 | 230 | {"INTC1047", 0}, |
| 231 | + {"INTC1050", 0}, | |
| 231 | 232 | {"", 0}, |
| 232 | 233 | }; |
| 233 | 234 | MODULE_DEVICE_TABLE(acpi, int3407_device_ids); |
| @@ -25,8 +25,8 @@ static int acpi_fan_remove(struct platform_device *pdev); · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | static const struct acpi_device_id fan_device_ids[] = { |
| 27 | 27 | {"PNP0C0B", 0}, |
| 28 | − {"INT1044", 0}, | |
| 29 | 28 | {"INT3404", 0}, |
| 29 | + {"INTC1044", 0}, | |
| 30 | 30 | {"", 0}, |
| 31 | 31 | }; |
| 32 | 32 | MODULE_DEVICE_TABLE(acpi, fan_device_ids); |
| @@ -938,13 +938,13 @@ static void __exit interrupt_stats_exit(void) · 937 unmodified lines | ||
| 938 | 938 | } |
| 939 | 939 | |
| 940 | 940 | static ssize_t |
| 941 | −acpi_show_profile(struct device *dev, struct device_attribute *attr, | |
| 941 | +acpi_show_profile(struct kobject *kobj, struct kobj_attribute *attr, | |
| 942 | 942 | char *buf) |
| 943 | 943 | { |
| 944 | 944 | return sprintf(buf, "%d\n", acpi_gbl_FADT.preferred_profile); |
| 945 | 945 | } |
| 946 | 946 | |
| 947 | −static const struct device_attribute pm_profile_attr = | |
| 947 | +static const struct kobj_attribute pm_profile_attr = | |
| 948 | 948 | __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL); |
| 949 | 949 | |
| 950 | 950 | static ssize_t hotplug_enabled_show(struct kobject *kobj, |
| @@ -120,7 +120,7 @@ static const u32 tegra_ahb_gizmo[] = { · 119 unmodified lines | ||
| 120 | 120 | struct tegra_ahb { |
| 121 | 121 | void __iomem *regs; |
| 122 | 122 | struct device *dev; |
| 123 | − u32 ctx[0]; | |
| 123 | + u32 ctx[]; | |
| 124 | 124 | }; |
| 125 | 125 | |
| 126 | 126 | static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset) |
| @@ -4686,8 +4686,15 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc) · 4685 unmodified lines | ||
| 4686 | 4686 | |
| 4687 | 4687 | static void binder_free_proc(struct binder_proc *proc) |
| 4688 | 4688 | { |
| 4689 | + struct binder_device *device; | |
| 4690 | + | |
| 4689 | 4691 | BUG_ON(!list_empty(&proc->todo)); |
| 4690 | 4692 | BUG_ON(!list_empty(&proc->delivered_death)); |
| 4693 | + device = container_of(proc->context, struct binder_device, context); | |
| 4694 | + if (refcount_dec_and_test(&device->ref)) { | |
| 4695 | + kfree(proc->context->name); | |
| 4696 | + kfree(device); | |
| 4697 | + } | |
| 4691 | 4698 | binder_alloc_deferred_release(&proc->alloc); |
| 4692 | 4699 | put_task_struct(proc->tsk); |
| 4693 | 4700 | binder_stats_deleted(BINDER_STAT_PROC); |
| @@ -5406,7 +5413,6 @@ static int binder_node_release(struct binder_node *node, int refs) · 712 unmodified lines | ||
| 5406 | 5413 | static void binder_deferred_release(struct binder_proc *proc) |
| 5407 | 5414 | { |
| 5408 | 5415 | struct binder_context *context = proc->context; |
| 5409 | − struct binder_device *device; | |
| 5410 | 5416 | struct rb_node *n; |
| 5411 | 5417 | int threads, nodes, incoming_refs, outgoing_refs, active_transactions; |
| 5412 | 5418 | |
| @@ -5423,12 +5429,6 @@ static void binder_deferred_release(struct binder_proc *proc) · 10 unmodified lines | ||
| 5423 | 5429 | context->binder_context_mgr_node = NULL; |
| 5424 | 5430 | } |
| 5425 | 5431 | mutex_unlock(&context->context_mgr_node_lock); |
| 5426 | − device = container_of(proc->context, struct binder_device, context); | |
| 5427 | − if (refcount_dec_and_test(&device->ref)) { | |
| 5428 | − kfree(context->name); | |
| 5429 | − kfree(device); | |
| 5430 | − } | |
| 5431 | − proc->context = NULL; | |
| 5432 | 5432 | binder_inner_proc_lock(proc); |
| 5433 | 5433 | /* |
| 5434 | 5434 | * Make sure proc stays alive after we |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <linux/workqueue.h> |
| 43 | 43 | #include <linux/scatterlist.h> |
| 44 | 44 | #include <linux/io.h> |
| 45 | −#include <linux/async.h> | |
| 46 | 45 | #include <linux/log2.h> |
| 47 | 46 | #include <linux/slab.h> |
| 48 | 47 | #include <linux/glob.h> |
| @@ -5778,7 +5777,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) · 5729 unmodified lines | ||
| 5778 | 5777 | /* perform each probe asynchronously */ |
| 5779 | 5778 | for (i = 0; i < host->n_ports; i++) { |
| 5780 | 5779 | struct ata_port *ap = host->ports[i]; |
| 5781 | − async_schedule(async_port_probe, ap); | |
| 5780 | + ap->cookie = async_schedule(async_port_probe, ap); | |
| 5782 | 5781 | } |
| 5783 | 5782 | |
| 5784 | 5783 | return 0; |
| @@ -5920,11 +5919,11 @@ void ata_host_detach(struct ata_host *host) · 135 unmodified lines | ||
| 5920 | 5919 | { |
| 5921 | 5920 | int i; |
| 5922 | 5921 | |
| 5923 | − /* Ensure ata_port probe has completed */ | |
| 5924 | − async_synchronize_full(); | |
| 5925 | − | |
| 5926 | − for (i = 0; i < host->n_ports; i++) | |
| 5922 | + for (i = 0; i < host->n_ports; i++) { | |
| 5923 | + /* Ensure ata_port probe has completed */ | |
| 5924 | + async_synchronize_cookie(host->ports[i]->cookie + 1); | |
| 5927 | 5925 | ata_port_detach(host->ports[i]); |
| 5926 | + } | |
| 5928 | 5927 | |
| 5929 | 5928 | /* the host is dead now, dissociate ACPI */ |
| 5930 | 5929 | ata_acpi_dissociate(host); |
| @@ -3684,12 +3684,13 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) · 3683 unmodified lines | ||
| 3684 | 3684 | { |
| 3685 | 3685 | struct scsi_cmnd *scmd = qc->scsicmd; |
| 3686 | 3686 | const u8 *cdb = scmd->cmnd; |
| 3687 | − const u8 *p; | |
| 3688 | 3687 | u8 pg, spg; |
| 3689 | 3688 | unsigned six_byte, pg_len, hdr_len, bd_len; |
| 3690 | 3689 | int len; |
| 3691 | 3690 | u16 fp = (u16)-1; |
| 3692 | 3691 | u8 bp = 0xff; |
| 3692 | + u8 buffer[64]; | |
| 3693 | + const u8 *p = buffer; | |
| 3693 | 3694 | |
| 3694 | 3695 | VPRINTK("ENTER\n"); |
| 3695 | 3696 | |
| @@ -3723,12 +3724,14 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) · 27 unmodified lines | ||
| 3723 | 3724 | if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len) |
| 3724 | 3725 | goto invalid_param_len; |
| 3725 | 3726 | |
| 3726 | − p = page_address(sg_page(scsi_sglist(scmd))); | |
| 3727 | − | |
| 3728 | 3727 | /* Move past header and block descriptors. */ |
| 3729 | 3728 | if (len < hdr_len) |
| 3730 | 3729 | goto invalid_param_len; |
| 3731 | 3730 | |
| 3731 | + if (!sg_copy_to_buffer(scsi_sglist(scmd), scsi_sg_count(scmd), | |
| 3732 | + buffer, sizeof(buffer))) | |
| 3733 | + goto invalid_param_len; | |
| 3734 | + | |
| 3732 | 3735 | if (six_byte) |
| 3733 | 3736 | bd_len = p[3]; |
| 3734 | 3737 | else |
| @@ -907,7 +907,7 @@ static int sata_rcar_probe(struct platform_device *pdev) · 906 unmodified lines | ||
| 907 | 907 | pm_runtime_enable(dev); |
| 908 | 908 | ret = pm_runtime_get_sync(dev); |
| 909 | 909 | if (ret < 0) |
| 910 | − goto err_pm_disable; | |
| 910 | + goto err_pm_put; | |
| 911 | 911 | |
| 912 | 912 | host = ata_host_alloc(dev, 1); |
| 913 | 913 | if (!host) { |
| @@ -937,7 +937,6 @@ static int sata_rcar_probe(struct platform_device *pdev) · 23 unmodified lines | ||
| 937 | 937 | |
| 938 | 938 | err_pm_put: |
| 939 | 939 | pm_runtime_put(dev); |
| 940 | −err_pm_disable: | |
| 941 | 940 | pm_runtime_disable(dev); |
| 942 | 941 | return ret; |
| 943 | 942 | } |
| @@ -991,8 +990,10 @@ static int sata_rcar_resume(struct device *dev) · 47 unmodified lines | ||
| 991 | 990 | int ret; |
| 992 | 991 | |
| 993 | 992 | ret = pm_runtime_get_sync(dev); |
| 994 | − if (ret < 0) | |
| 993 | + if (ret < 0) { | |
| 994 | + pm_runtime_put(dev); | |
| 995 | 995 | return ret; |
| 996 | + } | |
| 996 | 997 | |
| 997 | 998 | if (priv->type == RCAR_GEN3_SATA) { |
| 998 | 999 | sata_rcar_init_module(priv); |
| @@ -1017,8 +1018,10 @@ static int sata_rcar_restore(struct device *dev) · 18 unmodified lines | ||
| 1017 | 1018 | int ret; |
| 1018 | 1019 | |
| 1019 | 1020 | ret = pm_runtime_get_sync(dev); |
| 1020 | − if (ret < 0) | |
| 1021 | + if (ret < 0) { | |
| 1022 | + pm_runtime_put(dev); | |
| 1021 | 1023 | return ret; |
| 1024 | + } | |
| 1022 | 1025 | |
| 1023 | 1026 | sata_rcar_setup_port(host); |
| 1024 | 1027 | |
| @@ -265,14 +265,14 @@ static struct notifier_block pm_trace_nb = { · 264 unmodified lines | ||
| 265 | 265 | .notifier_call = pm_trace_notify, |
| 266 | 266 | }; |
| 267 | 267 | |
| 268 | −static int early_resume_init(void) | |
| 268 | +static int __init early_resume_init(void) | |
| 269 | 269 | { |
| 270 | 270 | hash_value_early_read = read_magic_time(); |
| 271 | 271 | register_pm_notifier(&pm_trace_nb); |
| 272 | 272 | return 0; |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | −static int late_resume_init(void) | |
| 275 | +static int __init late_resume_init(void) | |
| 276 | 276 | { |
| 277 | 277 | unsigned int val = hash_value_early_read; |
| 278 | 278 | unsigned int user, file, dev; |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/delay.h> |
| 18 | 18 | #include <linux/log2.h> |
| 19 | 19 | #include <linux/hwspinlock.h> |
| 20 | +#include <asm/unaligned.h> | |
| 20 | 21 | |
| 21 | 22 | #define CREATE_TRACE_POINTS |
| 22 | 23 | #include "trace.h" |
| @@ -249,22 +250,20 @@ static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) · 226 unmodified lines | ||
| 249 | 250 | |
| 250 | 251 | static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) |
| 251 | 252 | { |
| 252 | − __be16 *b = buf; | |
| 253 | − | |
| 254 | − b[0] = cpu_to_be16(val << shift); | |
| 253 | + put_unaligned_be16(val << shift, buf); | |
| 255 | 254 | } |
| 256 | 255 | |
| 257 | 256 | static void regmap_format_16_le(void *buf, unsigned int val, unsigned int shift) |
| 258 | 257 | { |
| 259 | − __le16 *b = buf; | |
| 260 | − | |
| 261 | − b[0] = cpu_to_le16(val << shift); | |
| 258 | + put_unaligned_le16(val << shift, buf); | |
| 262 | 259 | } |
| 263 | 260 | |
| 264 | 261 | static void regmap_format_16_native(void *buf, unsigned int val, |
| 265 | 262 | unsigned int shift) |
| 266 | 263 | { |
| 267 | − *(u16 *)buf = val << shift; | |
| 264 | + u16 v = val << shift; | |
| 265 | + | |
| 266 | + memcpy(buf, &v, sizeof(v)); | |
| 268 | 267 | } |
| 269 | 268 | |
| 270 | 269 | static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) |
| @@ -280,43 +279,39 @@ static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) · 9 unmodified lines | ||
| 280 | 279 | |
| 281 | 280 | static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) |
| 282 | 281 | { |
| 283 | − __be32 *b = buf; | |
| 284 | − | |
| 285 | − b[0] = cpu_to_be32(val << shift); | |
| 282 | + put_unaligned_be32(val << shift, buf); | |
| 286 | 283 | } |
| 287 | 284 | |
| 288 | 285 | static void regmap_format_32_le(void *buf, unsigned int val, unsigned int shift) |
| 289 | 286 | { |
| 290 | − __le32 *b = buf; | |
| 291 | − | |
| 292 | − b[0] = cpu_to_le32(val << shift); | |
| 287 | + put_unaligned_le32(val << shift, buf); | |
| 293 | 288 | } |
| 294 | 289 | |
| 295 | 290 | static void regmap_format_32_native(void *buf, unsigned int val, |
| 296 | 291 | unsigned int shift) |
| 297 | 292 | { |
| 298 | − *(u32 *)buf = val << shift; | |
| 293 | + u32 v = val << shift; | |
| 294 | + | |
| 295 | + memcpy(buf, &v, sizeof(v)); | |
| 299 | 296 | } |
| 300 | 297 | |
| 301 | 298 | #ifdef CONFIG_64BIT |
| 302 | 299 | static void regmap_format_64_be(void *buf, unsigned int val, unsigned int shift) |
| 303 | 300 | { |
| 304 | − __be64 *b = buf; | |
| 305 | − | |
| 306 | − b[0] = cpu_to_be64((u64)val << shift); | |
| 301 | + put_unaligned_be64((u64) val << shift, buf); | |
| 307 | 302 | } |
| 308 | 303 | |
| 309 | 304 | static void regmap_format_64_le(void *buf, unsigned int val, unsigned int shift) |
| 310 | 305 | { |
| 311 | − __le64 *b = buf; | |
| 312 | − | |
| 313 | − b[0] = cpu_to_le64((u64)val << shift); | |
| 306 | + put_unaligned_le64((u64) val << shift, buf); | |
| 314 | 307 | } |
| 315 | 308 | |
| 316 | 309 | static void regmap_format_64_native(void *buf, unsigned int val, |
| 317 | 310 | unsigned int shift) |
| 318 | 311 | { |
| 319 | − *(u64 *)buf = (u64)val << shift; | |
| 312 | + u64 v = (u64) val << shift; | |
| 313 | + | |
| 314 | + memcpy(buf, &v, sizeof(v)); | |
| 320 | 315 | } |
| 321 | 316 | #endif |
| 322 | 317 | |
| @@ -333,35 +328,34 @@ static unsigned int regmap_parse_8(const void *buf) · 10 unmodified lines | ||
| 333 | 328 | |
| 334 | 329 | static unsigned int regmap_parse_16_be(const void *buf) |
| 335 | 330 | { |
| 336 | − const __be16 *b = buf; | |
| 337 | − | |
| 338 | − return be16_to_cpu(b[0]); | |
| 331 | + return get_unaligned_be16(buf); | |
| 339 | 332 | } |
| 340 | 333 | |
| 341 | 334 | static unsigned int regmap_parse_16_le(const void *buf) |
| 342 | 335 | { |
| 343 | − const __le16 *b = buf; | |
| 344 | − | |
| 345 | − return le16_to_cpu(b[0]); | |
| 336 | + return get_unaligned_le16(buf); | |
| 346 | 337 | } |
| 347 | 338 | |
| 348 | 339 | static void regmap_parse_16_be_inplace(void *buf) |
| 349 | 340 | { |
| 350 | − __be16 *b = buf; | |
| 341 | + u16 v = get_unaligned_be16(buf); | |
| 351 | 342 | |
| 352 | − b[0] = be16_to_cpu(b[0]); | |
| 343 | + memcpy(buf, &v, sizeof(v)); | |
| 353 | 344 | } |
| 354 | 345 | |
| 355 | 346 | static void regmap_parse_16_le_inplace(void *buf) |
| 356 | 347 | { |
| 357 | − __le16 *b = buf; | |
| 348 | + u16 v = get_unaligned_le16(buf); | |
| 358 | 349 | |
| 359 | − b[0] = le16_to_cpu(b[0]); | |
| 350 | + memcpy(buf, &v, sizeof(v)); | |
| 360 | 351 | } |
| 361 | 352 | |
| 362 | 353 | static unsigned int regmap_parse_16_native(const void *buf) |
| 363 | 354 | { |
| 364 | − return *(u16 *)buf; | |
| 355 | + u16 v; | |
| 356 | + | |
| 357 | + memcpy(&v, buf, sizeof(v)); | |
| 358 | + return v; | |
| 365 | 359 | } |
| 366 | 360 | |
| 367 | 361 | static unsigned int regmap_parse_24(const void *buf) |
| @@ -376,69 +370,67 @@ static unsigned int regmap_parse_24(const void *buf) · 8 unmodified lines | ||
| 376 | 370 | |
| 377 | 371 | static unsigned int regmap_parse_32_be(const void *buf) |
| 378 | 372 | { |
| 379 | − const __be32 *b = buf; | |
| 380 | − | |
| 381 | − return be32_to_cpu(b[0]); | |
| 373 | + return get_unaligned_be32(buf); | |
| 382 | 374 | } |
| 383 | 375 | |
| 384 | 376 | static unsigned int regmap_parse_32_le(const void *buf) |
| 385 | 377 | { |
| 386 | − const __le32 *b = buf; | |
| 387 | − | |
| 388 | − return le32_to_cpu(b[0]); | |
| 378 | + return get_unaligned_le32(buf); | |
| 389 | 379 | } |
| 390 | 380 | |
| 391 | 381 | static void regmap_parse_32_be_inplace(void *buf) |
| 392 | 382 | { |
| 393 | − __be32 *b = buf; | |
| 383 | + u32 v = get_unaligned_be32(buf); | |
| 394 | 384 | |
| 395 | − b[0] = be32_to_cpu(b[0]); | |
| 385 | + memcpy(buf, &v, sizeof(v)); | |
| 396 | 386 | } |
| 397 | 387 | |
| 398 | 388 | static void regmap_parse_32_le_inplace(void *buf) |
| 399 | 389 | { |
| 400 | − __le32 *b = buf; | |
| 390 | + u32 v = get_unaligned_le32(buf); | |
| 401 | 391 | |
| 402 | − b[0] = le32_to_cpu(b[0]); | |
| 392 | + memcpy(buf, &v, sizeof(v)); | |
| 403 | 393 | } |
| 404 | 394 | |
| 405 | 395 | static unsigned int regmap_parse_32_native(const void *buf) |
| 406 | 396 | { |
| 407 | − return *(u32 *)buf; | |
| 397 | + u32 v; | |
| 398 | + | |
| 399 | + memcpy(&v, buf, sizeof(v)); | |
| 400 | + return v; | |
| 408 | 401 | } |
| 409 | 402 | |
| 410 | 403 | #ifdef CONFIG_64BIT |
| 411 | 404 | static unsigned int regmap_parse_64_be(const void *buf) |
| 412 | 405 | { |
| 413 | − const __be64 *b = buf; | |
| 414 | − | |
| 415 | − return be64_to_cpu(b[0]); | |
| 406 | + return get_unaligned_be64(buf); | |
| 416 | 407 | } |
| 417 | 408 | |
| 418 | 409 | static unsigned int regmap_parse_64_le(const void *buf) |
| 419 | 410 | { |
| 420 | − const __le64 *b = buf; | |
| 421 | − | |
| 422 | − return le64_to_cpu(b[0]); | |
| 411 | + return get_unaligned_le64(buf); | |
| 423 | 412 | } |
| 424 | 413 | |
| 425 | 414 | static void regmap_parse_64_be_inplace(void *buf) |
| 426 | 415 | { |
| 427 | − __be64 *b = buf; | |
| 416 | + u64 v = get_unaligned_be64(buf); | |
| 428 | 417 | |
| 429 | − b[0] = be64_to_cpu(b[0]); | |
| 418 | + memcpy(buf, &v, sizeof(v)); | |
| 430 | 419 | } |
| 431 | 420 | |
| 432 | 421 | static void regmap_parse_64_le_inplace(void *buf) |
| 433 | 422 | { |
| 434 | − __le64 *b = buf; | |
| 423 | + u64 v = get_unaligned_le64(buf); | |
| 435 | 424 | |
| 436 | − b[0] = le64_to_cpu(b[0]); | |
| 425 | + memcpy(buf, &v, sizeof(v)); | |
| 437 | 426 | } |
| 438 | 427 | |
| 439 | 428 | static unsigned int regmap_parse_64_native(const void *buf) |
| 440 | 429 | { |
| 441 | − return *(u64 *)buf; | |
| 430 | + u64 v; | |
| 431 | + | |
| 432 | + memcpy(&v, buf, sizeof(v)); | |
| 433 | + return v; | |
| 442 | 434 | } |
| 443 | 435 | #endif |
| 444 | 436 | |
| @@ -1357,6 +1349,7 @@ void regmap_exit(struct regmap *map) · 912 unmodified lines | ||
| 1357 | 1349 | if (map->hwlock) |
| 1358 | 1350 | hwspin_lock_free(map->hwlock); |
| 1359 | 1351 | kfree_const(map->name); |
| 1352 | + kfree(map->patch); | |
| 1360 | 1353 | kfree(map); |
| 1361 | 1354 | } |
| 1362 | 1355 | EXPORT_SYMBOL_GPL(regmap_exit); |
| @@ -2944,8 +2937,9 @@ EXPORT_SYMBOL_GPL(regmap_update_bits_base); · 1581 unmodified lines | ||
| 2944 | 2937 | * @reg: Register to read from |
| 2945 | 2938 | * @bits: Bits to test |
| 2946 | 2939 | * |
| 2947 | − * Returns -1 if the underlying regmap_read() fails, 0 if at least one of the | |
| 2948 | − * tested bits is not set and 1 if all tested bits are set. | |
| 2940 | + * Returns 0 if at least one of the tested bits is not set, 1 if all tested | |
| 2941 | + * bits are set and a negative error number if the underlying regmap_read() | |
| 2942 | + * fails. | |
| 2949 | 2943 | */ |
| 2950 | 2944 | int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) |
| 2951 | 2945 | { |
| @@ -620,7 +620,7 @@ struct fifo_buffer { · 619 unmodified lines | ||
| 620 | 620 | unsigned int head_index; |
| 621 | 621 | unsigned int size; |
| 622 | 622 | int total; /* sum of all values */ |
| 623 | − int values[0]; | |
| 623 | + int values[]; | |
| 624 | 624 | }; |
| 625 | 625 | extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size); |
| 626 | 626 | |
| @@ -271,7 +271,7 @@ struct p_rs_param { · 270 unmodified lines | ||
| 271 | 271 | u32 resync_rate; |
| 272 | 272 | |
| 273 | 273 | /* Since protocol version 88 and higher. */ |
| 274 | − char verify_alg[0]; | |
| 274 | + char verify_alg[]; | |
| 275 | 275 | } __packed; |
| 276 | 276 | |
| 277 | 277 | struct p_rs_param_89 { |
| @@ -305,7 +305,7 @@ struct p_protocol { · 27 unmodified lines | ||
| 305 | 305 | u32 two_primaries; |
| 306 | 306 | |
| 307 | 307 | /* Since protocol version 87 and higher. */ |
| 308 | − char integrity_alg[0]; | |
| 308 | + char integrity_alg[]; | |
| 309 | 309 | |
| 310 | 310 | } __packed; |
| 311 | 311 | |
| @@ -360,7 +360,7 @@ struct p_sizes { · 48 unmodified lines | ||
| 360 | 360 | u16 dds_flags; /* use enum dds_flags here. */ |
| 361 | 361 | |
| 362 | 362 | /* optional queue_limits if (agreed_features & DRBD_FF_WSAME) */ |
| 363 | − struct o_qlim qlim[0]; | |
| 363 | + struct o_qlim qlim[]; | |
| 364 | 364 | } __packed; |
| 365 | 365 | |
| 366 | 366 | struct p_state { |
| @@ -409,7 +409,7 @@ struct p_compressed_bm { · 42 unmodified lines | ||
| 409 | 409 | */ |
| 410 | 410 | u8 encoding; |
| 411 | 411 | |
| 412 | − u8 code[0]; | |
| 412 | + u8 code[]; | |
| 413 | 413 | } __packed; |
| 414 | 414 | |
| 415 | 415 | struct p_delay_probe93 { |
| @@ -1368,14 +1368,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) · 1367 unmodified lines | ||
| 1368 | 1368 | lo->lo_sizelimit != info->lo_sizelimit) { |
| 1369 | 1369 | size_changed = true; |
| 1370 | 1370 | sync_blockdev(lo->lo_device); |
| 1371 | − kill_bdev(lo->lo_device); | |
| 1371 | + invalidate_bdev(lo->lo_device); | |
| 1372 | 1372 | } |
| 1373 | 1373 | |
| 1374 | 1374 | /* I/O need to be drained during transfer transition */ |
| 1375 | 1375 | blk_mq_freeze_queue(lo->lo_queue); |
| 1376 | 1376 | |
| 1377 | 1377 | if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) { |
| 1378 | − /* If any pages were dirtied after kill_bdev(), try again */ | |
| 1378 | + /* If any pages were dirtied after invalidate_bdev(), try again */ | |
| 1379 | 1379 | err = -EAGAIN; |
| 1380 | 1380 | pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", |
| 1381 | 1381 | __func__, lo->lo_number, lo->lo_file_name, |
| @@ -1615,11 +1615,11 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) · 233 unmodified lines | ||
| 1615 | 1615 | return 0; |
| 1616 | 1616 | |
| 1617 | 1617 | sync_blockdev(lo->lo_device); |
| 1618 | − kill_bdev(lo->lo_device); | |
| 1618 | + invalidate_bdev(lo->lo_device); | |
| 1619 | 1619 | |
| 1620 | 1620 | blk_mq_freeze_queue(lo->lo_queue); |
| 1621 | 1621 | |
| 1622 | − /* kill_bdev should have truncated all the pages */ | |
| 1622 | + /* invalidate_bdev should have truncated all the pages */ | |
| 1623 | 1623 | if (lo->lo_device->bd_inode->i_mapping->nrpages) { |
| 1624 | 1624 | err = -EAGAIN; |
| 1625 | 1625 | pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", |
| @@ -1451,8 +1451,10 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req) · 1450 unmodified lines | ||
| 1451 | 1451 | static void rbd_osd_format_read(struct ceph_osd_request *osd_req) |
| 1452 | 1452 | { |
| 1453 | 1453 | struct rbd_obj_request *obj_request = osd_req->r_priv; |
| 1454 | + struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev; | |
| 1455 | + struct ceph_options *opt = rbd_dev->rbd_client->client->options; | |
| 1454 | 1456 | |
| 1455 | − osd_req->r_flags = CEPH_OSD_FLAG_READ; | |
| 1457 | + osd_req->r_flags = CEPH_OSD_FLAG_READ | opt->read_from_replica; | |
| 1456 | 1458 | osd_req->r_snapid = obj_request->img_request->snap_id; |
| 1457 | 1459 | } |
| 1458 | 1460 | |
| @@ -878,6 +878,7 @@ out_put_disk: · 877 unmodified lines | ||
| 878 | 878 | put_disk(vblk->disk); |
| 879 | 879 | out_free_vq: |
| 880 | 880 | vdev->config->del_vqs(vdev); |
| 881 | + kfree(vblk->vqs); | |
| 881 | 882 | out_free_vblk: |
| 882 | 883 | kfree(vblk); |
| 883 | 884 | out_free_index: |
| @@ -221,6 +221,35 @@ static u32 sysc_read_sysstatus(struct sysc *ddata) · 220 unmodified lines | ||
| 221 | 221 | return sysc_read(ddata, offset); |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | +/* Poll on reset status */ | |
| 225 | +static int sysc_wait_softreset(struct sysc *ddata) | |
| 226 | +{ | |
| 227 | + u32 sysc_mask, syss_done, rstval; | |
| 228 | + int syss_offset, error = 0; | |
| 229 | + | |
| 230 | + syss_offset = ddata->offsets[SYSC_SYSSTATUS]; | |
| 231 | + sysc_mask = BIT(ddata->cap->regbits->srst_shift); | |
| 232 | + | |
| 233 | + if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) | |
| 234 | + syss_done = 0; | |
| 235 | + else | |
| 236 | + syss_done = ddata->cfg.syss_mask; | |
| 237 | + | |
| 238 | + if (syss_offset >= 0) { | |
| 239 | + error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval, | |
| 240 | + (rstval & ddata->cfg.syss_mask) == | |
| 241 | + syss_done, | |
| 242 | + 100, MAX_MODULE_SOFTRESET_WAIT); | |
| 243 | + | |
| 244 | + } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { | |
| 245 | + error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval, | |
| 246 | + !(rstval & sysc_mask), | |
| 247 | + 100, MAX_MODULE_SOFTRESET_WAIT); | |
| 248 | + } | |
| 249 | + | |
| 250 | + return error; | |
| 251 | +} | |
| 252 | + | |
| 224 | 253 | static int sysc_add_named_clock_from_child(struct sysc *ddata, |
| 225 | 254 | const char *name, |
| 226 | 255 | const char *optfck_name) |
| @@ -925,18 +954,47 @@ static int sysc_enable_module(struct device *dev) · 698 unmodified lines | ||
| 925 | 954 | struct sysc *ddata; |
| 926 | 955 | const struct sysc_regbits *regbits; |
| 927 | 956 | u32 reg, idlemodes, best_mode; |
| 957 | + int error; | |
| 928 | 958 | |
| 929 | 959 | ddata = dev_get_drvdata(dev); |
| 960 | + | |
| 961 | + /* | |
| 962 | + * Some modules like DSS reset automatically on idle. Enable optional | |
| 963 | + * reset clocks and wait for OCP softreset to complete. | |
| 964 | + */ | |
| 965 | + if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET) { | |
| 966 | + error = sysc_enable_opt_clocks(ddata); | |
| 967 | + if (error) { | |
| 968 | + dev_err(ddata->dev, | |
| 969 | + "Optional clocks failed for enable: %i\n", | |
| 970 | + error); | |
| 971 | + return error; | |
| 972 | + } | |
| 973 | + } | |
| 974 | + error = sysc_wait_softreset(ddata); | |
| 975 | + if (error) | |
| 976 | + dev_warn(ddata->dev, "OCP softreset timed out\n"); | |
| 977 | + if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET) | |
| 978 | + sysc_disable_opt_clocks(ddata); | |
| 979 | + | |
| 980 | + /* | |
| 981 | + * Some subsystem private interconnects, like DSS top level module, | |
| 982 | + * need only the automatic OCP softreset handling with no sysconfig | |
| 983 | + * register bits to configure. | |
| 984 | + */ | |
| 930 | 985 | if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) |
| 931 | 986 | return 0; |
| 932 | 987 | |
| 933 | 988 | regbits = ddata->cap->regbits; |
| 934 | 989 | reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); |
| 935 | 990 | |
| 936 | − /* Set CLOCKACTIVITY, we only use it for ick */ | |
| 991 | + /* | |
| 992 | + * Set CLOCKACTIVITY, we only use it for ick. And we only configure it | |
| 993 | + * based on the SYSC_QUIRK_USE_CLOCKACT flag, not based on the hardware | |
| 994 | + * capabilities. See the old HWMOD_SET_DEFAULT_CLOCKACT flag. | |
| 995 | + */ | |
| 937 | 996 | if (regbits->clkact_shift >= 0 && |
| 938 | − (ddata->cfg.quirks & SYSC_QUIRK_USE_CLOCKACT || | |
| 939 | − ddata->cfg.sysc_val & BIT(regbits->clkact_shift))) | |
| 997 | + (ddata->cfg.quirks & SYSC_QUIRK_USE_CLOCKACT)) | |
| 940 | 998 | reg |= SYSC_CLOCACT_ICK << regbits->clkact_shift; |
| 941 | 999 | |
| 942 | 1000 | /* Set SIDLE mode */ |
| @@ -991,6 +1049,9 @@ set_autoidle: · 48 unmodified lines | ||
| 991 | 1049 | sysc_write_sysconfig(ddata, reg); |
| 992 | 1050 | } |
| 993 | 1051 | |
| 1052 | + /* Flush posted write */ | |
| 1053 | + sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); | |
| 1054 | + | |
| 994 | 1055 | if (ddata->module_enable_quirk) |
| 995 | 1056 | ddata->module_enable_quirk(ddata); |
| 996 | 1057 | |
| @@ -1071,6 +1132,9 @@ set_sidle: · 74 unmodified lines | ||
| 1071 | 1132 | reg |= 1 << regbits->autoidle_shift; |
| 1072 | 1133 | sysc_write_sysconfig(ddata, reg); |
| 1073 | 1134 | |
| 1135 | + /* Flush posted write */ | |
| 1136 | + sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); | |
| 1137 | + | |
| 1074 | 1138 | return 0; |
| 1075 | 1139 | } |
| 1076 | 1140 | |
| @@ -1488,7 +1552,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset, · 411 unmodified lines | ||
| 1488 | 1552 | bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false; |
| 1489 | 1553 | const int lcd_en_mask = BIT(0), digit_en_mask = BIT(1); |
| 1490 | 1554 | int manager_count; |
| 1491 | − bool framedonetv_irq; | |
| 1555 | + bool framedonetv_irq = true; | |
| 1492 | 1556 | u32 val, irq_mask = 0; |
| 1493 | 1557 | |
| 1494 | 1558 | switch (sysc_soc->soc) { |
| @@ -1505,6 +1569,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset, · 10 unmodified lines | ||
| 1505 | 1569 | break; |
| 1506 | 1570 | case SOC_AM4: |
| 1507 | 1571 | manager_count = 1; |
| 1572 | + framedonetv_irq = false; | |
| 1508 | 1573 | break; |
| 1509 | 1574 | case SOC_UNKNOWN: |
| 1510 | 1575 | default: |
| @@ -1822,11 +1887,10 @@ static int sysc_legacy_init(struct sysc *ddata) · 311 unmodified lines | ||
| 1822 | 1887 | */ |
| 1823 | 1888 | static int sysc_reset(struct sysc *ddata) |
| 1824 | 1889 | { |
| 1825 | − int sysc_offset, syss_offset, sysc_val, rstval, error = 0; | |
| 1826 | − u32 sysc_mask, syss_done; | |
| 1890 | + int sysc_offset, sysc_val, error; | |
| 1891 | + u32 sysc_mask; | |
| 1827 | 1892 | |
| 1828 | 1893 | sysc_offset = ddata->offsets[SYSC_SYSCONFIG]; |
| 1829 | − syss_offset = ddata->offsets[SYSC_SYSSTATUS]; | |
| 1830 | 1894 | |
| 1831 | 1895 | if (ddata->legacy_mode || |
| 1832 | 1896 | ddata->cap->regbits->srst_shift < 0 || |
| @@ -1835,11 +1899,6 @@ static int sysc_reset(struct sysc *ddata) · 2 unmodified lines | ||
| 1835 | 1899 | |
| 1836 | 1900 | sysc_mask = BIT(ddata->cap->regbits->srst_shift); |
| 1837 | 1901 | |
| 1838 | − if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) | |
| 1839 | − syss_done = 0; | |
| 1840 | − else | |
| 1841 | − syss_done = ddata->cfg.syss_mask; | |
| 1842 | − | |
| 1843 | 1902 | if (ddata->pre_reset_quirk) |
| 1844 | 1903 | ddata->pre_reset_quirk(ddata); |
| 1845 | 1904 | |
| @@ -1856,18 +1915,9 @@ static int sysc_reset(struct sysc *ddata) · 10 unmodified lines | ||
| 1856 | 1915 | if (ddata->post_reset_quirk) |
| 1857 | 1916 | ddata->post_reset_quirk(ddata); |
| 1858 | 1917 | |
| 1859 | − /* Poll on reset status */ | |
| 1860 | − if (syss_offset >= 0) { | |
| 1861 | − error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval, | |
| 1862 | − (rstval & ddata->cfg.syss_mask) == | |
| 1863 | − syss_done, | |
| 1864 | − 100, MAX_MODULE_SOFTRESET_WAIT); | |
| 1865 | − | |
| 1866 | − } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { | |
| 1867 | − error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval, | |
| 1868 | − !(rstval & sysc_mask), | |
| 1869 | − 100, MAX_MODULE_SOFTRESET_WAIT); | |
| 1870 | − } | |
| 1918 | + error = sysc_wait_softreset(ddata); | |
| 1919 | + if (error) | |
| 1920 | + dev_warn(ddata->dev, "OCP softreset timed out\n"); | |
| 1871 | 1921 | |
| 1872 | 1922 | if (ddata->reset_done_quirk) |
| 1873 | 1923 | ddata->reset_done_quirk(ddata); |
| @@ -244,6 +244,7 @@ static int ks_sa_rng_probe(struct platform_device *pdev) · 243 unmodified lines | ||
| 244 | 244 | ret = pm_runtime_get_sync(dev); |
| 245 | 245 | if (ret < 0) { |
| 246 | 246 | dev_err(dev, "Failed to enable SA power-domain\n"); |
| 247 | + pm_runtime_put_noidle(dev); | |
| 247 | 248 | pm_runtime_disable(dev); |
| 248 | 249 | return ret; |
| 249 | 250 | } |
| @@ -171,7 +171,7 @@ static ssize_t read_mem(struct file *file, char __user *buf, · 170 unmodified lines | ||
| 171 | 171 | if (!ptr) |
| 172 | 172 | goto failed; |
| 173 | 173 | |
| 174 | − probe = probe_kernel_read(bounce, ptr, sz); | |
| 174 | + probe = copy_from_kernel_nofault(bounce, ptr, sz); | |
| 175 | 175 | unxlate_dev_mem_ptr(p, ptr); |
| 176 | 176 | if (probe) |
| 177 | 177 | goto failed; |
| @@ -210,7 +210,7 @@ static int st33zp24_i2c_request_resources(struct i2c_client *client) · 209 unmodified lines | ||
| 210 | 210 | |
| 211 | 211 | /* |
| 212 | 212 | * st33zp24_i2c_probe initialize the TPM device |
| 213 | − * @param: client, the i2c_client drescription (TPM I2C description). | |
| 213 | + * @param: client, the i2c_client description (TPM I2C description). | |
| 214 | 214 | * @param: id, the i2c_device_id struct. |
| 215 | 215 | * @return: 0 in case of success. |
| 216 | 216 | * -1 in other case. |
| @@ -329,7 +329,7 @@ static int st33zp24_spi_request_resources(struct spi_device *dev) · 328 unmodified lines | ||
| 329 | 329 | |
| 330 | 330 | /* |
| 331 | 331 | * st33zp24_spi_probe initialize the TPM device |
| 332 | − * @param: dev, the spi_device drescription (TPM SPI description). | |
| 332 | + * @param: dev, the spi_device description (TPM SPI description). | |
| 333 | 333 | * @return: 0 in case of success. |
| 334 | 334 | * or a negative value describing the error. |
| 335 | 335 | */ |
| @@ -378,7 +378,7 @@ static int st33zp24_spi_probe(struct spi_device *dev) · 42 unmodified lines | ||
| 378 | 378 | |
| 379 | 379 | /* |
| 380 | 380 | * st33zp24_spi_remove remove the TPM device |
| 381 | − * @param: client, the spi_device drescription (TPM SPI description). | |
| 381 | + * @param: client, the spi_device description (TPM SPI description). | |
| 382 | 382 | * @return: 0 in case of success. |
| 383 | 383 | */ |
| 384 | 384 | static int st33zp24_spi_remove(struct spi_device *dev) |
| @@ -502,7 +502,7 @@ static const struct tpm_class_ops st33zp24_tpm = { · 501 unmodified lines | ||
| 502 | 502 | |
| 503 | 503 | /* |
| 504 | 504 | * st33zp24_probe initialize the TPM device |
| 505 | − * @param: client, the i2c_client drescription (TPM I2C description). | |
| 505 | + * @param: client, the i2c_client description (TPM I2C description). | |
| 506 | 506 | * @param: id, the i2c_device_id struct. |
| 507 | 507 | * @return: 0 in case of success. |
| 508 | 508 | * -1 in other case. |
| @@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, · 188 unmodified lines | ||
| 189 | 189 | goto out; |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | − /* atomic tpm command send and result receive. We only hold the ops | |
| 193 | − * lock during this period so that the tpm can be unregistered even if | |
| 194 | − * the char dev is held open. | |
| 195 | − */ | |
| 196 | − if (tpm_try_get_ops(priv->chip)) { | |
| 197 | − ret = -EPIPE; | |
| 198 | − goto out; | |
| 199 | − } | |
| 200 | − | |
| 201 | 192 | priv->response_length = 0; |
| 202 | 193 | priv->response_read = false; |
| 203 | 194 | *off = 0; |
| @@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, · 7 unmodified lines | ||
| 211 | 202 | if (file->f_flags & O_NONBLOCK) { |
| 212 | 203 | priv->command_enqueued = true; |
| 213 | 204 | queue_work(tpm_dev_wq, &priv->async_work); |
| 214 | − tpm_put_ops(priv->chip); | |
| 215 | 205 | mutex_unlock(&priv->buffer_mutex); |
| 216 | 206 | return size; |
| 217 | 207 | } |
| 218 | 208 | |
| 209 | + /* atomic tpm command send and result receive. We only hold the ops | |
| 210 | + * lock during this period so that the tpm can be unregistered even if | |
| 211 | + * the char dev is held open. | |
| 212 | + */ | |
| 213 | + if (tpm_try_get_ops(priv->chip)) { | |
| 214 | + ret = -EPIPE; | |
| 215 | + goto out; | |
| 216 | + } | |
| 217 | + | |
| 219 | 218 | ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer, |
| 220 | 219 | sizeof(priv->data_buffer)); |
| 221 | 220 | tpm_put_ops(priv->chip); |
| @@ -683,13 +683,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, · 682 unmodified lines | ||
| 683 | 683 | if (rc) |
| 684 | 684 | goto init_irq_cleanup; |
| 685 | 685 | |
| 686 | − if (!strcmp(id->compat, "IBM,vtpm20")) { | |
| 687 | − chip->flags |= TPM_CHIP_FLAG_TPM2; | |
| 688 | − rc = tpm2_get_cc_attrs_tbl(chip); | |
| 689 | − if (rc) | |
| 690 | − goto init_irq_cleanup; | |
| 691 | − } | |
| 692 | − | |
| 693 | 686 | if (!wait_event_timeout(ibmvtpm->crq_queue.wq, |
| 694 | 687 | ibmvtpm->rtce_buf != NULL, |
| 695 | 688 | HZ)) { |
| @@ -697,6 +690,13 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, · 1 unmodified line | ||
| 697 | 690 | goto init_irq_cleanup; |
| 698 | 691 | } |
| 699 | 692 | |
| 693 | + if (!strcmp(id->compat, "IBM,vtpm20")) { | |
| 694 | + chip->flags |= TPM_CHIP_FLAG_TPM2; | |
| 695 | + rc = tpm2_get_cc_attrs_tbl(chip); | |
| 696 | + if (rc) | |
| 697 | + goto init_irq_cleanup; | |
| 698 | + } | |
| 699 | + | |
| 700 | 700 | return tpm_chip_register(chip); |
| 701 | 701 | init_irq_cleanup: |
| 702 | 702 | do { |
| @@ -238,7 +238,6 @@ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, · 237 unmodified lines | ||
| 238 | 238 | static struct pnp_device_id tpm_pnp_tbl[] = { |
| 239 | 239 | {"PNP0C31", 0}, /* TPM */ |
| 240 | 240 | {"ATM1200", 0}, /* Atmel */ |
| 241 | − {"IFX0102", 0}, /* Infineon */ | |
| 242 | 241 | {"BCM0101", 0}, /* Broadcom */ |
| 243 | 242 | {"BCM0102", 0}, /* Broadcom */ |
| 244 | 243 | {"NSC1200", 0}, /* National */ |
| @@ -1085,7 +1085,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 1084 unmodified lines | ||
| 1085 | 1085 | |
| 1086 | 1086 | return 0; |
| 1087 | 1087 | out_err: |
| 1088 | − if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) | |
| 1088 | + if (chip->ops->clk_enable != NULL) | |
| 1089 | 1089 | chip->ops->clk_enable(chip, false); |
| 1090 | 1090 | |
| 1091 | 1091 | tpm_tis_remove(chip); |
| @@ -53,8 +53,6 @@ static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy, · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | if ((phy->iobuf[3] & 0x01) == 0) { |
| 55 | 55 | // handle SPI wait states |
| 56 | − phy->iobuf[0] = 0; | |
| 57 | − | |
| 58 | 56 | for (i = 0; i < TPM_RETRY; i++) { |
| 59 | 57 | spi_xfer->len = 1; |
| 60 | 58 | spi_message_init(&m); |
| @@ -104,6 +102,8 @@ int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, · 43 unmodified lines | ||
| 104 | 102 | if (ret < 0) |
| 105 | 103 | goto exit; |
| 106 | 104 | |
| 105 | + /* Flow control transfers are receive only */ | |
| 106 | + spi_xfer.tx_buf = NULL; | |
| 107 | 107 | ret = phy->flow_control(phy, &spi_xfer); |
| 108 | 108 | if (ret < 0) |
| 109 | 109 | goto exit; |
| @@ -113,9 +113,8 @@ int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, · 3 unmodified lines | ||
| 113 | 113 | spi_xfer.delay.value = 5; |
| 114 | 114 | spi_xfer.delay.unit = SPI_DELAY_UNIT_USECS; |
| 115 | 115 | |
| 116 | − if (in) { | |
| 117 | − spi_xfer.tx_buf = NULL; | |
| 118 | − } else if (out) { | |
| 116 | + if (out) { | |
| 117 | + spi_xfer.tx_buf = phy->iobuf; | |
| 119 | 118 | spi_xfer.rx_buf = NULL; |
| 120 | 119 | memcpy(phy->iobuf, out, transfer_len); |
| 121 | 120 | out += transfer_len; |
| @@ -288,6 +287,7 @@ static struct spi_driver tpm_tis_spi_driver = { · 166 unmodified lines | ||
| 288 | 287 | .pm = &tpm_tis_pm, |
| 289 | 288 | .of_match_table = of_match_ptr(of_tis_spi_match), |
| 290 | 289 | .acpi_match_table = ACPI_PTR(acpi_tis_spi_match), |
| 290 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, | |
| 291 | 291 | }, |
| 292 | 292 | .probe = tpm_tis_spi_driver_probe, |
| 293 | 293 | .remove = tpm_tis_spi_remove, |
| @@ -586,7 +586,10 @@ static int sifive_fu540_prci_probe(struct platform_device *pdev) · 585 unmodified lines | ||
| 586 | 586 | struct __prci_data *pd; |
| 587 | 587 | int r; |
| 588 | 588 | |
| 589 | − pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); | |
| 589 | + pd = devm_kzalloc(dev, | |
| 590 | + struct_size(pd, hw_clks.hws, | |
| 591 | + ARRAY_SIZE(__prci_init_clocks)), | |
| 592 | + GFP_KERNEL); | |
| 590 | 593 | if (!pd) |
| 591 | 594 | return -ENOMEM; |
| 592 | 595 | |
| @@ -2677,6 +2677,8 @@ static struct acpi_platform_list plat_info[] __initdata = { · 2676 unmodified lines | ||
| 2677 | 2677 | { } /* End */ |
| 2678 | 2678 | }; |
| 2679 | 2679 | |
| 2680 | +#define BITMASK_OOB (BIT(8) | BIT(18)) | |
| 2681 | + | |
| 2680 | 2682 | static bool __init intel_pstate_platform_pwr_mgmt_exists(void) |
| 2681 | 2683 | { |
| 2682 | 2684 | const struct x86_cpu_id *id; |
| @@ -2686,8 +2688,9 @@ static bool __init intel_pstate_platform_pwr_mgmt_exists(void) · 3 unmodified lines | ||
| 2686 | 2688 | id = x86_match_cpu(intel_pstate_cpu_oob_ids); |
| 2687 | 2689 | if (id) { |
| 2688 | 2690 | rdmsrl(MSR_MISC_PWR_MGMT, misc_pwr); |
| 2689 | − if (misc_pwr & (1 << 8)) { | |
| 2690 | − pr_debug("Bit 8 in the MISC_PWR_MGMT MSR set\n"); | |
| 2691 | + if (misc_pwr & BITMASK_OOB) { | |
| 2692 | + pr_debug("Bit 8 or 18 in the MISC_PWR_MGMT MSR set\n"); | |
| 2693 | + pr_debug("P states are controlled in Out of Band mode by the firmware/hardware\n"); | |
| 2691 | 2694 | return true; |
| 2692 | 2695 | } |
| 2693 | 2696 | } |
| @@ -186,9 +186,10 @@ int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev) · 185 unmodified lines | ||
| 186 | 186 | * be frozen safely. |
| 187 | 187 | */ |
| 188 | 188 | index = find_deepest_state(drv, dev, U64_MAX, 0, true); |
| 189 | − if (index > 0) | |
| 189 | + if (index > 0) { | |
| 190 | 190 | enter_s2idle_proper(drv, dev, index); |
| 191 | − | |
| 191 | + local_irq_enable(); | |
| 192 | + } | |
| 192 | 193 | return index; |
| 193 | 194 | } |
| 194 | 195 | #endif /* CONFIG_SUSPEND */ |
| @@ -147,7 +147,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API · 146 unmodified lines | ||
| 147 | 147 | select HW_RANDOM |
| 148 | 148 | help |
| 149 | 149 | Selecting this will register the SEC4 hardware rng to |
| 150 | − the hw_random API for suppying the kernel entropy pool. | |
| 150 | + the hw_random API for supplying the kernel entropy pool. | |
| 151 | 151 | |
| 152 | 152 | endif # CRYPTO_DEV_FSL_CAAM_JR |
| 153 | 153 | |
| @@ -54,7 +54,7 @@ static void build_instantiation_desc(u32 *desc, int handle, int do_sk) · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | /* |
| 56 | 56 | * load 1 to clear written reg: |
| 57 | − * resets the done interrrupt and returns the RNG to idle. | |
| 57 | + * resets the done interrupt and returns the RNG to idle. | |
| 58 | 58 | */ |
| 59 | 59 | append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW); |
| 60 | 60 | |
| @@ -156,7 +156,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc, · 95 unmodified lines | ||
| 156 | 156 | DESC_DER_DECO_STAT_SHIFT; |
| 157 | 157 | |
| 158 | 158 | /* |
| 159 | − * If an error occured in the descriptor, then | |
| 159 | + * If an error occurred in the descriptor, then | |
| 160 | 160 | * the DECO status field will be set to 0x0D |
| 161 | 161 | */ |
| 162 | 162 | if (deco_state == DECO_STAT_HOST_ERR) |
| @@ -264,7 +264,7 @@ static void devm_deinstantiate_rng(void *data) · 101 unmodified lines | ||
| 264 | 264 | * - -ENODEV if DECO0 couldn't be acquired |
| 265 | 265 | * - -EAGAIN if an error occurred when executing the descriptor |
| 266 | 266 | * f.i. there was a RNG hardware error due to not "good enough" |
| 267 | − * entropy being aquired. | |
| 267 | + * entropy being acquired. | |
| 268 | 268 | */ |
| 269 | 269 | static int instantiate_rng(struct device *ctrldev, int state_handle_mask, |
| 270 | 270 | int gen_sk) |
| @@ -733,8 +733,8 @@ static int caam_probe(struct platform_device *pdev) · 462 unmodified lines | ||
| 733 | 733 | handle_imx6_err005766(&ctrl->mcr); |
| 734 | 734 | |
| 735 | 735 | /* |
| 736 | − * Read the Compile Time paramters and SCFGR to determine | |
| 737 | − * if Virtualization is enabled for this platform | |
| 736 | + * Read the Compile Time parameters and SCFGR to determine | |
| 737 | + * if virtualization is enabled for this platform | |
| 738 | 738 | */ |
| 739 | 739 | scfgr = rd_reg32(&ctrl->scfgr); |
| 740 | 740 | |
| @@ -863,9 +863,9 @@ static int caam_probe(struct platform_device *pdev) · 122 unmodified lines | ||
| 863 | 863 | } |
| 864 | 864 | /* |
| 865 | 865 | * if instantiate_rng(...) fails, the loop will rerun |
| 866 | − * and the kick_trng(...) function will modfiy the | |
| 866 | + * and the kick_trng(...) function will modify the | |
| 867 | 867 | * upper and lower limits of the entropy sampling |
| 868 | − * interval, leading to a sucessful initialization of | |
| 868 | + * interval, leading to a successful initialization of | |
| 869 | 869 | * the RNG. |
| 870 | 870 | */ |
| 871 | 871 | ret = instantiate_rng(dev, inst_handles, |
| @@ -882,8 +882,8 @@ static int caam_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 882 | 882 | return ret; |
| 883 | 883 | } |
| 884 | 884 | /* |
| 885 | − * Set handles init'ed by this module as the complement of the | |
| 886 | − * already initialized ones | |
| 885 | + * Set handles initialized by this module as the complement of | |
| 886 | + * the already initialized ones | |
| 887 | 887 | */ |
| 888 | 888 | ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK; |
| 889 | 889 | |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | 20 | #define SEC4_SG_LEN_EXT 0x80000000 /* Entry points to table */ |
| 21 | −#define SEC4_SG_LEN_FIN 0x40000000 /* Last ent in table */ | |
| 21 | +#define SEC4_SG_LEN_FIN 0x40000000 /* Last entry in table */ | |
| 22 | 22 | #define SEC4_SG_BPID_MASK 0x000000ff |
| 23 | 23 | #define SEC4_SG_BPID_SHIFT 16 |
| 24 | 24 | #define SEC4_SG_LEN_MASK 0x3fffffff /* Excludes EXT and FINAL */ |
| @@ -113,7 +113,7 @@ · 88 unmodified lines | ||
| 113 | 113 | */ |
| 114 | 114 | #define HDR_REVERSE 0x00000800 |
| 115 | 115 | |
| 116 | −/* Propogate DNR property to SharedDesc */ | |
| 116 | +/* Propagate DNR property to SharedDesc */ | |
| 117 | 117 | #define HDR_PROP_DNR 0x00000800 |
| 118 | 118 | |
| 119 | 119 | /* JobDesc/SharedDesc share property */ |
| @@ -453,7 +453,7 @@ struct srtp_decap_pdb { · 452 unmodified lines | ||
| 453 | 453 | #define DSA_PDB_N_MASK 0x7f |
| 454 | 454 | |
| 455 | 455 | struct dsa_sign_pdb { |
| 456 | − u32 sgf_ln; /* Use DSA_PDB_ defintions per above */ | |
| 456 | + u32 sgf_ln; /* Use DSA_PDB_ definitions per above */ | |
| 457 | 457 | u8 *q; |
| 458 | 458 | u8 *r; |
| 459 | 459 | u8 *g; /* or Gx,y */ |
| @@ -376,6 +376,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) · 375 unmodified lines | ||
| 376 | 376 | struct sev_device *sev = psp_master->sev_data; |
| 377 | 377 | struct sev_user_data_pek_csr input; |
| 378 | 378 | struct sev_data_pek_csr *data; |
| 379 | + void __user *input_address; | |
| 379 | 380 | void *blob = NULL; |
| 380 | 381 | int ret; |
| 381 | 382 | |
| @@ -394,6 +395,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) · 12 unmodified lines | ||
| 394 | 395 | goto cmd; |
| 395 | 396 | |
| 396 | 397 | /* allocate a physically contiguous buffer to store the CSR blob */ |
| 398 | + input_address = (void __user *)input.address; | |
| 397 | 399 | if (input.length > SEV_FW_BLOB_MAX_SIZE) { |
| 398 | 400 | ret = -EFAULT; |
| 399 | 401 | goto e_free; |
| @@ -426,7 +428,7 @@ cmd: · 26 unmodified lines | ||
| 426 | 428 | } |
| 427 | 429 | |
| 428 | 430 | if (blob) { |
| 429 | − if (copy_to_user((void __user *)input.address, blob, input.length)) | |
| 431 | + if (copy_to_user(input_address, blob, input.length)) | |
| 430 | 432 | ret = -EFAULT; |
| 431 | 433 | } |
| 432 | 434 | |
| @@ -437,7 +439,7 @@ e_free: · 4 unmodified lines | ||
| 437 | 439 | return ret; |
| 438 | 440 | } |
| 439 | 441 | |
| 440 | −void *psp_copy_user_blob(u64 __user uaddr, u32 len) | |
| 442 | +void *psp_copy_user_blob(u64 uaddr, u32 len) | |
| 441 | 443 | { |
| 442 | 444 | if (!uaddr || !len) |
| 443 | 445 | return ERR_PTR(-EINVAL); |
| @@ -446,7 +448,7 @@ void *psp_copy_user_blob(u64 __user uaddr, u32 len) · 2 unmodified lines | ||
| 446 | 448 | if (len > SEV_FW_BLOB_MAX_SIZE) |
| 447 | 449 | return ERR_PTR(-EINVAL); |
| 448 | 450 | |
| 449 | − return memdup_user((void __user *)(uintptr_t)uaddr, len); | |
| 451 | + return memdup_user((void __user *)uaddr, len); | |
| 450 | 452 | } |
| 451 | 453 | EXPORT_SYMBOL_GPL(psp_copy_user_blob); |
| 452 | 454 | |
| @@ -621,6 +623,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) · 168 unmodified lines | ||
| 621 | 623 | { |
| 622 | 624 | struct sev_user_data_get_id2 input; |
| 623 | 625 | struct sev_data_get_id *data; |
| 626 | + void __user *input_address; | |
| 624 | 627 | void *id_blob = NULL; |
| 625 | 628 | int ret; |
| 626 | 629 | |
| @@ -631,6 +634,8 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) · 4 unmodified lines | ||
| 631 | 634 | if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) |
| 632 | 635 | return -EFAULT; |
| 633 | 636 | |
| 637 | + input_address = (void __user *)input.address; | |
| 638 | + | |
| 634 | 639 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
| 635 | 640 | if (!data) |
| 636 | 641 | return -ENOMEM; |
| @@ -660,8 +665,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) · 23 unmodified lines | ||
| 660 | 665 | } |
| 661 | 666 | |
| 662 | 667 | if (id_blob) { |
| 663 | − if (copy_to_user((void __user *)input.address, | |
| 664 | − id_blob, data->len)) { | |
| 668 | + if (copy_to_user(input_address, id_blob, data->len)) { | |
| 665 | 669 | ret = -EFAULT; |
| 666 | 670 | goto e_free; |
| 667 | 671 | } |
| @@ -720,6 +724,8 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) · 52 unmodified lines | ||
| 720 | 724 | struct sev_user_data_pdh_cert_export input; |
| 721 | 725 | void *pdh_blob = NULL, *cert_blob = NULL; |
| 722 | 726 | struct sev_data_pdh_cert_export *data; |
| 727 | + void __user *input_cert_chain_address; | |
| 728 | + void __user *input_pdh_cert_address; | |
| 723 | 729 | int ret; |
| 724 | 730 | |
| 725 | 731 | /* If platform is not in INIT state then transition it to INIT. */ |
| @@ -745,6 +751,9 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) · 19 unmodified lines | ||
| 745 | 751 | !input.cert_chain_address) |
| 746 | 752 | goto cmd; |
| 747 | 753 | |
| 754 | + input_pdh_cert_address = (void __user *)input.pdh_cert_address; | |
| 755 | + input_cert_chain_address = (void __user *)input.cert_chain_address; | |
| 756 | + | |
| 748 | 757 | /* Allocate a physically contiguous buffer to store the PDH blob. */ |
| 749 | 758 | if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) { |
| 750 | 759 | ret = -EFAULT; |
| @@ -788,7 +797,7 @@ cmd: · 37 unmodified lines | ||
| 788 | 797 | } |
| 789 | 798 | |
| 790 | 799 | if (pdh_blob) { |
| 791 | − if (copy_to_user((void __user *)input.pdh_cert_address, | |
| 800 | + if (copy_to_user(input_pdh_cert_address, | |
| 792 | 801 | pdh_blob, input.pdh_cert_len)) { |
| 793 | 802 | ret = -EFAULT; |
| 794 | 803 | goto e_free_cert; |
| @@ -796,7 +805,7 @@ cmd: · 1 unmodified line | ||
| 796 | 805 | } |
| 797 | 806 | |
| 798 | 807 | if (cert_blob) { |
| 799 | − if (copy_to_user((void __user *)input.cert_chain_address, | |
| 808 | + if (copy_to_user(input_cert_chain_address, | |
| 800 | 809 | cert_blob, input.cert_chain_len)) |
| 801 | 810 | ret = -EFAULT; |
| 802 | 811 | } |
| @@ -223,7 +223,7 @@ struct chcr_authenc_ctx { · 222 unmodified lines | ||
| 223 | 223 | |
| 224 | 224 | struct __aead_ctx { |
| 225 | 225 | struct chcr_gcm_ctx gcm[0]; |
| 226 | − struct chcr_authenc_ctx authenc[0]; | |
| 226 | + struct chcr_authenc_ctx authenc[]; | |
| 227 | 227 | }; |
| 228 | 228 | |
| 229 | 229 | struct chcr_aead_ctx { |
| @@ -235,7 +235,7 @@ struct chcr_aead_ctx { · 5 unmodified lines | ||
| 235 | 235 | u8 nonce[4]; |
| 236 | 236 | u16 hmac_ctrl; |
| 237 | 237 | u16 mayverify; |
| 238 | − struct __aead_ctx ctx[0]; | |
| 238 | + struct __aead_ctx ctx[]; | |
| 239 | 239 | }; |
| 240 | 240 | |
| 241 | 241 | struct hmac_ctx { |
| @@ -247,7 +247,7 @@ struct hmac_ctx { · 5 unmodified lines | ||
| 247 | 247 | struct __crypto_ctx { |
| 248 | 248 | struct hmac_ctx hmacctx[0]; |
| 249 | 249 | struct ablk_ctx ablkctx[0]; |
| 250 | − struct chcr_aead_ctx aeadctx[0]; | |
| 250 | + struct chcr_aead_ctx aeadctx[]; | |
| 251 | 251 | }; |
| 252 | 252 | |
| 253 | 253 | struct chcr_context { |
| @@ -257,7 +257,7 @@ struct chcr_context { · 3 unmodified lines | ||
| 257 | 257 | unsigned int ntxq; |
| 258 | 258 | unsigned int nrxq; |
| 259 | 259 | struct completion cbc_aes_aio_done; |
| 260 | − struct __crypto_ctx crypto_ctx[0]; | |
| 260 | + struct __crypto_ctx crypto_ctx[]; | |
| 261 | 261 | }; |
| 262 | 262 | |
| 263 | 263 | struct chcr_hctx_per_wr { |
| @@ -66,7 +66,8 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | sgl_size = sizeof(struct acc_hw_sge) * sge_nr + |
| 68 | 68 | sizeof(struct hisi_acc_hw_sgl); |
| 69 | − block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1)); | |
| 69 | + block_size = 1 << (PAGE_SHIFT + MAX_ORDER <= 32 ? | |
| 70 | + PAGE_SHIFT + MAX_ORDER - 1 : 31); | |
| 70 | 71 | sgl_num_per_block = block_size / sgl_size; |
| 71 | 72 | block_num = count / sgl_num_per_block; |
| 72 | 73 | remain_sgl = count % sgl_num_per_block; |
| @@ -118,6 +118,9 @@ static void otx_cpt_aead_callback(int status, void *arg1, void *arg2) · 117 unmodified lines | ||
| 118 | 118 | struct otx_cpt_req_info *cpt_req; |
| 119 | 119 | struct pci_dev *pdev; |
| 120 | 120 | |
| 121 | + if (!cpt_info) | |
| 122 | + goto complete; | |
| 123 | + | |
| 121 | 124 | cpt_req = cpt_info->req; |
| 122 | 125 | if (!status) { |
| 123 | 126 | /* |
| @@ -129,10 +132,10 @@ static void otx_cpt_aead_callback(int status, void *arg1, void *arg2) · 5 unmodified lines | ||
| 129 | 132 | !cpt_req->is_enc) |
| 130 | 133 | status = validate_hmac_cipher_null(cpt_req); |
| 131 | 134 | } |
| 132 | − if (cpt_info) { | |
| 133 | − pdev = cpt_info->pdev; | |
| 134 | − do_request_cleanup(pdev, cpt_info); | |
| 135 | − } | |
| 135 | + pdev = cpt_info->pdev; | |
| 136 | + do_request_cleanup(pdev, cpt_info); | |
| 137 | + | |
| 138 | +complete: | |
| 136 | 139 | if (areq) |
| 137 | 140 | areq->complete(areq, status); |
| 138 | 141 | } |
| @@ -135,7 +135,8 @@ int __init dio_find(int deviceid) · 134 unmodified lines | ||
| 135 | 135 | else |
| 136 | 136 | va = ioremap(pa, PAGE_SIZE); |
| 137 | 137 | |
| 138 | − if (probe_kernel_read(&i, (unsigned char *)va + DIO_IDOFF, 1)) { | |
| 138 | + if (copy_from_kernel_nofault(&i, | |
| 139 | + (unsigned char *)va + DIO_IDOFF, 1)) { | |
| 139 | 140 | if (scode >= DIOII_SCBASE) |
| 140 | 141 | iounmap(va); |
| 141 | 142 | continue; /* no board present at that select code */ |
| @@ -208,7 +209,8 @@ static int __init dio_init(void) · 66 unmodified lines | ||
| 208 | 209 | else |
| 209 | 210 | va = ioremap(pa, PAGE_SIZE); |
| 210 | 211 | |
| 211 | − if (probe_kernel_read(&i, (unsigned char *)va + DIO_IDOFF, 1)) { | |
| 212 | + if (copy_from_kernel_nofault(&i, | |
| 213 | + (unsigned char *)va + DIO_IDOFF, 1)) { | |
| 212 | 214 | if (scode >= DIOII_SCBASE) |
| 213 | 215 | iounmap(va); |
| 214 | 216 | continue; /* no board present at that select code */ |
| @@ -54,37 +54,11 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) · 53 unmodified lines | ||
| 54 | 54 | dentry->d_name.name, ret > 0 ? name : ""); |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | −static const struct dentry_operations dma_buf_dentry_ops = { | |
| 58 | − .d_dname = dmabuffs_dname, | |
| 59 | −}; | |
| 60 | − | |
| 61 | −static struct vfsmount *dma_buf_mnt; | |
| 62 | − | |
| 63 | −static int dma_buf_fs_init_context(struct fs_context *fc) | |
| 64 | −{ | |
| 65 | − struct pseudo_fs_context *ctx; | |
| 66 | − | |
| 67 | − ctx = init_pseudo(fc, DMA_BUF_MAGIC); | |
| 68 | − if (!ctx) | |
| 69 | − return -ENOMEM; | |
| 70 | − ctx->dops = &dma_buf_dentry_ops; | |
| 71 | − return 0; | |
| 72 | −} | |
| 73 | − | |
| 74 | −static struct file_system_type dma_buf_fs_type = { | |
| 75 | − .name = "dmabuf", | |
| 76 | − .init_fs_context = dma_buf_fs_init_context, | |
| 77 | − .kill_sb = kill_anon_super, | |
| 78 | −}; | |
| 79 | − | |
| 80 | −static int dma_buf_release(struct inode *inode, struct file *file) | |
| 57 | +static void dma_buf_release(struct dentry *dentry) | |
| 81 | 58 | { |
| 82 | 59 | struct dma_buf *dmabuf; |
| 83 | 60 | |
| 84 | − if (!is_dma_buf_file(file)) | |
| 85 | − return -EINVAL; | |
| 86 | − | |
| 87 | − dmabuf = file->private_data; | |
| 61 | + dmabuf = dentry->d_fsdata; | |
| 88 | 62 | |
| 89 | 63 | BUG_ON(dmabuf->vmapping_counter); |
| 90 | 64 | |
| @@ -110,9 +84,32 @@ static int dma_buf_release(struct inode *inode, struct file *file) · 19 unmodified lines | ||
| 110 | 84 | module_put(dmabuf->owner); |
| 111 | 85 | kfree(dmabuf->name); |
| 112 | 86 | kfree(dmabuf); |
| 87 | +} | |
| 88 | + | |
| 89 | +static const struct dentry_operations dma_buf_dentry_ops = { | |
| 90 | + .d_dname = dmabuffs_dname, | |
| 91 | + .d_release = dma_buf_release, | |
| 92 | +}; | |
| 93 | + | |
| 94 | +static struct vfsmount *dma_buf_mnt; | |
| 95 | + | |
| 96 | +static int dma_buf_fs_init_context(struct fs_context *fc) | |
| 97 | +{ | |
| 98 | + struct pseudo_fs_context *ctx; | |
| 99 | + | |
| 100 | + ctx = init_pseudo(fc, DMA_BUF_MAGIC); | |
| 101 | + if (!ctx) | |
| 102 | + return -ENOMEM; | |
| 103 | + ctx->dops = &dma_buf_dentry_ops; | |
| 113 | 104 | return 0; |
| 114 | 105 | } |
| 115 | 106 | |
| 107 | +static struct file_system_type dma_buf_fs_type = { | |
| 108 | + .name = "dmabuf", | |
| 109 | + .init_fs_context = dma_buf_fs_init_context, | |
| 110 | + .kill_sb = kill_anon_super, | |
| 111 | +}; | |
| 112 | + | |
| 116 | 113 | static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) |
| 117 | 114 | { |
| 118 | 115 | struct dma_buf *dmabuf; |
| @@ -412,7 +409,6 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) · 293 unmodified lines | ||
| 412 | 409 | } |
| 413 | 410 | |
| 414 | 411 | static const struct file_operations dma_buf_fops = { |
| 415 | − .release = dma_buf_release, | |
| 416 | 412 | .mmap = dma_buf_mmap_internal, |
| 417 | 413 | .llseek = dma_buf_llseek, |
| 418 | 414 | .poll = dma_buf_poll, |
| @@ -77,7 +77,7 @@ struct milbeaut_hdmac_device { · 76 unmodified lines | ||
| 77 | 77 | struct dma_device ddev; |
| 78 | 78 | struct clk *clk; |
| 79 | 79 | void __iomem *reg_base; |
| 80 | − struct milbeaut_hdmac_chan channels[0]; | |
| 80 | + struct milbeaut_hdmac_chan channels[]; | |
| 81 | 81 | }; |
| 82 | 82 | |
| 83 | 83 | static struct milbeaut_hdmac_chan * |
| @@ -74,7 +74,7 @@ struct milbeaut_xdmac_chan { · 73 unmodified lines | ||
| 74 | 74 | struct milbeaut_xdmac_device { |
| 75 | 75 | struct dma_device ddev; |
| 76 | 76 | void __iomem *reg_base; |
| 77 | − struct milbeaut_xdmac_chan channels[0]; | |
| 77 | + struct milbeaut_xdmac_chan channels[]; | |
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | 80 | static struct milbeaut_xdmac_chan * |
| @@ -127,7 +127,7 @@ struct moxart_desc { · 126 unmodified lines | ||
| 127 | 127 | unsigned int dma_cycles; |
| 128 | 128 | struct virt_dma_desc vd; |
| 129 | 129 | uint8_t es; |
| 130 | − struct moxart_sg sg[0]; | |
| 130 | + struct moxart_sg sg[]; | |
| 131 | 131 | }; |
| 132 | 132 | |
| 133 | 133 | struct moxart_chan { |
| @@ -225,7 +225,7 @@ struct tegra_dma { · 224 unmodified lines | ||
| 225 | 225 | u32 global_pause_count; |
| 226 | 226 | |
| 227 | 227 | /* Last member of the structure */ |
| 228 | − struct tegra_dma_channel channels[0]; | |
| 228 | + struct tegra_dma_channel channels[]; | |
| 229 | 229 | }; |
| 230 | 230 | |
| 231 | 231 | static inline void tdma_write(struct tegra_dma *tdma, u32 reg, u32 val) |
| @@ -211,7 +211,7 @@ struct edma_desc { · 210 unmodified lines | ||
| 211 | 211 | u32 residue; |
| 212 | 212 | u32 residue_stat; |
| 213 | 213 | |
| 214 | − struct edma_pset pset[0]; | |
| 214 | + struct edma_pset pset[]; | |
| 215 | 215 | }; |
| 216 | 216 | |
| 217 | 217 | struct edma_cc; |
| @@ -170,7 +170,7 @@ struct udma_desc { · 169 unmodified lines | ||
| 170 | 170 | void *metadata; /* pointer to provided metadata buffer (EPIP, PSdata) */ |
| 171 | 171 | |
| 172 | 172 | unsigned int hwdesc_count; |
| 173 | − struct udma_hwdesc hwdesc[0]; | |
| 173 | + struct udma_hwdesc hwdesc[]; | |
| 174 | 174 | }; |
| 175 | 175 | |
| 176 | 176 | enum udma_chan_state { |
| @@ -88,7 +88,7 @@ struct timb_dma { · 87 unmodified lines | ||
| 88 | 88 | struct dma_device dma; |
| 89 | 89 | void __iomem *membase; |
| 90 | 90 | struct tasklet_struct tasklet; |
| 91 | − struct timb_dma_chan channels[0]; | |
| 91 | + struct timb_dma_chan channels[]; | |
| 92 | 92 | }; |
| 93 | 93 | |
| 94 | 94 | static struct device *chan2dev(struct dma_chan *chan) |
| @@ -269,6 +269,8 @@ static int get_scrub_rate(struct mem_ctl_info *mci) · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | if (pvt->model == 0x60) |
| 271 | 271 | amd64_read_pci_cfg(pvt->F2, F15H_M60H_SCRCTRL, &scrubval); |
| 272 | + else | |
| 273 | + amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); | |
| 272 | 274 | } else { |
| 273 | 275 | amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); |
| 274 | 276 | } |
| @@ -117,7 +117,7 @@ struct inbound_transaction_resource { · 116 unmodified lines | ||
| 117 | 117 | struct descriptor_resource { |
| 118 | 118 | struct client_resource resource; |
| 119 | 119 | struct fw_descriptor descriptor; |
| 120 | − u32 data[0]; | |
| 120 | + u32 data[]; | |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | 123 | struct iso_resource { |
| @@ -620,7 +620,7 @@ struct fw_request { · 619 unmodified lines | ||
| 620 | 620 | u32 request_header[4]; |
| 621 | 621 | int ack; |
| 622 | 622 | u32 length; |
| 623 | − u32 data[0]; | |
| 623 | + u32 data[]; | |
| 624 | 624 | }; |
| 625 | 625 | |
| 626 | 626 | static void free_response_callback(struct fw_packet *packet, |
| @@ -191,7 +191,7 @@ struct fw_node { · 190 unmodified lines | ||
| 191 | 191 | /* Upper layer specific data. */ |
| 192 | 192 | void *data; |
| 193 | 193 | |
| 194 | − struct fw_node *ports[0]; | |
| 194 | + struct fw_node *ports[]; | |
| 195 | 195 | }; |
| 196 | 196 | |
| 197 | 197 | static inline struct fw_node *fw_node_get(struct fw_node *node) |
| @@ -52,7 +52,7 @@ struct pcl { · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | struct packet { |
| 54 | 54 | unsigned int length; |
| 55 | − char data[0]; | |
| 55 | + char data[]; | |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | 58 | struct packet_buffer { |
| @@ -111,7 +111,7 @@ struct descriptor_buffer { · 110 unmodified lines | ||
| 111 | 111 | dma_addr_t buffer_bus; |
| 112 | 112 | size_t buffer_size; |
| 113 | 113 | size_t used; |
| 114 | − struct descriptor buffer[0]; | |
| 114 | + struct descriptor buffer[]; | |
| 115 | 115 | }; |
| 116 | 116 | |
| 117 | 117 | struct context { |
| @@ -262,7 +262,7 @@ struct dmi_system_event_log { · 261 unmodified lines | ||
| 262 | 262 | u8 header_format; |
| 263 | 263 | u8 type_descriptors_supported_count; |
| 264 | 264 | u8 per_log_type_descriptor_length; |
| 265 | − u8 supported_log_type_descriptos[0]; | |
| 265 | + u8 supported_log_type_descriptos[]; | |
| 266 | 266 | } __packed; |
| 267 | 267 | |
| 268 | 268 | #define DMI_SYSFS_SEL_FIELD(_field) \ |
| @@ -278,3 +278,14 @@ config EFI_EARLYCON · 277 unmodified lines | ||
| 278 | 278 | depends on SERIAL_EARLYCON && !ARM && !IA64 |
| 279 | 279 | select FONT_SUPPORT |
| 280 | 280 | select ARCH_USE_MEMREMAP_PROT |
| 281 | + | |
| 282 | +config EFI_CUSTOM_SSDT_OVERLAYS | |
| 283 | + bool "Load custom ACPI SSDT overlay from an EFI variable" | |
| 284 | + depends on EFI_VARS && ACPI | |
| 285 | + default ACPI_TABLE_UPGRADE | |
| 286 | + help | |
| 287 | + Allow loading of an ACPI SSDT overlay from an EFI variable specified | |
| 288 | + by a kernel command line option. | |
| 289 | + | |
| 290 | + See Documentation/admin-guide/acpi/ssdt-overlays.rst for more | |
| 291 | + information. | |
| @@ -52,9 +52,11 @@ static phys_addr_t __init efi_to_phys(unsigned long addr) · 51 unmodified lines | ||
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR; |
| 55 | +static __initdata unsigned long cpu_state_table = EFI_INVALID_TABLE_ADDR; | |
| 55 | 56 | |
| 56 | 57 | static const efi_config_table_type_t arch_tables[] __initconst = { |
| 57 | 58 | {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table}, |
| 59 | + {LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table}, | |
| 58 | 60 | {} |
| 59 | 61 | }; |
| 60 | 62 | |
| @@ -62,7 +64,8 @@ static void __init init_screen_info(void) · 1 unmodified line | ||
| 62 | 64 | { |
| 63 | 65 | struct screen_info *si; |
| 64 | 66 | |
| 65 | − if (screen_info_table != EFI_INVALID_TABLE_ADDR) { | |
| 67 | + if (IS_ENABLED(CONFIG_ARM) && | |
| 68 | + screen_info_table != EFI_INVALID_TABLE_ADDR) { | |
| 66 | 69 | si = early_memremap_ro(screen_info_table, sizeof(*si)); |
| 67 | 70 | if (!si) { |
| 68 | 71 | pr_err("Could not map screen_info config table\n"); |
| @@ -116,7 +119,8 @@ static int __init uefi_init(u64 efi_system_table) · 47 unmodified lines | ||
| 116 | 119 | goto out; |
| 117 | 120 | } |
| 118 | 121 | retval = efi_config_parse_tables(config_tables, systab->nr_tables, |
| 119 | − arch_tables); | |
| 122 | + IS_ENABLED(CONFIG_ARM) ? arch_tables | |
| 123 | + : NULL); | |
| 120 | 124 | |
| 121 | 125 | early_memunmap(config_tables, table_size); |
| 122 | 126 | out: |
| @@ -238,9 +242,37 @@ void __init efi_init(void) · 115 unmodified lines | ||
| 238 | 242 | |
| 239 | 243 | init_screen_info(); |
| 240 | 244 | |
| 245 | +#ifdef CONFIG_ARM | |
| 241 | 246 | /* ARM does not permit early mappings to persist across paging_init() */ |
| 242 | − if (IS_ENABLED(CONFIG_ARM)) | |
| 243 | − efi_memmap_unmap(); | |
| 247 | + efi_memmap_unmap(); | |
| 248 | + | |
| 249 | + if (cpu_state_table != EFI_INVALID_TABLE_ADDR) { | |
| 250 | + struct efi_arm_entry_state *state; | |
| 251 | + bool dump_state = true; | |
| 252 | + | |
| 253 | + state = early_memremap_ro(cpu_state_table, | |
| 254 | + sizeof(struct efi_arm_entry_state)); | |
| 255 | + if (state == NULL) { | |
| 256 | + pr_warn("Unable to map CPU entry state table.\n"); | |
| 257 | + return; | |
| 258 | + } | |
| 259 | + | |
| 260 | + if ((state->sctlr_before_ebs & 1) == 0) | |
| 261 | + pr_warn(FW_BUG "EFI stub was entered with MMU and Dcache disabled, please fix your firmware!\n"); | |
| 262 | + else if ((state->sctlr_after_ebs & 1) == 0) | |
| 263 | + pr_warn(FW_BUG "ExitBootServices() returned with MMU and Dcache disabled, please fix your firmware!\n"); | |
| 264 | + else | |
| 265 | + dump_state = false; | |
| 266 | + | |
| 267 | + if (dump_state || efi_enabled(EFI_DBG)) { | |
| 268 | + pr_info("CPSR at EFI stub entry : 0x%08x\n", state->cpsr_before_ebs); | |
| 269 | + pr_info("SCTLR at EFI stub entry : 0x%08x\n", state->sctlr_before_ebs); | |
| 270 | + pr_info("CPSR after ExitBootServices() : 0x%08x\n", state->cpsr_after_ebs); | |
| 271 | + pr_info("SCTLR after ExitBootServices(): 0x%08x\n", state->sctlr_after_ebs); | |
| 272 | + } | |
| 273 | + early_memunmap(state, sizeof(struct efi_arm_entry_state)); | |
| 274 | + } | |
| 275 | +#endif | |
| 244 | 276 | } |
| 245 | 277 | |
| 246 | 278 | static bool efifb_overlaps_pci_range(const struct of_pci_range *range) |
| @@ -189,7 +189,7 @@ static void generic_ops_unregister(void) · 188 unmodified lines | ||
| 189 | 189 | efivars_unregister(&generic_efivars); |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | −#if IS_ENABLED(CONFIG_ACPI) | |
| 192 | +#ifdef CONFIG_EFI_CUSTOM_SSDT_OVERLAYS | |
| 193 | 193 | #define EFIVAR_SSDT_NAME_MAX 16 |
| 194 | 194 | static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata; |
| 195 | 195 | static int __init efivar_ssdt_setup(char *str) |
| @@ -622,7 +622,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, · 426 unmodified lines | ||
| 622 | 622 | rsv = (void *)(p + prsv % PAGE_SIZE); |
| 623 | 623 | |
| 624 | 624 | /* reserve the entry itself */ |
| 625 | − memblock_reserve(prsv, EFI_MEMRESERVE_SIZE(rsv->size)); | |
| 625 | + memblock_reserve(prsv, | |
| 626 | + struct_size(rsv, entry, rsv->size)); | |
| 626 | 627 | |
| 627 | 628 | for (i = 0; i < atomic_read(&rsv->count); i++) { |
| 628 | 629 | memblock_reserve(rsv->entry[i].base, |
| @@ -181,7 +181,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num) · 180 unmodified lines | ||
| 181 | 181 | rc = kobject_init_and_add(&entry->kobj, &esre1_ktype, NULL, |
| 182 | 182 | "entry%d", entry_num); |
| 183 | 183 | if (rc) { |
| 184 | − kfree(entry); | |
| 184 | + kobject_put(&entry->kobj); | |
| 185 | 185 | return rc; |
| 186 | 186 | } |
| 187 | 187 | } |
| @@ -6,7 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | # enabled, even if doing so doesn't break the build. |
| 7 | 7 | # |
| 8 | 8 | cflags-$(CONFIG_X86_32) := -march=i386 |
| 9 | −cflags-$(CONFIG_X86_64) := -mcmodel=small | |
| 9 | +cflags-$(CONFIG_X86_64) := -mcmodel=small \ | |
| 10 | + $(call cc-option,-maccumulate-outgoing-args) | |
| 10 | 11 | cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ |
| 11 | 12 | -fPIC -fno-strict-aliasing -mno-red-zone \ |
| 12 | 13 | -mno-mmx -mno-sse -fshort-wchar \ |
| @@ -7,10 +7,49 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include "efistub.h" |
| 9 | 9 | |
| 10 | +static efi_guid_t cpu_state_guid = LINUX_EFI_ARM_CPU_STATE_TABLE_GUID; | |
| 11 | + | |
| 12 | +struct efi_arm_entry_state *efi_entry_state; | |
| 13 | + | |
| 14 | +static void get_cpu_state(u32 *cpsr, u32 *sctlr) | |
| 15 | +{ | |
| 16 | + asm("mrs %0, cpsr" : "=r"(*cpsr)); | |
| 17 | + if ((*cpsr & MODE_MASK) == HYP_MODE) | |
| 18 | + asm("mrc p15, 4, %0, c1, c0, 0" : "=r"(*sctlr)); | |
| 19 | + else | |
| 20 | + asm("mrc p15, 0, %0, c1, c0, 0" : "=r"(*sctlr)); | |
| 21 | +} | |
| 22 | + | |
| 10 | 23 | efi_status_t check_platform_features(void) |
| 11 | 24 | { |
| 25 | + efi_status_t status; | |
| 26 | + u32 cpsr, sctlr; | |
| 12 | 27 | int block; |
| 13 | 28 | |
| 29 | + get_cpu_state(&cpsr, &sctlr); | |
| 30 | + | |
| 31 | + efi_info("Entering in %s mode with MMU %sabled\n", | |
| 32 | + ((cpsr & MODE_MASK) == HYP_MODE) ? "HYP" : "SVC", | |
| 33 | + (sctlr & 1) ? "en" : "dis"); | |
| 34 | + | |
| 35 | + status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, | |
| 36 | + sizeof(*efi_entry_state), | |
| 37 | + (void **)&efi_entry_state); | |
| 38 | + if (status != EFI_SUCCESS) { | |
| 39 | + efi_err("allocate_pool() failed\n"); | |
| 40 | + return status; | |
| 41 | + } | |
| 42 | + | |
| 43 | + efi_entry_state->cpsr_before_ebs = cpsr; | |
| 44 | + efi_entry_state->sctlr_before_ebs = sctlr; | |
| 45 | + | |
| 46 | + status = efi_bs_call(install_configuration_table, &cpu_state_guid, | |
| 47 | + efi_entry_state); | |
| 48 | + if (status != EFI_SUCCESS) { | |
| 49 | + efi_err("install_configuration_table() failed\n"); | |
| 50 | + goto free_state; | |
| 51 | + } | |
| 52 | + | |
| 14 | 53 | /* non-LPAE kernels can run anywhere */ |
| 15 | 54 | if (!IS_ENABLED(CONFIG_ARM_LPAE)) |
| 16 | 55 | return EFI_SUCCESS; |
| @@ -19,9 +58,22 @@ efi_status_t check_platform_features(void) · 2 unmodified lines | ||
| 19 | 58 | block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0); |
| 20 | 59 | if (block < 5) { |
| 21 | 60 | efi_err("This LPAE kernel is not supported by your CPU\n"); |
| 22 | − return EFI_UNSUPPORTED; | |
| 61 | + status = EFI_UNSUPPORTED; | |
| 62 | + goto drop_table; | |
| 23 | 63 | } |
| 24 | 64 | return EFI_SUCCESS; |
| 65 | + | |
| 66 | +drop_table: | |
| 67 | + efi_bs_call(install_configuration_table, &cpu_state_guid, NULL); | |
| 68 | +free_state: | |
| 69 | + efi_bs_call(free_pool, efi_entry_state); | |
| 70 | + return status; | |
| 71 | +} | |
| 72 | + | |
| 73 | +void efi_handle_post_ebs_state(void) | |
| 74 | +{ | |
| 75 | + get_cpu_state(&efi_entry_state->cpsr_after_ebs, | |
| 76 | + &efi_entry_state->sctlr_after_ebs); | |
| 25 | 77 | } |
| 26 | 78 | |
| 27 | 79 | static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID; |
| @@ -32,6 +32,10 @@ bool __pure __efi_soft_reserve_enabled(void) · 31 unmodified lines | ||
| 32 | 32 | return !efi_nosoftreserve; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | +/** | |
| 36 | + * efi_char16_puts() - Write a UCS-2 encoded string to the console | |
| 37 | + * @str: UCS-2 encoded string | |
| 38 | + */ | |
| 35 | 39 | void efi_char16_puts(efi_char16_t *str) |
| 36 | 40 | { |
| 37 | 41 | efi_call_proto(efi_table_attr(efi_system_table, con_out), |
| @@ -83,6 +87,10 @@ u32 utf8_to_utf32(const u8 **s8) · 45 unmodified lines | ||
| 83 | 87 | return c32; |
| 84 | 88 | } |
| 85 | 89 | |
| 90 | +/** | |
| 91 | + * efi_puts() - Write a UTF-8 encoded string to the console | |
| 92 | + * @str: UTF-8 encoded string | |
| 93 | + */ | |
| 86 | 94 | void efi_puts(const char *str) |
| 87 | 95 | { |
| 88 | 96 | efi_char16_t buf[128]; |
| @@ -113,6 +121,16 @@ void efi_puts(const char *str) · 24 unmodified lines | ||
| 113 | 121 | } |
| 114 | 122 | } |
| 115 | 123 | |
| 124 | +/** | |
| 125 | + * efi_printk() - Print a kernel message | |
| 126 | + * @fmt: format string | |
| 127 | + * | |
| 128 | + * The first letter of the format string is used to determine the logging level | |
| 129 | + * of the message. If the level is less then the current EFI logging level, the | |
| 130 | + * message is suppressed. The message will be truncated to 255 bytes. | |
| 131 | + * | |
| 132 | + * Return: number of printed characters | |
| 133 | + */ | |
| 116 | 134 | int efi_printk(const char *fmt, ...) |
| 117 | 135 | { |
| 118 | 136 | char printf_buf[256]; |
| @@ -154,13 +172,18 @@ int efi_printk(const char *fmt, ...) · 35 unmodified lines | ||
| 154 | 172 | return printed; |
| 155 | 173 | } |
| 156 | 174 | |
| 157 | −/* | |
| 158 | − * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi= | |
| 175 | +/** | |
| 176 | + * efi_parse_options() - Parse EFI command line options | |
| 177 | + * @cmdline: kernel command line | |
| 178 | + * | |
| 179 | + * Parse the ASCII string @cmdline for EFI options, denoted by the efi= | |
| 159 | 180 | * option, e.g. efi=nochunk. |
| 160 | 181 | * |
| 161 | 182 | * It should be noted that efi= is parsed in two very different |
| 162 | 183 | * environments, first in the early boot environment of the EFI boot |
| 163 | 184 | * stub, and subsequently during the kernel boot. |
| 185 | + * | |
| 186 | + * Return: status code | |
| 164 | 187 | */ |
| 165 | 188 | efi_status_t efi_parse_options(char const *cmdline) |
| 166 | 189 | { |
| @@ -286,13 +309,21 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) · 119 unmodified lines | ||
| 286 | 309 | return (char *)cmdline_addr; |
| 287 | 310 | } |
| 288 | 311 | |
| 289 | −/* | |
| 312 | +/** | |
| 313 | + * efi_exit_boot_services() - Exit boot services | |
| 314 | + * @handle: handle of the exiting image | |
| 315 | + * @map: pointer to receive the memory map | |
| 316 | + * @priv: argument to be passed to @priv_func | |
| 317 | + * @priv_func: function to process the memory map before exiting boot services | |
| 318 | + * | |
| 290 | 319 | * Handle calling ExitBootServices according to the requirements set out by the |
| 291 | 320 | * spec. Obtains the current memory map, and returns that info after calling |
| 292 | 321 | * ExitBootServices. The client must specify a function to perform any |
| 293 | 322 | * processing of the memory map data prior to ExitBootServices. A client |
| 294 | 323 | * specific structure may be passed to the function via priv. The client |
| 295 | 324 | * function may be called multiple times. |
| 325 | + * | |
| 326 | + * Return: status code | |
| 296 | 327 | */ |
| 297 | 328 | efi_status_t efi_exit_boot_services(void *handle, |
| 298 | 329 | struct efi_boot_memmap *map, |
| @@ -361,6 +392,11 @@ fail: · 62 unmodified lines | ||
| 361 | 392 | return status; |
| 362 | 393 | } |
| 363 | 394 | |
| 395 | +/** | |
| 396 | + * get_efi_config_table() - retrieve UEFI configuration table | |
| 397 | + * @guid: GUID of the configuration table to be retrieved | |
| 398 | + * Return: pointer to the configuration table or NULL | |
| 399 | + */ | |
| 364 | 400 | void *get_efi_config_table(efi_guid_t guid) |
| 365 | 401 | { |
| 366 | 402 | unsigned long tables = efi_table_attr(efi_system_table, tables); |
| @@ -408,17 +444,18 @@ static const struct { · 41 unmodified lines | ||
| 408 | 444 | }; |
| 409 | 445 | |
| 410 | 446 | /** |
| 411 | − * efi_load_initrd_dev_path - load the initrd from the Linux initrd device path | |
| 447 | + * efi_load_initrd_dev_path() - load the initrd from the Linux initrd device path | |
| 412 | 448 | * @load_addr: pointer to store the address where the initrd was loaded |
| 413 | 449 | * @load_size: pointer to store the size of the loaded initrd |
| 414 | 450 | * @max: upper limit for the initrd memory allocation |
| 415 | − * @return: %EFI_SUCCESS if the initrd was loaded successfully, in which | |
| 416 | − * case @load_addr and @load_size are assigned accordingly | |
| 417 | − * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd | |
| 418 | − * device path | |
| 419 | − * %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL | |
| 420 | − * %EFI_OUT_OF_RESOURCES if memory allocation failed | |
| 421 | − * %EFI_LOAD_ERROR in all other cases | |
| 451 | + * | |
| 452 | + * Return: | |
| 453 | + * * %EFI_SUCCESS if the initrd was loaded successfully, in which | |
| 454 | + * case @load_addr and @load_size are assigned accordingly | |
| 455 | + * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path | |
| 456 | + * * %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL | |
| 457 | + * * %EFI_OUT_OF_RESOURCES if memory allocation failed | |
| 458 | + * * %EFI_LOAD_ERROR in all other cases | |
| 422 | 459 | */ |
| 423 | 460 | static |
| 424 | 461 | efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, |
| @@ -481,6 +518,16 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, · 56 unmodified lines | ||
| 481 | 518 | load_addr, load_size); |
| 482 | 519 | } |
| 483 | 520 | |
| 521 | +/** | |
| 522 | + * efi_load_initrd() - Load initial RAM disk | |
| 523 | + * @image: EFI loaded image protocol | |
| 524 | + * @load_addr: pointer to loaded initrd | |
| 525 | + * @load_size: size of loaded initrd | |
| 526 | + * @soft_limit: preferred size of allocated memory for loading the initrd | |
| 527 | + * @hard_limit: minimum size of allocated memory | |
| 528 | + * | |
| 529 | + * Return: status code | |
| 530 | + */ | |
| 484 | 531 | efi_status_t efi_load_initrd(efi_loaded_image_t *image, |
| 485 | 532 | unsigned long *load_addr, |
| 486 | 533 | unsigned long *load_size, |
| @@ -505,6 +552,15 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, · 18 unmodified lines | ||
| 505 | 552 | return status; |
| 506 | 553 | } |
| 507 | 554 | |
| 555 | +/** | |
| 556 | + * efi_wait_for_key() - Wait for key stroke | |
| 557 | + * @usec: number of microseconds to wait for key stroke | |
| 558 | + * @key: key entered | |
| 559 | + * | |
| 560 | + * Wait for up to @usec microseconds for a key stroke. | |
| 561 | + * | |
| 562 | + * Return: status code, EFI_SUCCESS if key received | |
| 563 | + */ | |
| 508 | 564 | efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key) |
| 509 | 565 | { |
| 510 | 566 | efi_event_t events[2], timer; |
| @@ -329,6 +329,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, · 328 unmodified lines | ||
| 329 | 329 | if (status != EFI_SUCCESS) |
| 330 | 330 | goto fail_free_initrd; |
| 331 | 331 | |
| 332 | + if (IS_ENABLED(CONFIG_ARM)) | |
| 333 | + efi_handle_post_ebs_state(); | |
| 334 | + | |
| 332 | 335 | efi_enter_kernel(image_addr, fdt_addr, fdt_totalsize((void *)fdt_addr)); |
| 333 | 336 | /* not reached */ |
| 334 | 337 | |
| @@ -157,8 +157,14 @@ typedef void (__efiapi *efi_event_notify_t)(efi_event_t, void *); · 156 unmodified lines | ||
| 157 | 157 | #define EFI_EVT_NOTIFY_WAIT 0x00000100U |
| 158 | 158 | #define EFI_EVT_NOTIFY_SIGNAL 0x00000200U |
| 159 | 159 | |
| 160 | −/* | |
| 161 | − * boottime->wait_for_event takes an array of events as input. | |
| 160 | +/** | |
| 161 | + * efi_set_event_at() - add event to events array | |
| 162 | + * | |
| 163 | + * @events: array of UEFI events | |
| 164 | + * @ids: index where to put the event in the array | |
| 165 | + * @event: event to add to the aray | |
| 166 | + * | |
| 167 | + * boottime->wait_for_event() takes an array of events as input. | |
| 162 | 168 | * Provide a helper to set it up correctly for mixed mode. |
| 163 | 169 | */ |
| 164 | 170 | static inline |
| @@ -771,4 +777,6 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, · 606 unmodified lines | ||
| 771 | 777 | unsigned long soft_limit, |
| 772 | 778 | unsigned long hard_limit); |
| 773 | 779 | |
| 780 | +void efi_handle_post_ebs_state(void); | |
| 781 | + | |
| 774 | 782 | #endif |
| @@ -102,12 +102,20 @@ static int find_file_option(const efi_char16_t *cmdline, int cmdline_len, · 101 unmodified lines | ||
| 102 | 102 | if (!found) |
| 103 | 103 | return 0; |
| 104 | 104 | |
| 105 | + /* Skip any leading slashes */ | |
| 106 | + while (cmdline[i] == L'/' || cmdline[i] == L'\\') | |
| 107 | + i++; | |
| 108 | + | |
| 105 | 109 | while (--result_len > 0 && i < cmdline_len) { |
| 106 | − if (cmdline[i] == L'\0' || | |
| 107 | − cmdline[i] == L'\n' || | |
| 108 | − cmdline[i] == L' ') | |
| 110 | + efi_char16_t c = cmdline[i++]; | |
| 111 | + | |
| 112 | + if (c == L'\0' || c == L'\n' || c == L' ') | |
| 109 | 113 | break; |
| 110 | − *result++ = cmdline[i++]; | |
| 114 | + else if (c == L'/') | |
| 115 | + /* Replace UNIX dir separators with EFI standard ones */ | |
| 116 | + *result++ = L'\\'; | |
| 117 | + else | |
| 118 | + *result++ = c; | |
| 111 | 119 | } |
| 112 | 120 | *result = L'\0'; |
| 113 | 121 | return i; |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | 3 | #include <linux/ctype.h> |
| 4 | +#include <linux/string.h> | |
| 4 | 5 | #include <linux/types.h> |
| 5 | 6 | |
| 6 | 7 | char *skip_spaces(const char *str) |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | struct cbmem_cons { |
| 22 | 22 | u32 size_dont_access_after_boot; |
| 23 | 23 | u32 cursor; |
| 24 | − u8 body[0]; | |
| 24 | + u8 body[]; | |
| 25 | 25 | } __packed; |
| 26 | 26 | |
| 27 | 27 | #define CURSOR_MASK ((1 << 28) - 1) |
| @@ -32,7 +32,7 @@ struct vpd_cbmem { · 31 unmodified lines | ||
| 32 | 32 | u32 version; |
| 33 | 33 | u32 ro_size; |
| 34 | 34 | u32 rw_size; |
| 35 | − u8 blob[0]; | |
| 35 | + u8 blob[]; | |
| 36 | 36 | }; |
| 37 | 37 | |
| 38 | 38 | struct vpd_section { |
| @@ -104,7 +104,7 @@ struct ibft_control { · 103 unmodified lines | ||
| 104 | 104 | u16 tgt0_off; |
| 105 | 105 | u16 nic1_off; |
| 106 | 106 | u16 tgt1_off; |
| 107 | − u16 expansion[0]; | |
| 107 | + u16 expansion[]; | |
| 108 | 108 | } __attribute__((__packed__)); |
| 109 | 109 | |
| 110 | 110 | struct ibft_initiator { |
| @@ -103,6 +103,6 @@ struct pcdp { · 102 unmodified lines | ||
| 103 | 103 | u8 creator_id[4]; |
| 104 | 104 | u32 creator_rev; |
| 105 | 105 | u32 num_uarts; |
| 106 | − struct pcdp_uart uart[0]; /* actual size is num_uarts */ | |
| 106 | + struct pcdp_uart uart[]; /* actual size is num_uarts */ | |
| 107 | 107 | /* remainder of table is pcdp_device structures */ |
| 108 | 108 | } __attribute__((packed)); |
| @@ -181,6 +181,7 @@ EXPORT_SYMBOL_GPL(rpi_firmware_property); · 180 unmodified lines | ||
| 181 | 181 | static void |
| 182 | 182 | rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) |
| 183 | 183 | { |
| 184 | + time64_t date_and_time; | |
| 184 | 185 | u32 packet; |
| 185 | 186 | int ret = rpi_firmware_property(fw, |
| 186 | 187 | RPI_FIRMWARE_GET_FIRMWARE_REVISION, |
| @@ -189,7 +190,9 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) · 2 unmodified lines | ||
| 189 | 190 | if (ret) |
| 190 | 191 | return; |
| 191 | 192 | |
| 192 | − dev_info(fw->cl.dev, "Attached to firmware from %ptT\n", &packet); | |
| 193 | + /* This is not compatible with y2038 */ | |
| 194 | + date_and_time = packet; | |
| 195 | + dev_info(fw->cl.dev, "Attached to firmware from %ptT\n", &date_and_time); | |
| 193 | 196 | } |
| 194 | 197 | |
| 195 | 198 | static void |
| @@ -208,7 +208,7 @@ config FPGA_DFL_PCI · 207 unmodified lines | ||
| 208 | 208 | |
| 209 | 209 | config FPGA_MGR_ZYNQMP_FPGA |
| 210 | 210 | tristate "Xilinx ZynqMP FPGA" |
| 211 | − depends on ARCH_ZYNQMP || COMPILE_TEST | |
| 211 | + depends on ZYNQMP_FIRMWARE || (!ZYNQMP_FIRMWARE && COMPILE_TEST) | |
| 212 | 212 | help |
| 213 | 213 | FPGA manager driver support for Xilinx ZynqMP FPGAs. |
| 214 | 214 | This driver uses the processor configuration port(PCAP) |
| @@ -204,6 +204,7 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, · 203 unmodified lines | ||
| 204 | 204 | (mode_info->atom_context->bios + data_offset); |
| 205 | 205 | switch (crev) { |
| 206 | 206 | case 11: |
| 207 | + case 12: | |
| 207 | 208 | mem_channel_number = igp_info->v11.umachannelnumber; |
| 208 | 209 | /* channel width is 64 */ |
| 209 | 210 | if (vram_width) |
| @@ -696,7 +696,7 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, · 695 unmodified lines | ||
| 696 | 696 | * default power levels, write "r" (reset) to the file to reset them. |
| 697 | 697 | * |
| 698 | 698 | * |
| 699 | − * < For Vega20 > | |
| 699 | + * < For Vega20 and newer ASICs > | |
| 700 | 700 | * |
| 701 | 701 | * Reading the file will display: |
| 702 | 702 | * |
| @@ -1668,7 +1668,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, · 965 unmodified lines | ||
| 1668 | 1668 | } |
| 1669 | 1669 | |
| 1670 | 1670 | /** |
| 1671 | − * DOC: busy_percent | |
| 1671 | + * DOC: gpu_busy_percent | |
| 1672 | 1672 | * |
| 1673 | 1673 | * The amdgpu driver provides a sysfs API for reading how busy the GPU |
| 1674 | 1674 | * is as a percentage. The file gpu_busy_percent is used for this. |
| @@ -2784,7 +2784,7 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, · 1109 unmodified lines | ||
| 2784 | 2784 | if (r) |
| 2785 | 2785 | return r; |
| 2786 | 2786 | |
| 2787 | − return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000); | |
| 2787 | + return snprintf(buf, PAGE_SIZE, "%u\n", sclk * 10 * 1000); | |
| 2788 | 2788 | } |
| 2789 | 2789 | |
| 2790 | 2790 | static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev, |
| @@ -2819,7 +2819,7 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, · 28 unmodified lines | ||
| 2819 | 2819 | if (r) |
| 2820 | 2820 | return r; |
| 2821 | 2821 | |
| 2822 | − return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000); | |
| 2822 | + return snprintf(buf, PAGE_SIZE, "%u\n", mclk * 10 * 1000); | |
| 2823 | 2823 | } |
| 2824 | 2824 | |
| 2825 | 2825 | static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev, |
| @@ -1298,8 +1298,12 @@ static int sdma_v5_0_sw_fini(void *handle) · 1297 unmodified lines | ||
| 1298 | 1298 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1299 | 1299 | int i; |
| 1300 | 1300 | |
| 1301 | − for (i = 0; i < adev->sdma.num_instances; i++) | |
| 1301 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 1302 | + if (adev->sdma.instance[i].fw != NULL) | |
| 1303 | + release_firmware(adev->sdma.instance[i].fw); | |
| 1304 | + | |
| 1302 | 1305 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1306 | + } | |
| 1303 | 1307 | |
| 1304 | 1308 | return 0; |
| 1305 | 1309 | } |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | #include <drm/drm_file.h> |
| 41 | 41 | #include <drm/drm_drv.h> |
| 42 | 42 | #include <drm/drm_device.h> |
| 43 | +#include <drm/drm_ioctl.h> | |
| 43 | 44 | #include <kgd_kfd_interface.h> |
| 44 | 45 | #include <linux/swap.h> |
| 45 | 46 | |
| @@ -1076,7 +1077,7 @@ static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd) · 1030 unmodified lines | ||
| 1076 | 1077 | #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) |
| 1077 | 1078 | struct drm_device *ddev = kfd->ddev; |
| 1078 | 1079 | |
| 1079 | − return devcgroup_check_permission(DEVCG_DEV_CHAR, ddev->driver->major, | |
| 1080 | + return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR, | |
| 1080 | 1081 | ddev->render->index, |
| 1081 | 1082 | DEVCG_ACC_WRITE | DEVCG_ACC_READ); |
| 1082 | 1083 | #else |
| @@ -428,6 +428,7 @@ struct kfd_process *kfd_create_process(struct file *filep) · 427 unmodified lines | ||
| 428 | 428 | (int)process->lead_thread->pid); |
| 429 | 429 | if (ret) { |
| 430 | 430 | pr_warn("Creating procfs pid directory failed"); |
| 431 | + kobject_put(process->kobj); | |
| 431 | 432 | goto out; |
| 432 | 433 | } |
| 433 | 434 | |
| @@ -5024,7 +5024,8 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 5023 unmodified lines | ||
| 5024 | 5024 | struct drm_connector *connector = &aconnector->base; |
| 5025 | 5025 | struct amdgpu_device *adev = connector->dev->dev_private; |
| 5026 | 5026 | struct dc_stream_state *stream; |
| 5027 | − int requested_bpc = connector->state ? connector->state->max_requested_bpc : 8; | |
| 5027 | + const struct drm_connector_state *drm_state = dm_state ? &dm_state->base : NULL; | |
| 5028 | + int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8; | |
| 5028 | 5029 | enum dc_status dc_result = DC_OK; |
| 5029 | 5030 | |
| 5030 | 5031 | do { |
| @@ -1058,7 +1058,6 @@ static const struct { · 1057 unmodified lines | ||
| 1058 | 1058 | {"link_settings", &dp_link_settings_debugfs_fops}, |
| 1059 | 1059 | {"phy_settings", &dp_phy_settings_debugfs_fop}, |
| 1060 | 1060 | {"test_pattern", &dp_phy_test_pattern_fops}, |
| 1061 | − {"output_bpc", &output_bpc_fops}, | |
| 1062 | 1061 | {"vrr_range", &vrr_range_fops}, |
| 1063 | 1062 | #ifdef CONFIG_DRM_AMD_DC_HDCP |
| 1064 | 1063 | {"hdcp_sink_capability", &hdcp_sink_capability_fops}, |
| @@ -1142,6 +1141,9 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) · 77 unmodified lines | ||
| 1142 | 1141 | debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector, |
| 1143 | 1142 | &force_yuv420_output_fops); |
| 1144 | 1143 | |
| 1144 | + debugfs_create_file("output_bpc", 0644, dir, connector, | |
| 1145 | + &output_bpc_fops); | |
| 1146 | + | |
| 1145 | 1147 | connector->debugfs_dpcd_address = 0; |
| 1146 | 1148 | connector->debugfs_dpcd_size = 0; |
| 1147 | 1149 | |
| @@ -510,8 +510,10 @@ static ssize_t srm_data_read(struct file *filp, struct kobject *kobj, struct bin · 509 unmodified lines | ||
| 510 | 510 | |
| 511 | 511 | srm = psp_get_srm(work->hdcp.config.psp.handle, &srm_version, &srm_size); |
| 512 | 512 | |
| 513 | − if (!srm) | |
| 514 | − return -EINVAL; | |
| 513 | + if (!srm) { | |
| 514 | + ret = -EINVAL; | |
| 515 | + goto ret; | |
| 516 | + } | |
| 515 | 517 | |
| 516 | 518 | if (pos >= srm_size) |
| 517 | 519 | ret = 0; |
| @@ -2538,10 +2538,12 @@ void dc_commit_updates_for_stream(struct dc *dc, · 2537 unmodified lines | ||
| 2538 | 2538 | |
| 2539 | 2539 | copy_stream_update_to_stream(dc, context, stream, stream_update); |
| 2540 | 2540 | |
| 2541 | − if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { | |
| 2542 | − DC_ERROR("Mode validation failed for stream update!\n"); | |
| 2543 | − dc_release_state(context); | |
| 2544 | − return; | |
| 2541 | + if (update_type > UPDATE_TYPE_FAST) { | |
| 2542 | + if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { | |
| 2543 | + DC_ERROR("Mode validation failed for stream update!\n"); | |
| 2544 | + dc_release_state(context); | |
| 2545 | + return; | |
| 2546 | + } | |
| 2545 | 2547 | } |
| 2546 | 2548 | |
| 2547 | 2549 | commit_planes_for_stream( |
| @@ -28,8 +28,6 @@ endif · 27 unmodified lines | ||
| 28 | 28 | endif |
| 29 | 29 | |
| 30 | 30 | CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags) |
| 31 | −CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc_dpi.o := $(dsc_ccflags) | |
| 32 | −CFLAGS_$(AMDDALPATH)/dc/dsc/dc_dsc.o := $(dsc_ccflags) | |
| 33 | 31 | |
| 34 | 32 | DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o |
| 35 | 33 | |
| @@ -22,10 +22,12 @@ · 21 unmodified lines | ||
| 22 | 22 | * Author: AMD |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | +#include <drm/drm_dsc.h> | |
| 25 | 26 | #include "dc_hw_types.h" |
| 26 | 27 | #include "dsc.h" |
| 27 | 28 | #include <drm/drm_dp_helper.h> |
| 28 | 29 | #include "dc.h" |
| 30 | +#include "rc_calc.h" | |
| 29 | 31 | |
| 30 | 32 | /* This module's internal functions */ |
| 31 | 33 | |
| @@ -304,22 +306,6 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t value) · 272 unmodified lines | ||
| 304 | 306 | return (value + 9) / 10; |
| 305 | 307 | } |
| 306 | 308 | |
| 307 | −static inline uint32_t calc_dsc_bpp_x16(uint32_t stream_bandwidth_kbps, uint32_t pix_clk_100hz, uint32_t bpp_increment_div) | |
| 308 | −{ | |
| 309 | − uint32_t dsc_target_bpp_x16; | |
| 310 | − float f_dsc_target_bpp; | |
| 311 | − float f_stream_bandwidth_100bps = stream_bandwidth_kbps * 10.0f; | |
| 312 | − uint32_t precision = bpp_increment_div; // bpp_increment_div is actually precision | |
| 313 | − | |
| 314 | − f_dsc_target_bpp = f_stream_bandwidth_100bps / pix_clk_100hz; | |
| 315 | − | |
| 316 | − // Round down to the nearest precision stop to bring it into DSC spec range | |
| 317 | − dsc_target_bpp_x16 = (uint32_t)(f_dsc_target_bpp * precision); | |
| 318 | − dsc_target_bpp_x16 = (dsc_target_bpp_x16 * 16) / precision; | |
| 319 | − | |
| 320 | − return dsc_target_bpp_x16; | |
| 321 | −} | |
| 322 | − | |
| 323 | 309 | /* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock |
| 324 | 310 | * and uncompressed bandwidth. |
| 325 | 311 | */ |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | * Authors: AMD |
| 24 | 24 | * |
| 25 | 25 | */ |
| 26 | +#include <drm/drm_dsc.h> | |
| 26 | 27 | |
| 27 | 28 | #include "os_types.h" |
| 28 | 29 | #include "rc_calc.h" |
| @@ -40,7 +41,8 @@ · 11 unmodified lines | ||
| 40 | 41 | break |
| 41 | 42 | |
| 42 | 43 | |
| 43 | −void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, enum max_min max_min, float bpp) | |
| 44 | +static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, | |
| 45 | + enum max_min max_min, float bpp) | |
| 44 | 46 | { |
| 45 | 47 | int mode = MODE_SELECT(444, 422, 420); |
| 46 | 48 | int sel = table_hash(mode, bpc, max_min); |
| @@ -85,7 +87,7 @@ void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, enum ma · 38 unmodified lines | ||
| 85 | 87 | memcpy(qps, table[index].qps, sizeof(qp_set)); |
| 86 | 88 | } |
| 87 | 89 | |
| 88 | −double dsc_roundf(double num) | |
| 90 | +static double dsc_roundf(double num) | |
| 89 | 91 | { |
| 90 | 92 | if (num < 0.0) |
| 91 | 93 | num = num - 0.5; |
| @@ -95,7 +97,7 @@ double dsc_roundf(double num) · 3 unmodified lines | ||
| 95 | 97 | return (int)(num); |
| 96 | 98 | } |
| 97 | 99 | |
| 98 | −double dsc_ceil(double num) | |
| 100 | +static double dsc_ceil(double num) | |
| 99 | 101 | { |
| 100 | 102 | double retval = (int)num; |
| 101 | 103 | |
| @@ -105,7 +107,7 @@ double dsc_ceil(double num) · 3 unmodified lines | ||
| 105 | 107 | return (int)retval; |
| 106 | 108 | } |
| 107 | 109 | |
| 108 | −void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) | |
| 110 | +static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) | |
| 109 | 111 | { |
| 110 | 112 | int *p = ofs; |
| 111 | 113 | |
| @@ -160,7 +162,7 @@ void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) · 48 unmodified lines | ||
| 160 | 162 | } |
| 161 | 163 | } |
| 162 | 164 | |
| 163 | −int median3(int a, int b, int c) | |
| 165 | +static int median3(int a, int b, int c) | |
| 164 | 166 | { |
| 165 | 167 | if (a > b) |
| 166 | 168 | swap(a, b); |
| @@ -172,13 +174,25 @@ int median3(int a, int b, int c) · 5 unmodified lines | ||
| 172 | 174 | return b; |
| 173 | 175 | } |
| 174 | 176 | |
| 175 | −void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_comp bpc, float bpp, int slice_width, int slice_height, int minor_version) | |
| 177 | +static void _do_calc_rc_params(struct rc_params *rc, enum colour_mode cm, | |
| 178 | + enum bits_per_comp bpc, u8 drm_bpp, | |
| 179 | + bool is_navite_422_or_420, | |
| 180 | + int slice_width, int slice_height, | |
| 181 | + int minor_version) | |
| 176 | 182 | { |
| 183 | + float bpp; | |
| 177 | 184 | float bpp_group; |
| 178 | 185 | float initial_xmit_delay_factor; |
| 179 | 186 | int padding_pixels; |
| 180 | 187 | int i; |
| 181 | 188 | |
| 189 | + bpp = ((float)drm_bpp / 16.0); | |
| 190 | + /* in native_422 or native_420 modes, the bits_per_pixel is double the | |
| 191 | + * target bpp (the latter is what calc_rc_params expects) | |
| 192 | + */ | |
| 193 | + if (is_navite_422_or_420) | |
| 194 | + bpp /= 2.0; | |
| 195 | + | |
| 182 | 196 | rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); |
| 183 | 197 | rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); |
| 184 | 198 | |
| @@ -251,3 +265,128 @@ void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_com · 66 unmodified lines | ||
| 251 | 265 | rc->rc_buf_thresh[13] = 8064; |
| 252 | 266 | } |
| 253 | 267 | |
| 268 | +static u32 _do_bytes_per_pixel_calc(int slice_width, u8 drm_bpp, | |
| 269 | + bool is_navite_422_or_420) | |
| 270 | +{ | |
| 271 | + float bpp; | |
| 272 | + u32 bytes_per_pixel; | |
| 273 | + double d_bytes_per_pixel; | |
| 274 | + | |
| 275 | + bpp = ((float)drm_bpp / 16.0); | |
| 276 | + d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; | |
| 277 | + // TODO: Make sure the formula for calculating this is precise (ceiling | |
| 278 | + // vs. floor, and at what point they should be applied) | |
| 279 | + if (is_navite_422_or_420) | |
| 280 | + d_bytes_per_pixel /= 2; | |
| 281 | + | |
| 282 | + bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000); | |
| 283 | + | |
| 284 | + return bytes_per_pixel; | |
| 285 | +} | |
| 286 | + | |
| 287 | +static u32 _do_calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz, | |
| 288 | + u32 bpp_increment_div) | |
| 289 | +{ | |
| 290 | + u32 dsc_target_bpp_x16; | |
| 291 | + float f_dsc_target_bpp; | |
| 292 | + float f_stream_bandwidth_100bps; | |
| 293 | + // bpp_increment_div is actually precision | |
| 294 | + u32 precision = bpp_increment_div; | |
| 295 | + | |
| 296 | + f_stream_bandwidth_100bps = stream_bandwidth_kbps * 10.0f; | |
| 297 | + f_dsc_target_bpp = f_stream_bandwidth_100bps / pix_clk_100hz; | |
| 298 | + | |
| 299 | + // Round down to the nearest precision stop to bring it into DSC spec | |
| 300 | + // range | |
| 301 | + dsc_target_bpp_x16 = (u32)(f_dsc_target_bpp * precision); | |
| 302 | + dsc_target_bpp_x16 = (dsc_target_bpp_x16 * 16) / precision; | |
| 303 | + | |
| 304 | + return dsc_target_bpp_x16; | |
| 305 | +} | |
| 306 | + | |
| 307 | +/** | |
| 308 | + * calc_rc_params - reads the user's cmdline mode | |
| 309 | + * @rc: DC internal DSC parameters | |
| 310 | + * @pps: DRM struct with all required DSC values | |
| 311 | + * | |
| 312 | + * This function expects a drm_dsc_config data struct with all the required DSC | |
| 313 | + * values previously filled out by our driver and based on this information it | |
| 314 | + * computes some of the DSC values. | |
| 315 | + * | |
| 316 | + * @note This calculation requires float point operation, most of it executes | |
| 317 | + * under kernel_fpu_{begin,end}. | |
| 318 | + */ | |
| 319 | +void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps) | |
| 320 | +{ | |
| 321 | + enum colour_mode mode; | |
| 322 | + enum bits_per_comp bpc; | |
| 323 | + bool is_navite_422_or_420; | |
| 324 | + u8 drm_bpp = pps->bits_per_pixel; | |
| 325 | + int slice_width = pps->slice_width; | |
| 326 | + int slice_height = pps->slice_height; | |
| 327 | + | |
| 328 | + mode = pps->convert_rgb ? CM_RGB : (pps->simple_422 ? CM_444 : | |
| 329 | + (pps->native_422 ? CM_422 : | |
| 330 | + pps->native_420 ? CM_420 : CM_444)); | |
| 331 | + bpc = (pps->bits_per_component == 8) ? BPC_8 : (pps->bits_per_component == 10) | |
| 332 | + ? BPC_10 : BPC_12; | |
| 333 | + | |
| 334 | + is_navite_422_or_420 = pps->native_422 || pps->native_420; | |
| 335 | + | |
| 336 | + DC_FP_START(); | |
| 337 | + _do_calc_rc_params(rc, mode, bpc, drm_bpp, is_navite_422_or_420, | |
| 338 | + slice_width, slice_height, | |
| 339 | + pps->dsc_version_minor); | |
| 340 | + DC_FP_END(); | |
| 341 | +} | |
| 342 | + | |
| 343 | +/** | |
| 344 | + * calc_dsc_bytes_per_pixel - calculate bytes per pixel | |
| 345 | + * @pps: DRM struct with all required DSC values | |
| 346 | + * | |
| 347 | + * Based on the information inside drm_dsc_config, this function calculates the | |
| 348 | + * total of bytes per pixel. | |
| 349 | + * | |
| 350 | + * @note This calculation requires float point operation, most of it executes | |
| 351 | + * under kernel_fpu_{begin,end}. | |
| 352 | + * | |
| 353 | + * Return: | |
| 354 | + * Return the number of bytes per pixel | |
| 355 | + */ | |
| 356 | +u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps) | |
| 357 | + | |
| 358 | +{ | |
| 359 | + u32 ret; | |
| 360 | + u8 drm_bpp = pps->bits_per_pixel; | |
| 361 | + int slice_width = pps->slice_width; | |
| 362 | + bool is_navite_422_or_420 = pps->native_422 || pps->native_420; | |
| 363 | + | |
| 364 | + DC_FP_START(); | |
| 365 | + ret = _do_bytes_per_pixel_calc(slice_width, drm_bpp, | |
| 366 | + is_navite_422_or_420); | |
| 367 | + DC_FP_END(); | |
| 368 | + return ret; | |
| 369 | +} | |
| 370 | + | |
| 371 | +/** | |
| 372 | + * calc_dsc_bpp_x16 - retrieve the dsc bits per pixel | |
| 373 | + * @stream_bandwidth_kbps: | |
| 374 | + * @pix_clk_100hz: | |
| 375 | + * @bpp_increment_div: | |
| 376 | + * | |
| 377 | + * Calculate the total of bits per pixel for DSC configuration. | |
| 378 | + * | |
| 379 | + * @note This calculation requires float point operation, most of it executes | |
| 380 | + * under kernel_fpu_{begin,end}. | |
| 381 | + */ | |
| 382 | +u32 calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz, | |
| 383 | + u32 bpp_increment_div) | |
| 384 | +{ | |
| 385 | + u32 dsc_bpp; | |
| 386 | + | |
| 387 | + DC_FP_START(); | |
| 388 | + dsc_bpp = _do_calc_dsc_bpp_x16(stream_bandwidth_kbps, pix_clk_100hz, | |
| 389 | + bpp_increment_div); | |
| 390 | + DC_FP_END(); | |
| 391 | + return dsc_bpp; | |
| 392 | +} | |
| @@ -77,7 +77,10 @@ struct qp_entry { · 76 unmodified lines | ||
| 77 | 77 | |
| 78 | 78 | typedef struct qp_entry qp_table[]; |
| 79 | 79 | |
| 80 | −void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_comp bpc, float bpp, int slice_width, int slice_height, int minor_version); | |
| 80 | +void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps); | |
| 81 | +u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps); | |
| 82 | +u32 calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz, | |
| 83 | + u32 bpp_increment_div); | |
| 81 | 84 | |
| 82 | 85 | #endif |
| 83 | 86 | |
| @@ -27,8 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #include "dscc_types.h" |
| 28 | 28 | #include "rc_calc.h" |
| 29 | 29 | |
| 30 | −double dsc_ceil(double num); | |
| 31 | − | |
| 32 | 30 | static void copy_pps_fields(struct drm_dsc_config *to, const struct drm_dsc_config *from) |
| 33 | 31 | { |
| 34 | 32 | to->line_buf_depth = from->line_buf_depth; |
| @@ -100,34 +98,13 @@ static void copy_rc_to_cfg(struct drm_dsc_config *dsc_cfg, const struct rc_param · 65 unmodified lines | ||
| 100 | 98 | |
| 101 | 99 | int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_parameters *dsc_params) |
| 102 | 100 | { |
| 103 | − enum colour_mode mode = pps->convert_rgb ? CM_RGB : | |
| 104 | − (pps->simple_422 ? CM_444 : | |
| 105 | − (pps->native_422 ? CM_422 : | |
| 106 | − pps->native_420 ? CM_420 : CM_444)); | |
| 107 | − enum bits_per_comp bpc = (pps->bits_per_component == 8) ? BPC_8 : | |
| 108 | − (pps->bits_per_component == 10) ? BPC_10 : BPC_12; | |
| 109 | − float bpp = ((float) pps->bits_per_pixel / 16.0); | |
| 110 | − int slice_width = pps->slice_width; | |
| 111 | − int slice_height = pps->slice_height; | |
| 112 | 101 | int ret; |
| 113 | 102 | struct rc_params rc; |
| 114 | 103 | struct drm_dsc_config dsc_cfg; |
| 115 | 104 | |
| 116 | − double d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; | |
| 117 | − | |
| 118 | − // TODO: Make sure the formula for calculating this is precise (ceiling vs. floor, and at what point they should be applied) | |
| 119 | − if (pps->native_422 || pps->native_420) | |
| 120 | − d_bytes_per_pixel /= 2; | |
| 121 | − | |
| 122 | − dsc_params->bytes_per_pixel = (uint32_t)dsc_ceil(d_bytes_per_pixel * 0x10000000); | |
| 123 | − | |
| 124 | − /* in native_422 or native_420 modes, the bits_per_pixel is double the target bpp | |
| 125 | − * (the latter is what calc_rc_params expects) | |
| 126 | − */ | |
| 127 | − if (pps->native_422 || pps->native_420) | |
| 128 | − bpp /= 2.0; | |
| 105 | + dsc_params->bytes_per_pixel = calc_dsc_bytes_per_pixel(pps); | |
| 129 | 106 | |
| 130 | − calc_rc_params(&rc, mode, bpc, bpp, slice_width, slice_height, pps->dsc_version_minor); | |
| 107 | + calc_rc_params(&rc, pps); | |
| 131 | 108 | dsc_params->pps = *pps; |
| 132 | 109 | dsc_params->pps.initial_scale_value = 8 * rc.rc_model_size / (rc.rc_model_size - rc.initial_fullness_offset); |
| 133 | 110 | |
| @@ -843,7 +843,7 @@ static bool build_regamma(struct pwl_float_data_ex *rgb_regamma, · 842 unmodified lines | ||
| 843 | 843 | pow_buffer_ptr = -1; // reset back to no optimize |
| 844 | 844 | ret = true; |
| 845 | 845 | release: |
| 846 | − kfree(coeff); | |
| 846 | + kvfree(coeff); | |
| 847 | 847 | return ret; |
| 848 | 848 | } |
| 849 | 849 | |
| @@ -1777,7 +1777,7 @@ bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf, · 927 unmodified lines | ||
| 1777 | 1777 | |
| 1778 | 1778 | kfree(rgb_regamma); |
| 1779 | 1779 | rgb_regamma_alloc_fail: |
| 1780 | − kvfree(rgb_user); | |
| 1780 | + kfree(rgb_user); | |
| 1781 | 1781 | rgb_user_alloc_fail: |
| 1782 | 1782 | return ret; |
| 1783 | 1783 | } |
| @@ -239,7 +239,7 @@ static void ci_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) · 238 unmodified lines | ||
| 239 | 239 | |
| 240 | 240 | switch (dev_id) { |
| 241 | 241 | case 0x67BA: |
| 242 | − case 0x66B1: | |
| 242 | + case 0x67B1: | |
| 243 | 243 | smu_data->power_tune_defaults = &defaults_hawaii_pro; |
| 244 | 244 | break; |
| 245 | 245 | case 0x67B8: |
| @@ -522,9 +522,11 @@ static int vega20_smu_init(struct pp_hwmgr *hwmgr) · 521 unmodified lines | ||
| 522 | 522 | priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].version = 0x01; |
| 523 | 523 | priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].size = sizeof(DpmActivityMonitorCoeffInt_t); |
| 524 | 524 | |
| 525 | − ret = smu_v11_0_i2c_eeprom_control_init(&adev->pm.smu_i2c); | |
| 526 | − if (ret) | |
| 527 | − goto err4; | |
| 525 | + if (adev->psp.ras.ras) { | |
| 526 | + ret = smu_v11_0_i2c_eeprom_control_init(&adev->pm.smu_i2c); | |
| 527 | + if (ret) | |
| 528 | + goto err4; | |
| 529 | + } | |
| 528 | 530 | |
| 529 | 531 | return 0; |
| 530 | 532 | |
| @@ -560,7 +562,8 @@ static int vega20_smu_fini(struct pp_hwmgr *hwmgr) · 29 unmodified lines | ||
| 560 | 562 | (struct vega20_smumgr *)(hwmgr->smu_backend); |
| 561 | 563 | struct amdgpu_device *adev = hwmgr->adev; |
| 562 | 564 | |
| 563 | − smu_v11_0_i2c_eeprom_control_fini(&adev->pm.smu_i2c); | |
| 565 | + if (adev->psp.ras.ras) | |
| 566 | + smu_v11_0_i2c_eeprom_control_fini(&adev->pm.smu_i2c); | |
| 564 | 567 | |
| 565 | 568 | if (priv) { |
| 566 | 569 | amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle, |
| @@ -61,13 +61,8 @@ int drm_i2c_encoder_init(struct drm_device *dev, · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | request_module("%s%s", I2C_MODULE_PREFIX, info->type); |
| 63 | 63 | |
| 64 | − client = i2c_new_device(adap, info); | |
| 65 | − if (!client) { | |
| 66 | − err = -ENOMEM; | |
| 67 | − goto fail; | |
| 68 | − } | |
| 69 | − | |
| 70 | − if (!client->dev.driver) { | |
| 64 | + client = i2c_new_client_device(adap, info); | |
| 65 | + if (!i2c_client_has_driver(client)) { | |
| 71 | 66 | err = -ENODEV; |
| 72 | 67 | goto fail_unregister; |
| 73 | 68 | } |
| @@ -84,7 +79,7 @@ int drm_i2c_encoder_init(struct drm_device *dev, · 10 unmodified lines | ||
| 84 | 79 | |
| 85 | 80 | err = encoder_drv->encoder_init(client, dev, encoder); |
| 86 | 81 | if (err) |
| 87 | − goto fail_unregister; | |
| 82 | + goto fail_module_put; | |
| 88 | 83 | |
| 89 | 84 | if (info->platform_data) |
| 90 | 85 | encoder->slave_funcs->set_config(&encoder->base, |
| @@ -92,10 +87,10 @@ int drm_i2c_encoder_init(struct drm_device *dev, · 1 unmodified line | ||
| 92 | 87 | |
| 93 | 88 | return 0; |
| 94 | 89 | |
| 90 | +fail_module_put: | |
| 91 | + module_put(module); | |
| 95 | 92 | fail_unregister: |
| 96 | 93 | i2c_unregister_device(client); |
| 97 | − module_put(module); | |
| 98 | −fail: | |
| 99 | 94 | return err; |
| 100 | 95 | } |
| 101 | 96 | EXPORT_SYMBOL(drm_i2c_encoder_init); |
| @@ -227,18 +227,9 @@ int drm_fb_helper_debug_leave(struct fb_info *info) · 226 unmodified lines | ||
| 227 | 227 | } |
| 228 | 228 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); |
| 229 | 229 | |
| 230 | −/** | |
| 231 | − * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration | |
| 232 | − * @fb_helper: driver-allocated fbdev helper, can be NULL | |
| 233 | − * | |
| 234 | − * This should be called from driver's drm &drm_driver.lastclose callback | |
| 235 | − * when implementing an fbcon on top of kms using this helper. This ensures that | |
| 236 | − * the user isn't greeted with a black screen when e.g. X dies. | |
| 237 | − * | |
| 238 | − * RETURNS: | |
| 239 | − * Zero if everything went ok, negative error code otherwise. | |
| 240 | − */ | |
| 241 | −int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) | |
| 230 | +static int | |
| 231 | +__drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, | |
| 232 | + bool force) | |
| 242 | 233 | { |
| 243 | 234 | bool do_delayed; |
| 244 | 235 | int ret; |
| @@ -250,7 +241,16 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) · 5 unmodified lines | ||
| 250 | 241 | return 0; |
| 251 | 242 | |
| 252 | 243 | mutex_lock(&fb_helper->lock); |
| 253 | − ret = drm_client_modeset_commit(&fb_helper->client); | |
| 244 | + if (force) { | |
| 245 | + /* | |
| 246 | + * Yes this is the _locked version which expects the master lock | |
| 247 | + * to be held. But for forced restores we're intentionally | |
| 248 | + * racing here, see drm_fb_helper_set_par(). | |
| 249 | + */ | |
| 250 | + ret = drm_client_modeset_commit_locked(&fb_helper->client); | |
| 251 | + } else { | |
| 252 | + ret = drm_client_modeset_commit(&fb_helper->client); | |
| 253 | + } | |
| 254 | 254 | |
| 255 | 255 | do_delayed = fb_helper->delayed_hotplug; |
| 256 | 256 | if (do_delayed) |
| @@ -262,6 +262,22 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) · 5 unmodified lines | ||
| 262 | 262 | |
| 263 | 263 | return ret; |
| 264 | 264 | } |
| 265 | + | |
| 266 | +/** | |
| 267 | + * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration | |
| 268 | + * @fb_helper: driver-allocated fbdev helper, can be NULL | |
| 269 | + * | |
| 270 | + * This should be called from driver's drm &drm_driver.lastclose callback | |
| 271 | + * when implementing an fbcon on top of kms using this helper. This ensures that | |
| 272 | + * the user isn't greeted with a black screen when e.g. X dies. | |
| 273 | + * | |
| 274 | + * RETURNS: | |
| 275 | + * Zero if everything went ok, negative error code otherwise. | |
| 276 | + */ | |
| 277 | +int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) | |
| 278 | +{ | |
| 279 | + return __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, false); | |
| 280 | +} | |
| 265 | 281 | EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked); |
| 266 | 282 | |
| 267 | 283 | #ifdef CONFIG_MAGIC_SYSRQ |
| @@ -1318,6 +1334,7 @@ int drm_fb_helper_set_par(struct fb_info *info) · 1050 unmodified lines | ||
| 1318 | 1334 | { |
| 1319 | 1335 | struct drm_fb_helper *fb_helper = info->par; |
| 1320 | 1336 | struct fb_var_screeninfo *var = &info->var; |
| 1337 | + bool force; | |
| 1321 | 1338 | |
| 1322 | 1339 | if (oops_in_progress) |
| 1323 | 1340 | return -EBUSY; |
| @@ -1327,7 +1344,25 @@ int drm_fb_helper_set_par(struct fb_info *info) · 3 unmodified lines | ||
| 1327 | 1344 | return -EINVAL; |
| 1328 | 1345 | } |
| 1329 | 1346 | |
| 1330 | − drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); | |
| 1347 | + /* | |
| 1348 | + * Normally we want to make sure that a kms master takes precedence over | |
| 1349 | + * fbdev, to avoid fbdev flickering and occasionally stealing the | |
| 1350 | + * display status. But Xorg first sets the vt back to text mode using | |
| 1351 | + * the KDSET IOCTL with KD_TEXT, and only after that drops the master | |
| 1352 | + * status when exiting. | |
| 1353 | + * | |
| 1354 | + * In the past this was caught by drm_fb_helper_lastclose(), but on | |
| 1355 | + * modern systems where logind always keeps a drm fd open to orchestrate | |
| 1356 | + * the vt switching, this doesn't work. | |
| 1357 | + * | |
| 1358 | + * To not break the userspace ABI we have this special case here, which | |
| 1359 | + * is only used for the above case. Everything else uses the normal | |
| 1360 | + * commit function, which ensures that we never steal the display from | |
| 1361 | + * an active drm master. | |
| 1362 | + */ | |
| 1363 | + force = var->activate & FB_ACTIVATE_KD_TEXT; | |
| 1364 | + | |
| 1365 | + __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force); | |
| 1331 | 1366 | |
| 1332 | 1367 | return 0; |
| 1333 | 1368 | } |
| @@ -30,12 +30,6 @@ struct drm_dmi_panel_orientation_data { · 29 unmodified lines | ||
| 30 | 30 | int orientation; |
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | −static const struct drm_dmi_panel_orientation_data acer_s1003 = { | |
| 34 | − .width = 800, | |
| 35 | − .height = 1280, | |
| 36 | − .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, | |
| 37 | −}; | |
| 38 | − | |
| 39 | 33 | static const struct drm_dmi_panel_orientation_data asus_t100ha = { |
| 40 | 34 | .width = 800, |
| 41 | 35 | .height = 1280, |
| @@ -114,13 +108,19 @@ static const struct dmi_system_id orientation_data[] = { · 72 unmodified lines | ||
| 114 | 108 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), |
| 115 | 109 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), |
| 116 | 110 | }, |
| 117 | − .driver_data = (void *)&acer_s1003, | |
| 111 | + .driver_data = (void *)&lcd800x1280_rightside_up, | |
| 118 | 112 | }, { /* Asus T100HA */ |
| 119 | 113 | .matches = { |
| 120 | 114 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 121 | 115 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"), |
| 122 | 116 | }, |
| 123 | 117 | .driver_data = (void *)&asus_t100ha, |
| 118 | + }, { /* Asus T101HA */ | |
| 119 | + .matches = { | |
| 120 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 121 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T101HA"), | |
| 122 | + }, | |
| 123 | + .driver_data = (void *)&lcd800x1280_rightside_up, | |
| 124 | 124 | }, { /* GPD MicroPC (generic strings, also match on bios date) */ |
| 125 | 125 | .matches = { |
| 126 | 126 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), |
| @@ -61,7 +61,7 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, · 60 unmodified lines | ||
| 61 | 61 | struct device *subdrv_dev, void **dma_priv) |
| 62 | 62 | { |
| 63 | 63 | struct exynos_drm_private *priv = drm_dev->dev_private; |
| 64 | − int ret; | |
| 64 | + int ret = 0; | |
| 65 | 65 | |
| 66 | 66 | if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) { |
| 67 | 67 | DRM_DEV_ERROR(subdrv_dev, "Device %s lacks support for IOMMU\n", |
| @@ -92,7 +92,7 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, · 24 unmodified lines | ||
| 92 | 92 | if (ret) |
| 93 | 93 | clear_dma_max_seg_size(subdrv_dev); |
| 94 | 94 | |
| 95 | − return 0; | |
| 95 | + return ret; | |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | /* |
| @@ -1498,7 +1498,6 @@ static int g2d_probe(struct platform_device *pdev) · 1497 unmodified lines | ||
| 1498 | 1498 | |
| 1499 | 1499 | g2d->irq = platform_get_irq(pdev, 0); |
| 1500 | 1500 | if (g2d->irq < 0) { |
| 1501 | − dev_err(dev, "failed to get irq\n"); | |
| 1502 | 1501 | ret = g2d->irq; |
| 1503 | 1502 | goto err_put_clk; |
| 1504 | 1503 | } |
| @@ -269,8 +269,10 @@ static void mic_pre_enable(struct drm_bridge *bridge) · 268 unmodified lines | ||
| 269 | 269 | goto unlock; |
| 270 | 270 | |
| 271 | 271 | ret = pm_runtime_get_sync(mic->dev); |
| 272 | − if (ret < 0) | |
| 272 | + if (ret < 0) { | |
| 273 | + pm_runtime_put_noidle(mic->dev); | |
| 273 | 274 | goto unlock; |
| 275 | + } | |
| 274 | 276 | |
| 275 | 277 | mic_set_path(mic, 1); |
| 276 | 278 | |
| @@ -2579,14 +2579,14 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, · 2578 unmodified lines | ||
| 2579 | 2579 | |
| 2580 | 2580 | static void |
| 2581 | 2581 | tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock, |
| 2582 | − u32 level) | |
| 2582 | + u32 level, enum intel_output_type type) | |
| 2583 | 2583 | { |
| 2584 | 2584 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| 2585 | 2585 | enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); |
| 2586 | 2586 | const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations; |
| 2587 | 2587 | u32 n_entries, val, ln, dpcnt_mask, dpcnt_val; |
| 2588 | 2588 | |
| 2589 | − if (encoder->type == INTEL_OUTPUT_HDMI) { | |
| 2589 | + if (type == INTEL_OUTPUT_HDMI) { | |
| 2590 | 2590 | n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans); |
| 2591 | 2591 | ddi_translations = tgl_dkl_phy_hdmi_ddi_trans; |
| 2592 | 2592 | } else { |
| @@ -2638,7 +2638,7 @@ static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder, · 45 unmodified lines | ||
| 2638 | 2638 | if (intel_phy_is_combo(dev_priv, phy)) |
| 2639 | 2639 | icl_combo_phy_ddi_vswing_sequence(encoder, level, type); |
| 2640 | 2640 | else |
| 2641 | − tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level); | |
| 2641 | + tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type); | |
| 2642 | 2642 | } |
| 2643 | 2643 | |
| 2644 | 2644 | static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels) |
| @@ -2987,7 +2987,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port, · 342 unmodified lines | ||
| 2987 | 2987 | ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port)); |
| 2988 | 2988 | } |
| 2989 | 2989 | |
| 2990 | − ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X1_MODE); | |
| 2990 | + ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); | |
| 2991 | 2991 | ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); |
| 2992 | 2992 | |
| 2993 | 2993 | /* DPPATC */ |
| @@ -3472,7 +3472,9 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, · 478 unmodified lines | ||
| 3472 | 3472 | INTEL_OUTPUT_DP_MST); |
| 3473 | 3473 | enum phy phy = intel_port_to_phy(dev_priv, encoder->port); |
| 3474 | 3474 | |
| 3475 | − intel_dp_set_infoframes(encoder, false, old_crtc_state, old_conn_state); | |
| 3475 | + if (!is_mst) | |
| 3476 | + intel_dp_set_infoframes(encoder, false, | |
| 3477 | + old_crtc_state, old_conn_state); | |
| 3476 | 3478 | |
| 3477 | 3479 | /* |
| 3478 | 3480 | * Power down sink before disabling the port, otherwise we end |
| @@ -397,6 +397,14 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, · 396 unmodified lines | ||
| 397 | 397 | */ |
| 398 | 398 | drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, |
| 399 | 399 | false); |
| 400 | + | |
| 401 | + /* | |
| 402 | + * BSpec 4287: disable DIP after the transcoder is disabled and before | |
| 403 | + * the transcoder clock select is set to none. | |
| 404 | + */ | |
| 405 | + if (last_mst_stream) | |
| 406 | + intel_dp_set_infoframes(&intel_dig_port->base, false, | |
| 407 | + old_crtc_state, NULL); | |
| 400 | 408 | /* |
| 401 | 409 | * From TGL spec: "If multi-stream slave transcoder: Configure |
| 402 | 410 | * Transcoder Clock Select to direct no clock to the transcoder" |
| @@ -646,7 +646,7 @@ static int engine_setup_common(struct intel_engine_cs *engine) · 645 unmodified lines | ||
| 646 | 646 | struct measure_breadcrumb { |
| 647 | 647 | struct i915_request rq; |
| 648 | 648 | struct intel_ring ring; |
| 649 | − u32 cs[1024]; | |
| 649 | + u32 cs[2048]; | |
| 650 | 650 | }; |
| 651 | 651 | |
| 652 | 652 | static int measure_breadcrumb_dw(struct intel_context *ce) |
| @@ -668,6 +668,8 @@ static int measure_breadcrumb_dw(struct intel_context *ce) · 15 unmodified lines | ||
| 668 | 668 | |
| 669 | 669 | frame->ring.vaddr = frame->cs; |
| 670 | 670 | frame->ring.size = sizeof(frame->cs); |
| 671 | + frame->ring.wrap = | |
| 672 | + BITS_PER_TYPE(frame->ring.size) - ilog2(frame->ring.size); | |
| 671 | 673 | frame->ring.effective_size = frame->ring.size; |
| 672 | 674 | intel_ring_update_space(&frame->ring); |
| 673 | 675 | frame->rq.ring = &frame->ring; |
| @@ -1134,6 +1134,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine) · 1133 unmodified lines | ||
| 1134 | 1134 | list_move(&rq->sched.link, pl); |
| 1135 | 1135 | set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); |
| 1136 | 1136 | |
| 1137 | + /* Check in case we rollback so far we wrap [size/2] */ | |
| 1138 | + if (intel_ring_direction(rq->ring, | |
| 1139 | + intel_ring_wrap(rq->ring, | |
| 1140 | + rq->tail), | |
| 1141 | + rq->ring->tail) > 0) | |
| 1142 | + rq->context->lrc.desc |= CTX_DESC_FORCE_RESTORE; | |
| 1143 | + | |
| 1137 | 1144 | active = rq; |
| 1138 | 1145 | } else { |
| 1139 | 1146 | struct intel_engine_cs *owner = rq->context->engine; |
| @@ -1498,8 +1505,9 @@ static u64 execlists_update_context(struct i915_request *rq) · 358 unmodified lines | ||
| 1498 | 1505 | * HW has a tendency to ignore us rewinding the TAIL to the end of |
| 1499 | 1506 | * an earlier request. |
| 1500 | 1507 | */ |
| 1508 | + GEM_BUG_ON(ce->lrc_reg_state[CTX_RING_TAIL] != rq->ring->tail); | |
| 1509 | + prev = rq->ring->tail; | |
| 1501 | 1510 | tail = intel_ring_set_tail(rq->ring, rq->tail); |
| 1502 | − prev = ce->lrc_reg_state[CTX_RING_TAIL]; | |
| 1503 | 1511 | if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0)) |
| 1504 | 1512 | desc |= CTX_DESC_FORCE_RESTORE; |
| 1505 | 1513 | ce->lrc_reg_state[CTX_RING_TAIL] = tail; |
| @@ -1895,7 +1903,8 @@ static void defer_active(struct intel_engine_cs *engine) · 389 unmodified lines | ||
| 1895 | 1903 | |
| 1896 | 1904 | static bool |
| 1897 | 1905 | need_timeslice(const struct intel_engine_cs *engine, |
| 1898 | − const struct i915_request *rq) | |
| 1906 | + const struct i915_request *rq, | |
| 1907 | + const struct rb_node *rb) | |
| 1899 | 1908 | { |
| 1900 | 1909 | int hint; |
| 1901 | 1910 | |
| @@ -1903,9 +1912,28 @@ need_timeslice(const struct intel_engine_cs *engine, · 1 unmodified line | ||
| 1903 | 1912 | return false; |
| 1904 | 1913 | |
| 1905 | 1914 | hint = engine->execlists.queue_priority_hint; |
| 1915 | + | |
| 1916 | + if (rb) { | |
| 1917 | + const struct virtual_engine *ve = | |
| 1918 | + rb_entry(rb, typeof(*ve), nodes[engine->id].rb); | |
| 1919 | + const struct intel_engine_cs *inflight = | |
| 1920 | + intel_context_inflight(&ve->context); | |
| 1921 | + | |
| 1922 | + if (!inflight || inflight == engine) { | |
| 1923 | + struct i915_request *next; | |
| 1924 | + | |
| 1925 | + rcu_read_lock(); | |
| 1926 | + next = READ_ONCE(ve->request); | |
| 1927 | + if (next) | |
| 1928 | + hint = max(hint, rq_prio(next)); | |
| 1929 | + rcu_read_unlock(); | |
| 1930 | + } | |
| 1931 | + } | |
| 1932 | + | |
| 1906 | 1933 | if (!list_is_last(&rq->sched.link, &engine->active.requests)) |
| 1907 | 1934 | hint = max(hint, rq_prio(list_next_entry(rq, sched.link))); |
| 1908 | 1935 | |
| 1936 | + GEM_BUG_ON(hint >= I915_PRIORITY_UNPREEMPTABLE); | |
| 1909 | 1937 | return hint >= effective_prio(rq); |
| 1910 | 1938 | } |
| 1911 | 1939 | |
| @@ -1977,10 +2005,9 @@ static void set_timeslice(struct intel_engine_cs *engine) · 65 unmodified lines | ||
| 1977 | 2005 | set_timer_ms(&engine->execlists.timer, duration); |
| 1978 | 2006 | } |
| 1979 | 2007 | |
| 1980 | −static void start_timeslice(struct intel_engine_cs *engine) | |
| 2008 | +static void start_timeslice(struct intel_engine_cs *engine, int prio) | |
| 1981 | 2009 | { |
| 1982 | 2010 | struct intel_engine_execlists *execlists = &engine->execlists; |
| 1983 | − const int prio = queue_prio(execlists); | |
| 1984 | 2011 | unsigned long duration; |
| 1985 | 2012 | |
| 1986 | 2013 | if (!intel_engine_has_timeslices(engine)) |
| @@ -2140,7 +2167,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 153 unmodified lines | ||
| 2140 | 2167 | __unwind_incomplete_requests(engine); |
| 2141 | 2168 | |
| 2142 | 2169 | last = NULL; |
| 2143 | − } else if (need_timeslice(engine, last) && | |
| 2170 | + } else if (need_timeslice(engine, last, rb) && | |
| 2144 | 2171 | timeslice_expired(execlists, last)) { |
| 2145 | 2172 | if (i915_request_completed(last)) { |
| 2146 | 2173 | tasklet_hi_schedule(&execlists->tasklet); |
| @@ -2188,7 +2215,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 41 unmodified lines | ||
| 2188 | 2215 | * Even if ELSP[1] is occupied and not worthy |
| 2189 | 2216 | * of timeslices, our queue might be. |
| 2190 | 2217 | */ |
| 2191 | − start_timeslice(engine); | |
| 2218 | + start_timeslice(engine, queue_prio(execlists)); | |
| 2192 | 2219 | return; |
| 2193 | 2220 | } |
| 2194 | 2221 | } |
| @@ -2223,7 +2250,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 28 unmodified lines | ||
| 2223 | 2250 | |
| 2224 | 2251 | if (last && !can_merge_rq(last, rq)) { |
| 2225 | 2252 | spin_unlock(&ve->base.active.lock); |
| 2226 | − start_timeslice(engine); | |
| 2253 | + start_timeslice(engine, rq_prio(rq)); | |
| 2227 | 2254 | return; /* leave this for another sibling */ |
| 2228 | 2255 | } |
| 2229 | 2256 | |
| @@ -4739,6 +4766,14 @@ static int gen12_emit_flush(struct i915_request *request, u32 mode) · 2509 unmodified lines | ||
| 4739 | 4766 | return 0; |
| 4740 | 4767 | } |
| 4741 | 4768 | |
| 4769 | +static void assert_request_valid(struct i915_request *rq) | |
| 4770 | +{ | |
| 4771 | + struct intel_ring *ring __maybe_unused = rq->ring; | |
| 4772 | + | |
| 4773 | + /* Can we unwind this request without appearing to go forwards? */ | |
| 4774 | + GEM_BUG_ON(intel_ring_direction(ring, rq->wa_tail, rq->head) <= 0); | |
| 4775 | +} | |
| 4776 | + | |
| 4742 | 4777 | /* |
| 4743 | 4778 | * Reserve space for 2 NOOPs at the end of each request to be |
| 4744 | 4779 | * used as a workaround for not being allowed to do lite |
| @@ -4751,6 +4786,9 @@ static u32 *gen8_emit_wa_tail(struct i915_request *request, u32 *cs) · 6 unmodified lines | ||
| 4751 | 4786 | *cs++ = MI_NOOP; |
| 4752 | 4787 | request->wa_tail = intel_ring_offset(request, cs); |
| 4753 | 4788 | |
| 4789 | + /* Check that entire request is less than half the ring */ | |
| 4790 | + assert_request_valid(request); | |
| 4791 | + | |
| 4754 | 4792 | return cs; |
| 4755 | 4793 | } |
| 4756 | 4794 | |
| @@ -315,3 +315,7 @@ int intel_ring_cacheline_align(struct i915_request *rq) · 314 unmodified lines | ||
| 315 | 315 | GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1)); |
| 316 | 316 | return 0; |
| 317 | 317 | } |
| 318 | + | |
| 319 | +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) | |
| 320 | +#include "selftest_ring.c" | |
| 321 | +#endif | |
| @@ -178,6 +178,12 @@ wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 set) · 177 unmodified lines | ||
| 178 | 178 | wa_write_masked_or(wal, reg, set, set); |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | +static void | |
| 182 | +wa_write_clr(struct i915_wa_list *wal, i915_reg_t reg, u32 clr) | |
| 183 | +{ | |
| 184 | + wa_write_masked_or(wal, reg, clr, 0); | |
| 185 | +} | |
| 186 | + | |
| 181 | 187 | static void |
| 182 | 188 | wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val) |
| 183 | 189 | { |
| @@ -686,6 +692,227 @@ int intel_engine_emit_ctx_wa(struct i915_request *rq) · 502 unmodified lines | ||
| 686 | 692 | return 0; |
| 687 | 693 | } |
| 688 | 694 | |
| 695 | +static void | |
| 696 | +gen4_gt_workarounds_init(struct drm_i915_private *i915, | |
| 697 | + struct i915_wa_list *wal) | |
| 698 | +{ | |
| 699 | + /* WaDisable_RenderCache_OperationalFlush:gen4,ilk */ | |
| 700 | + wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE); | |
| 701 | +} | |
| 702 | + | |
| 703 | +static void | |
| 704 | +g4x_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) | |
| 705 | +{ | |
| 706 | + gen4_gt_workarounds_init(i915, wal); | |
| 707 | + | |
| 708 | + /* WaDisableRenderCachePipelinedFlush:g4x,ilk */ | |
| 709 | + wa_masked_en(wal, CACHE_MODE_0, CM0_PIPELINED_RENDER_FLUSH_DISABLE); | |
| 710 | +} | |
| 711 | + | |
| 712 | +static void | |
| 713 | +ilk_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) | |
| 714 | +{ | |
| 715 | + g4x_gt_workarounds_init(i915, wal); | |
| 716 | + | |
| 717 | + wa_masked_en(wal, _3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED); | |
| 718 | +} | |
| 719 | + | |
| 720 | +static void | |
| 721 | +snb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) | |
| 722 | +{ | |
| 723 | + /* WaDisableHiZPlanesWhenMSAAEnabled:snb */ | |
| 724 | + wa_masked_en(wal, | |
| 725 | + _3D_CHICKEN, | |
| 726 | + _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB); | |
| 727 | + | |
| 728 | + /* WaDisable_RenderCache_OperationalFlush:snb */ | |
| 729 | + wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE); | |
| 730 | + | |
| 731 | + /* | |
| 732 | + * BSpec recommends 8x4 when MSAA is used, | |
| 733 | + * however in practice 16x4 seems fastest. | |
| 734 | + * | |
| 735 | + * Note that PS/WM thread counts depend on the WIZ hashing | |
| 736 | + * disable bit, which we don't touch here, but it's good | |
| 737 | + * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 738 | + */ | |
| 739 | + wa_add(wal, | |
| 740 | + GEN6_GT_MODE, 0, | |
| 741 | + _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4), | |
| 742 | + GEN6_WIZ_HASHING_16x4); | |
| 743 | + | |
| 744 | + wa_masked_dis(wal, CACHE_MODE_0, CM0_STC_EVICT_DISABLE_LRA_SNB); | |
| 745 | + | |
| 746 | + wa_masked_en(wal, | |
| 747 | + _3D_CHICKEN3, | |
| 748 | + /* WaStripsFansDisableFastClipPerformanceFix:snb */ | |
| 749 | + _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL | | |
| 750 | + /* | |
| 751 | + * Bspec says: | |
| 752 | + * "This bit must be set if 3DSTATE_CLIP clip mode is set | |
| 753 | + * to normal and 3DSTATE_SF number of SF output attributes | |
| 754 | + * is more than 16." | |
| 755 | + */ | |
| 756 | + _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH); | |
| 757 | +} | |
| 758 | + | |
| 759 | +static void | |
| 760 | +ivb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) | |
| 761 | +{ | |
| 762 | + /* WaDisableEarlyCull:ivb */ | |
| 763 | + wa_masked_en(wal, _3D_CHICKEN3, _3D_CHICKEN_SF_DISABLE_OBJEND_CULL); | |
| 764 | + | |
| 765 | + /* WaDisablePSDDualDispatchEnable:ivb */ | |
| 766 | + if (IS_IVB_GT1(i915)) | |
| 767 | + wa_masked_en(wal, | |
| 768 | + GEN7_HALF_SLICE_CHICKEN1, | |
| 769 | + GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE); | |
| 770 | + | |
| 771 | + /* WaDisable_RenderCache_OperationalFlush:ivb */ | |
| 772 | + wa_masked_dis(wal, CACHE_MODE_0_GEN7, RC_OP_FLUSH_ENABLE); | |
| 773 | + | |
| 774 | + /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */ | |
| 775 | + wa_masked_dis(wal, | |
| 776 | + GEN7_COMMON_SLICE_CHICKEN1, | |
| 777 | + GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | |
| 778 | + | |
| 779 | + /* WaApplyL3ControlAndL3ChickenMode:ivb */ | |
| 780 | + wa_write(wal, GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL); | |
| 781 | + wa_write(wal, GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE); | |
| 782 | + | |
| 783 | + /* WaForceL3Serialization:ivb */ | |
| 784 | + wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE); | |
| 785 | + | |
| 786 | + /* | |
| 787 | + * WaVSThreadDispatchOverride:ivb,vlv | |
| 788 | + * | |
| 789 | + * This actually overrides the dispatch | |
| 790 | + * mode for all thread types. | |
| 791 | + */ | |
| 792 | + wa_write_masked_or(wal, GEN7_FF_THREAD_MODE, | |
| 793 | + GEN7_FF_SCHED_MASK, | |
| 794 | + GEN7_FF_TS_SCHED_HW | | |
| 795 | + GEN7_FF_VS_SCHED_HW | | |
| 796 | + GEN7_FF_DS_SCHED_HW); | |
| 797 | + | |
| 798 | + if (0) { /* causes HiZ corruption on ivb:gt1 */ | |
| 799 | + /* enable HiZ Raw Stall Optimization */ | |
| 800 | + wa_masked_dis(wal, CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); | |
| 801 | + } | |
| 802 | + | |
| 803 | + /* WaDisable4x2SubspanOptimization:ivb */ | |
| 804 | + wa_masked_en(wal, CACHE_MODE_1, PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); | |
| 805 | + | |
| 806 | + /* | |
| 807 | + * BSpec recommends 8x4 when MSAA is used, | |
| 808 | + * however in practice 16x4 seems fastest. | |
| 809 | + * | |
| 810 | + * Note that PS/WM thread counts depend on the WIZ hashing | |
| 811 | + * disable bit, which we don't touch here, but it's good | |
| 812 | + * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 813 | + */ | |
| 814 | + wa_add(wal, GEN7_GT_MODE, 0, | |
| 815 | + _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4), | |
| 816 | + GEN6_WIZ_HASHING_16x4); | |
| 817 | +} | |
| 818 | + | |
| 819 | +static void | |
| 820 | +vlv_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) | |
| 821 | +{ | |
| 822 | + /* WaDisableEarlyCull:vlv */ | |
| 823 | + wa_masked_en(wal, _3D_CHICKEN3, _3D_CHICKEN_SF_DISABLE_OBJEND_CULL); | |
| 824 | + | |
| 825 | + /* WaPsdDispatchEnable:vlv */ | |
| 826 | + /* WaDisablePSDDualDispatchEnable:vlv */ | |
| 827 | + wa_masked_en(wal, | |
| 828 | + GEN7_HALF_SLICE_CHICKEN1, | |
| 829 | + GEN7_MAX_PS_THREAD_DEP | | |
| 830 | + GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE); | |
| 831 | + | |
| 832 | + /* WaDisable_RenderCache_OperationalFlush:vlv */ | |
| 833 | + wa_masked_dis(wal, CACHE_MODE_0_GEN7, RC_OP_FLUSH_ENABLE); | |
| 834 | + | |
| 835 | + /* WaForceL3Serialization:vlv */ | |
| 836 | + wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE); | |
| 837 | + | |
| 838 | + /* | |
| 839 | + * WaVSThreadDispatchOverride:ivb,vlv | |
| 840 | + * | |
| 841 | + * This actually overrides the dispatch | |
| 842 | + * mode for all thread types. | |
| 843 | + */ | |
| 844 | + wa_write_masked_or(wal, | |
| 845 | + GEN7_FF_THREAD_MODE, | |
| 846 | + GEN7_FF_SCHED_MASK, | |
| 847 | + GEN7_FF_TS_SCHED_HW | | |
| 848 | + GEN7_FF_VS_SCHED_HW | | |
| 849 | + GEN7_FF_DS_SCHED_HW); | |
| 850 | + | |
| 851 | + /* | |
| 852 | + * BSpec says this must be set, even though | |
| 853 | + * WaDisable4x2SubspanOptimization isn't listed for VLV. | |
| 854 | + */ | |
| 855 | + wa_masked_en(wal, CACHE_MODE_1, PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); | |
| 856 | + | |
| 857 | + /* | |
| 858 | + * BSpec recommends 8x4 when MSAA is used, | |
| 859 | + * however in practice 16x4 seems fastest. | |
| 860 | + * | |
| 861 | + * Note that PS/WM thread counts depend on the WIZ hashing | |
| 862 | + * disable bit, which we don't touch here, but it's good | |
| 863 | + * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 864 | + */ | |
| 865 | + wa_add(wal, GEN7_GT_MODE, 0, | |
| 866 | + _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4), | |
| 867 | + GEN6_WIZ_HASHING_16x4); | |
| 868 | + | |
| 869 | + /* | |
| 870 | + * WaIncreaseL3CreditsForVLVB0:vlv | |
| 871 | + * This is the hardware default actually. | |
| 872 | + */ | |
| 873 | + wa_write(wal, GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE); | |
| 874 | +} | |
| 875 | + | |
| 876 | +static void | |
| 877 | +hsw_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) | |
| 878 | +{ | |
| 879 | + /* L3 caching of data atomics doesn't work -- disable it. */ | |
| 880 | + wa_write(wal, HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); | |
| 881 | + | |
| 882 | + wa_add(wal, | |
| 883 | + HSW_ROW_CHICKEN3, 0, | |
| 884 | + _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE), | |
| 885 | + 0 /* XXX does this reg exist? */); | |
| 886 | + | |
| 887 | + /* WaVSRefCountFullforceMissDisable:hsw */ | |
| 888 | + wa_write_clr(wal, GEN7_FF_THREAD_MODE, GEN7_FF_VS_REF_CNT_FFME); | |
| 889 | + | |
| 890 | + wa_masked_dis(wal, | |
| 891 | + CACHE_MODE_0_GEN7, | |
| 892 | + /* WaDisable_RenderCache_OperationalFlush:hsw */ | |
| 893 | + RC_OP_FLUSH_ENABLE | | |
| 894 | + /* enable HiZ Raw Stall Optimization */ | |
| 895 | + HIZ_RAW_STALL_OPT_DISABLE); | |
| 896 | + | |
| 897 | + /* WaDisable4x2SubspanOptimization:hsw */ | |
| 898 | + wa_masked_en(wal, CACHE_MODE_1, PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); | |
| 899 | + | |
| 900 | + /* | |
| 901 | + * BSpec recommends 8x4 when MSAA is used, | |
| 902 | + * however in practice 16x4 seems fastest. | |
| 903 | + * | |
| 904 | + * Note that PS/WM thread counts depend on the WIZ hashing | |
| 905 | + * disable bit, which we don't touch here, but it's good | |
| 906 | + * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 907 | + */ | |
| 908 | + wa_add(wal, GEN7_GT_MODE, 0, | |
| 909 | + _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4), | |
| 910 | + GEN6_WIZ_HASHING_16x4); | |
| 911 | + | |
| 912 | + /* WaSampleCChickenBitEnable:hsw */ | |
| 913 | + wa_masked_en(wal, HALF_SLICE_CHICKEN3, HSW_SAMPLE_C_PERFORMANCE); | |
| 914 | +} | |
| 915 | + | |
| 689 | 916 | static void |
| 690 | 917 | gen9_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) |
| 691 | 918 | { |
| @@ -963,6 +1190,20 @@ gt_init_workarounds(struct drm_i915_private *i915, struct i915_wa_list *wal) · 271 unmodified lines | ||
| 963 | 1190 | bxt_gt_workarounds_init(i915, wal); |
| 964 | 1191 | else if (IS_SKYLAKE(i915)) |
| 965 | 1192 | skl_gt_workarounds_init(i915, wal); |
| 1193 | + else if (IS_HASWELL(i915)) | |
| 1194 | + hsw_gt_workarounds_init(i915, wal); | |
| 1195 | + else if (IS_VALLEYVIEW(i915)) | |
| 1196 | + vlv_gt_workarounds_init(i915, wal); | |
| 1197 | + else if (IS_IVYBRIDGE(i915)) | |
| 1198 | + ivb_gt_workarounds_init(i915, wal); | |
| 1199 | + else if (IS_GEN(i915, 6)) | |
| 1200 | + snb_gt_workarounds_init(i915, wal); | |
| 1201 | + else if (IS_GEN(i915, 5)) | |
| 1202 | + ilk_gt_workarounds_init(i915, wal); | |
| 1203 | + else if (IS_G4X(i915)) | |
| 1204 | + g4x_gt_workarounds_init(i915, wal); | |
| 1205 | + else if (IS_GEN(i915, 4)) | |
| 1206 | + gen4_gt_workarounds_init(i915, wal); | |
| 966 | 1207 | else if (INTEL_GEN(i915) <= 8) |
| 967 | 1208 | return; |
| 968 | 1209 | else |
| @@ -310,22 +310,20 @@ static bool wait_until_running(struct hang *h, struct i915_request *rq) · 309 unmodified lines | ||
| 310 | 310 | 1000)); |
| 311 | 311 | } |
| 312 | 312 | |
| 313 | −static void engine_heartbeat_disable(struct intel_engine_cs *engine, | |
| 314 | − unsigned long *saved) | |
| 313 | +static void engine_heartbeat_disable(struct intel_engine_cs *engine) | |
| 315 | 314 | { |
| 316 | − *saved = engine->props.heartbeat_interval_ms; | |
| 317 | 315 | engine->props.heartbeat_interval_ms = 0; |
| 318 | 316 | |
| 319 | 317 | intel_engine_pm_get(engine); |
| 320 | 318 | intel_engine_park_heartbeat(engine); |
| 321 | 319 | } |
| 322 | 320 | |
| 323 | −static void engine_heartbeat_enable(struct intel_engine_cs *engine, | |
| 324 | − unsigned long saved) | |
| 321 | +static void engine_heartbeat_enable(struct intel_engine_cs *engine) | |
| 325 | 322 | { |
| 326 | 323 | intel_engine_pm_put(engine); |
| 327 | 324 | |
| 328 | − engine->props.heartbeat_interval_ms = saved; | |
| 325 | + engine->props.heartbeat_interval_ms = | |
| 326 | + engine->defaults.heartbeat_interval_ms; | |
| 329 | 327 | } |
| 330 | 328 | |
| 331 | 329 | static int igt_hang_sanitycheck(void *arg) |
| @@ -473,7 +471,6 @@ static int igt_reset_nop_engine(void *arg) · 141 unmodified lines | ||
| 473 | 471 | for_each_engine(engine, gt, id) { |
| 474 | 472 | unsigned int reset_count, reset_engine_count, count; |
| 475 | 473 | struct intel_context *ce; |
| 476 | − unsigned long heartbeat; | |
| 477 | 474 | IGT_TIMEOUT(end_time); |
| 478 | 475 | int err; |
| 479 | 476 | |
| @@ -485,7 +482,7 @@ static int igt_reset_nop_engine(void *arg) · 5 unmodified lines | ||
| 485 | 482 | reset_engine_count = i915_reset_engine_count(global, engine); |
| 486 | 483 | count = 0; |
| 487 | 484 | |
| 488 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 485 | + engine_heartbeat_disable(engine); | |
| 489 | 486 | set_bit(I915_RESET_ENGINE + id, >->reset.flags); |
| 490 | 487 | do { |
| 491 | 488 | int i; |
| @@ -529,7 +526,7 @@ static int igt_reset_nop_engine(void *arg) · 37 unmodified lines | ||
| 529 | 526 | } |
| 530 | 527 | } while (time_before(jiffies, end_time)); |
| 531 | 528 | clear_bit(I915_RESET_ENGINE + id, >->reset.flags); |
| 532 | − engine_heartbeat_enable(engine, heartbeat); | |
| 529 | + engine_heartbeat_enable(engine); | |
| 533 | 530 | |
| 534 | 531 | pr_info("%s(%s): %d resets\n", __func__, engine->name, count); |
| 535 | 532 | |
| @@ -564,7 +561,6 @@ static int __igt_reset_engine(struct intel_gt *gt, bool active) · 28 unmodified lines | ||
| 564 | 561 | |
| 565 | 562 | for_each_engine(engine, gt, id) { |
| 566 | 563 | unsigned int reset_count, reset_engine_count; |
| 567 | − unsigned long heartbeat; | |
| 568 | 564 | IGT_TIMEOUT(end_time); |
| 569 | 565 | |
| 570 | 566 | if (active && !intel_engine_can_store_dword(engine)) |
| @@ -580,7 +576,7 @@ static int __igt_reset_engine(struct intel_gt *gt, bool active) · 9 unmodified lines | ||
| 580 | 576 | reset_count = i915_reset_count(global); |
| 581 | 577 | reset_engine_count = i915_reset_engine_count(global, engine); |
| 582 | 578 | |
| 583 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 579 | + engine_heartbeat_disable(engine); | |
| 584 | 580 | set_bit(I915_RESET_ENGINE + id, >->reset.flags); |
| 585 | 581 | do { |
| 586 | 582 | if (active) { |
| @@ -632,7 +628,7 @@ static int __igt_reset_engine(struct intel_gt *gt, bool active) · 45 unmodified lines | ||
| 632 | 628 | } |
| 633 | 629 | } while (time_before(jiffies, end_time)); |
| 634 | 630 | clear_bit(I915_RESET_ENGINE + id, >->reset.flags); |
| 635 | − engine_heartbeat_enable(engine, heartbeat); | |
| 631 | + engine_heartbeat_enable(engine); | |
| 636 | 632 | |
| 637 | 633 | if (err) |
| 638 | 634 | break; |
| @@ -789,7 +785,6 @@ static int __igt_reset_engines(struct intel_gt *gt, · 150 unmodified lines | ||
| 789 | 785 | struct active_engine threads[I915_NUM_ENGINES] = {}; |
| 790 | 786 | unsigned long device = i915_reset_count(global); |
| 791 | 787 | unsigned long count = 0, reported; |
| 792 | − unsigned long heartbeat; | |
| 793 | 788 | IGT_TIMEOUT(end_time); |
| 794 | 789 | |
| 795 | 790 | if (flags & TEST_ACTIVE && |
| @@ -832,7 +827,7 @@ static int __igt_reset_engines(struct intel_gt *gt, · 36 unmodified lines | ||
| 832 | 827 | |
| 833 | 828 | yield(); /* start all threads before we begin */ |
| 834 | 829 | |
| 835 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 830 | + engine_heartbeat_disable(engine); | |
| 836 | 831 | set_bit(I915_RESET_ENGINE + id, >->reset.flags); |
| 837 | 832 | do { |
| 838 | 833 | struct i915_request *rq = NULL; |
| @@ -906,7 +901,7 @@ static int __igt_reset_engines(struct intel_gt *gt, · 67 unmodified lines | ||
| 906 | 901 | } |
| 907 | 902 | } while (time_before(jiffies, end_time)); |
| 908 | 903 | clear_bit(I915_RESET_ENGINE + id, >->reset.flags); |
| 909 | − engine_heartbeat_enable(engine, heartbeat); | |
| 904 | + engine_heartbeat_enable(engine); | |
| 910 | 905 | |
| 911 | 906 | pr_info("i915_reset_engine(%s:%s): %lu resets\n", |
| 912 | 907 | engine->name, test_name, count); |
| @@ -51,22 +51,20 @@ static struct i915_vma *create_scratch(struct intel_gt *gt) · 50 unmodified lines | ||
| 51 | 51 | return vma; |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | −static void engine_heartbeat_disable(struct intel_engine_cs *engine, | |
| 55 | − unsigned long *saved) | |
| 54 | +static void engine_heartbeat_disable(struct intel_engine_cs *engine) | |
| 56 | 55 | { |
| 57 | − *saved = engine->props.heartbeat_interval_ms; | |
| 58 | 56 | engine->props.heartbeat_interval_ms = 0; |
| 59 | 57 | |
| 60 | 58 | intel_engine_pm_get(engine); |
| 61 | 59 | intel_engine_park_heartbeat(engine); |
| 62 | 60 | } |
| 63 | 61 | |
| 64 | −static void engine_heartbeat_enable(struct intel_engine_cs *engine, | |
| 65 | − unsigned long saved) | |
| 62 | +static void engine_heartbeat_enable(struct intel_engine_cs *engine) | |
| 66 | 63 | { |
| 67 | 64 | intel_engine_pm_put(engine); |
| 68 | 65 | |
| 69 | − engine->props.heartbeat_interval_ms = saved; | |
| 66 | + engine->props.heartbeat_interval_ms = | |
| 67 | + engine->defaults.heartbeat_interval_ms; | |
| 70 | 68 | } |
| 71 | 69 | |
| 72 | 70 | static bool is_active(struct i915_request *rq) |
| @@ -224,7 +222,6 @@ static int live_unlite_restore(struct intel_gt *gt, int prio) · 151 unmodified lines | ||
| 224 | 222 | struct intel_context *ce[2] = {}; |
| 225 | 223 | struct i915_request *rq[2]; |
| 226 | 224 | struct igt_live_test t; |
| 227 | − unsigned long saved; | |
| 228 | 225 | int n; |
| 229 | 226 | |
| 230 | 227 | if (prio && !intel_engine_has_preemption(engine)) |
| @@ -237,7 +234,7 @@ static int live_unlite_restore(struct intel_gt *gt, int prio) · 6 unmodified lines | ||
| 237 | 234 | err = -EIO; |
| 238 | 235 | break; |
| 239 | 236 | } |
| 240 | − engine_heartbeat_disable(engine, &saved); | |
| 237 | + engine_heartbeat_disable(engine); | |
| 241 | 238 | |
| 242 | 239 | for (n = 0; n < ARRAY_SIZE(ce); n++) { |
| 243 | 240 | struct intel_context *tmp; |
| @@ -345,7 +342,7 @@ err_ce: · 101 unmodified lines | ||
| 345 | 342 | intel_context_put(ce[n]); |
| 346 | 343 | } |
| 347 | 344 | |
| 348 | − engine_heartbeat_enable(engine, saved); | |
| 345 | + engine_heartbeat_enable(engine); | |
| 349 | 346 | if (igt_live_test_end(&t)) |
| 350 | 347 | err = -EIO; |
| 351 | 348 | if (err) |
| @@ -466,7 +463,6 @@ static int live_hold_reset(void *arg) · 114 unmodified lines | ||
| 466 | 463 | |
| 467 | 464 | for_each_engine(engine, gt, id) { |
| 468 | 465 | struct intel_context *ce; |
| 469 | − unsigned long heartbeat; | |
| 470 | 466 | struct i915_request *rq; |
| 471 | 467 | |
| 472 | 468 | ce = intel_context_create(engine); |
| @@ -475,7 +471,7 @@ static int live_hold_reset(void *arg) · 2 unmodified lines | ||
| 475 | 471 | break; |
| 476 | 472 | } |
| 477 | 473 | |
| 478 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 474 | + engine_heartbeat_disable(engine); | |
| 479 | 475 | |
| 480 | 476 | rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK); |
| 481 | 477 | if (IS_ERR(rq)) { |
| @@ -535,7 +531,7 @@ static int live_hold_reset(void *arg) · 53 unmodified lines | ||
| 535 | 531 | i915_request_put(rq); |
| 536 | 532 | |
| 537 | 533 | out: |
| 538 | − engine_heartbeat_enable(engine, heartbeat); | |
| 534 | + engine_heartbeat_enable(engine); | |
| 539 | 535 | intel_context_put(ce); |
| 540 | 536 | if (err) |
| 541 | 537 | break; |
| @@ -580,10 +576,9 @@ static int live_error_interrupt(void *arg) · 38 unmodified lines | ||
| 580 | 576 | |
| 581 | 577 | for_each_engine(engine, gt, id) { |
| 582 | 578 | const struct error_phase *p; |
| 583 | − unsigned long heartbeat; | |
| 584 | 579 | int err = 0; |
| 585 | 580 | |
| 586 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 581 | + engine_heartbeat_disable(engine); | |
| 587 | 582 | |
| 588 | 583 | for (p = phases; p->error[0] != GOOD; p++) { |
| 589 | 584 | struct i915_request *client[ARRAY_SIZE(phases->error)]; |
| @@ -682,7 +677,7 @@ out: · 92 unmodified lines | ||
| 682 | 677 | } |
| 683 | 678 | } |
| 684 | 679 | |
| 685 | − engine_heartbeat_enable(engine, heartbeat); | |
| 680 | + engine_heartbeat_enable(engine); | |
| 686 | 681 | if (err) { |
| 687 | 682 | intel_gt_set_wedged(gt); |
| 688 | 683 | return err; |
| @@ -828,7 +823,7 @@ slice_semaphore_queue(struct intel_engine_cs *outer, · 139 unmodified lines | ||
| 828 | 823 | } |
| 829 | 824 | } |
| 830 | 825 | |
| 831 | − err = release_queue(outer, vma, n, INT_MAX); | |
| 826 | + err = release_queue(outer, vma, n, I915_PRIORITY_BARRIER); | |
| 832 | 827 | if (err) |
| 833 | 828 | goto out; |
| 834 | 829 | |
| @@ -895,16 +890,14 @@ static int live_timeslice_preempt(void *arg) · 60 unmodified lines | ||
| 895 | 890 | enum intel_engine_id id; |
| 896 | 891 | |
| 897 | 892 | for_each_engine(engine, gt, id) { |
| 898 | − unsigned long saved; | |
| 899 | − | |
| 900 | 893 | if (!intel_engine_has_preemption(engine)) |
| 901 | 894 | continue; |
| 902 | 895 | |
| 903 | 896 | memset(vaddr, 0, PAGE_SIZE); |
| 904 | 897 | |
| 905 | − engine_heartbeat_disable(engine, &saved); | |
| 898 | + engine_heartbeat_disable(engine); | |
| 906 | 899 | err = slice_semaphore_queue(engine, vma, count); |
| 907 | − engine_heartbeat_enable(engine, saved); | |
| 900 | + engine_heartbeat_enable(engine); | |
| 908 | 901 | if (err) |
| 909 | 902 | goto err_pin; |
| 910 | 903 | |
| @@ -1009,7 +1002,6 @@ static int live_timeslice_rewind(void *arg) · 98 unmodified lines | ||
| 1009 | 1002 | enum { X = 1, Z, Y }; |
| 1010 | 1003 | struct i915_request *rq[3] = {}; |
| 1011 | 1004 | struct intel_context *ce; |
| 1012 | − unsigned long heartbeat; | |
| 1013 | 1005 | unsigned long timeslice; |
| 1014 | 1006 | int i, err = 0; |
| 1015 | 1007 | u32 *slot; |
| @@ -1028,7 +1020,7 @@ static int live_timeslice_rewind(void *arg) · 12 unmodified lines | ||
| 1028 | 1020 | * Expect execution/evaluation order XZY |
| 1029 | 1021 | */ |
| 1030 | 1022 | |
| 1031 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 1023 | + engine_heartbeat_disable(engine); | |
| 1032 | 1024 | timeslice = xchg(&engine->props.timeslice_duration_ms, 1); |
| 1033 | 1025 | |
| 1034 | 1026 | slot = memset32(engine->status_page.addr + 1000, 0, 4); |
| @@ -1122,7 +1114,7 @@ err: · 87 unmodified lines | ||
| 1122 | 1114 | wmb(); |
| 1123 | 1115 | |
| 1124 | 1116 | engine->props.timeslice_duration_ms = timeslice; |
| 1125 | − engine_heartbeat_enable(engine, heartbeat); | |
| 1117 | + engine_heartbeat_enable(engine); | |
| 1126 | 1118 | for (i = 0; i < 3; i++) |
| 1127 | 1119 | i915_request_put(rq[i]); |
| 1128 | 1120 | if (igt_flush_test(gt->i915)) |
| @@ -1202,12 +1194,11 @@ static int live_timeslice_queue(void *arg) · 73 unmodified lines | ||
| 1202 | 1194 | .priority = I915_USER_PRIORITY(I915_PRIORITY_MAX), |
| 1203 | 1195 | }; |
| 1204 | 1196 | struct i915_request *rq, *nop; |
| 1205 | − unsigned long saved; | |
| 1206 | 1197 | |
| 1207 | 1198 | if (!intel_engine_has_preemption(engine)) |
| 1208 | 1199 | continue; |
| 1209 | 1200 | |
| 1210 | − engine_heartbeat_disable(engine, &saved); | |
| 1201 | + engine_heartbeat_disable(engine); | |
| 1211 | 1202 | memset(vaddr, 0, PAGE_SIZE); |
| 1212 | 1203 | |
| 1213 | 1204 | /* ELSP[0]: semaphore wait */ |
| @@ -1284,7 +1275,7 @@ static int live_timeslice_queue(void *arg) · 70 unmodified lines | ||
| 1284 | 1275 | err_rq: |
| 1285 | 1276 | i915_request_put(rq); |
| 1286 | 1277 | err_heartbeat: |
| 1287 | − engine_heartbeat_enable(engine, saved); | |
| 1278 | + engine_heartbeat_enable(engine); | |
| 1288 | 1279 | if (err) |
| 1289 | 1280 | break; |
| 1290 | 1281 | } |
| @@ -1298,6 +1289,121 @@ err_obj: · 7 unmodified lines | ||
| 1298 | 1289 | return err; |
| 1299 | 1290 | } |
| 1300 | 1291 | |
| 1292 | +static int live_timeslice_nopreempt(void *arg) | |
| 1293 | +{ | |
| 1294 | + struct intel_gt *gt = arg; | |
| 1295 | + struct intel_engine_cs *engine; | |
| 1296 | + enum intel_engine_id id; | |
| 1297 | + struct igt_spinner spin; | |
| 1298 | + int err = 0; | |
| 1299 | + | |
| 1300 | + /* | |
| 1301 | + * We should not timeslice into a request that is marked with | |
| 1302 | + * I915_REQUEST_NOPREEMPT. | |
| 1303 | + */ | |
| 1304 | + if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) | |
| 1305 | + return 0; | |
| 1306 | + | |
| 1307 | + if (igt_spinner_init(&spin, gt)) | |
| 1308 | + return -ENOMEM; | |
| 1309 | + | |
| 1310 | + for_each_engine(engine, gt, id) { | |
| 1311 | + struct intel_context *ce; | |
| 1312 | + struct i915_request *rq; | |
| 1313 | + unsigned long timeslice; | |
| 1314 | + | |
| 1315 | + if (!intel_engine_has_preemption(engine)) | |
| 1316 | + continue; | |
| 1317 | + | |
| 1318 | + ce = intel_context_create(engine); | |
| 1319 | + if (IS_ERR(ce)) { | |
| 1320 | + err = PTR_ERR(ce); | |
| 1321 | + break; | |
| 1322 | + } | |
| 1323 | + | |
| 1324 | + engine_heartbeat_disable(engine); | |
| 1325 | + timeslice = xchg(&engine->props.timeslice_duration_ms, 1); | |
| 1326 | + | |
| 1327 | + /* Create an unpreemptible spinner */ | |
| 1328 | + | |
| 1329 | + rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK); | |
| 1330 | + intel_context_put(ce); | |
| 1331 | + if (IS_ERR(rq)) { | |
| 1332 | + err = PTR_ERR(rq); | |
| 1333 | + goto out_heartbeat; | |
| 1334 | + } | |
| 1335 | + | |
| 1336 | + i915_request_get(rq); | |
| 1337 | + i915_request_add(rq); | |
| 1338 | + | |
| 1339 | + if (!igt_wait_for_spinner(&spin, rq)) { | |
| 1340 | + i915_request_put(rq); | |
| 1341 | + err = -ETIME; | |
| 1342 | + goto out_spin; | |
| 1343 | + } | |
| 1344 | + | |
| 1345 | + set_bit(I915_FENCE_FLAG_NOPREEMPT, &rq->fence.flags); | |
| 1346 | + i915_request_put(rq); | |
| 1347 | + | |
| 1348 | + /* Followed by a maximum priority barrier (heartbeat) */ | |
| 1349 | + | |
| 1350 | + ce = intel_context_create(engine); | |
| 1351 | + if (IS_ERR(ce)) { | |
| 1352 | + err = PTR_ERR(rq); | |
| 1353 | + goto out_spin; | |
| 1354 | + } | |
| 1355 | + | |
| 1356 | + rq = intel_context_create_request(ce); | |
| 1357 | + intel_context_put(ce); | |
| 1358 | + if (IS_ERR(rq)) { | |
| 1359 | + err = PTR_ERR(rq); | |
| 1360 | + goto out_spin; | |
| 1361 | + } | |
| 1362 | + | |
| 1363 | + rq->sched.attr.priority = I915_PRIORITY_BARRIER; | |
| 1364 | + i915_request_get(rq); | |
| 1365 | + i915_request_add(rq); | |
| 1366 | + | |
| 1367 | + /* | |
| 1368 | + * Wait until the barrier is in ELSP, and we know timeslicing | |
| 1369 | + * will have been activated. | |
| 1370 | + */ | |
| 1371 | + if (wait_for_submit(engine, rq, HZ / 2)) { | |
| 1372 | + i915_request_put(rq); | |
| 1373 | + err = -ETIME; | |
| 1374 | + goto out_spin; | |
| 1375 | + } | |
| 1376 | + | |
| 1377 | + /* | |
| 1378 | + * Since the ELSP[0] request is unpreemptible, it should not | |
| 1379 | + * allow the maximum priority barrier through. Wait long | |
| 1380 | + * enough to see if it is timesliced in by mistake. | |
| 1381 | + */ | |
| 1382 | + if (i915_request_wait(rq, 0, timeslice_threshold(engine)) >= 0) { | |
| 1383 | + pr_err("%s: I915_PRIORITY_BARRIER request completed, bypassing no-preempt request\n", | |
| 1384 | + engine->name); | |
| 1385 | + err = -EINVAL; | |
| 1386 | + } | |
| 1387 | + i915_request_put(rq); | |
| 1388 | + | |
| 1389 | +out_spin: | |
| 1390 | + igt_spinner_end(&spin); | |
| 1391 | +out_heartbeat: | |
| 1392 | + xchg(&engine->props.timeslice_duration_ms, timeslice); | |
| 1393 | + engine_heartbeat_enable(engine); | |
| 1394 | + if (err) | |
| 1395 | + break; | |
| 1396 | + | |
| 1397 | + if (igt_flush_test(gt->i915)) { | |
| 1398 | + err = -EIO; | |
| 1399 | + break; | |
| 1400 | + } | |
| 1401 | + } | |
| 1402 | + | |
| 1403 | + igt_spinner_fini(&spin); | |
| 1404 | + return err; | |
| 1405 | +} | |
| 1406 | + | |
| 1301 | 1407 | static int live_busywait_preempt(void *arg) |
| 1302 | 1408 | { |
| 1303 | 1409 | struct intel_gt *gt = arg; |
| @@ -4153,7 +4259,6 @@ static int reset_virtual_engine(struct intel_gt *gt, · 2849 unmodified lines | ||
| 4153 | 4259 | { |
| 4154 | 4260 | struct intel_engine_cs *engine; |
| 4155 | 4261 | struct intel_context *ve; |
| 4156 | − unsigned long *heartbeat; | |
| 4157 | 4262 | struct igt_spinner spin; |
| 4158 | 4263 | struct i915_request *rq; |
| 4159 | 4264 | unsigned int n; |
| @@ -4165,15 +4270,9 @@ static int reset_virtual_engine(struct intel_gt *gt, · 5 unmodified lines | ||
| 4165 | 4270 | * descendents are not executed while the capture is in progress. |
| 4166 | 4271 | */ |
| 4167 | 4272 | |
| 4168 | − heartbeat = kmalloc_array(nsibling, sizeof(*heartbeat), GFP_KERNEL); | |
| 4169 | − if (!heartbeat) | |
| 4273 | + if (igt_spinner_init(&spin, gt)) | |
| 4170 | 4274 | return -ENOMEM; |
| 4171 | 4275 | |
| 4172 | − if (igt_spinner_init(&spin, gt)) { | |
| 4173 | − err = -ENOMEM; | |
| 4174 | − goto out_free; | |
| 4175 | − } | |
| 4176 | − | |
| 4177 | 4276 | ve = intel_execlists_create_virtual(siblings, nsibling); |
| 4178 | 4277 | if (IS_ERR(ve)) { |
| 4179 | 4278 | err = PTR_ERR(ve); |
| @@ -4181,7 +4280,7 @@ static int reset_virtual_engine(struct intel_gt *gt, · 1 unmodified line | ||
| 4181 | 4280 | } |
| 4182 | 4281 | |
| 4183 | 4282 | for (n = 0; n < nsibling; n++) |
| 4184 | − engine_heartbeat_disable(siblings[n], &heartbeat[n]); | |
| 4283 | + engine_heartbeat_disable(siblings[n]); | |
| 4185 | 4284 | |
| 4186 | 4285 | rq = igt_spinner_create_request(&spin, ve, MI_ARB_CHECK); |
| 4187 | 4286 | if (IS_ERR(rq)) { |
| @@ -4252,13 +4351,11 @@ out_rq: · 64 unmodified lines | ||
| 4252 | 4351 | i915_request_put(rq); |
| 4253 | 4352 | out_heartbeat: |
| 4254 | 4353 | for (n = 0; n < nsibling; n++) |
| 4255 | − engine_heartbeat_enable(siblings[n], heartbeat[n]); | |
| 4354 | + engine_heartbeat_enable(siblings[n]); | |
| 4256 | 4355 | |
| 4257 | 4356 | intel_context_put(ve); |
| 4258 | 4357 | out_spin: |
| 4259 | 4358 | igt_spinner_fini(&spin); |
| 4260 | −out_free: | |
| 4261 | − kfree(heartbeat); | |
| 4262 | 4359 | return err; |
| 4263 | 4360 | } |
| 4264 | 4361 | |
| @@ -4314,6 +4411,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915) · 49 unmodified lines | ||
| 4314 | 4411 | SUBTEST(live_timeslice_preempt), |
| 4315 | 4412 | SUBTEST(live_timeslice_rewind), |
| 4316 | 4413 | SUBTEST(live_timeslice_queue), |
| 4414 | + SUBTEST(live_timeslice_nopreempt), | |
| 4317 | 4415 | SUBTEST(live_busywait_preempt), |
| 4318 | 4416 | SUBTEST(live_preempt), |
| 4319 | 4417 | SUBTEST(live_late_preempt), |
| @@ -4932,9 +5030,7 @@ static int live_lrc_gpr(void *arg) · 612 unmodified lines | ||
| 4932 | 5030 | return PTR_ERR(scratch); |
| 4933 | 5031 | |
| 4934 | 5032 | for_each_engine(engine, gt, id) { |
| 4935 | − unsigned long heartbeat; | |
| 4936 | − | |
| 4937 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 5033 | + engine_heartbeat_disable(engine); | |
| 4938 | 5034 | |
| 4939 | 5035 | err = __live_lrc_gpr(engine, scratch, false); |
| 4940 | 5036 | if (err) |
| @@ -4945,7 +5041,7 @@ static int live_lrc_gpr(void *arg) · 4 unmodified lines | ||
| 4945 | 5041 | goto err; |
| 4946 | 5042 | |
| 4947 | 5043 | err: |
| 4948 | − engine_heartbeat_enable(engine, heartbeat); | |
| 5044 | + engine_heartbeat_enable(engine); | |
| 4949 | 5045 | if (igt_flush_test(gt->i915)) |
| 4950 | 5046 | err = -EIO; |
| 4951 | 5047 | if (err) |
| @@ -5092,10 +5188,9 @@ static int live_lrc_timestamp(void *arg) · 140 unmodified lines | ||
| 5092 | 5188 | */ |
| 5093 | 5189 | |
| 5094 | 5190 | for_each_engine(data.engine, gt, id) { |
| 5095 | − unsigned long heartbeat; | |
| 5096 | 5191 | int i, err = 0; |
| 5097 | 5192 | |
| 5098 | − engine_heartbeat_disable(data.engine, &heartbeat); | |
| 5193 | + engine_heartbeat_disable(data.engine); | |
| 5099 | 5194 | |
| 5100 | 5195 | for (i = 0; i < ARRAY_SIZE(data.ce); i++) { |
| 5101 | 5196 | struct intel_context *tmp; |
| @@ -5128,7 +5223,7 @@ static int live_lrc_timestamp(void *arg) · 26 unmodified lines | ||
| 5128 | 5223 | } |
| 5129 | 5224 | |
| 5130 | 5225 | err: |
| 5131 | − engine_heartbeat_enable(data.engine, heartbeat); | |
| 5226 | + engine_heartbeat_enable(data.engine); | |
| 5132 | 5227 | for (i = 0; i < ARRAY_SIZE(data.ce); i++) { |
| 5133 | 5228 | if (!data.ce[i]) |
| 5134 | 5229 | break; |
| @@ -18,6 +18,20 @@ struct live_mocs { · 17 unmodified lines | ||
| 18 | 18 | void *vaddr; |
| 19 | 19 | }; |
| 20 | 20 | |
| 21 | +static struct intel_context *mocs_context_create(struct intel_engine_cs *engine) | |
| 22 | +{ | |
| 23 | + struct intel_context *ce; | |
| 24 | + | |
| 25 | + ce = intel_context_create(engine); | |
| 26 | + if (IS_ERR(ce)) | |
| 27 | + return ce; | |
| 28 | + | |
| 29 | + /* We build large requests to read the registers from the ring */ | |
| 30 | + ce->ring = __intel_context_ring_size(SZ_16K); | |
| 31 | + | |
| 32 | + return ce; | |
| 33 | +} | |
| 34 | + | |
| 21 | 35 | static int request_add_sync(struct i915_request *rq, int err) |
| 22 | 36 | { |
| 23 | 37 | i915_request_get(rq); |
| @@ -301,7 +315,7 @@ static int live_mocs_clean(void *arg) · 277 unmodified lines | ||
| 301 | 315 | for_each_engine(engine, gt, id) { |
| 302 | 316 | struct intel_context *ce; |
| 303 | 317 | |
| 304 | − ce = intel_context_create(engine); | |
| 318 | + ce = mocs_context_create(engine); | |
| 305 | 319 | if (IS_ERR(ce)) { |
| 306 | 320 | err = PTR_ERR(ce); |
| 307 | 321 | break; |
| @@ -395,7 +409,7 @@ static int live_mocs_reset(void *arg) · 87 unmodified lines | ||
| 395 | 409 | for_each_engine(engine, gt, id) { |
| 396 | 410 | struct intel_context *ce; |
| 397 | 411 | |
| 398 | − ce = intel_context_create(engine); | |
| 412 | + ce = mocs_context_create(engine); | |
| 399 | 413 | if (IS_ERR(ce)) { |
| 400 | 414 | err = PTR_ERR(ce); |
| 401 | 415 | break; |
| @@ -0,0 +1,110 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Copyright © 2020 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +static struct intel_ring *mock_ring(unsigned long sz) | |
| 7 | +{ | |
| 8 | + struct intel_ring *ring; | |
| 9 | + | |
| 10 | + ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL); | |
| 11 | + if (!ring) | |
| 12 | + return NULL; | |
| 13 | + | |
| 14 | + kref_init(&ring->ref); | |
| 15 | + ring->size = sz; | |
| 16 | + ring->wrap = BITS_PER_TYPE(ring->size) - ilog2(sz); | |
| 17 | + ring->effective_size = sz; | |
| 18 | + ring->vaddr = (void *)(ring + 1); | |
| 19 | + atomic_set(&ring->pin_count, 1); | |
| 20 | + | |
| 21 | + intel_ring_update_space(ring); | |
| 22 | + | |
| 23 | + return ring; | |
| 24 | +} | |
| 25 | + | |
| 26 | +static void mock_ring_free(struct intel_ring *ring) | |
| 27 | +{ | |
| 28 | + kfree(ring); | |
| 29 | +} | |
| 30 | + | |
| 31 | +static int check_ring_direction(struct intel_ring *ring, | |
| 32 | + u32 next, u32 prev, | |
| 33 | + int expected) | |
| 34 | +{ | |
| 35 | + int result; | |
| 36 | + | |
| 37 | + result = intel_ring_direction(ring, next, prev); | |
| 38 | + if (result < 0) | |
| 39 | + result = -1; | |
| 40 | + else if (result > 0) | |
| 41 | + result = 1; | |
| 42 | + | |
| 43 | + if (result != expected) { | |
| 44 | + pr_err("intel_ring_direction(%u, %u):%d != %d\n", | |
| 45 | + next, prev, result, expected); | |
| 46 | + return -EINVAL; | |
| 47 | + } | |
| 48 | + | |
| 49 | + return 0; | |
| 50 | +} | |
| 51 | + | |
| 52 | +static int check_ring_step(struct intel_ring *ring, u32 x, u32 step) | |
| 53 | +{ | |
| 54 | + u32 prev = x, next = intel_ring_wrap(ring, x + step); | |
| 55 | + int err = 0; | |
| 56 | + | |
| 57 | + err |= check_ring_direction(ring, next, next, 0); | |
| 58 | + err |= check_ring_direction(ring, prev, prev, 0); | |
| 59 | + err |= check_ring_direction(ring, next, prev, 1); | |
| 60 | + err |= check_ring_direction(ring, prev, next, -1); | |
| 61 | + | |
| 62 | + return err; | |
| 63 | +} | |
| 64 | + | |
| 65 | +static int check_ring_offset(struct intel_ring *ring, u32 x, u32 step) | |
| 66 | +{ | |
| 67 | + int err = 0; | |
| 68 | + | |
| 69 | + err |= check_ring_step(ring, x, step); | |
| 70 | + err |= check_ring_step(ring, intel_ring_wrap(ring, x + 1), step); | |
| 71 | + err |= check_ring_step(ring, intel_ring_wrap(ring, x - 1), step); | |
| 72 | + | |
| 73 | + return err; | |
| 74 | +} | |
| 75 | + | |
| 76 | +static int igt_ring_direction(void *dummy) | |
| 77 | +{ | |
| 78 | + struct intel_ring *ring; | |
| 79 | + unsigned int half = 2048; | |
| 80 | + int step, err = 0; | |
| 81 | + | |
| 82 | + ring = mock_ring(2 * half); | |
| 83 | + if (!ring) | |
| 84 | + return -ENOMEM; | |
| 85 | + | |
| 86 | + GEM_BUG_ON(ring->size != 2 * half); | |
| 87 | + | |
| 88 | + /* Precision of wrap detection is limited to ring->size / 2 */ | |
| 89 | + for (step = 1; step < half; step <<= 1) { | |
| 90 | + err |= check_ring_offset(ring, 0, step); | |
| 91 | + err |= check_ring_offset(ring, half, step); | |
| 92 | + } | |
| 93 | + err |= check_ring_step(ring, 0, half - 64); | |
| 94 | + | |
| 95 | + /* And check unwrapped handling for good measure */ | |
| 96 | + err |= check_ring_offset(ring, 0, 2 * half + 64); | |
| 97 | + err |= check_ring_offset(ring, 3 * half, 1); | |
| 98 | + | |
| 99 | + mock_ring_free(ring); | |
| 100 | + return err; | |
| 101 | +} | |
| 102 | + | |
| 103 | +int intel_ring_mock_selftests(void) | |
| 104 | +{ | |
| 105 | + static const struct i915_subtest tests[] = { | |
| 106 | + SUBTEST(igt_ring_direction), | |
| 107 | + }; | |
| 108 | + | |
| 109 | + return i915_subtests(tests, NULL); | |
| 110 | +} | |
| @@ -20,24 +20,20 @@ · 19 unmodified lines | ||
| 20 | 20 | /* Try to isolate the impact of cstates from determing frequency response */ |
| 21 | 21 | #define CPU_LATENCY 0 /* -1 to disable pm_qos, 0 to disable cstates */ |
| 22 | 22 | |
| 23 | −static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine) | |
| 23 | +static void engine_heartbeat_disable(struct intel_engine_cs *engine) | |
| 24 | 24 | { |
| 25 | − unsigned long old; | |
| 26 | − | |
| 27 | − old = fetch_and_zero(&engine->props.heartbeat_interval_ms); | |
| 25 | + engine->props.heartbeat_interval_ms = 0; | |
| 28 | 26 | |
| 29 | 27 | intel_engine_pm_get(engine); |
| 30 | 28 | intel_engine_park_heartbeat(engine); |
| 31 | − | |
| 32 | − return old; | |
| 33 | 29 | } |
| 34 | 30 | |
| 35 | −static void engine_heartbeat_enable(struct intel_engine_cs *engine, | |
| 36 | − unsigned long saved) | |
| 31 | +static void engine_heartbeat_enable(struct intel_engine_cs *engine) | |
| 37 | 32 | { |
| 38 | 33 | intel_engine_pm_put(engine); |
| 39 | 34 | |
| 40 | − engine->props.heartbeat_interval_ms = saved; | |
| 35 | + engine->props.heartbeat_interval_ms = | |
| 36 | + engine->defaults.heartbeat_interval_ms; | |
| 41 | 37 | } |
| 42 | 38 | |
| 43 | 39 | static void dummy_rps_work(struct work_struct *wrk) |
| @@ -246,7 +242,6 @@ int live_rps_clock_interval(void *arg) · 202 unmodified lines | ||
| 246 | 242 | intel_gt_check_clock_frequency(gt); |
| 247 | 243 | |
| 248 | 244 | for_each_engine(engine, gt, id) { |
| 249 | − unsigned long saved_heartbeat; | |
| 250 | 245 | struct i915_request *rq; |
| 251 | 246 | u32 cycles; |
| 252 | 247 | u64 dt; |
| @@ -254,13 +249,13 @@ int live_rps_clock_interval(void *arg) · 1 unmodified line | ||
| 254 | 249 | if (!intel_engine_can_store_dword(engine)) |
| 255 | 250 | continue; |
| 256 | 251 | |
| 257 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 252 | + engine_heartbeat_disable(engine); | |
| 258 | 253 | |
| 259 | 254 | rq = igt_spinner_create_request(&spin, |
| 260 | 255 | engine->kernel_context, |
| 261 | 256 | MI_NOOP); |
| 262 | 257 | if (IS_ERR(rq)) { |
| 263 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 258 | + engine_heartbeat_enable(engine); | |
| 264 | 259 | err = PTR_ERR(rq); |
| 265 | 260 | break; |
| 266 | 261 | } |
| @@ -271,7 +266,7 @@ int live_rps_clock_interval(void *arg) · 4 unmodified lines | ||
| 271 | 266 | pr_err("%s: RPS spinner did not start\n", |
| 272 | 267 | engine->name); |
| 273 | 268 | igt_spinner_end(&spin); |
| 274 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 269 | + engine_heartbeat_enable(engine); | |
| 275 | 270 | intel_gt_set_wedged(engine->gt); |
| 276 | 271 | err = -EIO; |
| 277 | 272 | break; |
| @@ -327,7 +322,7 @@ int live_rps_clock_interval(void *arg) · 49 unmodified lines | ||
| 327 | 322 | intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL); |
| 328 | 323 | |
| 329 | 324 | igt_spinner_end(&spin); |
| 330 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 325 | + engine_heartbeat_enable(engine); | |
| 331 | 326 | |
| 332 | 327 | if (err == 0) { |
| 333 | 328 | u64 time = intel_gt_pm_interval_to_ns(gt, cycles); |
| @@ -405,7 +400,6 @@ int live_rps_control(void *arg) · 71 unmodified lines | ||
| 405 | 400 | |
| 406 | 401 | intel_gt_pm_get(gt); |
| 407 | 402 | for_each_engine(engine, gt, id) { |
| 408 | − unsigned long saved_heartbeat; | |
| 409 | 403 | struct i915_request *rq; |
| 410 | 404 | ktime_t min_dt, max_dt; |
| 411 | 405 | int f, limit; |
| @@ -414,7 +408,7 @@ int live_rps_control(void *arg) · 2 unmodified lines | ||
| 414 | 408 | if (!intel_engine_can_store_dword(engine)) |
| 415 | 409 | continue; |
| 416 | 410 | |
| 417 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 411 | + engine_heartbeat_disable(engine); | |
| 418 | 412 | |
| 419 | 413 | rq = igt_spinner_create_request(&spin, |
| 420 | 414 | engine->kernel_context, |
| @@ -430,7 +424,7 @@ int live_rps_control(void *arg) · 9 unmodified lines | ||
| 430 | 424 | pr_err("%s: RPS spinner did not start\n", |
| 431 | 425 | engine->name); |
| 432 | 426 | igt_spinner_end(&spin); |
| 433 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 427 | + engine_heartbeat_enable(engine); | |
| 434 | 428 | intel_gt_set_wedged(engine->gt); |
| 435 | 429 | err = -EIO; |
| 436 | 430 | break; |
| @@ -440,7 +434,7 @@ int live_rps_control(void *arg) · 3 unmodified lines | ||
| 440 | 434 | pr_err("%s: could not set minimum frequency [%x], only %x!\n", |
| 441 | 435 | engine->name, rps->min_freq, read_cagf(rps)); |
| 442 | 436 | igt_spinner_end(&spin); |
| 443 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 437 | + engine_heartbeat_enable(engine); | |
| 444 | 438 | show_pstate_limits(rps); |
| 445 | 439 | err = -EINVAL; |
| 446 | 440 | break; |
| @@ -457,7 +451,7 @@ int live_rps_control(void *arg) · 10 unmodified lines | ||
| 457 | 451 | pr_err("%s: could not restore minimum frequency [%x], only %x!\n", |
| 458 | 452 | engine->name, rps->min_freq, read_cagf(rps)); |
| 459 | 453 | igt_spinner_end(&spin); |
| 460 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 454 | + engine_heartbeat_enable(engine); | |
| 461 | 455 | show_pstate_limits(rps); |
| 462 | 456 | err = -EINVAL; |
| 463 | 457 | break; |
| @@ -472,7 +466,7 @@ int live_rps_control(void *arg) · 8 unmodified lines | ||
| 472 | 466 | min_dt = ktime_sub(ktime_get(), min_dt); |
| 473 | 467 | |
| 474 | 468 | igt_spinner_end(&spin); |
| 475 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 469 | + engine_heartbeat_enable(engine); | |
| 476 | 470 | |
| 477 | 471 | pr_info("%s: range:[%x:%uMHz, %x:%uMHz] limit:[%x:%uMHz], %x:%x response %lluns:%lluns\n", |
| 478 | 472 | engine->name, |
| @@ -635,7 +629,6 @@ int live_rps_frequency_cs(void *arg) · 156 unmodified lines | ||
| 635 | 629 | rps->work.func = dummy_rps_work; |
| 636 | 630 | |
| 637 | 631 | for_each_engine(engine, gt, id) { |
| 638 | − unsigned long saved_heartbeat; | |
| 639 | 632 | struct i915_request *rq; |
| 640 | 633 | struct i915_vma *vma; |
| 641 | 634 | u32 *cancel, *cntr; |
| @@ -644,14 +637,14 @@ int live_rps_frequency_cs(void *arg) · 2 unmodified lines | ||
| 644 | 637 | int freq; |
| 645 | 638 | } min, max; |
| 646 | 639 | |
| 647 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 640 | + engine_heartbeat_disable(engine); | |
| 648 | 641 | |
| 649 | 642 | vma = create_spin_counter(engine, |
| 650 | 643 | engine->kernel_context->vm, false, |
| 651 | 644 | &cancel, &cntr); |
| 652 | 645 | if (IS_ERR(vma)) { |
| 653 | 646 | err = PTR_ERR(vma); |
| 654 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 647 | + engine_heartbeat_enable(engine); | |
| 655 | 648 | break; |
| 656 | 649 | } |
| 657 | 650 | |
| @@ -732,7 +725,7 @@ err_vma: · 74 unmodified lines | ||
| 732 | 725 | i915_vma_unpin(vma); |
| 733 | 726 | i915_vma_put(vma); |
| 734 | 727 | |
| 735 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 728 | + engine_heartbeat_enable(engine); | |
| 736 | 729 | if (igt_flush_test(gt->i915)) |
| 737 | 730 | err = -EIO; |
| 738 | 731 | if (err) |
| @@ -778,7 +771,6 @@ int live_rps_frequency_srm(void *arg) · 39 unmodified lines | ||
| 778 | 771 | rps->work.func = dummy_rps_work; |
| 779 | 772 | |
| 780 | 773 | for_each_engine(engine, gt, id) { |
| 781 | − unsigned long saved_heartbeat; | |
| 782 | 774 | struct i915_request *rq; |
| 783 | 775 | struct i915_vma *vma; |
| 784 | 776 | u32 *cancel, *cntr; |
| @@ -787,14 +779,14 @@ int live_rps_frequency_srm(void *arg) · 2 unmodified lines | ||
| 787 | 779 | int freq; |
| 788 | 780 | } min, max; |
| 789 | 781 | |
| 790 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 782 | + engine_heartbeat_disable(engine); | |
| 791 | 783 | |
| 792 | 784 | vma = create_spin_counter(engine, |
| 793 | 785 | engine->kernel_context->vm, true, |
| 794 | 786 | &cancel, &cntr); |
| 795 | 787 | if (IS_ERR(vma)) { |
| 796 | 788 | err = PTR_ERR(vma); |
| 797 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 789 | + engine_heartbeat_enable(engine); | |
| 798 | 790 | break; |
| 799 | 791 | } |
| 800 | 792 | |
| @@ -874,7 +866,7 @@ err_vma: · 73 unmodified lines | ||
| 874 | 866 | i915_vma_unpin(vma); |
| 875 | 867 | i915_vma_put(vma); |
| 876 | 868 | |
| 877 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 869 | + engine_heartbeat_enable(engine); | |
| 878 | 870 | if (igt_flush_test(gt->i915)) |
| 879 | 871 | err = -EIO; |
| 880 | 872 | if (err) |
| @@ -1066,16 +1058,14 @@ int live_rps_interrupt(void *arg) · 185 unmodified lines | ||
| 1066 | 1058 | for_each_engine(engine, gt, id) { |
| 1067 | 1059 | /* Keep the engine busy with a spinner; expect an UP! */ |
| 1068 | 1060 | if (pm_events & GEN6_PM_RP_UP_THRESHOLD) { |
| 1069 | − unsigned long saved_heartbeat; | |
| 1070 | − | |
| 1071 | 1061 | intel_gt_pm_wait_for_idle(engine->gt); |
| 1072 | 1062 | GEM_BUG_ON(intel_rps_is_active(rps)); |
| 1073 | 1063 | |
| 1074 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 1064 | + engine_heartbeat_disable(engine); | |
| 1075 | 1065 | |
| 1076 | 1066 | err = __rps_up_interrupt(rps, engine, &spin); |
| 1077 | 1067 | |
| 1078 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 1068 | + engine_heartbeat_enable(engine); | |
| 1079 | 1069 | if (err) |
| 1080 | 1070 | goto out; |
| 1081 | 1071 | |
| @@ -1084,15 +1074,13 @@ int live_rps_interrupt(void *arg) · 2 unmodified lines | ||
| 1084 | 1074 | |
| 1085 | 1075 | /* Keep the engine awake but idle and check for DOWN */ |
| 1086 | 1076 | if (pm_events & GEN6_PM_RP_DOWN_THRESHOLD) { |
| 1087 | − unsigned long saved_heartbeat; | |
| 1088 | − | |
| 1089 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 1077 | + engine_heartbeat_disable(engine); | |
| 1090 | 1078 | intel_rc6_disable(>->rc6); |
| 1091 | 1079 | |
| 1092 | 1080 | err = __rps_down_interrupt(rps, engine); |
| 1093 | 1081 | |
| 1094 | 1082 | intel_rc6_enable(>->rc6); |
| 1095 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 1083 | + engine_heartbeat_enable(engine); | |
| 1096 | 1084 | if (err) |
| 1097 | 1085 | goto out; |
| 1098 | 1086 | } |
| @@ -1168,7 +1156,6 @@ int live_rps_power(void *arg) · 69 unmodified lines | ||
| 1168 | 1156 | rps->work.func = dummy_rps_work; |
| 1169 | 1157 | |
| 1170 | 1158 | for_each_engine(engine, gt, id) { |
| 1171 | − unsigned long saved_heartbeat; | |
| 1172 | 1159 | struct i915_request *rq; |
| 1173 | 1160 | struct { |
| 1174 | 1161 | u64 power; |
| @@ -1178,13 +1165,13 @@ int live_rps_power(void *arg) · 3 unmodified lines | ||
| 1178 | 1165 | if (!intel_engine_can_store_dword(engine)) |
| 1179 | 1166 | continue; |
| 1180 | 1167 | |
| 1181 | − saved_heartbeat = engine_heartbeat_disable(engine); | |
| 1168 | + engine_heartbeat_disable(engine); | |
| 1182 | 1169 | |
| 1183 | 1170 | rq = igt_spinner_create_request(&spin, |
| 1184 | 1171 | engine->kernel_context, |
| 1185 | 1172 | MI_NOOP); |
| 1186 | 1173 | if (IS_ERR(rq)) { |
| 1187 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 1174 | + engine_heartbeat_enable(engine); | |
| 1188 | 1175 | err = PTR_ERR(rq); |
| 1189 | 1176 | break; |
| 1190 | 1177 | } |
| @@ -1195,7 +1182,7 @@ int live_rps_power(void *arg) · 4 unmodified lines | ||
| 1195 | 1182 | pr_err("%s: RPS spinner did not start\n", |
| 1196 | 1183 | engine->name); |
| 1197 | 1184 | igt_spinner_end(&spin); |
| 1198 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 1185 | + engine_heartbeat_enable(engine); | |
| 1199 | 1186 | intel_gt_set_wedged(engine->gt); |
| 1200 | 1187 | err = -EIO; |
| 1201 | 1188 | break; |
| @@ -1208,7 +1195,7 @@ int live_rps_power(void *arg) · 6 unmodified lines | ||
| 1208 | 1195 | min.power = measure_power_at(rps, &min.freq); |
| 1209 | 1196 | |
| 1210 | 1197 | igt_spinner_end(&spin); |
| 1211 | − engine_heartbeat_enable(engine, saved_heartbeat); | |
| 1198 | + engine_heartbeat_enable(engine); | |
| 1212 | 1199 | |
| 1213 | 1200 | pr_info("%s: min:%llumW @ %uMHz, max:%llumW @ %uMHz\n", |
| 1214 | 1201 | engine->name, |
| @@ -751,22 +751,20 @@ out_free: · 750 unmodified lines | ||
| 751 | 751 | return err; |
| 752 | 752 | } |
| 753 | 753 | |
| 754 | −static void engine_heartbeat_disable(struct intel_engine_cs *engine, | |
| 755 | − unsigned long *saved) | |
| 754 | +static void engine_heartbeat_disable(struct intel_engine_cs *engine) | |
| 756 | 755 | { |
| 757 | − *saved = engine->props.heartbeat_interval_ms; | |
| 758 | 756 | engine->props.heartbeat_interval_ms = 0; |
| 759 | 757 | |
| 760 | 758 | intel_engine_pm_get(engine); |
| 761 | 759 | intel_engine_park_heartbeat(engine); |
| 762 | 760 | } |
| 763 | 761 | |
| 764 | −static void engine_heartbeat_enable(struct intel_engine_cs *engine, | |
| 765 | − unsigned long saved) | |
| 762 | +static void engine_heartbeat_enable(struct intel_engine_cs *engine) | |
| 766 | 763 | { |
| 767 | 764 | intel_engine_pm_put(engine); |
| 768 | 765 | |
| 769 | − engine->props.heartbeat_interval_ms = saved; | |
| 766 | + engine->props.heartbeat_interval_ms = | |
| 767 | + engine->defaults.heartbeat_interval_ms; | |
| 770 | 768 | } |
| 771 | 769 | |
| 772 | 770 | static int live_hwsp_rollover_kernel(void *arg) |
| @@ -785,10 +783,9 @@ static int live_hwsp_rollover_kernel(void *arg) · 12 unmodified lines | ||
| 785 | 783 | struct intel_context *ce = engine->kernel_context; |
| 786 | 784 | struct intel_timeline *tl = ce->timeline; |
| 787 | 785 | struct i915_request *rq[3] = {}; |
| 788 | − unsigned long heartbeat; | |
| 789 | 786 | int i; |
| 790 | 787 | |
| 791 | − engine_heartbeat_disable(engine, &heartbeat); | |
| 788 | + engine_heartbeat_disable(engine); | |
| 792 | 789 | if (intel_gt_wait_for_idle(gt, HZ / 2)) { |
| 793 | 790 | err = -EIO; |
| 794 | 791 | goto out; |
| @@ -839,7 +836,7 @@ static int live_hwsp_rollover_kernel(void *arg) · 44 unmodified lines | ||
| 839 | 836 | out: |
| 840 | 837 | for (i = 0; i < ARRAY_SIZE(rq); i++) |
| 841 | 838 | i915_request_put(rq[i]); |
| 842 | − engine_heartbeat_enable(engine, heartbeat); | |
| 839 | + engine_heartbeat_enable(engine); | |
| 843 | 840 | if (err) |
| 844 | 841 | break; |
| 845 | 842 | } |
| @@ -623,6 +623,8 @@ err_request: · 622 unmodified lines | ||
| 623 | 623 | err = -EINVAL; |
| 624 | 624 | goto out_unpin; |
| 625 | 625 | } |
| 626 | + } else { | |
| 627 | + rsvd = 0; | |
| 626 | 628 | } |
| 627 | 629 | |
| 628 | 630 | expect = results[0]; |
| @@ -0,0 +1,46 @@ | ||
| 1 | +ASM sources for auto generated shaders | |
| 2 | +====================================== | |
| 3 | + | |
| 4 | +The i915/gt/hsw_clear_kernel.c and i915/gt/ivb_clear_kernel.c files contain | |
| 5 | +pre-compiled batch chunks that will clear any residual render cache during | |
| 6 | +context switch. | |
| 7 | + | |
| 8 | +They are generated from their respective platform ASM files present on | |
| 9 | +i915/gt/shaders/clear_kernel directory. | |
| 10 | + | |
| 11 | +The generated .c files should never be modified directly. Instead, any modification | |
| 12 | +needs to be done on the on their respective ASM files and build instructions below | |
| 13 | +needes to be followed. | |
| 14 | + | |
| 15 | +Building | |
| 16 | +======== | |
| 17 | + | |
| 18 | +Environment | |
| 19 | +----------- | |
| 20 | + | |
| 21 | +IGT GPU tool scripts and the Mesa's i965 instruction assembler tool are used | |
| 22 | +on building. | |
| 23 | + | |
| 24 | +Please make sure your Mesa tool is compiled with "-Dtools=intel" and | |
| 25 | +"-Ddri-drivers=i965", and run this script from IGT source root directory" | |
| 26 | + | |
| 27 | +The instructions bellow assume: | |
| 28 | + * IGT gpu tools source code is located on your home directory (~) as ~/igt | |
| 29 | + * Mesa source code is located on your home directory (~) as ~/mesa | |
| 30 | + and built under the ~/mesa/build directory | |
| 31 | + * Linux kernel source code is under your home directory (~) as ~/linux | |
| 32 | + | |
| 33 | +Instructions | |
| 34 | +------------ | |
| 35 | + | |
| 36 | +~ $ cp ~/linux/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm \ | |
| 37 | + ~/igt/lib/i915/shaders/clear_kernel/ivb.asm | |
| 38 | +~ $ cd ~/igt | |
| 39 | +igt $ ./scripts/generate_clear_kernel.sh -g ivb \ | |
| 40 | + -m ~/mesa/build/src/intel/tools/i965_asm | |
| 41 | + | |
| 42 | +~ $ cp ~/linux/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm \ | |
| 43 | + ~/igt/lib/i915/shaders/clear_kernel/hsw.asm | |
| 44 | +~ $ cd ~/igt | |
| 45 | +igt $ ./scripts/generate_clear_kernel.sh -g hsw \ | |
| 46 | + -m ~/mesa/build/src/intel/tools/i965_asm | |
| @@ -0,0 +1,119 @@ | ||
| 1 | +// SPDX-License-Identifier: MIT | |
| 2 | +/* | |
| 3 | + * Copyright © 2020 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +/* | |
| 7 | + * Kernel for PAVP buffer clear. | |
| 8 | + * | |
| 9 | + * 1. Clear all 64 GRF registers assigned to the kernel with designated value; | |
| 10 | + * 2. Write 32x16 block of all "0" to render target buffer which indirectly clears | |
| 11 | + * 512 bytes of Render Cache. | |
| 12 | + */ | |
| 13 | + | |
| 14 | +/* Store designated "clear GRF" value */ | |
| 15 | +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Curbe Format | |
| 19 | + * | |
| 20 | + * DW 1.0 - Block Offset to write Render Cache | |
| 21 | + * DW 1.1 [15:0] - Clear Word | |
| 22 | + * DW 1.2 - Delay iterations | |
| 23 | + * DW 1.3 - Enable Instrumentation (only for debug) | |
| 24 | + * DW 1.4 - Rsvd (intended for context ID) | |
| 25 | + * DW 1.5 - [31:16]:SliceCount, [15:0]:SubSlicePerSliceCount | |
| 26 | + * DW 1.6 - Rsvd MBZ (intended for Enable Wait on Total Thread Count) | |
| 27 | + * DW 1.7 - Rsvd MBZ (inteded for Total Thread Count) | |
| 28 | + * | |
| 29 | + * Binding Table | |
| 30 | + * | |
| 31 | + * BTI 0: 2D Surface to help clear L3 (Render/Data Cache) | |
| 32 | + * BTI 1: Wait/Instrumentation Buffer | |
| 33 | + * Size : (SliceCount * SubSliceCount * 16 EUs/SubSlice) rows * (16 threads/EU) cols (Format R32_UINT) | |
| 34 | + * Expected to be initialized to 0 by driver/another kernel | |
| 35 | + * Layout: | |
| 36 | + * RowN: Histogram for EU-N: (SliceID*SubSlicePerSliceCount + SSID)*16 + EUID [assume max 16 EUs / SS] | |
| 37 | + * Col-k[DW-k]: Threads Executed on ThreadID-k for EU-N | |
| 38 | + */ | |
| 39 | +add(1) g1.2<1>UD g1.2<0,1,0>UD 0x00000001UD { align1 1N }; /* Loop count to delay kernel: Init to (g1.2 + 1) */ | |
| 40 | +cmp.z.f0.0(1) null<1>UD g1.3<0,1,0>UD 0x00000000UD { align1 1N }; | |
| 41 | +(+f0.0) jmpi(1) 352D { align1 WE_all 1N }; | |
| 42 | + | |
| 43 | +/** | |
| 44 | + * State Register has info on where this thread is running | |
| 45 | + * IVB: sr0.0 :: [15:13]: MBZ, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID | |
| 46 | + * HSW: sr0.0 :: 15: MBZ, [14:13]: SliceID, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID | |
| 47 | + */ | |
| 48 | +mov(8) g3<1>UD 0x00000000UD { align1 1Q }; | |
| 49 | +shr(1) g3<1>D sr0<0,1,0>D 12D { align1 1N }; | |
| 50 | +and(1) g3<1>D g3<0,1,0>D 1D { align1 1N }; /* g3 has HSID */ | |
| 51 | +shr(1) g3.1<1>D sr0<0,1,0>D 13D { align1 1N }; | |
| 52 | +and(1) g3.1<1>D g3.1<0,1,0>D 3D { align1 1N }; /* g3.1 has sliceID */ | |
| 53 | +mul(1) g3.5<1>D g3.1<0,1,0>D g1.10<0,1,0>UW { align1 1N }; | |
| 54 | +add(1) g3<1>D g3<0,1,0>D g3.5<0,1,0>D { align1 1N }; /* g3 = sliceID * SubSlicePerSliceCount + HSID */ | |
| 55 | +shr(1) g3.2<1>D sr0<0,1,0>D 8D { align1 1N }; | |
| 56 | +and(1) g3.2<1>D g3.2<0,1,0>D 15D { align1 1N }; /* g3.2 = EUID */ | |
| 57 | +mul(1) g3.4<1>D g3<0,1,0>D 16D { align1 1N }; | |
| 58 | +add(1) g3.2<1>D g3.2<0,1,0>D g3.4<0,1,0>D { align1 1N }; /* g3.2 now points to EU row number (Y-pixel = V address ) in instrumentation surf */ | |
| 59 | + | |
| 60 | +mov(8) g5<1>UD 0x00000000UD { align1 1Q }; | |
| 61 | +and(1) g3.3<1>D sr0<0,1,0>D 7D { align1 1N }; | |
| 62 | +mul(1) g3.3<1>D g3.3<0,1,0>D 4D { align1 1N }; | |
| 63 | + | |
| 64 | +mov(8) g4<1>UD g0<8,8,1>UD { align1 1Q }; /* Initialize message header with g0 */ | |
| 65 | +mov(1) g4<1>UD g3.3<0,1,0>UD { align1 1N }; /* Block offset */ | |
| 66 | +mov(1) g4.1<1>UD g3.2<0,1,0>UD { align1 1N }; /* Block offset */ | |
| 67 | +mov(1) g4.2<1>UD 0x00000003UD { align1 1N }; /* Block size (1 row x 4 bytes) */ | |
| 68 | +and(1) g4.3<1>UD g4.3<0,1,0>UW 0xffffffffUD { align1 1N }; | |
| 69 | + | |
| 70 | +/* Media block read to fetch current value at specified location in instrumentation buffer */ | |
| 71 | +sendc(8) g5<1>UD g4<8,8,1>F 0x02190001 | |
| 72 | + | |
| 73 | + render MsgDesc: media block read MsgCtrl = 0x0 Surface = 1 mlen 1 rlen 1 { align1 1Q }; | |
| 74 | +add(1) g5<1>D g5<0,1,0>D 1D { align1 1N }; | |
| 75 | + | |
| 76 | +/* Media block write for updated value at specified location in instrumentation buffer */ | |
| 77 | +sendc(8) g5<1>UD g4<8,8,1>F 0x040a8001 | |
| 78 | + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 1 mlen 2 rlen 0 { align1 1Q }; | |
| 79 | + | |
| 80 | +/* Delay thread for specified parameter */ | |
| 81 | +add.nz.f0.0(1) g1.2<1>UD g1.2<0,1,0>UD -1D { align1 1N }; | |
| 82 | +(+f0.0) jmpi(1) -32D { align1 WE_all 1N }; | |
| 83 | + | |
| 84 | +/* Store designated "clear GRF" value */ | |
| 85 | +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; | |
| 86 | + | |
| 87 | +/* Initialize looping parameters */ | |
| 88 | +mov(1) a0<1>D 0D { align1 1N }; /* Initialize a0.0:w=0 */ | |
| 89 | +mov(1) a0.4<1>W 127W { align1 1N }; /* Loop count. Each loop contains 16 GRF's */ | |
| 90 | + | |
| 91 | +/* Write 32x16 all "0" block */ | |
| 92 | +mov(8) g2<1>UD g0<8,8,1>UD { align1 1Q }; | |
| 93 | +mov(8) g127<1>UD g0<8,8,1>UD { align1 1Q }; | |
| 94 | +mov(2) g2<1>UD g1<2,2,1>UW { align1 1N }; | |
| 95 | +mov(1) g2.2<1>UD 0x000f000fUD { align1 1N }; /* Block size (16x16) */ | |
| 96 | +and(1) g2.3<1>UD g2.3<0,1,0>UW 0xffffffefUD { align1 1N }; | |
| 97 | +mov(16) g3<1>UD 0x00000000UD { align1 1H }; | |
| 98 | +mov(16) g4<1>UD 0x00000000UD { align1 1H }; | |
| 99 | +mov(16) g5<1>UD 0x00000000UD { align1 1H }; | |
| 100 | +mov(16) g6<1>UD 0x00000000UD { align1 1H }; | |
| 101 | +mov(16) g7<1>UD 0x00000000UD { align1 1H }; | |
| 102 | +mov(16) g8<1>UD 0x00000000UD { align1 1H }; | |
| 103 | +mov(16) g9<1>UD 0x00000000UD { align1 1H }; | |
| 104 | +mov(16) g10<1>UD 0x00000000UD { align1 1H }; | |
| 105 | +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 | |
| 106 | + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; | |
| 107 | +add(1) g2<1>UD g1<0,1,0>UW 0x0010UW { align1 1N }; | |
| 108 | +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 | |
| 109 | + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; | |
| 110 | + | |
| 111 | +/* Now, clear all GRF registers */ | |
| 112 | +add.nz.f0.0(1) a0.4<1>W a0.4<0,1,0>W -1W { align1 1N }; | |
| 113 | +mov(16) g[a0]<1>UW f0.1<0,1,0>UW { align1 1H }; | |
| 114 | +add(1) a0<1>D a0<0,1,0>D 32D { align1 1N }; | |
| 115 | +(+f0.0) jmpi(1) -64D { align1 WE_all 1N }; | |
| 116 | + | |
| 117 | +/* Terminante the thread */ | |
| 118 | +sendc(8) null<1>UD g127<8,8,1>F 0x82000010 | |
| 119 | + thread_spawner MsgDesc: mlen 1 rlen 0 { align1 1Q EOT }; | |
| @@ -0,0 +1,117 @@ | ||
| 1 | +// SPDX-License-Identifier: MIT | |
| 2 | +/* | |
| 3 | + * Copyright © 2020 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +/* | |
| 7 | + * Kernel for PAVP buffer clear. | |
| 8 | + * | |
| 9 | + * 1. Clear all 64 GRF registers assigned to the kernel with designated value; | |
| 10 | + * 2. Write 32x16 block of all "0" to render target buffer which indirectly clears | |
| 11 | + * 512 bytes of Render Cache. | |
| 12 | + */ | |
| 13 | + | |
| 14 | +/* Store designated "clear GRF" value */ | |
| 15 | +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Curbe Format | |
| 19 | + * | |
| 20 | + * DW 1.0 - Block Offset to write Render Cache | |
| 21 | + * DW 1.1 [15:0] - Clear Word | |
| 22 | + * DW 1.2 - Delay iterations | |
| 23 | + * DW 1.3 - Enable Instrumentation (only for debug) | |
| 24 | + * DW 1.4 - Rsvd (intended for context ID) | |
| 25 | + * DW 1.5 - [31:16]:SliceCount, [15:0]:SubSlicePerSliceCount | |
| 26 | + * DW 1.6 - Rsvd MBZ (intended for Enable Wait on Total Thread Count) | |
| 27 | + * DW 1.7 - Rsvd MBZ (inteded for Total Thread Count) | |
| 28 | + * | |
| 29 | + * Binding Table | |
| 30 | + * | |
| 31 | + * BTI 0: 2D Surface to help clear L3 (Render/Data Cache) | |
| 32 | + * BTI 1: Wait/Instrumentation Buffer | |
| 33 | + * Size : (SliceCount * SubSliceCount * 16 EUs/SubSlice) rows * (16 threads/EU) cols (Format R32_UINT) | |
| 34 | + * Expected to be initialized to 0 by driver/another kernel | |
| 35 | + * Layout : | |
| 36 | + * RowN: Histogram for EU-N: (SliceID*SubSlicePerSliceCount + SSID)*16 + EUID [assume max 16 EUs / SS] | |
| 37 | + * Col-k[DW-k]: Threads Executed on ThreadID-k for EU-N | |
| 38 | + */ | |
| 39 | +add(1) g1.2<1>UD g1.2<0,1,0>UD 0x00000001UD { align1 1N }; /* Loop count to delay kernel: Init to (g1.2 + 1) */ | |
| 40 | +cmp.z.f0.0(1) null<1>UD g1.3<0,1,0>UD 0x00000000UD { align1 1N }; | |
| 41 | +(+f0.0) jmpi(1) 44D { align1 WE_all 1N }; | |
| 42 | + | |
| 43 | +/** | |
| 44 | + * State Register has info on where this thread is running | |
| 45 | + * IVB: sr0.0 :: [15:13]: MBZ, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID | |
| 46 | + * HSW: sr0.0 :: 15: MBZ, [14:13]: SliceID, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID | |
| 47 | + */ | |
| 48 | +mov(8) g3<1>UD 0x00000000UD { align1 1Q }; | |
| 49 | +shr(1) g3<1>D sr0<0,1,0>D 12D { align1 1N }; | |
| 50 | +and(1) g3<1>D g3<0,1,0>D 1D { align1 1N }; /* g3 has HSID */ | |
| 51 | +shr(1) g3.1<1>D sr0<0,1,0>D 13D { align1 1N }; | |
| 52 | +and(1) g3.1<1>D g3.1<0,1,0>D 3D { align1 1N }; /* g3.1 has sliceID */ | |
| 53 | +mul(1) g3.5<1>D g3.1<0,1,0>D g1.10<0,1,0>UW { align1 1N }; | |
| 54 | +add(1) g3<1>D g3<0,1,0>D g3.5<0,1,0>D { align1 1N }; /* g3 = sliceID * SubSlicePerSliceCount + HSID */ | |
| 55 | +shr(1) g3.2<1>D sr0<0,1,0>D 8D { align1 1N }; | |
| 56 | +and(1) g3.2<1>D g3.2<0,1,0>D 15D { align1 1N }; /* g3.2 = EUID */ | |
| 57 | +mul(1) g3.4<1>D g3<0,1,0>D 16D { align1 1N }; | |
| 58 | +add(1) g3.2<1>D g3.2<0,1,0>D g3.4<0,1,0>D { align1 1N }; /* g3.2 now points to EU row number (Y-pixel = V address ) in instrumentation surf */ | |
| 59 | + | |
| 60 | +mov(8) g5<1>UD 0x00000000UD { align1 1Q }; | |
| 61 | +and(1) g3.3<1>D sr0<0,1,0>D 7D { align1 1N }; | |
| 62 | +mul(1) g3.3<1>D g3.3<0,1,0>D 4D { align1 1N }; | |
| 63 | + | |
| 64 | +mov(8) g4<1>UD g0<8,8,1>UD { align1 1Q }; /* Initialize message header with g0 */ | |
| 65 | +mov(1) g4<1>UD g3.3<0,1,0>UD { align1 1N }; /* Block offset */ | |
| 66 | +mov(1) g4.1<1>UD g3.2<0,1,0>UD { align1 1N }; /* Block offset */ | |
| 67 | +mov(1) g4.2<1>UD 0x00000003UD { align1 1N }; /* Block size (1 row x 4 bytes) */ | |
| 68 | +and(1) g4.3<1>UD g4.3<0,1,0>UW 0xffffffffUD { align1 1N }; | |
| 69 | + | |
| 70 | +/* Media block read to fetch current value at specified location in instrumentation buffer */ | |
| 71 | +sendc(8) g5<1>UD g4<8,8,1>F 0x02190001 | |
| 72 | + render MsgDesc: media block read MsgCtrl = 0x0 Surface = 1 mlen 1 rlen 1 { align1 1Q }; | |
| 73 | +add(1) g5<1>D g5<0,1,0>D 1D { align1 1N }; | |
| 74 | + | |
| 75 | +/* Media block write for updated value at specified location in instrumentation buffer */ | |
| 76 | +sendc(8) g5<1>UD g4<8,8,1>F 0x040a8001 | |
| 77 | + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 1 mlen 2 rlen 0 { align1 1Q }; | |
| 78 | +/* Delay thread for specified parameter */ | |
| 79 | +add.nz.f0.0(1) g1.2<1>UD g1.2<0,1,0>UD -1D { align1 1N }; | |
| 80 | +(+f0.0) jmpi(1) -4D { align1 WE_all 1N }; | |
| 81 | + | |
| 82 | +/* Store designated "clear GRF" value */ | |
| 83 | +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; | |
| 84 | + | |
| 85 | +/* Initialize looping parameters */ | |
| 86 | +mov(1) a0<1>D 0D { align1 1N }; /* Initialize a0.0:w=0 */ | |
| 87 | +mov(1) a0.4<1>W 127W { align1 1N }; /* Loop count. Each loop contains 16 GRF's */ | |
| 88 | + | |
| 89 | +/* Write 32x16 all "0" block */ | |
| 90 | +mov(8) g2<1>UD g0<8,8,1>UD { align1 1Q }; | |
| 91 | +mov(8) g127<1>UD g0<8,8,1>UD { align1 1Q }; | |
| 92 | +mov(2) g2<1>UD g1<2,2,1>UW { align1 1N }; | |
| 93 | +mov(1) g2.2<1>UD 0x000f000fUD { align1 1N }; /* Block size (16x16) */ | |
| 94 | +and(1) g2.3<1>UD g2.3<0,1,0>UW 0xffffffefUD { align1 1N }; | |
| 95 | +mov(16) g3<1>UD 0x00000000UD { align1 1H }; | |
| 96 | +mov(16) g4<1>UD 0x00000000UD { align1 1H }; | |
| 97 | +mov(16) g5<1>UD 0x00000000UD { align1 1H }; | |
| 98 | +mov(16) g6<1>UD 0x00000000UD { align1 1H }; | |
| 99 | +mov(16) g7<1>UD 0x00000000UD { align1 1H }; | |
| 100 | +mov(16) g8<1>UD 0x00000000UD { align1 1H }; | |
| 101 | +mov(16) g9<1>UD 0x00000000UD { align1 1H }; | |
| 102 | +mov(16) g10<1>UD 0x00000000UD { align1 1H }; | |
| 103 | +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 | |
| 104 | + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; | |
| 105 | +add(1) g2<1>UD g1<0,1,0>UW 0x0010UW { align1 1N }; | |
| 106 | +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 | |
| 107 | + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; | |
| 108 | + | |
| 109 | +/* Now, clear all GRF registers */ | |
| 110 | +add.nz.f0.0(1) a0.4<1>W a0.4<0,1,0>W -1W { align1 1N }; | |
| 111 | +mov(16) g[a0]<1>UW f0.1<0,1,0>UW { align1 1H }; | |
| 112 | +add(1) a0<1>D a0<0,1,0>D 32D { align1 1N }; | |
| 113 | +(+f0.0) jmpi(1) -8D { align1 WE_all 1N }; | |
| 114 | + | |
| 115 | +/* Terminante the thread */ | |
| 116 | +sendc(8) null<1>UD g127<8,8,1>F 0x82000010 | |
| 117 | + thread_spawner MsgDesc: mlen 1 rlen 0 { align1 1Q EOT }; | |
| @@ -66,7 +66,7 @@ static inline int mmio_diff_handler(struct intel_gvt *gvt, · 65 unmodified lines | ||
| 66 | 66 | vreg = vgpu_vreg(param->vgpu, offset); |
| 67 | 67 | |
| 68 | 68 | if (preg != vreg) { |
| 69 | − node = kmalloc(sizeof(*node), GFP_KERNEL); | |
| 69 | + node = kmalloc(sizeof(*node), GFP_ATOMIC); | |
| 70 | 70 | if (!node) |
| 71 | 71 | return -ENOMEM; |
| 72 | 72 | |
| @@ -1726,13 +1726,13 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, · 1725 unmodified lines | ||
| 1726 | 1726 | (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(2); |
| 1727 | 1727 | write_vreg(vgpu, offset, p_data, bytes); |
| 1728 | 1728 | |
| 1729 | − if (data & _MASKED_BIT_ENABLE(1)) { | |
| 1729 | + if (IS_MASKED_BITS_ENABLED(data, 1)) { | |
| 1730 | 1730 | enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); |
| 1731 | 1731 | return 0; |
| 1732 | 1732 | } |
| 1733 | 1733 | |
| 1734 | 1734 | if (IS_COFFEELAKE(vgpu->gvt->gt->i915) && |
| 1735 | − data & _MASKED_BIT_ENABLE(2)) { | |
| 1735 | + IS_MASKED_BITS_ENABLED(data, 2)) { | |
| 1736 | 1736 | enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); |
| 1737 | 1737 | return 0; |
| 1738 | 1738 | } |
| @@ -1741,14 +1741,14 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, · 2 unmodified lines | ||
| 1741 | 1741 | * pvinfo, if not, we will treat this guest as non-gvtg-aware |
| 1742 | 1742 | * guest, and stop emulating its cfg space, mmio, gtt, etc. |
| 1743 | 1743 | */ |
| 1744 | − if (((data & _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)) || | |
| 1745 | − (data & _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE))) | |
| 1746 | − && !vgpu->pv_notified) { | |
| 1744 | + if ((IS_MASKED_BITS_ENABLED(data, GFX_PPGTT_ENABLE) || | |
| 1745 | + IS_MASKED_BITS_ENABLED(data, GFX_RUN_LIST_ENABLE)) && | |
| 1746 | + !vgpu->pv_notified) { | |
| 1747 | 1747 | enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); |
| 1748 | 1748 | return 0; |
| 1749 | 1749 | } |
| 1750 | − if ((data & _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)) | |
| 1751 | − || (data & _MASKED_BIT_DISABLE(GFX_RUN_LIST_ENABLE))) { | |
| 1750 | + if (IS_MASKED_BITS_ENABLED(data, GFX_RUN_LIST_ENABLE) || | |
| 1751 | + IS_MASKED_BITS_DISABLED(data, GFX_RUN_LIST_ENABLE)) { | |
| 1752 | 1752 | enable_execlist = !!(data & GFX_RUN_LIST_ENABLE); |
| 1753 | 1753 | |
| 1754 | 1754 | gvt_dbg_core("EXECLIST %s on ring %s\n", |
| @@ -1809,7 +1809,7 @@ static int ring_reset_ctl_write(struct intel_vgpu *vgpu, · 54 unmodified lines | ||
| 1809 | 1809 | write_vreg(vgpu, offset, p_data, bytes); |
| 1810 | 1810 | data = vgpu_vreg(vgpu, offset); |
| 1811 | 1811 | |
| 1812 | − if (data & _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)) | |
| 1812 | + if (IS_MASKED_BITS_ENABLED(data, RESET_CTL_REQUEST_RESET)) | |
| 1813 | 1813 | data |= RESET_CTL_READY_TO_RESET; |
| 1814 | 1814 | else if (data & _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)) |
| 1815 | 1815 | data &= ~RESET_CTL_READY_TO_RESET; |
| @@ -1827,7 +1827,8 @@ static int csfe_chicken1_mmio_write(struct intel_vgpu *vgpu, · 11 unmodified lines | ||
| 1827 | 1827 | (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(0x18); |
| 1828 | 1828 | write_vreg(vgpu, offset, p_data, bytes); |
| 1829 | 1829 | |
| 1830 | − if (data & _MASKED_BIT_ENABLE(0x10) || data & _MASKED_BIT_ENABLE(0x8)) | |
| 1830 | + if (IS_MASKED_BITS_ENABLED(data, 0x10) || | |
| 1831 | + IS_MASKED_BITS_ENABLED(data, 0x8)) | |
| 1831 | 1832 | enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); |
| 1832 | 1833 | |
| 1833 | 1834 | return 0; |
| @@ -3055,6 +3056,7 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) · 1221 unmodified lines | ||
| 3055 | 3056 | MMIO_D(_MMIO(0x72380), D_SKL_PLUS); |
| 3056 | 3057 | MMIO_D(_MMIO(0x7239c), D_SKL_PLUS); |
| 3057 | 3058 | MMIO_D(_MMIO(_PLANE_SURF_3_A), D_SKL_PLUS); |
| 3059 | + MMIO_D(_MMIO(_PLANE_SURF_3_B), D_SKL_PLUS); | |
| 3058 | 3060 | |
| 3059 | 3061 | MMIO_D(CSR_SSP_BASE, D_SKL_PLUS); |
| 3060 | 3062 | MMIO_D(CSR_HTP_SKL, D_SKL_PLUS); |
| @@ -3131,8 +3133,8 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) · 70 unmodified lines | ||
| 3131 | 3133 | MMIO_DFH(GEN9_WM_CHICKEN3, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, |
| 3132 | 3134 | NULL, NULL); |
| 3133 | 3135 | |
| 3134 | − MMIO_D(GAMT_CHKN_BIT_REG, D_KBL); | |
| 3135 | − MMIO_D(GEN9_CTX_PREEMPT_REG, D_KBL | D_SKL); | |
| 3136 | + MMIO_D(GAMT_CHKN_BIT_REG, D_KBL | D_CFL); | |
| 3137 | + MMIO_D(GEN9_CTX_PREEMPT_REG, D_SKL_PLUS); | |
| 3136 | 3138 | |
| 3137 | 3139 | return 0; |
| 3138 | 3140 | } |
| @@ -54,8 +54,8 @@ bool is_inhibit_context(struct intel_context *ce); · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, |
| 56 | 56 | struct i915_request *req); |
| 57 | −#define IS_RESTORE_INHIBIT(a) \ | |
| 58 | − (_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) == \ | |
| 59 | − ((a) & _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT))) | |
| 57 | + | |
| 58 | +#define IS_RESTORE_INHIBIT(a) \ | |
| 59 | + IS_MASKED_BITS_ENABLED(a, CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) | |
| 60 | 60 | |
| 61 | 61 | #endif |
| @@ -94,6 +94,11 @@ · 93 unmodified lines | ||
| 94 | 94 | #define GFX_MODE_BIT_SET_IN_MASK(val, bit) \ |
| 95 | 95 | ((((bit) & 0xffff0000) == 0) && !!((val) & (((bit) << 16)))) |
| 96 | 96 | |
| 97 | +#define IS_MASKED_BITS_ENABLED(_val, _b) \ | |
| 98 | + (((_val) & _MASKED_BIT_ENABLE(_b)) == _MASKED_BIT_ENABLE(_b)) | |
| 99 | +#define IS_MASKED_BITS_DISABLED(_val, _b) \ | |
| 100 | + ((_val) & _MASKED_BIT_DISABLE(_b)) | |
| 101 | + | |
| 97 | 102 | #define FORCEWAKE_RENDER_GEN9_REG 0xa278 |
| 98 | 103 | #define FORCEWAKE_ACK_RENDER_GEN9_REG 0x0D84 |
| 99 | 104 | #define FORCEWAKE_BLITTER_GEN9_REG 0xa188 |
| @@ -3125,6 +3125,7 @@ static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv) · 3124 unmodified lines | ||
| 3125 | 3125 | |
| 3126 | 3126 | val = I915_READ(GEN11_DE_HPD_IMR); |
| 3127 | 3127 | val &= ~hotplug_irqs; |
| 3128 | + val |= ~enabled_irqs & hotplug_irqs; | |
| 3128 | 3129 | I915_WRITE(GEN11_DE_HPD_IMR, val); |
| 3129 | 3130 | POSTING_READ(GEN11_DE_HPD_IMR); |
| 3130 | 3131 | |
| @@ -269,12 +269,48 @@ static bool exclusive_mmio_access(const struct drm_i915_private *i915) · 268 unmodified lines | ||
| 269 | 269 | return IS_GEN(i915, 7); |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | +static void engine_sample(struct intel_engine_cs *engine, unsigned int period_ns) | |
| 273 | +{ | |
| 274 | + struct intel_engine_pmu *pmu = &engine->pmu; | |
| 275 | + bool busy; | |
| 276 | + u32 val; | |
| 277 | + | |
| 278 | + val = ENGINE_READ_FW(engine, RING_CTL); | |
| 279 | + if (val == 0) /* powerwell off => engine idle */ | |
| 280 | + return; | |
| 281 | + | |
| 282 | + if (val & RING_WAIT) | |
| 283 | + add_sample(&pmu->sample[I915_SAMPLE_WAIT], period_ns); | |
| 284 | + if (val & RING_WAIT_SEMAPHORE) | |
| 285 | + add_sample(&pmu->sample[I915_SAMPLE_SEMA], period_ns); | |
| 286 | + | |
| 287 | + /* No need to sample when busy stats are supported. */ | |
| 288 | + if (intel_engine_supports_stats(engine)) | |
| 289 | + return; | |
| 290 | + | |
| 291 | + /* | |
| 292 | + * While waiting on a semaphore or event, MI_MODE reports the | |
| 293 | + * ring as idle. However, previously using the seqno, and with | |
| 294 | + * execlists sampling, we account for the ring waiting as the | |
| 295 | + * engine being busy. Therefore, we record the sample as being | |
| 296 | + * busy if either waiting or !idle. | |
| 297 | + */ | |
| 298 | + busy = val & (RING_WAIT_SEMAPHORE | RING_WAIT); | |
| 299 | + if (!busy) { | |
| 300 | + val = ENGINE_READ_FW(engine, RING_MI_MODE); | |
| 301 | + busy = !(val & MODE_IDLE); | |
| 302 | + } | |
| 303 | + if (busy) | |
| 304 | + add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns); | |
| 305 | +} | |
| 306 | + | |
| 272 | 307 | static void |
| 273 | 308 | engines_sample(struct intel_gt *gt, unsigned int period_ns) |
| 274 | 309 | { |
| 275 | 310 | struct drm_i915_private *i915 = gt->i915; |
| 276 | 311 | struct intel_engine_cs *engine; |
| 277 | 312 | enum intel_engine_id id; |
| 313 | + unsigned long flags; | |
| 278 | 314 | |
| 279 | 315 | if ((i915->pmu.enable & ENGINE_SAMPLE_MASK) == 0) |
| 280 | 316 | return; |
| @@ -283,53 +319,17 @@ engines_sample(struct intel_gt *gt, unsigned int period_ns) · 2 unmodified lines | ||
| 283 | 319 | return; |
| 284 | 320 | |
| 285 | 321 | for_each_engine(engine, gt, id) { |
| 286 | − struct intel_engine_pmu *pmu = &engine->pmu; | |
| 287 | − spinlock_t *mmio_lock; | |
| 288 | − unsigned long flags; | |
| 289 | − bool busy; | |
| 290 | − u32 val; | |
| 291 | − | |
| 292 | 322 | if (!intel_engine_pm_get_if_awake(engine)) |
| 293 | 323 | continue; |
| 294 | 324 | |
| 295 | − mmio_lock = NULL; | |
| 296 | − if (exclusive_mmio_access(i915)) | |
| 297 | − mmio_lock = &engine->uncore->lock; | |
| 298 | − | |
| 299 | − if (unlikely(mmio_lock)) | |
| 300 | − spin_lock_irqsave(mmio_lock, flags); | |
| 301 | − | |
| 302 | − val = ENGINE_READ_FW(engine, RING_CTL); | |
| 303 | − if (val == 0) /* powerwell off => engine idle */ | |
| 304 | − goto skip; | |
| 305 | − | |
| 306 | − if (val & RING_WAIT) | |
| 307 | − add_sample(&pmu->sample[I915_SAMPLE_WAIT], period_ns); | |
| 308 | − if (val & RING_WAIT_SEMAPHORE) | |
| 309 | − add_sample(&pmu->sample[I915_SAMPLE_SEMA], period_ns); | |
| 310 | − | |
| 311 | − /* No need to sample when busy stats are supported. */ | |
| 312 | − if (intel_engine_supports_stats(engine)) | |
| 313 | − goto skip; | |
| 314 | − | |
| 315 | − /* | |
| 316 | − * While waiting on a semaphore or event, MI_MODE reports the | |
| 317 | − * ring as idle. However, previously using the seqno, and with | |
| 318 | − * execlists sampling, we account for the ring waiting as the | |
| 319 | − * engine being busy. Therefore, we record the sample as being | |
| 320 | − * busy if either waiting or !idle. | |
| 321 | − */ | |
| 322 | − busy = val & (RING_WAIT_SEMAPHORE | RING_WAIT); | |
| 323 | − if (!busy) { | |
| 324 | − val = ENGINE_READ_FW(engine, RING_MI_MODE); | |
| 325 | − busy = !(val & MODE_IDLE); | |
| 325 | + if (exclusive_mmio_access(i915)) { | |
| 326 | + spin_lock_irqsave(&engine->uncore->lock, flags); | |
| 327 | + engine_sample(engine, period_ns); | |
| 328 | + spin_unlock_irqrestore(&engine->uncore->lock, flags); | |
| 329 | + } else { | |
| 330 | + engine_sample(engine, period_ns); | |
| 326 | 331 | } |
| 327 | − if (busy) | |
| 328 | − add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns); | |
| 329 | 332 | |
| 330 | −skip: | |
| 331 | − if (unlikely(mmio_lock)) | |
| 332 | − spin_unlock_irqrestore(mmio_lock, flags); | |
| 333 | 333 | intel_engine_pm_put_async(engine); |
| 334 | 334 | } |
| 335 | 335 | } |
| @@ -42,7 +42,7 @@ enum { · 41 unmodified lines | ||
| 42 | 42 | * active request. |
| 43 | 43 | */ |
| 44 | 44 | #define I915_PRIORITY_UNPREEMPTABLE INT_MAX |
| 45 | −#define I915_PRIORITY_BARRIER INT_MAX | |
| 45 | +#define I915_PRIORITY_BARRIER (I915_PRIORITY_UNPREEMPTABLE - 1) | |
| 46 | 46 | |
| 47 | 47 | struct i915_priolist { |
| 48 | 48 | struct list_head requests[I915_PRIORITY_COUNT]; |
| @@ -7896,7 +7896,7 @@ enum { · 7895 unmodified lines | ||
| 7896 | 7896 | |
| 7897 | 7897 | /* GEN7 chicken */ |
| 7898 | 7898 | #define GEN7_COMMON_SLICE_CHICKEN1 _MMIO(0x7010) |
| 7899 | − #define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1 << 10) | (1 << 26)) | |
| 7899 | + #define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC (1 << 10) | |
| 7900 | 7900 | #define GEN9_RHWO_OPTIMIZATION_DISABLE (1 << 14) |
| 7901 | 7901 | |
| 7902 | 7902 | #define COMMON_SLICE_CHICKEN2 _MMIO(0x7014) |
| @@ -6830,16 +6830,6 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) · 6829 unmodified lines | ||
| 6830 | 6830 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
| 6831 | 6831 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
| 6832 | 6832 | ILK_ELPIN_409_SELECT); |
| 6833 | − I915_WRITE(_3D_CHICKEN2, | |
| 6834 | − _3D_CHICKEN2_WM_READ_PIPELINED << 16 | | |
| 6835 | − _3D_CHICKEN2_WM_READ_PIPELINED); | |
| 6836 | − | |
| 6837 | − /* WaDisableRenderCachePipelinedFlush:ilk */ | |
| 6838 | − I915_WRITE(CACHE_MODE_0, | |
| 6839 | − _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); | |
| 6840 | − | |
| 6841 | − /* WaDisable_RenderCache_OperationalFlush:ilk */ | |
| 6842 | − I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 6843 | 6833 | |
| 6844 | 6834 | g4x_disable_trickle_feed(dev_priv); |
| 6845 | 6835 | |
| @@ -6902,27 +6892,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) · 56 unmodified lines | ||
| 6902 | 6892 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
| 6903 | 6893 | ILK_ELPIN_409_SELECT); |
| 6904 | 6894 | |
| 6905 | − /* WaDisableHiZPlanesWhenMSAAEnabled:snb */ | |
| 6906 | − I915_WRITE(_3D_CHICKEN, | |
| 6907 | − _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); | |
| 6908 | − | |
| 6909 | − /* WaDisable_RenderCache_OperationalFlush:snb */ | |
| 6910 | − I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 6911 | − | |
| 6912 | − /* | |
| 6913 | − * BSpec recoomends 8x4 when MSAA is used, | |
| 6914 | − * however in practice 16x4 seems fastest. | |
| 6915 | − * | |
| 6916 | − * Note that PS/WM thread counts depend on the WIZ hashing | |
| 6917 | − * disable bit, which we don't touch here, but it's good | |
| 6918 | − * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 6919 | − */ | |
| 6920 | − I915_WRITE(GEN6_GT_MODE, | |
| 6921 | − _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); | |
| 6922 | − | |
| 6923 | − I915_WRITE(CACHE_MODE_0, | |
| 6924 | − _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); | |
| 6925 | − | |
| 6926 | 6895 | I915_WRITE(GEN6_UCGCTL1, |
| 6927 | 6896 | I915_READ(GEN6_UCGCTL1) | |
| 6928 | 6897 | GEN6_BLBUNIT_CLOCK_GATE_DISABLE | |
| @@ -6945,18 +6914,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) · 16 unmodified lines | ||
| 6945 | 6914 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | |
| 6946 | 6915 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
| 6947 | 6916 | |
| 6948 | − /* WaStripsFansDisableFastClipPerformanceFix:snb */ | |
| 6949 | − I915_WRITE(_3D_CHICKEN3, | |
| 6950 | − _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL)); | |
| 6951 | − | |
| 6952 | − /* | |
| 6953 | − * Bspec says: | |
| 6954 | − * "This bit must be set if 3DSTATE_CLIP clip mode is set to normal and | |
| 6955 | − * 3DSTATE_SF number of SF output attributes is more than 16." | |
| 6956 | − */ | |
| 6957 | − I915_WRITE(_3D_CHICKEN3, | |
| 6958 | − _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH)); | |
| 6959 | − | |
| 6960 | 6917 | /* |
| 6961 | 6918 | * According to the spec the following bits should be |
| 6962 | 6919 | * set in order to enable memory self-refresh and fbc: |
| @@ -6986,24 +6943,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) · 23 unmodified lines | ||
| 6986 | 6943 | gen6_check_mch_setup(dev_priv); |
| 6987 | 6944 | } |
| 6988 | 6945 | |
| 6989 | −static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) | |
| 6990 | −{ | |
| 6991 | − u32 reg = I915_READ(GEN7_FF_THREAD_MODE); | |
| 6992 | − | |
| 6993 | − /* | |
| 6994 | − * WaVSThreadDispatchOverride:ivb,vlv | |
| 6995 | − * | |
| 6996 | − * This actually overrides the dispatch | |
| 6997 | − * mode for all thread types. | |
| 6998 | − */ | |
| 6999 | − reg &= ~GEN7_FF_SCHED_MASK; | |
| 7000 | − reg |= GEN7_FF_TS_SCHED_HW; | |
| 7001 | − reg |= GEN7_FF_VS_SCHED_HW; | |
| 7002 | − reg |= GEN7_FF_DS_SCHED_HW; | |
| 7003 | − | |
| 7004 | − I915_WRITE(GEN7_FF_THREAD_MODE, reg); | |
| 7005 | −} | |
| 7006 | − | |
| 7007 | 6946 | static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7008 | 6947 | { |
| 7009 | 6948 | /* |
| @@ -7230,45 +7169,10 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) · 220 unmodified lines | ||
| 7230 | 7169 | |
| 7231 | 7170 | static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7232 | 7171 | { |
| 7233 | − /* L3 caching of data atomics doesn't work -- disable it. */ | |
| 7234 | − I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); | |
| 7235 | − I915_WRITE(HSW_ROW_CHICKEN3, | |
| 7236 | − _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE)); | |
| 7237 | − | |
| 7238 | 7172 | /* This is required by WaCatErrorRejectionIssue:hsw */ |
| 7239 | 7173 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, |
| 7240 | − I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | |
| 7241 | − GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | |
| 7242 | − | |
| 7243 | − /* WaVSRefCountFullforceMissDisable:hsw */ | |
| 7244 | − I915_WRITE(GEN7_FF_THREAD_MODE, | |
| 7245 | − I915_READ(GEN7_FF_THREAD_MODE) & ~GEN7_FF_VS_REF_CNT_FFME); | |
| 7246 | − | |
| 7247 | − /* WaDisable_RenderCache_OperationalFlush:hsw */ | |
| 7248 | − I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 7249 | − | |
| 7250 | − /* enable HiZ Raw Stall Optimization */ | |
| 7251 | − I915_WRITE(CACHE_MODE_0_GEN7, | |
| 7252 | − _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE)); | |
| 7253 | − | |
| 7254 | − /* WaDisable4x2SubspanOptimization:hsw */ | |
| 7255 | − I915_WRITE(CACHE_MODE_1, | |
| 7256 | − _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | |
| 7257 | − | |
| 7258 | − /* | |
| 7259 | − * BSpec recommends 8x4 when MSAA is used, | |
| 7260 | − * however in practice 16x4 seems fastest. | |
| 7261 | − * | |
| 7262 | − * Note that PS/WM thread counts depend on the WIZ hashing | |
| 7263 | − * disable bit, which we don't touch here, but it's good | |
| 7264 | − * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 7265 | − */ | |
| 7266 | − I915_WRITE(GEN7_GT_MODE, | |
| 7267 | − _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); | |
| 7268 | − | |
| 7269 | − /* WaSampleCChickenBitEnable:hsw */ | |
| 7270 | − I915_WRITE(HALF_SLICE_CHICKEN3, | |
| 7271 | − _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE)); | |
| 7174 | + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | |
| 7175 | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | |
| 7272 | 7176 | |
| 7273 | 7177 | /* WaSwitchSolVfFArbitrationPriority:hsw */ |
| 7274 | 7178 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
| @@ -7282,32 +7186,11 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) · 7 unmodified lines | ||
| 7282 | 7186 | |
| 7283 | 7187 | I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); |
| 7284 | 7188 | |
| 7285 | − /* WaDisableEarlyCull:ivb */ | |
| 7286 | − I915_WRITE(_3D_CHICKEN3, | |
| 7287 | − _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); | |
| 7288 | − | |
| 7289 | 7189 | /* WaDisableBackToBackFlipFix:ivb */ |
| 7290 | 7190 | I915_WRITE(IVB_CHICKEN3, |
| 7291 | 7191 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
| 7292 | 7192 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
| 7293 | 7193 | |
| 7294 | − /* WaDisablePSDDualDispatchEnable:ivb */ | |
| 7295 | − if (IS_IVB_GT1(dev_priv)) | |
| 7296 | − I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, | |
| 7297 | − _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); | |
| 7298 | − | |
| 7299 | − /* WaDisable_RenderCache_OperationalFlush:ivb */ | |
| 7300 | − I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 7301 | − | |
| 7302 | − /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */ | |
| 7303 | − I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | |
| 7304 | − GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | |
| 7305 | − | |
| 7306 | − /* WaApplyL3ControlAndL3ChickenMode:ivb */ | |
| 7307 | − I915_WRITE(GEN7_L3CNTLREG1, | |
| 7308 | − GEN7_WA_FOR_GEN7_L3_CONTROL); | |
| 7309 | − I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, | |
| 7310 | − GEN7_WA_L3_CHICKEN_MODE); | |
| 7311 | 7194 | if (IS_IVB_GT1(dev_priv)) |
| 7312 | 7195 | I915_WRITE(GEN7_ROW_CHICKEN2, |
| 7313 | 7196 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); |
| @@ -7319,10 +7202,6 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) · 5 unmodified lines | ||
| 7319 | 7202 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); |
| 7320 | 7203 | } |
| 7321 | 7204 | |
| 7322 | − /* WaForceL3Serialization:ivb */ | |
| 7323 | − I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & | |
| 7324 | − ~L3SQ_URB_READ_CAM_MATCH_DISABLE); | |
| 7325 | − | |
| 7326 | 7205 | /* |
| 7327 | 7206 | * According to the spec, bit 13 (RCZUNIT) must be set on IVB. |
| 7328 | 7207 | * This implements the WaDisableRCZUnitClockGating:ivb workaround. |
| @@ -7337,29 +7216,6 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) · 8 unmodified lines | ||
| 7337 | 7216 | |
| 7338 | 7217 | g4x_disable_trickle_feed(dev_priv); |
| 7339 | 7218 | |
| 7340 | − gen7_setup_fixed_func_scheduler(dev_priv); | |
| 7341 | − | |
| 7342 | − if (0) { /* causes HiZ corruption on ivb:gt1 */ | |
| 7343 | − /* enable HiZ Raw Stall Optimization */ | |
| 7344 | − I915_WRITE(CACHE_MODE_0_GEN7, | |
| 7345 | − _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE)); | |
| 7346 | − } | |
| 7347 | − | |
| 7348 | − /* WaDisable4x2SubspanOptimization:ivb */ | |
| 7349 | − I915_WRITE(CACHE_MODE_1, | |
| 7350 | − _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | |
| 7351 | − | |
| 7352 | − /* | |
| 7353 | − * BSpec recommends 8x4 when MSAA is used, | |
| 7354 | − * however in practice 16x4 seems fastest. | |
| 7355 | − * | |
| 7356 | − * Note that PS/WM thread counts depend on the WIZ hashing | |
| 7357 | − * disable bit, which we don't touch here, but it's good | |
| 7358 | − * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 7359 | − */ | |
| 7360 | − I915_WRITE(GEN7_GT_MODE, | |
| 7361 | − _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); | |
| 7362 | − | |
| 7363 | 7219 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); |
| 7364 | 7220 | snpcr &= ~GEN6_MBC_SNPCR_MASK; |
| 7365 | 7221 | snpcr |= GEN6_MBC_SNPCR_MED; |
| @@ -7373,28 +7229,11 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) · 7 unmodified lines | ||
| 7373 | 7229 | |
| 7374 | 7230 | static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7375 | 7231 | { |
| 7376 | − /* WaDisableEarlyCull:vlv */ | |
| 7377 | − I915_WRITE(_3D_CHICKEN3, | |
| 7378 | − _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); | |
| 7379 | − | |
| 7380 | 7232 | /* WaDisableBackToBackFlipFix:vlv */ |
| 7381 | 7233 | I915_WRITE(IVB_CHICKEN3, |
| 7382 | 7234 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
| 7383 | 7235 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
| 7384 | 7236 | |
| 7385 | − /* WaPsdDispatchEnable:vlv */ | |
| 7386 | − /* WaDisablePSDDualDispatchEnable:vlv */ | |
| 7387 | − I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, | |
| 7388 | − _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP | | |
| 7389 | − GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); | |
| 7390 | − | |
| 7391 | − /* WaDisable_RenderCache_OperationalFlush:vlv */ | |
| 7392 | − I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 7393 | − | |
| 7394 | − /* WaForceL3Serialization:vlv */ | |
| 7395 | − I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & | |
| 7396 | − ~L3SQ_URB_READ_CAM_MATCH_DISABLE); | |
| 7397 | − | |
| 7398 | 7237 | /* WaDisableDopClockGating:vlv */ |
| 7399 | 7238 | I915_WRITE(GEN7_ROW_CHICKEN2, |
| 7400 | 7239 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); |
| @@ -7404,8 +7243,6 @@ static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) · 3 unmodified lines | ||
| 7404 | 7243 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
| 7405 | 7244 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); |
| 7406 | 7245 | |
| 7407 | − gen7_setup_fixed_func_scheduler(dev_priv); | |
| 7408 | − | |
| 7409 | 7246 | /* |
| 7410 | 7247 | * According to the spec, bit 13 (RCZUNIT) must be set on IVB. |
| 7411 | 7248 | * This implements the WaDisableRCZUnitClockGating:vlv workaround. |
| @@ -7419,30 +7256,6 @@ static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) · 7 unmodified lines | ||
| 7419 | 7256 | I915_WRITE(GEN7_UCGCTL4, |
| 7420 | 7257 | I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); |
| 7421 | 7258 | |
| 7422 | − /* | |
| 7423 | − * BSpec says this must be set, even though | |
| 7424 | − * WaDisable4x2SubspanOptimization isn't listed for VLV. | |
| 7425 | − */ | |
| 7426 | − I915_WRITE(CACHE_MODE_1, | |
| 7427 | − _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | |
| 7428 | − | |
| 7429 | − /* | |
| 7430 | − * BSpec recommends 8x4 when MSAA is used, | |
| 7431 | − * however in practice 16x4 seems fastest. | |
| 7432 | − * | |
| 7433 | − * Note that PS/WM thread counts depend on the WIZ hashing | |
| 7434 | − * disable bit, which we don't touch here, but it's good | |
| 7435 | − * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | |
| 7436 | − */ | |
| 7437 | − I915_WRITE(GEN7_GT_MODE, | |
| 7438 | − _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); | |
| 7439 | − | |
| 7440 | − /* | |
| 7441 | − * WaIncreaseL3CreditsForVLVB0:vlv | |
| 7442 | − * This is the hardware default actually. | |
| 7443 | − */ | |
| 7444 | − I915_WRITE(GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE); | |
| 7445 | − | |
| 7446 | 7259 | /* |
| 7447 | 7260 | * WaDisableVLVClockGating_VBIIssue:vlv |
| 7448 | 7261 | * Disable clock gating on th GCFG unit to prevent a delay |
| @@ -7495,13 +7308,6 @@ static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) · 46 unmodified lines | ||
| 7495 | 7308 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; |
| 7496 | 7309 | I915_WRITE(DSPCLK_GATE_D, dspclk_gate); |
| 7497 | 7310 | |
| 7498 | − /* WaDisableRenderCachePipelinedFlush */ | |
| 7499 | − I915_WRITE(CACHE_MODE_0, | |
| 7500 | − _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); | |
| 7501 | − | |
| 7502 | − /* WaDisable_RenderCache_OperationalFlush:g4x */ | |
| 7503 | − I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 7504 | − | |
| 7505 | 7311 | g4x_disable_trickle_feed(dev_priv); |
| 7506 | 7312 | } |
| 7507 | 7313 | |
| @@ -7517,11 +7323,6 @@ static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) · 9 unmodified lines | ||
| 7517 | 7323 | intel_uncore_write(uncore, |
| 7518 | 7324 | MI_ARB_STATE, |
| 7519 | 7325 | _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); |
| 7520 | − | |
| 7521 | − /* WaDisable_RenderCache_OperationalFlush:gen4 */ | |
| 7522 | − intel_uncore_write(uncore, | |
| 7523 | − CACHE_MODE_0, | |
| 7524 | − _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 7525 | 7326 | } |
| 7526 | 7327 | |
| 7527 | 7328 | static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) |
| @@ -7534,9 +7335,6 @@ static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) · 6 unmodified lines | ||
| 7534 | 7335 | I915_WRITE(RENCLK_GATE_D2, 0); |
| 7535 | 7336 | I915_WRITE(MI_ARB_STATE, |
| 7536 | 7337 | _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); |
| 7537 | − | |
| 7538 | − /* WaDisable_RenderCache_OperationalFlush:gen4 */ | |
| 7539 | − I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | |
| 7540 | 7338 | } |
| 7541 | 7339 | |
| 7542 | 7340 | static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) |
| @@ -21,6 +21,7 @@ selftest(fence, i915_sw_fence_mock_selftests) · 20 unmodified lines | ||
| 21 | 21 | selftest(scatterlist, scatterlist_mock_selftests) |
| 22 | 22 | selftest(syncmap, i915_syncmap_mock_selftests) |
| 23 | 23 | selftest(uncore, intel_uncore_mock_selftests) |
| 24 | +selftest(ring, intel_ring_mock_selftests) | |
| 24 | 25 | selftest(engine, intel_engine_cs_mock_selftests) |
| 25 | 26 | selftest(timelines, intel_timeline_mock_selftests) |
| 26 | 27 | selftest(requests, i915_request_mock_selftests) |
| @@ -812,7 +812,7 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, · 811 unmodified lines | ||
| 812 | 812 | struct drm_crtc *crtc = &pipe->crtc; |
| 813 | 813 | struct drm_plane *plane = &pipe->plane; |
| 814 | 814 | struct drm_device *drm = crtc->dev; |
| 815 | − struct mcde *mcde = drm->dev_private; | |
| 815 | + struct mcde *mcde = to_mcde(drm); | |
| 816 | 816 | const struct drm_display_mode *mode = &cstate->mode; |
| 817 | 817 | struct drm_framebuffer *fb = plane->state->fb; |
| 818 | 818 | u32 format = fb->format->format; |
| @@ -209,7 +209,6 @@ static int mcde_modeset_init(struct drm_device *drm) · 208 unmodified lines | ||
| 209 | 209 | |
| 210 | 210 | drm_mode_config_reset(drm); |
| 211 | 211 | drm_kms_helper_poll_init(drm); |
| 212 | − drm_fbdev_generic_setup(drm, 32); | |
| 213 | 212 | |
| 214 | 213 | return 0; |
| 215 | 214 | } |
| @@ -264,6 +263,8 @@ static int mcde_drm_bind(struct device *dev) · 48 unmodified lines | ||
| 264 | 263 | if (ret < 0) |
| 265 | 264 | goto unbind; |
| 266 | 265 | |
| 266 | + drm_fbdev_generic_setup(drm, 32); | |
| 267 | + | |
| 267 | 268 | return 0; |
| 268 | 269 | |
| 269 | 270 | unbind: |
| @@ -408,7 +408,7 @@ a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) · 407 unmodified lines | ||
| 408 | 408 | struct msm_gem_address_space *aspace; |
| 409 | 409 | |
| 410 | 410 | aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M, |
| 411 | − SZ_16M + 0xfff * SZ_64K); | |
| 411 | + 0xfff * SZ_64K); | |
| 412 | 412 | |
| 413 | 413 | if (IS_ERR(aspace) && !IS_ERR(mmu)) |
| 414 | 414 | mmu->funcs->destroy(mmu); |
| @@ -1121,7 +1121,7 @@ static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu) · 1120 unmodified lines | ||
| 1121 | 1121 | return -ENODEV; |
| 1122 | 1122 | |
| 1123 | 1123 | mmu = msm_iommu_new(gmu->dev, domain); |
| 1124 | − gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x7fffffff); | |
| 1124 | + gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x80000000); | |
| 1125 | 1125 | if (IS_ERR(gmu->aspace)) { |
| 1126 | 1126 | iommu_domain_free(domain); |
| 1127 | 1127 | return PTR_ERR(gmu->aspace); |
| @@ -893,8 +893,8 @@ static const struct adreno_gpu_funcs funcs = { · 892 unmodified lines | ||
| 893 | 893 | #if defined(CONFIG_DRM_MSM_GPU_STATE) |
| 894 | 894 | .gpu_state_get = a6xx_gpu_state_get, |
| 895 | 895 | .gpu_state_put = a6xx_gpu_state_put, |
| 896 | − .create_address_space = adreno_iommu_create_address_space, | |
| 897 | 896 | #endif |
| 897 | + .create_address_space = adreno_iommu_create_address_space, | |
| 898 | 898 | }, |
| 899 | 899 | .get_timestamp = a6xx_get_timestamp, |
| 900 | 900 | }; |
| @@ -194,7 +194,7 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, · 193 unmodified lines | ||
| 194 | 194 | struct msm_gem_address_space *aspace; |
| 195 | 195 | |
| 196 | 196 | aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M, |
| 197 | − 0xfffffff); | |
| 197 | + 0xffffffff - SZ_16M); | |
| 198 | 198 | |
| 199 | 199 | if (IS_ERR(aspace) && !IS_ERR(mmu)) |
| 200 | 200 | mmu->funcs->destroy(mmu); |
| @@ -521,7 +521,7 @@ static struct msm_display_topology dpu_encoder_get_topology( · 520 unmodified lines | ||
| 521 | 521 | struct dpu_kms *dpu_kms, |
| 522 | 522 | struct drm_display_mode *mode) |
| 523 | 523 | { |
| 524 | − struct msm_display_topology topology; | |
| 524 | + struct msm_display_topology topology = {0}; | |
| 525 | 525 | int i, intf_count = 0; |
| 526 | 526 | |
| 527 | 527 | for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) |
| @@ -537,7 +537,8 @@ static struct msm_display_topology dpu_encoder_get_topology( · 9 unmodified lines | ||
| 537 | 537 | * 1 LM, 1 INTF |
| 538 | 538 | * 2 LM, 1 INTF (stream merge to support high resolution interfaces) |
| 539 | 539 | * |
| 540 | − * Adding color blocks only to primary interface | |
| 540 | + * Adding color blocks only to primary interface if available in | |
| 541 | + * sufficient number | |
| 541 | 542 | */ |
| 542 | 543 | if (intf_count == 2) |
| 543 | 544 | topology.num_lm = 2; |
| @@ -546,8 +547,11 @@ static struct msm_display_topology dpu_encoder_get_topology( · 2 unmodified lines | ||
| 546 | 547 | else |
| 547 | 548 | topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; |
| 548 | 549 | |
| 549 | − if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) | |
| 550 | − topology.num_dspp = topology.num_lm; | |
| 550 | + if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { | |
| 551 | + if (dpu_kms->catalog->dspp && | |
| 552 | + (dpu_kms->catalog->dspp_count >= topology.num_lm)) | |
| 553 | + topology.num_dspp = topology.num_lm; | |
| 554 | + } | |
| 551 | 555 | |
| 552 | 556 | topology.num_enc = 0; |
| 553 | 557 | topology.num_intf = intf_count; |
| @@ -2136,7 +2140,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, · 1582 unmodified lines | ||
| 2136 | 2140 | |
| 2137 | 2141 | dpu_enc = to_dpu_encoder_virt(enc); |
| 2138 | 2142 | |
| 2139 | − mutex_init(&dpu_enc->enc_lock); | |
| 2140 | 2143 | ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); |
| 2141 | 2144 | if (ret) |
| 2142 | 2145 | goto fail; |
| @@ -2151,7 +2154,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, · 8 unmodified lines | ||
| 2151 | 2154 | 0); |
| 2152 | 2155 | |
| 2153 | 2156 | |
| 2154 | − mutex_init(&dpu_enc->rc_lock); | |
| 2155 | 2157 | INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, |
| 2156 | 2158 | dpu_encoder_off_work); |
| 2157 | 2159 | dpu_enc->idle_timeout = IDLE_TIMEOUT; |
| @@ -2183,7 +2185,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 25 unmodified lines | ||
| 2183 | 2185 | |
| 2184 | 2186 | dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); |
| 2185 | 2187 | if (!dpu_enc) |
| 2186 | − return ERR_PTR(ENOMEM); | |
| 2188 | + return ERR_PTR(-ENOMEM); | |
| 2187 | 2189 | |
| 2188 | 2190 | rc = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, |
| 2189 | 2191 | drm_enc_mode, NULL); |
| @@ -2196,6 +2198,8 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 6 unmodified lines | ||
| 2196 | 2198 | |
| 2197 | 2199 | spin_lock_init(&dpu_enc->enc_spinlock); |
| 2198 | 2200 | dpu_enc->enabled = false; |
| 2201 | + mutex_init(&dpu_enc->enc_lock); | |
| 2202 | + mutex_init(&dpu_enc->rc_lock); | |
| 2199 | 2203 | |
| 2200 | 2204 | return &dpu_enc->base; |
| 2201 | 2205 | } |
| @@ -780,7 +780,7 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) · 779 unmodified lines | ||
| 780 | 780 | |
| 781 | 781 | mmu = msm_iommu_new(dpu_kms->dev->dev, domain); |
| 782 | 782 | aspace = msm_gem_address_space_create(mmu, "dpu1", |
| 783 | − 0x1000, 0xfffffff); | |
| 783 | + 0x1000, 0x100000000 - 0x1000); | |
| 784 | 784 | |
| 785 | 785 | if (IS_ERR(aspace)) { |
| 786 | 786 | mmu->funcs->destroy(mmu); |
| @@ -514,7 +514,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) · 513 unmodified lines | ||
| 514 | 514 | config->iommu); |
| 515 | 515 | |
| 516 | 516 | aspace = msm_gem_address_space_create(mmu, |
| 517 | − "mdp4", 0x1000, 0xffffffff); | |
| 517 | + "mdp4", 0x1000, 0x100000000 - 0x1000); | |
| 518 | 518 | |
| 519 | 519 | if (IS_ERR(aspace)) { |
| 520 | 520 | if (!IS_ERR(mmu)) |
| @@ -633,7 +633,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) · 632 unmodified lines | ||
| 633 | 633 | mmu = msm_iommu_new(iommu_dev, config->platform.iommu); |
| 634 | 634 | |
| 635 | 635 | aspace = msm_gem_address_space_create(mmu, "mdp5", |
| 636 | − 0x1000, 0xffffffff); | |
| 636 | + 0x1000, 0x100000000 - 0x1000); | |
| 637 | 637 | |
| 638 | 638 | if (IS_ERR(aspace)) { |
| 639 | 639 | if (!IS_ERR(mmu)) |
| @@ -71,8 +71,10 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, · 70 unmodified lines | ||
| 71 | 71 | queue->flags = flags; |
| 72 | 72 | |
| 73 | 73 | if (priv->gpu) { |
| 74 | − if (prio >= priv->gpu->nr_rings) | |
| 74 | + if (prio >= priv->gpu->nr_rings) { | |
| 75 | + kfree(queue); | |
| 75 | 76 | return -EINVAL; |
| 77 | + } | |
| 76 | 78 | |
| 77 | 79 | queue->prio = prio; |
| 78 | 80 | } |
| @@ -2495,6 +2495,7 @@ static const struct panel_desc logicpd_type_28 = { · 2494 unmodified lines | ||
| 2495 | 2495 | .bus_format = MEDIA_BUS_FMT_RGB888_1X24, |
| 2496 | 2496 | .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE | |
| 2497 | 2497 | DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE, |
| 2498 | + .connector_type = DRM_MODE_CONNECTOR_DPI, | |
| 2498 | 2499 | }; |
| 2499 | 2500 | |
| 2500 | 2501 | static const struct panel_desc mitsubishi_aa070mc01 = { |
| @@ -2663,6 +2664,7 @@ static const struct panel_desc newhaven_nhd_43_480272ef_atxl = { · 162 unmodified lines | ||
| 2663 | 2664 | .bus_format = MEDIA_BUS_FMT_RGB888_1X24, |
| 2664 | 2665 | .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE | |
| 2665 | 2666 | DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE, |
| 2667 | + .connector_type = DRM_MODE_CONNECTOR_DPI, | |
| 2666 | 2668 | }; |
| 2667 | 2669 | |
| 2668 | 2670 | static const struct display_timing nlt_nl192108ac18_02d_timing = { |
| @@ -2127,7 +2127,7 @@ static int ni_init_smc_spll_table(struct radeon_device *rdev) · 2126 unmodified lines | ||
| 2127 | 2127 | if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT)) |
| 2128 | 2128 | ret = -EINVAL; |
| 2129 | 2129 | |
| 2130 | − if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT)) | |
| 2130 | + if (fb_div & ~(SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT)) | |
| 2131 | 2131 | ret = -EINVAL; |
| 2132 | 2132 | |
| 2133 | 2133 | if (clk_v & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT)) |
| @@ -31,6 +31,7 @@ config DRM_RCAR_DW_HDMI · 30 unmodified lines | ||
| 31 | 31 | config DRM_RCAR_LVDS |
| 32 | 32 | tristate "R-Car DU LVDS Encoder Support" |
| 33 | 33 | depends on DRM && DRM_BRIDGE && OF |
| 34 | + select DRM_KMS_HELPER | |
| 34 | 35 | select DRM_PANEL |
| 35 | 36 | select OF_FLATTREE |
| 36 | 37 | select OF_OVERLAY |
| @@ -259,9 +259,8 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force) · 258 unmodified lines | ||
| 259 | 259 | struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); |
| 260 | 260 | unsigned long reg; |
| 261 | 261 | |
| 262 | − if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg, | |
| 263 | − reg & SUN4I_HDMI_HPD_HIGH, | |
| 264 | − 0, 500000)) { | |
| 262 | + reg = readl(hdmi->base + SUN4I_HDMI_HPD_REG); | |
| 263 | + if (reg & SUN4I_HDMI_HPD_HIGH) { | |
| 265 | 264 | cec_phys_addr_invalidate(hdmi->cec_adap); |
| 266 | 265 | return connector_status_disconnected; |
| 267 | 266 | } |
| @@ -363,6 +363,19 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, · 362 unmodified lines | ||
| 363 | 363 | mixer->engine.ops = &sun8i_engine_ops; |
| 364 | 364 | mixer->engine.node = dev->of_node; |
| 365 | 365 | |
| 366 | + if (of_find_property(dev->of_node, "iommus", NULL)) { | |
| 367 | + /* | |
| 368 | + * This assume we have the same DMA constraints for | |
| 369 | + * all our the mixers in our pipeline. This sounds | |
| 370 | + * bad, but it has always been the case for us, and | |
| 371 | + * DRM doesn't do per-device allocation either, so we | |
| 372 | + * would need to fix DRM first... | |
| 373 | + */ | |
| 374 | + ret = of_dma_configure(drm->dev, dev->of_node, true); | |
| 375 | + if (ret) | |
| 376 | + return ret; | |
| 377 | + } | |
| 378 | + | |
| 366 | 379 | /* |
| 367 | 380 | * While this function can fail, we shouldn't do anything |
| 368 | 381 | * if this happens. Some early DE2 DT entries don't provide |
| @@ -957,6 +957,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, · 956 unmodified lines | ||
| 957 | 957 | } |
| 958 | 958 | |
| 959 | 959 | drm_plane_helper_add(&plane->base, &tegra_cursor_plane_helper_funcs); |
| 960 | + drm_plane_create_zpos_immutable_property(&plane->base, 255); | |
| 960 | 961 | |
| 961 | 962 | return &plane->base; |
| 962 | 963 | } |
| @@ -149,7 +149,9 @@ int tegra_display_hub_prepare(struct tegra_display_hub *hub) · 148 unmodified lines | ||
| 149 | 149 | for (i = 0; i < hub->soc->num_wgrps; i++) { |
| 150 | 150 | struct tegra_windowgroup *wgrp = &hub->wgrps[i]; |
| 151 | 151 | |
| 152 | − tegra_windowgroup_enable(wgrp); | |
| 152 | + /* Skip orphaned window group whose parent DC is disabled */ | |
| 153 | + if (wgrp->parent) | |
| 154 | + tegra_windowgroup_enable(wgrp); | |
| 153 | 155 | } |
| 154 | 156 | |
| 155 | 157 | return 0; |
| @@ -166,7 +168,9 @@ void tegra_display_hub_cleanup(struct tegra_display_hub *hub) · 10 unmodified lines | ||
| 166 | 168 | for (i = 0; i < hub->soc->num_wgrps; i++) { |
| 167 | 169 | struct tegra_windowgroup *wgrp = &hub->wgrps[i]; |
| 168 | 170 | |
| 169 | − tegra_windowgroup_disable(wgrp); | |
| 171 | + /* Skip orphaned window group whose parent DC is disabled */ | |
| 172 | + if (wgrp->parent) | |
| 173 | + tegra_windowgroup_disable(wgrp); | |
| 170 | 174 | } |
| 171 | 175 | } |
| 172 | 176 | |
| @@ -944,6 +948,15 @@ static int tegra_display_hub_probe(struct platform_device *pdev) · 771 unmodified lines | ||
| 944 | 948 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", |
| 945 | 949 | err); |
| 946 | 950 | |
| 951 | + err = devm_of_platform_populate(&pdev->dev); | |
| 952 | + if (err < 0) | |
| 953 | + goto unregister; | |
| 954 | + | |
| 955 | + return err; | |
| 956 | + | |
| 957 | +unregister: | |
| 958 | + host1x_client_unregister(&hub->client); | |
| 959 | + pm_runtime_disable(&pdev->dev); | |
| 947 | 960 | return err; |
| 948 | 961 | } |
| 949 | 962 | |
| @@ -883,8 +883,10 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, · 882 unmodified lines | ||
| 883 | 883 | if (!fence) |
| 884 | 884 | return 0; |
| 885 | 885 | |
| 886 | − if (no_wait_gpu) | |
| 886 | + if (no_wait_gpu) { | |
| 887 | + dma_fence_put(fence); | |
| 887 | 888 | return -EBUSY; |
| 889 | + } | |
| 888 | 890 | |
| 889 | 891 | dma_resv_add_shared_fence(bo->base.resv, fence); |
| 890 | 892 | |
| @@ -300,8 +300,10 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, · 299 unmodified lines | ||
| 300 | 300 | break; |
| 301 | 301 | case -EBUSY: |
| 302 | 302 | case -ERESTARTSYS: |
| 303 | + dma_fence_put(moving); | |
| 303 | 304 | return VM_FAULT_NOPAGE; |
| 304 | 305 | default: |
| 306 | + dma_fence_put(moving); | |
| 305 | 307 | return VM_FAULT_SIGBUS; |
| 306 | 308 | } |
| 307 | 309 | |
| @@ -686,8 +686,17 @@ EXPORT_SYMBOL(host1x_driver_register_full); · 685 unmodified lines | ||
| 686 | 686 | */ |
| 687 | 687 | void host1x_driver_unregister(struct host1x_driver *driver) |
| 688 | 688 | { |
| 689 | + struct host1x *host1x; | |
| 690 | + | |
| 689 | 691 | driver_unregister(&driver->driver); |
| 690 | 692 | |
| 693 | + mutex_lock(&devices_lock); | |
| 694 | + | |
| 695 | + list_for_each_entry(host1x, &devices, list) | |
| 696 | + host1x_detach_driver(host1x, driver); | |
| 697 | + | |
| 698 | + mutex_unlock(&devices_lock); | |
| 699 | + | |
| 691 | 700 | mutex_lock(&drivers_lock); |
| 692 | 701 | list_del_init(&driver->list); |
| 693 | 702 | mutex_unlock(&drivers_lock); |
| @@ -468,11 +468,18 @@ static int host1x_probe(struct platform_device *pdev) · 467 unmodified lines | ||
| 468 | 468 | |
| 469 | 469 | err = host1x_register(host); |
| 470 | 470 | if (err < 0) |
| 471 | − goto deinit_intr; | |
| 471 | + goto deinit_debugfs; | |
| 472 | + | |
| 473 | + err = devm_of_platform_populate(&pdev->dev); | |
| 474 | + if (err < 0) | |
| 475 | + goto unregister; | |
| 472 | 476 | |
| 473 | 477 | return 0; |
| 474 | 478 | |
| 475 | −deinit_intr: | |
| 479 | +unregister: | |
| 480 | + host1x_unregister(host); | |
| 481 | +deinit_debugfs: | |
| 482 | + host1x_debug_deinit(host); | |
| 476 | 483 | host1x_intr_deinit(host); |
| 477 | 484 | deinit_syncpt: |
| 478 | 485 | host1x_syncpt_deinit(host); |
| @@ -1368,7 +1368,7 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper, · 1367 unmodified lines | ||
| 1368 | 1368 | * Write dump contents to the page. No need to synchronize; panic should |
| 1369 | 1369 | * be single-threaded. |
| 1370 | 1370 | */ |
| 1371 | − kmsg_dump_get_buffer(dumper, true, hv_panic_page, HV_HYP_PAGE_SIZE, | |
| 1371 | + kmsg_dump_get_buffer(dumper, false, hv_panic_page, HV_HYP_PAGE_SIZE, | |
| 1372 | 1372 | &bytes_written); |
| 1373 | 1373 | if (bytes_written) |
| 1374 | 1374 | hyperv_report_panic_msg(panic_pa, bytes_written); |
| @@ -883,7 +883,7 @@ static int acpi_power_meter_add(struct acpi_device *device) · 882 unmodified lines | ||
| 883 | 883 | |
| 884 | 884 | res = setup_attrs(resource); |
| 885 | 885 | if (res) |
| 886 | − goto exit_free; | |
| 886 | + goto exit_free_capability; | |
| 887 | 887 | |
| 888 | 888 | resource->hwmon_dev = hwmon_device_register(&device->dev); |
| 889 | 889 | if (IS_ERR(resource->hwmon_dev)) { |
| @@ -896,6 +896,8 @@ static int acpi_power_meter_add(struct acpi_device *device) · 6 unmodified lines | ||
| 896 | 896 | |
| 897 | 897 | exit_remove: |
| 898 | 898 | remove_attrs(resource); |
| 899 | +exit_free_capability: | |
| 900 | + free_capabilities(resource); | |
| 899 | 901 | exit_free: |
| 900 | 902 | kfree(resource); |
| 901 | 903 | exit: |
| @@ -64,7 +64,7 @@ static const struct pvt_sensor_info pvt_info[] = { · 63 unmodified lines | ||
| 64 | 64 | * 48380, |
| 65 | 65 | * where T = [-48380, 147438] mC and N = [0, 1023]. |
| 66 | 66 | */ |
| 67 | −static const struct pvt_poly poly_temp_to_N = { | |
| 67 | +static const struct pvt_poly __maybe_unused poly_temp_to_N = { | |
| 68 | 68 | .total_divider = 10000, |
| 69 | 69 | .terms = { |
| 70 | 70 | {4, 18322, 10000, 10000}, |
| @@ -96,7 +96,7 @@ static const struct pvt_poly poly_N_to_temp = { · 25 unmodified lines | ||
| 96 | 96 | * N = (18658e-3*V - 11572) / 10, |
| 97 | 97 | * V = N * 10^5 / 18658 + 11572 * 10^4 / 18658. |
| 98 | 98 | */ |
| 99 | −static const struct pvt_poly poly_volt_to_N = { | |
| 99 | +static const struct pvt_poly __maybe_unused poly_volt_to_N = { | |
| 100 | 100 | .total_divider = 10, |
| 101 | 101 | .terms = { |
| 102 | 102 | {1, 18658, 1000, 1}, |
| @@ -300,12 +300,12 @@ static irqreturn_t pvt_soft_isr(int irq, void *data) · 197 unmodified lines | ||
| 300 | 300 | return IRQ_HANDLED; |
| 301 | 301 | } |
| 302 | 302 | |
| 303 | −inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) | |
| 303 | +static inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) | |
| 304 | 304 | { |
| 305 | 305 | return 0644; |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | −inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) | |
| 308 | +static inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) | |
| 309 | 309 | { |
| 310 | 310 | return 0444; |
| 311 | 311 | } |
| @@ -462,12 +462,12 @@ static irqreturn_t pvt_hard_isr(int irq, void *data) · 150 unmodified lines | ||
| 462 | 462 | |
| 463 | 463 | #define pvt_soft_isr NULL |
| 464 | 464 | |
| 465 | −inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) | |
| 465 | +static inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) | |
| 466 | 466 | { |
| 467 | 467 | return 0; |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | −inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) | |
| 470 | +static inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) | |
| 471 | 471 | { |
| 472 | 472 | return 0; |
| 473 | 473 | } |
| @@ -38,8 +38,9 @@ static const u8 MAX6697_REG_CRIT[] = { · 37 unmodified lines | ||
| 38 | 38 | * Map device tree / platform data register bit map to chip bit map. |
| 39 | 39 | * Applies to alert register and over-temperature register. |
| 40 | 40 | */ |
| 41 | −#define MAX6697_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ | |
| 41 | +#define MAX6697_ALERT_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ | |
| 42 | 42 | (((reg) & 0x01) << 6) | ((reg) & 0x80)) |
| 43 | +#define MAX6697_OVERT_MAP_BITS(reg) (((reg) >> 1) | (((reg) & 0x01) << 7)) | |
| 43 | 44 | |
| 44 | 45 | #define MAX6697_REG_STAT(n) (0x44 + (n)) |
| 45 | 46 | |
| @@ -562,12 +563,12 @@ static int max6697_init_chip(struct max6697_data *data, · 516 unmodified lines | ||
| 562 | 563 | return ret; |
| 563 | 564 | |
| 564 | 565 | ret = i2c_smbus_write_byte_data(client, MAX6697_REG_ALERT_MASK, |
| 565 | − MAX6697_MAP_BITS(pdata->alert_mask)); | |
| 566 | + MAX6697_ALERT_MAP_BITS(pdata->alert_mask)); | |
| 566 | 567 | if (ret < 0) |
| 567 | 568 | return ret; |
| 568 | 569 | |
| 569 | 570 | ret = i2c_smbus_write_byte_data(client, MAX6697_REG_OVERT_MASK, |
| 570 | − MAX6697_MAP_BITS(pdata->over_temperature_mask)); | |
| 571 | + MAX6697_OVERT_MAP_BITS(pdata->over_temperature_mask)); | |
| 571 | 572 | if (ret < 0) |
| 572 | 573 | return ret; |
| 573 | 574 | |
| @@ -71,7 +71,7 @@ config SENSORS_IR35221 · 70 unmodified lines | ||
| 71 | 71 | Infineon IR35221 controller. |
| 72 | 72 | |
| 73 | 73 | This driver can also be built as a module. If so, the module will |
| 74 | − be called ir35521. | |
| 74 | + be called ir35221. | |
| 75 | 75 | |
| 76 | 76 | config SENSORS_IR38064 |
| 77 | 77 | tristate "Infineon IR38064" |
| @@ -1869,7 +1869,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client, · 1868 unmodified lines | ||
| 1869 | 1869 | struct pmbus_sensor *sensor; |
| 1870 | 1870 | |
| 1871 | 1871 | sensor = pmbus_add_sensor(data, "fan", "target", index, page, |
| 1872 | − PMBUS_VIRT_FAN_TARGET_1 + id, 0xff, PSC_FAN, | |
| 1872 | + 0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN, | |
| 1873 | 1873 | false, false, true); |
| 1874 | 1874 | |
| 1875 | 1875 | if (!sensor) |
| @@ -1880,14 +1880,14 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client, · 4 unmodified lines | ||
| 1880 | 1880 | return 0; |
| 1881 | 1881 | |
| 1882 | 1882 | sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, |
| 1883 | − PMBUS_VIRT_PWM_1 + id, 0xff, PSC_PWM, | |
| 1883 | + 0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM, | |
| 1884 | 1884 | false, false, true); |
| 1885 | 1885 | |
| 1886 | 1886 | if (!sensor) |
| 1887 | 1887 | return -ENOMEM; |
| 1888 | 1888 | |
| 1889 | 1889 | sensor = pmbus_add_sensor(data, "pwm", "enable", index, page, |
| 1890 | − PMBUS_VIRT_PWM_ENABLE_1 + id, 0xff, PSC_PWM, | |
| 1890 | + 0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM, | |
| 1891 | 1891 | true, false, false); |
| 1892 | 1892 | |
| 1893 | 1893 | if (!sensor) |
| @@ -1929,7 +1929,7 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, · 35 unmodified lines | ||
| 1929 | 1929 | continue; |
| 1930 | 1930 | |
| 1931 | 1931 | if (pmbus_add_sensor(data, "fan", "input", index, |
| 1932 | − page, pmbus_fan_registers[f], 0xff, | |
| 1932 | + page, 0xff, pmbus_fan_registers[f], | |
| 1933 | 1933 | PSC_FAN, true, true, true) == NULL) |
| 1934 | 1934 | return -ENOMEM; |
| 1935 | 1935 | |
| @@ -34,7 +34,7 @@ struct stp_policy_node { · 33 unmodified lines | ||
| 34 | 34 | unsigned int first_channel; |
| 35 | 35 | unsigned int last_channel; |
| 36 | 36 | /* this is the one that's exposed to the attributes */ |
| 37 | − unsigned char priv[0]; | |
| 37 | + unsigned char priv[]; | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | void *stp_policy_node_priv(struct stp_policy_node *pn) |
| @@ -23,7 +23,7 @@ void *stp_policy_node_priv(struct stp_policy_node *pn); · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | struct stp_master { |
| 25 | 25 | unsigned int nr_free; |
| 26 | − unsigned long chan_map[0]; | |
| 26 | + unsigned long chan_map[]; | |
| 27 | 27 | }; |
| 28 | 28 | |
| 29 | 29 | struct stm_device { |
| @@ -42,7 +42,7 @@ struct stm_device { · 12 unmodified lines | ||
| 42 | 42 | const struct config_item_type *pdrv_node_type; |
| 43 | 43 | /* master allocation */ |
| 44 | 44 | spinlock_t mc_lock; |
| 45 | − struct stp_master *masters[0]; | |
| 45 | + struct stp_master *masters[]; | |
| 46 | 46 | }; |
| 47 | 47 | |
| 48 | 48 | #define to_stm_device(_d) \ |
| @@ -113,11 +113,18 @@ config I2C_STUB · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | config I2C_SLAVE |
| 115 | 115 | bool "I2C slave support" |
| 116 | + help | |
| 117 | + This enables Linux to act as an I2C slave device. Note that your I2C | |
| 118 | + bus master driver also needs to support this functionality. Please | |
| 119 | + read Documentation/i2c/slave-interface.rst for further details. | |
| 116 | 120 | |
| 117 | 121 | if I2C_SLAVE |
| 118 | 122 | |
| 119 | 123 | config I2C_SLAVE_EEPROM |
| 120 | 124 | tristate "I2C eeprom slave driver" |
| 125 | + help | |
| 126 | + This backend makes Linux behave like an I2C EEPROM. Please read | |
| 127 | + Documentation/i2c/slave-eeprom-backend.rst for further details. | |
| 121 | 128 | |
| 122 | 129 | endif |
| 123 | 130 | |
| @@ -314,7 +314,8 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, · 313 unmodified lines | ||
| 314 | 314 | DEB2("BUS ERROR - SDA Stuck low\n"); |
| 315 | 315 | pca_reset(adap); |
| 316 | 316 | goto out; |
| 317 | − case 0x90: /* Bus error - SCL stuck low */ | |
| 317 | + case 0x78: /* Bus error - SCL stuck low (PCA9665) */ | |
| 318 | + case 0x90: /* Bus error - SCL stuck low (PCA9564) */ | |
| 318 | 319 | DEB2("BUS ERROR - SCL Stuck low\n"); |
| 319 | 320 | pca_reset(adap); |
| 320 | 321 | goto out; |
| @@ -286,10 +286,8 @@ int i2c_dw_acpi_configure(struct device *device) · 285 unmodified lines | ||
| 286 | 286 | } |
| 287 | 287 | EXPORT_SYMBOL_GPL(i2c_dw_acpi_configure); |
| 288 | 288 | |
| 289 | −void i2c_dw_acpi_adjust_bus_speed(struct device *device) | |
| 289 | +static u32 i2c_dw_acpi_round_bus_speed(struct device *device) | |
| 290 | 290 | { |
| 291 | − struct dw_i2c_dev *dev = dev_get_drvdata(device); | |
| 292 | − struct i2c_timings *t = &dev->timings; | |
| 293 | 291 | u32 acpi_speed; |
| 294 | 292 | int i; |
| 295 | 293 | |
| @@ -300,9 +298,22 @@ void i2c_dw_acpi_adjust_bus_speed(struct device *device) · 4 unmodified lines | ||
| 300 | 298 | */ |
| 301 | 299 | for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) { |
| 302 | 300 | if (acpi_speed >= supported_speeds[i]) |
| 303 | − break; | |
| 301 | + return supported_speeds[i]; | |
| 304 | 302 | } |
| 305 | − acpi_speed = i < ARRAY_SIZE(supported_speeds) ? supported_speeds[i] : 0; | |
| 303 | + | |
| 304 | + return 0; | |
| 305 | +} | |
| 306 | + | |
| 307 | +#else /* CONFIG_ACPI */ | |
| 308 | + | |
| 309 | +static inline u32 i2c_dw_acpi_round_bus_speed(struct device *device) { return 0; } | |
| 310 | + | |
| 311 | +#endif /* CONFIG_ACPI */ | |
| 312 | + | |
| 313 | +void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev) | |
| 314 | +{ | |
| 315 | + u32 acpi_speed = i2c_dw_acpi_round_bus_speed(dev->dev); | |
| 316 | + struct i2c_timings *t = &dev->timings; | |
| 306 | 317 | |
| 307 | 318 | /* |
| 308 | 319 | * Find bus speed from the "clock-frequency" device property, ACPI |
| @@ -315,9 +326,7 @@ void i2c_dw_acpi_adjust_bus_speed(struct device *device) · 6 unmodified lines | ||
| 315 | 326 | else |
| 316 | 327 | t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; |
| 317 | 328 | } |
| 318 | −EXPORT_SYMBOL_GPL(i2c_dw_acpi_adjust_bus_speed); | |
| 319 | − | |
| 320 | −#endif /* CONFIG_ACPI */ | |
| 329 | +EXPORT_SYMBOL_GPL(i2c_dw_adjust_bus_speed); | |
| 321 | 330 | |
| 322 | 331 | u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) |
| 323 | 332 | { |
| @@ -361,11 +361,10 @@ static inline int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) { return 0; · 360 unmodified lines | ||
| 361 | 361 | #endif |
| 362 | 362 | |
| 363 | 363 | int i2c_dw_validate_speed(struct dw_i2c_dev *dev); |
| 364 | +void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev); | |
| 364 | 365 | |
| 365 | 366 | #if IS_ENABLED(CONFIG_ACPI) |
| 366 | 367 | int i2c_dw_acpi_configure(struct device *device); |
| 367 | −void i2c_dw_acpi_adjust_bus_speed(struct device *device); | |
| 368 | 368 | #else |
| 369 | 369 | static inline int i2c_dw_acpi_configure(struct device *device) { return -ENODEV; } |
| 370 | −static inline void i2c_dw_acpi_adjust_bus_speed(struct device *device) {} | |
| 371 | 370 | #endif |
| @@ -240,7 +240,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, · 239 unmodified lines | ||
| 240 | 240 | } |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | − i2c_dw_acpi_adjust_bus_speed(&pdev->dev); | |
| 243 | + i2c_dw_adjust_bus_speed(dev); | |
| 244 | 244 | |
| 245 | 245 | if (has_acpi_companion(&pdev->dev)) |
| 246 | 246 | i2c_dw_acpi_configure(&pdev->dev); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/clk-provider.h> |
| 13 | 13 | #include <linux/clk.h> |
| 14 | 14 | #include <linux/delay.h> |
| 15 | +#include <linux/dmi.h> | |
| 15 | 16 | #include <linux/err.h> |
| 16 | 17 | #include <linux/errno.h> |
| 17 | 18 | #include <linux/i2c.h> |
| @@ -191,6 +192,17 @@ static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev) · 173 unmodified lines | ||
| 191 | 192 | return ret; |
| 192 | 193 | } |
| 193 | 194 | |
| 195 | +static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = { | |
| 196 | + { | |
| 197 | + .ident = "Qtechnology QT5222", | |
| 198 | + .matches = { | |
| 199 | + DMI_MATCH(DMI_SYS_VENDOR, "Qtechnology"), | |
| 200 | + DMI_MATCH(DMI_PRODUCT_NAME, "QT5222"), | |
| 201 | + }, | |
| 202 | + }, | |
| 203 | + { } /* terminate list */ | |
| 204 | +}; | |
| 205 | + | |
| 194 | 206 | static int dw_i2c_plat_probe(struct platform_device *pdev) |
| 195 | 207 | { |
| 196 | 208 | struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev); |
| @@ -228,7 +240,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) · 31 unmodified lines | ||
| 228 | 240 | else |
| 229 | 241 | i2c_parse_fw_timings(&pdev->dev, t, false); |
| 230 | 242 | |
| 231 | − i2c_dw_acpi_adjust_bus_speed(&pdev->dev); | |
| 243 | + i2c_dw_adjust_bus_speed(dev); | |
| 232 | 244 | |
| 233 | 245 | if (pdev->dev.of_node) |
| 234 | 246 | dw_i2c_of_configure(pdev); |
| @@ -267,7 +279,8 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) · 32 unmodified lines | ||
| 267 | 279 | |
| 268 | 280 | adap = &dev->adapter; |
| 269 | 281 | adap->owner = THIS_MODULE; |
| 270 | − adap->class = I2C_CLASS_DEPRECATED; | |
| 282 | + adap->class = dmi_check_system(dw_i2c_hwmon_class_dmi) ? | |
| 283 | + I2C_CLASS_HWMON : I2C_CLASS_DEPRECATED; | |
| 271 | 284 | ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); |
| 272 | 285 | adap->dev.of_node = pdev->dev.of_node; |
| 273 | 286 | adap->nr = -1; |
| @@ -180,6 +180,7 @@ static const struct pci_device_id pch_pcidev_id[] = { · 179 unmodified lines | ||
| 180 | 180 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_I2C), 1, }, |
| 181 | 181 | {0,} |
| 182 | 182 | }; |
| 183 | +MODULE_DEVICE_TABLE(pci, pch_pcidev_id); | |
| 183 | 184 | |
| 184 | 185 | static irqreturn_t pch_i2c_handler(int irq, void *pData); |
| 185 | 186 | |
| @@ -98,7 +98,7 @@ · 97 unmodified lines | ||
| 98 | 98 | #define I2C_STAT_DAT_REQ BIT(25) |
| 99 | 99 | #define I2C_STAT_CMD_COMP BIT(24) |
| 100 | 100 | #define I2C_STAT_STOP_ERR BIT(23) |
| 101 | −#define I2C_STAT_MAX_PORT GENMASK(19, 16) | |
| 101 | +#define I2C_STAT_MAX_PORT GENMASK(22, 16) | |
| 102 | 102 | #define I2C_STAT_ANY_INT BIT(15) |
| 103 | 103 | #define I2C_STAT_SCL_IN BIT(11) |
| 104 | 104 | #define I2C_STAT_SDA_IN BIT(10) |
| @@ -337,9 +337,9 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv) · 336 unmodified lines | ||
| 337 | 337 | if (priv->smbus_block && (val & MLXCPLD_I2C_SMBUS_BLK_BIT)) { |
| 338 | 338 | mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG, |
| 339 | 339 | &datalen, 1); |
| 340 | − if (unlikely(datalen > (I2C_SMBUS_BLOCK_MAX + 1))) { | |
| 340 | + if (unlikely(datalen > I2C_SMBUS_BLOCK_MAX)) { | |
| 341 | 341 | dev_err(priv->dev, "Incorrect smbus block read message len\n"); |
| 342 | − return -E2BIG; | |
| 342 | + return -EPROTO; | |
| 343 | 343 | } |
| 344 | 344 | } else { |
| 345 | 345 | datalen = priv->xfer.data_len; |
| @@ -815,31 +815,6 @@ out_err_silent: · 814 unmodified lines | ||
| 815 | 815 | } |
| 816 | 816 | EXPORT_SYMBOL_GPL(i2c_new_client_device); |
| 817 | 817 | |
| 818 | −/** | |
| 819 | − * i2c_new_device - instantiate an i2c device | |
| 820 | − * @adap: the adapter managing the device | |
| 821 | − * @info: describes one I2C device; bus_num is ignored | |
| 822 | − * Context: can sleep | |
| 823 | − * | |
| 824 | − * This deprecated function has the same functionality as | |
| 825 | − * @i2c_new_client_device, it just returns NULL instead of an ERR_PTR in case of | |
| 826 | − * an error for compatibility with current I2C API. It will be removed once all | |
| 827 | − * users are converted. | |
| 828 | − * | |
| 829 | − * This returns the new i2c client, which may be saved for later use with | |
| 830 | − * i2c_unregister_device(); or NULL to indicate an error. | |
| 831 | − */ | |
| 832 | −struct i2c_client * | |
| 833 | −i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) | |
| 834 | −{ | |
| 835 | − struct i2c_client *ret; | |
| 836 | − | |
| 837 | − ret = i2c_new_client_device(adap, info); | |
| 838 | − return IS_ERR(ret) ? NULL : ret; | |
| 839 | −} | |
| 840 | −EXPORT_SYMBOL_GPL(i2c_new_device); | |
| 841 | − | |
| 842 | − | |
| 843 | 818 | /** |
| 844 | 819 | * i2c_unregister_device - reverse effect of i2c_new_*_device() |
| 845 | 820 | * @client: value returned from i2c_new_*_device() |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * |
| 5 | 5 | * This file contains the SMBus functions which are always included in the I2C |
| 6 | 6 | * core because they can be emulated via I2C. SMBus specific extensions |
| 7 | − * (e.g. smbalert) are handled in a seperate i2c-smbus module. | |
| 7 | + * (e.g. smbalert) are handled in a separate i2c-smbus module. | |
| 8 | 8 | * |
| 9 | 9 | * All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> |
| 10 | 10 | * SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and |
| @@ -495,6 +495,13 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, · 484 unmodified lines | ||
| 495 | 495 | break; |
| 496 | 496 | case I2C_SMBUS_BLOCK_DATA: |
| 497 | 497 | case I2C_SMBUS_BLOCK_PROC_CALL: |
| 498 | + if (msg[1].buf[0] > I2C_SMBUS_BLOCK_MAX) { | |
| 499 | + dev_err(&adapter->dev, | |
| 500 | + "Invalid block size returned: %d\n", | |
| 501 | + msg[1].buf[0]); | |
| 502 | + status = -EPROTO; | |
| 503 | + goto cleanup; | |
| 504 | + } | |
| 498 | 505 | for (i = 0; i < msg[1].buf[0] + 1; i++) |
| 499 | 506 | data->block[i] = msg[1].buf[i]; |
| 500 | 507 | break; |
| @@ -918,6 +918,7 @@ static void cm_free_work(struct cm_work *work) · 917 unmodified lines | ||
| 918 | 918 | |
| 919 | 919 | static void cm_queue_work_unlock(struct cm_id_private *cm_id_priv, |
| 920 | 920 | struct cm_work *work) |
| 921 | + __releases(&cm_id_priv->lock) | |
| 921 | 922 | { |
| 922 | 923 | bool immediate; |
| 923 | 924 | |
| @@ -1624,6 +1624,8 @@ static struct rdma_id_private *cma_find_listener( · 1623 unmodified lines | ||
| 1624 | 1624 | { |
| 1625 | 1625 | struct rdma_id_private *id_priv, *id_priv_dev; |
| 1626 | 1626 | |
| 1627 | + lockdep_assert_held(&lock); | |
| 1628 | + | |
| 1627 | 1629 | if (!bind_list) |
| 1628 | 1630 | return ERR_PTR(-EINVAL); |
| 1629 | 1631 | |
| @@ -1670,6 +1672,7 @@ cma_ib_id_from_event(struct ib_cm_id *cm_id, · 40 unmodified lines | ||
| 1670 | 1672 | } |
| 1671 | 1673 | } |
| 1672 | 1674 | |
| 1675 | + mutex_lock(&lock); | |
| 1673 | 1676 | /* |
| 1674 | 1677 | * Net namespace might be getting deleted while route lookup, |
| 1675 | 1678 | * cm_id lookup is in progress. Therefore, perform netdevice |
| @@ -1711,6 +1714,7 @@ cma_ib_id_from_event(struct ib_cm_id *cm_id, · 35 unmodified lines | ||
| 1711 | 1714 | id_priv = cma_find_listener(bind_list, cm_id, ib_event, req, *net_dev); |
| 1712 | 1715 | err: |
| 1713 | 1716 | rcu_read_unlock(); |
| 1717 | + mutex_unlock(&lock); | |
| 1714 | 1718 | if (IS_ERR(id_priv) && *net_dev) { |
| 1715 | 1719 | dev_put(*net_dev); |
| 1716 | 1720 | *net_dev = NULL; |
| @@ -2492,6 +2496,8 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv, · 775 unmodified lines | ||
| 2492 | 2496 | struct net *net = id_priv->id.route.addr.dev_addr.net; |
| 2493 | 2497 | int ret; |
| 2494 | 2498 | |
| 2499 | + lockdep_assert_held(&lock); | |
| 2500 | + | |
| 2495 | 2501 | if (cma_family(id_priv) == AF_IB && !rdma_cap_ib_cm(cma_dev->device, 1)) |
| 2496 | 2502 | return; |
| 2497 | 2503 | |
| @@ -3342,6 +3348,8 @@ static void cma_bind_port(struct rdma_bind_list *bind_list, · 844 unmodified lines | ||
| 3342 | 3348 | u64 sid, mask; |
| 3343 | 3349 | __be16 port; |
| 3344 | 3350 | |
| 3351 | + lockdep_assert_held(&lock); | |
| 3352 | + | |
| 3345 | 3353 | addr = cma_src_addr(id_priv); |
| 3346 | 3354 | port = htons(bind_list->port); |
| 3347 | 3355 | |
| @@ -3370,6 +3378,8 @@ static int cma_alloc_port(enum rdma_ucm_port_space ps, · 22 unmodified lines | ||
| 3370 | 3378 | struct rdma_bind_list *bind_list; |
| 3371 | 3379 | int ret; |
| 3372 | 3380 | |
| 3381 | + lockdep_assert_held(&lock); | |
| 3382 | + | |
| 3373 | 3383 | bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); |
| 3374 | 3384 | if (!bind_list) |
| 3375 | 3385 | return -ENOMEM; |
| @@ -3396,6 +3406,8 @@ static int cma_port_is_unique(struct rdma_bind_list *bind_list, · 20 unmodified lines | ||
| 3396 | 3406 | struct sockaddr *saddr = cma_src_addr(id_priv); |
| 3397 | 3407 | __be16 dport = cma_port(daddr); |
| 3398 | 3408 | |
| 3409 | + lockdep_assert_held(&lock); | |
| 3410 | + | |
| 3399 | 3411 | hlist_for_each_entry(cur_id, &bind_list->owners, node) { |
| 3400 | 3412 | struct sockaddr *cur_daddr = cma_dst_addr(cur_id); |
| 3401 | 3413 | struct sockaddr *cur_saddr = cma_src_addr(cur_id); |
| @@ -3435,6 +3447,8 @@ static int cma_alloc_any_port(enum rdma_ucm_port_space ps, · 33 unmodified lines | ||
| 3435 | 3447 | unsigned int rover; |
| 3436 | 3448 | struct net *net = id_priv->id.route.addr.dev_addr.net; |
| 3437 | 3449 | |
| 3450 | + lockdep_assert_held(&lock); | |
| 3451 | + | |
| 3438 | 3452 | inet_get_local_port_range(net, &low, &high); |
| 3439 | 3453 | remaining = (high - low) + 1; |
| 3440 | 3454 | rover = prandom_u32() % remaining + low; |
| @@ -3482,6 +3496,8 @@ static int cma_check_port(struct rdma_bind_list *bind_list, · 41 unmodified lines | ||
| 3482 | 3496 | struct rdma_id_private *cur_id; |
| 3483 | 3497 | struct sockaddr *addr, *cur_addr; |
| 3484 | 3498 | |
| 3499 | + lockdep_assert_held(&lock); | |
| 3500 | + | |
| 3485 | 3501 | addr = cma_src_addr(id_priv); |
| 3486 | 3502 | hlist_for_each_entry(cur_id, &bind_list->owners, node) { |
| 3487 | 3503 | if (id_priv == cur_id) |
| @@ -3512,6 +3528,8 @@ static int cma_use_port(enum rdma_ucm_port_space ps, · 24 unmodified lines | ||
| 3512 | 3528 | unsigned short snum; |
| 3513 | 3529 | int ret; |
| 3514 | 3530 | |
| 3531 | + lockdep_assert_held(&lock); | |
| 3532 | + | |
| 3515 | 3533 | snum = ntohs(cma_port(cma_src_addr(id_priv))); |
| 3516 | 3534 | if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) |
| 3517 | 3535 | return -EACCES; |
| @@ -202,7 +202,7 @@ static int __rdma_counter_unbind_qp(struct ib_qp *qp) · 201 unmodified lines | ||
| 202 | 202 | return ret; |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | −static void counter_history_stat_update(const struct rdma_counter *counter) | |
| 205 | +static void counter_history_stat_update(struct rdma_counter *counter) | |
| 206 | 206 | { |
| 207 | 207 | struct ib_device *dev = counter->device; |
| 208 | 208 | struct rdma_port_counter *port_counter; |
| @@ -212,6 +212,8 @@ static void counter_history_stat_update(const struct rdma_counter *counter) · 3 unmodified lines | ||
| 212 | 212 | if (!port_counter->hstats) |
| 213 | 213 | return; |
| 214 | 214 | |
| 215 | + rdma_counter_query_stats(counter); | |
| 216 | + | |
| 215 | 217 | for (i = 0; i < counter->stats->num_counters; i++) |
| 216 | 218 | port_counter->hstats->value[i] += counter->stats->value[i]; |
| 217 | 219 | } |
| @@ -509,10 +509,10 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv) · 508 unmodified lines | ||
| 509 | 509 | xa_erase(&ib_mad_clients, mad_agent_priv->agent.hi_tid); |
| 510 | 510 | |
| 511 | 511 | flush_workqueue(port_priv->wq); |
| 512 | − ib_cancel_rmpp_recvs(mad_agent_priv); | |
| 513 | 512 | |
| 514 | 513 | deref_mad_agent(mad_agent_priv); |
| 515 | 514 | wait_for_completion(&mad_agent_priv->comp); |
| 515 | + ib_cancel_rmpp_recvs(mad_agent_priv); | |
| 516 | 516 | |
| 517 | 517 | ib_mad_agent_security_cleanup(&mad_agent_priv->agent); |
| 518 | 518 | |
| @@ -2718,6 +2718,7 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, · 2199 unmodified lines | ||
| 2718 | 2718 | DMA_FROM_DEVICE); |
| 2719 | 2719 | if (unlikely(ib_dma_mapping_error(qp_info->port_priv->device, |
| 2720 | 2720 | sg_list.addr))) { |
| 2721 | + kfree(mad_priv); | |
| 2721 | 2722 | ret = -ENOMEM; |
| 2722 | 2723 | break; |
| 2723 | 2724 | } |
| @@ -470,40 +470,46 @@ static struct ib_uobject * · 469 unmodified lines | ||
| 470 | 470 | alloc_begin_fd_uobject(const struct uverbs_api_object *obj, |
| 471 | 471 | struct uverbs_attr_bundle *attrs) |
| 472 | 472 | { |
| 473 | − const struct uverbs_obj_fd_type *fd_type = | |
| 474 | − container_of(obj->type_attrs, struct uverbs_obj_fd_type, type); | |
| 473 | + const struct uverbs_obj_fd_type *fd_type; | |
| 475 | 474 | int new_fd; |
| 476 | − struct ib_uobject *uobj; | |
| 475 | + struct ib_uobject *uobj, *ret; | |
| 477 | 476 | struct file *filp; |
| 478 | 477 | |
| 478 | + uobj = alloc_uobj(attrs, obj); | |
| 479 | + if (IS_ERR(uobj)) | |
| 480 | + return uobj; | |
| 481 | + | |
| 482 | + fd_type = | |
| 483 | + container_of(obj->type_attrs, struct uverbs_obj_fd_type, type); | |
| 479 | 484 | if (WARN_ON(fd_type->fops->release != &uverbs_uobject_fd_release && |
| 480 | − fd_type->fops->release != &uverbs_async_event_release)) | |
| 481 | − return ERR_PTR(-EINVAL); | |
| 485 | + fd_type->fops->release != &uverbs_async_event_release)) { | |
| 486 | + ret = ERR_PTR(-EINVAL); | |
| 487 | + goto err_fd; | |
| 488 | + } | |
| 482 | 489 | |
| 483 | 490 | new_fd = get_unused_fd_flags(O_CLOEXEC); |
| 484 | − if (new_fd < 0) | |
| 485 | − return ERR_PTR(new_fd); | |
| 486 | − | |
| 487 | − uobj = alloc_uobj(attrs, obj); | |
| 488 | − if (IS_ERR(uobj)) | |
| 491 | + if (new_fd < 0) { | |
| 492 | + ret = ERR_PTR(new_fd); | |
| 489 | 493 | goto err_fd; |
| 494 | + } | |
| 490 | 495 | |
| 491 | 496 | /* Note that uverbs_uobject_fd_release() is called during abort */ |
| 492 | 497 | filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, |
| 493 | 498 | fd_type->flags); |
| 494 | 499 | if (IS_ERR(filp)) { |
| 495 | − uverbs_uobject_put(uobj); | |
| 496 | − uobj = ERR_CAST(filp); | |
| 497 | − goto err_fd; | |
| 500 | + ret = ERR_CAST(filp); | |
| 501 | + goto err_getfile; | |
| 498 | 502 | } |
| 499 | 503 | uobj->object = filp; |
| 500 | 504 | |
| 501 | 505 | uobj->id = new_fd; |
| 502 | 506 | return uobj; |
| 503 | 507 | |
| 504 | −err_fd: | |
| 508 | +err_getfile: | |
| 505 | 509 | put_unused_fd(new_fd); |
| 506 | − return uobj; | |
| 510 | +err_fd: | |
| 511 | + uverbs_uobject_put(uobj); | |
| 512 | + return ret; | |
| 507 | 513 | } |
| 508 | 514 | |
| 509 | 515 | struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj, |
| @@ -212,6 +212,7 @@ int efa_query_device(struct ib_device *ibdev, · 211 unmodified lines | ||
| 212 | 212 | props->max_send_sge = dev_attr->max_sq_sge; |
| 213 | 213 | props->max_recv_sge = dev_attr->max_rq_sge; |
| 214 | 214 | props->max_sge_rd = dev_attr->max_wr_rdma_sge; |
| 215 | + props->max_pkeys = 1; | |
| 215 | 216 | |
| 216 | 217 | if (udata && udata->outlen) { |
| 217 | 218 | resp.max_sq_sge = dev_attr->max_sq_sge; |
| @@ -985,15 +985,10 @@ static ssize_t qsfp2_debugfs_read(struct file *file, char __user *buf, · 984 unmodified lines | ||
| 985 | 985 | static int __i2c_debugfs_open(struct inode *in, struct file *fp, u32 target) |
| 986 | 986 | { |
| 987 | 987 | struct hfi1_pportdata *ppd; |
| 988 | − int ret; | |
| 989 | 988 | |
| 990 | 989 | ppd = private2ppd(fp); |
| 991 | 990 | |
| 992 | − ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0); | |
| 993 | − if (ret) /* failed - release the module */ | |
| 994 | − module_put(THIS_MODULE); | |
| 995 | − | |
| 996 | − return ret; | |
| 991 | + return acquire_chip_resource(ppd->dd, i2c_target(target), 0); | |
| 997 | 992 | } |
| 998 | 993 | |
| 999 | 994 | static int i2c1_debugfs_open(struct inode *in, struct file *fp) |
| @@ -1013,7 +1008,6 @@ static int __i2c_debugfs_release(struct inode *in, struct file *fp, u32 target) · 13 unmodified lines | ||
| 1013 | 1008 | ppd = private2ppd(fp); |
| 1014 | 1009 | |
| 1015 | 1010 | release_chip_resource(ppd->dd, i2c_target(target)); |
| 1016 | − module_put(THIS_MODULE); | |
| 1017 | 1011 | |
| 1018 | 1012 | return 0; |
| 1019 | 1013 | } |
| @@ -1031,18 +1025,10 @@ static int i2c2_debugfs_release(struct inode *in, struct file *fp) · 11 unmodified lines | ||
| 1031 | 1025 | static int __qsfp_debugfs_open(struct inode *in, struct file *fp, u32 target) |
| 1032 | 1026 | { |
| 1033 | 1027 | struct hfi1_pportdata *ppd; |
| 1034 | − int ret; | |
| 1035 | − | |
| 1036 | − if (!try_module_get(THIS_MODULE)) | |
| 1037 | − return -ENODEV; | |
| 1038 | 1028 | |
| 1039 | 1029 | ppd = private2ppd(fp); |
| 1040 | 1030 | |
| 1041 | − ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0); | |
| 1042 | − if (ret) /* failed - release the module */ | |
| 1043 | − module_put(THIS_MODULE); | |
| 1044 | − | |
| 1045 | − return ret; | |
| 1031 | + return acquire_chip_resource(ppd->dd, i2c_target(target), 0); | |
| 1046 | 1032 | } |
| 1047 | 1033 | |
| 1048 | 1034 | static int qsfp1_debugfs_open(struct inode *in, struct file *fp) |
| @@ -1062,7 +1048,6 @@ static int __qsfp_debugfs_release(struct inode *in, struct file *fp, u32 target) · 13 unmodified lines | ||
| 1062 | 1048 | ppd = private2ppd(fp); |
| 1063 | 1049 | |
| 1064 | 1050 | release_chip_resource(ppd->dd, i2c_target(target)); |
| 1065 | − module_put(THIS_MODULE); | |
| 1066 | 1051 | |
| 1067 | 1052 | return 0; |
| 1068 | 1053 | } |
| @@ -399,7 +399,7 @@ static inline void iowait_get_priority(struct iowait *w) · 398 unmodified lines | ||
| 399 | 399 | * @wait_head: the wait queue |
| 400 | 400 | * |
| 401 | 401 | * This function is called to insert an iowait struct into a |
| 402 | − * wait queue after a resource (eg, sdma decriptor or pio | |
| 402 | + * wait queue after a resource (eg, sdma descriptor or pio | |
| 403 | 403 | * buffer) is run out. |
| 404 | 404 | */ |
| 405 | 405 | static inline void iowait_queue(bool pkts_sent, struct iowait *w, |
| @@ -67,6 +67,9 @@ struct hfi1_ipoib_circ_buf { · 66 unmodified lines | ||
| 67 | 67 | * @sde: sdma engine |
| 68 | 68 | * @tx_list: tx request list |
| 69 | 69 | * @sent_txreqs: count of txreqs posted to sdma |
| 70 | + * @stops: count of stops of queue | |
| 71 | + * @ring_full: ring has been filled | |
| 72 | + * @no_desc: descriptor shortage seen | |
| 70 | 73 | * @flow: tracks when list needs to be flushed for a flow change |
| 71 | 74 | * @q_idx: ipoib Tx queue index |
| 72 | 75 | * @pkts_sent: indicator packets have been sent from this queue |
| @@ -80,6 +83,9 @@ struct hfi1_ipoib_txq { · 7 unmodified lines | ||
| 80 | 83 | struct sdma_engine *sde; |
| 81 | 84 | struct list_head tx_list; |
| 82 | 85 | u64 sent_txreqs; |
| 86 | + atomic_t stops; | |
| 87 | + atomic_t ring_full; | |
| 88 | + atomic_t no_desc; | |
| 83 | 89 | union hfi1_ipoib_flow flow; |
| 84 | 90 | u8 q_idx; |
| 85 | 91 | bool pkts_sent; |
| @@ -55,23 +55,48 @@ static u64 hfi1_ipoib_txreqs(const u64 sent, const u64 completed) · 54 unmodified lines | ||
| 55 | 55 | return sent - completed; |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | −static void hfi1_ipoib_check_queue_depth(struct hfi1_ipoib_txq *txq) | |
| 58 | +static u64 hfi1_ipoib_used(struct hfi1_ipoib_txq *txq) | |
| 59 | 59 | { |
| 60 | − if (unlikely(hfi1_ipoib_txreqs(++txq->sent_txreqs, | |
| 61 | − atomic64_read(&txq->complete_txreqs)) >= | |
| 62 | − min_t(unsigned int, txq->priv->netdev->tx_queue_len, | |
| 63 | − txq->tx_ring.max_items - 1))) | |
| 60 | + return hfi1_ipoib_txreqs(txq->sent_txreqs, | |
| 61 | + atomic64_read(&txq->complete_txreqs)); | |
| 62 | +} | |
| 63 | + | |
| 64 | +static void hfi1_ipoib_stop_txq(struct hfi1_ipoib_txq *txq) | |
| 65 | +{ | |
| 66 | + if (atomic_inc_return(&txq->stops) == 1) | |
| 64 | 67 | netif_stop_subqueue(txq->priv->netdev, txq->q_idx); |
| 65 | 68 | } |
| 66 | 69 | |
| 70 | +static void hfi1_ipoib_wake_txq(struct hfi1_ipoib_txq *txq) | |
| 71 | +{ | |
| 72 | + if (atomic_dec_and_test(&txq->stops)) | |
| 73 | + netif_wake_subqueue(txq->priv->netdev, txq->q_idx); | |
| 74 | +} | |
| 75 | + | |
| 76 | +static uint hfi1_ipoib_ring_hwat(struct hfi1_ipoib_txq *txq) | |
| 77 | +{ | |
| 78 | + return min_t(uint, txq->priv->netdev->tx_queue_len, | |
| 79 | + txq->tx_ring.max_items - 1); | |
| 80 | +} | |
| 81 | + | |
| 82 | +static uint hfi1_ipoib_ring_lwat(struct hfi1_ipoib_txq *txq) | |
| 83 | +{ | |
| 84 | + return min_t(uint, txq->priv->netdev->tx_queue_len, | |
| 85 | + txq->tx_ring.max_items) >> 1; | |
| 86 | +} | |
| 87 | + | |
| 88 | +static void hfi1_ipoib_check_queue_depth(struct hfi1_ipoib_txq *txq) | |
| 89 | +{ | |
| 90 | + ++txq->sent_txreqs; | |
| 91 | + if (hfi1_ipoib_used(txq) >= hfi1_ipoib_ring_hwat(txq) && | |
| 92 | + !atomic_xchg(&txq->ring_full, 1)) | |
| 93 | + hfi1_ipoib_stop_txq(txq); | |
| 94 | +} | |
| 95 | + | |
| 67 | 96 | static void hfi1_ipoib_check_queue_stopped(struct hfi1_ipoib_txq *txq) |
| 68 | 97 | { |
| 69 | 98 | struct net_device *dev = txq->priv->netdev; |
| 70 | 99 | |
| 71 | − /* If the queue is already running just return */ | |
| 72 | − if (likely(!__netif_subqueue_stopped(dev, txq->q_idx))) | |
| 73 | − return; | |
| 74 | − | |
| 75 | 100 | /* If shutting down just return as queue state is irrelevant */ |
| 76 | 101 | if (unlikely(dev->reg_state != NETREG_REGISTERED)) |
| 77 | 102 | return; |
| @@ -86,11 +111,9 @@ static void hfi1_ipoib_check_queue_stopped(struct hfi1_ipoib_txq *txq) · 8 unmodified lines | ||
| 86 | 111 | * Use the minimum of the current tx_queue_len or the rings max txreqs |
| 87 | 112 | * to protect against ring overflow. |
| 88 | 113 | */ |
| 89 | − if (hfi1_ipoib_txreqs(txq->sent_txreqs, | |
| 90 | − atomic64_read(&txq->complete_txreqs)) | |
| 91 | − < min_t(unsigned int, dev->tx_queue_len, | |
| 92 | − txq->tx_ring.max_items) >> 1) | |
| 93 | − netif_wake_subqueue(dev, txq->q_idx); | |
| 114 | + if (hfi1_ipoib_used(txq) < hfi1_ipoib_ring_lwat(txq) && | |
| 115 | + atomic_xchg(&txq->ring_full, 0)) | |
| 116 | + hfi1_ipoib_wake_txq(txq); | |
| 94 | 117 | } |
| 95 | 118 | |
| 96 | 119 | static void hfi1_ipoib_free_tx(struct ipoib_txreq *tx, int budget) |
| @@ -364,11 +387,12 @@ static struct ipoib_txreq *hfi1_ipoib_send_dma_common(struct net_device *dev, · 267 unmodified lines | ||
| 364 | 387 | if (unlikely(!tx)) |
| 365 | 388 | return ERR_PTR(-ENOMEM); |
| 366 | 389 | |
| 367 | − /* so that we can test if the sdma decriptors are there */ | |
| 390 | + /* so that we can test if the sdma descriptors are there */ | |
| 368 | 391 | tx->txreq.num_desc = 0; |
| 369 | 392 | tx->priv = priv; |
| 370 | 393 | tx->txq = txp->txq; |
| 371 | 394 | tx->skb = skb; |
| 395 | + INIT_LIST_HEAD(&tx->txreq.list); | |
| 372 | 396 | |
| 373 | 397 | hfi1_ipoib_build_ib_tx_headers(tx, txp); |
| 374 | 398 | |
| @@ -469,6 +493,7 @@ static int hfi1_ipoib_send_dma_single(struct net_device *dev, · 94 unmodified lines | ||
| 469 | 493 | |
| 470 | 494 | ret = hfi1_ipoib_submit_tx(txq, tx); |
| 471 | 495 | if (likely(!ret)) { |
| 496 | +tx_ok: | |
| 472 | 497 | trace_sdma_output_ibhdr(tx->priv->dd, |
| 473 | 498 | &tx->sdma_hdr.hdr, |
| 474 | 499 | ib_is_sc5(txp->flow.sc5)); |
| @@ -478,20 +503,8 @@ static int hfi1_ipoib_send_dma_single(struct net_device *dev, · 3 unmodified lines | ||
| 478 | 503 | |
| 479 | 504 | txq->pkts_sent = false; |
| 480 | 505 | |
| 481 | − if (ret == -EBUSY) { | |
| 482 | − list_add_tail(&tx->txreq.list, &txq->tx_list); | |
| 483 | − | |
| 484 | − trace_sdma_output_ibhdr(tx->priv->dd, | |
| 485 | − &tx->sdma_hdr.hdr, | |
| 486 | − ib_is_sc5(txp->flow.sc5)); | |
| 487 | − hfi1_ipoib_check_queue_depth(txq); | |
| 488 | − return NETDEV_TX_OK; | |
| 489 | − } | |
| 490 | − | |
| 491 | − if (ret == -ECOMM) { | |
| 492 | − hfi1_ipoib_check_queue_depth(txq); | |
| 493 | − return NETDEV_TX_OK; | |
| 494 | − } | |
| 506 | + if (ret == -EBUSY || ret == -ECOMM) | |
| 507 | + goto tx_ok; | |
| 495 | 508 | |
| 496 | 509 | sdma_txclean(priv->dd, &tx->txreq); |
| 497 | 510 | dev_kfree_skb_any(skb); |
| @@ -509,9 +522,17 @@ static int hfi1_ipoib_send_dma_list(struct net_device *dev, · 11 unmodified lines | ||
| 509 | 522 | struct ipoib_txreq *tx; |
| 510 | 523 | |
| 511 | 524 | /* Has the flow change ? */ |
| 512 | − if (txq->flow.as_int != txp->flow.as_int) | |
| 513 | − (void)hfi1_ipoib_flush_tx_list(dev, txq); | |
| 514 | − | |
| 525 | + if (txq->flow.as_int != txp->flow.as_int) { | |
| 526 | + int ret; | |
| 527 | + | |
| 528 | + ret = hfi1_ipoib_flush_tx_list(dev, txq); | |
| 529 | + if (unlikely(ret)) { | |
| 530 | + if (ret == -EBUSY) | |
| 531 | + ++dev->stats.tx_dropped; | |
| 532 | + dev_kfree_skb_any(skb); | |
| 533 | + return NETDEV_TX_OK; | |
| 534 | + } | |
| 535 | + } | |
| 515 | 536 | tx = hfi1_ipoib_send_dma_common(dev, skb, txp); |
| 516 | 537 | if (IS_ERR(tx)) { |
| 517 | 538 | int ret = PTR_ERR(tx); |
| @@ -610,10 +631,14 @@ static int hfi1_ipoib_sdma_sleep(struct sdma_engine *sde, · 92 unmodified lines | ||
| 610 | 631 | return -EAGAIN; |
| 611 | 632 | } |
| 612 | 633 | |
| 613 | − netif_stop_subqueue(txq->priv->netdev, txq->q_idx); | |
| 614 | − | |
| 615 | − if (list_empty(&txq->wait.list)) | |
| 634 | + if (list_empty(&txreq->list)) | |
| 635 | + /* came from non-list submit */ | |
| 636 | + list_add_tail(&txreq->list, &txq->tx_list); | |
| 637 | + if (list_empty(&txq->wait.list)) { | |
| 638 | + if (!atomic_xchg(&txq->no_desc, 1)) | |
| 639 | + hfi1_ipoib_stop_txq(txq); | |
| 616 | 640 | iowait_queue(pkts_sent, wait->iow, &sde->dmawait); |
| 641 | + } | |
| 617 | 642 | |
| 618 | 643 | write_sequnlock(&sde->waitlock); |
| 619 | 644 | return -EBUSY; |
| @@ -648,9 +673,9 @@ static void hfi1_ipoib_flush_txq(struct work_struct *work) · 28 unmodified lines | ||
| 648 | 673 | struct net_device *dev = txq->priv->netdev; |
| 649 | 674 | |
| 650 | 675 | if (likely(dev->reg_state == NETREG_REGISTERED) && |
| 651 | − likely(__netif_subqueue_stopped(dev, txq->q_idx)) && | |
| 652 | 676 | likely(!hfi1_ipoib_flush_tx_list(dev, txq))) |
| 653 | − netif_wake_subqueue(dev, txq->q_idx); | |
| 677 | + if (atomic_xchg(&txq->no_desc, 0)) | |
| 678 | + hfi1_ipoib_wake_txq(txq); | |
| 654 | 679 | } |
| 655 | 680 | |
| 656 | 681 | int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv) |
| @@ -704,6 +729,9 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv) · 47 unmodified lines | ||
| 704 | 729 | txq->sde = NULL; |
| 705 | 730 | INIT_LIST_HEAD(&txq->tx_list); |
| 706 | 731 | atomic64_set(&txq->complete_txreqs, 0); |
| 732 | + atomic_set(&txq->stops, 0); | |
| 733 | + atomic_set(&txq->ring_full, 0); | |
| 734 | + atomic_set(&txq->no_desc, 0); | |
| 707 | 735 | txq->q_idx = i; |
| 708 | 736 | txq->flow.tx_queue = 0xff; |
| 709 | 737 | txq->flow.sc5 = 0xff; |
| @@ -769,7 +797,7 @@ static void hfi1_ipoib_drain_tx_list(struct hfi1_ipoib_txq *txq) · 59 unmodified lines | ||
| 769 | 797 | atomic64_inc(complete_txreqs); |
| 770 | 798 | } |
| 771 | 799 | |
| 772 | − if (hfi1_ipoib_txreqs(txq->sent_txreqs, atomic64_read(complete_txreqs))) | |
| 800 | + if (hfi1_ipoib_used(txq)) | |
| 773 | 801 | dd_dev_warn(txq->priv->dd, |
| 774 | 802 | "txq %d not empty found %llu requests\n", |
| 775 | 803 | txq->q_idx, |
| @@ -373,7 +373,7 @@ void hfi1_netdev_free(struct hfi1_devdata *dd) · 372 unmodified lines | ||
| 373 | 373 | { |
| 374 | 374 | if (dd->dummy_netdev) { |
| 375 | 375 | dd_dev_info(dd, "hfi1 netdev freed\n"); |
| 376 | − free_netdev(dd->dummy_netdev); | |
| 376 | + kfree(dd->dummy_netdev); | |
| 377 | 377 | dd->dummy_netdev = NULL; |
| 378 | 378 | } |
| 379 | 379 | } |
| @@ -91,7 +91,7 @@ static inline struct verbs_txreq *get_txreq(struct hfi1_ibdev *dev, · 90 unmodified lines | ||
| 91 | 91 | tx->mr = NULL; |
| 92 | 92 | tx->sde = priv->s_sde; |
| 93 | 93 | tx->psc = priv->s_sendcontext; |
| 94 | − /* so that we can test if the sdma decriptors are there */ | |
| 94 | + /* so that we can test if the sdma descriptors are there */ | |
| 95 | 95 | tx->txreq.num_desc = 0; |
| 96 | 96 | /* Set the header type */ |
| 97 | 97 | tx->phdr.hdr.hdr_type = priv->hdr_type; |
| @@ -898,13 +898,14 @@ struct hns_roce_hw { · 897 unmodified lines | ||
| 898 | 898 | int (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr); |
| 899 | 899 | void (*set_mtu)(struct hns_roce_dev *hr_dev, u8 phy_port, |
| 900 | 900 | enum ib_mtu mtu); |
| 901 | − int (*write_mtpt)(void *mb_buf, struct hns_roce_mr *mr, | |
| 902 | − unsigned long mtpt_idx); | |
| 901 | + int (*write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf, | |
| 902 | + struct hns_roce_mr *mr, unsigned long mtpt_idx); | |
| 903 | 903 | int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev, |
| 904 | 904 | struct hns_roce_mr *mr, int flags, u32 pdn, |
| 905 | 905 | int mr_access_flags, u64 iova, u64 size, |
| 906 | 906 | void *mb_buf); |
| 907 | − int (*frmr_write_mtpt)(void *mb_buf, struct hns_roce_mr *mr); | |
| 907 | + int (*frmr_write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf, | |
| 908 | + struct hns_roce_mr *mr); | |
| 908 | 909 | int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw); |
| 909 | 910 | void (*write_cqc)(struct hns_roce_dev *hr_dev, |
| 910 | 911 | struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts, |
| @@ -1756,10 +1756,10 @@ static void hns_roce_v1_set_mtu(struct hns_roce_dev *hr_dev, u8 phy_port, · 1755 unmodified lines | ||
| 1756 | 1756 | val); |
| 1757 | 1757 | } |
| 1758 | 1758 | |
| 1759 | −static int hns_roce_v1_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, | |
| 1759 | +static int hns_roce_v1_write_mtpt(struct hns_roce_dev *hr_dev, void *mb_buf, | |
| 1760 | + struct hns_roce_mr *mr, | |
| 1760 | 1761 | unsigned long mtpt_idx) |
| 1761 | 1762 | { |
| 1762 | − struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device); | |
| 1763 | 1763 | u64 pages[HNS_ROCE_MAX_INNER_MTPT_NUM] = { 0 }; |
| 1764 | 1764 | struct ib_device *ibdev = &hr_dev->ib_dev; |
| 1765 | 1765 | struct hns_roce_v1_mpt_entry *mpt_entry; |
| @@ -910,7 +910,7 @@ static int hns_roce_v2_rst_process_cmd(struct hns_roce_dev *hr_dev) · 909 unmodified lines | ||
| 910 | 910 | instance_stage = handle->rinfo.instance_state; |
| 911 | 911 | reset_stage = handle->rinfo.reset_state; |
| 912 | 912 | reset_cnt = ops->ae_dev_reset_cnt(handle); |
| 913 | − hw_resetting = ops->get_hw_reset_stat(handle); | |
| 913 | + hw_resetting = ops->get_cmdq_stat(handle); | |
| 914 | 914 | sw_resetting = ops->ae_dev_resetting(handle); |
| 915 | 915 | |
| 916 | 916 | if (reset_cnt != hr_dev->reset_cnt) |
| @@ -2529,10 +2529,10 @@ static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port, · 1612 unmodified lines | ||
| 2529 | 2529 | return hns_roce_cmq_send(hr_dev, &desc, 1); |
| 2530 | 2530 | } |
| 2531 | 2531 | |
| 2532 | −static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry, | |
| 2532 | +static int set_mtpt_pbl(struct hns_roce_dev *hr_dev, | |
| 2533 | + struct hns_roce_v2_mpt_entry *mpt_entry, | |
| 2533 | 2534 | struct hns_roce_mr *mr) |
| 2534 | 2535 | { |
| 2535 | − struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device); | |
| 2536 | 2536 | u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 }; |
| 2537 | 2537 | struct ib_device *ibdev = &hr_dev->ib_dev; |
| 2538 | 2538 | dma_addr_t pbl_ba; |
| @@ -2571,7 +2571,8 @@ static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry, · 32 unmodified lines | ||
| 2571 | 2571 | return 0; |
| 2572 | 2572 | } |
| 2573 | 2573 | |
| 2574 | −static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, | |
| 2574 | +static int hns_roce_v2_write_mtpt(struct hns_roce_dev *hr_dev, | |
| 2575 | + void *mb_buf, struct hns_roce_mr *mr, | |
| 2575 | 2576 | unsigned long mtpt_idx) |
| 2576 | 2577 | { |
| 2577 | 2578 | struct hns_roce_v2_mpt_entry *mpt_entry; |
| @@ -2620,7 +2621,7 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, · 42 unmodified lines | ||
| 2620 | 2621 | if (mr->type == MR_TYPE_DMA) |
| 2621 | 2622 | return 0; |
| 2622 | 2623 | |
| 2623 | − ret = set_mtpt_pbl(mpt_entry, mr); | |
| 2624 | + ret = set_mtpt_pbl(hr_dev, mpt_entry, mr); | |
| 2624 | 2625 | |
| 2625 | 2626 | return ret; |
| 2626 | 2627 | } |
| @@ -2666,15 +2667,15 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev, · 39 unmodified lines | ||
| 2666 | 2667 | mr->iova = iova; |
| 2667 | 2668 | mr->size = size; |
| 2668 | 2669 | |
| 2669 | − ret = set_mtpt_pbl(mpt_entry, mr); | |
| 2670 | + ret = set_mtpt_pbl(hr_dev, mpt_entry, mr); | |
| 2670 | 2671 | } |
| 2671 | 2672 | |
| 2672 | 2673 | return ret; |
| 2673 | 2674 | } |
| 2674 | 2675 | |
| 2675 | −static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr) | |
| 2676 | +static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev, | |
| 2677 | + void *mb_buf, struct hns_roce_mr *mr) | |
| 2676 | 2678 | { |
| 2677 | − struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device); | |
| 2678 | 2679 | struct ib_device *ibdev = &hr_dev->ib_dev; |
| 2679 | 2680 | struct hns_roce_v2_mpt_entry *mpt_entry; |
| 2680 | 2681 | dma_addr_t pbl_ba = 0; |
| @@ -180,9 +180,10 @@ static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev, · 179 unmodified lines | ||
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | if (mr->type != MR_TYPE_FRMR) |
| 183 | − ret = hr_dev->hw->write_mtpt(mailbox->buf, mr, mtpt_idx); | |
| 183 | + ret = hr_dev->hw->write_mtpt(hr_dev, mailbox->buf, mr, | |
| 184 | + mtpt_idx); | |
| 184 | 185 | else |
| 185 | − ret = hr_dev->hw->frmr_write_mtpt(mailbox->buf, mr); | |
| 186 | + ret = hr_dev->hw->frmr_write_mtpt(hr_dev, mailbox->buf, mr); | |
| 186 | 187 | if (ret) { |
| 187 | 188 | dev_err(dev, "Write mtpt fail!\n"); |
| 188 | 189 | goto err_page; |
| @@ -1862,7 +1862,7 @@ static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 1861 unmodified lines | ||
| 1862 | 1862 | if (!in) |
| 1863 | 1863 | return -ENOMEM; |
| 1864 | 1864 | |
| 1865 | − if (MLX5_CAP_GEN(mdev, ece_support)) | |
| 1865 | + if (MLX5_CAP_GEN(mdev, ece_support) && ucmd) | |
| 1866 | 1866 | MLX5_SET(create_qp_in, in, ece, ucmd->ece_options); |
| 1867 | 1867 | qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); |
| 1868 | 1868 | |
| @@ -2341,18 +2341,18 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 472 unmodified lines | ||
| 2341 | 2341 | unsigned long flags; |
| 2342 | 2342 | int err; |
| 2343 | 2343 | |
| 2344 | − if (qp->ibqp.rwq_ind_tbl) { | |
| 2344 | + if (qp->is_rss) { | |
| 2345 | 2345 | destroy_rss_raw_qp_tir(dev, qp); |
| 2346 | 2346 | return; |
| 2347 | 2347 | } |
| 2348 | 2348 | |
| 2349 | − base = (qp->ibqp.qp_type == IB_QPT_RAW_PACKET || | |
| 2349 | + base = (qp->type == IB_QPT_RAW_PACKET || | |
| 2350 | 2350 | qp->flags & IB_QP_CREATE_SOURCE_QPN) ? |
| 2351 | − &qp->raw_packet_qp.rq.base : | |
| 2352 | − &qp->trans_qp.base; | |
| 2351 | + &qp->raw_packet_qp.rq.base : | |
| 2352 | + &qp->trans_qp.base; | |
| 2353 | 2353 | |
| 2354 | 2354 | if (qp->state != IB_QPS_RESET) { |
| 2355 | − if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET && | |
| 2355 | + if (qp->type != IB_QPT_RAW_PACKET && | |
| 2356 | 2356 | !(qp->flags & IB_QP_CREATE_SOURCE_QPN)) { |
| 2357 | 2357 | err = mlx5_core_qp_modify(dev, MLX5_CMD_OP_2RST_QP, 0, |
| 2358 | 2358 | NULL, &base->mqp, NULL); |
| @@ -2368,8 +2368,8 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 9 unmodified lines | ||
| 2368 | 2368 | base->mqp.qpn); |
| 2369 | 2369 | } |
| 2370 | 2370 | |
| 2371 | − get_cqs(qp->ibqp.qp_type, qp->ibqp.send_cq, qp->ibqp.recv_cq, | |
| 2372 | − &send_cq, &recv_cq); | |
| 2371 | + get_cqs(qp->type, qp->ibqp.send_cq, qp->ibqp.recv_cq, &send_cq, | |
| 2372 | + &recv_cq); | |
| 2373 | 2373 | |
| 2374 | 2374 | spin_lock_irqsave(&dev->reset_flow_resource_lock, flags); |
| 2375 | 2375 | mlx5_ib_lock_cqs(send_cq, recv_cq); |
| @@ -2391,7 +2391,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 15 unmodified lines | ||
| 2391 | 2391 | mlx5_ib_unlock_cqs(send_cq, recv_cq); |
| 2392 | 2392 | spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags); |
| 2393 | 2393 | |
| 2394 | − if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET || | |
| 2394 | + if (qp->type == IB_QPT_RAW_PACKET || | |
| 2395 | 2395 | qp->flags & IB_QP_CREATE_SOURCE_QPN) { |
| 2396 | 2396 | destroy_raw_packet_qp(dev, qp); |
| 2397 | 2397 | } else { |
| @@ -2668,6 +2668,9 @@ static int process_create_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 270 unmodified lines | ||
| 2668 | 2668 | if (qp_type == IB_QPT_RAW_PACKET && attr->rwq_ind_tbl) |
| 2669 | 2669 | return (create_flags) ? -EINVAL : 0; |
| 2670 | 2670 | |
| 2671 | + process_create_flag(dev, &create_flags, | |
| 2672 | + IB_QP_CREATE_INTEGRITY_EN, | |
| 2673 | + MLX5_CAP_GEN(mdev, sho), qp); | |
| 2671 | 2674 | process_create_flag(dev, &create_flags, |
| 2672 | 2675 | IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK, |
| 2673 | 2676 | MLX5_CAP_GEN(mdev, block_lb_mc), qp); |
| @@ -2873,7 +2876,6 @@ static int mlx5_ib_destroy_dct(struct mlx5_ib_qp *mqp) · 199 unmodified lines | ||
| 2873 | 2876 | static int check_ucmd_data(struct mlx5_ib_dev *dev, |
| 2874 | 2877 | struct mlx5_create_qp_params *params) |
| 2875 | 2878 | { |
| 2876 | − struct ib_qp_init_attr *attr = params->attr; | |
| 2877 | 2879 | struct ib_udata *udata = params->udata; |
| 2878 | 2880 | size_t size, last; |
| 2879 | 2881 | int ret; |
| @@ -2885,14 +2887,7 @@ static int check_ucmd_data(struct mlx5_ib_dev *dev, · 5 unmodified lines | ||
| 2885 | 2887 | */ |
| 2886 | 2888 | last = sizeof(struct mlx5_ib_create_qp_rss); |
| 2887 | 2889 | else |
| 2888 | − /* IB_QPT_RAW_PACKET doesn't have ECE data */ | |
| 2889 | − switch (attr->qp_type) { | |
| 2890 | − case IB_QPT_RAW_PACKET: | |
| 2891 | − last = offsetof(struct mlx5_ib_create_qp, ece_options); | |
| 2892 | − break; | |
| 2893 | − default: | |
| 2894 | − last = offsetof(struct mlx5_ib_create_qp, reserved); | |
| 2895 | − } | |
| 2890 | + last = offsetof(struct mlx5_ib_create_qp, reserved); | |
| 2896 | 2891 | |
| 2897 | 2892 | if (udata->inlen <= last) |
| 2898 | 2893 | return 0; |
| @@ -2907,7 +2902,7 @@ static int check_ucmd_data(struct mlx5_ib_dev *dev, · 8 unmodified lines | ||
| 2907 | 2902 | if (!ret) |
| 2908 | 2903 | mlx5_ib_dbg( |
| 2909 | 2904 | dev, |
| 2910 | − "udata is not cleared, inlen = %lu, ucmd = %lu, last = %lu, size = %lu\n", | |
| 2905 | + "udata is not cleared, inlen = %zu, ucmd = %zu, last = %zu, size = %zu\n", | |
| 2911 | 2906 | udata->inlen, params->ucmd_size, last, size); |
| 2912 | 2907 | return ret ? 0 : -EINVAL; |
| 2913 | 2908 | } |
| @@ -3002,10 +2997,18 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr, · 88 unmodified lines | ||
| 3002 | 2997 | return &qp->ibqp; |
| 3003 | 2998 | |
| 3004 | 2999 | destroy_qp: |
| 3005 | − if (qp->type == MLX5_IB_QPT_DCT) | |
| 3000 | + if (qp->type == MLX5_IB_QPT_DCT) { | |
| 3006 | 3001 | mlx5_ib_destroy_dct(qp); |
| 3007 | − else | |
| 3002 | + } else { | |
| 3003 | + /* | |
| 3004 | + * The two lines below are temp solution till QP allocation | |
| 3005 | + * will be moved to be under IB/core responsiblity. | |
| 3006 | + */ | |
| 3007 | + qp->ibqp.send_cq = attr->send_cq; | |
| 3008 | + qp->ibqp.recv_cq = attr->recv_cq; | |
| 3008 | 3009 | destroy_qp_common(dev, qp, udata); |
| 3010 | + } | |
| 3011 | + | |
| 3009 | 3012 | qp = NULL; |
| 3010 | 3013 | free_qp: |
| 3011 | 3014 | kfree(qp); |
| @@ -4162,8 +4165,6 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 1150 unmodified lines | ||
| 4162 | 4165 | |
| 4163 | 4166 | if (udata->outlen < min_resp_len) |
| 4164 | 4167 | return -EINVAL; |
| 4165 | − resp.response_length = min_resp_len; | |
| 4166 | − | |
| 4167 | 4168 | /* |
| 4168 | 4169 | * If we don't have enough space for the ECE options, |
| 4169 | 4170 | * simply indicate it with resp.response_length. |
| @@ -4384,8 +4385,7 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev, · 214 unmodified lines | ||
| 4384 | 4385 | MLX5_GET(ads, path, src_addr_index), |
| 4385 | 4386 | MLX5_GET(ads, path, hop_limit), |
| 4386 | 4387 | MLX5_GET(ads, path, tclass)); |
| 4387 | − memcpy(ah_attr, MLX5_ADDR_OF(ads, path, rgid_rip), | |
| 4388 | − MLX5_FLD_SZ_BYTES(ads, rgid_rip)); | |
| 4388 | + rdma_ah_set_dgid_raw(ah_attr, MLX5_ADDR_OF(ads, path, rgid_rip)); | |
| 4389 | 4389 | } |
| 4390 | 4390 | } |
| 4391 | 4391 | |
| @@ -346,6 +346,9 @@ static int get_ece_from_mbox(void *out, u16 opcode) · 345 unmodified lines | ||
| 346 | 346 | int ece = 0; |
| 347 | 347 | |
| 348 | 348 | switch (opcode) { |
| 349 | + case MLX5_CMD_OP_INIT2INIT_QP: | |
| 350 | + ece = MLX5_GET(init2init_qp_out, out, ece); | |
| 351 | + break; | |
| 349 | 352 | case MLX5_CMD_OP_INIT2RTR_QP: |
| 350 | 353 | ece = MLX5_GET(init2rtr_qp_out, out, ece); |
| 351 | 354 | break; |
| @@ -355,6 +358,9 @@ static int get_ece_from_mbox(void *out, u16 opcode) · 3 unmodified lines | ||
| 355 | 358 | case MLX5_CMD_OP_RTS2RTS_QP: |
| 356 | 359 | ece = MLX5_GET(rts2rts_qp_out, out, ece); |
| 357 | 360 | break; |
| 361 | + case MLX5_CMD_OP_RST2INIT_QP: | |
| 362 | + ece = MLX5_GET(rst2init_qp_out, out, ece); | |
| 363 | + break; | |
| 358 | 364 | default: |
| 359 | 365 | break; |
| 360 | 366 | } |
| @@ -406,6 +412,7 @@ static int modify_qp_mbox_alloc(struct mlx5_core_dev *dev, u16 opcode, int qpn, · 45 unmodified lines | ||
| 406 | 412 | return -ENOMEM; |
| 407 | 413 | MOD_QP_IN_SET_QPC(rst2init_qp, mbox->in, opcode, qpn, |
| 408 | 414 | opt_param_mask, qpc, uid); |
| 415 | + MLX5_SET(rst2init_qp_in, mbox->in, ece, ece); | |
| 409 | 416 | break; |
| 410 | 417 | case MLX5_CMD_OP_INIT2RTR_QP: |
| 411 | 418 | if (MBOX_ALLOC(mbox, init2rtr_qp)) |
| @@ -439,6 +446,7 @@ static int modify_qp_mbox_alloc(struct mlx5_core_dev *dev, u16 opcode, int qpn, · 27 unmodified lines | ||
| 439 | 446 | return -ENOMEM; |
| 440 | 447 | MOD_QP_IN_SET_QPC(init2init_qp, mbox->in, opcode, qpn, |
| 441 | 448 | opt_param_mask, qpc, uid); |
| 449 | + MLX5_SET(init2init_qp_in, mbox->in, ece, ece); | |
| 442 | 450 | break; |
| 443 | 451 | default: |
| 444 | 452 | return -EINVAL; |
| @@ -150,8 +150,17 @@ qedr_iw_issue_event(void *context, · 149 unmodified lines | ||
| 150 | 150 | if (params->cm_info) { |
| 151 | 151 | event.ird = params->cm_info->ird; |
| 152 | 152 | event.ord = params->cm_info->ord; |
| 153 | − event.private_data_len = params->cm_info->private_data_len; | |
| 154 | − event.private_data = (void *)params->cm_info->private_data; | |
| 153 | + /* Only connect_request and reply have valid private data | |
| 154 | + * the rest of the events this may be left overs from | |
| 155 | + * connection establishment. CONNECT_REQUEST is issued via | |
| 156 | + * qedr_iw_mpa_request | |
| 157 | + */ | |
| 158 | + if (event_type == IW_CM_EVENT_CONNECT_REPLY) { | |
| 159 | + event.private_data_len = | |
| 160 | + params->cm_info->private_data_len; | |
| 161 | + event.private_data = | |
| 162 | + (void *)params->cm_info->private_data; | |
| 163 | + } | |
| 155 | 164 | } |
| 156 | 165 | |
| 157 | 166 | if (ep->cm_id) |
| @@ -1204,7 +1204,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, · 1203 unmodified lines | ||
| 1204 | 1204 | err = alloc_ud_wq_attr(qp, rdi->dparms.node); |
| 1205 | 1205 | if (err) { |
| 1206 | 1206 | ret = (ERR_PTR(err)); |
| 1207 | − goto bail_driver_priv; | |
| 1207 | + goto bail_rq_rvt; | |
| 1208 | 1208 | } |
| 1209 | 1209 | |
| 1210 | 1210 | if (init_attr->create_flags & IB_QP_CREATE_NETDEV_USE) |
| @@ -1314,9 +1314,11 @@ bail_qpn: · 103 unmodified lines | ||
| 1314 | 1314 | rvt_free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num); |
| 1315 | 1315 | |
| 1316 | 1316 | bail_rq_wq: |
| 1317 | − rvt_free_rq(&qp->r_rq); | |
| 1318 | 1317 | free_ud_wq_attr(qp); |
| 1319 | 1318 | |
| 1319 | +bail_rq_rvt: | |
| 1320 | + rvt_free_rq(&qp->r_rq); | |
| 1321 | + | |
| 1320 | 1322 | bail_driver_priv: |
| 1321 | 1323 | rdi->driver_f.qp_priv_free(rdi, qp); |
| 1322 | 1324 | |
| @@ -139,7 +139,8 @@ static int siw_rx_pbl(struct siw_rx_stream *srx, int *pbl_idx, · 138 unmodified lines | ||
| 139 | 139 | break; |
| 140 | 140 | |
| 141 | 141 | bytes = min(bytes, len); |
| 142 | − if (siw_rx_kva(srx, (void *)buf_addr, bytes) == bytes) { | |
| 142 | + if (siw_rx_kva(srx, (void *)(uintptr_t)buf_addr, bytes) == | |
| 143 | + bytes) { | |
| 143 | 144 | copied += bytes; |
| 144 | 145 | offset += bytes; |
| 145 | 146 | len -= bytes; |
| @@ -1021,7 +1021,7 @@ static int __init hp_sdc_register(void) · 1020 unmodified lines | ||
| 1021 | 1021 | hp_sdc.base_io = (unsigned long) 0xf0428000; |
| 1022 | 1022 | hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1; |
| 1023 | 1023 | hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3; |
| 1024 | − if (!probe_kernel_read(&i, (unsigned char *)hp_sdc.data_io, 1)) | |
| 1024 | + if (!copy_from_kernel_nofault(&i, (unsigned char *)hp_sdc.data_io, 1)) | |
| 1025 | 1025 | hp_sdc.dev = (void *)1; |
| 1026 | 1026 | hp_sdc.dev_err = hp_sdc_init(); |
| 1027 | 1027 | #endif |
| @@ -211,7 +211,7 @@ config INTEL_IOMMU_DEBUGFS · 210 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | config INTEL_IOMMU_SVM |
| 213 | 213 | bool "Support for Shared Virtual Memory with Intel IOMMU" |
| 214 | − depends on INTEL_IOMMU && X86 | |
| 214 | + depends on INTEL_IOMMU && X86_64 | |
| 215 | 215 | select PCI_PASID |
| 216 | 216 | select PCI_PRI |
| 217 | 217 | select MMU_NOTIFIER |
| @@ -898,7 +898,8 @@ int __init detect_intel_iommu(void) · 897 unmodified lines | ||
| 898 | 898 | if (!ret) |
| 899 | 899 | ret = dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl, |
| 900 | 900 | &validate_drhd_cb); |
| 901 | − if (!ret && !no_iommu && !iommu_detected && !dmar_disabled) { | |
| 901 | + if (!ret && !no_iommu && !iommu_detected && | |
| 902 | + (!dmar_disabled || dmar_platform_optin())) { | |
| 902 | 903 | iommu_detected = 1; |
| 903 | 904 | /* Make sure ACS will be enabled */ |
| 904 | 905 | pci_request_acs(); |
| @@ -612,6 +612,12 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) · 611 unmodified lines | ||
| 612 | 612 | return g_iommus[iommu_id]; |
| 613 | 613 | } |
| 614 | 614 | |
| 615 | +static inline bool iommu_paging_structure_coherency(struct intel_iommu *iommu) | |
| 616 | +{ | |
| 617 | + return sm_supported(iommu) ? | |
| 618 | + ecap_smpwc(iommu->ecap) : ecap_coherent(iommu->ecap); | |
| 619 | +} | |
| 620 | + | |
| 615 | 621 | static void domain_update_iommu_coherency(struct dmar_domain *domain) |
| 616 | 622 | { |
| 617 | 623 | struct dmar_drhd_unit *drhd; |
| @@ -623,7 +629,7 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) · 5 unmodified lines | ||
| 623 | 629 | |
| 624 | 630 | for_each_domain_iommu(i, domain) { |
| 625 | 631 | found = true; |
| 626 | − if (!ecap_coherent(g_iommus[i]->ecap)) { | |
| 632 | + if (!iommu_paging_structure_coherency(g_iommus[i])) { | |
| 627 | 633 | domain->iommu_coherency = 0; |
| 628 | 634 | break; |
| 629 | 635 | } |
| @@ -634,7 +640,7 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) · 4 unmodified lines | ||
| 634 | 640 | /* No hardware attached; use lowest common denominator */ |
| 635 | 641 | rcu_read_lock(); |
| 636 | 642 | for_each_active_iommu(iommu, drhd) { |
| 637 | − if (!ecap_coherent(iommu->ecap)) { | |
| 643 | + if (!iommu_paging_structure_coherency(iommu)) { | |
| 638 | 644 | domain->iommu_coherency = 0; |
| 639 | 645 | break; |
| 640 | 646 | } |
| @@ -921,7 +927,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, · 280 unmodified lines | ||
| 921 | 927 | domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE); |
| 922 | 928 | pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE; |
| 923 | 929 | if (domain_use_first_level(domain)) |
| 924 | − pteval |= DMA_FL_PTE_XD; | |
| 930 | + pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US; | |
| 925 | 931 | if (cmpxchg64(&pte->val, 0ULL, pteval)) |
| 926 | 932 | /* Someone else set it while we were thinking; use theirs. */ |
| 927 | 933 | free_pgtable_page(tmp_page); |
| @@ -1951,7 +1957,6 @@ static inline void · 1023 unmodified lines | ||
| 1951 | 1957 | context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid) |
| 1952 | 1958 | { |
| 1953 | 1959 | context->hi |= pasid & ((1 << 20) - 1); |
| 1954 | − context->hi |= (1 << 20); | |
| 1955 | 1960 | } |
| 1956 | 1961 | |
| 1957 | 1962 | /* |
| @@ -2095,7 +2100,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain, · 137 unmodified lines | ||
| 2095 | 2100 | |
| 2096 | 2101 | context_set_fault_enable(context); |
| 2097 | 2102 | context_set_present(context); |
| 2098 | − domain_flush_cache(domain, context, sizeof(*context)); | |
| 2103 | + if (!ecap_coherent(iommu->ecap)) | |
| 2104 | + clflush_cache_range(context, sizeof(*context)); | |
| 2099 | 2105 | |
| 2100 | 2106 | /* |
| 2101 | 2107 | * It's a non-present to present mapping. If hardware doesn't cache |
| @@ -2243,7 +2249,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, · 141 unmodified lines | ||
| 2243 | 2249 | |
| 2244 | 2250 | attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP); |
| 2245 | 2251 | if (domain_use_first_level(domain)) |
| 2246 | − attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD; | |
| 2252 | + attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD | DMA_FL_PTE_US; | |
| 2247 | 2253 | |
| 2248 | 2254 | if (!sg) { |
| 2249 | 2255 | sg_res = nr_pages; |
| @@ -2695,7 +2701,9 @@ static int __init si_domain_init(int hw) · 445 unmodified lines | ||
| 2695 | 2701 | end >> agaw_to_width(si_domain->agaw))) |
| 2696 | 2702 | continue; |
| 2697 | 2703 | |
| 2698 | − ret = iommu_domain_identity_map(si_domain, start, end); | |
| 2704 | + ret = iommu_domain_identity_map(si_domain, | |
| 2705 | + mm_to_dma_pfn(start >> PAGE_SHIFT), | |
| 2706 | + mm_to_dma_pfn(end >> PAGE_SHIFT)); | |
| 2699 | 2707 | if (ret) |
| 2700 | 2708 | return ret; |
| 2701 | 2709 | } |
| @@ -6021,6 +6029,23 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain, · 3319 unmodified lines | ||
| 6021 | 6029 | return ret; |
| 6022 | 6030 | } |
| 6023 | 6031 | |
| 6032 | +/* | |
| 6033 | + * Check that the device does not live on an external facing PCI port that is | |
| 6034 | + * marked as untrusted. Such devices should not be able to apply quirks and | |
| 6035 | + * thus not be able to bypass the IOMMU restrictions. | |
| 6036 | + */ | |
| 6037 | +static bool risky_device(struct pci_dev *pdev) | |
| 6038 | +{ | |
| 6039 | + if (pdev->untrusted) { | |
| 6040 | + pci_info(pdev, | |
| 6041 | + "Skipping IOMMU quirk for dev [%04X:%04X] on untrusted PCI link\n", | |
| 6042 | + pdev->vendor, pdev->device); | |
| 6043 | + pci_info(pdev, "Please check with your BIOS/Platform vendor about this\n"); | |
| 6044 | + return true; | |
| 6045 | + } | |
| 6046 | + return false; | |
| 6047 | +} | |
| 6048 | + | |
| 6024 | 6049 | const struct iommu_ops intel_iommu_ops = { |
| 6025 | 6050 | .capable = intel_iommu_capable, |
| 6026 | 6051 | .domain_alloc = intel_iommu_domain_alloc, |
| @@ -6060,6 +6085,9 @@ const struct iommu_ops intel_iommu_ops = { · 33 unmodified lines | ||
| 6060 | 6085 | |
| 6061 | 6086 | static void quirk_iommu_igfx(struct pci_dev *dev) |
| 6062 | 6087 | { |
| 6088 | + if (risky_device(dev)) | |
| 6089 | + return; | |
| 6090 | + | |
| 6063 | 6091 | pci_info(dev, "Disabling IOMMU for graphics on this chipset\n"); |
| 6064 | 6092 | dmar_map_gfx = 0; |
| 6065 | 6093 | } |
| @@ -6101,6 +6129,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); · 35 unmodified lines | ||
| 6101 | 6129 | |
| 6102 | 6130 | static void quirk_iommu_rwbf(struct pci_dev *dev) |
| 6103 | 6131 | { |
| 6132 | + if (risky_device(dev)) | |
| 6133 | + return; | |
| 6134 | + | |
| 6104 | 6135 | /* |
| 6105 | 6136 | * Mobile 4 Series Chipset neglects to set RWBF capability, |
| 6106 | 6137 | * but needs it. Same seems to hold for the desktop versions. |
| @@ -6131,6 +6162,9 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev) · 24 unmodified lines | ||
| 6131 | 6162 | { |
| 6132 | 6163 | unsigned short ggc; |
| 6133 | 6164 | |
| 6165 | + if (risky_device(dev)) | |
| 6166 | + return; | |
| 6167 | + | |
| 6134 | 6168 | if (pci_read_config_word(dev, GGC, &ggc)) |
| 6135 | 6169 | return; |
| 6136 | 6170 | |
| @@ -6164,6 +6198,12 @@ static void __init check_tylersburg_isoch(void) · 27 unmodified lines | ||
| 6164 | 6198 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL); |
| 6165 | 6199 | if (!pdev) |
| 6166 | 6200 | return; |
| 6201 | + | |
| 6202 | + if (risky_device(pdev)) { | |
| 6203 | + pci_dev_put(pdev); | |
| 6204 | + return; | |
| 6205 | + } | |
| 6206 | + | |
| 6167 | 6207 | pci_dev_put(pdev); |
| 6168 | 6208 | |
| 6169 | 6209 | /* System Management Registers. Might be hidden, in which case |
| @@ -6173,6 +6213,11 @@ static void __init check_tylersburg_isoch(void) · 3 unmodified lines | ||
| 6173 | 6213 | if (!pdev) |
| 6174 | 6214 | return; |
| 6175 | 6215 | |
| 6216 | + if (risky_device(pdev)) { | |
| 6217 | + pci_dev_put(pdev); | |
| 6218 | + return; | |
| 6219 | + } | |
| 6220 | + | |
| 6176 | 6221 | if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) { |
| 6177 | 6222 | pci_dev_put(pdev); |
| 6178 | 6223 | return; |
| @@ -563,7 +563,7 @@ config LOONGSON_PCH_PIC · 562 unmodified lines | ||
| 563 | 563 | Support for the Loongson PCH PIC Controller. |
| 564 | 564 | |
| 565 | 565 | config LOONGSON_PCH_MSI |
| 566 | − bool "Loongson PCH PIC Controller" | |
| 566 | + bool "Loongson PCH MSI Controller" | |
| 567 | 567 | depends on MACH_LOONGSON64 || COMPILE_TEST |
| 568 | 568 | depends on PCI |
| 569 | 569 | default MACH_LOONGSON64 |
| @@ -3797,10 +3797,10 @@ static void its_wait_vpt_parse_complete(void) · 3796 unmodified lines | ||
| 3797 | 3797 | if (!gic_rdists->has_vpend_valid_dirty) |
| 3798 | 3798 | return; |
| 3799 | 3799 | |
| 3800 | − WARN_ON_ONCE(readq_relaxed_poll_timeout(vlpi_base + GICR_VPENDBASER, | |
| 3801 | − val, | |
| 3802 | − !(val & GICR_VPENDBASER_Dirty), | |
| 3803 | − 10, 500)); | |
| 3800 | + WARN_ON_ONCE(readq_relaxed_poll_timeout_atomic(vlpi_base + GICR_VPENDBASER, | |
| 3801 | + val, | |
| 3802 | + !(val & GICR_VPENDBASER_Dirty), | |
| 3803 | + 10, 500)); | |
| 3804 | 3804 | } |
| 3805 | 3805 | |
| 3806 | 3806 | static void its_vpe_schedule(struct its_vpe *vpe) |
| @@ -329,10 +329,8 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) · 328 unmodified lines | ||
| 329 | 329 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, |
| 330 | 330 | bool force) |
| 331 | 331 | { |
| 332 | − void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); | |
| 333 | − unsigned int cpu, shift = (gic_irq(d) % 4) * 8; | |
| 334 | − u32 val, mask, bit; | |
| 335 | − unsigned long flags; | |
| 332 | + void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); | |
| 333 | + unsigned int cpu; | |
| 336 | 334 | |
| 337 | 335 | if (!force) |
| 338 | 336 | cpu = cpumask_any_and(mask_val, cpu_online_mask); |
| @@ -342,13 +340,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, · 3 unmodified lines | ||
| 342 | 340 | if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) |
| 343 | 341 | return -EINVAL; |
| 344 | 342 | |
| 345 | − gic_lock_irqsave(flags); | |
| 346 | − mask = 0xff << shift; | |
| 347 | − bit = gic_cpu_map[cpu] << shift; | |
| 348 | − val = readl_relaxed(reg) & ~mask; | |
| 349 | − writel_relaxed(val | bit, reg); | |
| 350 | − gic_unlock_irqrestore(flags); | |
| 351 | − | |
| 343 | + writeb_relaxed(gic_cpu_map[cpu], reg); | |
| 352 | 344 | irq_data_update_effective_affinity(d, cpumask_of(cpu)); |
| 353 | 345 | |
| 354 | 346 | return IRQ_SET_MASK_OK_DONE; |
| @@ -99,7 +99,7 @@ static int __init riscv_intc_init(struct device_node *node, · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | hartid = riscv_of_parent_hartid(node); |
| 101 | 101 | if (hartid < 0) { |
| 102 | − pr_warn("unable to fine hart id for %pOF\n", node); | |
| 102 | + pr_warn("unable to find hart id for %pOF\n", node); | |
| 103 | 103 | return 0; |
| 104 | 104 | } |
| 105 | 105 | |
| @@ -1389,7 +1389,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, · 1388 unmodified lines | ||
| 1389 | 1389 | if (__set_blocks(n1, n1->keys + n2->keys, |
| 1390 | 1390 | block_bytes(b->c)) > |
| 1391 | 1391 | btree_blocks(new_nodes[i])) |
| 1392 | − goto out_nocoalesce; | |
| 1392 | + goto out_unlock_nocoalesce; | |
| 1393 | 1393 | |
| 1394 | 1394 | keys = n2->keys; |
| 1395 | 1395 | /* Take the key of the node we're getting rid of */ |
| @@ -1418,7 +1418,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, · 22 unmodified lines | ||
| 1418 | 1418 | |
| 1419 | 1419 | if (__bch_keylist_realloc(&keylist, |
| 1420 | 1420 | bkey_u64s(&new_nodes[i]->key))) |
| 1421 | − goto out_nocoalesce; | |
| 1421 | + goto out_unlock_nocoalesce; | |
| 1422 | 1422 | |
| 1423 | 1423 | bch_btree_node_write(new_nodes[i], &cl); |
| 1424 | 1424 | bch_keylist_add(&keylist, &new_nodes[i]->key); |
| @@ -1464,6 +1464,10 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, · 39 unmodified lines | ||
| 1464 | 1464 | /* Invalidated our iterator */ |
| 1465 | 1465 | return -EINTR; |
| 1466 | 1466 | |
| 1467 | +out_unlock_nocoalesce: | |
| 1468 | + for (i = 0; i < nodes; i++) | |
| 1469 | + mutex_unlock(&new_nodes[i]->write_lock); | |
| 1470 | + | |
| 1467 | 1471 | out_nocoalesce: |
| 1468 | 1472 | closure_sync(&cl); |
| 1469 | 1473 | |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/genhd.h> |
| 20 | 20 | #include <linux/idr.h> |
| 21 | 21 | #include <linux/kthread.h> |
| 22 | +#include <linux/workqueue.h> | |
| 22 | 23 | #include <linux/module.h> |
| 23 | 24 | #include <linux/random.h> |
| 24 | 25 | #include <linux/reboot.h> |
| @@ -819,7 +820,8 @@ static void bcache_device_free(struct bcache_device *d) · 794 unmodified lines | ||
| 819 | 820 | } |
| 820 | 821 | |
| 821 | 822 | static int bcache_device_init(struct bcache_device *d, unsigned int block_size, |
| 822 | − sector_t sectors, make_request_fn make_request_fn) | |
| 823 | + sector_t sectors, make_request_fn make_request_fn, | |
| 824 | + struct block_device *cached_bdev) | |
| 823 | 825 | { |
| 824 | 826 | struct request_queue *q; |
| 825 | 827 | const size_t max_stripes = min_t(size_t, INT_MAX, |
| @@ -885,6 +887,20 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, · 59 unmodified lines | ||
| 885 | 887 | q->limits.io_min = block_size; |
| 886 | 888 | q->limits.logical_block_size = block_size; |
| 887 | 889 | q->limits.physical_block_size = block_size; |
| 890 | + | |
| 891 | + if (q->limits.logical_block_size > PAGE_SIZE && cached_bdev) { | |
| 892 | + /* | |
| 893 | + * This should only happen with BCACHE_SB_VERSION_BDEV. | |
| 894 | + * Block/page size is checked for BCACHE_SB_VERSION_CDEV. | |
| 895 | + */ | |
| 896 | + pr_info("%s: sb/logical block size (%u) greater than page size (%lu) falling back to device logical block size (%u)\n", | |
| 897 | + d->disk->disk_name, q->limits.logical_block_size, | |
| 898 | + PAGE_SIZE, bdev_logical_block_size(cached_bdev)); | |
| 899 | + | |
| 900 | + /* This also adjusts physical block size/min io size if needed */ | |
| 901 | + blk_queue_logical_block_size(q, bdev_logical_block_size(cached_bdev)); | |
| 902 | + } | |
| 903 | + | |
| 888 | 904 | blk_queue_flag_set(QUEUE_FLAG_NONROT, d->disk->queue); |
| 889 | 905 | blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, d->disk->queue); |
| 890 | 906 | blk_queue_flag_set(QUEUE_FLAG_DISCARD, d->disk->queue); |
| @@ -1340,7 +1356,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size) · 449 unmodified lines | ||
| 1340 | 1356 | |
| 1341 | 1357 | ret = bcache_device_init(&dc->disk, block_size, |
| 1342 | 1358 | dc->bdev->bd_part->nr_sects - dc->sb.data_offset, |
| 1343 | − cached_dev_make_request); | |
| 1359 | + cached_dev_make_request, dc->bdev); | |
| 1344 | 1360 | if (ret) |
| 1345 | 1361 | return ret; |
| 1346 | 1362 | |
| @@ -1453,7 +1469,7 @@ static int flash_dev_run(struct cache_set *c, struct uuid_entry *u) · 106 unmodified lines | ||
| 1453 | 1469 | kobject_init(&d->kobj, &bch_flash_dev_ktype); |
| 1454 | 1470 | |
| 1455 | 1471 | if (bcache_device_init(d, block_bytes(c), u->sectors, |
| 1456 | − flash_dev_make_request)) | |
| 1472 | + flash_dev_make_request, NULL)) | |
| 1457 | 1473 | goto err; |
| 1458 | 1474 | |
| 1459 | 1475 | bcache_device_attach(d, c, u - c->uuids); |
| @@ -2364,7 +2380,7 @@ static bool bch_is_open(struct block_device *bdev) · 904 unmodified lines | ||
| 2364 | 2380 | } |
| 2365 | 2381 | |
| 2366 | 2382 | struct async_reg_args { |
| 2367 | − struct work_struct reg_work; | |
| 2383 | + struct delayed_work reg_work; | |
| 2368 | 2384 | char *path; |
| 2369 | 2385 | struct cache_sb *sb; |
| 2370 | 2386 | struct cache_sb_disk *sb_disk; |
| @@ -2375,7 +2391,7 @@ static void register_bdev_worker(struct work_struct *work) · 4 unmodified lines | ||
| 2375 | 2391 | { |
| 2376 | 2392 | int fail = false; |
| 2377 | 2393 | struct async_reg_args *args = |
| 2378 | − container_of(work, struct async_reg_args, reg_work); | |
| 2394 | + container_of(work, struct async_reg_args, reg_work.work); | |
| 2379 | 2395 | struct cached_dev *dc; |
| 2380 | 2396 | |
| 2381 | 2397 | dc = kzalloc(sizeof(*dc), GFP_KERNEL); |
| @@ -2405,7 +2421,7 @@ static void register_cache_worker(struct work_struct *work) · 23 unmodified lines | ||
| 2405 | 2421 | { |
| 2406 | 2422 | int fail = false; |
| 2407 | 2423 | struct async_reg_args *args = |
| 2408 | − container_of(work, struct async_reg_args, reg_work); | |
| 2424 | + container_of(work, struct async_reg_args, reg_work.work); | |
| 2409 | 2425 | struct cache *ca; |
| 2410 | 2426 | |
| 2411 | 2427 | ca = kzalloc(sizeof(*ca), GFP_KERNEL); |
| @@ -2433,11 +2449,12 @@ out: · 21 unmodified lines | ||
| 2433 | 2449 | static void register_device_aync(struct async_reg_args *args) |
| 2434 | 2450 | { |
| 2435 | 2451 | if (SB_IS_BDEV(args->sb)) |
| 2436 | − INIT_WORK(&args->reg_work, register_bdev_worker); | |
| 2452 | + INIT_DELAYED_WORK(&args->reg_work, register_bdev_worker); | |
| 2437 | 2453 | else |
| 2438 | − INIT_WORK(&args->reg_work, register_cache_worker); | |
| 2454 | + INIT_DELAYED_WORK(&args->reg_work, register_cache_worker); | |
| 2439 | 2455 | |
| 2440 | − queue_work(system_wq, &args->reg_work); | |
| 2456 | + /* 10 jiffies is enough for a delay */ | |
| 2457 | + queue_delayed_work(system_wq, &args->reg_work, 10); | |
| 2441 | 2458 | } |
| 2442 | 2459 | |
| 2443 | 2460 | static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, |
| @@ -1471,7 +1471,7 @@ static void retrieve_deps(struct dm_table *table, · 1470 unmodified lines | ||
| 1471 | 1471 | /* |
| 1472 | 1472 | * Check we have enough space. |
| 1473 | 1473 | */ |
| 1474 | − needed = sizeof(*deps) + (sizeof(*deps->dev) * count); | |
| 1474 | + needed = struct_size(deps, dev, count); | |
| 1475 | 1475 | if (len < needed) { |
| 1476 | 1476 | param->flags |= DM_BUFFER_FULL_FLAG; |
| 1477 | 1477 | return; |
| @@ -282,6 +282,8 @@ static int persistent_memory_claim(struct dm_writecache *wc) · 281 unmodified lines | ||
| 282 | 282 | while (daa-- && i < p) { |
| 283 | 283 | pages[i++] = pfn_t_to_page(pfn); |
| 284 | 284 | pfn.val++; |
| 285 | + if (!(i & 15)) | |
| 286 | + cond_resched(); | |
| 285 | 287 | } |
| 286 | 288 | } while (i < p); |
| 287 | 289 | wc->memory_map = vmap(pages, p, VM_MAP, PAGE_KERNEL); |
| @@ -849,10 +851,14 @@ static void writecache_discard(struct dm_writecache *wc, sector_t start, sector_ · 561 unmodified lines | ||
| 849 | 851 | |
| 850 | 852 | if (likely(!e->write_in_progress)) { |
| 851 | 853 | if (!discarded_something) { |
| 852 | − writecache_wait_for_ios(wc, READ); | |
| 853 | − writecache_wait_for_ios(wc, WRITE); | |
| 854 | + if (!WC_MODE_PMEM(wc)) { | |
| 855 | + writecache_wait_for_ios(wc, READ); | |
| 856 | + writecache_wait_for_ios(wc, WRITE); | |
| 857 | + } | |
| 854 | 858 | discarded_something = true; |
| 855 | 859 | } |
| 860 | + if (!writecache_entry_is_committed(wc, e)) | |
| 861 | + wc->uncommitted_blocks--; | |
| 856 | 862 | writecache_free_entry(wc, e); |
| 857 | 863 | } |
| 858 | 864 | |
| @@ -1078,7 +1078,8 @@ static int dmz_check_sb(struct dmz_metadata *zmd, struct dmz_sb *dsb, · 1077 unmodified lines | ||
| 1078 | 1078 | nr_meta_zones = (le32_to_cpu(sb->nr_meta_blocks) + zmd->zone_nr_blocks - 1) |
| 1079 | 1079 | >> zmd->zone_nr_blocks_shift; |
| 1080 | 1080 | if (!nr_meta_zones || |
| 1081 | − nr_meta_zones >= zmd->nr_rnd_zones) { | |
| 1081 | + (zmd->nr_devs <= 1 && nr_meta_zones >= zmd->nr_rnd_zones) || | |
| 1082 | + (zmd->nr_devs > 1 && nr_meta_zones >= zmd->nr_cache_zones)) { | |
| 1082 | 1083 | dmz_dev_err(dev, "Invalid number of metadata blocks"); |
| 1083 | 1084 | return -ENXIO; |
| 1084 | 1085 | } |
| @@ -1949,7 +1950,7 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd, · 864 unmodified lines | ||
| 1949 | 1950 | unsigned int idx, bool idle) |
| 1950 | 1951 | { |
| 1951 | 1952 | struct dm_zone *dzone = NULL; |
| 1952 | − struct dm_zone *zone, *last = NULL; | |
| 1953 | + struct dm_zone *zone, *maxw_z = NULL; | |
| 1953 | 1954 | struct list_head *zone_list; |
| 1954 | 1955 | |
| 1955 | 1956 | /* If we have cache zones select from the cache zone list */ |
| @@ -1961,18 +1962,37 @@ static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd, · 5 unmodified lines | ||
| 1961 | 1962 | } else |
| 1962 | 1963 | zone_list = &zmd->dev[idx].map_rnd_list; |
| 1963 | 1964 | |
| 1965 | + /* | |
| 1966 | + * Find the buffer zone with the heaviest weight or the first (oldest) | |
| 1967 | + * data zone that can be reclaimed. | |
| 1968 | + */ | |
| 1964 | 1969 | list_for_each_entry(zone, zone_list, link) { |
| 1965 | 1970 | if (dmz_is_buf(zone)) { |
| 1966 | 1971 | dzone = zone->bzone; |
| 1967 | − if (dzone->dev->dev_idx != idx) | |
| 1968 | − continue; | |
| 1969 | − if (!last) { | |
| 1970 | − last = dzone; | |
| 1972 | + if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx) | |
| 1971 | 1973 | continue; |
| 1972 | − } | |
| 1973 | − if (last->weight < dzone->weight) | |
| 1974 | + if (!maxw_z || maxw_z->weight < dzone->weight) | |
| 1975 | + maxw_z = dzone; | |
| 1976 | + } else { | |
| 1977 | + dzone = zone; | |
| 1978 | + if (dmz_lock_zone_reclaim(dzone)) | |
| 1979 | + return dzone; | |
| 1980 | + } | |
| 1981 | + } | |
| 1982 | + | |
| 1983 | + if (maxw_z && dmz_lock_zone_reclaim(maxw_z)) | |
| 1984 | + return maxw_z; | |
| 1985 | + | |
| 1986 | + /* | |
| 1987 | + * If we come here, none of the zones inspected could be locked for | |
| 1988 | + * reclaim. Try again, being more aggressive, that is, find the | |
| 1989 | + * first zone that can be reclaimed regardless of its weitght. | |
| 1990 | + */ | |
| 1991 | + list_for_each_entry(zone, zone_list, link) { | |
| 1992 | + if (dmz_is_buf(zone)) { | |
| 1993 | + dzone = zone->bzone; | |
| 1994 | + if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx) | |
| 1974 | 1995 | continue; |
| 1975 | − dzone = last; | |
| 1976 | 1996 | } else |
| 1977 | 1997 | dzone = zone; |
| 1978 | 1998 | if (dmz_lock_zone_reclaim(dzone)) |
| @@ -2006,7 +2026,7 @@ static struct dm_zone *dmz_get_seq_zone_for_reclaim(struct dmz_metadata *zmd, · 27 unmodified lines | ||
| 2006 | 2026 | struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, |
| 2007 | 2027 | unsigned int dev_idx, bool idle) |
| 2008 | 2028 | { |
| 2009 | − struct dm_zone *zone; | |
| 2029 | + struct dm_zone *zone = NULL; | |
| 2010 | 2030 | |
| 2011 | 2031 | /* |
| 2012 | 2032 | * Search for a zone candidate to reclaim: 2 cases are possible. |
| @@ -2019,7 +2039,7 @@ struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, · 6 unmodified lines | ||
| 2019 | 2039 | dmz_lock_map(zmd); |
| 2020 | 2040 | if (list_empty(&zmd->reserved_seq_zones_list)) |
| 2021 | 2041 | zone = dmz_get_seq_zone_for_reclaim(zmd, dev_idx); |
| 2022 | − else | |
| 2042 | + if (!zone) | |
| 2023 | 2043 | zone = dmz_get_rnd_zone_for_reclaim(zmd, dev_idx, idle); |
| 2024 | 2044 | dmz_unlock_map(zmd); |
| 2025 | 2045 | |
| @@ -377,6 +377,7 @@ static int dmz_do_reclaim(struct dmz_reclaim *zrc) · 376 unmodified lines | ||
| 377 | 377 | dmz_metadata_label(zmd), zrc->dev_idx); |
| 378 | 378 | return -EBUSY; |
| 379 | 379 | } |
| 380 | + rzone = dzone; | |
| 380 | 381 | |
| 381 | 382 | start = jiffies; |
| 382 | 383 | if (dmz_is_cache(dzone) || dmz_is_rnd(dzone)) { |
| @@ -391,8 +392,6 @@ static int dmz_do_reclaim(struct dmz_reclaim *zrc) · 8 unmodified lines | ||
| 391 | 392 | */ |
| 392 | 393 | ret = dmz_reclaim_rnd_data(zrc, dzone); |
| 393 | 394 | } |
| 394 | − rzone = dzone; | |
| 395 | − | |
| 396 | 395 | } else { |
| 397 | 396 | struct dm_zone *bzone = dzone->bzone; |
| 398 | 397 | sector_t chunk_block = 0; |
| @@ -415,7 +414,6 @@ static int dmz_do_reclaim(struct dmz_reclaim *zrc) · 16 unmodified lines | ||
| 415 | 414 | * be later reclaimed. |
| 416 | 415 | */ |
| 417 | 416 | ret = dmz_reclaim_seq_data(zrc, dzone); |
| 418 | − rzone = dzone; | |
| 419 | 417 | } |
| 420 | 418 | } |
| 421 | 419 | out: |
| @@ -890,7 +890,7 @@ static int dmz_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 889 unmodified lines | ||
| 890 | 890 | } |
| 891 | 891 | |
| 892 | 892 | /* Set target (no write same support) */ |
| 893 | − ti->max_io_len = dmz_zone_nr_sectors(dmz->metadata) << 9; | |
| 893 | + ti->max_io_len = dmz_zone_nr_sectors(dmz->metadata); | |
| 894 | 894 | ti->num_flush_bios = 1; |
| 895 | 895 | ti->num_discard_bios = 1; |
| 896 | 896 | ti->num_write_zeroes_bios = 1; |
| @@ -1009,6 +1009,7 @@ static void clone_endio(struct bio *bio) · 1008 unmodified lines | ||
| 1009 | 1009 | struct dm_io *io = tio->io; |
| 1010 | 1010 | struct mapped_device *md = tio->io->md; |
| 1011 | 1011 | dm_endio_fn endio = tio->ti->type->end_io; |
| 1012 | + struct bio *orig_bio = io->orig_bio; | |
| 1012 | 1013 | |
| 1013 | 1014 | if (unlikely(error == BLK_STS_TARGET) && md->type != DM_TYPE_NVME_BIO_BASED) { |
| 1014 | 1015 | if (bio_op(bio) == REQ_OP_DISCARD && |
| @@ -1022,6 +1023,18 @@ static void clone_endio(struct bio *bio) · 7 unmodified lines | ||
| 1022 | 1023 | disable_write_zeroes(md); |
| 1023 | 1024 | } |
| 1024 | 1025 | |
| 1026 | + /* | |
| 1027 | + * For zone-append bios get offset in zone of the written | |
| 1028 | + * sector and add that to the original bio sector pos. | |
| 1029 | + */ | |
| 1030 | + if (bio_op(orig_bio) == REQ_OP_ZONE_APPEND) { | |
| 1031 | + sector_t written_sector = bio->bi_iter.bi_sector; | |
| 1032 | + struct request_queue *q = orig_bio->bi_disk->queue; | |
| 1033 | + u64 mask = (u64)blk_queue_zone_sectors(q) - 1; | |
| 1034 | + | |
| 1035 | + orig_bio->bi_iter.bi_sector += written_sector & mask; | |
| 1036 | + } | |
| 1037 | + | |
| 1025 | 1038 | if (endio) { |
| 1026 | 1039 | int r = endio(tio->ti, bio, &error); |
| 1027 | 1040 | switch (r) { |
| @@ -39,8 +39,6 @@ · 38 unmodified lines | ||
| 39 | 39 | * Troy Laramy <t-laramy@ti.com> |
| 40 | 40 | */ |
| 41 | 41 | |
| 42 | −#include <asm/cacheflush.h> | |
| 43 | − | |
| 44 | 42 | #include <linux/clk.h> |
| 45 | 43 | #include <linux/clkdev.h> |
| 46 | 44 | #include <linux/delay.h> |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/sched.h> |
| 19 | 19 | #include <linux/slab.h> |
| 20 | 20 | #include <linux/vmalloc.h> |
| 21 | −#include <asm/cacheflush.h> | |
| 22 | 21 | |
| 23 | 22 | #include <media/v4l2-dev.h> |
| 24 | 23 | #include <media/v4l2-ioctl.h> |
| @@ -193,7 +193,7 @@ struct pwc_raw_frame { · 192 unmodified lines | ||
| 193 | 193 | decompressor) */ |
| 194 | 194 | __u8 cmd[4]; /* the four byte of the command (in case of |
| 195 | 195 | nala, only the first 3 bytes is filled) */ |
| 196 | − __u8 rawframe[0]; /* frame_size = H / 4 * vbandlength */ | |
| 196 | + __u8 rawframe[]; /* frame_size = H / 4 * vbandlength */ | |
| 197 | 197 | } __packed; |
| 198 | 198 | |
| 199 | 199 | /* intermediate buffers with raw data from the USB cam */ |
| @@ -1324,13 +1324,13 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) · 1323 unmodified lines | ||
| 1324 | 1324 | return 0; /* fw doesn't need any host buffers */ |
| 1325 | 1325 | |
| 1326 | 1326 | /* spin till we get enough memory */ |
| 1327 | − while(host_page_buffer_sz > 0) { | |
| 1328 | − | |
| 1329 | − if((ioc->HostPageBuffer = pci_alloc_consistent( | |
| 1330 | − ioc->pcidev, | |
| 1331 | − host_page_buffer_sz, | |
| 1332 | − &ioc->HostPageBuffer_dma)) != NULL) { | |
| 1333 | − | |
| 1327 | + while (host_page_buffer_sz > 0) { | |
| 1328 | + ioc->HostPageBuffer = | |
| 1329 | + dma_alloc_coherent(&ioc->pcidev->dev, | |
| 1330 | + host_page_buffer_sz, | |
| 1331 | + &ioc->HostPageBuffer_dma, | |
| 1332 | + GFP_KERNEL); | |
| 1333 | + if (ioc->HostPageBuffer) { | |
| 1334 | 1334 | dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
| 1335 | 1335 | "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", |
| 1336 | 1336 | ioc->name, ioc->HostPageBuffer, |
| @@ -2741,8 +2741,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) · 1404 unmodified lines | ||
| 2741 | 2741 | sz = ioc->alloc_sz; |
| 2742 | 2742 | dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n", |
| 2743 | 2743 | ioc->name, ioc->alloc, ioc->alloc_sz)); |
| 2744 | − pci_free_consistent(ioc->pcidev, sz, | |
| 2745 | − ioc->alloc, ioc->alloc_dma); | |
| 2744 | + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc, | |
| 2745 | + ioc->alloc_dma); | |
| 2746 | 2746 | ioc->reply_frames = NULL; |
| 2747 | 2747 | ioc->req_frames = NULL; |
| 2748 | 2748 | ioc->alloc = NULL; |
| @@ -2751,8 +2751,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) · 2 unmodified lines | ||
| 2751 | 2751 | |
| 2752 | 2752 | if (ioc->sense_buf_pool != NULL) { |
| 2753 | 2753 | sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); |
| 2754 | − pci_free_consistent(ioc->pcidev, sz, | |
| 2755 | − ioc->sense_buf_pool, ioc->sense_buf_pool_dma); | |
| 2754 | + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool, | |
| 2755 | + ioc->sense_buf_pool_dma); | |
| 2756 | 2756 | ioc->sense_buf_pool = NULL; |
| 2757 | 2757 | ioc->alloc_total -= sz; |
| 2758 | 2758 | } |
| @@ -2802,7 +2802,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) · 43 unmodified lines | ||
| 2802 | 2802 | "HostPageBuffer free @ %p, sz=%d bytes\n", |
| 2803 | 2803 | ioc->name, ioc->HostPageBuffer, |
| 2804 | 2804 | ioc->HostPageBuffer_sz)); |
| 2805 | − pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, | |
| 2805 | + dma_free_coherent(&ioc->pcidev->dev, ioc->HostPageBuffer_sz, | |
| 2806 | 2806 | ioc->HostPageBuffer, ioc->HostPageBuffer_dma); |
| 2807 | 2807 | ioc->HostPageBuffer = NULL; |
| 2808 | 2808 | ioc->HostPageBuffer_sz = 0; |
| @@ -4497,7 +4497,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc) · 1688 unmodified lines | ||
| 4497 | 4497 | ioc->name, sz, sz, num_chain)); |
| 4498 | 4498 | |
| 4499 | 4499 | total_size += sz; |
| 4500 | − mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma); | |
| 4500 | + mem = dma_alloc_coherent(&ioc->pcidev->dev, total_size, | |
| 4501 | + &alloc_dma, GFP_KERNEL); | |
| 4501 | 4502 | if (mem == NULL) { |
| 4502 | 4503 | printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n", |
| 4503 | 4504 | ioc->name); |
| @@ -4574,8 +4575,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc) · 70 unmodified lines | ||
| 4574 | 4575 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); |
| 4575 | 4576 | |
| 4576 | 4577 | sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); |
| 4577 | − ioc->sense_buf_pool = | |
| 4578 | − pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma); | |
| 4578 | + ioc->sense_buf_pool = dma_alloc_coherent(&ioc->pcidev->dev, sz, | |
| 4579 | + &ioc->sense_buf_pool_dma, GFP_KERNEL); | |
| 4579 | 4580 | if (ioc->sense_buf_pool == NULL) { |
| 4580 | 4581 | printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n", |
| 4581 | 4582 | ioc->name); |
| @@ -4613,18 +4614,16 @@ out_fail: · 31 unmodified lines | ||
| 4613 | 4614 | |
| 4614 | 4615 | if (ioc->alloc != NULL) { |
| 4615 | 4616 | sz = ioc->alloc_sz; |
| 4616 | − pci_free_consistent(ioc->pcidev, | |
| 4617 | − sz, | |
| 4618 | − ioc->alloc, ioc->alloc_dma); | |
| 4617 | + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc, | |
| 4618 | + ioc->alloc_dma); | |
| 4619 | 4619 | ioc->reply_frames = NULL; |
| 4620 | 4620 | ioc->req_frames = NULL; |
| 4621 | 4621 | ioc->alloc_total -= sz; |
| 4622 | 4622 | } |
| 4623 | 4623 | if (ioc->sense_buf_pool != NULL) { |
| 4624 | 4624 | sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); |
| 4625 | − pci_free_consistent(ioc->pcidev, | |
| 4626 | − sz, | |
| 4627 | − ioc->sense_buf_pool, ioc->sense_buf_pool_dma); | |
| 4625 | + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool, | |
| 4626 | + ioc->sense_buf_pool_dma); | |
| 4628 | 4627 | ioc->sense_buf_pool = NULL; |
| 4629 | 4628 | } |
| 4630 | 4629 | |
| @@ -118,8 +118,6 @@ int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); · 117 unmodified lines | ||
| 118 | 118 | int mptscsih_resume(struct pci_dev *pdev); |
| 119 | 119 | #endif |
| 120 | 120 | |
| 121 | −#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE | |
| 122 | − | |
| 123 | 121 | |
| 124 | 122 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 125 | 123 | /* |
| @@ -2422,7 +2420,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR · 2296 unmodified lines | ||
| 2422 | 2420 | /* Copy the sense received into the scsi command block. */ |
| 2423 | 2421 | req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); |
| 2424 | 2422 | sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); |
| 2425 | − memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc)); | |
| 2423 | + memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC); | |
| 2426 | 2424 | |
| 2427 | 2425 | /* Log SMART data (asc = 0x5D, non-IM case only) if required. |
| 2428 | 2426 | */ |
| @@ -412,6 +412,7 @@ MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id); · 411 unmodified lines | ||
| 412 | 412 | |
| 413 | 413 | static struct i2c_driver mt6360_pmu_driver = { |
| 414 | 414 | .driver = { |
| 415 | + .name = "mt6360_pmu", | |
| 415 | 416 | .pm = &mt6360_pmu_pm_ops, |
| 416 | 417 | .of_match_table = of_match_ptr(mt6360_pmu_of_id), |
| 417 | 418 | }, |
| @@ -62,6 +62,12 @@ static void hl_fence_release(struct dma_fence *fence) · 61 unmodified lines | ||
| 62 | 62 | container_of(fence, struct hl_cs_compl, base_fence); |
| 63 | 63 | struct hl_device *hdev = hl_cs_cmpl->hdev; |
| 64 | 64 | |
| 65 | + /* EBUSY means the CS was never submitted and hence we don't have | |
| 66 | + * an attached hw_sob object that we should handle here | |
| 67 | + */ | |
| 68 | + if (fence->error == -EBUSY) | |
| 69 | + goto free; | |
| 70 | + | |
| 65 | 71 | if ((hl_cs_cmpl->type == CS_TYPE_SIGNAL) || |
| 66 | 72 | (hl_cs_cmpl->type == CS_TYPE_WAIT)) { |
| 67 | 73 | |
| @@ -92,6 +98,7 @@ static void hl_fence_release(struct dma_fence *fence) · 24 unmodified lines | ||
| 92 | 98 | kref_put(&hl_cs_cmpl->hw_sob->kref, hl_sob_reset); |
| 93 | 99 | } |
| 94 | 100 | |
| 101 | +free: | |
| 95 | 102 | kfree_rcu(hl_cs_cmpl, base_fence.rcu); |
| 96 | 103 | } |
| 97 | 104 | |
| @@ -328,10 +335,16 @@ static void cs_do_release(struct kref *ref) · 230 unmodified lines | ||
| 328 | 335 | |
| 329 | 336 | hl_ctx_put(cs->ctx); |
| 330 | 337 | |
| 338 | + /* We need to mark an error for not submitted because in that case | |
| 339 | + * the dma fence release flow is different. Mainly, we don't need | |
| 340 | + * to handle hw_sob for signal/wait | |
| 341 | + */ | |
| 331 | 342 | if (cs->timedout) |
| 332 | 343 | dma_fence_set_error(cs->fence, -ETIMEDOUT); |
| 333 | 344 | else if (cs->aborted) |
| 334 | 345 | dma_fence_set_error(cs->fence, -EIO); |
| 346 | + else if (!cs->submitted) | |
| 347 | + dma_fence_set_error(cs->fence, -EBUSY); | |
| 335 | 348 | |
| 336 | 349 | dma_fence_signal(cs->fence); |
| 337 | 350 | dma_fence_put(cs->fence); |
| @@ -480,7 +480,7 @@ out: · 479 unmodified lines | ||
| 480 | 480 | return 0; |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | −static ssize_t mmu_write(struct file *file, const char __user *buf, | |
| 483 | +static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf, | |
| 484 | 484 | size_t count, loff_t *f_pos) |
| 485 | 485 | { |
| 486 | 486 | struct seq_file *s = file->private_data; |
| @@ -1125,7 +1125,7 @@ static const struct hl_info_list hl_debugfs_list[] = { · 638 unmodified lines | ||
| 1125 | 1125 | {"command_submission_jobs", command_submission_jobs_show, NULL}, |
| 1126 | 1126 | {"userptr", userptr_show, NULL}, |
| 1127 | 1127 | {"vm", vm_show, NULL}, |
| 1128 | − {"mmu", mmu_show, mmu_write}, | |
| 1128 | + {"mmu", mmu_show, mmu_asid_va_write}, | |
| 1129 | 1129 | {"engines", engines_show, NULL} |
| 1130 | 1130 | }; |
| 1131 | 1131 | |
| @@ -96,7 +96,7 @@ · 95 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | #define GAUDI_NUM_OF_QM_ARB_ERR_CAUSE 3 |
| 98 | 98 | |
| 99 | −#define GAUDI_ARB_WDT_TIMEOUT 0x400000 | |
| 99 | +#define GAUDI_ARB_WDT_TIMEOUT 0x1000000 | |
| 100 | 100 | |
| 101 | 101 | static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { |
| 102 | 102 | "gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3", |
| @@ -1893,6 +1893,8 @@ static void gaudi_init_pci_dma_qman(struct hl_device *hdev, int dma_id, · 1790 unmodified lines | ||
| 1893 | 1893 | WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_LO_0 + q_off, so_base_ws_lo); |
| 1894 | 1894 | WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_HI_0 + q_off, so_base_ws_hi); |
| 1895 | 1895 | |
| 1896 | + WREG32(mmDMA0_QM_CP_BARRIER_CFG_0 + q_off, 0x100); | |
| 1897 | + | |
| 1896 | 1898 | /* The following configuration is needed only once per QMAN */ |
| 1897 | 1899 | if (qman_id == 0) { |
| 1898 | 1900 | /* Configure RAZWI IRQ */ |
| @@ -2725,6 +2727,12 @@ static int gaudi_mmu_init(struct hl_device *hdev) · 826 unmodified lines | ||
| 2725 | 2727 | WREG32(mmSTLB_HOP_CONFIGURATION, |
| 2726 | 2728 | hdev->mmu_huge_page_opt ? 0x30440 : 0x40440); |
| 2727 | 2729 | |
| 2730 | + /* | |
| 2731 | + * The H/W expects the first PI after init to be 1. After wraparound | |
| 2732 | + * we'll write 0. | |
| 2733 | + */ | |
| 2734 | + gaudi->mmu_cache_inv_pi = 1; | |
| 2735 | + | |
| 2728 | 2736 | gaudi->hw_cap_initialized |= HW_CAP_MMU; |
| 2729 | 2737 | |
| 2730 | 2738 | return 0; |
| @@ -3790,6 +3798,25 @@ static int gaudi_validate_dma_pkt_no_mmu(struct hl_device *hdev, · 1059 unmodified lines | ||
| 3790 | 3798 | src_in_host); |
| 3791 | 3799 | } |
| 3792 | 3800 | |
| 3801 | +static int gaudi_validate_load_and_exe_pkt(struct hl_device *hdev, | |
| 3802 | + struct hl_cs_parser *parser, | |
| 3803 | + struct packet_load_and_exe *user_pkt) | |
| 3804 | +{ | |
| 3805 | + u32 cfg; | |
| 3806 | + | |
| 3807 | + cfg = le32_to_cpu(user_pkt->cfg); | |
| 3808 | + | |
| 3809 | + if (cfg & GAUDI_PKT_LOAD_AND_EXE_CFG_DST_MASK) { | |
| 3810 | + dev_err(hdev->dev, | |
| 3811 | + "User not allowed to use Load and Execute\n"); | |
| 3812 | + return -EPERM; | |
| 3813 | + } | |
| 3814 | + | |
| 3815 | + parser->patched_cb_size += sizeof(struct packet_load_and_exe); | |
| 3816 | + | |
| 3817 | + return 0; | |
| 3818 | +} | |
| 3819 | + | |
| 3793 | 3820 | static int gaudi_validate_cb(struct hl_device *hdev, |
| 3794 | 3821 | struct hl_cs_parser *parser, bool is_mmu) |
| 3795 | 3822 | { |
| @@ -3838,6 +3865,11 @@ static int gaudi_validate_cb(struct hl_device *hdev, · 42 unmodified lines | ||
| 3838 | 3865 | rc = -EPERM; |
| 3839 | 3866 | break; |
| 3840 | 3867 | |
| 3868 | + case PACKET_LOAD_AND_EXE: | |
| 3869 | + rc = gaudi_validate_load_and_exe_pkt(hdev, parser, | |
| 3870 | + (struct packet_load_and_exe *) user_pkt); | |
| 3871 | + break; | |
| 3872 | + | |
| 3841 | 3873 | case PACKET_LIN_DMA: |
| 3842 | 3874 | parser->contains_dma_pkt = true; |
| 3843 | 3875 | if (is_mmu) |
| @@ -3855,7 +3887,6 @@ static int gaudi_validate_cb(struct hl_device *hdev, · 11 unmodified lines | ||
| 3855 | 3887 | case PACKET_FENCE: |
| 3856 | 3888 | case PACKET_NOP: |
| 3857 | 3889 | case PACKET_ARB_POINT: |
| 3858 | − case PACKET_LOAD_AND_EXE: | |
| 3859 | 3890 | parser->patched_cb_size += pkt_size; |
| 3860 | 3891 | break; |
| 3861 | 3892 | |
| @@ -5994,6 +6025,8 @@ static int gaudi_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard, · 2132 unmodified lines | ||
| 5994 | 6025 | mutex_lock(&hdev->mmu_cache_lock); |
| 5995 | 6026 | |
| 5996 | 6027 | /* L0 & L1 invalidation */ |
| 6028 | + WREG32(mmSTLB_INV_PS, 3); | |
| 6029 | + WREG32(mmSTLB_CACHE_INV, gaudi->mmu_cache_inv_pi++); | |
| 5997 | 6030 | WREG32(mmSTLB_INV_PS, 2); |
| 5998 | 6031 | |
| 5999 | 6032 | rc = hl_poll_timeout( |
| @@ -229,6 +229,8 @@ struct gaudi_internal_qman_info { · 228 unmodified lines | ||
| 229 | 229 | * @multi_msi_mode: whether we are working in multi MSI single MSI mode. |
| 230 | 230 | * Multi MSI is possible only with IOMMU enabled. |
| 231 | 231 | * @ext_queue_idx: helper index for external queues initialization. |
| 232 | + * @mmu_cache_inv_pi: PI for MMU cache invalidation flow. The H/W expects an | |
| 233 | + * 8-bit value so use u8. | |
| 232 | 234 | */ |
| 233 | 235 | struct gaudi_device { |
| 234 | 236 | int (*armcp_info_get)(struct hl_device *hdev); |
| @@ -248,6 +250,7 @@ struct gaudi_device { · 13 unmodified lines | ||
| 248 | 250 | u32 hw_cap_initialized; |
| 249 | 251 | u8 multi_msi_mode; |
| 250 | 252 | u8 ext_queue_idx; |
| 253 | + u8 mmu_cache_inv_pi; | |
| 251 | 254 | }; |
| 252 | 255 | |
| 253 | 256 | void gaudi_init_security(struct hl_device *hdev); |
| @@ -197,6 +197,9 @@ struct packet_wait { · 196 unmodified lines | ||
| 197 | 197 | __le32 ctl; |
| 198 | 198 | }; |
| 199 | 199 | |
| 200 | +#define GAUDI_PKT_LOAD_AND_EXE_CFG_DST_SHIFT 0 | |
| 201 | +#define GAUDI_PKT_LOAD_AND_EXE_CFG_DST_MASK 0x00000001 | |
| 202 | + | |
| 200 | 203 | struct packet_load_and_exe { |
| 201 | 204 | __le32 cfg; |
| 202 | 205 | __le32 ctl; |
| @@ -828,7 +828,7 @@ static void run_plant_and_detach_test(int is_early) · 827 unmodified lines | ||
| 828 | 828 | char before[BREAK_INSTR_SIZE]; |
| 829 | 829 | char after[BREAK_INSTR_SIZE]; |
| 830 | 830 | |
| 831 | − probe_kernel_read(before, (char *)kgdbts_break_test, | |
| 831 | + copy_from_kernel_nofault(before, (char *)kgdbts_break_test, | |
| 832 | 832 | BREAK_INSTR_SIZE); |
| 833 | 833 | init_simple_test(); |
| 834 | 834 | ts.tst = plant_and_detach_test; |
| @@ -836,8 +836,8 @@ static void run_plant_and_detach_test(int is_early) · 1 unmodified line | ||
| 836 | 836 | /* Activate test with initial breakpoint */ |
| 837 | 837 | if (!is_early) |
| 838 | 838 | kgdb_breakpoint(); |
| 839 | − probe_kernel_read(after, (char *)kgdbts_break_test, | |
| 840 | − BREAK_INSTR_SIZE); | |
| 839 | + copy_from_kernel_nofault(after, (char *)kgdbts_break_test, | |
| 840 | + BREAK_INSTR_SIZE); | |
| 841 | 841 | if (memcmp(before, after, BREAK_INSTR_SIZE)) { |
| 842 | 842 | printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n"); |
| 843 | 843 | panic("kgdb memory corruption"); |
| @@ -94,6 +94,7 @@ · 93 unmodified lines | ||
| 94 | 94 | #define MEI_DEV_ID_JSP_N 0x4DE0 /* Jasper Lake Point N */ |
| 95 | 95 | |
| 96 | 96 | #define MEI_DEV_ID_TGP_LP 0xA0E0 /* Tiger Lake Point LP */ |
| 97 | +#define MEI_DEV_ID_TGP_H 0x43E0 /* Tiger Lake Point H */ | |
| 97 | 98 | |
| 98 | 99 | #define MEI_DEV_ID_MCC 0x4B70 /* Mule Creek Canyon (EHL) */ |
| 99 | 100 | #define MEI_DEV_ID_MCC_4 0x4B75 /* Mule Creek Canyon 4 (EHL) */ |
| @@ -107,6 +108,8 @@ · 7 unmodified lines | ||
| 107 | 108 | # define PCI_CFG_HFS_1_D0I3_MSK 0x80000000 |
| 108 | 109 | #define PCI_CFG_HFS_2 0x48 |
| 109 | 110 | #define PCI_CFG_HFS_3 0x60 |
| 111 | +# define PCI_CFG_HFS_3_FW_SKU_MSK 0x00000070 | |
| 112 | +# define PCI_CFG_HFS_3_FW_SKU_SPS 0x00000060 | |
| 110 | 113 | #define PCI_CFG_HFS_4 0x64 |
| 111 | 114 | #define PCI_CFG_HFS_5 0x68 |
| 112 | 115 | #define PCI_CFG_HFS_6 0x6C |
| @@ -1366,7 +1366,7 @@ static bool mei_me_fw_type_nm(struct pci_dev *pdev) · 1365 unmodified lines | ||
| 1366 | 1366 | #define MEI_CFG_FW_NM \ |
| 1367 | 1367 | .quirk_probe = mei_me_fw_type_nm |
| 1368 | 1368 | |
| 1369 | −static bool mei_me_fw_type_sps(struct pci_dev *pdev) | |
| 1369 | +static bool mei_me_fw_type_sps_4(struct pci_dev *pdev) | |
| 1370 | 1370 | { |
| 1371 | 1371 | u32 reg; |
| 1372 | 1372 | unsigned int devfn; |
| @@ -1382,7 +1382,36 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev) · 9 unmodified lines | ||
| 1382 | 1382 | return (reg & 0xf0000) == 0xf0000; |
| 1383 | 1383 | } |
| 1384 | 1384 | |
| 1385 | −#define MEI_CFG_FW_SPS \ | |
| 1385 | +#define MEI_CFG_FW_SPS_4 \ | |
| 1386 | + .quirk_probe = mei_me_fw_type_sps_4 | |
| 1387 | + | |
| 1388 | +/** | |
| 1389 | + * mei_me_fw_sku_sps() - check for sps sku | |
| 1390 | + * | |
| 1391 | + * Read ME FW Status register to check for SPS Firmware. | |
| 1392 | + * The SPS FW is only signaled in pci function 0 | |
| 1393 | + * | |
| 1394 | + * @pdev: pci device | |
| 1395 | + * | |
| 1396 | + * Return: true in case of SPS firmware | |
| 1397 | + */ | |
| 1398 | +static bool mei_me_fw_type_sps(struct pci_dev *pdev) | |
| 1399 | +{ | |
| 1400 | + u32 reg; | |
| 1401 | + u32 fw_type; | |
| 1402 | + unsigned int devfn; | |
| 1403 | + | |
| 1404 | + devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); | |
| 1405 | + pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_3, ®); | |
| 1406 | + trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_3", PCI_CFG_HFS_3, reg); | |
| 1407 | + fw_type = (reg & PCI_CFG_HFS_3_FW_SKU_MSK); | |
| 1408 | + | |
| 1409 | + dev_dbg(&pdev->dev, "fw type is %d\n", fw_type); | |
| 1410 | + | |
| 1411 | + return fw_type == PCI_CFG_HFS_3_FW_SKU_SPS; | |
| 1412 | +} | |
| 1413 | + | |
| 1414 | +#define MEI_CFG_FW_SPS \ | |
| 1386 | 1415 | .quirk_probe = mei_me_fw_type_sps |
| 1387 | 1416 | |
| 1388 | 1417 | #define MEI_CFG_FW_VER_SUPP \ |
| @@ -1452,10 +1481,17 @@ static const struct mei_cfg mei_me_pch8_cfg = { · 63 unmodified lines | ||
| 1452 | 1481 | }; |
| 1453 | 1482 | |
| 1454 | 1483 | /* PCH8 Lynx Point with quirk for SPS Firmware exclusion */ |
| 1455 | −static const struct mei_cfg mei_me_pch8_sps_cfg = { | |
| 1484 | +static const struct mei_cfg mei_me_pch8_sps_4_cfg = { | |
| 1456 | 1485 | MEI_CFG_PCH8_HFS, |
| 1457 | 1486 | MEI_CFG_FW_VER_SUPP, |
| 1458 | − MEI_CFG_FW_SPS, | |
| 1487 | + MEI_CFG_FW_SPS_4, | |
| 1488 | +}; | |
| 1489 | + | |
| 1490 | +/* LBG with quirk for SPS (4.0) Firmware exclusion */ | |
| 1491 | +static const struct mei_cfg mei_me_pch12_sps_4_cfg = { | |
| 1492 | + MEI_CFG_PCH8_HFS, | |
| 1493 | + MEI_CFG_FW_VER_SUPP, | |
| 1494 | + MEI_CFG_FW_SPS_4, | |
| 1459 | 1495 | }; |
| 1460 | 1496 | |
| 1461 | 1497 | /* Cannon Lake and newer devices */ |
| @@ -1465,8 +1501,18 @@ static const struct mei_cfg mei_me_pch12_cfg = { · 3 unmodified lines | ||
| 1465 | 1501 | MEI_CFG_DMA_128, |
| 1466 | 1502 | }; |
| 1467 | 1503 | |
| 1468 | −/* LBG with quirk for SPS Firmware exclusion */ | |
| 1504 | +/* Cannon Lake with quirk for SPS 5.0 and newer Firmware exclusion */ | |
| 1469 | 1505 | static const struct mei_cfg mei_me_pch12_sps_cfg = { |
| 1506 | + MEI_CFG_PCH8_HFS, | |
| 1507 | + MEI_CFG_FW_VER_SUPP, | |
| 1508 | + MEI_CFG_DMA_128, | |
| 1509 | + MEI_CFG_FW_SPS, | |
| 1510 | +}; | |
| 1511 | + | |
| 1512 | +/* Cannon Lake with quirk for SPS 5.0 and newer Firmware exclusion | |
| 1513 | + * w/o DMA support | |
| 1514 | + */ | |
| 1515 | +static const struct mei_cfg mei_me_pch12_nodma_sps_cfg = { | |
| 1470 | 1516 | MEI_CFG_PCH8_HFS, |
| 1471 | 1517 | MEI_CFG_FW_VER_SUPP, |
| 1472 | 1518 | MEI_CFG_FW_SPS, |
| @@ -1480,6 +1526,15 @@ static const struct mei_cfg mei_me_pch15_cfg = { · 7 unmodified lines | ||
| 1480 | 1526 | MEI_CFG_TRC, |
| 1481 | 1527 | }; |
| 1482 | 1528 | |
| 1529 | +/* Tiger Lake with quirk for SPS 5.0 and newer Firmware exclusion */ | |
| 1530 | +static const struct mei_cfg mei_me_pch15_sps_cfg = { | |
| 1531 | + MEI_CFG_PCH8_HFS, | |
| 1532 | + MEI_CFG_FW_VER_SUPP, | |
| 1533 | + MEI_CFG_DMA_128, | |
| 1534 | + MEI_CFG_TRC, | |
| 1535 | + MEI_CFG_FW_SPS, | |
| 1536 | +}; | |
| 1537 | + | |
| 1483 | 1538 | /* |
| 1484 | 1539 | * mei_cfg_list - A list of platform platform specific configurations. |
| 1485 | 1540 | * Note: has to be synchronized with enum mei_cfg_idx. |
| @@ -1492,10 +1547,13 @@ static const struct mei_cfg *const mei_cfg_list[] = { · 6 unmodified lines | ||
| 1492 | 1547 | [MEI_ME_PCH7_CFG] = &mei_me_pch7_cfg, |
| 1493 | 1548 | [MEI_ME_PCH_CPT_PBG_CFG] = &mei_me_pch_cpt_pbg_cfg, |
| 1494 | 1549 | [MEI_ME_PCH8_CFG] = &mei_me_pch8_cfg, |
| 1495 | − [MEI_ME_PCH8_SPS_CFG] = &mei_me_pch8_sps_cfg, | |
| 1550 | + [MEI_ME_PCH8_SPS_4_CFG] = &mei_me_pch8_sps_4_cfg, | |
| 1496 | 1551 | [MEI_ME_PCH12_CFG] = &mei_me_pch12_cfg, |
| 1552 | + [MEI_ME_PCH12_SPS_4_CFG] = &mei_me_pch12_sps_4_cfg, | |
| 1497 | 1553 | [MEI_ME_PCH12_SPS_CFG] = &mei_me_pch12_sps_cfg, |
| 1554 | + [MEI_ME_PCH12_SPS_NODMA_CFG] = &mei_me_pch12_nodma_sps_cfg, | |
| 1498 | 1555 | [MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg, |
| 1556 | + [MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg, | |
| 1499 | 1557 | }; |
| 1500 | 1558 | |
| 1501 | 1559 | const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx) |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2012-2019, Intel Corporation. All rights reserved. | |
| 3 | + * Copyright (c) 2012-2020, Intel Corporation. All rights reserved. | |
| 4 | 4 | * Intel Management Engine Interface (Intel MEI) Linux driver |
| 5 | 5 | */ |
| 6 | 6 | |
| @@ -76,14 +76,20 @@ struct mei_me_hw { · 69 unmodified lines | ||
| 76 | 76 | * with quirk for Node Manager exclusion. |
| 77 | 77 | * @MEI_ME_PCH8_CFG: Platform Controller Hub Gen8 and newer |
| 78 | 78 | * client platforms. |
| 79 | − * @MEI_ME_PCH8_SPS_CFG: Platform Controller Hub Gen8 and newer | |
| 79 | + * @MEI_ME_PCH8_SPS_4_CFG: Platform Controller Hub Gen8 and newer | |
| 80 | 80 | * servers platforms with quirk for |
| 81 | 81 | * SPS firmware exclusion. |
| 82 | 82 | * @MEI_ME_PCH12_CFG: Platform Controller Hub Gen12 and newer |
| 83 | − * @MEI_ME_PCH12_SPS_CFG: Platform Controller Hub Gen12 and newer | |
| 83 | + * @MEI_ME_PCH12_SPS_4_CFG:Platform Controller Hub Gen12 up to 4.0 | |
| 84 | + * servers platforms with quirk for | |
| 85 | + * SPS firmware exclusion. | |
| 86 | + * @MEI_ME_PCH12_SPS_CFG: Platform Controller Hub Gen12 5.0 and newer | |
| 84 | 87 | * servers platforms with quirk for |
| 85 | 88 | * SPS firmware exclusion. |
| 86 | 89 | * @MEI_ME_PCH15_CFG: Platform Controller Hub Gen15 and newer |
| 90 | + * @MEI_ME_PCH15_SPS_CFG: Platform Controller Hub Gen15 and newer | |
| 91 | + * servers platforms with quirk for | |
| 92 | + * SPS firmware exclusion. | |
| 87 | 93 | * @MEI_ME_NUM_CFG: Upper Sentinel. |
| 88 | 94 | */ |
| 89 | 95 | enum mei_cfg_idx { |
| @@ -94,10 +100,13 @@ enum mei_cfg_idx { · 4 unmodified lines | ||
| 94 | 100 | MEI_ME_PCH7_CFG, |
| 95 | 101 | MEI_ME_PCH_CPT_PBG_CFG, |
| 96 | 102 | MEI_ME_PCH8_CFG, |
| 97 | − MEI_ME_PCH8_SPS_CFG, | |
| 103 | + MEI_ME_PCH8_SPS_4_CFG, | |
| 98 | 104 | MEI_ME_PCH12_CFG, |
| 105 | + MEI_ME_PCH12_SPS_4_CFG, | |
| 99 | 106 | MEI_ME_PCH12_SPS_CFG, |
| 107 | + MEI_ME_PCH12_SPS_NODMA_CFG, | |
| 100 | 108 | MEI_ME_PCH15_CFG, |
| 109 | + MEI_ME_PCH15_SPS_CFG, | |
| 101 | 110 | MEI_ME_NUM_CFG, |
| 102 | 111 | }; |
| 103 | 112 | |
| @@ -59,18 +59,18 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 58 unmodified lines | ||
| 59 | 59 | {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH7_CFG)}, |
| 60 | 60 | {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH7_CFG)}, |
| 61 | 61 | {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH7_CFG)}, |
| 62 | − {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_CFG)}, | |
| 63 | − {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_CFG)}, | |
| 62 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_4_CFG)}, | |
| 63 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_4_CFG)}, | |
| 64 | 64 | {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)}, |
| 65 | − {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_CFG)}, | |
| 65 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_4_CFG)}, | |
| 66 | 66 | {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, MEI_ME_PCH8_CFG)}, |
| 67 | 67 | {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, MEI_ME_PCH8_CFG)}, |
| 68 | 68 | |
| 69 | 69 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)}, |
| 70 | 70 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)}, |
| 71 | − {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)}, | |
| 72 | − {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)}, | |
| 73 | − {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_SPS_CFG)}, | |
| 71 | + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_4_CFG)}, | |
| 72 | + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_4_CFG)}, | |
| 73 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_SPS_4_CFG)}, | |
| 74 | 74 | |
| 75 | 75 | {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)}, |
| 76 | 76 | {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)}, |
| @@ -84,8 +84,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 7 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH12_CFG)}, |
| 86 | 86 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_3, MEI_ME_PCH8_CFG)}, |
| 87 | − {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_CFG)}, | |
| 88 | − {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_3, MEI_ME_PCH8_CFG)}, | |
| 87 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_SPS_CFG)}, | |
| 88 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_3, MEI_ME_PCH12_SPS_NODMA_CFG)}, | |
| 89 | 89 | |
| 90 | 90 | {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)}, |
| 91 | 91 | {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_CFG)}, |
| @@ -96,6 +96,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 4 unmodified lines | ||
| 96 | 96 | {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, |
| 97 | 97 | |
| 98 | 98 | {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)}, |
| 99 | + {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_H, MEI_ME_PCH15_SPS_CFG)}, | |
| 99 | 100 | |
| 100 | 101 | {MEI_PCI_DEVICE(MEI_DEV_ID_JSP_N, MEI_ME_PCH15_CFG)}, |
| 101 | 102 | |
| @@ -552,6 +552,8 @@ static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[], · 551 unmodified lines | ||
| 552 | 552 | static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf, |
| 553 | 553 | struct netlink_ext_ack *extack) |
| 554 | 554 | { |
| 555 | + memset(conf, 0, sizeof(*conf)); | |
| 556 | + | |
| 555 | 557 | if (!data[IFLA_BAREUDP_PORT]) { |
| 556 | 558 | NL_SET_ERR_MSG(extack, "port not specified"); |
| 557 | 559 | return -EINVAL; |
| @@ -570,6 +572,9 @@ static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf, · 12 unmodified lines | ||
| 570 | 572 | if (data[IFLA_BAREUDP_SRCPORT_MIN]) |
| 571 | 573 | conf->sport_min = nla_get_u16(data[IFLA_BAREUDP_SRCPORT_MIN]); |
| 572 | 574 | |
| 575 | + if (data[IFLA_BAREUDP_MULTIPROTO_MODE]) | |
| 576 | + conf->multi_proto_mode = true; | |
| 577 | + | |
| 573 | 578 | return 0; |
| 574 | 579 | } |
| 575 | 580 | |
| @@ -146,7 +146,7 @@ struct pciefd_rx_dma { · 145 unmodified lines | ||
| 146 | 146 | __le32 irq_status; |
| 147 | 147 | __le32 sys_time_low; |
| 148 | 148 | __le32 sys_time_high; |
| 149 | − struct pucan_rx_msg msg[0]; | |
| 149 | + struct pucan_rx_msg msg[]; | |
| 150 | 150 | } __packed __aligned(4); |
| 151 | 151 | |
| 152 | 152 | /* Tx Link record */ |
| @@ -194,7 +194,7 @@ struct pciefd_board { · 41 unmodified lines | ||
| 194 | 194 | struct pci_dev *pci_dev; |
| 195 | 195 | int can_count; |
| 196 | 196 | spinlock_t cmd_lock; /* 64-bits cmds must be atomic */ |
| 197 | − struct pciefd_can *can[0]; /* array of network devices */ | |
| 197 | + struct pciefd_can *can[]; /* array of network devices */ | |
| 198 | 198 | }; |
| 199 | 199 | |
| 200 | 200 | /* supported device ids. */ |
| @@ -1147,6 +1147,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) · 1146 unmodified lines | ||
| 1147 | 1147 | set_bit(0, priv->cfp.used); |
| 1148 | 1148 | set_bit(0, priv->cfp.unique); |
| 1149 | 1149 | |
| 1150 | + /* Balance of_node_put() done by of_find_node_by_name() */ | |
| 1151 | + of_node_get(dn); | |
| 1150 | 1152 | ports = of_find_node_by_name(dn, "ports"); |
| 1151 | 1153 | if (ports) { |
| 1152 | 1154 | bcm_sf2_identify_ports(priv, ports); |
| @@ -891,16 +891,16 @@ void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int port, · 890 unmodified lines | ||
| 891 | 891 | |
| 892 | 892 | mutex_lock(&ptp_data->lock); |
| 893 | 893 | |
| 894 | − rc = sja1105_ptpclkval_read(priv, &ticks, NULL); | |
| 894 | + rc = sja1105_ptpegr_ts_poll(ds, port, &ts); | |
| 895 | 895 | if (rc < 0) { |
| 896 | − dev_err(ds->dev, "Failed to read PTP clock: %d\n", rc); | |
| 896 | + dev_err(ds->dev, "timed out polling for tstamp\n"); | |
| 897 | 897 | kfree_skb(skb); |
| 898 | 898 | goto out; |
| 899 | 899 | } |
| 900 | 900 | |
| 901 | − rc = sja1105_ptpegr_ts_poll(ds, port, &ts); | |
| 901 | + rc = sja1105_ptpclkval_read(priv, &ticks, NULL); | |
| 902 | 902 | if (rc < 0) { |
| 903 | − dev_err(ds->dev, "timed out polling for tstamp\n"); | |
| 903 | + dev_err(ds->dev, "Failed to read PTP clock: %d\n", rc); | |
| 904 | 904 | kfree_skb(skb); |
| 905 | 905 | goto out; |
| 906 | 906 | } |
| @@ -7,6 +7,165 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #define SJA1105_SIZE_VL_STATUS 8 |
| 9 | 9 | |
| 10 | +/* Insert into the global gate list, sorted by gate action time. */ | |
| 11 | +static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg, | |
| 12 | + struct sja1105_rule *rule, | |
| 13 | + u8 gate_state, s64 entry_time, | |
| 14 | + struct netlink_ext_ack *extack) | |
| 15 | +{ | |
| 16 | + struct sja1105_gate_entry *e; | |
| 17 | + int rc; | |
| 18 | + | |
| 19 | + e = kzalloc(sizeof(*e), GFP_KERNEL); | |
| 20 | + if (!e) | |
| 21 | + return -ENOMEM; | |
| 22 | + | |
| 23 | + e->rule = rule; | |
| 24 | + e->gate_state = gate_state; | |
| 25 | + e->interval = entry_time; | |
| 26 | + | |
| 27 | + if (list_empty(&gating_cfg->entries)) { | |
| 28 | + list_add(&e->list, &gating_cfg->entries); | |
| 29 | + } else { | |
| 30 | + struct sja1105_gate_entry *p; | |
| 31 | + | |
| 32 | + list_for_each_entry(p, &gating_cfg->entries, list) { | |
| 33 | + if (p->interval == e->interval) { | |
| 34 | + NL_SET_ERR_MSG_MOD(extack, | |
| 35 | + "Gate conflict"); | |
| 36 | + rc = -EBUSY; | |
| 37 | + goto err; | |
| 38 | + } | |
| 39 | + | |
| 40 | + if (e->interval < p->interval) | |
| 41 | + break; | |
| 42 | + } | |
| 43 | + list_add(&e->list, p->list.prev); | |
| 44 | + } | |
| 45 | + | |
| 46 | + gating_cfg->num_entries++; | |
| 47 | + | |
| 48 | + return 0; | |
| 49 | +err: | |
| 50 | + kfree(e); | |
| 51 | + return rc; | |
| 52 | +} | |
| 53 | + | |
| 54 | +/* The gate entries contain absolute times in their e->interval field. Convert | |
| 55 | + * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5"). | |
| 56 | + */ | |
| 57 | +static void | |
| 58 | +sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg, | |
| 59 | + u64 cycle_time) | |
| 60 | +{ | |
| 61 | + struct sja1105_gate_entry *last_e; | |
| 62 | + struct sja1105_gate_entry *e; | |
| 63 | + struct list_head *prev; | |
| 64 | + | |
| 65 | + list_for_each_entry(e, &gating_cfg->entries, list) { | |
| 66 | + struct sja1105_gate_entry *p; | |
| 67 | + | |
| 68 | + prev = e->list.prev; | |
| 69 | + | |
| 70 | + if (prev == &gating_cfg->entries) | |
| 71 | + continue; | |
| 72 | + | |
| 73 | + p = list_entry(prev, struct sja1105_gate_entry, list); | |
| 74 | + p->interval = e->interval - p->interval; | |
| 75 | + } | |
| 76 | + last_e = list_last_entry(&gating_cfg->entries, | |
| 77 | + struct sja1105_gate_entry, list); | |
| 78 | + last_e->interval = cycle_time - last_e->interval; | |
| 79 | +} | |
| 80 | + | |
| 81 | +static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg) | |
| 82 | +{ | |
| 83 | + struct sja1105_gate_entry *e, *n; | |
| 84 | + | |
| 85 | + list_for_each_entry_safe(e, n, &gating_cfg->entries, list) { | |
| 86 | + list_del(&e->list); | |
| 87 | + kfree(e); | |
| 88 | + } | |
| 89 | +} | |
| 90 | + | |
| 91 | +static int sja1105_compose_gating_subschedule(struct sja1105_private *priv, | |
| 92 | + struct netlink_ext_ack *extack) | |
| 93 | +{ | |
| 94 | + struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg; | |
| 95 | + struct sja1105_rule *rule; | |
| 96 | + s64 max_cycle_time = 0; | |
| 97 | + s64 its_base_time = 0; | |
| 98 | + int i, rc = 0; | |
| 99 | + | |
| 100 | + sja1105_free_gating_config(gating_cfg); | |
| 101 | + | |
| 102 | + list_for_each_entry(rule, &priv->flow_block.rules, list) { | |
| 103 | + if (rule->type != SJA1105_RULE_VL) | |
| 104 | + continue; | |
| 105 | + if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) | |
| 106 | + continue; | |
| 107 | + | |
| 108 | + if (max_cycle_time < rule->vl.cycle_time) { | |
| 109 | + max_cycle_time = rule->vl.cycle_time; | |
| 110 | + its_base_time = rule->vl.base_time; | |
| 111 | + } | |
| 112 | + } | |
| 113 | + | |
| 114 | + if (!max_cycle_time) | |
| 115 | + return 0; | |
| 116 | + | |
| 117 | + dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n", | |
| 118 | + max_cycle_time, its_base_time); | |
| 119 | + | |
| 120 | + gating_cfg->base_time = its_base_time; | |
| 121 | + gating_cfg->cycle_time = max_cycle_time; | |
| 122 | + gating_cfg->num_entries = 0; | |
| 123 | + | |
| 124 | + list_for_each_entry(rule, &priv->flow_block.rules, list) { | |
| 125 | + s64 time; | |
| 126 | + s64 rbt; | |
| 127 | + | |
| 128 | + if (rule->type != SJA1105_RULE_VL) | |
| 129 | + continue; | |
| 130 | + if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) | |
| 131 | + continue; | |
| 132 | + | |
| 133 | + /* Calculate the difference between this gating schedule's | |
| 134 | + * base time, and the base time of the gating schedule with the | |
| 135 | + * longest cycle time. We call it the relative base time (rbt). | |
| 136 | + */ | |
| 137 | + rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time, | |
| 138 | + its_base_time); | |
| 139 | + rbt -= its_base_time; | |
| 140 | + | |
| 141 | + time = rbt; | |
| 142 | + | |
| 143 | + for (i = 0; i < rule->vl.num_entries; i++) { | |
| 144 | + u8 gate_state = rule->vl.entries[i].gate_state; | |
| 145 | + s64 entry_time = time; | |
| 146 | + | |
| 147 | + while (entry_time < max_cycle_time) { | |
| 148 | + rc = sja1105_insert_gate_entry(gating_cfg, rule, | |
| 149 | + gate_state, | |
| 150 | + entry_time, | |
| 151 | + extack); | |
| 152 | + if (rc) | |
| 153 | + goto err; | |
| 154 | + | |
| 155 | + entry_time += rule->vl.cycle_time; | |
| 156 | + } | |
| 157 | + time += rule->vl.entries[i].interval; | |
| 158 | + } | |
| 159 | + } | |
| 160 | + | |
| 161 | + sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time); | |
| 162 | + | |
| 163 | + return 0; | |
| 164 | +err: | |
| 165 | + sja1105_free_gating_config(gating_cfg); | |
| 166 | + return rc; | |
| 167 | +} | |
| 168 | + | |
| 10 | 169 | /* The switch flow classification core implements TTEthernet, which 'thinks' in |
| 11 | 170 | * terms of Virtual Links (VL), a concept borrowed from ARINC 664 part 7. |
| 12 | 171 | * However it also has one other operating mode (VLLUPFORMAT=0) where it acts |
| @@ -342,7 +501,9 @@ int sja1105_vl_redirect(struct sja1105_private *priv, int port, · 329 unmodified lines | ||
| 342 | 501 | NL_SET_ERR_MSG_MOD(extack, |
| 343 | 502 | "Can only redirect based on DMAC"); |
| 344 | 503 | return -EOPNOTSUPP; |
| 345 | − } else if (key->type != SJA1105_KEY_VLAN_AWARE_VL) { | |
| 504 | + } else if ((priv->vlan_state == SJA1105_VLAN_BEST_EFFORT || | |
| 505 | + priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) && | |
| 506 | + key->type != SJA1105_KEY_VLAN_AWARE_VL) { | |
| 346 | 507 | NL_SET_ERR_MSG_MOD(extack, |
| 347 | 508 | "Can only redirect based on {DMAC, VID, PCP}"); |
| 348 | 509 | return -EOPNOTSUPP; |
| @@ -388,171 +549,19 @@ int sja1105_vl_delete(struct sja1105_private *priv, int port, · 39 unmodified lines | ||
| 388 | 549 | kfree(rule); |
| 389 | 550 | } |
| 390 | 551 | |
| 391 | − rc = sja1105_init_virtual_links(priv, extack); | |
| 552 | + rc = sja1105_compose_gating_subschedule(priv, extack); | |
| 392 | 553 | if (rc) |
| 393 | 554 | return rc; |
| 394 | 555 | |
| 395 | − return sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS); | |
| 396 | −} | |
| 397 | − | |
| 398 | −/* Insert into the global gate list, sorted by gate action time. */ | |
| 399 | −static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg, | |
| 400 | − struct sja1105_rule *rule, | |
| 401 | − u8 gate_state, s64 entry_time, | |
| 402 | − struct netlink_ext_ack *extack) | |
| 403 | −{ | |
| 404 | − struct sja1105_gate_entry *e; | |
| 405 | − int rc; | |
| 406 | − | |
| 407 | − e = kzalloc(sizeof(*e), GFP_KERNEL); | |
| 408 | − if (!e) | |
| 409 | − return -ENOMEM; | |
| 410 | − | |
| 411 | − e->rule = rule; | |
| 412 | − e->gate_state = gate_state; | |
| 413 | − e->interval = entry_time; | |
| 414 | − | |
| 415 | − if (list_empty(&gating_cfg->entries)) { | |
| 416 | − list_add(&e->list, &gating_cfg->entries); | |
| 417 | − } else { | |
| 418 | − struct sja1105_gate_entry *p; | |
| 419 | − | |
| 420 | − list_for_each_entry(p, &gating_cfg->entries, list) { | |
| 421 | − if (p->interval == e->interval) { | |
| 422 | − NL_SET_ERR_MSG_MOD(extack, | |
| 423 | − "Gate conflict"); | |
| 424 | − rc = -EBUSY; | |
| 425 | − goto err; | |
| 426 | − } | |
| 427 | − | |
| 428 | − if (e->interval < p->interval) | |
| 429 | − break; | |
| 430 | − } | |
| 431 | − list_add(&e->list, p->list.prev); | |
| 432 | − } | |
| 433 | − | |
| 434 | − gating_cfg->num_entries++; | |
| 435 | − | |
| 436 | − return 0; | |
| 437 | −err: | |
| 438 | − kfree(e); | |
| 439 | − return rc; | |
| 440 | −} | |
| 441 | − | |
| 442 | −/* The gate entries contain absolute times in their e->interval field. Convert | |
| 443 | − * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5"). | |
| 444 | − */ | |
| 445 | −static void | |
| 446 | −sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg, | |
| 447 | − u64 cycle_time) | |
| 448 | −{ | |
| 449 | − struct sja1105_gate_entry *last_e; | |
| 450 | − struct sja1105_gate_entry *e; | |
| 451 | − struct list_head *prev; | |
| 452 | − | |
| 453 | − list_for_each_entry(e, &gating_cfg->entries, list) { | |
| 454 | − struct sja1105_gate_entry *p; | |
| 455 | − | |
| 456 | − prev = e->list.prev; | |
| 457 | − | |
| 458 | − if (prev == &gating_cfg->entries) | |
| 459 | − continue; | |
| 460 | − | |
| 461 | − p = list_entry(prev, struct sja1105_gate_entry, list); | |
| 462 | − p->interval = e->interval - p->interval; | |
| 463 | − } | |
| 464 | − last_e = list_last_entry(&gating_cfg->entries, | |
| 465 | − struct sja1105_gate_entry, list); | |
| 466 | − if (last_e->list.prev != &gating_cfg->entries) | |
| 467 | − last_e->interval = cycle_time - last_e->interval; | |
| 468 | −} | |
| 469 | − | |
| 470 | −static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg) | |
| 471 | −{ | |
| 472 | − struct sja1105_gate_entry *e, *n; | |
| 473 | − | |
| 474 | − list_for_each_entry_safe(e, n, &gating_cfg->entries, list) { | |
| 475 | − list_del(&e->list); | |
| 476 | − kfree(e); | |
| 477 | − } | |
| 478 | −} | |
| 479 | − | |
| 480 | −static int sja1105_compose_gating_subschedule(struct sja1105_private *priv, | |
| 481 | − struct netlink_ext_ack *extack) | |
| 482 | −{ | |
| 483 | − struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg; | |
| 484 | − struct sja1105_rule *rule; | |
| 485 | − s64 max_cycle_time = 0; | |
| 486 | − s64 its_base_time = 0; | |
| 487 | − int i, rc = 0; | |
| 488 | − | |
| 489 | − list_for_each_entry(rule, &priv->flow_block.rules, list) { | |
| 490 | − if (rule->type != SJA1105_RULE_VL) | |
| 491 | − continue; | |
| 492 | − if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) | |
| 493 | − continue; | |
| 494 | − | |
| 495 | − if (max_cycle_time < rule->vl.cycle_time) { | |
| 496 | − max_cycle_time = rule->vl.cycle_time; | |
| 497 | − its_base_time = rule->vl.base_time; | |
| 498 | − } | |
| 499 | − } | |
| 500 | − | |
| 501 | − if (!max_cycle_time) | |
| 502 | − return 0; | |
| 503 | − | |
| 504 | − dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n", | |
| 505 | − max_cycle_time, its_base_time); | |
| 506 | − | |
| 507 | − sja1105_free_gating_config(gating_cfg); | |
| 508 | − | |
| 509 | − gating_cfg->base_time = its_base_time; | |
| 510 | − gating_cfg->cycle_time = max_cycle_time; | |
| 511 | − gating_cfg->num_entries = 0; | |
| 512 | − | |
| 513 | − list_for_each_entry(rule, &priv->flow_block.rules, list) { | |
| 514 | − s64 time; | |
| 515 | − s64 rbt; | |
| 516 | − | |
| 517 | − if (rule->type != SJA1105_RULE_VL) | |
| 518 | − continue; | |
| 519 | − if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED) | |
| 520 | − continue; | |
| 521 | − | |
| 522 | − /* Calculate the difference between this gating schedule's | |
| 523 | − * base time, and the base time of the gating schedule with the | |
| 524 | − * longest cycle time. We call it the relative base time (rbt). | |
| 525 | − */ | |
| 526 | − rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time, | |
| 527 | − its_base_time); | |
| 528 | − rbt -= its_base_time; | |
| 529 | − | |
| 530 | − time = rbt; | |
| 531 | − | |
| 532 | − for (i = 0; i < rule->vl.num_entries; i++) { | |
| 533 | − u8 gate_state = rule->vl.entries[i].gate_state; | |
| 534 | − s64 entry_time = time; | |
| 535 | − | |
| 536 | − while (entry_time < max_cycle_time) { | |
| 537 | − rc = sja1105_insert_gate_entry(gating_cfg, rule, | |
| 538 | − gate_state, | |
| 539 | − entry_time, | |
| 540 | − extack); | |
| 541 | − if (rc) | |
| 542 | − goto err; | |
| 543 | − | |
| 544 | − entry_time += rule->vl.cycle_time; | |
| 545 | − } | |
| 546 | − time += rule->vl.entries[i].interval; | |
| 547 | − } | |
| 548 | − } | |
| 556 | + rc = sja1105_init_virtual_links(priv, extack); | |
| 557 | + if (rc) | |
| 558 | + return rc; | |
| 549 | 559 | |
| 550 | − sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time); | |
| 560 | + rc = sja1105_init_scheduling(priv); | |
| 561 | + if (rc < 0) | |
| 562 | + return rc; | |
| 551 | 563 | |
| 552 | − return 0; | |
| 553 | −err: | |
| 554 | − sja1105_free_gating_config(gating_cfg); | |
| 555 | − return rc; | |
| 564 | + return sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS); | |
| 556 | 565 | } |
| 557 | 566 | |
| 558 | 567 | int sja1105_vl_gate(struct sja1105_private *priv, int port, |
| @@ -588,14 +597,12 @@ int sja1105_vl_gate(struct sja1105_private *priv, int port, · 29 unmodified lines | ||
| 588 | 597 | |
| 589 | 598 | if (priv->vlan_state == SJA1105_VLAN_UNAWARE && |
| 590 | 599 | key->type != SJA1105_KEY_VLAN_UNAWARE_VL) { |
| 591 | − dev_err(priv->ds->dev, "1: vlan state %d key type %d\n", | |
| 592 | − priv->vlan_state, key->type); | |
| 593 | 600 | NL_SET_ERR_MSG_MOD(extack, |
| 594 | 601 | "Can only gate based on DMAC"); |
| 595 | 602 | return -EOPNOTSUPP; |
| 596 | − } else if (key->type != SJA1105_KEY_VLAN_AWARE_VL) { | |
| 597 | − dev_err(priv->ds->dev, "2: vlan state %d key type %d\n", | |
| 598 | − priv->vlan_state, key->type); | |
| 603 | + } else if ((priv->vlan_state == SJA1105_VLAN_BEST_EFFORT || | |
| 604 | + priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) && | |
| 605 | + key->type != SJA1105_KEY_VLAN_AWARE_VL) { | |
| 599 | 606 | NL_SET_ERR_MSG_MOD(extack, |
| 600 | 607 | "Can only gate based on {DMAC, VID, PCP}"); |
| 601 | 608 | return -EOPNOTSUPP; |
| @@ -1249,8 +1249,12 @@ out_disable_adv_intr: · 1248 unmodified lines | ||
| 1249 | 1249 | |
| 1250 | 1250 | static void __alx_stop(struct alx_priv *alx) |
| 1251 | 1251 | { |
| 1252 | − alx_halt(alx); | |
| 1253 | 1252 | alx_free_irq(alx); |
| 1253 | + | |
| 1254 | + cancel_work_sync(&alx->link_check_wk); | |
| 1255 | + cancel_work_sync(&alx->reset_wk); | |
| 1256 | + | |
| 1257 | + alx_halt(alx); | |
| 1254 | 1258 | alx_free_rings(alx); |
| 1255 | 1259 | alx_free_napis(alx); |
| 1256 | 1260 | } |
| @@ -1855,9 +1859,6 @@ static void alx_remove(struct pci_dev *pdev) · 598 unmodified lines | ||
| 1855 | 1859 | struct alx_priv *alx = pci_get_drvdata(pdev); |
| 1856 | 1860 | struct alx_hw *hw = &alx->hw; |
| 1857 | 1861 | |
| 1858 | − cancel_work_sync(&alx->link_check_wk); | |
| 1859 | − cancel_work_sync(&alx->reset_wk); | |
| 1860 | − | |
| 1861 | 1862 | /* restore permanent mac address */ |
| 1862 | 1863 | alx_set_macaddr(hw, hw->perm_addr); |
| 1863 | 1864 | |
| @@ -6292,6 +6292,7 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) · 6291 unmodified lines | ||
| 6292 | 6292 | |
| 6293 | 6293 | static void bnxt_hwrm_stat_ctx_free(struct bnxt *bp) |
| 6294 | 6294 | { |
| 6295 | + struct hwrm_stat_ctx_clr_stats_input req0 = {0}; | |
| 6295 | 6296 | struct hwrm_stat_ctx_free_input req = {0}; |
| 6296 | 6297 | int i; |
| 6297 | 6298 | |
| @@ -6301,6 +6302,7 @@ static void bnxt_hwrm_stat_ctx_free(struct bnxt *bp) · 3 unmodified lines | ||
| 6301 | 6302 | if (BNXT_CHIP_TYPE_NITRO_A0(bp)) |
| 6302 | 6303 | return; |
| 6303 | 6304 | |
| 6305 | + bnxt_hwrm_cmd_hdr_init(bp, &req0, HWRM_STAT_CTX_CLR_STATS, -1, -1); | |
| 6304 | 6306 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_STAT_CTX_FREE, -1, -1); |
| 6305 | 6307 | |
| 6306 | 6308 | mutex_lock(&bp->hwrm_cmd_lock); |
| @@ -6310,7 +6312,11 @@ static void bnxt_hwrm_stat_ctx_free(struct bnxt *bp) · 3 unmodified lines | ||
| 6310 | 6312 | |
| 6311 | 6313 | if (cpr->hw_stats_ctx_id != INVALID_STATS_CTX_ID) { |
| 6312 | 6314 | req.stat_ctx_id = cpu_to_le32(cpr->hw_stats_ctx_id); |
| 6313 | − | |
| 6315 | + if (BNXT_FW_MAJ(bp) <= 20) { | |
| 6316 | + req0.stat_ctx_id = req.stat_ctx_id; | |
| 6317 | + _hwrm_send_message(bp, &req0, sizeof(req0), | |
| 6318 | + HWRM_CMD_TIMEOUT); | |
| 6319 | + } | |
| 6314 | 6320 | _hwrm_send_message(bp, &req, sizeof(req), |
| 6315 | 6321 | HWRM_CMD_TIMEOUT); |
| 6316 | 6322 | |
| @@ -6976,7 +6982,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) · 659 unmodified lines | ||
| 6976 | 6982 | bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD; |
| 6977 | 6983 | |
| 6978 | 6984 | bp->tx_push_thresh = 0; |
| 6979 | − if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) | |
| 6985 | + if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) && | |
| 6986 | + BNXT_FW_MAJ(bp) > 217) | |
| 6980 | 6987 | bp->tx_push_thresh = BNXT_TX_PUSH_THRESH; |
| 6981 | 6988 | |
| 6982 | 6989 | hw_resc->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); |
| @@ -7240,8 +7247,9 @@ static int __bnxt_hwrm_ver_get(struct bnxt *bp, bool silent) · 257 unmodified lines | ||
| 7240 | 7247 | static int bnxt_hwrm_ver_get(struct bnxt *bp) |
| 7241 | 7248 | { |
| 7242 | 7249 | struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr; |
| 7250 | + u16 fw_maj, fw_min, fw_bld, fw_rsv; | |
| 7243 | 7251 | u32 dev_caps_cfg, hwrm_ver; |
| 7244 | − int rc; | |
| 7252 | + int rc, len; | |
| 7245 | 7253 | |
| 7246 | 7254 | bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN; |
| 7247 | 7255 | mutex_lock(&bp->hwrm_cmd_lock); |
| @@ -7273,9 +7281,22 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) · 25 unmodified lines | ||
| 7273 | 7281 | resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b, |
| 7274 | 7282 | resp->hwrm_intf_upd_8b); |
| 7275 | 7283 | |
| 7276 | − snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d.%d", | |
| 7277 | − resp->hwrm_fw_maj_8b, resp->hwrm_fw_min_8b, | |
| 7278 | − resp->hwrm_fw_bld_8b, resp->hwrm_fw_rsvd_8b); | |
| 7284 | + fw_maj = le16_to_cpu(resp->hwrm_fw_major); | |
| 7285 | + if (bp->hwrm_spec_code > 0x10803 && fw_maj) { | |
| 7286 | + fw_min = le16_to_cpu(resp->hwrm_fw_minor); | |
| 7287 | + fw_bld = le16_to_cpu(resp->hwrm_fw_build); | |
| 7288 | + fw_rsv = le16_to_cpu(resp->hwrm_fw_patch); | |
| 7289 | + len = FW_VER_STR_LEN; | |
| 7290 | + } else { | |
| 7291 | + fw_maj = resp->hwrm_fw_maj_8b; | |
| 7292 | + fw_min = resp->hwrm_fw_min_8b; | |
| 7293 | + fw_bld = resp->hwrm_fw_bld_8b; | |
| 7294 | + fw_rsv = resp->hwrm_fw_rsvd_8b; | |
| 7295 | + len = BC_HWRM_STR_LEN; | |
| 7296 | + } | |
| 7297 | + bp->fw_ver_code = BNXT_FW_VER_CODE(fw_maj, fw_min, fw_bld, fw_rsv); | |
| 7298 | + snprintf(bp->fw_ver_str, len, "%d.%d.%d.%d", fw_maj, fw_min, fw_bld, | |
| 7299 | + fw_rsv); | |
| 7279 | 7300 | |
| 7280 | 7301 | if (strlen(resp->active_pkg_name)) { |
| 7281 | 7302 | int fw_ver_len = strlen(bp->fw_ver_str); |
| @@ -10037,7 +10058,7 @@ static void bnxt_timer(struct timer_list *t) · 2755 unmodified lines | ||
| 10037 | 10058 | struct bnxt *bp = from_timer(bp, t, timer); |
| 10038 | 10059 | struct net_device *dev = bp->dev; |
| 10039 | 10060 | |
| 10040 | − if (!netif_running(dev)) | |
| 10061 | + if (!netif_running(dev) || !test_bit(BNXT_STATE_OPEN, &bp->state)) | |
| 10041 | 10062 | return; |
| 10042 | 10063 | |
| 10043 | 10064 | if (atomic_read(&bp->intr_sem) != 0) |
| @@ -11892,7 +11913,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 1848 unmodified lines | ||
| 11892 | 11913 | dev->ethtool_ops = &bnxt_ethtool_ops; |
| 11893 | 11914 | pci_set_drvdata(pdev, dev); |
| 11894 | 11915 | |
| 11895 | − bnxt_vpd_read_info(bp); | |
| 11916 | + if (BNXT_PF(bp)) | |
| 11917 | + bnxt_vpd_read_info(bp); | |
| 11896 | 11918 | |
| 11897 | 11919 | rc = bnxt_alloc_hwrm_resources(bp); |
| 11898 | 11920 | if (rc) |
| @@ -12133,19 +12155,9 @@ static int bnxt_resume(struct device *device) · 234 unmodified lines | ||
| 12133 | 12155 | goto resume_exit; |
| 12134 | 12156 | } |
| 12135 | 12157 | |
| 12136 | − if (bnxt_hwrm_queue_qportcfg(bp)) { | |
| 12137 | − rc = -ENODEV; | |
| 12158 | + rc = bnxt_hwrm_func_qcaps(bp); | |
| 12159 | + if (rc) | |
| 12138 | 12160 | goto resume_exit; |
| 12139 | − } | |
| 12140 | − | |
| 12141 | − if (bp->hwrm_spec_code >= 0x10803) { | |
| 12142 | − if (bnxt_alloc_ctx_mem(bp)) { | |
| 12143 | − rc = -ENODEV; | |
| 12144 | − goto resume_exit; | |
| 12145 | − } | |
| 12146 | − } | |
| 12147 | − if (BNXT_NEW_RM(bp)) | |
| 12148 | − bnxt_hwrm_func_resc_qcaps(bp, false); | |
| 12149 | 12161 | |
| 12150 | 12162 | if (bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false)) { |
| 12151 | 12163 | rc = -ENODEV; |
| @@ -12161,6 +12173,8 @@ static int bnxt_resume(struct device *device) · 9 unmodified lines | ||
| 12161 | 12173 | |
| 12162 | 12174 | resume_exit: |
| 12163 | 12175 | bnxt_ulp_start(bp, rc); |
| 12176 | + if (!rc) | |
| 12177 | + bnxt_reenable_sriov(bp); | |
| 12164 | 12178 | rtnl_unlock(); |
| 12165 | 12179 | return rc; |
| 12166 | 12180 | } |
| @@ -12204,6 +12218,9 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev, · 37 unmodified lines | ||
| 12204 | 12218 | bnxt_close(netdev); |
| 12205 | 12219 | |
| 12206 | 12220 | pci_disable_device(pdev); |
| 12221 | + bnxt_free_ctx_mem(bp); | |
| 12222 | + kfree(bp->ctx); | |
| 12223 | + bp->ctx = NULL; | |
| 12207 | 12224 | rtnl_unlock(); |
| 12208 | 12225 | |
| 12209 | 12226 | /* Request a slot slot reset. */ |
| @@ -12237,12 +12254,16 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 27 unmodified lines | ||
| 12237 | 12254 | pci_set_master(pdev); |
| 12238 | 12255 | |
| 12239 | 12256 | err = bnxt_hwrm_func_reset(bp); |
| 12240 | − if (!err && netif_running(netdev)) | |
| 12241 | − err = bnxt_open(netdev); | |
| 12242 | − | |
| 12243 | − if (!err) | |
| 12244 | − result = PCI_ERS_RESULT_RECOVERED; | |
| 12257 | + if (!err) { | |
| 12258 | + err = bnxt_hwrm_func_qcaps(bp); | |
| 12259 | + if (!err && netif_running(netdev)) | |
| 12260 | + err = bnxt_open(netdev); | |
| 12261 | + } | |
| 12245 | 12262 | bnxt_ulp_start(bp, err); |
| 12263 | + if (!err) { | |
| 12264 | + bnxt_reenable_sriov(bp); | |
| 12265 | + result = PCI_ERS_RESULT_RECOVERED; | |
| 12266 | + } | |
| 12246 | 12267 | } |
| 12247 | 12268 | |
| 12248 | 12269 | if (result != PCI_ERS_RESULT_RECOVERED) { |
| @@ -1746,6 +1746,11 @@ struct bnxt { · 1745 unmodified lines | ||
| 1746 | 1746 | #define PHY_VER_STR_LEN (FW_VER_STR_LEN - BC_HWRM_STR_LEN) |
| 1747 | 1747 | char fw_ver_str[FW_VER_STR_LEN]; |
| 1748 | 1748 | char hwrm_ver_supp[FW_VER_STR_LEN]; |
| 1749 | + u64 fw_ver_code; | |
| 1750 | +#define BNXT_FW_VER_CODE(maj, min, bld, rsv) \ | |
| 1751 | + ((u64)(maj) << 48 | (u64)(min) << 32 | (u64)(bld) << 16 | (rsv)) | |
| 1752 | +#define BNXT_FW_MAJ(bp) ((bp)->fw_ver_code >> 48) | |
| 1753 | + | |
| 1749 | 1754 | __be16 vxlan_port; |
| 1750 | 1755 | u8 vxlan_port_cnt; |
| 1751 | 1756 | __le16 vxlan_fw_dst_port_id; |
| @@ -1889,7 +1889,8 @@ static void bnxt_tc_setup_indr_rel(void *cb_priv) · 1888 unmodified lines | ||
| 1889 | 1889 | } |
| 1890 | 1890 | |
| 1891 | 1891 | static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp, |
| 1892 | − struct flow_block_offload *f) | |
| 1892 | + struct flow_block_offload *f, void *data, | |
| 1893 | + void (*cleanup)(struct flow_block_cb *block_cb)) | |
| 1893 | 1894 | { |
| 1894 | 1895 | struct bnxt_flower_indr_block_cb_priv *cb_priv; |
| 1895 | 1896 | struct flow_block_cb *block_cb; |
| @@ -1907,9 +1908,10 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp, · 11 unmodified lines | ||
| 1907 | 1908 | cb_priv->bp = bp; |
| 1908 | 1909 | list_add(&cb_priv->list, &bp->tc_indr_block_list); |
| 1909 | 1910 | |
| 1910 | − block_cb = flow_block_cb_alloc(bnxt_tc_setup_indr_block_cb, | |
| 1911 | − cb_priv, cb_priv, | |
| 1912 | − bnxt_tc_setup_indr_rel); | |
| 1911 | + block_cb = flow_indr_block_cb_alloc(bnxt_tc_setup_indr_block_cb, | |
| 1912 | + cb_priv, cb_priv, | |
| 1913 | + bnxt_tc_setup_indr_rel, f, | |
| 1914 | + netdev, data, bp, cleanup); | |
| 1913 | 1915 | if (IS_ERR(block_cb)) { |
| 1914 | 1916 | list_del(&cb_priv->list); |
| 1915 | 1917 | kfree(cb_priv); |
| @@ -1930,7 +1932,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp, · 14 unmodified lines | ||
| 1930 | 1932 | if (!block_cb) |
| 1931 | 1933 | return -ENOENT; |
| 1932 | 1934 | |
| 1933 | − flow_block_cb_remove(block_cb, f); | |
| 1935 | + flow_indr_block_cb_remove(block_cb, f); | |
| 1934 | 1936 | list_del(&block_cb->driver_list); |
| 1935 | 1937 | break; |
| 1936 | 1938 | default: |
| @@ -1945,14 +1947,17 @@ static bool bnxt_is_netdev_indr_offload(struct net_device *netdev) · 8 unmodified lines | ||
| 1945 | 1947 | } |
| 1946 | 1948 | |
| 1947 | 1949 | static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv, |
| 1948 | − enum tc_setup_type type, void *type_data) | |
| 1950 | + enum tc_setup_type type, void *type_data, | |
| 1951 | + void *data, | |
| 1952 | + void (*cleanup)(struct flow_block_cb *block_cb)) | |
| 1949 | 1953 | { |
| 1950 | 1954 | if (!bnxt_is_netdev_indr_offload(netdev)) |
| 1951 | 1955 | return -EOPNOTSUPP; |
| 1952 | 1956 | |
| 1953 | 1957 | switch (type) { |
| 1954 | 1958 | case TC_SETUP_BLOCK: |
| 1955 | − return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data); | |
| 1959 | + return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data, data, | |
| 1960 | + cleanup); | |
| 1956 | 1961 | default: |
| 1957 | 1962 | break; |
| 1958 | 1963 | } |
| @@ -2074,7 +2079,7 @@ void bnxt_shutdown_tc(struct bnxt *bp) · 115 unmodified lines | ||
| 2074 | 2079 | return; |
| 2075 | 2080 | |
| 2076 | 2081 | flow_indr_dev_unregister(bnxt_tc_setup_indr_cb, bp, |
| 2077 | − bnxt_tc_setup_indr_block_cb); | |
| 2082 | + bnxt_tc_setup_indr_rel); | |
| 2078 | 2083 | rhashtable_destroy(&tc_info->flow_table); |
| 2079 | 2084 | rhashtable_destroy(&tc_info->l2_table); |
| 2080 | 2085 | rhashtable_destroy(&tc_info->decap_l2_table); |
| @@ -459,17 +459,6 @@ static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv, · 458 unmodified lines | ||
| 459 | 459 | genet_dma_ring_regs[r]); |
| 460 | 460 | } |
| 461 | 461 | |
| 462 | −static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv, | |
| 463 | − u32 f_index) | |
| 464 | −{ | |
| 465 | − u32 offset; | |
| 466 | − u32 reg; | |
| 467 | − | |
| 468 | − offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); | |
| 469 | − reg = bcmgenet_hfb_reg_readl(priv, offset); | |
| 470 | − return !!(reg & (1 << (f_index % 32))); | |
| 471 | −} | |
| 472 | − | |
| 473 | 462 | static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index) |
| 474 | 463 | { |
| 475 | 464 | u32 offset; |
| @@ -533,19 +522,6 @@ static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv, · 57 unmodified lines | ||
| 533 | 522 | bcmgenet_hfb_reg_writel(priv, reg, offset); |
| 534 | 523 | } |
| 535 | 524 | |
| 536 | −static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv) | |
| 537 | −{ | |
| 538 | − u32 f_index; | |
| 539 | − | |
| 540 | − /* First MAX_NUM_OF_FS_RULES are reserved for Rx NFC filters */ | |
| 541 | − for (f_index = MAX_NUM_OF_FS_RULES; | |
| 542 | − f_index < priv->hw_params->hfb_filter_cnt; f_index++) | |
| 543 | − if (!bcmgenet_hfb_is_filter_enabled(priv, f_index)) | |
| 544 | − return f_index; | |
| 545 | − | |
| 546 | − return -ENOMEM; | |
| 547 | −} | |
| 548 | − | |
| 549 | 525 | static int bcmgenet_hfb_validate_mask(void *mask, size_t size) |
| 550 | 526 | { |
| 551 | 527 | while (size) { |
| @@ -634,8 +610,9 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 82 unmodified lines | ||
| 634 | 610 | { |
| 635 | 611 | struct ethtool_rx_flow_spec *fs = &rule->fs; |
| 636 | 612 | int err = 0, offset = 0, f_length = 0; |
| 637 | − u16 val_16, mask_16; | |
| 638 | 613 | u8 val_8, mask_8; |
| 614 | + __be16 val_16; | |
| 615 | + u16 mask_16; | |
| 639 | 616 | size_t size; |
| 640 | 617 | u32 *f_data; |
| 641 | 618 | |
| @@ -744,59 +721,6 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 102 unmodified lines | ||
| 744 | 721 | return err; |
| 745 | 722 | } |
| 746 | 723 | |
| 747 | −/* bcmgenet_hfb_add_filter | |
| 748 | − * | |
| 749 | − * Add new filter to Hardware Filter Block to match and direct Rx traffic to | |
| 750 | − * desired Rx queue. | |
| 751 | − * | |
| 752 | − * f_data is an array of unsigned 32-bit integers where each 32-bit integer | |
| 753 | − * provides filter data for 2 bytes (4 nibbles) of Rx frame: | |
| 754 | − * | |
| 755 | − * bits 31:20 - unused | |
| 756 | − * bit 19 - nibble 0 match enable | |
| 757 | − * bit 18 - nibble 1 match enable | |
| 758 | − * bit 17 - nibble 2 match enable | |
| 759 | − * bit 16 - nibble 3 match enable | |
| 760 | − * bits 15:12 - nibble 0 data | |
| 761 | − * bits 11:8 - nibble 1 data | |
| 762 | − * bits 7:4 - nibble 2 data | |
| 763 | − * bits 3:0 - nibble 3 data | |
| 764 | − * | |
| 765 | − * Example: | |
| 766 | − * In order to match: | |
| 767 | − * - Ethernet frame type = 0x0800 (IP) | |
| 768 | − * - IP version field = 4 | |
| 769 | − * - IP protocol field = 0x11 (UDP) | |
| 770 | − * | |
| 771 | − * The following filter is needed: | |
| 772 | − * u32 hfb_filter_ipv4_udp[] = { | |
| 773 | − * Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000, | |
| 774 | − * Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000, | |
| 775 | − * Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011, | |
| 776 | − * }; | |
| 777 | − * | |
| 778 | − * To add the filter to HFB and direct the traffic to Rx queue 0, call: | |
| 779 | − * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp, | |
| 780 | − * ARRAY_SIZE(hfb_filter_ipv4_udp), 0); | |
| 781 | − */ | |
| 782 | −int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, | |
| 783 | − u32 f_length, u32 rx_queue) | |
| 784 | −{ | |
| 785 | − int f_index; | |
| 786 | − | |
| 787 | − f_index = bcmgenet_hfb_find_unused_filter(priv); | |
| 788 | − if (f_index < 0) | |
| 789 | − return -ENOMEM; | |
| 790 | − | |
| 791 | − if (f_length > priv->hw_params->hfb_filter_size) | |
| 792 | − return -EINVAL; | |
| 793 | − | |
| 794 | − bcmgenet_hfb_set_filter(priv, f_data, f_length, rx_queue, f_index); | |
| 795 | − bcmgenet_hfb_enable_filter(priv, f_index); | |
| 796 | − | |
| 797 | − return 0; | |
| 798 | −} | |
| 799 | − | |
| 800 | 724 | /* bcmgenet_hfb_clear |
| 801 | 725 | * |
| 802 | 726 | * Clear Hardware Filter Block and disable all filtering. |
| @@ -2118,11 +2042,6 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 1315 unmodified lines | ||
| 2118 | 2042 | goto out; |
| 2119 | 2043 | } |
| 2120 | 2044 | |
| 2121 | − if (skb_padto(skb, ETH_ZLEN)) { | |
| 2122 | − ret = NETDEV_TX_OK; | |
| 2123 | − goto out; | |
| 2124 | − } | |
| 2125 | − | |
| 2126 | 2045 | /* Retain how many bytes will be sent on the wire, without TSB inserted |
| 2127 | 2046 | * by transmit checksum offload |
| 2128 | 2047 | */ |
| @@ -2169,6 +2088,9 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 40 unmodified lines | ||
| 2169 | 2088 | len_stat = (size << DMA_BUFLENGTH_SHIFT) | |
| 2170 | 2089 | (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT); |
| 2171 | 2090 | |
| 2091 | + /* Note: if we ever change from DMA_TX_APPEND_CRC below we | |
| 2092 | + * will need to restore software padding of "runt" packets | |
| 2093 | + */ | |
| 2172 | 2094 | if (!i) { |
| 2173 | 2095 | len_stat |= DMA_TX_APPEND_CRC | DMA_SOP; |
| 2174 | 2096 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| @@ -18168,8 +18168,8 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, · 18167 unmodified lines | ||
| 18168 | 18168 | |
| 18169 | 18169 | rtnl_lock(); |
| 18170 | 18170 | |
| 18171 | − /* We probably don't have netdev yet */ | |
| 18172 | − if (!netdev || !netif_running(netdev)) | |
| 18171 | + /* Could be second call or maybe we don't have netdev yet */ | |
| 18172 | + if (!netdev || tp->pcierr_recovery || !netif_running(netdev)) | |
| 18173 | 18173 | goto done; |
| 18174 | 18174 | |
| 18175 | 18175 | /* We needn't recover from permanent error */ |
| @@ -2558,22 +2558,23 @@ static int macb_open(struct net_device *dev) · 2557 unmodified lines | ||
| 2558 | 2558 | |
| 2559 | 2559 | err = macb_phylink_connect(bp); |
| 2560 | 2560 | if (err) |
| 2561 | − goto napi_exit; | |
| 2561 | + goto reset_hw; | |
| 2562 | 2562 | |
| 2563 | 2563 | netif_tx_start_all_queues(dev); |
| 2564 | 2564 | |
| 2565 | 2565 | if (bp->ptp_info) |
| 2566 | 2566 | bp->ptp_info->ptp_init(dev); |
| 2567 | 2567 | |
| 2568 | −napi_exit: | |
| 2568 | + return 0; | |
| 2569 | + | |
| 2570 | +reset_hw: | |
| 2571 | + macb_reset_hw(bp); | |
| 2569 | 2572 | for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) |
| 2570 | 2573 | napi_disable(&queue->napi); |
| 2574 | + macb_free_consistent(bp); | |
| 2571 | 2575 | pm_exit: |
| 2572 | − if (err) { | |
| 2573 | − pm_runtime_put_sync(&bp->pdev->dev); | |
| 2574 | − return err; | |
| 2575 | − } | |
| 2576 | − return 0; | |
| 2576 | + pm_runtime_put_sync(&bp->pdev->dev); | |
| 2577 | + return err; | |
| 2577 | 2578 | } |
| 2578 | 2579 | |
| 2579 | 2580 | static int macb_close(struct net_device *dev) |
| @@ -3761,15 +3762,9 @@ static int macb_init(struct platform_device *pdev) · 1181 unmodified lines | ||
| 3761 | 3762 | |
| 3762 | 3763 | static struct sifive_fu540_macb_mgmt *mgmt; |
| 3763 | 3764 | |
| 3764 | −/* Initialize and start the Receiver and Transmit subsystems */ | |
| 3765 | −static int at91ether_start(struct net_device *dev) | |
| 3765 | +static int at91ether_alloc_coherent(struct macb *lp) | |
| 3766 | 3766 | { |
| 3767 | − struct macb *lp = netdev_priv(dev); | |
| 3768 | 3767 | struct macb_queue *q = &lp->queues[0]; |
| 3769 | − struct macb_dma_desc *desc; | |
| 3770 | − dma_addr_t addr; | |
| 3771 | − u32 ctl; | |
| 3772 | − int i; | |
| 3773 | 3768 | |
| 3774 | 3769 | q->rx_ring = dma_alloc_coherent(&lp->pdev->dev, |
| 3775 | 3770 | (AT91ETHER_MAX_RX_DESCR * |
| @@ -3791,6 +3786,43 @@ static int at91ether_start(struct net_device *dev) · 15 unmodified lines | ||
| 3791 | 3786 | return -ENOMEM; |
| 3792 | 3787 | } |
| 3793 | 3788 | |
| 3789 | + return 0; | |
| 3790 | +} | |
| 3791 | + | |
| 3792 | +static void at91ether_free_coherent(struct macb *lp) | |
| 3793 | +{ | |
| 3794 | + struct macb_queue *q = &lp->queues[0]; | |
| 3795 | + | |
| 3796 | + if (q->rx_ring) { | |
| 3797 | + dma_free_coherent(&lp->pdev->dev, | |
| 3798 | + AT91ETHER_MAX_RX_DESCR * | |
| 3799 | + macb_dma_desc_get_size(lp), | |
| 3800 | + q->rx_ring, q->rx_ring_dma); | |
| 3801 | + q->rx_ring = NULL; | |
| 3802 | + } | |
| 3803 | + | |
| 3804 | + if (q->rx_buffers) { | |
| 3805 | + dma_free_coherent(&lp->pdev->dev, | |
| 3806 | + AT91ETHER_MAX_RX_DESCR * | |
| 3807 | + AT91ETHER_MAX_RBUFF_SZ, | |
| 3808 | + q->rx_buffers, q->rx_buffers_dma); | |
| 3809 | + q->rx_buffers = NULL; | |
| 3810 | + } | |
| 3811 | +} | |
| 3812 | + | |
| 3813 | +/* Initialize and start the Receiver and Transmit subsystems */ | |
| 3814 | +static int at91ether_start(struct macb *lp) | |
| 3815 | +{ | |
| 3816 | + struct macb_queue *q = &lp->queues[0]; | |
| 3817 | + struct macb_dma_desc *desc; | |
| 3818 | + dma_addr_t addr; | |
| 3819 | + u32 ctl; | |
| 3820 | + int i, ret; | |
| 3821 | + | |
| 3822 | + ret = at91ether_alloc_coherent(lp); | |
| 3823 | + if (ret) | |
| 3824 | + return ret; | |
| 3825 | + | |
| 3794 | 3826 | addr = q->rx_buffers_dma; |
| 3795 | 3827 | for (i = 0; i < AT91ETHER_MAX_RX_DESCR; i++) { |
| 3796 | 3828 | desc = macb_rx_desc(q, i); |
| @@ -3812,9 +3844,39 @@ static int at91ether_start(struct net_device *dev) · 15 unmodified lines | ||
| 3812 | 3844 | ctl = macb_readl(lp, NCR); |
| 3813 | 3845 | macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE)); |
| 3814 | 3846 | |
| 3847 | + /* Enable MAC interrupts */ | |
| 3848 | + macb_writel(lp, IER, MACB_BIT(RCOMP) | | |
| 3849 | + MACB_BIT(RXUBR) | | |
| 3850 | + MACB_BIT(ISR_TUND) | | |
| 3851 | + MACB_BIT(ISR_RLE) | | |
| 3852 | + MACB_BIT(TCOMP) | | |
| 3853 | + MACB_BIT(ISR_ROVR) | | |
| 3854 | + MACB_BIT(HRESP)); | |
| 3855 | + | |
| 3815 | 3856 | return 0; |
| 3816 | 3857 | } |
| 3817 | 3858 | |
| 3859 | +static void at91ether_stop(struct macb *lp) | |
| 3860 | +{ | |
| 3861 | + u32 ctl; | |
| 3862 | + | |
| 3863 | + /* Disable MAC interrupts */ | |
| 3864 | + macb_writel(lp, IDR, MACB_BIT(RCOMP) | | |
| 3865 | + MACB_BIT(RXUBR) | | |
| 3866 | + MACB_BIT(ISR_TUND) | | |
| 3867 | + MACB_BIT(ISR_RLE) | | |
| 3868 | + MACB_BIT(TCOMP) | | |
| 3869 | + MACB_BIT(ISR_ROVR) | | |
| 3870 | + MACB_BIT(HRESP)); | |
| 3871 | + | |
| 3872 | + /* Disable Receiver and Transmitter */ | |
| 3873 | + ctl = macb_readl(lp, NCR); | |
| 3874 | + macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); | |
| 3875 | + | |
| 3876 | + /* Free resources. */ | |
| 3877 | + at91ether_free_coherent(lp); | |
| 3878 | +} | |
| 3879 | + | |
| 3818 | 3880 | /* Open the ethernet interface */ |
| 3819 | 3881 | static int at91ether_open(struct net_device *dev) |
| 3820 | 3882 | { |
| @@ -3834,63 +3896,36 @@ static int at91ether_open(struct net_device *dev) · 13 unmodified lines | ||
| 3834 | 3896 | |
| 3835 | 3897 | macb_set_hwaddr(lp); |
| 3836 | 3898 | |
| 3837 | − ret = at91ether_start(dev); | |
| 3899 | + ret = at91ether_start(lp); | |
| 3838 | 3900 | if (ret) |
| 3839 | − return ret; | |
| 3840 | − | |
| 3841 | − /* Enable MAC interrupts */ | |
| 3842 | − macb_writel(lp, IER, MACB_BIT(RCOMP) | | |
| 3843 | − MACB_BIT(RXUBR) | | |
| 3844 | − MACB_BIT(ISR_TUND) | | |
| 3845 | − MACB_BIT(ISR_RLE) | | |
| 3846 | − MACB_BIT(TCOMP) | | |
| 3847 | − MACB_BIT(ISR_ROVR) | | |
| 3848 | − MACB_BIT(HRESP)); | |
| 3901 | + goto pm_exit; | |
| 3849 | 3902 | |
| 3850 | 3903 | ret = macb_phylink_connect(lp); |
| 3851 | 3904 | if (ret) |
| 3852 | − return ret; | |
| 3905 | + goto stop; | |
| 3853 | 3906 | |
| 3854 | 3907 | netif_start_queue(dev); |
| 3855 | 3908 | |
| 3856 | 3909 | return 0; |
| 3910 | + | |
| 3911 | +stop: | |
| 3912 | + at91ether_stop(lp); | |
| 3913 | +pm_exit: | |
| 3914 | + pm_runtime_put_sync(&lp->pdev->dev); | |
| 3915 | + return ret; | |
| 3857 | 3916 | } |
| 3858 | 3917 | |
| 3859 | 3918 | /* Close the interface */ |
| 3860 | 3919 | static int at91ether_close(struct net_device *dev) |
| 3861 | 3920 | { |
| 3862 | 3921 | struct macb *lp = netdev_priv(dev); |
| 3863 | − struct macb_queue *q = &lp->queues[0]; | |
| 3864 | − u32 ctl; | |
| 3865 | − | |
| 3866 | − /* Disable Receiver and Transmitter */ | |
| 3867 | − ctl = macb_readl(lp, NCR); | |
| 3868 | − macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); | |
| 3869 | − | |
| 3870 | − /* Disable MAC interrupts */ | |
| 3871 | − macb_writel(lp, IDR, MACB_BIT(RCOMP) | | |
| 3872 | − MACB_BIT(RXUBR) | | |
| 3873 | − MACB_BIT(ISR_TUND) | | |
| 3874 | − MACB_BIT(ISR_RLE) | | |
| 3875 | − MACB_BIT(TCOMP) | | |
| 3876 | − MACB_BIT(ISR_ROVR) | | |
| 3877 | − MACB_BIT(HRESP)); | |
| 3878 | 3922 | |
| 3879 | 3923 | netif_stop_queue(dev); |
| 3880 | 3924 | |
| 3881 | 3925 | phylink_stop(lp->phylink); |
| 3882 | 3926 | phylink_disconnect_phy(lp->phylink); |
| 3883 | 3927 | |
| 3884 | − dma_free_coherent(&lp->pdev->dev, | |
| 3885 | − AT91ETHER_MAX_RX_DESCR * | |
| 3886 | − macb_dma_desc_get_size(lp), | |
| 3887 | − q->rx_ring, q->rx_ring_dma); | |
| 3888 | − q->rx_ring = NULL; | |
| 3889 | − | |
| 3890 | − dma_free_coherent(&lp->pdev->dev, | |
| 3891 | − AT91ETHER_MAX_RX_DESCR * AT91ETHER_MAX_RBUFF_SZ, | |
| 3892 | − q->rx_buffers, q->rx_buffers_dma); | |
| 3893 | − q->rx_buffers = NULL; | |
| 3928 | + at91ether_stop(lp); | |
| 3894 | 3929 | |
| 3895 | 3930 | return pm_runtime_put(&lp->pdev->dev); |
| 3896 | 3931 | } |
| @@ -1975,7 +1975,6 @@ int cudbg_collect_dump_context(struct cudbg_init *pdbg_init, · 1974 unmodified lines | ||
| 1975 | 1975 | u8 mem_type[CTXT_INGRESS + 1] = { 0 }; |
| 1976 | 1976 | struct cudbg_buffer temp_buff = { 0 }; |
| 1977 | 1977 | struct cudbg_ch_cntxt *buff; |
| 1978 | − u64 *dst_off, *src_off; | |
| 1979 | 1978 | u8 *ctx_buf; |
| 1980 | 1979 | u8 i, k; |
| 1981 | 1980 | int rc; |
| @@ -2044,8 +2043,11 @@ int cudbg_collect_dump_context(struct cudbg_init *pdbg_init, · 62 unmodified lines | ||
| 2044 | 2043 | } |
| 2045 | 2044 | |
| 2046 | 2045 | for (j = 0; j < max_ctx_qid; j++) { |
| 2046 | + __be64 *dst_off; | |
| 2047 | + u64 *src_off; | |
| 2048 | + | |
| 2047 | 2049 | src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE); |
| 2048 | − dst_off = (u64 *)buff->data; | |
| 2050 | + dst_off = (__be64 *)buff->data; | |
| 2049 | 2051 | |
| 2050 | 2052 | /* The data is stored in 64-bit cpu order. Convert it |
| 2051 | 2053 | * to big endian before parsing. |
| @@ -136,6 +136,9 @@ static inline __u8 bitswap_1(unsigned char val) · 135 unmodified lines | ||
| 136 | 136 | ((val & 0x02) << 5) | |
| 137 | 137 | ((val & 0x01) << 7); |
| 138 | 138 | } |
| 139 | + | |
| 140 | +extern const char * const dcb_ver_array[]; | |
| 141 | + | |
| 139 | 142 | #define CXGB4_DCB_ENABLED true |
| 140 | 143 | |
| 141 | 144 | #else /* !CONFIG_CHELSIO_T4_DCB */ |
| @@ -2379,7 +2379,6 @@ static const struct file_operations rss_vf_config_debugfs_fops = { · 2378 unmodified lines | ||
| 2379 | 2379 | }; |
| 2380 | 2380 | |
| 2381 | 2381 | #ifdef CONFIG_CHELSIO_T4_DCB |
| 2382 | −extern char *dcb_ver_array[]; | |
| 2383 | 2382 | |
| 2384 | 2383 | /* Data Center Briging information for each port. |
| 2385 | 2384 | */ |
| @@ -588,7 +588,7 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, · 587 unmodified lines | ||
| 588 | 588 | /** |
| 589 | 589 | * lmm_to_fw_caps - translate ethtool Link Mode Mask to Firmware |
| 590 | 590 | * capabilities |
| 591 | − * @et_lmm: ethtool Link Mode Mask | |
| 591 | + * @link_mode_mask: ethtool Link Mode Mask | |
| 592 | 592 | * |
| 593 | 593 | * Translate ethtool Link Mode Mask into a Firmware Port capabilities |
| 594 | 594 | * value. |
| @@ -165,6 +165,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f, · 164 unmodified lines | ||
| 165 | 165 | unsigned int tid, bool dip, bool sip, bool dp, |
| 166 | 166 | bool sp) |
| 167 | 167 | { |
| 168 | + u8 *nat_lp = (u8 *)&f->fs.nat_lport; | |
| 169 | + u8 *nat_fp = (u8 *)&f->fs.nat_fport; | |
| 170 | + | |
| 168 | 171 | if (dip) { |
| 169 | 172 | if (f->fs.type) { |
| 170 | 173 | set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W, |
| @@ -236,8 +239,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f, · 65 unmodified lines | ||
| 236 | 239 | } |
| 237 | 240 | |
| 238 | 241 | set_tcb_field(adap, f, tid, TCB_PDU_HDR_LEN_W, WORD_MASK, |
| 239 | − (dp ? f->fs.nat_lport : 0) | | |
| 240 | − (sp ? f->fs.nat_fport << 16 : 0), 1); | |
| 242 | + (dp ? (nat_lp[1] | nat_lp[0] << 8) : 0) | | |
| 243 | + (sp ? (nat_fp[1] << 16 | nat_fp[0] << 24) : 0), | |
| 244 | + 1); | |
| 241 | 245 | } |
| 242 | 246 | |
| 243 | 247 | /* Validate filter spec against configuration done on the card. */ |
| @@ -909,6 +913,9 @@ int set_filter_wr(struct adapter *adapter, int fidx) · 665 unmodified lines | ||
| 909 | 913 | fwr->fpm = htons(f->fs.mask.fport); |
| 910 | 914 | |
| 911 | 915 | if (adapter->params.filter2_wr_support) { |
| 916 | + u8 *nat_lp = (u8 *)&f->fs.nat_lport; | |
| 917 | + u8 *nat_fp = (u8 *)&f->fs.nat_fport; | |
| 918 | + | |
| 912 | 919 | fwr->natmode_to_ulp_type = |
| 913 | 920 | FW_FILTER2_WR_ULP_TYPE_V(f->fs.nat_mode ? |
| 914 | 921 | ULP_MODE_TCPDDP : |
| @@ -916,8 +923,8 @@ int set_filter_wr(struct adapter *adapter, int fidx) · 1 unmodified line | ||
| 916 | 923 | FW_FILTER2_WR_NATMODE_V(f->fs.nat_mode); |
| 917 | 924 | memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip)); |
| 918 | 925 | memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip)); |
| 919 | − fwr->newlport = htons(f->fs.nat_lport); | |
| 920 | − fwr->newfport = htons(f->fs.nat_fport); | |
| 926 | + fwr->newlport = htons(nat_lp[1] | nat_lp[0] << 8); | |
| 927 | + fwr->newfport = htons(nat_fp[1] | nat_fp[0] << 8); | |
| 921 | 928 | } |
| 922 | 929 | |
| 923 | 930 | /* Mark the filter as "pending" and ship off the Filter Work Request. |
| @@ -1105,16 +1112,16 @@ static bool is_addr_all_mask(u8 *ipmask, int family) · 181 unmodified lines | ||
| 1105 | 1112 | struct in_addr *addr; |
| 1106 | 1113 | |
| 1107 | 1114 | addr = (struct in_addr *)ipmask; |
| 1108 | − if (addr->s_addr == 0xffffffff) | |
| 1115 | + if (ntohl(addr->s_addr) == 0xffffffff) | |
| 1109 | 1116 | return true; |
| 1110 | 1117 | } else if (family == AF_INET6) { |
| 1111 | 1118 | struct in6_addr *addr6; |
| 1112 | 1119 | |
| 1113 | 1120 | addr6 = (struct in6_addr *)ipmask; |
| 1114 | − if (addr6->s6_addr32[0] == 0xffffffff && | |
| 1115 | − addr6->s6_addr32[1] == 0xffffffff && | |
| 1116 | − addr6->s6_addr32[2] == 0xffffffff && | |
| 1117 | − addr6->s6_addr32[3] == 0xffffffff) | |
| 1121 | + if (ntohl(addr6->s6_addr32[0]) == 0xffffffff && | |
| 1122 | + ntohl(addr6->s6_addr32[1]) == 0xffffffff && | |
| 1123 | + ntohl(addr6->s6_addr32[2]) == 0xffffffff && | |
| 1124 | + ntohl(addr6->s6_addr32[3]) == 0xffffffff) | |
| 1118 | 1125 | return true; |
| 1119 | 1126 | } |
| 1120 | 1127 | return false; |
| @@ -449,7 +449,7 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) · 448 unmodified lines | ||
| 449 | 449 | * or -1 |
| 450 | 450 | * @addr: the new MAC address value |
| 451 | 451 | * @persist: whether a new MAC allocation should be persistent |
| 452 | − * @add_smt: if true also add the address to the HW SMT | |
| 452 | + * @smt_idx: the destination to store the new SMT index. | |
| 453 | 453 | * |
| 454 | 454 | * Modifies an MPS filter and sets it to the new MAC address if |
| 455 | 455 | * @tcam_idx >= 0, or adds the MAC address to a new filter if |
| @@ -1615,6 +1615,7 @@ static int tid_init(struct tid_info *t) · 1159 unmodified lines | ||
| 1615 | 1615 | * @stid: the server TID |
| 1616 | 1616 | * @sip: local IP address to bind server to |
| 1617 | 1617 | * @sport: the server's TCP port |
| 1618 | + * @vlan: the VLAN header information | |
| 1618 | 1619 | * @queue: queue to direct messages from this server to |
| 1619 | 1620 | * |
| 1620 | 1621 | * Create an IP server for the given port and address. |
| @@ -2609,7 +2610,7 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, · 988 unmodified lines | ||
| 2609 | 2610 | |
| 2610 | 2611 | /* Clear out filter specifications */ |
| 2611 | 2612 | memset(&f->fs, 0, sizeof(struct ch_filter_specification)); |
| 2612 | − f->fs.val.lport = cpu_to_be16(sport); | |
| 2613 | + f->fs.val.lport = be16_to_cpu(sport); | |
| 2613 | 2614 | f->fs.mask.lport = ~0; |
| 2614 | 2615 | val = (u8 *)&sip; |
| 2615 | 2616 | if ((val[0] | val[1] | val[2] | val[3]) != 0) { |
| @@ -5377,10 +5378,10 @@ static inline bool is_x_10g_port(const struct link_config *lc) · 2761 unmodified lines | ||
| 5377 | 5378 | static int cfg_queues(struct adapter *adap) |
| 5378 | 5379 | { |
| 5379 | 5380 | u32 avail_qsets, avail_eth_qsets, avail_uld_qsets; |
| 5380 | − u32 i, n10g = 0, qidx = 0, n1g = 0; | |
| 5381 | 5381 | u32 ncpus = num_online_cpus(); |
| 5382 | 5382 | u32 niqflint, neq, num_ulds; |
| 5383 | 5383 | struct sge *s = &adap->sge; |
| 5384 | + u32 i, n10g = 0, qidx = 0; | |
| 5384 | 5385 | u32 q10g = 0, q1g; |
| 5385 | 5386 | |
| 5386 | 5387 | /* Reduce memory usage in kdump environment, disable all offload. */ |
| @@ -5426,7 +5427,6 @@ static int cfg_queues(struct adapter *adap) · 39 unmodified lines | ||
| 5426 | 5427 | if (n10g) |
| 5427 | 5428 | q10g = (avail_eth_qsets - (adap->params.nports - n10g)) / n10g; |
| 5428 | 5429 | |
| 5429 | − n1g = adap->params.nports - n10g; | |
| 5430 | 5430 | #ifdef CONFIG_CHELSIO_T4_DCB |
| 5431 | 5431 | /* For Data Center Bridging support we need to be able to support up |
| 5432 | 5432 | * to 8 Traffic Priorities; each of which will be assigned to its |
| @@ -5444,7 +5444,8 @@ static int cfg_queues(struct adapter *adap) · 11 unmodified lines | ||
| 5444 | 5444 | else |
| 5445 | 5445 | q10g = max(8U, q10g); |
| 5446 | 5446 | |
| 5447 | − while ((q10g * n10g) > (avail_eth_qsets - n1g * q1g)) | |
| 5447 | + while ((q10g * n10g) > | |
| 5448 | + (avail_eth_qsets - (adap->params.nports - n10g) * q1g)) | |
| 5448 | 5449 | q10g--; |
| 5449 | 5450 | |
| 5450 | 5451 | #else /* !CONFIG_CHELSIO_T4_DCB */ |
| @@ -194,6 +194,7 @@ int cxgb4_ptp_redirect_rx_packet(struct adapter *adapter, struct port_info *pi) · 193 unmodified lines | ||
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | /** |
| 197 | + * cxgb4_ptp_adjfreq - Adjust frequency of PHC cycle counter | |
| 197 | 198 | * @ptp: ptp clock structure |
| 198 | 199 | * @ppb: Desired frequency change in parts per billion |
| 199 | 200 | * |
| @@ -229,7 +230,7 @@ static int cxgb4_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) · 29 unmodified lines | ||
| 229 | 230 | |
| 230 | 231 | /** |
| 231 | 232 | * cxgb4_ptp_fineadjtime - Shift the time of the hardware clock |
| 232 | − * @ptp: ptp clock structure | |
| 233 | + * @adapter: board private structure | |
| 233 | 234 | * @delta: Desired change in nanoseconds |
| 234 | 235 | * |
| 235 | 236 | * Adjust the timer by resetting the timecounter structure. |
| @@ -58,10 +58,6 @@ static struct ch_tc_pedit_fields pedits[] = { · 57 unmodified lines | ||
| 58 | 58 | PEDIT_FIELDS(IP6_, DST_63_32, 4, nat_lip, 4), |
| 59 | 59 | PEDIT_FIELDS(IP6_, DST_95_64, 4, nat_lip, 8), |
| 60 | 60 | PEDIT_FIELDS(IP6_, DST_127_96, 4, nat_lip, 12), |
| 61 | − PEDIT_FIELDS(TCP_, SPORT, 2, nat_fport, 0), | |
| 62 | − PEDIT_FIELDS(TCP_, DPORT, 2, nat_lport, 0), | |
| 63 | − PEDIT_FIELDS(UDP_, SPORT, 2, nat_fport, 0), | |
| 64 | − PEDIT_FIELDS(UDP_, DPORT, 2, nat_lport, 0), | |
| 65 | 61 | }; |
| 66 | 62 | |
| 67 | 63 | static struct ch_tc_flower_entry *allocate_flower_entry(void) |
| @@ -156,14 +152,14 @@ static void cxgb4_process_flow_match(struct net_device *dev, · 88 unmodified lines | ||
| 156 | 152 | struct flow_match_ports match; |
| 157 | 153 | |
| 158 | 154 | flow_rule_match_ports(rule, &match); |
| 159 | − fs->val.lport = cpu_to_be16(match.key->dst); | |
| 160 | − fs->mask.lport = cpu_to_be16(match.mask->dst); | |
| 161 | − fs->val.fport = cpu_to_be16(match.key->src); | |
| 162 | − fs->mask.fport = cpu_to_be16(match.mask->src); | |
| 155 | + fs->val.lport = be16_to_cpu(match.key->dst); | |
| 156 | + fs->mask.lport = be16_to_cpu(match.mask->dst); | |
| 157 | + fs->val.fport = be16_to_cpu(match.key->src); | |
| 158 | + fs->mask.fport = be16_to_cpu(match.mask->src); | |
| 163 | 159 | |
| 164 | 160 | /* also initialize nat_lport/fport to same values */ |
| 165 | − fs->nat_lport = cpu_to_be16(match.key->dst); | |
| 166 | − fs->nat_fport = cpu_to_be16(match.key->src); | |
| 161 | + fs->nat_lport = fs->val.lport; | |
| 162 | + fs->nat_fport = fs->val.fport; | |
| 167 | 163 | } |
| 168 | 164 | |
| 169 | 165 | if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { |
| @@ -354,12 +350,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, · 184 unmodified lines | ||
| 354 | 350 | switch (offset) { |
| 355 | 351 | case PEDIT_TCP_SPORT_DPORT: |
| 356 | 352 | if (~mask & PEDIT_TCP_UDP_SPORT_MASK) |
| 357 | − offload_pedit(fs, cpu_to_be32(val) >> 16, | |
| 358 | − cpu_to_be32(mask) >> 16, | |
| 359 | − TCP_SPORT); | |
| 353 | + fs->nat_fport = val; | |
| 360 | 354 | else |
| 361 | − offload_pedit(fs, cpu_to_be32(val), | |
| 362 | − cpu_to_be32(mask), TCP_DPORT); | |
| 355 | + fs->nat_lport = val >> 16; | |
| 363 | 356 | } |
| 364 | 357 | fs->nat_mode = NAT_MODE_ALL; |
| 365 | 358 | break; |
| @@ -367,12 +360,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, · 1 unmodified line | ||
| 367 | 360 | switch (offset) { |
| 368 | 361 | case PEDIT_UDP_SPORT_DPORT: |
| 369 | 362 | if (~mask & PEDIT_TCP_UDP_SPORT_MASK) |
| 370 | − offload_pedit(fs, cpu_to_be32(val) >> 16, | |
| 371 | − cpu_to_be32(mask) >> 16, | |
| 372 | − UDP_SPORT); | |
| 363 | + fs->nat_fport = val; | |
| 373 | 364 | else |
| 374 | − offload_pedit(fs, cpu_to_be32(val), | |
| 375 | − cpu_to_be32(mask), UDP_DPORT); | |
| 365 | + fs->nat_lport = val >> 16; | |
| 376 | 366 | } |
| 377 | 367 | fs->nat_mode = NAT_MODE_ALL; |
| 378 | 368 | } |
| @@ -48,7 +48,7 @@ static int fill_match_fields(struct adapter *adap, · 47 unmodified lines | ||
| 48 | 48 | bool next_header) |
| 49 | 49 | { |
| 50 | 50 | unsigned int i, j; |
| 51 | − u32 val, mask; | |
| 51 | + __be32 val, mask; | |
| 52 | 52 | int off, err; |
| 53 | 53 | bool found; |
| 54 | 54 | |
| @@ -228,7 +228,7 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) · 173 unmodified lines | ||
| 228 | 228 | const struct cxgb4_next_header *next; |
| 229 | 229 | bool found = false; |
| 230 | 230 | unsigned int i, j; |
| 231 | − u32 val, mask; | |
| 231 | + __be32 val, mask; | |
| 232 | 232 | int off; |
| 233 | 233 | |
| 234 | 234 | if (t->table[link_uhtid - 1].link_handle) { |
| @@ -242,10 +242,10 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) · 7 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | /* Try to find matches that allow jumps to next header. */ |
| 244 | 244 | for (i = 0; next[i].jump; i++) { |
| 245 | − if (next[i].offoff != cls->knode.sel->offoff || | |
| 246 | − next[i].shift != cls->knode.sel->offshift || | |
| 247 | − next[i].mask != cls->knode.sel->offmask || | |
| 248 | − next[i].offset != cls->knode.sel->off) | |
| 245 | + if (next[i].sel.offoff != cls->knode.sel->offoff || | |
| 246 | + next[i].sel.offshift != cls->knode.sel->offshift || | |
| 247 | + next[i].sel.offmask != cls->knode.sel->offmask || | |
| 248 | + next[i].sel.off != cls->knode.sel->off) | |
| 249 | 249 | continue; |
| 250 | 250 | |
| 251 | 251 | /* Found a possible candidate. Find a key that |
| @@ -257,9 +257,9 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) · 5 unmodified lines | ||
| 257 | 257 | val = cls->knode.sel->keys[j].val; |
| 258 | 258 | mask = cls->knode.sel->keys[j].mask; |
| 259 | 259 | |
| 260 | − if (next[i].match_off == off && | |
| 261 | − next[i].match_val == val && | |
| 262 | − next[i].match_mask == mask) { | |
| 260 | + if (next[i].key.off == off && | |
| 261 | + next[i].key.val == val && | |
| 262 | + next[i].key.mask == mask) { | |
| 263 | 263 | found = true; |
| 264 | 264 | break; |
| 265 | 265 | } |
| @@ -38,12 +38,12 @@ · 37 unmodified lines | ||
| 38 | 38 | struct cxgb4_match_field { |
| 39 | 39 | int off; /* Offset from the beginning of the header to match */ |
| 40 | 40 | /* Fill the value/mask pair in the spec if matched */ |
| 41 | − int (*val)(struct ch_filter_specification *f, u32 val, u32 mask); | |
| 41 | + int (*val)(struct ch_filter_specification *f, __be32 val, __be32 mask); | |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | 44 | /* IPv4 match fields */ |
| 45 | 45 | static inline int cxgb4_fill_ipv4_tos(struct ch_filter_specification *f, |
| 46 | − u32 val, u32 mask) | |
| 46 | + __be32 val, __be32 mask) | |
| 47 | 47 | { |
| 48 | 48 | f->val.tos = (ntohl(val) >> 16) & 0x000000FF; |
| 49 | 49 | f->mask.tos = (ntohl(mask) >> 16) & 0x000000FF; |
| @@ -52,7 +52,7 @@ static inline int cxgb4_fill_ipv4_tos(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | static inline int cxgb4_fill_ipv4_frag(struct ch_filter_specification *f, |
| 55 | − u32 val, u32 mask) | |
| 55 | + __be32 val, __be32 mask) | |
| 56 | 56 | { |
| 57 | 57 | u32 mask_val; |
| 58 | 58 | u8 frag_val; |
| @@ -74,7 +74,7 @@ static inline int cxgb4_fill_ipv4_frag(struct ch_filter_specification *f, · 15 unmodified lines | ||
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | static inline int cxgb4_fill_ipv4_proto(struct ch_filter_specification *f, |
| 77 | − u32 val, u32 mask) | |
| 77 | + __be32 val, __be32 mask) | |
| 78 | 78 | { |
| 79 | 79 | f->val.proto = (ntohl(val) >> 16) & 0x000000FF; |
| 80 | 80 | f->mask.proto = (ntohl(mask) >> 16) & 0x000000FF; |
| @@ -83,7 +83,7 @@ static inline int cxgb4_fill_ipv4_proto(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | static inline int cxgb4_fill_ipv4_src_ip(struct ch_filter_specification *f, |
| 86 | − u32 val, u32 mask) | |
| 86 | + __be32 val, __be32 mask) | |
| 87 | 87 | { |
| 88 | 88 | memcpy(&f->val.fip[0], &val, sizeof(u32)); |
| 89 | 89 | memcpy(&f->mask.fip[0], &mask, sizeof(u32)); |
| @@ -92,7 +92,7 @@ static inline int cxgb4_fill_ipv4_src_ip(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | static inline int cxgb4_fill_ipv4_dst_ip(struct ch_filter_specification *f, |
| 95 | − u32 val, u32 mask) | |
| 95 | + __be32 val, __be32 mask) | |
| 96 | 96 | { |
| 97 | 97 | memcpy(&f->val.lip[0], &val, sizeof(u32)); |
| 98 | 98 | memcpy(&f->mask.lip[0], &mask, sizeof(u32)); |
| @@ -111,7 +111,7 @@ static const struct cxgb4_match_field cxgb4_ipv4_fields[] = { · 12 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | /* IPv6 match fields */ |
| 113 | 113 | static inline int cxgb4_fill_ipv6_tos(struct ch_filter_specification *f, |
| 114 | − u32 val, u32 mask) | |
| 114 | + __be32 val, __be32 mask) | |
| 115 | 115 | { |
| 116 | 116 | f->val.tos = (ntohl(val) >> 20) & 0x000000FF; |
| 117 | 117 | f->mask.tos = (ntohl(mask) >> 20) & 0x000000FF; |
| @@ -120,7 +120,7 @@ static inline int cxgb4_fill_ipv6_tos(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | static inline int cxgb4_fill_ipv6_proto(struct ch_filter_specification *f, |
| 123 | − u32 val, u32 mask) | |
| 123 | + __be32 val, __be32 mask) | |
| 124 | 124 | { |
| 125 | 125 | f->val.proto = (ntohl(val) >> 8) & 0x000000FF; |
| 126 | 126 | f->mask.proto = (ntohl(mask) >> 8) & 0x000000FF; |
| @@ -129,7 +129,7 @@ static inline int cxgb4_fill_ipv6_proto(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | static inline int cxgb4_fill_ipv6_src_ip0(struct ch_filter_specification *f, |
| 132 | − u32 val, u32 mask) | |
| 132 | + __be32 val, __be32 mask) | |
| 133 | 133 | { |
| 134 | 134 | memcpy(&f->val.fip[0], &val, sizeof(u32)); |
| 135 | 135 | memcpy(&f->mask.fip[0], &mask, sizeof(u32)); |
| @@ -138,7 +138,7 @@ static inline int cxgb4_fill_ipv6_src_ip0(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | static inline int cxgb4_fill_ipv6_src_ip1(struct ch_filter_specification *f, |
| 141 | − u32 val, u32 mask) | |
| 141 | + __be32 val, __be32 mask) | |
| 142 | 142 | { |
| 143 | 143 | memcpy(&f->val.fip[4], &val, sizeof(u32)); |
| 144 | 144 | memcpy(&f->mask.fip[4], &mask, sizeof(u32)); |
| @@ -147,7 +147,7 @@ static inline int cxgb4_fill_ipv6_src_ip1(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | static inline int cxgb4_fill_ipv6_src_ip2(struct ch_filter_specification *f, |
| 150 | − u32 val, u32 mask) | |
| 150 | + __be32 val, __be32 mask) | |
| 151 | 151 | { |
| 152 | 152 | memcpy(&f->val.fip[8], &val, sizeof(u32)); |
| 153 | 153 | memcpy(&f->mask.fip[8], &mask, sizeof(u32)); |
| @@ -156,7 +156,7 @@ static inline int cxgb4_fill_ipv6_src_ip2(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | static inline int cxgb4_fill_ipv6_src_ip3(struct ch_filter_specification *f, |
| 159 | − u32 val, u32 mask) | |
| 159 | + __be32 val, __be32 mask) | |
| 160 | 160 | { |
| 161 | 161 | memcpy(&f->val.fip[12], &val, sizeof(u32)); |
| 162 | 162 | memcpy(&f->mask.fip[12], &mask, sizeof(u32)); |
| @@ -165,7 +165,7 @@ static inline int cxgb4_fill_ipv6_src_ip3(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 165 | 165 | } |
| 166 | 166 | |
| 167 | 167 | static inline int cxgb4_fill_ipv6_dst_ip0(struct ch_filter_specification *f, |
| 168 | − u32 val, u32 mask) | |
| 168 | + __be32 val, __be32 mask) | |
| 169 | 169 | { |
| 170 | 170 | memcpy(&f->val.lip[0], &val, sizeof(u32)); |
| 171 | 171 | memcpy(&f->mask.lip[0], &mask, sizeof(u32)); |
| @@ -174,7 +174,7 @@ static inline int cxgb4_fill_ipv6_dst_ip0(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 174 | 174 | } |
| 175 | 175 | |
| 176 | 176 | static inline int cxgb4_fill_ipv6_dst_ip1(struct ch_filter_specification *f, |
| 177 | − u32 val, u32 mask) | |
| 177 | + __be32 val, __be32 mask) | |
| 178 | 178 | { |
| 179 | 179 | memcpy(&f->val.lip[4], &val, sizeof(u32)); |
| 180 | 180 | memcpy(&f->mask.lip[4], &mask, sizeof(u32)); |
| @@ -183,7 +183,7 @@ static inline int cxgb4_fill_ipv6_dst_ip1(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 183 | 183 | } |
| 184 | 184 | |
| 185 | 185 | static inline int cxgb4_fill_ipv6_dst_ip2(struct ch_filter_specification *f, |
| 186 | − u32 val, u32 mask) | |
| 186 | + __be32 val, __be32 mask) | |
| 187 | 187 | { |
| 188 | 188 | memcpy(&f->val.lip[8], &val, sizeof(u32)); |
| 189 | 189 | memcpy(&f->mask.lip[8], &mask, sizeof(u32)); |
| @@ -192,7 +192,7 @@ static inline int cxgb4_fill_ipv6_dst_ip2(struct ch_filter_specification *f, · 2 unmodified lines | ||
| 192 | 192 | } |
| 193 | 193 | |
| 194 | 194 | static inline int cxgb4_fill_ipv6_dst_ip3(struct ch_filter_specification *f, |
| 195 | − u32 val, u32 mask) | |
| 195 | + __be32 val, __be32 mask) | |
| 196 | 196 | { |
| 197 | 197 | memcpy(&f->val.lip[12], &val, sizeof(u32)); |
| 198 | 198 | memcpy(&f->mask.lip[12], &mask, sizeof(u32)); |
| @@ -216,7 +216,7 @@ static const struct cxgb4_match_field cxgb4_ipv6_fields[] = { · 17 unmodified lines | ||
| 216 | 216 | |
| 217 | 217 | /* TCP/UDP match */ |
| 218 | 218 | static inline int cxgb4_fill_l4_ports(struct ch_filter_specification *f, |
| 219 | − u32 val, u32 mask) | |
| 219 | + __be32 val, __be32 mask) | |
| 220 | 220 | { |
| 221 | 221 | f->val.fport = ntohl(val) >> 16; |
| 222 | 222 | f->mask.fport = ntohl(mask) >> 16; |
| @@ -237,19 +237,13 @@ static const struct cxgb4_match_field cxgb4_udp_fields[] = { · 14 unmodified lines | ||
| 237 | 237 | }; |
| 238 | 238 | |
| 239 | 239 | struct cxgb4_next_header { |
| 240 | − unsigned int offset; /* Offset to next header */ | |
| 241 | − /* offset, shift, and mask added to offset above | |
| 240 | + /* Offset, shift, and mask added to beginning of the header | |
| 242 | 241 | * to get to next header. Useful when using a header |
| 243 | 242 | * field's value to jump to next header such as IHL field |
| 244 | 243 | * in IPv4 header. |
| 245 | 244 | */ |
| 246 | − unsigned int offoff; | |
| 247 | − u32 shift; | |
| 248 | − u32 mask; | |
| 249 | − /* match criteria to make this jump */ | |
| 250 | − unsigned int match_off; | |
| 251 | − u32 match_val; | |
| 252 | − u32 match_mask; | |
| 245 | + struct tc_u32_sel sel; | |
| 246 | + struct tc_u32_key key; | |
| 253 | 247 | /* location of jump to make */ |
| 254 | 248 | const struct cxgb4_match_field *jump; |
| 255 | 249 | }; |
| @@ -258,26 +252,74 @@ struct cxgb4_next_header { · 2 unmodified lines | ||
| 258 | 252 | * IPv4 header. |
| 259 | 253 | */ |
| 260 | 254 | static const struct cxgb4_next_header cxgb4_ipv4_jumps[] = { |
| 261 | − { .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF, | |
| 262 | − .match_off = 8, .match_val = 0x600, .match_mask = 0xFF00, | |
| 263 | − .jump = cxgb4_tcp_fields }, | |
| 264 | − { .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF, | |
| 265 | − .match_off = 8, .match_val = 0x1100, .match_mask = 0xFF00, | |
| 266 | − .jump = cxgb4_udp_fields }, | |
| 267 | − { .jump = NULL } | |
| 255 | + { | |
| 256 | + /* TCP Jump */ | |
| 257 | + .sel = { | |
| 258 | + .off = 0, | |
| 259 | + .offoff = 0, | |
| 260 | + .offshift = 6, | |
| 261 | + .offmask = cpu_to_be16(0x0f00), | |
| 262 | + }, | |
| 263 | + .key = { | |
| 264 | + .off = 8, | |
| 265 | + .val = cpu_to_be32(0x00060000), | |
| 266 | + .mask = cpu_to_be32(0x00ff0000), | |
| 267 | + }, | |
| 268 | + .jump = cxgb4_tcp_fields, | |
| 269 | + }, | |
| 270 | + { | |
| 271 | + /* UDP Jump */ | |
| 272 | + .sel = { | |
| 273 | + .off = 0, | |
| 274 | + .offoff = 0, | |
| 275 | + .offshift = 6, | |
| 276 | + .offmask = cpu_to_be16(0x0f00), | |
| 277 | + }, | |
| 278 | + .key = { | |
| 279 | + .off = 8, | |
| 280 | + .val = cpu_to_be32(0x00110000), | |
| 281 | + .mask = cpu_to_be32(0x00ff0000), | |
| 282 | + }, | |
| 283 | + .jump = cxgb4_udp_fields, | |
| 284 | + }, | |
| 285 | + { .jump = NULL }, | |
| 268 | 286 | }; |
| 269 | 287 | |
| 270 | 288 | /* Accept a rule with a jump directly past the 40 Bytes of IPv6 fixed header |
| 271 | 289 | * to get to transport layer header. |
| 272 | 290 | */ |
| 273 | 291 | static const struct cxgb4_next_header cxgb4_ipv6_jumps[] = { |
| 274 | − { .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0, | |
| 275 | − .match_off = 4, .match_val = 0x60000, .match_mask = 0xFF0000, | |
| 276 | − .jump = cxgb4_tcp_fields }, | |
| 277 | − { .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0, | |
| 278 | − .match_off = 4, .match_val = 0x110000, .match_mask = 0xFF0000, | |
| 279 | − .jump = cxgb4_udp_fields }, | |
| 280 | − { .jump = NULL } | |
| 292 | + { | |
| 293 | + /* TCP Jump */ | |
| 294 | + .sel = { | |
| 295 | + .off = 40, | |
| 296 | + .offoff = 0, | |
| 297 | + .offshift = 0, | |
| 298 | + .offmask = 0, | |
| 299 | + }, | |
| 300 | + .key = { | |
| 301 | + .off = 4, | |
| 302 | + .val = cpu_to_be32(0x00000600), | |
| 303 | + .mask = cpu_to_be32(0x0000ff00), | |
| 304 | + }, | |
| 305 | + .jump = cxgb4_tcp_fields, | |
| 306 | + }, | |
| 307 | + { | |
| 308 | + /* UDP Jump */ | |
| 309 | + .sel = { | |
| 310 | + .off = 40, | |
| 311 | + .offoff = 0, | |
| 312 | + .offshift = 0, | |
| 313 | + .offmask = 0, | |
| 314 | + }, | |
| 315 | + .key = { | |
| 316 | + .off = 4, | |
| 317 | + .val = cpu_to_be32(0x00001100), | |
| 318 | + .mask = cpu_to_be32(0x0000ff00), | |
| 319 | + }, | |
| 320 | + .jump = cxgb4_udp_fields, | |
| 321 | + }, | |
| 322 | + { .jump = NULL }, | |
| 281 | 323 | }; |
| 282 | 324 | |
| 283 | 325 | struct cxgb4_link { |
| @@ -502,41 +502,20 @@ u64 cxgb4_select_ntuple(struct net_device *dev, · 501 unmodified lines | ||
| 502 | 502 | } |
| 503 | 503 | EXPORT_SYMBOL(cxgb4_select_ntuple); |
| 504 | 504 | |
| 505 | −/* | |
| 506 | − * Called when address resolution fails for an L2T entry to handle packets | |
| 507 | − * on the arpq head. If a packet specifies a failure handler it is invoked, | |
| 508 | − * otherwise the packet is sent to the device. | |
| 509 | − */ | |
| 510 | −static void handle_failed_resolution(struct adapter *adap, struct l2t_entry *e) | |
| 511 | −{ | |
| 512 | − struct sk_buff *skb; | |
| 513 | − | |
| 514 | − while ((skb = __skb_dequeue(&e->arpq)) != NULL) { | |
| 515 | − const struct l2t_skb_cb *cb = L2T_SKB_CB(skb); | |
| 516 | − | |
| 517 | − spin_unlock(&e->lock); | |
| 518 | − if (cb->arp_err_handler) | |
| 519 | − cb->arp_err_handler(cb->handle, skb); | |
| 520 | − else | |
| 521 | − t4_ofld_send(adap, skb); | |
| 522 | − spin_lock(&e->lock); | |
| 523 | − } | |
| 524 | −} | |
| 525 | − | |
| 526 | 505 | /* |
| 527 | 506 | * Called when the host's neighbor layer makes a change to some entry that is |
| 528 | 507 | * loaded into the HW L2 table. |
| 529 | 508 | */ |
| 530 | 509 | void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) |
| 531 | 510 | { |
| 532 | − struct l2t_entry *e; | |
| 533 | − struct sk_buff_head *arpq = NULL; | |
| 534 | − struct l2t_data *d = adap->l2t; | |
| 535 | 511 | unsigned int addr_len = neigh->tbl->key_len; |
| 536 | 512 | u32 *addr = (u32 *) neigh->primary_key; |
| 537 | − int ifidx = neigh->dev->ifindex; | |
| 538 | − int hash = addr_hash(d, addr, addr_len, ifidx); | |
| 513 | + int hash, ifidx = neigh->dev->ifindex; | |
| 514 | + struct sk_buff_head *arpq = NULL; | |
| 515 | + struct l2t_data *d = adap->l2t; | |
| 516 | + struct l2t_entry *e; | |
| 539 | 517 | |
| 518 | + hash = addr_hash(d, addr, addr_len, ifidx); | |
| 540 | 519 | read_lock_bh(&d->lock); |
| 541 | 520 | for (e = d->l2tab[hash].first; e; e = e->next) |
| 542 | 521 | if (!addreq(e, addr) && e->ifindex == ifidx) { |
| @@ -569,8 +548,25 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) · 26 unmodified lines | ||
| 569 | 548 | write_l2e(adap, e, 0); |
| 570 | 549 | } |
| 571 | 550 | |
| 572 | − if (arpq) | |
| 573 | − handle_failed_resolution(adap, e); | |
| 551 | + if (arpq) { | |
| 552 | + struct sk_buff *skb; | |
| 553 | + | |
| 554 | + /* Called when address resolution fails for an L2T | |
| 555 | + * entry to handle packets on the arpq head. If a | |
| 556 | + * packet specifies a failure handler it is invoked, | |
| 557 | + * otherwise the packet is sent to the device. | |
| 558 | + */ | |
| 559 | + while ((skb = __skb_dequeue(&e->arpq)) != NULL) { | |
| 560 | + const struct l2t_skb_cb *cb = L2T_SKB_CB(skb); | |
| 561 | + | |
| 562 | + spin_unlock(&e->lock); | |
| 563 | + if (cb->arp_err_handler) | |
| 564 | + cb->arp_err_handler(cb->handle, skb); | |
| 565 | + else | |
| 566 | + t4_ofld_send(adap, skb); | |
| 567 | + spin_lock(&e->lock); | |
| 568 | + } | |
| 569 | + } | |
| 574 | 570 | spin_unlock_bh(&e->lock); |
| 575 | 571 | } |
| 576 | 572 | |
| @@ -613,6 +609,7 @@ struct l2t_entry *t4_l2t_alloc_switching(struct adapter *adap, u16 vlan, · 36 unmodified lines | ||
| 613 | 609 | } |
| 614 | 610 | |
| 615 | 611 | /** |
| 612 | + * cxgb4_l2t_alloc_switching - Allocates an L2T entry for switch filters | |
| 616 | 613 | * @dev: net_device pointer |
| 617 | 614 | * @vlan: VLAN Id |
| 618 | 615 | * @port: Associated port |
| @@ -598,7 +598,7 @@ struct sched_class *cxgb4_sched_class_alloc(struct net_device *dev, · 597 unmodified lines | ||
| 598 | 598 | /** |
| 599 | 599 | * cxgb4_sched_class_free - free a scheduling class |
| 600 | 600 | * @dev: net_device pointer |
| 601 | − * @e: scheduling class | |
| 601 | + * @classid: scheduling class id to free | |
| 602 | 602 | * |
| 603 | 603 | * Frees a scheduling class if there are no users. |
| 604 | 604 | */ |
| @@ -302,7 +302,7 @@ static void deferred_unmap_destructor(struct sk_buff *skb) · 301 unmodified lines | ||
| 302 | 302 | |
| 303 | 303 | /** |
| 304 | 304 | * free_tx_desc - reclaims Tx descriptors and their buffers |
| 305 | − * @adapter: the adapter | |
| 305 | + * @adap: the adapter | |
| 306 | 306 | * @q: the Tx queue to reclaim descriptors from |
| 307 | 307 | * @n: the number of descriptors to reclaim |
| 308 | 308 | * @unmap: whether the buffers should be unmapped for DMA |
| @@ -722,6 +722,7 @@ static inline unsigned int flits_to_desc(unsigned int n) · 413 unmodified lines | ||
| 722 | 722 | /** |
| 723 | 723 | * is_eth_imm - can an Ethernet packet be sent as immediate data? |
| 724 | 724 | * @skb: the packet |
| 725 | + * @chip_ver: chip version | |
| 725 | 726 | * |
| 726 | 727 | * Returns whether an Ethernet packet is small enough to fit as |
| 727 | 728 | * immediate data. Return value corresponds to headroom required. |
| @@ -749,6 +750,7 @@ static inline int is_eth_imm(const struct sk_buff *skb, unsigned int chip_ver) · 21 unmodified lines | ||
| 749 | 750 | /** |
| 750 | 751 | * calc_tx_flits - calculate the number of flits for a packet Tx WR |
| 751 | 752 | * @skb: the packet |
| 753 | + * @chip_ver: chip version | |
| 752 | 754 | * |
| 753 | 755 | * Returns the number of flits needed for a Tx WR for the given Ethernet |
| 754 | 756 | * packet, including the needed WR and CPL headers. |
| @@ -804,6 +806,7 @@ static inline unsigned int calc_tx_flits(const struct sk_buff *skb, · 49 unmodified lines | ||
| 804 | 806 | /** |
| 805 | 807 | * calc_tx_descs - calculate the number of Tx descriptors for a packet |
| 806 | 808 | * @skb: the packet |
| 809 | + * @chip_ver: chip version | |
| 807 | 810 | * |
| 808 | 811 | * Returns the number of Tx descriptors needed for the given Ethernet |
| 809 | 812 | * packet, including the needed WR and CPL headers. |
| @@ -1425,12 +1428,10 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 615 unmodified lines | ||
| 1425 | 1428 | |
| 1426 | 1429 | qidx = skb_get_queue_mapping(skb); |
| 1427 | 1430 | if (ptp_enabled) { |
| 1428 | − spin_lock(&adap->ptp_lock); | |
| 1429 | 1431 | if (!(adap->ptp_tx_skb)) { |
| 1430 | 1432 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
| 1431 | 1433 | adap->ptp_tx_skb = skb_get(skb); |
| 1432 | 1434 | } else { |
| 1433 | − spin_unlock(&adap->ptp_lock); | |
| 1434 | 1435 | goto out_free; |
| 1435 | 1436 | } |
| 1436 | 1437 | q = &adap->sge.ptptxq; |
| @@ -1444,11 +1445,8 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 7 unmodified lines | ||
| 1444 | 1445 | |
| 1445 | 1446 | #ifdef CONFIG_CHELSIO_T4_FCOE |
| 1446 | 1447 | ret = cxgb_fcoe_offload(skb, adap, pi, &cntrl); |
| 1447 | − if (unlikely(ret == -ENOTSUPP)) { | |
| 1448 | − if (ptp_enabled) | |
| 1449 | − spin_unlock(&adap->ptp_lock); | |
| 1448 | + if (unlikely(ret == -EOPNOTSUPP)) | |
| 1450 | 1449 | goto out_free; |
| 1451 | − } | |
| 1452 | 1450 | #endif /* CONFIG_CHELSIO_T4_FCOE */ |
| 1453 | 1451 | |
| 1454 | 1452 | chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip); |
| @@ -1461,8 +1459,6 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 6 unmodified lines | ||
| 1461 | 1459 | dev_err(adap->pdev_dev, |
| 1462 | 1460 | "%s: Tx ring %u full while queue awake!\n", |
| 1463 | 1461 | dev->name, qidx); |
| 1464 | − if (ptp_enabled) | |
| 1465 | − spin_unlock(&adap->ptp_lock); | |
| 1466 | 1462 | return NETDEV_TX_BUSY; |
| 1467 | 1463 | } |
| 1468 | 1464 | |
| @@ -1481,8 +1477,6 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 12 unmodified lines | ||
| 1481 | 1477 | unlikely(cxgb4_map_skb(adap->pdev_dev, skb, sgl_sdesc->addr) < 0)) { |
| 1482 | 1478 | memset(sgl_sdesc->addr, 0, sizeof(sgl_sdesc->addr)); |
| 1483 | 1479 | q->mapping_err++; |
| 1484 | − if (ptp_enabled) | |
| 1485 | − spin_unlock(&adap->ptp_lock); | |
| 1486 | 1480 | goto out_free; |
| 1487 | 1481 | } |
| 1488 | 1482 | |
| @@ -1533,8 +1527,7 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 44 unmodified lines | ||
| 1533 | 1527 | if (iph->version == 4) { |
| 1534 | 1528 | iph->check = 0; |
| 1535 | 1529 | iph->tot_len = 0; |
| 1536 | − iph->check = (u16)(~ip_fast_csum((u8 *)iph, | |
| 1537 | − iph->ihl)); | |
| 1530 | + iph->check = ~ip_fast_csum((u8 *)iph, iph->ihl); | |
| 1538 | 1531 | } |
| 1539 | 1532 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 1540 | 1533 | cntrl = hwcsum(adap->params.chip, skb); |
| @@ -1630,8 +1623,6 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 89 unmodified lines | ||
| 1630 | 1623 | txq_advance(&q->q, ndesc); |
| 1631 | 1624 | |
| 1632 | 1625 | cxgb4_ring_tx_db(adap, &q->q, ndesc); |
| 1633 | − if (ptp_enabled) | |
| 1634 | − spin_unlock(&adap->ptp_lock); | |
| 1635 | 1626 | return NETDEV_TX_OK; |
| 1636 | 1627 | |
| 1637 | 1628 | out_free: |
| @@ -2377,6 +2368,16 @@ netdev_tx_t t4_start_xmit(struct sk_buff *skb, struct net_device *dev) · 739 unmodified lines | ||
| 2377 | 2368 | if (unlikely(qid >= pi->nqsets)) |
| 2378 | 2369 | return cxgb4_ethofld_xmit(skb, dev); |
| 2379 | 2370 | |
| 2371 | + if (is_ptp_enabled(skb, dev)) { | |
| 2372 | + struct adapter *adap = netdev2adap(dev); | |
| 2373 | + netdev_tx_t ret; | |
| 2374 | + | |
| 2375 | + spin_lock(&adap->ptp_lock); | |
| 2376 | + ret = cxgb4_eth_xmit(skb, dev); | |
| 2377 | + spin_unlock(&adap->ptp_lock); | |
| 2378 | + return ret; | |
| 2379 | + } | |
| 2380 | + | |
| 2380 | 2381 | return cxgb4_eth_xmit(skb, dev); |
| 2381 | 2382 | } |
| 2382 | 2383 | |
| @@ -2410,9 +2411,9 @@ static void eosw_txq_flush_pending_skbs(struct sge_eosw_txq *eosw_txq) · 27 unmodified lines | ||
| 2410 | 2411 | |
| 2411 | 2412 | /** |
| 2412 | 2413 | * cxgb4_ethofld_send_flowc - Send ETHOFLD flowc request to bind eotid to tc. |
| 2413 | − * @dev - netdevice | |
| 2414 | − * @eotid - ETHOFLD tid to bind/unbind | |
| 2415 | − * @tc - traffic class. If set to FW_SCHED_CLS_NONE, then unbinds the @eotid | |
| 2414 | + * @dev: netdevice | |
| 2415 | + * @eotid: ETHOFLD tid to bind/unbind | |
| 2416 | + * @tc: traffic class. If set to FW_SCHED_CLS_NONE, then unbinds the @eotid | |
| 2416 | 2417 | * |
| 2417 | 2418 | * Send a FLOWC work request to bind an ETHOFLD TID to a traffic class. |
| 2418 | 2419 | * If @tc is set to FW_SCHED_CLS_NONE, then the @eotid is unbound from |
| @@ -2691,7 +2692,6 @@ static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb) · 272 unmodified lines | ||
| 2691 | 2692 | |
| 2692 | 2693 | /** |
| 2693 | 2694 | * txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion |
| 2694 | − * @adap: the adapter | |
| 2695 | 2695 | * @q: the queue to stop |
| 2696 | 2696 | * |
| 2697 | 2697 | * Mark a Tx queue stopped due to I/O MMU exhaustion and resulting |
| @@ -3286,7 +3286,7 @@ enum { · 588 unmodified lines | ||
| 3286 | 3286 | |
| 3287 | 3287 | /** |
| 3288 | 3288 | * t4_systim_to_hwstamp - read hardware time stamp |
| 3289 | − * @adap: the adapter | |
| 3289 | + * @adapter: the adapter | |
| 3290 | 3290 | * @skb: the packet |
| 3291 | 3291 | * |
| 3292 | 3292 | * Read Time Stamp from MPS packet and insert in skb which |
| @@ -3313,15 +3313,16 @@ static noinline int t4_systim_to_hwstamp(struct adapter *adapter, · 20 unmodified lines | ||
| 3313 | 3313 | |
| 3314 | 3314 | hwtstamps = skb_hwtstamps(skb); |
| 3315 | 3315 | memset(hwtstamps, 0, sizeof(*hwtstamps)); |
| 3316 | − hwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(*((u64 *)data))); | |
| 3316 | + hwtstamps->hwtstamp = ns_to_ktime(get_unaligned_be64(data)); | |
| 3317 | 3317 | |
| 3318 | 3318 | return RX_PTP_PKT_SUC; |
| 3319 | 3319 | } |
| 3320 | 3320 | |
| 3321 | 3321 | /** |
| 3322 | 3322 | * t4_rx_hststamp - Recv PTP Event Message |
| 3323 | − * @adap: the adapter | |
| 3323 | + * @adapter: the adapter | |
| 3324 | 3324 | * @rsp: the response queue descriptor holding the RX_PKT message |
| 3325 | + * @rxq: the response queue holding the RX_PKT message | |
| 3325 | 3326 | * @skb: the packet |
| 3326 | 3327 | * |
| 3327 | 3328 | * PTP enabled and MPS packet, read HW timestamp |
| @@ -3345,7 +3346,7 @@ static int t4_rx_hststamp(struct adapter *adapter, const __be64 *rsp, · 17 unmodified lines | ||
| 3345 | 3346 | |
| 3346 | 3347 | /** |
| 3347 | 3348 | * t4_tx_hststamp - Loopback PTP Transmit Event Message |
| 3348 | − * @adap: the adapter | |
| 3349 | + * @adapter: the adapter | |
| 3349 | 3350 | * @skb: the packet |
| 3350 | 3351 | * @dev: the ingress net device |
| 3351 | 3352 | * |
| @@ -103,6 +103,7 @@ static void t4_smte_free(struct smt_entry *e) · 102 unmodified lines | ||
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | /** |
| 106 | + * cxgb4_smt_release - Release SMT entry | |
| 106 | 107 | * @e: smt entry to release |
| 107 | 108 | * |
| 108 | 109 | * Releases ref count and frees up an smt entry from SMT table |
| @@ -231,6 +232,7 @@ static struct smt_entry *t4_smt_alloc_switching(struct adapter *adap, u16 pfvf, · 122 unmodified lines | ||
| 231 | 232 | } |
| 232 | 233 | |
| 233 | 234 | /** |
| 235 | + * cxgb4_smt_alloc_switching - Allocates an SMT entry for switch filters. | |
| 234 | 236 | * @dev: net_device pointer |
| 235 | 237 | * @smac: MAC address to add to SMT |
| 236 | 238 | * Returns pointer to the SMT entry created |
| @@ -3163,7 +3163,7 @@ int t4_get_tp_version(struct adapter *adapter, u32 *vers) · 3162 unmodified lines | ||
| 3163 | 3163 | |
| 3164 | 3164 | /** |
| 3165 | 3165 | * t4_get_exprom_version - return the Expansion ROM version (if any) |
| 3166 | − * @adapter: the adapter | |
| 3166 | + * @adap: the adapter | |
| 3167 | 3167 | * @vers: where to place the version |
| 3168 | 3168 | * |
| 3169 | 3169 | * Reads the Expansion ROM header from FLASH and returns the version |
| @@ -5310,7 +5310,7 @@ static unsigned int t4_use_ldst(struct adapter *adap) · 2140 unmodified lines | ||
| 5310 | 5310 | * @cmd: TP fw ldst address space type |
| 5311 | 5311 | * @vals: where the indirect register values are stored/written |
| 5312 | 5312 | * @nregs: how many indirect registers to read/write |
| 5313 | − * @start_idx: index of first indirect register to read/write | |
| 5313 | + * @start_index: index of first indirect register to read/write | |
| 5314 | 5314 | * @rw: Read (1) or Write (0) |
| 5315 | 5315 | * @sleep_ok: if true we may sleep while awaiting command completion |
| 5316 | 5316 | * |
| @@ -6115,7 +6115,7 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) · 798 unmodified lines | ||
| 6115 | 6115 | |
| 6116 | 6116 | /** |
| 6117 | 6117 | * compute_mps_bg_map - compute the MPS Buffer Group Map for a Port |
| 6118 | − * @adap: the adapter | |
| 6118 | + * @adapter: the adapter | |
| 6119 | 6119 | * @pidx: the port index |
| 6120 | 6120 | * |
| 6121 | 6121 | * Computes and returns a bitmap indicating which MPS buffer groups are |
| @@ -6252,7 +6252,7 @@ static unsigned int t4_get_tp_e2c_map(struct adapter *adapter, int pidx) · 130 unmodified lines | ||
| 6252 | 6252 | |
| 6253 | 6253 | /** |
| 6254 | 6254 | * t4_get_tp_ch_map - return TP ingress channels associated with a port |
| 6255 | − * @adapter: the adapter | |
| 6255 | + * @adap: the adapter | |
| 6256 | 6256 | * @pidx: the port index |
| 6257 | 6257 | * |
| 6258 | 6258 | * Returns a bitmap indicating which TP Ingress Channels are associated |
| @@ -6589,7 +6589,7 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, · 330 unmodified lines | ||
| 6589 | 6589 | * @phy_addr: the PHY address |
| 6590 | 6590 | * @mmd: the PHY MMD to access (0 for clause 22 PHYs) |
| 6591 | 6591 | * @reg: the register to write |
| 6592 | − * @valp: value to write | |
| 6592 | + * @val: value to write | |
| 6593 | 6593 | * |
| 6594 | 6594 | * Issues a FW command through the given mailbox to write a PHY register. |
| 6595 | 6595 | */ |
| @@ -6615,7 +6615,7 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, · 19 unmodified lines | ||
| 6615 | 6615 | |
| 6616 | 6616 | /** |
| 6617 | 6617 | * t4_sge_decode_idma_state - decode the idma state |
| 6618 | − * @adap: the adapter | |
| 6618 | + * @adapter: the adapter | |
| 6619 | 6619 | * @state: the state idma is stuck in |
| 6620 | 6620 | */ |
| 6621 | 6621 | void t4_sge_decode_idma_state(struct adapter *adapter, int state) |
| @@ -6782,7 +6782,7 @@ void t4_sge_decode_idma_state(struct adapter *adapter, int state) · 160 unmodified lines | ||
| 6782 | 6782 | * t4_sge_ctxt_flush - flush the SGE context cache |
| 6783 | 6783 | * @adap: the adapter |
| 6784 | 6784 | * @mbox: mailbox to use for the FW command |
| 6785 | − * @ctx_type: Egress or Ingress | |
| 6785 | + * @ctxt_type: Egress or Ingress | |
| 6786 | 6786 | * |
| 6787 | 6787 | * Issues a FW command through the given mailbox to flush the |
| 6788 | 6788 | * SGE context cache. |
| @@ -6809,7 +6809,7 @@ int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox, int ctxt_type) · 20 unmodified lines | ||
| 6809 | 6809 | |
| 6810 | 6810 | /** |
| 6811 | 6811 | * t4_read_sge_dbqtimers - read SGE Doorbell Queue Timer values |
| 6812 | − * @adap - the adapter | |
| 6812 | + * @adap: the adapter | |
| 6813 | 6813 | * @ndbqtimers: size of the provided SGE Doorbell Queue Timer table |
| 6814 | 6814 | * @dbqtimers: SGE Doorbell Queue Timer table |
| 6815 | 6815 | * |
| @@ -7092,6 +7092,7 @@ static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) · 276 unmodified lines | ||
| 7092 | 7092 | /** |
| 7093 | 7093 | * t4_fw_restart - restart the firmware by taking the uP out of RESET |
| 7094 | 7094 | * @adap: the adapter |
| 7095 | + * @mbox: mailbox to use for the FW command | |
| 7095 | 7096 | * @reset: if we want to do a RESET to restart things |
| 7096 | 7097 | * |
| 7097 | 7098 | * Restart firmware previously halted by t4_fw_halt(). On successful |
| @@ -7630,6 +7631,8 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, · 532 unmodified lines | ||
| 7630 | 7631 | * @nmac: number of MAC addresses needed (1 to 5) |
| 7631 | 7632 | * @mac: the MAC addresses of the VI |
| 7632 | 7633 | * @rss_size: size of RSS table slice associated with this VI |
| 7634 | + * @vivld: the destination to store the VI Valid value. | |
| 7635 | + * @vin: the destination to store the VIN value. | |
| 7633 | 7636 | * |
| 7634 | 7637 | * Allocates a virtual interface for the given physical port. If @mac is |
| 7635 | 7638 | * not %NULL it contains the MAC addresses of the VI as assigned by FW. |
| @@ -7848,7 +7851,7 @@ int t4_free_raw_mac_filt(struct adapter *adap, unsigned int viid, · 212 unmodified lines | ||
| 7848 | 7851 | * t4_alloc_encap_mac_filt - Adds a mac entry in mps tcam with VNI support |
| 7849 | 7852 | * @adap: the adapter |
| 7850 | 7853 | * @viid: the VI id |
| 7851 | − * @mac: the MAC address | |
| 7854 | + * @addr: the MAC address | |
| 7852 | 7855 | * @mask: the mask |
| 7853 | 7856 | * @vni: the VNI id for the tunnel protocol |
| 7854 | 7857 | * @vni_mask: mask for the VNI id |
| @@ -7897,11 +7900,11 @@ int t4_alloc_encap_mac_filt(struct adapter *adap, unsigned int viid, · 42 unmodified lines | ||
| 7897 | 7900 | * t4_alloc_raw_mac_filt - Adds a mac entry in mps tcam |
| 7898 | 7901 | * @adap: the adapter |
| 7899 | 7902 | * @viid: the VI id |
| 7900 | − * @mac: the MAC address | |
| 7903 | + * @addr: the MAC address | |
| 7901 | 7904 | * @mask: the mask |
| 7902 | 7905 | * @idx: index at which to add this entry |
| 7903 | − * @port_id: the port index | |
| 7904 | 7906 | * @lookup_type: MAC address for inner (1) or outer (0) header |
| 7907 | + * @port_id: the port index | |
| 7905 | 7908 | * @sleep_ok: call is allowed to sleep |
| 7906 | 7909 | * |
| 7907 | 7910 | * Adds the mac entry at the specified index using raw mac interface. |
| @@ -8126,7 +8129,7 @@ int t4_free_mac_filt(struct adapter *adap, unsigned int mbox, · 218 unmodified lines | ||
| 8126 | 8129 | * @idx: index of existing filter for old value of MAC address, or -1 |
| 8127 | 8130 | * @addr: the new MAC address value |
| 8128 | 8131 | * @persist: whether a new MAC allocation should be persistent |
| 8129 | − * @add_smt: if true also add the address to the HW SMT | |
| 8132 | + * @smt_idx: the destination to store the new SMT index. | |
| 8130 | 8133 | * |
| 8131 | 8134 | * Modifies an exact-match filter and sets it to the new MAC address. |
| 8132 | 8135 | * Note that in general it is not possible to modify the value of a given |
| @@ -8448,7 +8451,6 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, · 315 unmodified lines | ||
| 8448 | 8451 | |
| 8449 | 8452 | /** |
| 8450 | 8453 | * t4_link_down_rc_str - return a string for a Link Down Reason Code |
| 8451 | − * @adap: the adapter | |
| 8452 | 8454 | * @link_down_rc: Link Down Reason Code |
| 8453 | 8455 | * |
| 8454 | 8456 | * Returns a string representation of the Link Down Reason Code. |
| @@ -8472,9 +8474,7 @@ static const char *t4_link_down_rc_str(unsigned char link_down_rc) · 17 unmodified lines | ||
| 8472 | 8474 | return reason[link_down_rc]; |
| 8473 | 8475 | } |
| 8474 | 8476 | |
| 8475 | −/** | |
| 8476 | − * Return the highest speed set in the port capabilities, in Mb/s. | |
| 8477 | − */ | |
| 8477 | +/* Return the highest speed set in the port capabilities, in Mb/s. */ | |
| 8478 | 8478 | static unsigned int fwcap_to_speed(fw_port_cap32_t caps) |
| 8479 | 8479 | { |
| 8480 | 8480 | #define TEST_SPEED_RETURN(__caps_speed, __speed) \ |
| @@ -9110,7 +9110,6 @@ found: · 629 unmodified lines | ||
| 9110 | 9110 | /** |
| 9111 | 9111 | * t4_prep_adapter - prepare SW and HW for operation |
| 9112 | 9112 | * @adapter: the adapter |
| 9113 | − * @reset: if true perform a HW reset | |
| 9114 | 9113 | * |
| 9115 | 9114 | * Initialize adapter SW state for the various HW modules, set initial |
| 9116 | 9115 | * values for some adapter tunables, take PHYs out of reset, and |
| @@ -10395,6 +10394,7 @@ int t4_sched_params(struct adapter *adapter, u8 type, u8 level, u8 mode, · 1278 unmodified lines | ||
| 10395 | 10394 | /** |
| 10396 | 10395 | * t4_i2c_rd - read I2C data from adapter |
| 10397 | 10396 | * @adap: the adapter |
| 10397 | + * @mbox: mailbox to use for the FW command | |
| 10398 | 10398 | * @port: Port number if per-port device; <0 if not |
| 10399 | 10399 | * @devid: per-port device ID or absolute device ID |
| 10400 | 10400 | * @offset: byte offset into device I2C space |
| @@ -10450,7 +10450,7 @@ int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port, · 49 unmodified lines | ||
| 10450 | 10450 | |
| 10451 | 10451 | /** |
| 10452 | 10452 | * t4_set_vlan_acl - Set a VLAN id for the specified VF |
| 10453 | − * @adapter: the adapter | |
| 10453 | + * @adap: the adapter | |
| 10454 | 10454 | * @mbox: mailbox to use for the FW command |
| 10455 | 10455 | * @vf: one of the VFs instantiated by the specified PF |
| 10456 | 10456 | * @vlan: The vlanid to be set |
| @@ -260,8 +260,7 @@ static int cxgb4vf_set_addr_hash(struct port_info *pi) · 259 unmodified lines | ||
| 260 | 260 | * @tcam_idx: TCAM index of existing filter for old value of MAC address, |
| 261 | 261 | * or -1 |
| 262 | 262 | * @addr: the new MAC address value |
| 263 | − * @persist: whether a new MAC allocation should be persistent | |
| 264 | − * @add_smt: if true also add the address to the HW SMT | |
| 263 | + * @persistent: whether a new MAC allocation should be persistent | |
| 265 | 264 | * |
| 266 | 265 | * Modifies an MPS filter and sets it to the new MAC address if |
| 267 | 266 | * @tcam_idx >= 0, or adds the MAC address to a new filter if |
| @@ -1692,7 +1692,7 @@ static inline bool is_new_response(const struct rsp_ctrl *rc, · 1691 unmodified lines | ||
| 1692 | 1692 | * restore_rx_bufs - put back a packet's RX buffers |
| 1693 | 1693 | * @gl: the packet gather list |
| 1694 | 1694 | * @fl: the SGE Free List |
| 1695 | − * @nfrags: how many fragments in @si | |
| 1695 | + * @frags: how many fragments in @si | |
| 1696 | 1696 | * |
| 1697 | 1697 | * Called when we find out that the current packet, @si, can't be |
| 1698 | 1698 | * processed right away for some reason. This is a very rare event and |
| @@ -2054,7 +2054,7 @@ irq_handler_t t4vf_intr_handler(struct adapter *adapter) · 355 unmodified lines | ||
| 2054 | 2054 | |
| 2055 | 2055 | /** |
| 2056 | 2056 | * sge_rx_timer_cb - perform periodic maintenance of SGE RX queues |
| 2057 | − * @data: the adapter | |
| 2057 | + * @t: Rx timer | |
| 2058 | 2058 | * |
| 2059 | 2059 | * Runs periodically from a timer to perform maintenance of SGE RX queues. |
| 2060 | 2060 | * |
| @@ -2113,7 +2113,7 @@ static void sge_rx_timer_cb(struct timer_list *t) · 52 unmodified lines | ||
| 2113 | 2113 | |
| 2114 | 2114 | /** |
| 2115 | 2115 | * sge_tx_timer_cb - perform periodic maintenance of SGE Tx queues |
| 2116 | − * @data: the adapter | |
| 2116 | + * @t: Tx timer | |
| 2117 | 2117 | * |
| 2118 | 2118 | * Runs periodically from a timer to perform maintenance of SGE TX queues. |
| 2119 | 2119 | * |
| @@ -2405,6 +2405,7 @@ err: · 285 unmodified lines | ||
| 2405 | 2405 | * t4vf_sge_alloc_eth_txq - allocate an SGE Ethernet TX Queue |
| 2406 | 2406 | * @adapter: the adapter |
| 2407 | 2407 | * @txq: pointer to the new txq to be filled in |
| 2408 | + * @dev: the network device | |
| 2408 | 2409 | * @devq: the network TX queue associated with the new txq |
| 2409 | 2410 | * @iqid: the relative ingress queue ID to which events relating to |
| 2410 | 2411 | * the new txq should be directed |
| @@ -389,9 +389,7 @@ static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec) · 388 unmodified lines | ||
| 389 | 389 | return cc_fec; |
| 390 | 390 | } |
| 391 | 391 | |
| 392 | −/** | |
| 393 | − * Return the highest speed set in the port capabilities, in Mb/s. | |
| 394 | − */ | |
| 392 | +/* Return the highest speed set in the port capabilities, in Mb/s. */ | |
| 395 | 393 | static unsigned int fwcap_to_speed(fw_port_cap32_t caps) |
| 396 | 394 | { |
| 397 | 395 | #define TEST_SPEED_RETURN(__caps_speed, __speed) \ |
| @@ -1467,6 +1465,7 @@ int t4vf_identify_port(struct adapter *adapter, unsigned int viid, · 1069 unmodified lines | ||
| 1467 | 1465 | * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change |
| 1468 | 1466 | * @vlanex: 1 to enable hardware VLAN Tag extraction, 0 to disable it, |
| 1469 | 1467 | * -1 no change |
| 1468 | + * @sleep_ok: call is allowed to sleep | |
| 1470 | 1469 | * |
| 1471 | 1470 | * Sets Rx properties of a virtual interface. |
| 1472 | 1471 | */ |
| @@ -1906,7 +1905,7 @@ static const char *t4vf_link_down_rc_str(unsigned char link_down_rc) · 433 unmodified lines | ||
| 1906 | 1905 | /** |
| 1907 | 1906 | * t4vf_handle_get_port_info - process a FW reply message |
| 1908 | 1907 | * @pi: the port info |
| 1909 | − * @rpl: start of the FW message | |
| 1908 | + * @cmd: start of the FW message | |
| 1910 | 1909 | * |
| 1911 | 1910 | * Processes a GET_PORT_INFO FW reply message. |
| 1912 | 1911 | */ |
| @@ -2137,8 +2136,6 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) · 224 unmodified lines | ||
| 2137 | 2136 | return 0; |
| 2138 | 2137 | } |
| 2139 | 2138 | |
| 2140 | −/** | |
| 2141 | − */ | |
| 2142 | 2139 | int t4vf_prep_adapter(struct adapter *adapter) |
| 2143 | 2140 | { |
| 2144 | 2141 | int err; |
| @@ -1595,6 +1595,24 @@ static int enetc_set_psfp(struct net_device *ndev, int en) · 1594 unmodified lines | ||
| 1595 | 1595 | return 0; |
| 1596 | 1596 | } |
| 1597 | 1597 | |
| 1598 | +static void enetc_enable_rxvlan(struct net_device *ndev, bool en) | |
| 1599 | +{ | |
| 1600 | + struct enetc_ndev_priv *priv = netdev_priv(ndev); | |
| 1601 | + int i; | |
| 1602 | + | |
| 1603 | + for (i = 0; i < priv->num_rx_rings; i++) | |
| 1604 | + enetc_bdr_enable_rxvlan(&priv->si->hw, i, en); | |
| 1605 | +} | |
| 1606 | + | |
| 1607 | +static void enetc_enable_txvlan(struct net_device *ndev, bool en) | |
| 1608 | +{ | |
| 1609 | + struct enetc_ndev_priv *priv = netdev_priv(ndev); | |
| 1610 | + int i; | |
| 1611 | + | |
| 1612 | + for (i = 0; i < priv->num_tx_rings; i++) | |
| 1613 | + enetc_bdr_enable_txvlan(&priv->si->hw, i, en); | |
| 1614 | +} | |
| 1615 | + | |
| 1598 | 1616 | int enetc_set_features(struct net_device *ndev, |
| 1599 | 1617 | netdev_features_t features) |
| 1600 | 1618 | { |
| @@ -1604,6 +1622,14 @@ int enetc_set_features(struct net_device *ndev, · 3 unmodified lines | ||
| 1604 | 1622 | if (changed & NETIF_F_RXHASH) |
| 1605 | 1623 | enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH)); |
| 1606 | 1624 | |
| 1625 | + if (changed & NETIF_F_HW_VLAN_CTAG_RX) | |
| 1626 | + enetc_enable_rxvlan(ndev, | |
| 1627 | + !!(features & NETIF_F_HW_VLAN_CTAG_RX)); | |
| 1628 | + | |
| 1629 | + if (changed & NETIF_F_HW_VLAN_CTAG_TX) | |
| 1630 | + enetc_enable_txvlan(ndev, | |
| 1631 | + !!(features & NETIF_F_HW_VLAN_CTAG_TX)); | |
| 1632 | + | |
| 1607 | 1633 | if (changed & NETIF_F_HW_TC) |
| 1608 | 1634 | err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC)); |
| 1609 | 1635 | |
| @@ -531,22 +531,22 @@ struct enetc_msg_cmd_header { · 530 unmodified lines | ||
| 531 | 531 | |
| 532 | 532 | /* Common H/W utility functions */ |
| 533 | 533 | |
| 534 | −static inline void enetc_enable_rxvlan(struct enetc_hw *hw, int si_idx, | |
| 535 | − bool en) | |
| 534 | +static inline void enetc_bdr_enable_rxvlan(struct enetc_hw *hw, int idx, | |
| 535 | + bool en) | |
| 536 | 536 | { |
| 537 | − u32 val = enetc_rxbdr_rd(hw, si_idx, ENETC_RBMR); | |
| 537 | + u32 val = enetc_rxbdr_rd(hw, idx, ENETC_RBMR); | |
| 538 | 538 | |
| 539 | 539 | val = (val & ~ENETC_RBMR_VTE) | (en ? ENETC_RBMR_VTE : 0); |
| 540 | − enetc_rxbdr_wr(hw, si_idx, ENETC_RBMR, val); | |
| 540 | + enetc_rxbdr_wr(hw, idx, ENETC_RBMR, val); | |
| 541 | 541 | } |
| 542 | 542 | |
| 543 | −static inline void enetc_enable_txvlan(struct enetc_hw *hw, int si_idx, | |
| 544 | − bool en) | |
| 543 | +static inline void enetc_bdr_enable_txvlan(struct enetc_hw *hw, int idx, | |
| 544 | + bool en) | |
| 545 | 545 | { |
| 546 | − u32 val = enetc_txbdr_rd(hw, si_idx, ENETC_TBMR); | |
| 546 | + u32 val = enetc_txbdr_rd(hw, idx, ENETC_TBMR); | |
| 547 | 547 | |
| 548 | 548 | val = (val & ~ENETC_TBMR_VIH) | (en ? ENETC_TBMR_VIH : 0); |
| 549 | − enetc_txbdr_wr(hw, si_idx, ENETC_TBMR, val); | |
| 549 | + enetc_txbdr_wr(hw, idx, ENETC_TBMR, val); | |
| 550 | 550 | } |
| 551 | 551 | |
| 552 | 552 | static inline void enetc_set_bdr_prio(struct enetc_hw *hw, int bdr_idx, |
| @@ -649,14 +649,6 @@ static int enetc_pf_set_features(struct net_device *ndev, · 648 unmodified lines | ||
| 649 | 649 | netdev_features_t changed = ndev->features ^ features; |
| 650 | 650 | struct enetc_ndev_priv *priv = netdev_priv(ndev); |
| 651 | 651 | |
| 652 | − if (changed & NETIF_F_HW_VLAN_CTAG_RX) | |
| 653 | − enetc_enable_rxvlan(&priv->si->hw, 0, | |
| 654 | − !!(features & NETIF_F_HW_VLAN_CTAG_RX)); | |
| 655 | − | |
| 656 | − if (changed & NETIF_F_HW_VLAN_CTAG_TX) | |
| 657 | − enetc_enable_txvlan(&priv->si->hw, 0, | |
| 658 | − !!(features & NETIF_F_HW_VLAN_CTAG_TX)); | |
| 659 | − | |
| 660 | 652 | if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) { |
| 661 | 653 | struct enetc_pf *pf = enetc_si_priv(priv->si); |
| 662 | 654 | |
| @@ -699,7 +699,7 @@ static void hns_nic_rx_up_pro(struct hns_nic_ring_data *ring_data, · 698 unmodified lines | ||
| 699 | 699 | struct net_device *ndev = ring_data->napi.dev; |
| 700 | 700 | |
| 701 | 701 | skb->protocol = eth_type_trans(skb, ndev); |
| 702 | − (void)napi_gro_receive(&ring_data->napi, skb); | |
| 702 | + napi_gro_receive(&ring_data->napi, skb); | |
| 703 | 703 | } |
| 704 | 704 | |
| 705 | 705 | static int hns_desc_unused(struct hnae_ring *ring) |
| @@ -1715,7 +1715,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) · 1714 unmodified lines | ||
| 1715 | 1715 | } |
| 1716 | 1716 | |
| 1717 | 1717 | netdev->min_mtu = IBMVETH_MIN_MTU; |
| 1718 | − netdev->max_mtu = ETH_MAX_MTU; | |
| 1718 | + netdev->max_mtu = ETH_MAX_MTU - IBMVETH_BUFF_OH; | |
| 1719 | 1719 | |
| 1720 | 1720 | memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN); |
| 1721 | 1721 | |
| @@ -842,12 +842,13 @@ static int ibmvnic_login(struct net_device *netdev) · 841 unmodified lines | ||
| 842 | 842 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 843 | 843 | unsigned long timeout = msecs_to_jiffies(30000); |
| 844 | 844 | int retry_count = 0; |
| 845 | + int retries = 10; | |
| 845 | 846 | bool retry; |
| 846 | 847 | int rc; |
| 847 | 848 | |
| 848 | 849 | do { |
| 849 | 850 | retry = false; |
| 850 | − if (retry_count > IBMVNIC_MAX_QUEUES) { | |
| 851 | + if (retry_count > retries) { | |
| 851 | 852 | netdev_warn(netdev, "Login attempts exceeded\n"); |
| 852 | 853 | return -1; |
| 853 | 854 | } |
| @@ -862,11 +863,23 @@ static int ibmvnic_login(struct net_device *netdev) · 8 unmodified lines | ||
| 862 | 863 | |
| 863 | 864 | if (!wait_for_completion_timeout(&adapter->init_done, |
| 864 | 865 | timeout)) { |
| 865 | − netdev_warn(netdev, "Login timed out\n"); | |
| 866 | − return -1; | |
| 866 | + netdev_warn(netdev, "Login timed out, retrying...\n"); | |
| 867 | + retry = true; | |
| 868 | + adapter->init_done_rc = 0; | |
| 869 | + retry_count++; | |
| 870 | + continue; | |
| 867 | 871 | } |
| 868 | 872 | |
| 869 | − if (adapter->init_done_rc == PARTIALSUCCESS) { | |
| 873 | + if (adapter->init_done_rc == ABORTED) { | |
| 874 | + netdev_warn(netdev, "Login aborted, retrying...\n"); | |
| 875 | + retry = true; | |
| 876 | + adapter->init_done_rc = 0; | |
| 877 | + retry_count++; | |
| 878 | + /* FW or device may be busy, so | |
| 879 | + * wait a bit before retrying login | |
| 880 | + */ | |
| 881 | + msleep(500); | |
| 882 | + } else if (adapter->init_done_rc == PARTIALSUCCESS) { | |
| 870 | 883 | retry_count++; |
| 871 | 884 | release_sub_crqs(adapter, 1); |
| 872 | 885 | |
| @@ -1958,13 +1971,18 @@ static int do_reset(struct ibmvnic_adapter *adapter, · 1085 unmodified lines | ||
| 1958 | 1971 | release_sub_crqs(adapter, 1); |
| 1959 | 1972 | } else { |
| 1960 | 1973 | rc = ibmvnic_reset_crq(adapter); |
| 1961 | − if (!rc) | |
| 1974 | + if (rc == H_CLOSED || rc == H_SUCCESS) { | |
| 1962 | 1975 | rc = vio_enable_interrupts(adapter->vdev); |
| 1976 | + if (rc) | |
| 1977 | + netdev_err(adapter->netdev, | |
| 1978 | + "Reset failed to enable interrupts. rc=%d\n", | |
| 1979 | + rc); | |
| 1980 | + } | |
| 1963 | 1981 | } |
| 1964 | 1982 | |
| 1965 | 1983 | if (rc) { |
| 1966 | 1984 | netdev_err(adapter->netdev, |
| 1967 | − "Couldn't initialize crq. rc=%d\n", rc); | |
| 1985 | + "Reset couldn't initialize crq. rc=%d\n", rc); | |
| 1968 | 1986 | goto out; |
| 1969 | 1987 | } |
| 1970 | 1988 | |
| @@ -151,10 +151,8 @@ static int e1000_vlan_rx_kill_vid(struct net_device *netdev, · 150 unmodified lines | ||
| 151 | 151 | __be16 proto, u16 vid); |
| 152 | 152 | static void e1000_restore_vlan(struct e1000_adapter *adapter); |
| 153 | 153 | |
| 154 | −#ifdef CONFIG_PM | |
| 155 | −static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); | |
| 156 | −static int e1000_resume(struct pci_dev *pdev); | |
| 157 | −#endif | |
| 154 | +static int __maybe_unused e1000_suspend(struct device *dev); | |
| 155 | +static int __maybe_unused e1000_resume(struct device *dev); | |
| 158 | 156 | static void e1000_shutdown(struct pci_dev *pdev); |
| 159 | 157 | |
| 160 | 158 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| @@ -179,16 +177,16 @@ static const struct pci_error_handlers e1000_err_handler = { · 18 unmodified lines | ||
| 179 | 177 | .resume = e1000_io_resume, |
| 180 | 178 | }; |
| 181 | 179 | |
| 180 | +static SIMPLE_DEV_PM_OPS(e1000_pm_ops, e1000_suspend, e1000_resume); | |
| 181 | + | |
| 182 | 182 | static struct pci_driver e1000_driver = { |
| 183 | 183 | .name = e1000_driver_name, |
| 184 | 184 | .id_table = e1000_pci_tbl, |
| 185 | 185 | .probe = e1000_probe, |
| 186 | 186 | .remove = e1000_remove, |
| 187 | −#ifdef CONFIG_PM | |
| 188 | − /* Power Management Hooks */ | |
| 189 | − .suspend = e1000_suspend, | |
| 190 | − .resume = e1000_resume, | |
| 191 | −#endif | |
| 187 | + .driver = { | |
| 188 | + .pm = &e1000_pm_ops, | |
| 189 | + }, | |
| 192 | 190 | .shutdown = e1000_shutdown, |
| 193 | 191 | .err_handler = &e1000_err_handler |
| 194 | 192 | }; |
| @@ -5060,9 +5058,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) · 4865 unmodified lines | ||
| 5060 | 5058 | struct e1000_hw *hw = &adapter->hw; |
| 5061 | 5059 | u32 ctrl, ctrl_ext, rctl, status; |
| 5062 | 5060 | u32 wufc = adapter->wol; |
| 5063 | −#ifdef CONFIG_PM | |
| 5064 | − int retval = 0; | |
| 5065 | −#endif | |
| 5066 | 5061 | |
| 5067 | 5062 | netif_device_detach(netdev); |
| 5068 | 5063 | |
| @@ -5076,12 +5071,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) · 7 unmodified lines | ||
| 5076 | 5071 | e1000_down(adapter); |
| 5077 | 5072 | } |
| 5078 | 5073 | |
| 5079 | −#ifdef CONFIG_PM | |
| 5080 | − retval = pci_save_state(pdev); | |
| 5081 | − if (retval) | |
| 5082 | − return retval; | |
| 5083 | −#endif | |
| 5084 | − | |
| 5085 | 5074 | status = er32(STATUS); |
| 5086 | 5075 | if (status & E1000_STATUS_LU) |
| 5087 | 5076 | wufc &= ~E1000_WUFC_LNKC; |
| @@ -5142,37 +5131,26 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) · 54 unmodified lines | ||
| 5142 | 5131 | return 0; |
| 5143 | 5132 | } |
| 5144 | 5133 | |
| 5145 | −#ifdef CONFIG_PM | |
| 5146 | −static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |
| 5134 | +static int __maybe_unused e1000_suspend(struct device *dev) | |
| 5147 | 5135 | { |
| 5148 | 5136 | int retval; |
| 5137 | + struct pci_dev *pdev = to_pci_dev(dev); | |
| 5149 | 5138 | bool wake; |
| 5150 | 5139 | |
| 5151 | 5140 | retval = __e1000_shutdown(pdev, &wake); |
| 5152 | − if (retval) | |
| 5153 | − return retval; | |
| 5154 | − | |
| 5155 | − if (wake) { | |
| 5156 | − pci_prepare_to_sleep(pdev); | |
| 5157 | − } else { | |
| 5158 | − pci_wake_from_d3(pdev, false); | |
| 5159 | − pci_set_power_state(pdev, PCI_D3hot); | |
| 5160 | − } | |
| 5141 | + device_set_wakeup_enable(dev, wake); | |
| 5161 | 5142 | |
| 5162 | − return 0; | |
| 5143 | + return retval; | |
| 5163 | 5144 | } |
| 5164 | 5145 | |
| 5165 | −static int e1000_resume(struct pci_dev *pdev) | |
| 5146 | +static int __maybe_unused e1000_resume(struct device *dev) | |
| 5166 | 5147 | { |
| 5148 | + struct pci_dev *pdev = to_pci_dev(dev); | |
| 5167 | 5149 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 5168 | 5150 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 5169 | 5151 | struct e1000_hw *hw = &adapter->hw; |
| 5170 | 5152 | u32 err; |
| 5171 | 5153 | |
| 5172 | − pci_set_power_state(pdev, PCI_D0); | |
| 5173 | − pci_restore_state(pdev); | |
| 5174 | − pci_save_state(pdev); | |
| 5175 | − | |
| 5176 | 5154 | if (adapter->need_ioport) |
| 5177 | 5155 | err = pci_enable_device(pdev); |
| 5178 | 5156 | else |
| @@ -5209,7 +5187,6 @@ static int e1000_resume(struct pci_dev *pdev) · 30 unmodified lines | ||
| 5209 | 5187 | |
| 5210 | 5188 | return 0; |
| 5211 | 5189 | } |
| 5212 | −#endif | |
| 5213 | 5190 | |
| 5214 | 5191 | static void e1000_shutdown(struct pci_dev *pdev) |
| 5215 | 5192 | { |
| @@ -6349,7 +6349,6 @@ fl_out: · 6348 unmodified lines | ||
| 6349 | 6349 | pm_runtime_put_sync(netdev->dev.parent); |
| 6350 | 6350 | } |
| 6351 | 6351 | |
| 6352 | −#ifdef CONFIG_PM_SLEEP | |
| 6353 | 6352 | /* S0ix implementation */ |
| 6354 | 6353 | static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter) |
| 6355 | 6354 | { |
| @@ -6571,7 +6570,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter) · 215 unmodified lines | ||
| 6571 | 6570 | mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS; |
| 6572 | 6571 | ew32(CTRL_EXT, mac_data); |
| 6573 | 6572 | } |
| 6574 | −#endif /* CONFIG_PM_SLEEP */ | |
| 6575 | 6573 | |
| 6576 | 6574 | static int e1000e_pm_freeze(struct device *dev) |
| 6577 | 6575 | { |
| @@ -6611,11 +6609,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) · 33 unmodified lines | ||
| 6611 | 6609 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 6612 | 6610 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 6613 | 6611 | struct e1000_hw *hw = &adapter->hw; |
| 6614 | − u32 ctrl, ctrl_ext, rctl, status; | |
| 6615 | − /* Runtime suspend should only enable wakeup for link changes */ | |
| 6616 | − u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol; | |
| 6612 | + u32 ctrl, ctrl_ext, rctl, status, wufc; | |
| 6617 | 6613 | int retval = 0; |
| 6618 | 6614 | |
| 6615 | + /* Runtime suspend should only enable wakeup for link changes */ | |
| 6616 | + if (runtime) | |
| 6617 | + wufc = E1000_WUFC_LNKC; | |
| 6618 | + else if (device_may_wakeup(&pdev->dev)) | |
| 6619 | + wufc = adapter->wol; | |
| 6620 | + else | |
| 6621 | + wufc = 0; | |
| 6622 | + | |
| 6619 | 6623 | status = er32(STATUS); |
| 6620 | 6624 | if (status & E1000_STATUS_LU) |
| 6621 | 6625 | wufc &= ~E1000_WUFC_LNKC; |
| @@ -6672,7 +6676,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) · 50 unmodified lines | ||
| 6672 | 6676 | if (adapter->hw.phy.type == e1000_phy_igp_3) { |
| 6673 | 6677 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); |
| 6674 | 6678 | } else if (hw->mac.type >= e1000_pch_lpt) { |
| 6675 | − if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) | |
| 6679 | + if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) | |
| 6676 | 6680 | /* ULP does not support wake from unicast, multicast |
| 6677 | 6681 | * or broadcast. |
| 6678 | 6682 | */ |
| @@ -6869,7 +6873,6 @@ err_irq: · 190 unmodified lines | ||
| 6869 | 6873 | return rc; |
| 6870 | 6874 | } |
| 6871 | 6875 | |
| 6872 | −#ifdef CONFIG_PM | |
| 6873 | 6876 | static int __e1000_resume(struct pci_dev *pdev) |
| 6874 | 6877 | { |
| 6875 | 6878 | struct net_device *netdev = pci_get_drvdata(pdev); |
| @@ -6935,8 +6938,7 @@ static int __e1000_resume(struct pci_dev *pdev) · 59 unmodified lines | ||
| 6935 | 6938 | return 0; |
| 6936 | 6939 | } |
| 6937 | 6940 | |
| 6938 | −#ifdef CONFIG_PM_SLEEP | |
| 6939 | −static int e1000e_pm_suspend(struct device *dev) | |
| 6941 | +static __maybe_unused int e1000e_pm_suspend(struct device *dev) | |
| 6940 | 6942 | { |
| 6941 | 6943 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
| 6942 | 6944 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| @@ -6960,7 +6962,7 @@ static int e1000e_pm_suspend(struct device *dev) · 17 unmodified lines | ||
| 6960 | 6962 | return rc; |
| 6961 | 6963 | } |
| 6962 | 6964 | |
| 6963 | −static int e1000e_pm_resume(struct device *dev) | |
| 6965 | +static __maybe_unused int e1000e_pm_resume(struct device *dev) | |
| 6964 | 6966 | { |
| 6965 | 6967 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
| 6966 | 6968 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| @@ -6979,9 +6981,8 @@ static int e1000e_pm_resume(struct device *dev) · 12 unmodified lines | ||
| 6979 | 6981 | |
| 6980 | 6982 | return e1000e_pm_thaw(dev); |
| 6981 | 6983 | } |
| 6982 | −#endif /* CONFIG_PM_SLEEP */ | |
| 6983 | 6984 | |
| 6984 | −static int e1000e_pm_runtime_idle(struct device *dev) | |
| 6985 | +static __maybe_unused int e1000e_pm_runtime_idle(struct device *dev) | |
| 6985 | 6986 | { |
| 6986 | 6987 | struct net_device *netdev = dev_get_drvdata(dev); |
| 6987 | 6988 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| @@ -6997,7 +6998,7 @@ static int e1000e_pm_runtime_idle(struct device *dev) · 9 unmodified lines | ||
| 6997 | 6998 | return -EBUSY; |
| 6998 | 6999 | } |
| 6999 | 7000 | |
| 7000 | −static int e1000e_pm_runtime_resume(struct device *dev) | |
| 7001 | +static __maybe_unused int e1000e_pm_runtime_resume(struct device *dev) | |
| 7001 | 7002 | { |
| 7002 | 7003 | struct pci_dev *pdev = to_pci_dev(dev); |
| 7003 | 7004 | struct net_device *netdev = pci_get_drvdata(pdev); |
| @@ -7014,7 +7015,7 @@ static int e1000e_pm_runtime_resume(struct device *dev) · 10 unmodified lines | ||
| 7014 | 7015 | return rc; |
| 7015 | 7016 | } |
| 7016 | 7017 | |
| 7017 | −static int e1000e_pm_runtime_suspend(struct device *dev) | |
| 7018 | +static __maybe_unused int e1000e_pm_runtime_suspend(struct device *dev) | |
| 7018 | 7019 | { |
| 7019 | 7020 | struct pci_dev *pdev = to_pci_dev(dev); |
| 7020 | 7021 | struct net_device *netdev = pci_get_drvdata(pdev); |
| @@ -7039,7 +7040,6 @@ static int e1000e_pm_runtime_suspend(struct device *dev) · 18 unmodified lines | ||
| 7039 | 7040 | |
| 7040 | 7041 | return 0; |
| 7041 | 7042 | } |
| 7042 | −#endif /* CONFIG_PM */ | |
| 7043 | 7043 | |
| 7044 | 7044 | static void e1000_shutdown(struct pci_dev *pdev) |
| 7045 | 7045 | { |
| @@ -2070,6 +2070,9 @@ static int i40e_set_ringparam(struct net_device *netdev, · 2069 unmodified lines | ||
| 2070 | 2070 | */ |
| 2071 | 2071 | rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS; |
| 2072 | 2072 | err = i40e_setup_rx_descriptors(&rx_rings[i]); |
| 2073 | + if (err) | |
| 2074 | + goto rx_unwind; | |
| 2075 | + err = i40e_alloc_rx_bi(&rx_rings[i]); | |
| 2073 | 2076 | if (err) |
| 2074 | 2077 | goto rx_unwind; |
| 2075 | 2078 | |
| @@ -439,11 +439,15 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev, · 438 unmodified lines | ||
| 439 | 439 | i40e_get_netdev_stats_struct_tx(ring, stats); |
| 440 | 440 | |
| 441 | 441 | if (i40e_enabled_xdp_vsi(vsi)) { |
| 442 | − ring++; | |
| 442 | + ring = READ_ONCE(vsi->xdp_rings[i]); | |
| 443 | + if (!ring) | |
| 444 | + continue; | |
| 443 | 445 | i40e_get_netdev_stats_struct_tx(ring, stats); |
| 444 | 446 | } |
| 445 | 447 | |
| 446 | − ring++; | |
| 448 | + ring = READ_ONCE(vsi->rx_rings[i]); | |
| 449 | + if (!ring) | |
| 450 | + continue; | |
| 447 | 451 | do { |
| 448 | 452 | start = u64_stats_fetch_begin_irq(&ring->syncp); |
| 449 | 453 | packets = ring->stats.packets; |
| @@ -787,6 +791,8 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) · 337 unmodified lines | ||
| 787 | 791 | for (q = 0; q < vsi->num_queue_pairs; q++) { |
| 788 | 792 | /* locate Tx ring */ |
| 789 | 793 | p = READ_ONCE(vsi->tx_rings[q]); |
| 794 | + if (!p) | |
| 795 | + continue; | |
| 790 | 796 | |
| 791 | 797 | do { |
| 792 | 798 | start = u64_stats_fetch_begin_irq(&p->syncp); |
| @@ -800,8 +806,11 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) · 7 unmodified lines | ||
| 800 | 806 | tx_linearize += p->tx_stats.tx_linearize; |
| 801 | 807 | tx_force_wb += p->tx_stats.tx_force_wb; |
| 802 | 808 | |
| 803 | − /* Rx queue is part of the same block as Tx queue */ | |
| 804 | − p = &p[1]; | |
| 809 | + /* locate Rx ring */ | |
| 810 | + p = READ_ONCE(vsi->rx_rings[q]); | |
| 811 | + if (!p) | |
| 812 | + continue; | |
| 813 | + | |
| 805 | 814 | do { |
| 806 | 815 | start = u64_stats_fetch_begin_irq(&p->syncp); |
| 807 | 816 | packets = p->stats.packets; |
| @@ -10824,10 +10833,10 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi) · 10016 unmodified lines | ||
| 10824 | 10833 | if (vsi->tx_rings && vsi->tx_rings[0]) { |
| 10825 | 10834 | for (i = 0; i < vsi->alloc_queue_pairs; i++) { |
| 10826 | 10835 | kfree_rcu(vsi->tx_rings[i], rcu); |
| 10827 | − vsi->tx_rings[i] = NULL; | |
| 10828 | − vsi->rx_rings[i] = NULL; | |
| 10836 | + WRITE_ONCE(vsi->tx_rings[i], NULL); | |
| 10837 | + WRITE_ONCE(vsi->rx_rings[i], NULL); | |
| 10829 | 10838 | if (vsi->xdp_rings) |
| 10830 | − vsi->xdp_rings[i] = NULL; | |
| 10839 | + WRITE_ONCE(vsi->xdp_rings[i], NULL); | |
| 10831 | 10840 | } |
| 10832 | 10841 | } |
| 10833 | 10842 | } |
| @@ -10861,7 +10870,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi) · 27 unmodified lines | ||
| 10861 | 10870 | if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE) |
| 10862 | 10871 | ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; |
| 10863 | 10872 | ring->itr_setting = pf->tx_itr_default; |
| 10864 | − vsi->tx_rings[i] = ring++; | |
| 10873 | + WRITE_ONCE(vsi->tx_rings[i], ring++); | |
| 10865 | 10874 | |
| 10866 | 10875 | if (!i40e_enabled_xdp_vsi(vsi)) |
| 10867 | 10876 | goto setup_rx; |
| @@ -10879,7 +10888,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi) · 11 unmodified lines | ||
| 10879 | 10888 | ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; |
| 10880 | 10889 | set_ring_xdp(ring); |
| 10881 | 10890 | ring->itr_setting = pf->tx_itr_default; |
| 10882 | − vsi->xdp_rings[i] = ring++; | |
| 10891 | + WRITE_ONCE(vsi->xdp_rings[i], ring++); | |
| 10883 | 10892 | |
| 10884 | 10893 | setup_rx: |
| 10885 | 10894 | ring->queue_index = i; |
| @@ -10892,7 +10901,7 @@ setup_rx: · 6 unmodified lines | ||
| 10892 | 10901 | ring->size = 0; |
| 10893 | 10902 | ring->dcb_tc = 0; |
| 10894 | 10903 | ring->itr_setting = pf->rx_itr_default; |
| 10895 | − vsi->rx_rings[i] = ring; | |
| 10904 | + WRITE_ONCE(vsi->rx_rings[i], ring); | |
| 10896 | 10905 | } |
| 10897 | 10906 | |
| 10898 | 10907 | return 0; |
| @@ -1194,7 +1194,7 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi) · 1193 unmodified lines | ||
| 1194 | 1194 | for (i = 0; i < vsi->alloc_txq; i++) { |
| 1195 | 1195 | if (vsi->tx_rings[i]) { |
| 1196 | 1196 | kfree_rcu(vsi->tx_rings[i], rcu); |
| 1197 | − vsi->tx_rings[i] = NULL; | |
| 1197 | + WRITE_ONCE(vsi->tx_rings[i], NULL); | |
| 1198 | 1198 | } |
| 1199 | 1199 | } |
| 1200 | 1200 | } |
| @@ -1202,7 +1202,7 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi) · 1 unmodified line | ||
| 1202 | 1202 | for (i = 0; i < vsi->alloc_rxq; i++) { |
| 1203 | 1203 | if (vsi->rx_rings[i]) { |
| 1204 | 1204 | kfree_rcu(vsi->rx_rings[i], rcu); |
| 1205 | − vsi->rx_rings[i] = NULL; | |
| 1205 | + WRITE_ONCE(vsi->rx_rings[i], NULL); | |
| 1206 | 1206 | } |
| 1207 | 1207 | } |
| 1208 | 1208 | } |
| @@ -1235,7 +1235,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi) · 26 unmodified lines | ||
| 1235 | 1235 | ring->vsi = vsi; |
| 1236 | 1236 | ring->dev = dev; |
| 1237 | 1237 | ring->count = vsi->num_tx_desc; |
| 1238 | − vsi->tx_rings[i] = ring; | |
| 1238 | + WRITE_ONCE(vsi->tx_rings[i], ring); | |
| 1239 | 1239 | } |
| 1240 | 1240 | |
| 1241 | 1241 | /* Allocate Rx rings */ |
| @@ -1254,7 +1254,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi) · 12 unmodified lines | ||
| 1254 | 1254 | ring->netdev = vsi->netdev; |
| 1255 | 1255 | ring->dev = dev; |
| 1256 | 1256 | ring->count = vsi->num_rx_desc; |
| 1257 | − vsi->rx_rings[i] = ring; | |
| 1257 | + WRITE_ONCE(vsi->rx_rings[i], ring); | |
| 1258 | 1258 | } |
| 1259 | 1259 | |
| 1260 | 1260 | return 0; |
| @@ -1702,7 +1702,7 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi) · 1701 unmodified lines | ||
| 1702 | 1702 | xdp_ring->netdev = NULL; |
| 1703 | 1703 | xdp_ring->dev = dev; |
| 1704 | 1704 | xdp_ring->count = vsi->num_tx_desc; |
| 1705 | − vsi->xdp_rings[i] = xdp_ring; | |
| 1705 | + WRITE_ONCE(vsi->xdp_rings[i], xdp_ring); | |
| 1706 | 1706 | if (ice_setup_tx_ring(xdp_ring)) |
| 1707 | 1707 | goto free_xdp_rings; |
| 1708 | 1708 | ice_set_ring_xdp(xdp_ring); |
| @@ -921,7 +921,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, · 920 unmodified lines | ||
| 921 | 921 | ring->queue_index = txr_idx; |
| 922 | 922 | |
| 923 | 923 | /* assign ring to adapter */ |
| 924 | − adapter->tx_ring[txr_idx] = ring; | |
| 924 | + WRITE_ONCE(adapter->tx_ring[txr_idx], ring); | |
| 925 | 925 | |
| 926 | 926 | /* update count and index */ |
| 927 | 927 | txr_count--; |
| @@ -948,7 +948,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, · 20 unmodified lines | ||
| 948 | 948 | set_ring_xdp(ring); |
| 949 | 949 | |
| 950 | 950 | /* assign ring to adapter */ |
| 951 | − adapter->xdp_ring[xdp_idx] = ring; | |
| 951 | + WRITE_ONCE(adapter->xdp_ring[xdp_idx], ring); | |
| 952 | 952 | |
| 953 | 953 | /* update count and index */ |
| 954 | 954 | xdp_count--; |
| @@ -991,7 +991,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, · 36 unmodified lines | ||
| 991 | 991 | ring->queue_index = rxr_idx; |
| 992 | 992 | |
| 993 | 993 | /* assign ring to adapter */ |
| 994 | − adapter->rx_ring[rxr_idx] = ring; | |
| 994 | + WRITE_ONCE(adapter->rx_ring[rxr_idx], ring); | |
| 995 | 995 | |
| 996 | 996 | /* update count and index */ |
| 997 | 997 | rxr_count--; |
| @@ -1020,13 +1020,13 @@ static void ixgbe_free_q_vector(struct ixgbe_adapter *adapter, int v_idx) · 22 unmodified lines | ||
| 1020 | 1020 | |
| 1021 | 1021 | ixgbe_for_each_ring(ring, q_vector->tx) { |
| 1022 | 1022 | if (ring_is_xdp(ring)) |
| 1023 | − adapter->xdp_ring[ring->queue_index] = NULL; | |
| 1023 | + WRITE_ONCE(adapter->xdp_ring[ring->queue_index], NULL); | |
| 1024 | 1024 | else |
| 1025 | − adapter->tx_ring[ring->queue_index] = NULL; | |
| 1025 | + WRITE_ONCE(adapter->tx_ring[ring->queue_index], NULL); | |
| 1026 | 1026 | } |
| 1027 | 1027 | |
| 1028 | 1028 | ixgbe_for_each_ring(ring, q_vector->rx) |
| 1029 | − adapter->rx_ring[ring->queue_index] = NULL; | |
| 1029 | + WRITE_ONCE(adapter->rx_ring[ring->queue_index], NULL); | |
| 1030 | 1030 | |
| 1031 | 1031 | adapter->q_vector[v_idx] = NULL; |
| 1032 | 1032 | napi_hash_del(&q_vector->napi); |
| @@ -7051,7 +7051,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) · 7050 unmodified lines | ||
| 7051 | 7051 | } |
| 7052 | 7052 | |
| 7053 | 7053 | for (i = 0; i < adapter->num_rx_queues; i++) { |
| 7054 | − struct ixgbe_ring *rx_ring = adapter->rx_ring[i]; | |
| 7054 | + struct ixgbe_ring *rx_ring = READ_ONCE(adapter->rx_ring[i]); | |
| 7055 | + | |
| 7056 | + if (!rx_ring) | |
| 7057 | + continue; | |
| 7055 | 7058 | non_eop_descs += rx_ring->rx_stats.non_eop_descs; |
| 7056 | 7059 | alloc_rx_page += rx_ring->rx_stats.alloc_rx_page; |
| 7057 | 7060 | alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed; |
| @@ -7072,15 +7075,20 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) · 14 unmodified lines | ||
| 7072 | 7075 | packets = 0; |
| 7073 | 7076 | /* gather some stats to the adapter struct that are per queue */ |
| 7074 | 7077 | for (i = 0; i < adapter->num_tx_queues; i++) { |
| 7075 | − struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; | |
| 7078 | + struct ixgbe_ring *tx_ring = READ_ONCE(adapter->tx_ring[i]); | |
| 7079 | + | |
| 7080 | + if (!tx_ring) | |
| 7081 | + continue; | |
| 7076 | 7082 | restart_queue += tx_ring->tx_stats.restart_queue; |
| 7077 | 7083 | tx_busy += tx_ring->tx_stats.tx_busy; |
| 7078 | 7084 | bytes += tx_ring->stats.bytes; |
| 7079 | 7085 | packets += tx_ring->stats.packets; |
| 7080 | 7086 | } |
| 7081 | 7087 | for (i = 0; i < adapter->num_xdp_queues; i++) { |
| 7082 | − struct ixgbe_ring *xdp_ring = adapter->xdp_ring[i]; | |
| 7088 | + struct ixgbe_ring *xdp_ring = READ_ONCE(adapter->xdp_ring[i]); | |
| 7083 | 7089 | |
| 7090 | + if (!xdp_ring) | |
| 7091 | + continue; | |
| 7084 | 7092 | restart_queue += xdp_ring->tx_stats.restart_queue; |
| 7085 | 7093 | tx_busy += xdp_ring->tx_stats.tx_busy; |
| 7086 | 7094 | bytes += xdp_ring->stats.bytes; |
| @@ -106,9 +106,11 @@ · 105 unmodified lines | ||
| 106 | 106 | #define MVNETA_TX_IN_PRGRS BIT(1) |
| 107 | 107 | #define MVNETA_TX_FIFO_EMPTY BIT(8) |
| 108 | 108 | #define MVNETA_RX_MIN_FRAME_SIZE 0x247c |
| 109 | +/* Only exists on Armada XP and Armada 370 */ | |
| 109 | 110 | #define MVNETA_SERDES_CFG 0x24A0 |
| 110 | 111 | #define MVNETA_SGMII_SERDES_PROTO 0x0cc7 |
| 111 | 112 | #define MVNETA_QSGMII_SERDES_PROTO 0x0667 |
| 113 | +#define MVNETA_HSGMII_SERDES_PROTO 0x1107 | |
| 112 | 114 | #define MVNETA_TYPE_PRIO 0x24bc |
| 113 | 115 | #define MVNETA_FORCE_UNI BIT(21) |
| 114 | 116 | #define MVNETA_TXQ_CMD_1 0x24e4 |
| @@ -3529,26 +3531,60 @@ static int mvneta_setup_txqs(struct mvneta_port *pp) · 3414 unmodified lines | ||
| 3529 | 3531 | return 0; |
| 3530 | 3532 | } |
| 3531 | 3533 | |
| 3532 | −static int mvneta_comphy_init(struct mvneta_port *pp) | |
| 3534 | +static int mvneta_comphy_init(struct mvneta_port *pp, phy_interface_t interface) | |
| 3533 | 3535 | { |
| 3534 | 3536 | int ret; |
| 3535 | 3537 | |
| 3536 | − if (!pp->comphy) | |
| 3537 | − return 0; | |
| 3538 | − | |
| 3539 | − ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, | |
| 3540 | − pp->phy_interface); | |
| 3538 | + ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, interface); | |
| 3541 | 3539 | if (ret) |
| 3542 | 3540 | return ret; |
| 3543 | 3541 | |
| 3544 | 3542 | return phy_power_on(pp->comphy); |
| 3545 | 3543 | } |
| 3546 | 3544 | |
| 3545 | +static int mvneta_config_interface(struct mvneta_port *pp, | |
| 3546 | + phy_interface_t interface) | |
| 3547 | +{ | |
| 3548 | + int ret = 0; | |
| 3549 | + | |
| 3550 | + if (pp->comphy) { | |
| 3551 | + if (interface == PHY_INTERFACE_MODE_SGMII || | |
| 3552 | + interface == PHY_INTERFACE_MODE_1000BASEX || | |
| 3553 | + interface == PHY_INTERFACE_MODE_2500BASEX) { | |
| 3554 | + ret = mvneta_comphy_init(pp, interface); | |
| 3555 | + } | |
| 3556 | + } else { | |
| 3557 | + switch (interface) { | |
| 3558 | + case PHY_INTERFACE_MODE_QSGMII: | |
| 3559 | + mvreg_write(pp, MVNETA_SERDES_CFG, | |
| 3560 | + MVNETA_QSGMII_SERDES_PROTO); | |
| 3561 | + break; | |
| 3562 | + | |
| 3563 | + case PHY_INTERFACE_MODE_SGMII: | |
| 3564 | + case PHY_INTERFACE_MODE_1000BASEX: | |
| 3565 | + mvreg_write(pp, MVNETA_SERDES_CFG, | |
| 3566 | + MVNETA_SGMII_SERDES_PROTO); | |
| 3567 | + break; | |
| 3568 | + | |
| 3569 | + case PHY_INTERFACE_MODE_2500BASEX: | |
| 3570 | + mvreg_write(pp, MVNETA_SERDES_CFG, | |
| 3571 | + MVNETA_HSGMII_SERDES_PROTO); | |
| 3572 | + break; | |
| 3573 | + default: | |
| 3574 | + break; | |
| 3575 | + } | |
| 3576 | + } | |
| 3577 | + | |
| 3578 | + pp->phy_interface = interface; | |
| 3579 | + | |
| 3580 | + return ret; | |
| 3581 | +} | |
| 3582 | + | |
| 3547 | 3583 | static void mvneta_start_dev(struct mvneta_port *pp) |
| 3548 | 3584 | { |
| 3549 | 3585 | int cpu; |
| 3550 | 3586 | |
| 3551 | − WARN_ON(mvneta_comphy_init(pp)); | |
| 3587 | + WARN_ON(mvneta_config_interface(pp, pp->phy_interface)); | |
| 3552 | 3588 | |
| 3553 | 3589 | mvneta_max_rx_size_set(pp, pp->pkt_size); |
| 3554 | 3590 | mvneta_txq_max_tx_size_set(pp, pp->pkt_size); |
| @@ -3926,14 +3962,10 @@ static void mvneta_mac_config(struct phylink_config *config, unsigned int mode, · 371 unmodified lines | ||
| 3926 | 3962 | if (state->speed == SPEED_2500) |
| 3927 | 3963 | new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; |
| 3928 | 3964 | |
| 3929 | − if (pp->comphy && pp->phy_interface != state->interface && | |
| 3930 | − (state->interface == PHY_INTERFACE_MODE_SGMII || | |
| 3931 | − state->interface == PHY_INTERFACE_MODE_1000BASEX || | |
| 3932 | − state->interface == PHY_INTERFACE_MODE_2500BASEX)) { | |
| 3933 | − pp->phy_interface = state->interface; | |
| 3934 | − | |
| 3935 | − WARN_ON(phy_power_off(pp->comphy)); | |
| 3936 | − WARN_ON(mvneta_comphy_init(pp)); | |
| 3965 | + if (pp->phy_interface != state->interface) { | |
| 3966 | + if (pp->comphy) | |
| 3967 | + WARN_ON(phy_power_off(pp->comphy)); | |
| 3968 | + WARN_ON(mvneta_config_interface(pp, state->interface)); | |
| 3937 | 3969 | } |
| 3938 | 3970 | |
| 3939 | 3971 | if (new_ctrl0 != gmac_ctrl0) |
| @@ -4982,12 +5014,10 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) · 1042 unmodified lines | ||
| 4982 | 5014 | /* MAC Cause register should be cleared */ |
| 4983 | 5015 | mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0); |
| 4984 | 5016 | |
| 4985 | − if (phy_mode == PHY_INTERFACE_MODE_QSGMII) | |
| 4986 | − mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); | |
| 4987 | − else if (phy_mode == PHY_INTERFACE_MODE_SGMII || | |
| 4988 | − phy_interface_mode_is_8023z(phy_mode)) | |
| 4989 | − mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); | |
| 4990 | − else if (!phy_interface_mode_is_rgmii(phy_mode)) | |
| 5017 | + if (phy_mode != PHY_INTERFACE_MODE_QSGMII && | |
| 5018 | + phy_mode != PHY_INTERFACE_MODE_SGMII && | |
| 5019 | + !phy_interface_mode_is_8023z(phy_mode) && | |
| 5020 | + !phy_interface_mode_is_rgmii(phy_mode)) | |
| 4991 | 5021 | return -EINVAL; |
| 4992 | 5022 | |
| 4993 | 5023 | return 0; |
| @@ -5176,10 +5206,10 @@ static int mvneta_probe(struct platform_device *pdev) · 182 unmodified lines | ||
| 5176 | 5206 | if (err < 0) |
| 5177 | 5207 | goto err_netdev; |
| 5178 | 5208 | |
| 5179 | − err = mvneta_port_power_up(pp, phy_mode); | |
| 5209 | + err = mvneta_port_power_up(pp, pp->phy_interface); | |
| 5180 | 5210 | if (err < 0) { |
| 5181 | 5211 | dev_err(&pdev->dev, "can't power up port\n"); |
| 5182 | − goto err_netdev; | |
| 5212 | + return err; | |
| 5183 | 5213 | } |
| 5184 | 5214 | |
| 5185 | 5215 | /* Armada3700 network controller does not support per-cpu |
| @@ -1544,7 +1544,7 @@ static void mvpp2_read_stats(struct mvpp2_port *port) · 1543 unmodified lines | ||
| 1544 | 1544 | for (q = 0; q < port->ntxqs; q++) |
| 1545 | 1545 | for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++) |
| 1546 | 1546 | *pstats++ += mvpp2_read_index(port->priv, |
| 1547 | − MVPP22_CTRS_TX_CTR(port->id, i), | |
| 1547 | + MVPP22_CTRS_TX_CTR(port->id, q), | |
| 1548 | 1548 | mvpp2_ethtool_txq_regs[i].offset); |
| 1549 | 1549 | |
| 1550 | 1550 | /* Rxqs are numbered from 0 from the user standpoint, but not from the |
| @@ -1553,7 +1553,7 @@ static void mvpp2_read_stats(struct mvpp2_port *port) · 2 unmodified lines | ||
| 1553 | 1553 | for (q = 0; q < port->nrxqs; q++) |
| 1554 | 1554 | for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++) |
| 1555 | 1555 | *pstats++ += mvpp2_read_index(port->priv, |
| 1556 | − port->first_rxq + i, | |
| 1556 | + port->first_rxq + q, | |
| 1557 | 1557 | mvpp2_ethtool_rxq_regs[i].offset); |
| 1558 | 1558 | } |
| 1559 | 1559 | |
| @@ -5983,8 +5983,8 @@ static int mvpp2_remove(struct platform_device *pdev) · 4423 unmodified lines | ||
| 5983 | 5983 | { |
| 5984 | 5984 | struct mvpp2 *priv = platform_get_drvdata(pdev); |
| 5985 | 5985 | struct fwnode_handle *fwnode = pdev->dev.fwnode; |
| 5986 | + int i = 0, poolnum = MVPP2_BM_POOLS_NUM; | |
| 5986 | 5987 | struct fwnode_handle *port_fwnode; |
| 5987 | − int i = 0; | |
| 5988 | 5988 | |
| 5989 | 5989 | mvpp2_dbgfs_cleanup(priv); |
| 5990 | 5990 | |
| @@ -5998,7 +5998,10 @@ static int mvpp2_remove(struct platform_device *pdev) · 7 unmodified lines | ||
| 5998 | 5998 | |
| 5999 | 5999 | destroy_workqueue(priv->stats_queue); |
| 6000 | 6000 | |
| 6001 | − for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { | |
| 6001 | + if (priv->percpu_pools) | |
| 6002 | + poolnum = mvpp2_get_nrxqs(priv) * 2; | |
| 6003 | + | |
| 6004 | + for (i = 0; i < poolnum; i++) { | |
| 6002 | 6005 | struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i]; |
| 6003 | 6006 | |
| 6004 | 6007 | mvpp2_bm_pool_destroy(&pdev->dev, priv, bm_pool); |
| @@ -24,7 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/regmap.h> |
| 25 | 25 | #include <linux/skbuff.h> |
| 26 | 26 | #include <linux/spinlock.h> |
| 27 | −#include <linux/workqueue.h> | |
| 28 | 27 | |
| 29 | 28 | #define MTK_STAR_DRVNAME "mtk_star_emac" |
| 30 | 29 | |
| @@ -262,7 +261,6 @@ struct mtk_star_priv { · 231 unmodified lines | ||
| 262 | 261 | spinlock_t lock; |
| 263 | 262 | |
| 264 | 263 | struct rtnl_link_stats64 stats; |
| 265 | − struct work_struct stats_work; | |
| 266 | 264 | }; |
| 267 | 265 | |
| 268 | 266 | static struct device *mtk_star_get_dev(struct mtk_star_priv *priv) |
| @@ -432,42 +430,6 @@ static void mtk_star_intr_disable(struct mtk_star_priv *priv) · 163 unmodified lines | ||
| 432 | 430 | regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0); |
| 433 | 431 | } |
| 434 | 432 | |
| 435 | −static void mtk_star_intr_enable_tx(struct mtk_star_priv *priv) | |
| 436 | −{ | |
| 437 | − regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK, | |
| 438 | − MTK_STAR_BIT_INT_STS_TNTC); | |
| 439 | −} | |
| 440 | − | |
| 441 | −static void mtk_star_intr_enable_rx(struct mtk_star_priv *priv) | |
| 442 | −{ | |
| 443 | − regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK, | |
| 444 | − MTK_STAR_BIT_INT_STS_FNRC); | |
| 445 | −} | |
| 446 | − | |
| 447 | −static void mtk_star_intr_enable_stats(struct mtk_star_priv *priv) | |
| 448 | −{ | |
| 449 | − regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK, | |
| 450 | − MTK_STAR_REG_INT_STS_MIB_CNT_TH); | |
| 451 | −} | |
| 452 | − | |
| 453 | −static void mtk_star_intr_disable_tx(struct mtk_star_priv *priv) | |
| 454 | −{ | |
| 455 | − regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK, | |
| 456 | − MTK_STAR_BIT_INT_STS_TNTC); | |
| 457 | −} | |
| 458 | − | |
| 459 | −static void mtk_star_intr_disable_rx(struct mtk_star_priv *priv) | |
| 460 | −{ | |
| 461 | − regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK, | |
| 462 | − MTK_STAR_BIT_INT_STS_FNRC); | |
| 463 | −} | |
| 464 | − | |
| 465 | −static void mtk_star_intr_disable_stats(struct mtk_star_priv *priv) | |
| 466 | −{ | |
| 467 | − regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK, | |
| 468 | − MTK_STAR_REG_INT_STS_MIB_CNT_TH); | |
| 469 | −} | |
| 470 | − | |
| 471 | 433 | static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv) |
| 472 | 434 | { |
| 473 | 435 | unsigned int val; |
| @@ -663,20 +625,6 @@ static void mtk_star_update_stats(struct mtk_star_priv *priv) · 189 unmodified lines | ||
| 663 | 625 | stats->rx_errors += stats->rx_fifo_errors; |
| 664 | 626 | } |
| 665 | 627 | |
| 666 | −/* This runs in process context and parallel TX and RX paths executing in | |
| 667 | − * napi context may result in losing some stats data but this should happen | |
| 668 | − * seldom enough to be acceptable. | |
| 669 | − */ | |
| 670 | −static void mtk_star_update_stats_work(struct work_struct *work) | |
| 671 | −{ | |
| 672 | − struct mtk_star_priv *priv = container_of(work, struct mtk_star_priv, | |
| 673 | − stats_work); | |
| 674 | − | |
| 675 | − mtk_star_update_stats(priv); | |
| 676 | − mtk_star_reset_counters(priv); | |
| 677 | − mtk_star_intr_enable_stats(priv); | |
| 678 | −} | |
| 679 | − | |
| 680 | 628 | static struct sk_buff *mtk_star_alloc_skb(struct net_device *ndev) |
| 681 | 629 | { |
| 682 | 630 | uintptr_t tail, offset; |
| @@ -767,42 +715,25 @@ static void mtk_star_free_tx_skbs(struct mtk_star_priv *priv) · 84 unmodified lines | ||
| 767 | 715 | mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx); |
| 768 | 716 | } |
| 769 | 717 | |
| 770 | −/* All processing for TX and RX happens in the napi poll callback. */ | |
| 718 | +/* All processing for TX and RX happens in the napi poll callback. | |
| 719 | + * | |
| 720 | + * FIXME: The interrupt handling should be more fine-grained with each | |
| 721 | + * interrupt enabled/disabled independently when needed. Unfortunatly this | |
| 722 | + * turned out to impact the driver's stability and until we have something | |
| 723 | + * working properly, we're disabling all interrupts during TX & RX processing | |
| 724 | + * or when resetting the counter registers. | |
| 725 | + */ | |
| 771 | 726 | static irqreturn_t mtk_star_handle_irq(int irq, void *data) |
| 772 | 727 | { |
| 773 | 728 | struct mtk_star_priv *priv; |
| 774 | 729 | struct net_device *ndev; |
| 775 | − bool need_napi = false; | |
| 776 | − unsigned int status; | |
| 777 | 730 | |
| 778 | 731 | ndev = data; |
| 779 | 732 | priv = netdev_priv(ndev); |
| 780 | 733 | |
| 781 | 734 | if (netif_running(ndev)) { |
| 782 | − status = mtk_star_intr_read(priv); | |
| 783 | − | |
| 784 | − if (status & MTK_STAR_BIT_INT_STS_TNTC) { | |
| 785 | − mtk_star_intr_disable_tx(priv); | |
| 786 | − need_napi = true; | |
| 787 | − } | |
| 788 | − | |
| 789 | − if (status & MTK_STAR_BIT_INT_STS_FNRC) { | |
| 790 | − mtk_star_intr_disable_rx(priv); | |
| 791 | − need_napi = true; | |
| 792 | − } | |
| 793 | − | |
| 794 | − if (need_napi) | |
| 795 | − napi_schedule(&priv->napi); | |
| 796 | − | |
| 797 | − /* One of the counters reached 0x8000000 - update stats and | |
| 798 | − * reset all counters. | |
| 799 | − */ | |
| 800 | − if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) { | |
| 801 | − mtk_star_intr_disable_stats(priv); | |
| 802 | − schedule_work(&priv->stats_work); | |
| 803 | − } | |
| 804 | − | |
| 805 | − mtk_star_intr_ack_all(priv); | |
| 735 | + mtk_star_intr_disable(priv); | |
| 736 | + napi_schedule(&priv->napi); | |
| 806 | 737 | } |
| 807 | 738 | |
| 808 | 739 | return IRQ_HANDLED; |
| @@ -1169,8 +1100,6 @@ static void mtk_star_tx_complete_all(struct mtk_star_priv *priv) · 360 unmodified lines | ||
| 1169 | 1100 | if (wake && netif_queue_stopped(ndev)) |
| 1170 | 1101 | netif_wake_queue(ndev); |
| 1171 | 1102 | |
| 1172 | − mtk_star_intr_enable_tx(priv); | |
| 1173 | − | |
| 1174 | 1103 | spin_unlock(&priv->lock); |
| 1175 | 1104 | } |
| 1176 | 1105 | |
| @@ -1332,20 +1261,32 @@ static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget) · 155 unmodified lines | ||
| 1332 | 1261 | static int mtk_star_poll(struct napi_struct *napi, int budget) |
| 1333 | 1262 | { |
| 1334 | 1263 | struct mtk_star_priv *priv; |
| 1264 | + unsigned int status; | |
| 1335 | 1265 | int received = 0; |
| 1336 | 1266 | |
| 1337 | 1267 | priv = container_of(napi, struct mtk_star_priv, napi); |
| 1338 | 1268 | |
| 1339 | − /* Clean-up all TX descriptors. */ | |
| 1340 | − mtk_star_tx_complete_all(priv); | |
| 1341 | − /* Receive up to $budget packets. */ | |
| 1342 | − received = mtk_star_process_rx(priv, budget); | |
| 1269 | + status = mtk_star_intr_read(priv); | |
| 1270 | + mtk_star_intr_ack_all(priv); | |
| 1343 | 1271 | |
| 1344 | − if (received < budget) { | |
| 1345 | − napi_complete_done(napi, received); | |
| 1346 | − mtk_star_intr_enable_rx(priv); | |
| 1272 | + if (status & MTK_STAR_BIT_INT_STS_TNTC) | |
| 1273 | + /* Clean-up all TX descriptors. */ | |
| 1274 | + mtk_star_tx_complete_all(priv); | |
| 1275 | + | |
| 1276 | + if (status & MTK_STAR_BIT_INT_STS_FNRC) | |
| 1277 | + /* Receive up to $budget packets. */ | |
| 1278 | + received = mtk_star_process_rx(priv, budget); | |
| 1279 | + | |
| 1280 | + if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) { | |
| 1281 | + mtk_star_update_stats(priv); | |
| 1282 | + mtk_star_reset_counters(priv); | |
| 1347 | 1283 | } |
| 1348 | 1284 | |
| 1285 | + if (received < budget) | |
| 1286 | + napi_complete_done(napi, received); | |
| 1287 | + | |
| 1288 | + mtk_star_intr_enable(priv); | |
| 1289 | + | |
| 1349 | 1290 | return received; |
| 1350 | 1291 | } |
| 1351 | 1292 | |
| @@ -1532,7 +1473,6 @@ static int mtk_star_probe(struct platform_device *pdev) · 180 unmodified lines | ||
| 1532 | 1473 | ndev->max_mtu = MTK_STAR_MAX_FRAME_SIZE; |
| 1533 | 1474 | |
| 1534 | 1475 | spin_lock_init(&priv->lock); |
| 1535 | − INIT_WORK(&priv->stats_work, mtk_star_update_stats_work); | |
| 1536 | 1476 | |
| 1537 | 1477 | base = devm_platform_ioremap_resource(pdev, 0); |
| 1538 | 1478 | if (IS_ERR(base)) |
| @@ -407,7 +407,9 @@ static int · 406 unmodified lines | ||
| 407 | 407 | mlx5e_rep_indr_setup_block(struct net_device *netdev, |
| 408 | 408 | struct mlx5e_rep_priv *rpriv, |
| 409 | 409 | struct flow_block_offload *f, |
| 410 | − flow_setup_cb_t *setup_cb) | |
| 410 | + flow_setup_cb_t *setup_cb, | |
| 411 | + void *data, | |
| 412 | + void (*cleanup)(struct flow_block_cb *block_cb)) | |
| 411 | 413 | { |
| 412 | 414 | struct mlx5e_priv *priv = netdev_priv(rpriv->netdev); |
| 413 | 415 | struct mlx5e_rep_indr_block_priv *indr_priv; |
| @@ -438,8 +440,10 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, · 24 unmodified lines | ||
| 438 | 440 | list_add(&indr_priv->list, |
| 439 | 441 | &rpriv->uplink_priv.tc_indr_block_priv_list); |
| 440 | 442 | |
| 441 | − block_cb = flow_block_cb_alloc(setup_cb, indr_priv, indr_priv, | |
| 442 | − mlx5e_rep_indr_block_unbind); | |
| 443 | + block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv, | |
| 444 | + mlx5e_rep_indr_block_unbind, | |
| 445 | + f, netdev, data, rpriv, | |
| 446 | + cleanup); | |
| 443 | 447 | if (IS_ERR(block_cb)) { |
| 444 | 448 | list_del(&indr_priv->list); |
| 445 | 449 | kfree(indr_priv); |
| @@ -458,7 +462,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, · 12 unmodified lines | ||
| 458 | 462 | if (!block_cb) |
| 459 | 463 | return -ENOENT; |
| 460 | 464 | |
| 461 | − flow_block_cb_remove(block_cb, f); | |
| 465 | + flow_indr_block_cb_remove(block_cb, f); | |
| 462 | 466 | list_del(&block_cb->driver_list); |
| 463 | 467 | return 0; |
| 464 | 468 | default: |
| @@ -469,15 +473,19 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, · 4 unmodified lines | ||
| 469 | 473 | |
| 470 | 474 | static |
| 471 | 475 | int mlx5e_rep_indr_setup_cb(struct net_device *netdev, void *cb_priv, |
| 472 | − enum tc_setup_type type, void *type_data) | |
| 476 | + enum tc_setup_type type, void *type_data, | |
| 477 | + void *data, | |
| 478 | + void (*cleanup)(struct flow_block_cb *block_cb)) | |
| 473 | 479 | { |
| 474 | 480 | switch (type) { |
| 475 | 481 | case TC_SETUP_BLOCK: |
| 476 | 482 | return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data, |
| 477 | − mlx5e_rep_indr_setup_tc_cb); | |
| 483 | + mlx5e_rep_indr_setup_tc_cb, | |
| 484 | + data, cleanup); | |
| 478 | 485 | case TC_SETUP_FT: |
| 479 | 486 | return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data, |
| 480 | − mlx5e_rep_indr_setup_ft_cb); | |
| 487 | + mlx5e_rep_indr_setup_ft_cb, | |
| 488 | + data, cleanup); | |
| 481 | 489 | default: |
| 482 | 490 | return -EOPNOTSUPP; |
| 483 | 491 | } |
| @@ -496,7 +504,7 @@ int mlx5e_rep_tc_netdevice_event_register(struct mlx5e_rep_priv *rpriv) · 12 unmodified lines | ||
| 496 | 504 | void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv) |
| 497 | 505 | { |
| 498 | 506 | flow_indr_dev_unregister(mlx5e_rep_indr_setup_cb, rpriv, |
| 499 | − mlx5e_rep_indr_setup_tc_cb); | |
| 507 | + mlx5e_rep_indr_block_unbind); | |
| 500 | 508 | } |
| 501 | 509 | |
| 502 | 510 | #if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) |
| @@ -978,8 +978,10 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, · 977 unmodified lines | ||
| 978 | 978 | |
| 979 | 979 | lossy = !(pfc || pause_en); |
| 980 | 980 | thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu); |
| 981 | + thres_cells = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, thres_cells); | |
| 981 | 982 | delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay, |
| 982 | 983 | pfc, pause_en); |
| 984 | + delay_cells = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, delay_cells); | |
| 983 | 985 | total_cells = thres_cells + delay_cells; |
| 984 | 986 | |
| 985 | 987 | taken_headroom_cells += total_cells; |
| @@ -374,6 +374,17 @@ mlxsw_sp_port_vlan_find_by_vid(const struct mlxsw_sp_port *mlxsw_sp_port, · 373 unmodified lines | ||
| 374 | 374 | return NULL; |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | +static inline u32 | |
| 378 | +mlxsw_sp_port_headroom_8x_adjust(const struct mlxsw_sp_port *mlxsw_sp_port, | |
| 379 | + u32 size_cells) | |
| 380 | +{ | |
| 381 | + /* Ports with eight lanes use two headroom buffers between which the | |
| 382 | + * configured headroom size is split. Therefore, multiply the calculated | |
| 383 | + * headroom size by two. | |
| 384 | + */ | |
| 385 | + return mlxsw_sp_port->mapping.width == 8 ? 2 * size_cells : size_cells; | |
| 386 | +} | |
| 387 | + | |
| 377 | 388 | enum mlxsw_sp_flood_type { |
| 378 | 389 | MLXSW_SP_FLOOD_TYPE_UC, |
| 379 | 390 | MLXSW_SP_FLOOD_TYPE_BC, |
| @@ -312,6 +312,7 @@ static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port) · 311 unmodified lines | ||
| 312 | 312 | |
| 313 | 313 | if (i == MLXSW_SP_PB_UNUSED) |
| 314 | 314 | continue; |
| 315 | + size = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, size); | |
| 315 | 316 | mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size); |
| 316 | 317 | } |
| 317 | 318 | mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, |
| @@ -782,6 +782,7 @@ mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu) · 781 unmodified lines | ||
| 782 | 782 | speed = 0; |
| 783 | 783 | |
| 784 | 784 | buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, speed, mtu); |
| 785 | + buffsize = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, buffsize); | |
| 785 | 786 | mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize); |
| 786 | 787 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); |
| 787 | 788 | } |
| @@ -3091,6 +3091,8 @@ static const struct pci_device_id lan743x_pcidev_tbl[] = { · 3090 unmodified lines | ||
| 3091 | 3091 | { 0, } |
| 3092 | 3092 | }; |
| 3093 | 3093 | |
| 3094 | +MODULE_DEVICE_TABLE(pci, lan743x_pcidev_tbl); | |
| 3095 | + | |
| 3094 | 3096 | static struct pci_driver lan743x_pcidev_driver = { |
| 3095 | 3097 | .name = DRIVER_NAME, |
| 3096 | 3098 | .id_table = lan743x_pcidev_tbl, |
| @@ -297,7 +297,7 @@ struct vxge_hw_fifo_config { · 296 unmodified lines | ||
| 297 | 297 | * @greedy_return: If Set it forces the device to return absolutely all RxD |
| 298 | 298 | * that are consumed and still on board when a timer interrupt |
| 299 | 299 | * triggers. If Clear, then if the device has already returned |
| 300 | − * RxD before current timer interrupt trigerred and after the | |
| 300 | + * RxD before current timer interrupt triggered and after the | |
| 301 | 301 | * previous timer interrupt triggered, then the device is not |
| 302 | 302 | * forced to returned the rest of the consumed RxD that it has |
| 303 | 303 | * on board which account for a byte count less than the one |
| @@ -861,7 +861,7 @@ static void nfp_flower_clean(struct nfp_app *app) · 860 unmodified lines | ||
| 861 | 861 | flush_work(&app_priv->cmsg_work); |
| 862 | 862 | |
| 863 | 863 | flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app, |
| 864 | − nfp_flower_setup_indr_block_cb); | |
| 864 | + nfp_flower_setup_indr_tc_release); | |
| 865 | 865 | |
| 866 | 866 | if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM) |
| 867 | 867 | nfp_flower_qos_cleanup(app); |
| @@ -459,9 +459,10 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev, · 458 unmodified lines | ||
| 459 | 459 | struct tc_cls_matchall_offload *flow); |
| 460 | 460 | void nfp_flower_stats_rlim_reply(struct nfp_app *app, struct sk_buff *skb); |
| 461 | 461 | int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv, |
| 462 | − enum tc_setup_type type, void *type_data); | |
| 463 | −int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, void *type_data, | |
| 464 | − void *cb_priv); | |
| 462 | + enum tc_setup_type type, void *type_data, | |
| 463 | + void *data, | |
| 464 | + void (*cleanup)(struct flow_block_cb *block_cb)); | |
| 465 | +void nfp_flower_setup_indr_tc_release(void *cb_priv); | |
| 465 | 466 | |
| 466 | 467 | void |
| 467 | 468 | __nfp_flower_non_repr_priv_get(struct nfp_flower_non_repr_priv *non_repr_priv); |
| @@ -1619,8 +1619,8 @@ nfp_flower_indr_block_cb_priv_lookup(struct nfp_app *app, · 1618 unmodified lines | ||
| 1619 | 1619 | return NULL; |
| 1620 | 1620 | } |
| 1621 | 1621 | |
| 1622 | −int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, | |
| 1623 | − void *type_data, void *cb_priv) | |
| 1622 | +static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, | |
| 1623 | + void *type_data, void *cb_priv) | |
| 1624 | 1624 | { |
| 1625 | 1625 | struct nfp_flower_indr_block_cb_priv *priv = cb_priv; |
| 1626 | 1626 | struct flow_cls_offload *flower = type_data; |
| @@ -1637,7 +1637,7 @@ int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, · 10 unmodified lines | ||
| 1637 | 1637 | } |
| 1638 | 1638 | } |
| 1639 | 1639 | |
| 1640 | −static void nfp_flower_setup_indr_tc_release(void *cb_priv) | |
| 1640 | +void nfp_flower_setup_indr_tc_release(void *cb_priv) | |
| 1641 | 1641 | { |
| 1642 | 1642 | struct nfp_flower_indr_block_cb_priv *priv = cb_priv; |
| 1643 | 1643 | |
| @@ -1647,7 +1647,8 @@ static void nfp_flower_setup_indr_tc_release(void *cb_priv) · 3 unmodified lines | ||
| 1647 | 1647 | |
| 1648 | 1648 | static int |
| 1649 | 1649 | nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, |
| 1650 | − struct flow_block_offload *f) | |
| 1650 | + struct flow_block_offload *f, void *data, | |
| 1651 | + void (*cleanup)(struct flow_block_cb *block_cb)) | |
| 1651 | 1652 | { |
| 1652 | 1653 | struct nfp_flower_indr_block_cb_priv *cb_priv; |
| 1653 | 1654 | struct nfp_flower_priv *priv = app->priv; |
| @@ -1676,9 +1677,10 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, · 22 unmodified lines | ||
| 1676 | 1677 | cb_priv->app = app; |
| 1677 | 1678 | list_add(&cb_priv->list, &priv->indr_block_cb_priv); |
| 1678 | 1679 | |
| 1679 | − block_cb = flow_block_cb_alloc(nfp_flower_setup_indr_block_cb, | |
| 1680 | − cb_priv, cb_priv, | |
| 1681 | − nfp_flower_setup_indr_tc_release); | |
| 1680 | + block_cb = flow_indr_block_cb_alloc(nfp_flower_setup_indr_block_cb, | |
| 1681 | + cb_priv, cb_priv, | |
| 1682 | + nfp_flower_setup_indr_tc_release, | |
| 1683 | + f, netdev, data, app, cleanup); | |
| 1682 | 1684 | if (IS_ERR(block_cb)) { |
| 1683 | 1685 | list_del(&cb_priv->list); |
| 1684 | 1686 | kfree(cb_priv); |
| @@ -1699,7 +1701,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, · 14 unmodified lines | ||
| 1699 | 1701 | if (!block_cb) |
| 1700 | 1702 | return -ENOENT; |
| 1701 | 1703 | |
| 1702 | − flow_block_cb_remove(block_cb, f); | |
| 1704 | + flow_indr_block_cb_remove(block_cb, f); | |
| 1703 | 1705 | list_del(&block_cb->driver_list); |
| 1704 | 1706 | return 0; |
| 1705 | 1707 | default: |
| @@ -1710,7 +1712,9 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, · 4 unmodified lines | ||
| 1710 | 1712 | |
| 1711 | 1713 | int |
| 1712 | 1714 | nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv, |
| 1713 | − enum tc_setup_type type, void *type_data) | |
| 1715 | + enum tc_setup_type type, void *type_data, | |
| 1716 | + void *data, | |
| 1717 | + void (*cleanup)(struct flow_block_cb *block_cb)) | |
| 1714 | 1718 | { |
| 1715 | 1719 | if (!nfp_fl_is_netdev_to_offload(netdev)) |
| 1716 | 1720 | return -EOPNOTSUPP; |
| @@ -1718,7 +1722,7 @@ nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv, · 1 unmodified line | ||
| 1718 | 1722 | switch (type) { |
| 1719 | 1723 | case TC_SETUP_BLOCK: |
| 1720 | 1724 | return nfp_flower_setup_indr_tc_block(netdev, cb_priv, |
| 1721 | − type_data); | |
| 1725 | + type_data, data, cleanup); | |
| 1722 | 1726 | default: |
| 1723 | 1727 | return -EOPNOTSUPP; |
| 1724 | 1728 | } |
| @@ -147,7 +147,7 @@ struct pch_gbe_regs { · 146 unmodified lines | ||
| 147 | 147 | #define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */ |
| 148 | 148 | #define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */ |
| 149 | 149 | #define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */ |
| 150 | −/* RX FIFO Read Triger Threshold */ | |
| 150 | +/* RX FIFO Read Trigger Threshold */ | |
| 151 | 151 | #define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */ |
| 152 | 152 | #define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */ |
| 153 | 153 | #define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */ |
| @@ -96,7 +96,8 @@ static void ionic_link_status_check(struct ionic_lif *lif) · 95 unmodified lines | ||
| 96 | 96 | u16 link_status; |
| 97 | 97 | bool link_up; |
| 98 | 98 | |
| 99 | − if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state)) | |
| 99 | + if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state) || | |
| 100 | + test_bit(IONIC_LIF_F_QUEUE_RESET, lif->state)) | |
| 100 | 101 | return; |
| 101 | 102 | |
| 102 | 103 | link_status = le16_to_cpu(lif->info->status.link_status); |
| @@ -1245,6 +1246,7 @@ static int ionic_init_nic_features(struct ionic_lif *lif) · 1142 unmodified lines | ||
| 1245 | 1246 | |
| 1246 | 1247 | netdev->hw_features |= netdev->hw_enc_features; |
| 1247 | 1248 | netdev->features |= netdev->hw_features; |
| 1249 | + netdev->vlan_features |= netdev->features & ~NETIF_F_VLAN_FEATURES; | |
| 1248 | 1250 | |
| 1249 | 1251 | netdev->priv_flags |= IFF_UNICAST_FLT | |
| 1250 | 1252 | IFF_LIVE_ADDR_CHANGE; |
| @@ -1692,15 +1694,15 @@ static void ionic_stop_queues(struct ionic_lif *lif) · 441 unmodified lines | ||
| 1692 | 1694 | if (!test_and_clear_bit(IONIC_LIF_F_UP, lif->state)) |
| 1693 | 1695 | return; |
| 1694 | 1696 | |
| 1695 | − ionic_txrx_disable(lif); | |
| 1696 | 1697 | netif_tx_disable(lif->netdev); |
| 1698 | + ionic_txrx_disable(lif); | |
| 1697 | 1699 | } |
| 1698 | 1700 | |
| 1699 | 1701 | int ionic_stop(struct net_device *netdev) |
| 1700 | 1702 | { |
| 1701 | 1703 | struct ionic_lif *lif = netdev_priv(netdev); |
| 1702 | 1704 | |
| 1703 | − if (!netif_device_present(netdev)) | |
| 1705 | + if (test_bit(IONIC_LIF_F_FW_RESET, lif->state)) | |
| 1704 | 1706 | return 0; |
| 1705 | 1707 | |
| 1706 | 1708 | ionic_stop_queues(lif); |
| @@ -1983,18 +1985,19 @@ int ionic_reset_queues(struct ionic_lif *lif) · 276 unmodified lines | ||
| 1983 | 1985 | bool running; |
| 1984 | 1986 | int err = 0; |
| 1985 | 1987 | |
| 1986 | − /* Put off the next watchdog timeout */ | |
| 1987 | − netif_trans_update(lif->netdev); | |
| 1988 | − | |
| 1989 | 1988 | err = ionic_wait_for_bit(lif, IONIC_LIF_F_QUEUE_RESET); |
| 1990 | 1989 | if (err) |
| 1991 | 1990 | return err; |
| 1992 | 1991 | |
| 1993 | 1992 | running = netif_running(lif->netdev); |
| 1994 | − if (running) | |
| 1993 | + if (running) { | |
| 1994 | + netif_device_detach(lif->netdev); | |
| 1995 | 1995 | err = ionic_stop(lif->netdev); |
| 1996 | − if (!err && running) | |
| 1996 | + } | |
| 1997 | + if (!err && running) { | |
| 1997 | 1998 | ionic_open(lif->netdev); |
| 1999 | + netif_device_attach(lif->netdev); | |
| 2000 | + } | |
| 1998 | 2001 | |
| 1999 | 2002 | clear_bit(IONIC_LIF_F_QUEUE_RESET, lif->state); |
| 2000 | 2003 | |
| @@ -271,7 +271,7 @@ static void qed_cxt_qm_iids(struct qed_hwfn *p_hwfn, · 270 unmodified lines | ||
| 271 | 271 | vf_tids += segs[NUM_TASK_PF_SEGMENTS].count; |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | − iids->vf_cids += vf_cids * p_mngr->vf_count; | |
| 274 | + iids->vf_cids = vf_cids; | |
| 275 | 275 | iids->tids += vf_tids * p_mngr->vf_count; |
| 276 | 276 | |
| 277 | 277 | DP_VERBOSE(p_hwfn, QED_MSG_ILT, |
| @@ -465,6 +465,20 @@ static struct qed_ilt_cli_blk *qed_cxt_set_blk(struct qed_ilt_cli_blk *p_blk) · 187 unmodified lines | ||
| 465 | 465 | return p_blk; |
| 466 | 466 | } |
| 467 | 467 | |
| 468 | +static void qed_cxt_ilt_blk_reset(struct qed_hwfn *p_hwfn) | |
| 469 | +{ | |
| 470 | + struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients; | |
| 471 | + u32 cli_idx, blk_idx; | |
| 472 | + | |
| 473 | + for (cli_idx = 0; cli_idx < MAX_ILT_CLIENTS; cli_idx++) { | |
| 474 | + for (blk_idx = 0; blk_idx < ILT_CLI_PF_BLOCKS; blk_idx++) | |
| 475 | + clients[cli_idx].pf_blks[blk_idx].total_size = 0; | |
| 476 | + | |
| 477 | + for (blk_idx = 0; blk_idx < ILT_CLI_VF_BLOCKS; blk_idx++) | |
| 478 | + clients[cli_idx].vf_blks[blk_idx].total_size = 0; | |
| 479 | + } | |
| 480 | +} | |
| 481 | + | |
| 468 | 482 | int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count) |
| 469 | 483 | { |
| 470 | 484 | struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr; |
| @@ -484,6 +498,11 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count) · 13 unmodified lines | ||
| 484 | 498 | |
| 485 | 499 | p_mngr->pf_start_line = RESC_START(p_hwfn, QED_ILT); |
| 486 | 500 | |
| 501 | + /* Reset all ILT blocks at the beginning of ILT computing in order | |
| 502 | + * to prevent memory allocation for irrelevant blocks afterwards. | |
| 503 | + */ | |
| 504 | + qed_cxt_ilt_blk_reset(p_hwfn); | |
| 505 | + | |
| 487 | 506 | DP_VERBOSE(p_hwfn, QED_MSG_ILT, |
| 488 | 507 | "hwfn [%d] - Set context manager starting line to be 0x%08x\n", |
| 489 | 508 | p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line); |
| @@ -5568,7 +5568,8 @@ static const char * const s_status_str[] = { · 5567 unmodified lines | ||
| 5568 | 5568 | |
| 5569 | 5569 | /* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */ |
| 5570 | 5570 | "The filter/trigger constraint dword offsets are not enabled for recording", |
| 5571 | − | |
| 5571 | + /* DBG_STATUS_NO_MATCHING_FRAMING_MODE */ | |
| 5572 | + "No matching framing mode", | |
| 5572 | 5573 | |
| 5573 | 5574 | /* DBG_STATUS_VFC_READ_ERROR */ |
| 5574 | 5575 | "Error reading from VFC", |
| @@ -980,7 +980,7 @@ int qed_llh_add_mac_filter(struct qed_dev *cdev, · 979 unmodified lines | ||
| 980 | 980 | struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev); |
| 981 | 981 | struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn); |
| 982 | 982 | union qed_llh_filter filter = {}; |
| 983 | − u8 filter_idx, abs_ppfid; | |
| 983 | + u8 filter_idx, abs_ppfid = 0; | |
| 984 | 984 | u32 high, low, ref_cnt; |
| 985 | 985 | int rc = 0; |
| 986 | 986 | |
| @@ -1368,6 +1368,8 @@ static void qed_dbg_user_data_free(struct qed_hwfn *p_hwfn) · 381 unmodified lines | ||
| 1368 | 1368 | |
| 1369 | 1369 | void qed_resc_free(struct qed_dev *cdev) |
| 1370 | 1370 | { |
| 1371 | + struct qed_rdma_info *rdma_info; | |
| 1372 | + struct qed_hwfn *p_hwfn; | |
| 1371 | 1373 | int i; |
| 1372 | 1374 | |
| 1373 | 1375 | if (IS_VF(cdev)) { |
| @@ -1385,7 +1387,8 @@ void qed_resc_free(struct qed_dev *cdev) · 11 unmodified lines | ||
| 1385 | 1387 | qed_llh_free(cdev); |
| 1386 | 1388 | |
| 1387 | 1389 | for_each_hwfn(cdev, i) { |
| 1388 | − struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; | |
| 1390 | + p_hwfn = cdev->hwfns + i; | |
| 1391 | + rdma_info = p_hwfn->p_rdma_info; | |
| 1389 | 1392 | |
| 1390 | 1393 | qed_cxt_mngr_free(p_hwfn); |
| 1391 | 1394 | qed_qm_info_free(p_hwfn); |
| @@ -1404,8 +1407,10 @@ void qed_resc_free(struct qed_dev *cdev) · 12 unmodified lines | ||
| 1404 | 1407 | qed_ooo_free(p_hwfn); |
| 1405 | 1408 | } |
| 1406 | 1409 | |
| 1407 | − if (QED_IS_RDMA_PERSONALITY(p_hwfn)) | |
| 1410 | + if (QED_IS_RDMA_PERSONALITY(p_hwfn) && rdma_info) { | |
| 1411 | + qed_spq_unregister_async_cb(p_hwfn, rdma_info->proto); | |
| 1408 | 1412 | qed_rdma_info_free(p_hwfn); |
| 1413 | + } | |
| 1409 | 1414 | |
| 1410 | 1415 | qed_iov_free(p_hwfn); |
| 1411 | 1416 | qed_l2_free(p_hwfn); |
| @@ -2836,8 +2836,6 @@ int qed_iwarp_stop(struct qed_hwfn *p_hwfn) · 2835 unmodified lines | ||
| 2836 | 2836 | if (rc) |
| 2837 | 2837 | return rc; |
| 2838 | 2838 | |
| 2839 | − qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_IWARP); | |
| 2840 | − | |
| 2841 | 2839 | return qed_iwarp_ll2_stop(p_hwfn); |
| 2842 | 2840 | } |
| 2843 | 2841 | |
| @@ -113,7 +113,6 @@ void qed_roce_stop(struct qed_hwfn *p_hwfn) · 112 unmodified lines | ||
| 113 | 113 | break; |
| 114 | 114 | } |
| 115 | 115 | } |
| 116 | − qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_ROCE); | |
| 117 | 116 | } |
| 118 | 117 | |
| 119 | 118 | static void qed_rdma_copy_gids(struct qed_rdma_qp *qp, __le32 *src_gid, |
| @@ -81,12 +81,17 @@ static void qed_vf_pf_req_end(struct qed_hwfn *p_hwfn, int req_status) · 80 unmodified lines | ||
| 81 | 81 | mutex_unlock(&(p_hwfn->vf_iov_info->mutex)); |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | +#define QED_VF_CHANNEL_USLEEP_ITERATIONS 90 | |
| 85 | +#define QED_VF_CHANNEL_USLEEP_DELAY 100 | |
| 86 | +#define QED_VF_CHANNEL_MSLEEP_ITERATIONS 10 | |
| 87 | +#define QED_VF_CHANNEL_MSLEEP_DELAY 25 | |
| 88 | + | |
| 84 | 89 | static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size) |
| 85 | 90 | { |
| 86 | 91 | union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request; |
| 87 | 92 | struct ustorm_trigger_vf_zone trigger; |
| 88 | 93 | struct ustorm_vf_zone *zone_data; |
| 89 | − int rc = 0, time = 100; | |
| 94 | + int iter, rc = 0; | |
| 90 | 95 | |
| 91 | 96 | zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B; |
| 92 | 97 | |
| @@ -126,11 +131,19 @@ static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size) · 33 unmodified lines | ||
| 126 | 131 | REG_WR(p_hwfn, (uintptr_t)&zone_data->trigger, *((u32 *)&trigger)); |
| 127 | 132 | |
| 128 | 133 | /* When PF would be done with the response, it would write back to the |
| 129 | − * `done' address. Poll until then. | |
| 134 | + * `done' address from a coherent DMA zone. Poll until then. | |
| 130 | 135 | */ |
| 131 | − while ((!*done) && time) { | |
| 132 | − msleep(25); | |
| 133 | − time--; | |
| 136 | + | |
| 137 | + iter = QED_VF_CHANNEL_USLEEP_ITERATIONS; | |
| 138 | + while (!*done && iter--) { | |
| 139 | + udelay(QED_VF_CHANNEL_USLEEP_DELAY); | |
| 140 | + dma_rmb(); | |
| 141 | + } | |
| 142 | + | |
| 143 | + iter = QED_VF_CHANNEL_MSLEEP_ITERATIONS; | |
| 144 | + while (!*done && iter--) { | |
| 145 | + msleep(QED_VF_CHANNEL_MSLEEP_DELAY); | |
| 146 | + dma_rmb(); | |
| 134 | 147 | } |
| 135 | 148 | |
| 136 | 149 | if (!*done) { |
| @@ -1229,7 +1229,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, · 1228 unmodified lines | ||
| 1229 | 1229 | |
| 1230 | 1230 | /* PTP not supported on VFs */ |
| 1231 | 1231 | if (!is_vf) |
| 1232 | − qede_ptp_enable(edev, (mode == QEDE_PROBE_NORMAL)); | |
| 1232 | + qede_ptp_enable(edev); | |
| 1233 | 1233 | |
| 1234 | 1234 | edev->ops->register_ops(cdev, &qede_ll_ops, edev); |
| 1235 | 1235 | |
| @@ -1318,6 +1318,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) · 82 unmodified lines | ||
| 1318 | 1318 | if (system_state == SYSTEM_POWER_OFF) |
| 1319 | 1319 | return; |
| 1320 | 1320 | qed_ops->common->remove(cdev); |
| 1321 | + edev->cdev = NULL; | |
| 1321 | 1322 | |
| 1322 | 1323 | /* Since this can happen out-of-sync with other flows, |
| 1323 | 1324 | * don't release the netdevice until after slowpath stop |
| @@ -412,6 +412,7 @@ void qede_ptp_disable(struct qede_dev *edev) · 411 unmodified lines | ||
| 412 | 412 | if (ptp->tx_skb) { |
| 413 | 413 | dev_kfree_skb_any(ptp->tx_skb); |
| 414 | 414 | ptp->tx_skb = NULL; |
| 415 | + clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags); | |
| 415 | 416 | } |
| 416 | 417 | |
| 417 | 418 | /* Disable PTP in HW */ |
| @@ -423,7 +424,7 @@ void qede_ptp_disable(struct qede_dev *edev) · 5 unmodified lines | ||
| 423 | 424 | edev->ptp = NULL; |
| 424 | 425 | } |
| 425 | 426 | |
| 426 | −static int qede_ptp_init(struct qede_dev *edev, bool init_tc) | |
| 427 | +static int qede_ptp_init(struct qede_dev *edev) | |
| 427 | 428 | { |
| 428 | 429 | struct qede_ptp *ptp; |
| 429 | 430 | int rc; |
| @@ -444,25 +445,19 @@ static int qede_ptp_init(struct qede_dev *edev, bool init_tc) · 14 unmodified lines | ||
| 444 | 445 | /* Init work queue for Tx timestamping */ |
| 445 | 446 | INIT_WORK(&ptp->work, qede_ptp_task); |
| 446 | 447 | |
| 447 | − /* Init cyclecounter and timecounter. This is done only in the first | |
| 448 | − * load. If done in every load, PTP application will fail when doing | |
| 449 | − * unload / load (e.g. MTU change) while it is running. | |
| 450 | − */ | |
| 451 | − if (init_tc) { | |
| 452 | − memset(&ptp->cc, 0, sizeof(ptp->cc)); | |
| 453 | − ptp->cc.read = qede_ptp_read_cc; | |
| 454 | − ptp->cc.mask = CYCLECOUNTER_MASK(64); | |
| 455 | − ptp->cc.shift = 0; | |
| 456 | − ptp->cc.mult = 1; | |
| 457 | − | |
| 458 | − timecounter_init(&ptp->tc, &ptp->cc, | |
| 459 | − ktime_to_ns(ktime_get_real())); | |
| 460 | − } | |
| 448 | + /* Init cyclecounter and timecounter */ | |
| 449 | + memset(&ptp->cc, 0, sizeof(ptp->cc)); | |
| 450 | + ptp->cc.read = qede_ptp_read_cc; | |
| 451 | + ptp->cc.mask = CYCLECOUNTER_MASK(64); | |
| 452 | + ptp->cc.shift = 0; | |
| 453 | + ptp->cc.mult = 1; | |
| 461 | 454 | |
| 462 | − return rc; | |
| 455 | + timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); | |
| 456 | + | |
| 457 | + return 0; | |
| 463 | 458 | } |
| 464 | 459 | |
| 465 | −int qede_ptp_enable(struct qede_dev *edev, bool init_tc) | |
| 460 | +int qede_ptp_enable(struct qede_dev *edev) | |
| 466 | 461 | { |
| 467 | 462 | struct qede_ptp *ptp; |
| 468 | 463 | int rc; |
| @@ -483,7 +478,7 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc) · 14 unmodified lines | ||
| 483 | 478 | |
| 484 | 479 | edev->ptp = ptp; |
| 485 | 480 | |
| 486 | − rc = qede_ptp_init(edev, init_tc); | |
| 481 | + rc = qede_ptp_init(edev); | |
| 487 | 482 | if (rc) |
| 488 | 483 | goto err1; |
| 489 | 484 | |
| @@ -41,7 +41,7 @@ void qede_ptp_rx_ts(struct qede_dev *edev, struct sk_buff *skb); · 40 unmodified lines | ||
| 41 | 41 | void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb); |
| 42 | 42 | int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *req); |
| 43 | 43 | void qede_ptp_disable(struct qede_dev *edev); |
| 44 | −int qede_ptp_enable(struct qede_dev *edev, bool init_tc); | |
| 44 | +int qede_ptp_enable(struct qede_dev *edev); | |
| 45 | 45 | int qede_ptp_get_ts_info(struct qede_dev *edev, struct ethtool_ts_info *ts); |
| 46 | 46 | |
| 47 | 47 | static inline void qede_ptp_record_rx_ts(struct qede_dev *edev, |
| @@ -105,6 +105,7 @@ static void qede_rdma_destroy_wq(struct qede_dev *edev) · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | qede_rdma_cleanup_event(edev); |
| 107 | 107 | destroy_workqueue(edev->rdma_info.rdma_wq); |
| 108 | + edev->rdma_info.rdma_wq = NULL; | |
| 108 | 109 | } |
| 109 | 110 | |
| 110 | 111 | int qede_rdma_dev_add(struct qede_dev *edev, bool recovery) |
| @@ -325,7 +326,7 @@ static void qede_rdma_add_event(struct qede_dev *edev, · 214 unmodified lines | ||
| 325 | 326 | if (edev->rdma_info.exp_recovery) |
| 326 | 327 | return; |
| 327 | 328 | |
| 328 | − if (!edev->rdma_info.qedr_dev) | |
| 329 | + if (!edev->rdma_info.qedr_dev || !edev->rdma_info.rdma_wq) | |
| 329 | 330 | return; |
| 330 | 331 | |
| 331 | 332 | /* We don't want the cleanup flow to start while we're allocating and |
| @@ -269,7 +269,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, · 268 unmodified lines | ||
| 269 | 269 | struct bin_attribute *attr, char *buf, |
| 270 | 270 | loff_t offset, size_t size) |
| 271 | 271 | { |
| 272 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 272 | + struct device *dev = kobj_to_dev(kobj); | |
| 273 | 273 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 274 | 274 | int ret; |
| 275 | 275 | |
| @@ -286,7 +286,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, · 10 unmodified lines | ||
| 286 | 286 | struct bin_attribute *attr, char *buf, |
| 287 | 287 | loff_t offset, size_t size) |
| 288 | 288 | { |
| 289 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 289 | + struct device *dev = kobj_to_dev(kobj); | |
| 290 | 290 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 291 | 291 | int ret; |
| 292 | 292 | |
| @@ -315,7 +315,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, · 22 unmodified lines | ||
| 315 | 315 | struct bin_attribute *attr, char *buf, |
| 316 | 316 | loff_t offset, size_t size) |
| 317 | 317 | { |
| 318 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 318 | + struct device *dev = kobj_to_dev(kobj); | |
| 319 | 319 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 320 | 320 | u64 data; |
| 321 | 321 | int ret; |
| @@ -337,7 +337,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, · 15 unmodified lines | ||
| 337 | 337 | struct bin_attribute *attr, char *buf, |
| 338 | 338 | loff_t offset, size_t size) |
| 339 | 339 | { |
| 340 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 340 | + struct device *dev = kobj_to_dev(kobj); | |
| 341 | 341 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 342 | 342 | u64 data; |
| 343 | 343 | int ret; |
| @@ -402,7 +402,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, · 58 unmodified lines | ||
| 402 | 402 | char *buf, loff_t offset, |
| 403 | 403 | size_t size) |
| 404 | 404 | { |
| 405 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 405 | + struct device *dev = kobj_to_dev(kobj); | |
| 406 | 406 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 407 | 407 | struct qlcnic_pm_func_cfg *pm_cfg; |
| 408 | 408 | u32 id, action, pci_func; |
| @@ -452,7 +452,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, · 43 unmodified lines | ||
| 452 | 452 | char *buf, loff_t offset, |
| 453 | 453 | size_t size) |
| 454 | 454 | { |
| 455 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 455 | + struct device *dev = kobj_to_dev(kobj); | |
| 456 | 456 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 457 | 457 | struct qlcnic_pm_func_cfg *pm_cfg; |
| 458 | 458 | u8 pci_func; |
| @@ -545,7 +545,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, · 86 unmodified lines | ||
| 545 | 545 | char *buf, loff_t offset, |
| 546 | 546 | size_t size) |
| 547 | 547 | { |
| 548 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 548 | + struct device *dev = kobj_to_dev(kobj); | |
| 549 | 549 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 550 | 550 | struct qlcnic_esw_func_cfg *esw_cfg; |
| 551 | 551 | struct qlcnic_npar_info *npar; |
| @@ -629,7 +629,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, · 77 unmodified lines | ||
| 629 | 629 | char *buf, loff_t offset, |
| 630 | 630 | size_t size) |
| 631 | 631 | { |
| 632 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 632 | + struct device *dev = kobj_to_dev(kobj); | |
| 633 | 633 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 634 | 634 | struct qlcnic_esw_func_cfg *esw_cfg; |
| 635 | 635 | u8 pci_func; |
| @@ -681,7 +681,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, · 45 unmodified lines | ||
| 681 | 681 | char *buf, loff_t offset, |
| 682 | 682 | size_t size) |
| 683 | 683 | { |
| 684 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 684 | + struct device *dev = kobj_to_dev(kobj); | |
| 685 | 685 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 686 | 686 | struct qlcnic_info nic_info; |
| 687 | 687 | struct qlcnic_npar_func_cfg *np_cfg; |
| @@ -728,7 +728,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, · 40 unmodified lines | ||
| 728 | 728 | char *buf, loff_t offset, |
| 729 | 729 | size_t size) |
| 730 | 730 | { |
| 731 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 731 | + struct device *dev = kobj_to_dev(kobj); | |
| 732 | 732 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 733 | 733 | struct qlcnic_npar_func_cfg *np_cfg; |
| 734 | 734 | struct qlcnic_info nic_info; |
| @@ -775,7 +775,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, · 40 unmodified lines | ||
| 775 | 775 | char *buf, loff_t offset, |
| 776 | 776 | size_t size) |
| 777 | 777 | { |
| 778 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 778 | + struct device *dev = kobj_to_dev(kobj); | |
| 779 | 779 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 780 | 780 | struct qlcnic_esw_statistics port_stats; |
| 781 | 781 | int ret; |
| @@ -810,7 +810,7 @@ static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file, · 28 unmodified lines | ||
| 810 | 810 | char *buf, loff_t offset, |
| 811 | 811 | size_t size) |
| 812 | 812 | { |
| 813 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 813 | + struct device *dev = kobj_to_dev(kobj); | |
| 814 | 814 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 815 | 815 | struct qlcnic_esw_statistics esw_stats; |
| 816 | 816 | int ret; |
| @@ -845,7 +845,7 @@ static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file, · 28 unmodified lines | ||
| 845 | 845 | char *buf, loff_t offset, |
| 846 | 846 | size_t size) |
| 847 | 847 | { |
| 848 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 848 | + struct device *dev = kobj_to_dev(kobj); | |
| 849 | 849 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 850 | 850 | int ret; |
| 851 | 851 | |
| @@ -875,7 +875,7 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file, · 23 unmodified lines | ||
| 875 | 875 | size_t size) |
| 876 | 876 | { |
| 877 | 877 | |
| 878 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 878 | + struct device *dev = kobj_to_dev(kobj); | |
| 879 | 879 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 880 | 880 | int ret; |
| 881 | 881 | |
| @@ -904,7 +904,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, · 22 unmodified lines | ||
| 904 | 904 | char *buf, loff_t offset, |
| 905 | 905 | size_t size) |
| 906 | 906 | { |
| 907 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 907 | + struct device *dev = kobj_to_dev(kobj); | |
| 908 | 908 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 909 | 909 | struct qlcnic_pci_func_cfg *pci_cfg; |
| 910 | 910 | struct qlcnic_pci_info *pci_info; |
| @@ -946,7 +946,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp, · 35 unmodified lines | ||
| 946 | 946 | { |
| 947 | 947 | unsigned char *p_read_buf; |
| 948 | 948 | int ret, count; |
| 949 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 949 | + struct device *dev = kobj_to_dev(kobj); | |
| 950 | 950 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 951 | 951 | |
| 952 | 952 | if (!size) |
| @@ -1124,7 +1124,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp, · 171 unmodified lines | ||
| 1124 | 1124 | int ret; |
| 1125 | 1125 | static int flash_mode; |
| 1126 | 1126 | unsigned long data; |
| 1127 | − struct device *dev = container_of(kobj, struct device, kobj); | |
| 1127 | + struct device *dev = kobj_to_dev(kobj); | |
| 1128 | 1128 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
| 1129 | 1129 | |
| 1130 | 1130 | ret = kstrtoul(buf, 16, &data); |
| @@ -2114,8 +2114,11 @@ static void rtl_release_firmware(struct rtl8169_private *tp) · 2113 unmodified lines | ||
| 2114 | 2114 | void r8169_apply_firmware(struct rtl8169_private *tp) |
| 2115 | 2115 | { |
| 2116 | 2116 | /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ |
| 2117 | − if (tp->rtl_fw) | |
| 2117 | + if (tp->rtl_fw) { | |
| 2118 | 2118 | rtl_fw_write_firmware(tp, tp->rtl_fw); |
| 2119 | + /* At least one firmware doesn't reset tp->ocp_base. */ | |
| 2120 | + tp->ocp_base = OCP_STD_PHY_BASE; | |
| 2121 | + } | |
| 2119 | 2122 | } |
| 2120 | 2123 | |
| 2121 | 2124 | static void rtl8168_config_eee_mac(struct rtl8169_private *tp) |
| @@ -647,10 +647,10 @@ static int rocker_dma_rings_init(struct rocker *rocker) · 646 unmodified lines | ||
| 647 | 647 | err_dma_event_ring_bufs_alloc: |
| 648 | 648 | rocker_dma_ring_destroy(rocker, &rocker->event_ring); |
| 649 | 649 | err_dma_event_ring_create: |
| 650 | + rocker_dma_cmd_ring_waits_free(rocker); | |
| 651 | +err_dma_cmd_ring_waits_alloc: | |
| 650 | 652 | rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring, |
| 651 | 653 | PCI_DMA_BIDIRECTIONAL); |
| 652 | −err_dma_cmd_ring_waits_alloc: | |
| 653 | − rocker_dma_cmd_ring_waits_free(rocker); | |
| 654 | 654 | err_dma_cmd_ring_bufs_alloc: |
| 655 | 655 | rocker_dma_ring_destroy(rocker, &rocker->cmd_ring); |
| 656 | 656 | return err; |
| @@ -1044,8 +1044,9 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget) · 1043 unmodified lines | ||
| 1044 | 1044 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 1045 | 1045 | |
| 1046 | 1046 | next: |
| 1047 | − if ((skb && napi_gro_receive(&priv->napi, skb) != GRO_DROP) || | |
| 1048 | − xdp_result) { | |
| 1047 | + if (skb) | |
| 1048 | + napi_gro_receive(&priv->napi, skb); | |
| 1049 | + if (skb || xdp_result) { | |
| 1049 | 1050 | ndev->stats.rx_packets++; |
| 1050 | 1051 | ndev->stats.rx_bytes += xdp.data_end - xdp.data; |
| 1051 | 1052 | } |
| @@ -186,7 +186,7 @@ · 185 unmodified lines | ||
| 186 | 186 | #define XAE_RAF_TXVSTRPMODE_MASK 0x00000180 /* Tx VLAN STRIP mode */ |
| 187 | 187 | #define XAE_RAF_RXVSTRPMODE_MASK 0x00000600 /* Rx VLAN STRIP mode */ |
| 188 | 188 | #define XAE_RAF_NEWFNCENBL_MASK 0x00000800 /* New function mode */ |
| 189 | −/* Exteneded Multicast Filtering mode */ | |
| 189 | +/* Extended Multicast Filtering mode */ | |
| 190 | 190 | #define XAE_RAF_EMULTIFLTRENBL_MASK 0x00001000 |
| 191 | 191 | #define XAE_RAF_STATSRST_MASK 0x00002000 /* Stats. Counter Reset */ |
| 192 | 192 | #define XAE_RAF_RXBADFRMEN_MASK 0x00004000 /* Recv Bad Frame Enable */ |
| @@ -1649,6 +1649,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[], · 1648 unmodified lines | ||
| 1649 | 1649 | geneve->collect_md = metadata; |
| 1650 | 1650 | geneve->use_udp6_rx_checksums = use_udp6_rx_checksums; |
| 1651 | 1651 | geneve->ttl_inherit = ttl_inherit; |
| 1652 | + geneve->df = df; | |
| 1652 | 1653 | geneve_unquiesce(geneve, gs4, gs6); |
| 1653 | 1654 | |
| 1654 | 1655 | return 0; |
| @@ -480,8 +480,7 @@ config MICROCHIP_T1_PHY · 479 unmodified lines | ||
| 480 | 480 | config MICROSEMI_PHY |
| 481 | 481 | tristate "Microsemi PHYs" |
| 482 | 482 | depends on MACSEC || MACSEC=n |
| 483 | − select CRYPTO_AES | |
| 484 | − select CRYPTO_ECB | |
| 483 | + select CRYPTO_LIB_AES if MACSEC | |
| 485 | 484 | help |
| 486 | 485 | Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs |
| 487 | 486 | |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/phy.h> |
| 11 | 11 | #include <dt-bindings/net/mscc-phy-vsc8531.h> |
| 12 | 12 | |
| 13 | −#include <crypto/skcipher.h> | |
| 13 | +#include <crypto/aes.h> | |
| 14 | 14 | |
| 15 | 15 | #include <net/macsec.h> |
| 16 | 16 | |
| @@ -500,39 +500,17 @@ static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow) · 483 unmodified lines | ||
| 500 | 500 | static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN], |
| 501 | 501 | u16 key_len, u8 hkey[16]) |
| 502 | 502 | { |
| 503 | − struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0); | |
| 504 | − struct skcipher_request *req = NULL; | |
| 505 | − struct scatterlist src, dst; | |
| 506 | − DECLARE_CRYPTO_WAIT(wait); | |
| 507 | − u32 input[4] = {0}; | |
| 503 | + const u8 input[AES_BLOCK_SIZE] = {0}; | |
| 504 | + struct crypto_aes_ctx ctx; | |
| 508 | 505 | int ret; |
| 509 | 506 | |
| 510 | − if (IS_ERR(tfm)) | |
| 511 | − return PTR_ERR(tfm); | |
| 512 | − | |
| 513 | − req = skcipher_request_alloc(tfm, GFP_KERNEL); | |
| 514 | − if (!req) { | |
| 515 | − ret = -ENOMEM; | |
| 516 | − goto out; | |
| 517 | − } | |
| 518 | − | |
| 519 | − skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | | |
| 520 | − CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, | |
| 521 | − &wait); | |
| 522 | − ret = crypto_skcipher_setkey(tfm, key, key_len); | |
| 523 | − if (ret < 0) | |
| 524 | − goto out; | |
| 525 | − | |
| 526 | − sg_init_one(&src, input, 16); | |
| 527 | − sg_init_one(&dst, hkey, 16); | |
| 528 | − skcipher_request_set_crypt(req, &src, &dst, 16, NULL); | |
| 529 | − | |
| 530 | − ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); | |
| 507 | + ret = aes_expandkey(&ctx, key, key_len); | |
| 508 | + if (ret) | |
| 509 | + return ret; | |
| 531 | 510 | |
| 532 | −out: | |
| 533 | − skcipher_request_free(req); | |
| 534 | − crypto_free_skcipher(tfm); | |
| 535 | − return ret; | |
| 511 | + aes_encrypt(&ctx, hkey, input); | |
| 512 | + memzero_explicit(&ctx, sizeof(ctx)); | |
| 513 | + return 0; | |
| 536 | 514 | } |
| 537 | 515 | |
| 538 | 516 | static int vsc8584_macsec_transformation(struct phy_device *phydev, |
| @@ -840,7 +840,7 @@ static void phy_error(struct phy_device *phydev) · 839 unmodified lines | ||
| 840 | 840 | * phy_disable_interrupts - Disable the PHY interrupts from the PHY side |
| 841 | 841 | * @phydev: target phy_device struct |
| 842 | 842 | */ |
| 843 | −static int phy_disable_interrupts(struct phy_device *phydev) | |
| 843 | +int phy_disable_interrupts(struct phy_device *phydev) | |
| 844 | 844 | { |
| 845 | 845 | int err; |
| 846 | 846 | |
| @@ -794,8 +794,10 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, · 793 unmodified lines | ||
| 794 | 794 | |
| 795 | 795 | /* Grab the bits from PHYIR2, and put them in the lower half */ |
| 796 | 796 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); |
| 797 | − if (phy_reg < 0) | |
| 798 | − return -EIO; | |
| 797 | + if (phy_reg < 0) { | |
| 798 | + /* returning -ENODEV doesn't stop bus scanning */ | |
| 799 | + return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO; | |
| 800 | + } | |
| 799 | 801 | |
| 800 | 802 | *phy_id |= phy_reg; |
| 801 | 803 | |
| @@ -1090,6 +1092,10 @@ int phy_init_hw(struct phy_device *phydev) · 288 unmodified lines | ||
| 1090 | 1092 | if (ret < 0) |
| 1091 | 1093 | return ret; |
| 1092 | 1094 | |
| 1095 | + ret = phy_disable_interrupts(phydev); | |
| 1096 | + if (ret) | |
| 1097 | + return ret; | |
| 1098 | + | |
| 1093 | 1099 | if (phydev->drv->config_init) |
| 1094 | 1100 | ret = phydev->drv->config_init(phydev); |
| 1095 | 1101 | |
| @@ -1463,6 +1463,8 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, · 1462 unmodified lines | ||
| 1463 | 1463 | struct ethtool_pauseparam *pause) |
| 1464 | 1464 | { |
| 1465 | 1465 | struct phylink_link_state *config = &pl->link_config; |
| 1466 | + bool manual_changed; | |
| 1467 | + int pause_state; | |
| 1466 | 1468 | |
| 1467 | 1469 | ASSERT_RTNL(); |
| 1468 | 1470 | |
| @@ -1477,15 +1479,15 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, · 8 unmodified lines | ||
| 1477 | 1479 | !pause->autoneg && pause->rx_pause != pause->tx_pause) |
| 1478 | 1480 | return -EINVAL; |
| 1479 | 1481 | |
| 1480 | − mutex_lock(&pl->state_mutex); | |
| 1481 | − config->pause = 0; | |
| 1482 | + pause_state = 0; | |
| 1482 | 1483 | if (pause->autoneg) |
| 1483 | − config->pause |= MLO_PAUSE_AN; | |
| 1484 | + pause_state |= MLO_PAUSE_AN; | |
| 1484 | 1485 | if (pause->rx_pause) |
| 1485 | − config->pause |= MLO_PAUSE_RX; | |
| 1486 | + pause_state |= MLO_PAUSE_RX; | |
| 1486 | 1487 | if (pause->tx_pause) |
| 1487 | − config->pause |= MLO_PAUSE_TX; | |
| 1488 | + pause_state |= MLO_PAUSE_TX; | |
| 1488 | 1489 | |
| 1490 | + mutex_lock(&pl->state_mutex); | |
| 1489 | 1491 | /* |
| 1490 | 1492 | * See the comments for linkmode_set_pause(), wrt the deficiencies |
| 1491 | 1493 | * with the current implementation. A solution to this issue would |
| @@ -1502,18 +1504,35 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, · 10 unmodified lines | ||
| 1502 | 1504 | linkmode_set_pause(config->advertising, pause->tx_pause, |
| 1503 | 1505 | pause->rx_pause); |
| 1504 | 1506 | |
| 1505 | − /* If we have a PHY, phylib will call our link state function if the | |
| 1506 | − * mode has changed, which will trigger a resolve and update the MAC | |
| 1507 | − * configuration. | |
| 1507 | + manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || | |
| 1508 | + (!(pause_state & MLO_PAUSE_AN) && | |
| 1509 | + (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); | |
| 1510 | + | |
| 1511 | + config->pause = pause_state; | |
| 1512 | + | |
| 1513 | + if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED, | |
| 1514 | + &pl->phylink_disable_state)) | |
| 1515 | + phylink_pcs_config(pl, true, &pl->link_config); | |
| 1516 | + | |
| 1517 | + mutex_unlock(&pl->state_mutex); | |
| 1518 | + | |
| 1519 | + /* If we have a PHY, a change of the pause frame advertisement will | |
| 1520 | + * cause phylib to renegotiate (if AN is enabled) which will in turn | |
| 1521 | + * call our phylink_phy_change() and trigger a resolve. Note that | |
| 1522 | + * we can't hold our state mutex while calling phy_set_asym_pause(). | |
| 1508 | 1523 | */ |
| 1509 | − if (pl->phydev) { | |
| 1524 | + if (pl->phydev) | |
| 1510 | 1525 | phy_set_asym_pause(pl->phydev, pause->rx_pause, |
| 1511 | 1526 | pause->tx_pause); |
| 1512 | − } else if (!test_bit(PHYLINK_DISABLE_STOPPED, | |
| 1513 | − &pl->phylink_disable_state)) { | |
| 1514 | − phylink_pcs_config(pl, true, &pl->link_config); | |
| 1527 | + | |
| 1528 | + /* If the manual pause settings changed, make sure we trigger a | |
| 1529 | + * resolve to update their state; we can not guarantee that the | |
| 1530 | + * link will cycle. | |
| 1531 | + */ | |
| 1532 | + if (manual_changed) { | |
| 1533 | + pl->mac_link_dropped = true; | |
| 1534 | + phylink_run_resolve(pl); | |
| 1515 | 1535 | } |
| 1516 | − mutex_unlock(&pl->state_mutex); | |
| 1517 | 1536 | |
| 1518 | 1537 | return 0; |
| 1519 | 1538 | } |
| @@ -122,10 +122,13 @@ static int lan87xx_read_status(struct phy_device *phydev) · 121 unmodified lines | ||
| 122 | 122 | if (rc < 0) |
| 123 | 123 | return rc; |
| 124 | 124 | |
| 125 | − /* Wait max 640 ms to detect energy */ | |
| 126 | − phy_read_poll_timeout(phydev, MII_LAN83C185_CTRL_STATUS, rc, | |
| 127 | − rc & MII_LAN83C185_ENERGYON, 10000, | |
| 128 | − 640000, true); | |
| 125 | + /* Wait max 640 ms to detect energy and the timeout is not | |
| 126 | + * an actual error. | |
| 127 | + */ | |
| 128 | + read_poll_timeout(phy_read, rc, | |
| 129 | + rc & MII_LAN83C185_ENERGYON || rc < 0, | |
| 130 | + 10000, 640000, true, phydev, | |
| 131 | + MII_LAN83C185_CTRL_STATUS); | |
| 129 | 132 | if (rc < 0) |
| 130 | 133 | return rc; |
| 131 | 134 | |
| @@ -1491,10 +1491,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) · 1490 unmodified lines | ||
| 1491 | 1491 | } |
| 1492 | 1492 | |
| 1493 | 1493 | if (pkt_cnt == 0) { |
| 1494 | − /* Skip IP alignment psudo header */ | |
| 1495 | − skb_pull(skb, 2); | |
| 1496 | 1494 | skb->len = pkt_len; |
| 1497 | − skb_set_tail_pointer(skb, pkt_len); | |
| 1495 | + /* Skip IP alignment pseudo header */ | |
| 1496 | + skb_pull(skb, 2); | |
| 1497 | + skb_set_tail_pointer(skb, skb->len); | |
| 1498 | 1498 | skb->truesize = pkt_len + sizeof(struct sk_buff); |
| 1499 | 1499 | ax88179_rx_checksum(skb, pkt_hdr); |
| 1500 | 1500 | return 1; |
| @@ -1503,8 +1503,9 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) · 2 unmodified lines | ||
| 1503 | 1503 | ax_skb = skb_clone(skb, GFP_ATOMIC); |
| 1504 | 1504 | if (ax_skb) { |
| 1505 | 1505 | ax_skb->len = pkt_len; |
| 1506 | − ax_skb->data = skb->data + 2; | |
| 1507 | − skb_set_tail_pointer(ax_skb, pkt_len); | |
| 1506 | + /* Skip IP alignment pseudo header */ | |
| 1507 | + skb_pull(ax_skb, 2); | |
| 1508 | + skb_set_tail_pointer(ax_skb, ax_skb->len); | |
| 1508 | 1509 | ax_skb->truesize = pkt_len + sizeof(struct sk_buff); |
| 1509 | 1510 | ax88179_rx_checksum(ax_skb, pkt_hdr); |
| 1510 | 1511 | usbnet_skb_return(dev, ax_skb); |
| @@ -1324,7 +1324,7 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) · 1323 unmodified lines | ||
| 1324 | 1324 | struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); |
| 1325 | 1325 | |
| 1326 | 1326 | if (pdata) { |
| 1327 | − cancel_delayed_work(&pdata->carrier_check); | |
| 1327 | + cancel_delayed_work_sync(&pdata->carrier_check); | |
| 1328 | 1328 | netif_dbg(dev, ifdown, dev->net, "free pdata\n"); |
| 1329 | 1329 | kfree(pdata); |
| 1330 | 1330 | pdata = NULL; |
| @@ -1380,6 +1380,8 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, · 1379 unmodified lines | ||
| 1380 | 1380 | struct vxlan_rdst *rd; |
| 1381 | 1381 | |
| 1382 | 1382 | if (rcu_access_pointer(f->nh)) { |
| 1383 | + if (*idx < cb->args[2]) | |
| 1384 | + goto skip_nh; | |
| 1383 | 1385 | err = vxlan_fdb_info(skb, vxlan, f, |
| 1384 | 1386 | NETLINK_CB(cb->skb).portid, |
| 1385 | 1387 | cb->nlh->nlmsg_seq, |
| @@ -1387,6 +1389,8 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, · 1 unmodified line | ||
| 1387 | 1389 | NLM_F_MULTI, NULL); |
| 1388 | 1390 | if (err < 0) |
| 1389 | 1391 | goto out; |
| 1392 | +skip_nh: | |
| 1393 | + *idx += 1; | |
| 1390 | 1394 | continue; |
| 1391 | 1395 | } |
| 1392 | 1396 | |
| @@ -45,17 +45,18 @@ static int wg_open(struct net_device *dev) · 44 unmodified lines | ||
| 45 | 45 | if (dev_v6) |
| 46 | 46 | dev_v6->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_NONE; |
| 47 | 47 | |
| 48 | + mutex_lock(&wg->device_update_lock); | |
| 48 | 49 | ret = wg_socket_init(wg, wg->incoming_port); |
| 49 | 50 | if (ret < 0) |
| 50 | − return ret; | |
| 51 | − mutex_lock(&wg->device_update_lock); | |
| 51 | + goto out; | |
| 52 | 52 | list_for_each_entry(peer, &wg->peer_list, peer_list) { |
| 53 | 53 | wg_packet_send_staged_packets(peer); |
| 54 | 54 | if (peer->persistent_keepalive_interval) |
| 55 | 55 | wg_packet_send_keepalive(peer); |
| 56 | 56 | } |
| 57 | +out: | |
| 57 | 58 | mutex_unlock(&wg->device_update_lock); |
| 58 | − return 0; | |
| 59 | + return ret; | |
| 59 | 60 | } |
| 60 | 61 | |
| 61 | 62 | #ifdef CONFIG_PM_SLEEP |
| @@ -225,6 +226,7 @@ static void wg_destruct(struct net_device *dev) · 163 unmodified lines | ||
| 225 | 226 | list_del(&wg->device_list); |
| 226 | 227 | rtnl_unlock(); |
| 227 | 228 | mutex_lock(&wg->device_update_lock); |
| 229 | + rcu_assign_pointer(wg->creating_net, NULL); | |
| 228 | 230 | wg->incoming_port = 0; |
| 229 | 231 | wg_socket_reinit(wg, NULL, NULL); |
| 230 | 232 | /* The final references are cleared in the below calls to destroy_workqueue. */ |
| @@ -240,13 +242,11 @@ static void wg_destruct(struct net_device *dev) · 9 unmodified lines | ||
| 240 | 242 | skb_queue_purge(&wg->incoming_handshakes); |
| 241 | 243 | free_percpu(dev->tstats); |
| 242 | 244 | free_percpu(wg->incoming_handshakes_worker); |
| 243 | − if (wg->have_creating_net_ref) | |
| 244 | − put_net(wg->creating_net); | |
| 245 | 245 | kvfree(wg->index_hashtable); |
| 246 | 246 | kvfree(wg->peer_hashtable); |
| 247 | 247 | mutex_unlock(&wg->device_update_lock); |
| 248 | 248 | |
| 249 | − pr_debug("%s: Interface deleted\n", dev->name); | |
| 249 | + pr_debug("%s: Interface destroyed\n", dev->name); | |
| 250 | 250 | free_netdev(dev); |
| 251 | 251 | } |
| 252 | 252 | |
| @@ -292,7 +292,7 @@ static int wg_newlink(struct net *src_net, struct net_device *dev, · 39 unmodified lines | ||
| 292 | 292 | struct wg_device *wg = netdev_priv(dev); |
| 293 | 293 | int ret = -ENOMEM; |
| 294 | 294 | |
| 295 | − wg->creating_net = src_net; | |
| 295 | + rcu_assign_pointer(wg->creating_net, src_net); | |
| 296 | 296 | init_rwsem(&wg->static_identity.lock); |
| 297 | 297 | mutex_init(&wg->socket_update_lock); |
| 298 | 298 | mutex_init(&wg->device_update_lock); |
| @@ -393,30 +393,26 @@ static struct rtnl_link_ops link_ops __read_mostly = { · 94 unmodified lines | ||
| 393 | 393 | .newlink = wg_newlink, |
| 394 | 394 | }; |
| 395 | 395 | |
| 396 | −static int wg_netdevice_notification(struct notifier_block *nb, | |
| 397 | − unsigned long action, void *data) | |
| 396 | +static void wg_netns_pre_exit(struct net *net) | |
| 398 | 397 | { |
| 399 | − struct net_device *dev = ((struct netdev_notifier_info *)data)->dev; | |
| 400 | − struct wg_device *wg = netdev_priv(dev); | |
| 401 | − | |
| 402 | − ASSERT_RTNL(); | |
| 403 | − | |
| 404 | − if (action != NETDEV_REGISTER || dev->netdev_ops != &netdev_ops) | |
| 405 | − return 0; | |
| 398 | + struct wg_device *wg; | |
| 406 | 399 | |
| 407 | − if (dev_net(dev) == wg->creating_net && wg->have_creating_net_ref) { | |
| 408 | − put_net(wg->creating_net); | |
| 409 | − wg->have_creating_net_ref = false; | |
| 410 | − } else if (dev_net(dev) != wg->creating_net && | |
| 411 | − !wg->have_creating_net_ref) { | |
| 412 | − wg->have_creating_net_ref = true; | |
| 413 | − get_net(wg->creating_net); | |
| 400 | + rtnl_lock(); | |
| 401 | + list_for_each_entry(wg, &device_list, device_list) { | |
| 402 | + if (rcu_access_pointer(wg->creating_net) == net) { | |
| 403 | + pr_debug("%s: Creating namespace exiting\n", wg->dev->name); | |
| 404 | + netif_carrier_off(wg->dev); | |
| 405 | + mutex_lock(&wg->device_update_lock); | |
| 406 | + rcu_assign_pointer(wg->creating_net, NULL); | |
| 407 | + wg_socket_reinit(wg, NULL, NULL); | |
| 408 | + mutex_unlock(&wg->device_update_lock); | |
| 409 | + } | |
| 414 | 410 | } |
| 415 | − return 0; | |
| 411 | + rtnl_unlock(); | |
| 416 | 412 | } |
| 417 | 413 | |
| 418 | −static struct notifier_block netdevice_notifier = { | |
| 419 | − .notifier_call = wg_netdevice_notification | |
| 414 | +static struct pernet_operations pernet_ops = { | |
| 415 | + .pre_exit = wg_netns_pre_exit | |
| 420 | 416 | }; |
| 421 | 417 | |
| 422 | 418 | int __init wg_device_init(void) |
| @@ -429,18 +425,18 @@ int __init wg_device_init(void) · 6 unmodified lines | ||
| 429 | 425 | return ret; |
| 430 | 426 | #endif |
| 431 | 427 | |
| 432 | − ret = register_netdevice_notifier(&netdevice_notifier); | |
| 428 | + ret = register_pernet_device(&pernet_ops); | |
| 433 | 429 | if (ret) |
| 434 | 430 | goto error_pm; |
| 435 | 431 | |
| 436 | 432 | ret = rtnl_link_register(&link_ops); |
| 437 | 433 | if (ret) |
| 438 | − goto error_netdevice; | |
| 434 | + goto error_pernet; | |
| 439 | 435 | |
| 440 | 436 | return 0; |
| 441 | 437 | |
| 442 | −error_netdevice: | |
| 443 | − unregister_netdevice_notifier(&netdevice_notifier); | |
| 438 | +error_pernet: | |
| 439 | + unregister_pernet_device(&pernet_ops); | |
| 444 | 440 | error_pm: |
| 445 | 441 | #ifdef CONFIG_PM_SLEEP |
| 446 | 442 | unregister_pm_notifier(&pm_notifier); |
| @@ -451,7 +447,7 @@ error_pm: · 4 unmodified lines | ||
| 451 | 447 | void wg_device_uninit(void) |
| 452 | 448 | { |
| 453 | 449 | rtnl_link_unregister(&link_ops); |
| 454 | − unregister_netdevice_notifier(&netdevice_notifier); | |
| 450 | + unregister_pernet_device(&pernet_ops); | |
| 455 | 451 | #ifdef CONFIG_PM_SLEEP |
| 456 | 452 | unregister_pm_notifier(&pm_notifier); |
| 457 | 453 | #endif |
| @@ -40,7 +40,7 @@ struct wg_device { · 39 unmodified lines | ||
| 40 | 40 | struct net_device *dev; |
| 41 | 41 | struct crypt_queue encrypt_queue, decrypt_queue; |
| 42 | 42 | struct sock __rcu *sock4, *sock6; |
| 43 | − struct net *creating_net; | |
| 43 | + struct net __rcu *creating_net; | |
| 44 | 44 | struct noise_static_identity static_identity; |
| 45 | 45 | struct workqueue_struct *handshake_receive_wq, *handshake_send_wq; |
| 46 | 46 | struct workqueue_struct *packet_crypt_wq; |
| @@ -56,7 +56,6 @@ struct wg_device { · 9 unmodified lines | ||
| 56 | 56 | unsigned int num_peers, device_update_gen; |
| 57 | 57 | u32 fwmark; |
| 58 | 58 | u16 incoming_port; |
| 59 | − bool have_creating_net_ref; | |
| 60 | 59 | }; |
| 61 | 60 | |
| 62 | 61 | int wg_device_init(void); |
| @@ -511,11 +511,15 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info) · 510 unmodified lines | ||
| 511 | 511 | if (flags & ~__WGDEVICE_F_ALL) |
| 512 | 512 | goto out; |
| 513 | 513 | |
| 514 | − ret = -EPERM; | |
| 515 | − if ((info->attrs[WGDEVICE_A_LISTEN_PORT] || | |
| 516 | − info->attrs[WGDEVICE_A_FWMARK]) && | |
| 517 | − !ns_capable(wg->creating_net->user_ns, CAP_NET_ADMIN)) | |
| 518 | − goto out; | |
| 514 | + if (info->attrs[WGDEVICE_A_LISTEN_PORT] || info->attrs[WGDEVICE_A_FWMARK]) { | |
| 515 | + struct net *net; | |
| 516 | + rcu_read_lock(); | |
| 517 | + net = rcu_dereference(wg->creating_net); | |
| 518 | + ret = !net || !ns_capable(net->user_ns, CAP_NET_ADMIN) ? -EPERM : 0; | |
| 519 | + rcu_read_unlock(); | |
| 520 | + if (ret) | |
| 521 | + goto out; | |
| 522 | + } | |
| 519 | 523 | |
| 520 | 524 | ++wg->device_update_gen; |
| 521 | 525 | |
| @@ -617,8 +617,8 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src, · 616 unmodified lines | ||
| 617 | 617 | memcpy(handshake->hash, hash, NOISE_HASH_LEN); |
| 618 | 618 | memcpy(handshake->chaining_key, chaining_key, NOISE_HASH_LEN); |
| 619 | 619 | handshake->remote_index = src->sender_index; |
| 620 | − if ((s64)(handshake->last_initiation_consumption - | |
| 621 | − (initiation_consumption = ktime_get_coarse_boottime_ns())) < 0) | |
| 620 | + initiation_consumption = ktime_get_coarse_boottime_ns(); | |
| 621 | + if ((s64)(handshake->last_initiation_consumption - initiation_consumption) < 0) | |
| 622 | 622 | handshake->last_initiation_consumption = initiation_consumption; |
| 623 | 623 | handshake->state = HANDSHAKE_CONSUMED_INITIATION; |
| 624 | 624 | up_write(&handshake->lock); |
| @@ -414,14 +414,8 @@ static void wg_packet_consume_data_done(struct wg_peer *peer, · 413 unmodified lines | ||
| 414 | 414 | if (unlikely(routed_peer != peer)) |
| 415 | 415 | goto dishonest_packet_peer; |
| 416 | 416 | |
| 417 | − if (unlikely(napi_gro_receive(&peer->napi, skb) == GRO_DROP)) { | |
| 418 | − ++dev->stats.rx_dropped; | |
| 419 | − net_dbg_ratelimited("%s: Failed to give packet to userspace from peer %llu (%pISpfsc)\n", | |
| 420 | − dev->name, peer->internal_id, | |
| 421 | − &peer->endpoint.addr); | |
| 422 | − } else { | |
| 423 | − update_rx_stats(peer, message_data_len(len_before_trim)); | |
| 424 | − } | |
| 417 | + napi_gro_receive(&peer->napi, skb); | |
| 418 | + update_rx_stats(peer, message_data_len(len_before_trim)); | |
| 425 | 419 | return; |
| 426 | 420 | |
| 427 | 421 | dishonest_packet_peer: |
| @@ -347,6 +347,7 @@ static void set_sock_opts(struct socket *sock) · 346 unmodified lines | ||
| 347 | 347 | |
| 348 | 348 | int wg_socket_init(struct wg_device *wg, u16 port) |
| 349 | 349 | { |
| 350 | + struct net *net; | |
| 350 | 351 | int ret; |
| 351 | 352 | struct udp_tunnel_sock_cfg cfg = { |
| 352 | 353 | .sk_user_data = wg, |
| @@ -371,37 +372,47 @@ int wg_socket_init(struct wg_device *wg, u16 port) · 18 unmodified lines | ||
| 371 | 372 | }; |
| 372 | 373 | #endif |
| 373 | 374 | |
| 375 | + rcu_read_lock(); | |
| 376 | + net = rcu_dereference(wg->creating_net); | |
| 377 | + net = net ? maybe_get_net(net) : NULL; | |
| 378 | + rcu_read_unlock(); | |
| 379 | + if (unlikely(!net)) | |
| 380 | + return -ENONET; | |
| 381 | + | |
| 374 | 382 | #if IS_ENABLED(CONFIG_IPV6) |
| 375 | 383 | retry: |
| 376 | 384 | #endif |
| 377 | 385 | |
| 378 | − ret = udp_sock_create(wg->creating_net, &port4, &new4); | |
| 386 | + ret = udp_sock_create(net, &port4, &new4); | |
| 379 | 387 | if (ret < 0) { |
| 380 | 388 | pr_err("%s: Could not create IPv4 socket\n", wg->dev->name); |
| 381 | − return ret; | |
| 389 | + goto out; | |
| 382 | 390 | } |
| 383 | 391 | set_sock_opts(new4); |
| 384 | − setup_udp_tunnel_sock(wg->creating_net, new4, &cfg); | |
| 392 | + setup_udp_tunnel_sock(net, new4, &cfg); | |
| 385 | 393 | |
| 386 | 394 | #if IS_ENABLED(CONFIG_IPV6) |
| 387 | 395 | if (ipv6_mod_enabled()) { |
| 388 | 396 | port6.local_udp_port = inet_sk(new4->sk)->inet_sport; |
| 389 | − ret = udp_sock_create(wg->creating_net, &port6, &new6); | |
| 397 | + ret = udp_sock_create(net, &port6, &new6); | |
| 390 | 398 | if (ret < 0) { |
| 391 | 399 | udp_tunnel_sock_release(new4); |
| 392 | 400 | if (ret == -EADDRINUSE && !port && retries++ < 100) |
| 393 | 401 | goto retry; |
| 394 | 402 | pr_err("%s: Could not create IPv6 socket\n", |
| 395 | 403 | wg->dev->name); |
| 396 | − return ret; | |
| 404 | + goto out; | |
| 397 | 405 | } |
| 398 | 406 | set_sock_opts(new6); |
| 399 | − setup_udp_tunnel_sock(wg->creating_net, new6, &cfg); | |
| 407 | + setup_udp_tunnel_sock(net, new6, &cfg); | |
| 400 | 408 | } |
| 401 | 409 | #endif |
| 402 | 410 | |
| 403 | 411 | wg_socket_reinit(wg, new4->sk, new6 ? new6->sk : NULL); |
| 404 | − return 0; | |
| 412 | + ret = 0; | |
| 413 | +out: | |
| 414 | + put_net(net); | |
| 415 | + return ret; | |
| 405 | 416 | } |
| 406 | 417 | |
| 407 | 418 | void wg_socket_reinit(struct wg_device *wg, struct sock *new4, |
| @@ -897,7 +897,6 @@ static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) · 896 unmodified lines | ||
| 897 | 897 | void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, |
| 898 | 898 | struct wil_net_stats *stats, bool gro) |
| 899 | 899 | { |
| 900 | − gro_result_t rc = GRO_NORMAL; | |
| 901 | 900 | struct wil6210_vif *vif = ndev_to_vif(ndev); |
| 902 | 901 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
| 903 | 902 | struct wireless_dev *wdev = vif_to_wdev(vif); |
| @@ -908,22 +907,16 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, · 4 unmodified lines | ||
| 908 | 907 | */ |
| 909 | 908 | int mcast = is_multicast_ether_addr(da); |
| 910 | 909 | struct sk_buff *xmit_skb = NULL; |
| 911 | − static const char * const gro_res_str[] = { | |
| 912 | − [GRO_MERGED] = "GRO_MERGED", | |
| 913 | − [GRO_MERGED_FREE] = "GRO_MERGED_FREE", | |
| 914 | − [GRO_HELD] = "GRO_HELD", | |
| 915 | − [GRO_NORMAL] = "GRO_NORMAL", | |
| 916 | − [GRO_DROP] = "GRO_DROP", | |
| 917 | − [GRO_CONSUMED] = "GRO_CONSUMED", | |
| 918 | − }; | |
| 919 | 910 | |
| 920 | 911 | if (wdev->iftype == NL80211_IFTYPE_STATION) { |
| 921 | 912 | sa = wil_skb_get_sa(skb); |
| 922 | 913 | if (mcast && ether_addr_equal(sa, ndev->dev_addr)) { |
| 923 | 914 | /* mcast packet looped back to us */ |
| 924 | − rc = GRO_DROP; | |
| 925 | 915 | dev_kfree_skb(skb); |
| 926 | − goto stats; | |
| 916 | + ndev->stats.rx_dropped++; | |
| 917 | + stats->rx_dropped++; | |
| 918 | + wil_dbg_txrx(wil, "Rx drop %d bytes\n", len); | |
| 919 | + return; | |
| 927 | 920 | } |
| 928 | 921 | } else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) { |
| 929 | 922 | if (mcast) { |
| @@ -967,26 +960,16 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, · 37 unmodified lines | ||
| 967 | 960 | wil_rx_handle_eapol(vif, skb); |
| 968 | 961 | |
| 969 | 962 | if (gro) |
| 970 | − rc = napi_gro_receive(&wil->napi_rx, skb); | |
| 963 | + napi_gro_receive(&wil->napi_rx, skb); | |
| 971 | 964 | else |
| 972 | 965 | netif_rx_ni(skb); |
| 973 | − wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", | |
| 974 | − len, gro_res_str[rc]); | |
| 975 | − } | |
| 976 | −stats: | |
| 977 | − /* statistics. rc set to GRO_NORMAL for AP bridging */ | |
| 978 | − if (unlikely(rc == GRO_DROP)) { | |
| 979 | − ndev->stats.rx_dropped++; | |
| 980 | − stats->rx_dropped++; | |
| 981 | − wil_dbg_txrx(wil, "Rx drop %d bytes\n", len); | |
| 982 | − } else { | |
| 983 | − ndev->stats.rx_packets++; | |
| 984 | − stats->rx_packets++; | |
| 985 | − ndev->stats.rx_bytes += len; | |
| 986 | − stats->rx_bytes += len; | |
| 987 | − if (mcast) | |
| 988 | − ndev->stats.multicast++; | |
| 989 | 966 | } |
| 967 | + ndev->stats.rx_packets++; | |
| 968 | + stats->rx_packets++; | |
| 969 | + ndev->stats.rx_bytes += len; | |
| 970 | + stats->rx_bytes += len; | |
| 971 | + if (mcast) | |
| 972 | + ndev->stats.multicast++; | |
| 990 | 973 | } |
| 991 | 974 | |
| 992 | 975 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) |
| @@ -679,18 +679,8 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n) · 678 unmodified lines | ||
| 679 | 679 | return a->mode; |
| 680 | 680 | } |
| 681 | 681 | |
| 682 | − if (a == &dev_attr_align.attr) { | |
| 683 | − int i; | |
| 684 | − | |
| 685 | − for (i = 0; i < nd_region->ndr_mappings; i++) { | |
| 686 | − struct nd_mapping *nd_mapping = &nd_region->mapping[i]; | |
| 687 | − struct nvdimm *nvdimm = nd_mapping->nvdimm; | |
| 688 | − | |
| 689 | − if (test_bit(NDD_LABELING, &nvdimm->flags)) | |
| 690 | − return a->mode; | |
| 691 | − } | |
| 692 | − return 0; | |
| 693 | − } | |
| 682 | + if (a == &dev_attr_align.attr) | |
| 683 | + return a->mode; | |
| 694 | 684 | |
| 695 | 685 | if (a != &dev_attr_set_cookie.attr |
| 696 | 686 | && a != &dev_attr_available_size.attr) |
| @@ -1116,10 +1116,16 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, · 1115 unmodified lines | ||
| 1116 | 1116 | dev_warn(ctrl->device, |
| 1117 | 1117 | "Identify Descriptors failed (%d)\n", status); |
| 1118 | 1118 | /* |
| 1119 | − * Don't treat an error as fatal, as we potentially already | |
| 1120 | − * have a NGUID or EUI-64. | |
| 1119 | + * Don't treat non-retryable errors as fatal, as we potentially | |
| 1120 | + * already have a NGUID or EUI-64. If we failed with DNR set, | |
| 1121 | + * we want to silently ignore the error as we can still | |
| 1122 | + * identify the device, but if the status has DNR set, we want | |
| 1123 | + * to propagate the error back specifically for the disk | |
| 1124 | + * revalidation flow to make sure we don't abandon the | |
| 1125 | + * device just because of a temporal retry-able error (such | |
| 1126 | + * as path of transport errors). | |
| 1121 | 1127 | */ |
| 1122 | − if (status > 0 && !(status & NVME_SC_DNR)) | |
| 1128 | + if (status > 0 && (status & NVME_SC_DNR)) | |
| 1123 | 1129 | status = 0; |
| 1124 | 1130 | goto free_data; |
| 1125 | 1131 | } |
| @@ -1974,7 +1980,6 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id) · 848 unmodified lines | ||
| 1974 | 1980 | if (ns->head->disk) { |
| 1975 | 1981 | nvme_update_disk_info(ns->head->disk, ns, id); |
| 1976 | 1982 | blk_queue_stack_limits(ns->head->disk->queue, ns->queue); |
| 1977 | − revalidate_disk(ns->head->disk); | |
| 1978 | 1983 | } |
| 1979 | 1984 | #endif |
| 1980 | 1985 | return 0; |
| @@ -4174,6 +4179,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, · 2193 unmodified lines | ||
| 4174 | 4179 | ctrl->dev = dev; |
| 4175 | 4180 | ctrl->ops = ops; |
| 4176 | 4181 | ctrl->quirks = quirks; |
| 4182 | + ctrl->numa_node = NUMA_NO_NODE; | |
| 4177 | 4183 | INIT_WORK(&ctrl->scan_work, nvme_scan_work); |
| 4178 | 4184 | INIT_WORK(&ctrl->async_event_work, nvme_async_event_work); |
| 4179 | 4185 | INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work); |
| @@ -409,15 +409,14 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) · 408 unmodified lines | ||
| 409 | 409 | { |
| 410 | 410 | struct nvme_ns_head *head = ns->head; |
| 411 | 411 | |
| 412 | − lockdep_assert_held(&ns->head->lock); | |
| 413 | − | |
| 414 | 412 | if (!head->disk) |
| 415 | 413 | return; |
| 416 | 414 | |
| 417 | − if (!(head->disk->flags & GENHD_FL_UP)) | |
| 415 | + if (!test_and_set_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) | |
| 418 | 416 | device_add_disk(&head->subsys->dev, head->disk, |
| 419 | 417 | nvme_ns_id_attr_groups); |
| 420 | 418 | |
| 419 | + mutex_lock(&head->lock); | |
| 421 | 420 | if (nvme_path_is_optimized(ns)) { |
| 422 | 421 | int node, srcu_idx; |
| 423 | 422 | |
| @@ -426,9 +425,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) · 2 unmodified lines | ||
| 426 | 425 | __nvme_find_path(head, node); |
| 427 | 426 | srcu_read_unlock(&head->srcu, srcu_idx); |
| 428 | 427 | } |
| 428 | + mutex_unlock(&head->lock); | |
| 429 | 429 | |
| 430 | − synchronize_srcu(&ns->head->srcu); | |
| 431 | − kblockd_schedule_work(&ns->head->requeue_work); | |
| 430 | + synchronize_srcu(&head->srcu); | |
| 431 | + kblockd_schedule_work(&head->requeue_work); | |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | 434 | static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data, |
| @@ -483,14 +483,12 @@ static inline bool nvme_state_is_live(enum nvme_ana_state state) · 48 unmodified lines | ||
| 483 | 483 | static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc, |
| 484 | 484 | struct nvme_ns *ns) |
| 485 | 485 | { |
| 486 | − mutex_lock(&ns->head->lock); | |
| 487 | 486 | ns->ana_grpid = le32_to_cpu(desc->grpid); |
| 488 | 487 | ns->ana_state = desc->state; |
| 489 | 488 | clear_bit(NVME_NS_ANA_PENDING, &ns->flags); |
| 490 | 489 | |
| 491 | 490 | if (nvme_state_is_live(ns->ana_state)) |
| 492 | 491 | nvme_mpath_set_live(ns); |
| 493 | − mutex_unlock(&ns->head->lock); | |
| 494 | 492 | } |
| 495 | 493 | |
| 496 | 494 | static int nvme_update_ana_state(struct nvme_ctrl *ctrl, |
| @@ -640,38 +638,45 @@ static ssize_t ana_state_show(struct device *dev, struct device_attribute *attr, · 143 unmodified lines | ||
| 640 | 638 | } |
| 641 | 639 | DEVICE_ATTR_RO(ana_state); |
| 642 | 640 | |
| 643 | −static int nvme_set_ns_ana_state(struct nvme_ctrl *ctrl, | |
| 641 | +static int nvme_lookup_ana_group_desc(struct nvme_ctrl *ctrl, | |
| 644 | 642 | struct nvme_ana_group_desc *desc, void *data) |
| 645 | 643 | { |
| 646 | − struct nvme_ns *ns = data; | |
| 644 | + struct nvme_ana_group_desc *dst = data; | |
| 647 | 645 | |
| 648 | − if (ns->ana_grpid == le32_to_cpu(desc->grpid)) { | |
| 649 | − nvme_update_ns_ana_state(desc, ns); | |
| 650 | − return -ENXIO; /* just break out of the loop */ | |
| 651 | − } | |
| 646 | + if (desc->grpid != dst->grpid) | |
| 647 | + return 0; | |
| 652 | 648 | |
| 653 | − return 0; | |
| 649 | + *dst = *desc; | |
| 650 | + return -ENXIO; /* just break out of the loop */ | |
| 654 | 651 | } |
| 655 | 652 | |
| 656 | 653 | void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id) |
| 657 | 654 | { |
| 658 | 655 | if (nvme_ctrl_use_ana(ns->ctrl)) { |
| 656 | + struct nvme_ana_group_desc desc = { | |
| 657 | + .grpid = id->anagrpid, | |
| 658 | + .state = 0, | |
| 659 | + }; | |
| 660 | + | |
| 659 | 661 | mutex_lock(&ns->ctrl->ana_lock); |
| 660 | 662 | ns->ana_grpid = le32_to_cpu(id->anagrpid); |
| 661 | − nvme_parse_ana_log(ns->ctrl, ns, nvme_set_ns_ana_state); | |
| 663 | + nvme_parse_ana_log(ns->ctrl, &desc, nvme_lookup_ana_group_desc); | |
| 662 | 664 | mutex_unlock(&ns->ctrl->ana_lock); |
| 665 | + if (desc.state) { | |
| 666 | + /* found the group desc: update */ | |
| 667 | + nvme_update_ns_ana_state(&desc, ns); | |
| 668 | + } | |
| 663 | 669 | } else { |
| 664 | − mutex_lock(&ns->head->lock); | |
| 665 | 670 | ns->ana_state = NVME_ANA_OPTIMIZED; |
| 666 | 671 | nvme_mpath_set_live(ns); |
| 667 | − mutex_unlock(&ns->head->lock); | |
| 668 | 672 | } |
| 669 | 673 | |
| 670 | 674 | if (bdi_cap_stable_pages_required(ns->queue->backing_dev_info)) { |
| 671 | − struct backing_dev_info *info = | |
| 672 | − ns->head->disk->queue->backing_dev_info; | |
| 675 | + struct gendisk *disk = ns->head->disk; | |
| 673 | 676 | |
| 674 | − info->capabilities |= BDI_CAP_STABLE_WRITES; | |
| 677 | + if (disk) | |
| 678 | + disk->queue->backing_dev_info->capabilities |= | |
| 679 | + BDI_CAP_STABLE_WRITES; | |
| 675 | 680 | } |
| 676 | 681 | } |
| 677 | 682 | |
| @@ -686,6 +691,14 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) · 8 unmodified lines | ||
| 686 | 691 | kblockd_schedule_work(&head->requeue_work); |
| 687 | 692 | flush_work(&head->requeue_work); |
| 688 | 693 | blk_cleanup_queue(head->disk->queue); |
| 694 | + if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { | |
| 695 | + /* | |
| 696 | + * if device_add_disk wasn't called, prevent | |
| 697 | + * disk release to put a bogus reference on the | |
| 698 | + * request queue | |
| 699 | + */ | |
| 700 | + head->disk->queue = NULL; | |
| 701 | + } | |
| 689 | 702 | put_disk(head->disk); |
| 690 | 703 | } |
| 691 | 704 | |
| @@ -364,6 +364,8 @@ struct nvme_ns_head { · 363 unmodified lines | ||
| 364 | 364 | spinlock_t requeue_lock; |
| 365 | 365 | struct work_struct requeue_work; |
| 366 | 366 | struct mutex lock; |
| 367 | + unsigned long flags; | |
| 368 | +#define NVME_NSHEAD_DISK_LIVE 0 | |
| 367 | 369 | struct nvme_ns __rcu *current_path[]; |
| 368 | 370 | #endif |
| 369 | 371 | }; |
| @@ -1593,7 +1593,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) · 1592 unmodified lines | ||
| 1593 | 1593 | |
| 1594 | 1594 | dev->admin_tagset.queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 1595 | 1595 | dev->admin_tagset.timeout = ADMIN_TIMEOUT; |
| 1596 | − dev->admin_tagset.numa_node = dev_to_node(dev->dev); | |
| 1596 | + dev->admin_tagset.numa_node = dev->ctrl.numa_node; | |
| 1597 | 1597 | dev->admin_tagset.cmd_size = sizeof(struct nvme_iod); |
| 1598 | 1598 | dev->admin_tagset.flags = BLK_MQ_F_NO_SCHED; |
| 1599 | 1599 | dev->admin_tagset.driver_data = dev; |
| @@ -1669,6 +1669,8 @@ static int nvme_pci_configure_admin_queue(struct nvme_dev *dev) · 69 unmodified lines | ||
| 1669 | 1669 | if (result) |
| 1670 | 1670 | return result; |
| 1671 | 1671 | |
| 1672 | + dev->ctrl.numa_node = dev_to_node(dev->dev); | |
| 1673 | + | |
| 1672 | 1674 | nvmeq = &dev->queues[0]; |
| 1673 | 1675 | aqa = nvmeq->q_depth - 1; |
| 1674 | 1676 | aqa |= aqa << 16; |
| @@ -2257,7 +2259,7 @@ static void nvme_dev_add(struct nvme_dev *dev) · 582 unmodified lines | ||
| 2257 | 2259 | if (dev->io_queues[HCTX_TYPE_POLL]) |
| 2258 | 2260 | dev->tagset.nr_maps++; |
| 2259 | 2261 | dev->tagset.timeout = NVME_IO_TIMEOUT; |
| 2260 | − dev->tagset.numa_node = dev_to_node(dev->dev); | |
| 2262 | + dev->tagset.numa_node = dev->ctrl.numa_node; | |
| 2261 | 2263 | dev->tagset.queue_depth = |
| 2262 | 2264 | min_t(int, dev->q_depth, BLK_MQ_MAX_DEPTH) - 1; |
| 2263 | 2265 | dev->tagset.cmd_size = sizeof(struct nvme_iod); |
| @@ -470,7 +470,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue) · 469 unmodified lines | ||
| 470 | 470 | * Spread I/O queues completion vectors according their queue index. |
| 471 | 471 | * Admin queues can always go on completion vector 0. |
| 472 | 472 | */ |
| 473 | − comp_vector = idx == 0 ? idx : idx - 1; | |
| 473 | + comp_vector = (idx == 0 ? idx : idx - 1) % ibdev->num_comp_vectors; | |
| 474 | 474 | |
| 475 | 475 | /* Polling queues need direct cq polling context */ |
| 476 | 476 | if (nvme_rdma_poll_queue(queue)) |
| @@ -1532,7 +1532,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl, · 1531 unmodified lines | ||
| 1532 | 1532 | set->ops = &nvme_tcp_admin_mq_ops; |
| 1533 | 1533 | set->queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 1534 | 1534 | set->reserved_tags = 2; /* connect + keep-alive */ |
| 1535 | − set->numa_node = NUMA_NO_NODE; | |
| 1535 | + set->numa_node = nctrl->numa_node; | |
| 1536 | 1536 | set->flags = BLK_MQ_F_BLOCKING; |
| 1537 | 1537 | set->cmd_size = sizeof(struct nvme_tcp_request); |
| 1538 | 1538 | set->driver_data = ctrl; |
| @@ -1544,7 +1544,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl, · 5 unmodified lines | ||
| 1544 | 1544 | set->ops = &nvme_tcp_mq_ops; |
| 1545 | 1545 | set->queue_depth = nctrl->sqsize + 1; |
| 1546 | 1546 | set->reserved_tags = 1; /* fabric connect */ |
| 1547 | − set->numa_node = NUMA_NO_NODE; | |
| 1547 | + set->numa_node = nctrl->numa_node; | |
| 1548 | 1548 | set->flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING; |
| 1549 | 1549 | set->cmd_size = sizeof(struct nvme_tcp_request); |
| 1550 | 1550 | set->driver_data = ctrl; |
| @@ -340,7 +340,7 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl) · 339 unmodified lines | ||
| 340 | 340 | ctrl->admin_tag_set.ops = &nvme_loop_admin_mq_ops; |
| 341 | 341 | ctrl->admin_tag_set.queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 342 | 342 | ctrl->admin_tag_set.reserved_tags = 2; /* connect + keep-alive */ |
| 343 | − ctrl->admin_tag_set.numa_node = NUMA_NO_NODE; | |
| 343 | + ctrl->admin_tag_set.numa_node = ctrl->ctrl.numa_node; | |
| 344 | 344 | ctrl->admin_tag_set.cmd_size = sizeof(struct nvme_loop_iod) + |
| 345 | 345 | NVME_INLINE_SG_CNT * sizeof(struct scatterlist); |
| 346 | 346 | ctrl->admin_tag_set.driver_data = ctrl; |
| @@ -512,7 +512,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl) · 165 unmodified lines | ||
| 512 | 512 | ctrl->tag_set.ops = &nvme_loop_mq_ops; |
| 513 | 513 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; |
| 514 | 514 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ |
| 515 | − ctrl->tag_set.numa_node = NUMA_NO_NODE; | |
| 515 | + ctrl->tag_set.numa_node = ctrl->ctrl.numa_node; | |
| 516 | 516 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
| 517 | 517 | ctrl->tag_set.cmd_size = sizeof(struct nvme_loop_iod) + |
| 518 | 518 | NVME_INLINE_SG_CNT * sizeof(struct scatterlist); |
| @@ -314,10 +314,15 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) · 313 unmodified lines | ||
| 314 | 314 | child, addr); |
| 315 | 315 | |
| 316 | 316 | if (of_mdiobus_child_is_phy(child)) { |
| 317 | + /* -ENODEV is the return code that PHYLIB has | |
| 318 | + * standardized on to indicate that bus | |
| 319 | + * scanning should continue. | |
| 320 | + */ | |
| 317 | 321 | rc = of_mdiobus_register_phy(mdio, child, addr); |
| 318 | − if (rc && rc != -ENODEV) | |
| 322 | + if (!rc) | |
| 323 | + break; | |
| 324 | + if (rc != -ENODEV) | |
| 319 | 325 | goto unregister; |
| 320 | − break; | |
| 321 | 326 | } |
| 322 | 327 | } |
| 323 | 328 | } |
| @@ -33,7 +33,7 @@ void flush_cpu_work(void); · 32 unmodified lines | ||
| 33 | 33 | struct op_sample { |
| 34 | 34 | unsigned long eip; |
| 35 | 35 | unsigned long event; |
| 36 | − unsigned long data[0]; | |
| 36 | + unsigned long data[]; | |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | 39 | struct op_entry; |
| @@ -43,7 +43,7 @@ struct samsung_usb2_phy_driver { · 42 unmodified lines | ||
| 43 | 43 | struct regmap *reg_pmu; |
| 44 | 44 | struct regmap *reg_sys; |
| 45 | 45 | spinlock_t lock; |
| 46 | − struct samsung_usb2_phy_instance instances[0]; | |
| 46 | + struct samsung_usb2_phy_instance instances[]; | |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | 49 | struct samsung_usb2_common_phy { |
| @@ -824,13 +824,12 @@ int imx_pinctrl_probe(struct platform_device *pdev, · 823 unmodified lines | ||
| 824 | 824 | return -EINVAL; |
| 825 | 825 | } |
| 826 | 826 | |
| 827 | − ipctl->input_sel_base = devm_of_iomap(&pdev->dev, np, | |
| 828 | − 0, NULL); | |
| 827 | + ipctl->input_sel_base = of_iomap(np, 0); | |
| 829 | 828 | of_node_put(np); |
| 830 | − if (IS_ERR(ipctl->input_sel_base)) { | |
| 829 | + if (!ipctl->input_sel_base) { | |
| 831 | 830 | dev_err(&pdev->dev, |
| 832 | 831 | "iomuxc input select base address not found\n"); |
| 833 | − return PTR_ERR(ipctl->input_sel_base); | |
| 832 | + return -ENOMEM; | |
| 834 | 833 | } |
| 835 | 834 | } |
| 836 | 835 | } |
| @@ -126,10 +126,7 @@ static int mcp23s08_spi_regmap_init(struct mcp23s08 *mcp, struct device *dev, · 125 unmodified lines | ||
| 126 | 126 | copy->name = name; |
| 127 | 127 | |
| 128 | 128 | mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp, copy); |
| 129 | − if (IS_ERR(mcp->regmap)) | |
| 130 | − return PTR_ERR(mcp->regmap); | |
| 131 | − | |
| 132 | − return 0; | |
| 129 | + return PTR_ERR_OR_ZERO(mcp->regmap); | |
| 133 | 130 | } |
| 134 | 131 | |
| 135 | 132 | static int mcp23s08_probe(struct spi_device *spi) |
| @@ -958,7 +958,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, · 957 unmodified lines | ||
| 958 | 958 | } |
| 959 | 959 | |
| 960 | 960 | /** |
| 961 | − * smux_parse_one_pinctrl_entry() - parses a device tree mux entry | |
| 961 | + * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry | |
| 962 | 962 | * @pctldev: pin controller device |
| 963 | 963 | * @pcs: pinctrl driver instance |
| 964 | 964 | * @np: device node of the mux entry |
| @@ -367,7 +367,8 @@ static const char * const wci20_groups[] = { · 366 unmodified lines | ||
| 367 | 367 | |
| 368 | 368 | static const char * const qpic_pad_groups[] = { |
| 369 | 369 | "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio9", "gpio10", |
| 370 | − "gpio11", "gpio17", | |
| 370 | + "gpio11", "gpio17", "gpio15", "gpio12", "gpio13", "gpio14", "gpio5", | |
| 371 | + "gpio6", "gpio7", "gpio8", | |
| 371 | 372 | }; |
| 372 | 373 | |
| 373 | 374 | static const char * const burn0_groups[] = { |
| @@ -170,6 +170,7 @@ struct pmic_gpio_state { · 169 unmodified lines | ||
| 170 | 170 | struct regmap *map; |
| 171 | 171 | struct pinctrl_dev *ctrl; |
| 172 | 172 | struct gpio_chip chip; |
| 173 | + struct irq_chip irq; | |
| 173 | 174 | }; |
| 174 | 175 | |
| 175 | 176 | static const struct pinconf_generic_params pmic_gpio_bindings[] = { |
| @@ -917,16 +918,6 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state, · 741 unmodified lines | ||
| 917 | 918 | return 0; |
| 918 | 919 | } |
| 919 | 920 | |
| 920 | −static struct irq_chip pmic_gpio_irq_chip = { | |
| 921 | − .name = "spmi-gpio", | |
| 922 | − .irq_ack = irq_chip_ack_parent, | |
| 923 | − .irq_mask = irq_chip_mask_parent, | |
| 924 | − .irq_unmask = irq_chip_unmask_parent, | |
| 925 | − .irq_set_type = irq_chip_set_type_parent, | |
| 926 | − .irq_set_wake = irq_chip_set_wake_parent, | |
| 927 | − .flags = IRQCHIP_MASK_ON_SUSPEND, | |
| 928 | −}; | |
| 929 | − | |
| 930 | 921 | static int pmic_gpio_domain_translate(struct irq_domain *domain, |
| 931 | 922 | struct irq_fwspec *fwspec, |
| 932 | 923 | unsigned long *hwirq, |
| @@ -1053,8 +1044,16 @@ static int pmic_gpio_probe(struct platform_device *pdev) · 120 unmodified lines | ||
| 1053 | 1044 | if (!parent_domain) |
| 1054 | 1045 | return -ENXIO; |
| 1055 | 1046 | |
| 1047 | + state->irq.name = "spmi-gpio", | |
| 1048 | + state->irq.irq_ack = irq_chip_ack_parent, | |
| 1049 | + state->irq.irq_mask = irq_chip_mask_parent, | |
| 1050 | + state->irq.irq_unmask = irq_chip_unmask_parent, | |
| 1051 | + state->irq.irq_set_type = irq_chip_set_type_parent, | |
| 1052 | + state->irq.irq_set_wake = irq_chip_set_wake_parent, | |
| 1053 | + state->irq.flags = IRQCHIP_MASK_ON_SUSPEND, | |
| 1054 | + | |
| 1056 | 1055 | girq = &state->chip.irq; |
| 1057 | − girq->chip = &pmic_gpio_irq_chip; | |
| 1056 | + girq->chip = &state->irq; | |
| 1058 | 1057 | girq->default_type = IRQ_TYPE_NONE; |
| 1059 | 1058 | girq->handler = handle_level_irq; |
| 1060 | 1059 | girq->fwnode = of_node_to_fwnode(state->dev->of_node); |
| @@ -731,8 +731,8 @@ static int tegra_pinctrl_resume(struct device *dev) · 730 unmodified lines | ||
| 731 | 731 | } |
| 732 | 732 | |
| 733 | 733 | const struct dev_pm_ops tegra_pinctrl_pm = { |
| 734 | − .suspend = &tegra_pinctrl_suspend, | |
| 735 | − .resume = &tegra_pinctrl_resume | |
| 734 | + .suspend_noirq = &tegra_pinctrl_suspend, | |
| 735 | + .resume_noirq = &tegra_pinctrl_resume | |
| 736 | 736 | }; |
| 737 | 737 | |
| 738 | 738 | static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx) |
| @@ -39,7 +39,7 @@ struct rio_id_table { · 38 unmodified lines | ||
| 39 | 39 | u16 start; /* logical minimal id */ |
| 40 | 40 | u32 max; /* max number of IDs in table */ |
| 41 | 41 | spinlock_t lock; |
| 42 | − unsigned long table[0]; | |
| 42 | + unsigned long table[]; | |
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | 45 | static int next_destid = 0; |
| @@ -684,7 +684,7 @@ config REGULATOR_MT6323 · 683 unmodified lines | ||
| 684 | 684 | |
| 685 | 685 | config REGULATOR_MT6358 |
| 686 | 686 | tristate "MediaTek MT6358 PMIC" |
| 687 | − depends on MFD_MT6397 && BROKEN | |
| 687 | + depends on MFD_MT6397 | |
| 688 | 688 | help |
| 689 | 689 | Say y here to select this option to enable the power regulator of |
| 690 | 690 | MediaTek MT6358 PMIC. |
| @@ -512,7 +512,6 @@ static const struct da9063_regulator_info da9063_regulator_info[] = { · 511 unmodified lines | ||
| 512 | 512 | }, |
| 513 | 513 | { |
| 514 | 514 | DA9063_LDO(DA9063, LDO9, 950, 50, 3600), |
| 515 | − .suspend = BFIELD(DA9063_REG_LDO9_CONT, DA9063_VLDO9_SEL), | |
| 516 | 515 | }, |
| 517 | 516 | { |
| 518 | 517 | DA9063_LDO(DA9063, LDO11, 900, 50, 3600), |
| @@ -486,7 +486,7 @@ int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev, · 485 unmodified lines | ||
| 486 | 486 | continue; |
| 487 | 487 | } |
| 488 | 488 | |
| 489 | − ret = selector + sel; | |
| 489 | + ret = selector + sel - range->min_sel; | |
| 490 | 490 | |
| 491 | 491 | voltage = rdev->desc->ops->list_voltage(rdev, ret); |
| 492 | 492 | |
| @@ -209,6 +209,19 @@ static const struct regulator_ops pfuze100_swb_regulator_ops = { · 208 unmodified lines | ||
| 209 | 209 | |
| 210 | 210 | }; |
| 211 | 211 | |
| 212 | +static const struct regulator_ops pfuze3000_sw_regulator_ops = { | |
| 213 | + .enable = regulator_enable_regmap, | |
| 214 | + .disable = regulator_disable_regmap, | |
| 215 | + .is_enabled = regulator_is_enabled_regmap, | |
| 216 | + .list_voltage = regulator_list_voltage_table, | |
| 217 | + .map_voltage = regulator_map_voltage_ascend, | |
| 218 | + .set_voltage_sel = regulator_set_voltage_sel_regmap, | |
| 219 | + .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
| 220 | + .set_voltage_time_sel = regulator_set_voltage_time_sel, | |
| 221 | + .set_ramp_delay = pfuze100_set_ramp_delay, | |
| 222 | + | |
| 223 | +}; | |
| 224 | + | |
| 212 | 225 | #define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \ |
| 213 | 226 | [_chip ## _ ## _name] = { \ |
| 214 | 227 | .desc = { \ |
| @@ -318,23 +331,28 @@ static const struct regulator_ops pfuze100_swb_regulator_ops = { · 103 unmodified lines | ||
| 318 | 331 | .stby_mask = 0x20, \ |
| 319 | 332 | } |
| 320 | 333 | |
| 321 | − | |
| 322 | −#define PFUZE3000_SW2_REG(_chip, _name, base, min, max, step) { \ | |
| 323 | − .desc = { \ | |
| 324 | − .name = #_name,\ | |
| 325 | − .n_voltages = ((max) - (min)) / (step) + 1, \ | |
| 326 | − .ops = &pfuze100_sw_regulator_ops, \ | |
| 327 | − .type = REGULATOR_VOLTAGE, \ | |
| 328 | − .id = _chip ## _ ## _name, \ | |
| 329 | − .owner = THIS_MODULE, \ | |
| 330 | − .min_uV = (min), \ | |
| 331 | − .uV_step = (step), \ | |
| 332 | − .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ | |
| 333 | − .vsel_mask = 0x7, \ | |
| 334 | − }, \ | |
| 335 | − .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ | |
| 336 | − .stby_mask = 0x7, \ | |
| 337 | −} | |
| 334 | +/* No linar case for the some switches of PFUZE3000 */ | |
| 335 | +#define PFUZE3000_SW_REG(_chip, _name, base, mask, voltages) \ | |
| 336 | + [_chip ## _ ## _name] = { \ | |
| 337 | + .desc = { \ | |
| 338 | + .name = #_name, \ | |
| 339 | + .n_voltages = ARRAY_SIZE(voltages), \ | |
| 340 | + .ops = &pfuze3000_sw_regulator_ops, \ | |
| 341 | + .type = REGULATOR_VOLTAGE, \ | |
| 342 | + .id = _chip ## _ ## _name, \ | |
| 343 | + .owner = THIS_MODULE, \ | |
| 344 | + .volt_table = voltages, \ | |
| 345 | + .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ | |
| 346 | + .vsel_mask = (mask), \ | |
| 347 | + .enable_reg = (base) + PFUZE100_MODE_OFFSET, \ | |
| 348 | + .enable_mask = 0xf, \ | |
| 349 | + .enable_val = 0x8, \ | |
| 350 | + .enable_time = 500, \ | |
| 351 | + }, \ | |
| 352 | + .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ | |
| 353 | + .stby_mask = (mask), \ | |
| 354 | + .sw_reg = true, \ | |
| 355 | + } | |
| 338 | 356 | |
| 339 | 357 | #define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \ |
| 340 | 358 | .desc = { \ |
| @@ -391,9 +409,9 @@ static struct pfuze_regulator pfuze200_regulators[] = { · 50 unmodified lines | ||
| 391 | 409 | }; |
| 392 | 410 | |
| 393 | 411 | static struct pfuze_regulator pfuze3000_regulators[] = { |
| 394 | − PFUZE100_SWB_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), | |
| 412 | + PFUZE3000_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), | |
| 395 | 413 | PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000), |
| 396 | − PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), | |
| 414 | + PFUZE3000_SW_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), | |
| 397 | 415 | PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), |
| 398 | 416 | PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst), |
| 399 | 417 | PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), |
| @@ -407,8 +425,8 @@ static struct pfuze_regulator pfuze3000_regulators[] = { · 7 unmodified lines | ||
| 407 | 425 | }; |
| 408 | 426 | |
| 409 | 427 | static struct pfuze_regulator pfuze3001_regulators[] = { |
| 410 | − PFUZE100_SWB_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), | |
| 411 | − PFUZE100_SWB_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), | |
| 428 | + PFUZE3000_SW_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), | |
| 429 | + PFUZE3000_SW_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), | |
| 412 | 430 | PFUZE3000_SW3_REG(PFUZE3001, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), |
| 413 | 431 | PFUZE100_SWB_REG(PFUZE3001, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), |
| 414 | 432 | PFUZE100_VGEN_REG(PFUZE3001, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000), |
| @@ -182,10 +182,9 @@ enum qdio_irq_poll_states { · 181 unmodified lines | ||
| 182 | 182 | }; |
| 183 | 183 | |
| 184 | 184 | struct qdio_input_q { |
| 185 | − /* first ACK'ed buffer */ | |
| 186 | − int ack_start; | |
| 187 | − /* how many SBALs are acknowledged */ | |
| 188 | − int ack_count; | |
| 185 | + /* Batch of SBALs that we processed while polling the queue: */ | |
| 186 | + unsigned int batch_start; | |
| 187 | + unsigned int batch_count; | |
| 189 | 188 | /* last time of noticing incoming data */ |
| 190 | 189 | u64 timestamp; |
| 191 | 190 | }; |
| @@ -110,8 +110,8 @@ static int qstat_show(struct seq_file *m, void *v) · 109 unmodified lines | ||
| 110 | 110 | seq_printf(m, "nr_used: %d ftc: %d\n", |
| 111 | 111 | atomic_read(&q->nr_buf_used), q->first_to_check); |
| 112 | 112 | if (q->is_input_q) { |
| 113 | − seq_printf(m, "ack start: %d ack count: %d\n", | |
| 114 | − q->u.in.ack_start, q->u.in.ack_count); | |
| 113 | + seq_printf(m, "batch start: %u batch count: %u\n", | |
| 114 | + q->u.in.batch_start, q->u.in.batch_count); | |
| 115 | 115 | seq_printf(m, "DSCI: %x IRQs disabled: %u\n", |
| 116 | 116 | *(u8 *)q->irq_ptr->dsci, |
| 117 | 117 | test_bit(QDIO_IRQ_DISABLED, |
| @@ -254,10 +254,17 @@ static inline int set_buf_states(struct qdio_q *q, int bufnr, · 253 unmodified lines | ||
| 254 | 254 | if (is_qebsm(q)) |
| 255 | 255 | return qdio_do_sqbs(q, state, bufnr, count); |
| 256 | 256 | |
| 257 | + /* Ensure that all preceding changes to the SBALs are visible: */ | |
| 258 | + mb(); | |
| 259 | + | |
| 257 | 260 | for (i = 0; i < count; i++) { |
| 258 | − xchg(&q->slsb.val[bufnr], state); | |
| 261 | + WRITE_ONCE(q->slsb.val[bufnr], state); | |
| 259 | 262 | bufnr = next_buf(bufnr); |
| 260 | 263 | } |
| 264 | + | |
| 265 | + /* Make our SLSB changes visible: */ | |
| 266 | + mb(); | |
| 267 | + | |
| 261 | 268 | return count; |
| 262 | 269 | } |
| 263 | 270 | |
| @@ -393,15 +400,15 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, · 129 unmodified lines | ||
| 393 | 400 | |
| 394 | 401 | static inline void qdio_stop_polling(struct qdio_q *q) |
| 395 | 402 | { |
| 396 | − if (!q->u.in.ack_count) | |
| 403 | + if (!q->u.in.batch_count) | |
| 397 | 404 | return; |
| 398 | 405 | |
| 399 | 406 | qperf_inc(q, stop_polling); |
| 400 | 407 | |
| 401 | 408 | /* show the card that we are not polling anymore */ |
| 402 | − set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT, | |
| 403 | − q->u.in.ack_count); | |
| 404 | − q->u.in.ack_count = 0; | |
| 409 | + set_buf_states(q, q->u.in.batch_start, SLSB_P_INPUT_NOT_INIT, | |
| 410 | + q->u.in.batch_count); | |
| 411 | + q->u.in.batch_count = 0; | |
| 405 | 412 | } |
| 406 | 413 | |
| 407 | 414 | static inline void account_sbals(struct qdio_q *q, unsigned int count) |
| @@ -441,42 +448,13 @@ static void process_buffer_error(struct qdio_q *q, unsigned int start, · 33 unmodified lines | ||
| 441 | 448 | static inline void inbound_handle_work(struct qdio_q *q, unsigned int start, |
| 442 | 449 | int count, bool auto_ack) |
| 443 | 450 | { |
| 444 | − int new; | |
| 445 | − | |
| 446 | − if (auto_ack) { | |
| 447 | − if (!q->u.in.ack_count) { | |
| 448 | − q->u.in.ack_count = count; | |
| 449 | − q->u.in.ack_start = start; | |
| 450 | − return; | |
| 451 | − } | |
| 452 | − | |
| 453 | − /* delete the previous ACK's */ | |
| 454 | − set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT, | |
| 455 | − q->u.in.ack_count); | |
| 456 | − q->u.in.ack_count = count; | |
| 457 | − q->u.in.ack_start = start; | |
| 458 | − return; | |
| 459 | − } | |
| 460 | − | |
| 461 | − /* | |
| 462 | − * ACK the newest buffer. The ACK will be removed in qdio_stop_polling | |
| 463 | − * or by the next inbound run. | |
| 464 | − */ | |
| 465 | − new = add_buf(start, count - 1); | |
| 466 | − set_buf_state(q, new, SLSB_P_INPUT_ACK); | |
| 467 | − | |
| 468 | − /* delete the previous ACKs */ | |
| 469 | − if (q->u.in.ack_count) | |
| 470 | − set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT, | |
| 471 | − q->u.in.ack_count); | |
| 451 | + /* ACK the newest SBAL: */ | |
| 452 | + if (!auto_ack) | |
| 453 | + set_buf_state(q, add_buf(start, count - 1), SLSB_P_INPUT_ACK); | |
| 472 | 454 | |
| 473 | − q->u.in.ack_count = 1; | |
| 474 | − q->u.in.ack_start = new; | |
| 475 | − count--; | |
| 476 | − if (!count) | |
| 477 | − return; | |
| 478 | − /* need to change ALL buffers to get more interrupts */ | |
| 479 | − set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count); | |
| 455 | + if (!q->u.in.batch_count) | |
| 456 | + q->u.in.batch_start = start; | |
| 457 | + q->u.in.batch_count += count; | |
| 480 | 458 | } |
| 481 | 459 | |
| 482 | 460 | static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start) |
| @@ -525,15 +503,18 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start) · 42 unmodified lines | ||
| 525 | 503 | account_sbals_error(q, count); |
| 526 | 504 | return count; |
| 527 | 505 | case SLSB_CU_INPUT_EMPTY: |
| 528 | − case SLSB_P_INPUT_NOT_INIT: | |
| 529 | − case SLSB_P_INPUT_ACK: | |
| 530 | 506 | if (q->irq_ptr->perf_stat_enabled) |
| 531 | 507 | q->q_stats.nr_sbal_nop++; |
| 532 | 508 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop:%1d %#02x", |
| 533 | 509 | q->nr, start); |
| 534 | 510 | return 0; |
| 511 | + case SLSB_P_INPUT_NOT_INIT: | |
| 512 | + case SLSB_P_INPUT_ACK: | |
| 513 | + /* We should never see this state, throw a WARN: */ | |
| 535 | 514 | default: |
| 536 | − WARN_ON_ONCE(1); | |
| 515 | + dev_WARN_ONCE(&q->irq_ptr->cdev->dev, 1, | |
| 516 | + "found state %#x at index %u on queue %u\n", | |
| 517 | + state, start, q->nr); | |
| 537 | 518 | return 0; |
| 538 | 519 | } |
| 539 | 520 | } |
| @@ -738,11 +719,14 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start) · 198 unmodified lines | ||
| 738 | 719 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", |
| 739 | 720 | q->nr); |
| 740 | 721 | return 0; |
| 741 | − case SLSB_P_OUTPUT_NOT_INIT: | |
| 742 | 722 | case SLSB_P_OUTPUT_HALTED: |
| 743 | 723 | return 0; |
| 724 | + case SLSB_P_OUTPUT_NOT_INIT: | |
| 725 | + /* We should never see this state, throw a WARN: */ | |
| 744 | 726 | default: |
| 745 | − WARN_ON_ONCE(1); | |
| 727 | + dev_WARN_ONCE(&q->irq_ptr->cdev->dev, 1, | |
| 728 | + "found state %#x at index %u on queue %u\n", | |
| 729 | + state, start, q->nr); | |
| 746 | 730 | return 0; |
| 747 | 731 | } |
| 748 | 732 | } |
| @@ -938,10 +922,10 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) · 189 unmodified lines | ||
| 938 | 922 | } |
| 939 | 923 | } |
| 940 | 924 | |
| 941 | −static void qdio_handle_activate_check(struct ccw_device *cdev, | |
| 942 | − unsigned long intparm, int cstat, int dstat) | |
| 925 | +static void qdio_handle_activate_check(struct qdio_irq *irq_ptr, | |
| 926 | + unsigned long intparm, int cstat, | |
| 927 | + int dstat) | |
| 943 | 928 | { |
| 944 | − struct qdio_irq *irq_ptr = cdev->private->qdio_data; | |
| 945 | 929 | struct qdio_q *q; |
| 946 | 930 | |
| 947 | 931 | DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no); |
| @@ -968,11 +952,9 @@ no_handler: · 20 unmodified lines | ||
| 968 | 952 | lgr_info_log(); |
| 969 | 953 | } |
| 970 | 954 | |
| 971 | −static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, | |
| 955 | +static void qdio_establish_handle_irq(struct qdio_irq *irq_ptr, int cstat, | |
| 972 | 956 | int dstat) |
| 973 | 957 | { |
| 974 | − struct qdio_irq *irq_ptr = cdev->private->qdio_data; | |
| 975 | − | |
| 976 | 958 | DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq"); |
| 977 | 959 | |
| 978 | 960 | if (cstat) |
| @@ -1019,7 +1001,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, · 40 unmodified lines | ||
| 1019 | 1001 | |
| 1020 | 1002 | switch (irq_ptr->state) { |
| 1021 | 1003 | case QDIO_IRQ_STATE_INACTIVE: |
| 1022 | − qdio_establish_handle_irq(cdev, cstat, dstat); | |
| 1004 | + qdio_establish_handle_irq(irq_ptr, cstat, dstat); | |
| 1023 | 1005 | break; |
| 1024 | 1006 | case QDIO_IRQ_STATE_CLEANUP: |
| 1025 | 1007 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); |
| @@ -1031,7 +1013,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, · 5 unmodified lines | ||
| 1031 | 1013 | return; |
| 1032 | 1014 | } |
| 1033 | 1015 | if (cstat || dstat) |
| 1034 | − qdio_handle_activate_check(cdev, intparm, cstat, | |
| 1016 | + qdio_handle_activate_check(irq_ptr, intparm, cstat, | |
| 1035 | 1017 | dstat); |
| 1036 | 1018 | break; |
| 1037 | 1019 | case QDIO_IRQ_STATE_STOPPED: |
| @@ -1446,12 +1428,12 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags, · 408 unmodified lines | ||
| 1446 | 1428 | |
| 1447 | 1429 | qperf_inc(q, inbound_call); |
| 1448 | 1430 | |
| 1449 | − /* If any ACKed SBALs are returned to HW, adjust ACK tracking: */ | |
| 1450 | − overlap = min(count - sub_buf(q->u.in.ack_start, bufnr), | |
| 1451 | − q->u.in.ack_count); | |
| 1431 | + /* If any processed SBALs are returned to HW, adjust our tracking: */ | |
| 1432 | + overlap = min_t(int, count - sub_buf(q->u.in.batch_start, bufnr), | |
| 1433 | + q->u.in.batch_count); | |
| 1452 | 1434 | if (overlap > 0) { |
| 1453 | − q->u.in.ack_start = add_buf(q->u.in.ack_start, overlap); | |
| 1454 | − q->u.in.ack_count -= overlap; | |
| 1435 | + q->u.in.batch_start = add_buf(q->u.in.batch_start, overlap); | |
| 1436 | + q->u.in.batch_count -= overlap; | |
| 1455 | 1437 | } |
| 1456 | 1438 | |
| 1457 | 1439 | count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count); |
| @@ -1535,12 +1517,11 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags, · 77 unmodified lines | ||
| 1535 | 1517 | int do_QDIO(struct ccw_device *cdev, unsigned int callflags, |
| 1536 | 1518 | int q_nr, unsigned int bufnr, unsigned int count) |
| 1537 | 1519 | { |
| 1538 | − struct qdio_irq *irq_ptr; | |
| 1520 | + struct qdio_irq *irq_ptr = cdev->private->qdio_data; | |
| 1539 | 1521 | |
| 1540 | 1522 | if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q) |
| 1541 | 1523 | return -EINVAL; |
| 1542 | 1524 | |
| 1543 | − irq_ptr = cdev->private->qdio_data; | |
| 1544 | 1525 | if (!irq_ptr) |
| 1545 | 1526 | return -ENODEV; |
| 1546 | 1527 | |
| @@ -195,11 +195,10 @@ static inline struct ep11_cprb *alloc_cprb(size_t payload_len) · 194 unmodified lines | ||
| 195 | 195 | size_t len = sizeof(struct ep11_cprb) + payload_len; |
| 196 | 196 | struct ep11_cprb *cprb; |
| 197 | 197 | |
| 198 | − cprb = kmalloc(len, GFP_KERNEL); | |
| 198 | + cprb = kzalloc(len, GFP_KERNEL); | |
| 199 | 199 | if (!cprb) |
| 200 | 200 | return NULL; |
| 201 | 201 | |
| 202 | − memset(cprb, 0, len); | |
| 203 | 202 | cprb->cprb_len = sizeof(struct ep11_cprb); |
| 204 | 203 | cprb->cprb_ver_id = 0x04; |
| 205 | 204 | memcpy(cprb->func_id, "T4", 2); |
| @@ -4544,9 +4544,6 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, · 4543 unmodified lines | ||
| 4544 | 4544 | int fallback = *(int *)reply->param; |
| 4545 | 4545 | |
| 4546 | 4546 | QETH_CARD_TEXT(card, 4, "setaccb"); |
| 4547 | − if (cmd->hdr.return_code) | |
| 4548 | − return -EIO; | |
| 4549 | − qeth_setadpparms_inspect_rc(cmd); | |
| 4550 | 4547 | |
| 4551 | 4548 | access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; |
| 4552 | 4549 | QETH_CARD_TEXT_(card, 2, "rc=%d", |
| @@ -4556,7 +4553,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, · 3 unmodified lines | ||
| 4556 | 4553 | QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%#x) on device %x: %#x\n", |
| 4557 | 4554 | access_ctrl_req->subcmd_code, CARD_DEVID(card), |
| 4558 | 4555 | cmd->data.setadapterparms.hdr.return_code); |
| 4559 | − switch (cmd->data.setadapterparms.hdr.return_code) { | |
| 4556 | + switch (qeth_setadpparms_inspect_rc(cmd)) { | |
| 4560 | 4557 | case SET_ACCESS_CTRL_RC_SUCCESS: |
| 4561 | 4558 | if (card->options.isolation == ISOLATION_MODE_NONE) { |
| 4562 | 4559 | dev_info(&card->gdev->dev, |
| @@ -6840,9 +6837,11 @@ netdev_features_t qeth_features_check(struct sk_buff *skb, · 2277 unmodified lines | ||
| 6840 | 6837 | struct net_device *dev, |
| 6841 | 6838 | netdev_features_t features) |
| 6842 | 6839 | { |
| 6840 | + struct qeth_card *card = dev->ml_priv; | |
| 6841 | + | |
| 6843 | 6842 | /* Traffic with local next-hop is not eligible for some offloads: */ |
| 6844 | − if (skb->ip_summed == CHECKSUM_PARTIAL) { | |
| 6845 | − struct qeth_card *card = dev->ml_priv; | |
| 6843 | + if (skb->ip_summed == CHECKSUM_PARTIAL && | |
| 6844 | + card->options.isolation != ISOLATION_MODE_FWD) { | |
| 6846 | 6845 | netdev_features_t restricted = 0; |
| 6847 | 6846 | |
| 6848 | 6847 | if (skb_is_gso(skb) && !netif_needs_gso(skb, features)) |
| @@ -577,7 +577,10 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act) · 576 unmodified lines | ||
| 577 | 577 | ZFCP_STATUS_ERP_TIMEDOUT)) { |
| 578 | 578 | req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; |
| 579 | 579 | zfcp_dbf_rec_run("erscf_1", act); |
| 580 | − req->erp_action = NULL; | |
| 580 | + /* lock-free concurrent access with | |
| 581 | + * zfcp_erp_timeout_handler() | |
| 582 | + */ | |
| 583 | + WRITE_ONCE(req->erp_action, NULL); | |
| 581 | 584 | } |
| 582 | 585 | if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) |
| 583 | 586 | zfcp_dbf_rec_run("erscf_2", act); |
| @@ -613,8 +616,14 @@ void zfcp_erp_notify(struct zfcp_erp_action *erp_action, unsigned long set_mask) · 29 unmodified lines | ||
| 613 | 616 | void zfcp_erp_timeout_handler(struct timer_list *t) |
| 614 | 617 | { |
| 615 | 618 | struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer); |
| 616 | − struct zfcp_erp_action *act = fsf_req->erp_action; | |
| 619 | + struct zfcp_erp_action *act; | |
| 617 | 620 | |
| 621 | + if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) | |
| 622 | + return; | |
| 623 | + /* lock-free concurrent access with zfcp_erp_strategy_check_fsfreq() */ | |
| 624 | + act = READ_ONCE(fsf_req->erp_action); | |
| 625 | + if (!act) | |
| 626 | + return; | |
| 618 | 627 | zfcp_erp_notify(act, ZFCP_STATUS_ERP_TIMEDOUT); |
| 619 | 628 | } |
| 620 | 629 | |
| @@ -1372,27 +1372,6 @@ static struct ccw_device_id virtio_ids[] = { · 1371 unmodified lines | ||
| 1372 | 1372 | {}, |
| 1373 | 1373 | }; |
| 1374 | 1374 | |
| 1375 | −#ifdef CONFIG_PM_SLEEP | |
| 1376 | −static int virtio_ccw_freeze(struct ccw_device *cdev) | |
| 1377 | −{ | |
| 1378 | − struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev); | |
| 1379 | − | |
| 1380 | − return virtio_device_freeze(&vcdev->vdev); | |
| 1381 | −} | |
| 1382 | − | |
| 1383 | −static int virtio_ccw_restore(struct ccw_device *cdev) | |
| 1384 | −{ | |
| 1385 | − struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev); | |
| 1386 | − int ret; | |
| 1387 | − | |
| 1388 | − ret = virtio_ccw_set_transport_rev(vcdev); | |
| 1389 | − if (ret) | |
| 1390 | − return ret; | |
| 1391 | − | |
| 1392 | − return virtio_device_restore(&vcdev->vdev); | |
| 1393 | −} | |
| 1394 | −#endif | |
| 1395 | − | |
| 1396 | 1375 | static struct ccw_driver virtio_ccw_driver = { |
| 1397 | 1376 | .driver = { |
| 1398 | 1377 | .owner = THIS_MODULE, |
| @@ -1405,11 +1384,6 @@ static struct ccw_driver virtio_ccw_driver = { · 6 unmodified lines | ||
| 1405 | 1384 | .set_online = virtio_ccw_online, |
| 1406 | 1385 | .notify = virtio_ccw_cio_notify, |
| 1407 | 1386 | .int_class = IRQIO_VIR, |
| 1408 | −#ifdef CONFIG_PM_SLEEP | |
| 1409 | − .freeze = virtio_ccw_freeze, | |
| 1410 | − .thaw = virtio_ccw_restore, | |
| 1411 | − .restore = virtio_ccw_restore, | |
| 1412 | −#endif | |
| 1413 | 1387 | }; |
| 1414 | 1388 | |
| 1415 | 1389 | static int __init pure_hex(char **cp, unsigned int *val, int min_digit, |
| @@ -40,6 +40,7 @@ static struct scsi_host_template aic94xx_sht = { · 39 unmodified lines | ||
| 40 | 40 | /* .name is initialized */ |
| 41 | 41 | .name = "aic94xx", |
| 42 | 42 | .queuecommand = sas_queuecommand, |
| 43 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 43 | 44 | .target_alloc = sas_target_alloc, |
| 44 | 45 | .slave_configure = sas_slave_configure, |
| 45 | 46 | .scan_finished = asd_scan_finished, |
| @@ -1756,6 +1756,7 @@ static struct scsi_host_template sht_v1_hw = { · 1755 unmodified lines | ||
| 1756 | 1756 | .proc_name = DRV_NAME, |
| 1757 | 1757 | .module = THIS_MODULE, |
| 1758 | 1758 | .queuecommand = sas_queuecommand, |
| 1759 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 1759 | 1760 | .target_alloc = sas_target_alloc, |
| 1760 | 1761 | .slave_configure = hisi_sas_slave_configure, |
| 1761 | 1762 | .scan_finished = hisi_sas_scan_finished, |
| @@ -3532,6 +3532,7 @@ static struct scsi_host_template sht_v2_hw = { · 3531 unmodified lines | ||
| 3532 | 3532 | .proc_name = DRV_NAME, |
| 3533 | 3533 | .module = THIS_MODULE, |
| 3534 | 3534 | .queuecommand = sas_queuecommand, |
| 3535 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 3535 | 3536 | .target_alloc = sas_target_alloc, |
| 3536 | 3537 | .slave_configure = hisi_sas_slave_configure, |
| 3537 | 3538 | .scan_finished = hisi_sas_scan_finished, |
| @@ -3075,6 +3075,7 @@ static struct scsi_host_template sht_v3_hw = { · 3074 unmodified lines | ||
| 3075 | 3075 | .proc_name = DRV_NAME, |
| 3076 | 3076 | .module = THIS_MODULE, |
| 3077 | 3077 | .queuecommand = sas_queuecommand, |
| 3078 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 3078 | 3079 | .target_alloc = sas_target_alloc, |
| 3079 | 3080 | .slave_configure = hisi_sas_slave_configure, |
| 3080 | 3081 | .scan_finished = hisi_sas_scan_finished, |
| @@ -6731,6 +6731,7 @@ static struct scsi_host_template driver_template = { · 6730 unmodified lines | ||
| 6731 | 6731 | .compat_ioctl = ipr_ioctl, |
| 6732 | 6732 | #endif |
| 6733 | 6733 | .queuecommand = ipr_queuecommand, |
| 6734 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 6734 | 6735 | .eh_abort_handler = ipr_eh_abort, |
| 6735 | 6736 | .eh_device_reset_handler = ipr_eh_dev_reset, |
| 6736 | 6737 | .eh_host_reset_handler = ipr_eh_host_reset, |
| @@ -153,6 +153,7 @@ static struct scsi_host_template isci_sht = { · 152 unmodified lines | ||
| 153 | 153 | .name = DRV_NAME, |
| 154 | 154 | .proc_name = DRV_NAME, |
| 155 | 155 | .queuecommand = sas_queuecommand, |
| 156 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 156 | 157 | .target_alloc = sas_target_alloc, |
| 157 | 158 | .slave_configure = sas_slave_configure, |
| 158 | 159 | .scan_finished = isci_host_scan_finished, |
| @@ -133,8 +133,10 @@ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) · 132 unmodified lines | ||
| 133 | 133 | lockdep_assert_held(&lport->disc.disc_mutex); |
| 134 | 134 | |
| 135 | 135 | rdata = fc_rport_lookup(lport, port_id); |
| 136 | − if (rdata) | |
| 136 | + if (rdata) { | |
| 137 | + kref_put(&rdata->kref, fc_rport_destroy); | |
| 137 | 138 | return rdata; |
| 139 | + } | |
| 138 | 140 | |
| 139 | 141 | if (lport->rport_priv_size > 0) |
| 140 | 142 | rport_priv_size = lport->rport_priv_size; |
| @@ -481,10 +483,11 @@ static void fc_rport_enter_delete(struct fc_rport_priv *rdata, · 340 unmodified lines | ||
| 481 | 483 | |
| 482 | 484 | fc_rport_state_enter(rdata, RPORT_ST_DELETE); |
| 483 | 485 | |
| 484 | − kref_get(&rdata->kref); | |
| 485 | − if (rdata->event == RPORT_EV_NONE && | |
| 486 | − !queue_work(rport_event_queue, &rdata->event_work)) | |
| 487 | − kref_put(&rdata->kref, fc_rport_destroy); | |
| 486 | + if (rdata->event == RPORT_EV_NONE) { | |
| 487 | + kref_get(&rdata->kref); | |
| 488 | + if (!queue_work(rport_event_queue, &rdata->event_work)) | |
| 489 | + kref_put(&rdata->kref, fc_rport_destroy); | |
| 490 | + } | |
| 488 | 491 | |
| 489 | 492 | rdata->event = event; |
| 490 | 493 | } |
| @@ -11878,7 +11878,8 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) · 11877 unmodified lines | ||
| 11878 | 11878 | lpfc_sli4_xri_exchange_busy_wait(phba); |
| 11879 | 11879 | |
| 11880 | 11880 | /* per-phba callback de-registration for hotplug event */ |
| 11881 | − lpfc_cpuhp_remove(phba); | |
| 11881 | + if (phba->pport) | |
| 11882 | + lpfc_cpuhp_remove(phba); | |
| 11882 | 11883 | |
| 11883 | 11884 | /* Disable PCI subsystem interrupt */ |
| 11884 | 11885 | lpfc_sli4_disable_intr(phba); |
| @@ -33,6 +33,7 @@ static struct scsi_host_template mvs_sht = { · 32 unmodified lines | ||
| 33 | 33 | .module = THIS_MODULE, |
| 34 | 34 | .name = DRV_NAME, |
| 35 | 35 | .queuecommand = sas_queuecommand, |
| 36 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 36 | 37 | .target_alloc = sas_target_alloc, |
| 37 | 38 | .slave_configure = sas_slave_configure, |
| 38 | 39 | .scan_finished = mvs_scan_finished, |
| @@ -87,6 +87,7 @@ static struct scsi_host_template pm8001_sht = { · 86 unmodified lines | ||
| 87 | 87 | .module = THIS_MODULE, |
| 88 | 88 | .name = DRV_NAME, |
| 89 | 89 | .queuecommand = sas_queuecommand, |
| 90 | + .dma_need_drain = ata_scsi_dma_need_drain, | |
| 90 | 91 | .target_alloc = sas_target_alloc, |
| 91 | 92 | .slave_configure = sas_slave_configure, |
| 92 | 93 | .scan_finished = pm8001_scan_finished, |
| @@ -3496,7 +3496,9 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) · 3495 unmodified lines | ||
| 3496 | 3496 | qla2x00_clear_loop_id(fcport); |
| 3497 | 3497 | fcport->flags |= FCF_FABRIC_DEVICE; |
| 3498 | 3498 | } else if (fcport->d_id.b24 != rp->id.b24 || |
| 3499 | − fcport->scan_needed) { | |
| 3499 | + (fcport->scan_needed && | |
5 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 24 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 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 45 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 9 lines aren’t shown here.
This diff is large: its 117 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 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 37 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 13 lines aren’t shown here.
This diff is large: its 67 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 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 7 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 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 362 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 212 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 24 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 51 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 84 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 20 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 95 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 62 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 60 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 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 498 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 18 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 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 60 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 16 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 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 660 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 59 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 25 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 41 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 19 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 38 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 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 18 lines aren’t shown here.
This diff is large: its 14 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 45 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 8 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 56 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 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 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 188 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 9 lines aren’t shown here.
This diff is large: its 18 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 112 lines aren’t shown here.
This diff is large: its 286 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 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 43 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 25 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 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 170 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 71 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 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 43 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 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 228 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 195 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 18 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 23 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 83 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 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 340 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 197 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 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 67 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 51 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 291 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 103 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 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 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 31 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
Empty file added.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 32 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 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 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 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 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 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.