Unified · Split
| @@ -36,6 +36,7 @@ Andrew Morton <akpm@linux-foundation.org> · 35 unmodified lines | |||
| 36 | Andrew Murray <amurray@thegoodpenguin.co.uk> <amurray@embedded-bits.co.uk> | 36 | Andrew Murray <amurray@thegoodpenguin.co.uk> <amurray@embedded-bits.co.uk> |
| 37 | Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com> | 37 | Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com> |
| 38 | Andrew Vasquez <andrew.vasquez@qlogic.com> | 38 | Andrew Vasquez <andrew.vasquez@qlogic.com> |
| 39 | Andrey Konovalov <andreyknvl@gmail.com> <andreyknvl@google.com> | ||
| 39 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> | 40 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> |
| 40 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> | 41 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> |
| 41 | Andy Adamson <andros@citi.umich.edu> | 42 | Andy Adamson <andros@citi.umich.edu> |
| @@ -65,6 +66,8 @@ Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com> · 23 unmodified lines | |||
| 65 | Changbin Du <changbin.du@intel.com> <changbin.du@intel.com> | 66 | Changbin Du <changbin.du@intel.com> <changbin.du@intel.com> |
| 66 | Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> | 67 | Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> |
| 67 | Chao Yu <chao@kernel.org> <yuchao0@huawei.com> | 68 | Chao Yu <chao@kernel.org> <yuchao0@huawei.com> |
| 69 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessm.com> | ||
| 70 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org> | ||
| 68 | Christophe Ricard <christophe.ricard@gmail.com> | 71 | Christophe Ricard <christophe.ricard@gmail.com> |
| 69 | Christoph Hellwig <hch@lst.de> | 72 | Christoph Hellwig <hch@lst.de> |
| 70 | Corey Minyard <minyard@acm.org> | 73 | Corey Minyard <minyard@acm.org> |
| @@ -33,7 +33,7 @@ Contact: xfs@oss.sgi.com · 32 unmodified lines | |||
| 33 | Description: | 33 | Description: |
| 34 | The current state of the log write grant head. It | 34 | The current state of the log write grant head. It |
| 35 | represents the total log reservation of all currently | 35 | represents the total log reservation of all currently |
| 36 | oustanding transactions, including regrants due to | 36 | outstanding transactions, including regrants due to |
| 37 | rolling transactions. The grant head is exported in | 37 | rolling transactions. The grant head is exported in |
| 38 | "cycle:bytes" format. | 38 | "cycle:bytes" format. |
| 39 | Users: xfstests | 39 | Users: xfstests |
| @@ -17,12 +17,12 @@ For ACPI on arm64, tables also fall into the following categories: · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | - Recommended: BERT, EINJ, ERST, HEST, PCCT, SSDT | 18 | - Recommended: BERT, EINJ, ERST, HEST, PCCT, SSDT |
| 19 | 19 | ||
| 20 | - Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, IORT, | 20 | - Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, IBFT, |
| 21 | MCHI, MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, STAO, | 21 | IORT, MCHI, MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, |
| 22 | TCPA, TPM2, UEFI, XENV | 22 | STAO, TCPA, TPM2, UEFI, XENV |
| 23 | 23 | ||
| 24 | - Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, LPIT, | 24 | - Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IVRS, LPIT, MSDM, OEMx, |
| 25 | MSDM, OEMx, PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT | 25 | PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT |
| 26 | 26 | ||
| 27 | ====== ======================================================================== | 27 | ====== ======================================================================== |
| 28 | Table Usage for ARMv8 Linux | 28 | Table Usage for ARMv8 Linux |
| @@ -130,6 +130,9 @@ stable kernels. · 129 unmodified lines | |||
| 130 | | Marvell | ARM-MMU-500 | #582743 | N/A | | 130 | | Marvell | ARM-MMU-500 | #582743 | N/A | |
| 131 | +----------------+-----------------+-----------------+-----------------------------+ | 131 | +----------------+-----------------+-----------------+-----------------------------+ |
| 132 | +----------------+-----------------+-----------------+-----------------------------+ | 132 | +----------------+-----------------+-----------------+-----------------------------+ |
| 133 | | NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM | | ||
| 134 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 135 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 133 | | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | | 136 | | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | |
| 134 | +----------------+-----------------+-----------------+-----------------------------+ | 137 | +----------------+-----------------+-----------------+-----------------------------+ |
| 135 | +----------------+-----------------+-----------------+-----------------------------+ | 138 | +----------------+-----------------+-----------------+-----------------------------+ |
| @@ -23,6 +23,7 @@ properties: · 22 unmodified lines | |||
| 23 | - enum: | 23 | - enum: |
| 24 | - ingenic,jz4775-intc | 24 | - ingenic,jz4775-intc |
| 25 | - ingenic,jz4770-intc | 25 | - ingenic,jz4770-intc |
| 26 | - ingenic,jz4760b-intc | ||
| 26 | - const: ingenic,jz4760-intc | 27 | - const: ingenic,jz4760-intc |
| 27 | - items: | 28 | - items: |
| 28 | - const: ingenic,x1000-intc | 29 | - const: ingenic,x1000-intc |
| @@ -21,6 +21,10 @@ properties: · 20 unmodified lines | |||
| 21 | - fsl,vf610-spdif | 21 | - fsl,vf610-spdif |
| 22 | - fsl,imx6sx-spdif | 22 | - fsl,imx6sx-spdif |
| 23 | - fsl,imx8qm-spdif | 23 | - fsl,imx8qm-spdif |
| 24 | - fsl,imx8qxp-spdif | ||
| 25 | - fsl,imx8mq-spdif | ||
| 26 | - fsl,imx8mm-spdif | ||
| 27 | - fsl,imx8mn-spdif | ||
| 24 | 28 | ||
| 25 | reg: | 29 | reg: |
| 26 | maxItems: 1 | 30 | maxItems: 1 |
| @@ -613,6 +613,27 @@ Some of these date from the very introduction of KMS in 2008 ... · 612 unmodified lines | |||
| 613 | 613 | ||
| 614 | Level: Intermediate | 614 | Level: Intermediate |
| 615 | 615 | ||
| 616 | Remove automatic page mapping from dma-buf importing | ||
| 617 | ---------------------------------------------------- | ||
| 618 | |||
| 619 | When importing dma-bufs, the dma-buf and PRIME frameworks automatically map | ||
| 620 | imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and | ||
| 621 | drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach() | ||
| 622 | even if they never do actual device DMA, but only CPU access through | ||
| 623 | dma_buf_vmap(). This is a problem for USB devices, which do not support DMA | ||
| 624 | operations. | ||
| 625 | |||
| 626 | To fix the issue, automatic page mappings should be removed from the | ||
| 627 | buffer-sharing code. Fixing this is a bit more involved, since the import/export | ||
| 628 | cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over | ||
| 629 | this problem for USB devices by fishing out the USB host controller device, as | ||
| 630 | long as that supports DMA. Otherwise importing can still needlessly fail. | ||
| 631 | |||
| 632 | Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter | ||
| 633 | |||
| 634 | Level: Advanced | ||
| 635 | |||
| 636 | |||
| 616 | Better Testing | 637 | Better Testing |
| 617 | ============== | 638 | ============== |
| 618 | 639 | ||
| @@ -267,7 +267,7 @@ DATA PATH · 266 unmodified lines | |||
| 267 | Tx | 267 | Tx |
| 268 | -- | 268 | -- |
| 269 | 269 | ||
| 270 | end_start_xmit() is called by the stack. This function does the following: | 270 | ena_start_xmit() is called by the stack. This function does the following: |
| 271 | 271 | ||
| 272 | - Maps data buffers (skb->data and frags). | 272 | - Maps data buffers (skb->data and frags). |
| 273 | - Populates ena_buf for the push buffer (if the driver and device are | 273 | - Populates ena_buf for the push buffer (if the driver and device are |
| @@ -52,7 +52,7 @@ purposes as a standard complementary tool. The system's view from · 51 unmodified lines | |||
| 52 | ``devlink-dpipe`` should change according to the changes done by the | 52 | ``devlink-dpipe`` should change according to the changes done by the |
| 53 | standard configuration tools. | 53 | standard configuration tools. |
| 54 | 54 | ||
| 55 | For example, it’s quiet common to implement Access Control Lists (ACL) | 55 | For example, it’s quite common to implement Access Control Lists (ACL) |
| 56 | using Ternary Content Addressable Memory (TCAM). The TCAM memory can be | 56 | using Ternary Content Addressable Memory (TCAM). The TCAM memory can be |
| 57 | divided into TCAM regions. Complex TC filters can have multiple rules with | 57 | divided into TCAM regions. Complex TC filters can have multiple rules with |
| 58 | different priorities and different lookup keys. On the other hand hardware | 58 | different priorities and different lookup keys. On the other hand hardware |
| @@ -151,7 +151,7 @@ representor netdevice. · 150 unmodified lines | |||
| 151 | ------------- | 151 | ------------- |
| 152 | A subfunction devlink port is created but it is not active yet. That means the | 152 | A subfunction devlink port is created but it is not active yet. That means the |
| 153 | entities are created on devlink side, the e-switch port representor is created, | 153 | entities are created on devlink side, the e-switch port representor is created, |
| 154 | but the subfunction device itself it not created. A user might use e-switch port | 154 | but the subfunction device itself is not created. A user might use e-switch port |
| 155 | representor to do settings, putting it into bridge, adding TC rules, etc. A user | 155 | representor to do settings, putting it into bridge, adding TC rules, etc. A user |
| 156 | might as well configure the hardware address (such as MAC address) of the | 156 | might as well configure the hardware address (such as MAC address) of the |
| 157 | subfunction while subfunction is inactive. | 157 | subfunction while subfunction is inactive. |
| @@ -173,7 +173,7 @@ Terms and Definitions · 15 unmodified lines | |||
| 173 | * - Term | 173 | * - Term |
| 174 | - Definitions | 174 | - Definitions |
| 175 | * - ``PCI device`` | 175 | * - ``PCI device`` |
| 176 | - A physical PCI device having one or more PCI bus consists of one or | 176 | - A physical PCI device having one or more PCI buses consists of one or |
| 177 | more PCI controllers. | 177 | more PCI controllers. |
| 178 | * - ``PCI controller`` | 178 | * - ``PCI controller`` |
| 179 | - A controller consists of potentially multiple physical functions, | 179 | - A controller consists of potentially multiple physical functions, |
| @@ -50,7 +50,7 @@ Callbacks to implement · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | The NIC driver offering ipsec offload will need to implement these | 51 | The NIC driver offering ipsec offload will need to implement these |
| 52 | callbacks to make the offload available to the network stack's | 52 | callbacks to make the offload available to the network stack's |
| 53 | XFRM subsytem. Additionally, the feature bits NETIF_F_HW_ESP and | 53 | XFRM subsystem. Additionally, the feature bits NETIF_F_HW_ESP and |
| 54 | NETIF_F_HW_ESP_TX_CSUM will signal the availability of the offload. | 54 | NETIF_F_HW_ESP_TX_CSUM will signal the availability of the offload. |
| 55 | 55 | ||
| 56 | 56 | ||
| @@ -182,6 +182,9 @@ is dependent on the CPU capability and the kernel configuration. The limit can · 181 unmodified lines | |||
| 182 | be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION | 182 | be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION |
| 183 | ioctl() at run-time. | 183 | ioctl() at run-time. |
| 184 | 184 | ||
| 185 | Creation of the VM will fail if the requested IPA size (whether it is | ||
| 186 | implicit or explicit) is unsupported on the host. | ||
| 187 | |||
| 185 | Please note that configuring the IPA size does not affect the capability | 188 | Please note that configuring the IPA size does not affect the capability |
| 186 | exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects | 189 | exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects |
| 187 | size of the address translated by the stage2 level (guest physical to | 190 | size of the address translated by the stage2 level (guest physical to |
| @@ -1492,7 +1495,8 @@ Fails if any VCPU has already been created. · 1304 unmodified lines | |||
| 1492 | 1495 | ||
| 1493 | Define which vcpu is the Bootstrap Processor (BSP). Values are the same | 1496 | Define which vcpu is the Bootstrap Processor (BSP). Values are the same |
| 1494 | as the vcpu id in KVM_CREATE_VCPU. If this ioctl is not called, the default | 1497 | as the vcpu id in KVM_CREATE_VCPU. If this ioctl is not called, the default |
| 1495 | is vcpu 0. | 1498 | is vcpu 0. This ioctl has to be called before vcpu creation, |
| 1499 | otherwise it will return EBUSY error. | ||
| 1496 | 1500 | ||
| 1497 | 1501 | ||
| 1498 | 4.42 KVM_GET_XSAVE | 1502 | 4.42 KVM_GET_XSAVE |
| @@ -4803,8 +4807,10 @@ If an MSR access is not permitted through the filtering, it generates a · 3304 unmodified lines | |||
| 4803 | allows user space to deflect and potentially handle various MSR accesses | 4807 | allows user space to deflect and potentially handle various MSR accesses |
| 4804 | into user space. | 4808 | into user space. |
| 4805 | 4809 | ||
| 4806 | If a vCPU is in running state while this ioctl is invoked, the vCPU may | 4810 | Note, invoking this ioctl with a vCPU is running is inherently racy. However, |
| 4807 | experience inconsistent filtering behavior on MSR accesses. | 4811 | KVM does guarantee that vCPUs will see either the previous filter or the new |
| 4812 | filter, e.g. MSRs with identical settings in both the old and new filter will | ||
| 4813 | have deterministic behavior. | ||
| 4808 | 4814 | ||
| 4809 | 4.127 KVM_XEN_HVM_SET_ATTR | 4815 | 4.127 KVM_XEN_HVM_SET_ATTR |
| 4810 | -------------------------- | 4816 | -------------------------- |
| @@ -261,8 +261,8 @@ ABI/API · 260 unmodified lines | |||
| 261 | L: linux-api@vger.kernel.org | 261 | L: linux-api@vger.kernel.org |
| 262 | F: include/linux/syscalls.h | 262 | F: include/linux/syscalls.h |
| 263 | F: kernel/sys_ni.c | 263 | F: kernel/sys_ni.c |
| 264 | F: include/uapi/ | 264 | X: include/uapi/ |
| 265 | F: arch/*/include/uapi/ | 265 | X: arch/*/include/uapi/ |
| 266 | 266 | ||
| 267 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER | 267 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER |
| 268 | M: Hans de Goede <hdegoede@redhat.com> | 268 | M: Hans de Goede <hdegoede@redhat.com> |
| @@ -1181,7 +1181,7 @@ M: Joel Fernandes <joel@joelfernandes.org> · 912 unmodified lines | |||
| 1181 | M: Christian Brauner <christian@brauner.io> | 1181 | M: Christian Brauner <christian@brauner.io> |
| 1182 | M: Hridya Valsaraju <hridya@google.com> | 1182 | M: Hridya Valsaraju <hridya@google.com> |
| 1183 | M: Suren Baghdasaryan <surenb@google.com> | 1183 | M: Suren Baghdasaryan <surenb@google.com> |
| 1184 | L: devel@driverdev.osuosl.org | 1184 | L: linux-kernel@vger.kernel.org |
| 1185 | S: Supported | 1185 | S: Supported |
| 1186 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git | 1186 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git |
| 1187 | F: drivers/android/ | 1187 | F: drivers/android/ |
| @@ -5839,7 +5839,7 @@ M: David Airlie <airlied@linux.ie> · 4651 unmodified lines | |||
| 5839 | M: Daniel Vetter <daniel@ffwll.ch> | 5839 | M: Daniel Vetter <daniel@ffwll.ch> |
| 5840 | L: dri-devel@lists.freedesktop.org | 5840 | L: dri-devel@lists.freedesktop.org |
| 5841 | S: Maintained | 5841 | S: Maintained |
| 5842 | B: https://bugs.freedesktop.org/ | 5842 | B: https://gitlab.freedesktop.org/drm |
| 5843 | C: irc://chat.freenode.net/dri-devel | 5843 | C: irc://chat.freenode.net/dri-devel |
| 5844 | T: git git://anongit.freedesktop.org/drm/drm | 5844 | T: git git://anongit.freedesktop.org/drm/drm |
| 5845 | F: Documentation/devicetree/bindings/display/ | 5845 | F: Documentation/devicetree/bindings/display/ |
| @@ -8120,7 +8120,6 @@ F: drivers/crypto/hisilicon/sec2/sec_main.c · 2274 unmodified lines | |||
| 8120 | 8120 | ||
| 8121 | HISILICON STAGING DRIVERS FOR HIKEY 960/970 | 8121 | HISILICON STAGING DRIVERS FOR HIKEY 960/970 |
| 8122 | M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 8122 | M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| 8123 | L: devel@driverdev.osuosl.org | ||
| 8124 | S: Maintained | 8123 | S: Maintained |
| 8125 | F: drivers/staging/hikey9xx/ | 8124 | F: drivers/staging/hikey9xx/ |
| 8126 | 8125 | ||
| @@ -8525,6 +8524,7 @@ IBM Power SRIOV Virtual NIC Device Driver · 398 unmodified lines | |||
| 8525 | M: Dany Madden <drt@linux.ibm.com> | 8524 | M: Dany Madden <drt@linux.ibm.com> |
| 8526 | M: Lijun Pan <ljp@linux.ibm.com> | 8525 | M: Lijun Pan <ljp@linux.ibm.com> |
| 8527 | M: Sukadev Bhattiprolu <sukadev@linux.ibm.com> | 8526 | M: Sukadev Bhattiprolu <sukadev@linux.ibm.com> |
| 8527 | R: Thomas Falcon <tlfalcon@linux.ibm.com> | ||
| 8528 | L: netdev@vger.kernel.org | 8528 | L: netdev@vger.kernel.org |
| 8529 | S: Supported | 8529 | S: Supported |
| 8530 | F: drivers/net/ethernet/ibm/ibmvnic.* | 8530 | F: drivers/net/ethernet/ibm/ibmvnic.* |
| @@ -12542,7 +12542,7 @@ NETWORKING [MPTCP] · 4011 unmodified lines | |||
| 12542 | M: Mat Martineau <mathew.j.martineau@linux.intel.com> | 12542 | M: Mat Martineau <mathew.j.martineau@linux.intel.com> |
| 12543 | M: Matthieu Baerts <matthieu.baerts@tessares.net> | 12543 | M: Matthieu Baerts <matthieu.baerts@tessares.net> |
| 12544 | L: netdev@vger.kernel.org | 12544 | L: netdev@vger.kernel.org |
| 12545 | L: mptcp@lists.01.org | 12545 | L: mptcp@lists.linux.dev |
| 12546 | S: Maintained | 12546 | S: Maintained |
| 12547 | W: https://github.com/multipath-tcp/mptcp_net-next/wiki | 12547 | W: https://github.com/multipath-tcp/mptcp_net-next/wiki |
| 12548 | B: https://github.com/multipath-tcp/mptcp_net-next/issues | 12548 | B: https://github.com/multipath-tcp/mptcp_net-next/issues |
| @@ -14713,15 +14713,11 @@ F: drivers/net/ethernet/qlogic/qlcnic/ · 2164 unmodified lines | |||
| 14713 | QLOGIC QLGE 10Gb ETHERNET DRIVER | 14713 | QLOGIC QLGE 10Gb ETHERNET DRIVER |
| 14714 | M: Manish Chopra <manishc@marvell.com> | 14714 | M: Manish Chopra <manishc@marvell.com> |
| 14715 | M: GR-Linux-NIC-Dev@marvell.com | 14715 | M: GR-Linux-NIC-Dev@marvell.com |
| 14716 | L: netdev@vger.kernel.org | ||
| 14717 | S: Supported | ||
| 14718 | F: drivers/staging/qlge/ | ||
| 14719 | |||
| 14720 | QLOGIC QLGE 10Gb ETHERNET DRIVER | ||
| 14721 | M: Coiby Xu <coiby.xu@gmail.com> | 14716 | M: Coiby Xu <coiby.xu@gmail.com> |
| 14722 | L: netdev@vger.kernel.org | 14717 | L: netdev@vger.kernel.org |
| 14723 | S: Maintained | 14718 | S: Supported |
| 14724 | F: Documentation/networking/device_drivers/qlogic/qlge.rst | 14719 | F: Documentation/networking/device_drivers/qlogic/qlge.rst |
| 14720 | F: drivers/staging/qlge/ | ||
| 14725 | 14721 | ||
| 14726 | QM1D1B0004 MEDIA DRIVER | 14722 | QM1D1B0004 MEDIA DRIVER |
| 14727 | M: Akihiro Tsukada <tskd08@gmail.com> | 14723 | M: Akihiro Tsukada <tskd08@gmail.com> |
| @@ -16891,8 +16887,10 @@ F: tools/spi/ · 2163 unmodified lines | |||
| 16891 | 16887 | ||
| 16892 | SPIDERNET NETWORK DRIVER for CELL | 16888 | SPIDERNET NETWORK DRIVER for CELL |
| 16893 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> | 16889 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> |
| 16890 | M: Geoff Levand <geoff@infradead.org> | ||
| 16894 | L: netdev@vger.kernel.org | 16891 | L: netdev@vger.kernel.org |
| 16895 | S: Supported | 16892 | L: linuxppc-dev@lists.ozlabs.org |
| 16893 | S: Maintained | ||
| 16896 | F: Documentation/networking/device_drivers/ethernet/toshiba/spider_net.rst | 16894 | F: Documentation/networking/device_drivers/ethernet/toshiba/spider_net.rst |
| 16897 | F: drivers/net/ethernet/toshiba/spider_net* | 16895 | F: drivers/net/ethernet/toshiba/spider_net* |
| 16898 | 16896 | ||
| @@ -17044,7 +17042,7 @@ F: drivers/staging/vt665?/ · 145 unmodified lines | |||
| 17044 | 17042 | ||
| 17045 | STAGING SUBSYSTEM | 17043 | STAGING SUBSYSTEM |
| 17046 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 17044 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 17047 | L: devel@driverdev.osuosl.org | 17045 | L: linux-staging@lists.linux.dev |
| 17048 | S: Supported | 17046 | S: Supported |
| 17049 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git | 17047 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git |
| 17050 | F: drivers/staging/ | 17048 | F: drivers/staging/ |
| @@ -19139,7 +19137,7 @@ VME SUBSYSTEM · 2088 unmodified lines | |||
| 19139 | M: Martyn Welch <martyn@welchs.me.uk> | 19137 | M: Martyn Welch <martyn@welchs.me.uk> |
| 19140 | M: Manohar Vanga <manohar.vanga@gmail.com> | 19138 | M: Manohar Vanga <manohar.vanga@gmail.com> |
| 19141 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 19139 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 19142 | L: devel@driverdev.osuosl.org | 19140 | L: linux-kernel@vger.kernel.org |
| 19143 | S: Maintained | 19141 | S: Maintained |
| 19144 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git | 19142 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git |
| 19145 | F: Documentation/driver-api/vme.rst | 19143 | F: Documentation/driver-api/vme.rst |
| @@ -19170,7 +19168,7 @@ S: Maintained · 24 unmodified lines | |||
| 19170 | F: drivers/infiniband/hw/vmw_pvrdma/ | 19168 | F: drivers/infiniband/hw/vmw_pvrdma/ |
| 19171 | 19169 | ||
| 19172 | VMware PVSCSI driver | 19170 | VMware PVSCSI driver |
| 19173 | M: Jim Gill <jgill@vmware.com> | 19171 | M: Vishal Bhakta <vbhakta@vmware.com> |
| 19174 | M: VMware PV-Drivers <pv-drivers@vmware.com> | 19172 | M: VMware PV-Drivers <pv-drivers@vmware.com> |
| 19175 | L: linux-scsi@vger.kernel.org | 19173 | L: linux-scsi@vger.kernel.org |
| 19176 | S: Maintained | 19174 | S: Maintained |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 12 | 3 | PATCHLEVEL = 12 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Frozen Wasteland | 6 | NAME = Frozen Wasteland |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -264,7 +264,8 @@ no-dot-config-targets := $(clean-targets) \ · 255 unmodified lines | |||
| 264 | $(version_h) headers headers_% archheaders archscripts \ | 264 | $(version_h) headers headers_% archheaders archscripts \ |
| 265 | %asm-generic kernelversion %src-pkg dt_binding_check \ | 265 | %asm-generic kernelversion %src-pkg dt_binding_check \ |
| 266 | outputmakefile | 266 | outputmakefile |
| 267 | no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease | 267 | no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \ |
| 268 | image_name | ||
| 268 | single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ | 269 | single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ |
| 269 | 270 | ||
| 270 | config-build := | 271 | config-build := |
| @@ -478,6 +479,7 @@ USERINCLUDE := \ · 207 unmodified lines | |||
| 478 | -I$(objtree)/arch/$(SRCARCH)/include/generated/uapi \ | 479 | -I$(objtree)/arch/$(SRCARCH)/include/generated/uapi \ |
| 479 | -I$(srctree)/include/uapi \ | 480 | -I$(srctree)/include/uapi \ |
| 480 | -I$(objtree)/include/generated/uapi \ | 481 | -I$(objtree)/include/generated/uapi \ |
| 482 | -include $(srctree)/include/linux/compiler-version.h \ | ||
| 481 | -include $(srctree)/include/linux/kconfig.h | 483 | -include $(srctree)/include/linux/kconfig.h |
| 482 | 484 | ||
| 483 | # Use LINUXINCLUDE when you must reference the include/ directory. | 485 | # Use LINUXINCLUDE when you must reference the include/ directory. |
| @@ -632,13 +632,12 @@ config HAS_LTO_CLANG · 631 unmodified lines | |||
| 632 | def_bool y | 632 | def_bool y |
| 633 | # Clang >= 11: https://github.com/ClangBuiltLinux/linux/issues/510 | 633 | # Clang >= 11: https://github.com/ClangBuiltLinux/linux/issues/510 |
| 634 | depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD | 634 | depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD |
| 635 | depends on $(success,test $(LLVM) -eq 1) | ||
| 636 | depends on $(success,test $(LLVM_IAS) -eq 1) | 635 | depends on $(success,test $(LLVM_IAS) -eq 1) |
| 637 | depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm) | 636 | depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm) |
| 638 | depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm) | 637 | depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm) |
| 639 | depends on ARCH_SUPPORTS_LTO_CLANG | 638 | depends on ARCH_SUPPORTS_LTO_CLANG |
| 640 | depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT | 639 | depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT |
| 641 | depends on !KASAN | 640 | depends on !KASAN || KASAN_HW_TAGS |
| 642 | depends on !GCOV_KERNEL | 641 | depends on !GCOV_KERNEL |
| 643 | help | 642 | help |
| 644 | The compiler and Kconfig options support building with Clang's | 643 | The compiler and Kconfig options support building with Clang's |
| @@ -348,6 +348,7 @@ config ARCH_EP93XX · 347 unmodified lines | |||
| 348 | select ARM_AMBA | 348 | select ARM_AMBA |
| 349 | imply ARM_PATCH_PHYS_VIRT | 349 | imply ARM_PATCH_PHYS_VIRT |
| 350 | select ARM_VIC | 350 | select ARM_VIC |
| 351 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 351 | select AUTO_ZRELADDR | 352 | select AUTO_ZRELADDR |
| 352 | select CLKDEV_LOOKUP | 353 | select CLKDEV_LOOKUP |
| 353 | select CLKSRC_MMIO | 354 | select CLKSRC_MMIO |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include <xen/xen.h> | 12 | #include <xen/xen.h> |
| 13 | #include <xen/interface/memory.h> | 13 | #include <xen/interface/memory.h> |
| 14 | #include <xen/grant_table.h> | ||
| 14 | #include <xen/page.h> | 15 | #include <xen/page.h> |
| 15 | #include <xen/swiotlb-xen.h> | 16 | #include <xen/swiotlb-xen.h> |
| 16 | 17 | ||
| @@ -109,7 +110,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 92 unmodified lines | |||
| 109 | map_ops[i].status = GNTST_general_error; | 110 | map_ops[i].status = GNTST_general_error; |
| 110 | unmap.host_addr = map_ops[i].host_addr, | 111 | unmap.host_addr = map_ops[i].host_addr, |
| 111 | unmap.handle = map_ops[i].handle; | 112 | unmap.handle = map_ops[i].handle; |
| 112 | map_ops[i].handle = ~0; | 113 | map_ops[i].handle = INVALID_GRANT_HANDLE; |
| 113 | if (map_ops[i].flags & GNTMAP_device_map) | 114 | if (map_ops[i].flags & GNTMAP_device_map) |
| 114 | unmap.dev_bus_addr = map_ops[i].dev_bus_addr; | 115 | unmap.dev_bus_addr = map_ops[i].dev_bus_addr; |
| 115 | else | 116 | else |
| @@ -130,7 +131,6 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 14 unmodified lines | |||
| 130 | 131 | ||
| 131 | return 0; | 132 | return 0; |
| 132 | } | 133 | } |
| 133 | EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping); | ||
| 134 | 134 | ||
| 135 | int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, | 135 | int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, |
| 136 | struct gnttab_unmap_grant_ref *kunmap_ops, | 136 | struct gnttab_unmap_grant_ref *kunmap_ops, |
| @@ -145,7 +145,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, · 8 unmodified lines | |||
| 145 | 145 | ||
| 146 | return 0; | 146 | return 0; |
| 147 | } | 147 | } |
| 148 | EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping); | ||
| 149 | 148 | ||
| 150 | bool __set_phys_to_machine_multi(unsigned long pfn, | 149 | bool __set_phys_to_machine_multi(unsigned long pfn, |
| 151 | unsigned long mfn, unsigned long nr_pages) | 150 | unsigned long mfn, unsigned long nr_pages) |
| @@ -810,6 +810,16 @@ config QCOM_FALKOR_ERRATUM_E1041 · 809 unmodified lines | |||
| 810 | 810 | ||
| 811 | If unsure, say Y. | 811 | If unsure, say Y. |
| 812 | 812 | ||
| 813 | config NVIDIA_CARMEL_CNP_ERRATUM | ||
| 814 | bool "NVIDIA Carmel CNP: CNP on Carmel semantically different than ARM cores" | ||
| 815 | default y | ||
| 816 | help | ||
| 817 | If CNP is enabled on Carmel cores, non-sharable TLBIs on a core will not | ||
| 818 | invalidate shared TLB entries installed by a different core, as it would | ||
| 819 | on standard ARM cores. | ||
| 820 | |||
| 821 | If unsure, say Y. | ||
| 822 | |||
| 813 | config SOCIONEXT_SYNQUACER_PREITS | 823 | config SOCIONEXT_SYNQUACER_PREITS |
| 814 | bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" | 824 | bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" |
| 815 | default y | 825 | default y |
| @@ -1055,8 +1065,6 @@ config HW_PERF_EVENTS · 239 unmodified lines | |||
| 1055 | config SYS_SUPPORTS_HUGETLBFS | 1065 | config SYS_SUPPORTS_HUGETLBFS |
| 1056 | def_bool y | 1066 | def_bool y |
| 1057 | 1067 | ||
| 1058 | config ARCH_WANT_HUGE_PMD_SHARE | ||
| 1059 | |||
| 1060 | config ARCH_HAS_CACHE_LINE_SIZE | 1068 | config ARCH_HAS_CACHE_LINE_SIZE |
| 1061 | def_bool y | 1069 | def_bool y |
| 1062 | 1070 | ||
| @@ -1157,8 +1165,8 @@ config XEN · 94 unmodified lines | |||
| 1157 | 1165 | ||
| 1158 | config FORCE_MAX_ZONEORDER | 1166 | config FORCE_MAX_ZONEORDER |
| 1159 | int | 1167 | int |
| 1160 | default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) | 1168 | default "14" if ARM64_64K_PAGES |
| 1161 | default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) | 1169 | default "12" if ARM64_16K_PAGES |
| 1162 | default "11" | 1170 | default "11" |
| 1163 | help | 1171 | help |
| 1164 | The kernel memory allocator divides physically contiguous memory | 1172 | The kernel memory allocator divides physically contiguous memory |
| @@ -1855,12 +1863,6 @@ config CMDLINE_FROM_BOOTLOADER · 690 unmodified lines | |||
| 1855 | the boot loader doesn't provide any, the default kernel command | 1863 | the boot loader doesn't provide any, the default kernel command |
| 1856 | string provided in CMDLINE will be used. | 1864 | string provided in CMDLINE will be used. |
| 1857 | 1865 | ||
| 1858 | config CMDLINE_EXTEND | ||
| 1859 | bool "Extend bootloader kernel arguments" | ||
| 1860 | help | ||
| 1861 | The command-line arguments provided by the boot loader will be | ||
| 1862 | appended to the default kernel command string. | ||
| 1863 | |||
| 1864 | config CMDLINE_FORCE | 1866 | config CMDLINE_FORCE |
| 1865 | bool "Always use the default kernel command string" | 1867 | bool "Always use the default kernel command string" |
| 1866 | help | 1868 | help |
| @@ -37,7 +37,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) · 36 unmodified lines | |||
| 37 | } while (--n > 0); | 37 | } while (--n > 0); |
| 38 | 38 | ||
| 39 | sum += ((sum >> 32) | (sum << 32)); | 39 | sum += ((sum >> 32) | (sum << 32)); |
| 40 | return csum_fold((__force u32)(sum >> 32)); | 40 | return csum_fold((__force __wsum)(sum >> 32)); |
| 41 | } | 41 | } |
| 42 | #define ip_fast_csum ip_fast_csum | 42 | #define ip_fast_csum ip_fast_csum |
| 43 | 43 | ||
| @@ -66,7 +66,8 @@ · 65 unmodified lines | |||
| 66 | #define ARM64_WORKAROUND_1508412 58 | 66 | #define ARM64_WORKAROUND_1508412 58 |
| 67 | #define ARM64_HAS_LDAPR 59 | 67 | #define ARM64_HAS_LDAPR 59 |
| 68 | #define ARM64_KVM_PROTECTED_MODE 60 | 68 | #define ARM64_KVM_PROTECTED_MODE 60 |
| 69 | #define ARM64_WORKAROUND_NVIDIA_CARMEL_CNP 61 | ||
| 69 | 70 | ||
| 70 | #define ARM64_NCAPS 61 | 71 | #define ARM64_NCAPS 62 |
| 71 | 72 | ||
| 72 | #endif /* __ASM_CPUCAPS_H */ | 73 | #endif /* __ASM_CPUCAPS_H */ |
| @@ -47,10 +47,10 @@ · 46 unmodified lines | |||
| 47 | #define __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context 2 | 47 | #define __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context 2 |
| 48 | #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa 3 | 48 | #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa 3 |
| 49 | #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid 4 | 49 | #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid 4 |
| 50 | #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_local_vmid 5 | 50 | #define __KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context 5 |
| 51 | #define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff 6 | 51 | #define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff 6 |
| 52 | #define __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs 7 | 52 | #define __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs 7 |
| 53 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_ich_vtr_el2 8 | 53 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_gic_config 8 |
| 54 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr 9 | 54 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr 9 |
| 55 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr 10 | 55 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr 10 |
| 56 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs 11 | 56 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs 11 |
| @@ -183,16 +183,16 @@ DECLARE_KVM_HYP_SYM(__bp_harden_hyp_vecs); · 126 unmodified lines | |||
| 183 | #define __bp_harden_hyp_vecs CHOOSE_HYP_SYM(__bp_harden_hyp_vecs) | 183 | #define __bp_harden_hyp_vecs CHOOSE_HYP_SYM(__bp_harden_hyp_vecs) |
| 184 | 184 | ||
| 185 | extern void __kvm_flush_vm_context(void); | 185 | extern void __kvm_flush_vm_context(void); |
| 186 | extern void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu); | ||
| 186 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, | 187 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, |
| 187 | int level); | 188 | int level); |
| 188 | extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); | 189 | extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); |
| 189 | extern void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu); | ||
| 190 | 190 | ||
| 191 | extern void __kvm_timer_set_cntvoff(u64 cntvoff); | 191 | extern void __kvm_timer_set_cntvoff(u64 cntvoff); |
| 192 | 192 | ||
| 193 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); | 193 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); |
| 194 | 194 | ||
| 195 | extern u64 __vgic_v3_get_ich_vtr_el2(void); | 195 | extern u64 __vgic_v3_get_gic_config(void); |
| 196 | extern u64 __vgic_v3_read_vmcr(void); | 196 | extern u64 __vgic_v3_read_vmcr(void); |
| 197 | extern void __vgic_v3_write_vmcr(u32 vmcr); | 197 | extern void __vgic_v3_write_vmcr(u32 vmcr); |
| 198 | extern void __vgic_v3_init_lrs(void); | 198 | extern void __vgic_v3_init_lrs(void); |
| @@ -83,6 +83,11 @@ void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt); · 82 unmodified lines | |||
| 83 | void __debug_switch_to_guest(struct kvm_vcpu *vcpu); | 83 | void __debug_switch_to_guest(struct kvm_vcpu *vcpu); |
| 84 | void __debug_switch_to_host(struct kvm_vcpu *vcpu); | 84 | void __debug_switch_to_host(struct kvm_vcpu *vcpu); |
| 85 | 85 | ||
| 86 | #ifdef __KVM_NVHE_HYPERVISOR__ | ||
| 87 | void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu); | ||
| 88 | void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu); | ||
| 89 | #endif | ||
| 90 | |||
| 86 | void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); | 91 | void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); |
| 87 | void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); | 92 | void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); |
| 88 | 93 | ||
| @@ -97,7 +102,8 @@ bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt); · 8 unmodified lines | |||
| 97 | 102 | ||
| 98 | void __noreturn hyp_panic(void); | 103 | void __noreturn hyp_panic(void); |
| 99 | #ifdef __KVM_NVHE_HYPERVISOR__ | 104 | #ifdef __KVM_NVHE_HYPERVISOR__ |
| 100 | void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par); | 105 | void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, |
| 106 | u64 elr, u64 par); | ||
| 101 | #endif | 107 | #endif |
| 102 | 108 | ||
| 103 | #endif /* __ARM64_KVM_HYP_H__ */ | 109 | #endif /* __ARM64_KVM_HYP_H__ */ |
| @@ -328,6 +328,11 @@ static inline void *phys_to_virt(phys_addr_t x) · 327 unmodified lines | |||
| 328 | #define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET) | 328 | #define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET) |
| 329 | 329 | ||
| 330 | #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL) | 330 | #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL) |
| 331 | #define page_to_virt(x) ({ \ | ||
| 332 | __typeof__(x) __page = x; \ | ||
| 333 | void *__addr = __va(page_to_phys(__page)); \ | ||
| 334 | (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ | ||
| 335 | }) | ||
| 331 | #define virt_to_page(x) pfn_to_page(virt_to_pfn(x)) | 336 | #define virt_to_page(x) pfn_to_page(virt_to_pfn(x)) |
| 332 | #else | 337 | #else |
| 333 | #define page_to_virt(x) ({ \ | 338 | #define page_to_virt(x) ({ \ |
| @@ -63,23 +63,6 @@ static inline void cpu_switch_mm(pgd_t *pgd, struct mm_struct *mm) · 62 unmodified lines | |||
| 63 | extern u64 idmap_t0sz; | 63 | extern u64 idmap_t0sz; |
| 64 | extern u64 idmap_ptrs_per_pgd; | 64 | extern u64 idmap_ptrs_per_pgd; |
| 65 | 65 | ||
| 66 | static inline bool __cpu_uses_extended_idmap(void) | ||
| 67 | { | ||
| 68 | if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52)) | ||
| 69 | return false; | ||
| 70 | |||
| 71 | return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)); | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * True if the extended ID map requires an extra level of translation table | ||
| 76 | * to be configured. | ||
| 77 | */ | ||
| 78 | static inline bool __cpu_uses_extended_idmap_level(void) | ||
| 79 | { | ||
| 80 | return ARM64_HW_PGTABLE_LEVELS(64 - idmap_t0sz) > CONFIG_PGTABLE_LEVELS; | ||
| 81 | } | ||
| 82 | |||
| 83 | /* | 66 | /* |
| 84 | * Ensure TCR.T0SZ is set to the provided value. | 67 | * Ensure TCR.T0SZ is set to the provided value. |
| 85 | */ | 68 | */ |
| @@ -66,7 +66,6 @@ extern bool arm64_use_ng_mappings; · 65 unmodified lines | |||
| 66 | #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) | 66 | #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) |
| 67 | 67 | ||
| 68 | #define PAGE_KERNEL __pgprot(PROT_NORMAL) | 68 | #define PAGE_KERNEL __pgprot(PROT_NORMAL) |
| 69 | #define PAGE_KERNEL_TAGGED __pgprot(PROT_NORMAL_TAGGED) | ||
| 70 | #define PAGE_KERNEL_RO __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY) | 69 | #define PAGE_KERNEL_RO __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY) |
| 71 | #define PAGE_KERNEL_ROX __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY) | 70 | #define PAGE_KERNEL_ROX __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY) |
| 72 | #define PAGE_KERNEL_EXEC __pgprot(PROT_NORMAL & ~PTE_PXN) | 71 | #define PAGE_KERNEL_EXEC __pgprot(PROT_NORMAL & ~PTE_PXN) |
| @@ -486,6 +486,9 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd) · 485 unmodified lines | |||
| 486 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) | 486 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) |
| 487 | #define pgprot_device(prot) \ | 487 | #define pgprot_device(prot) \ |
| 488 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) | 488 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) |
| 489 | #define pgprot_tagged(prot) \ | ||
| 490 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_TAGGED)) | ||
| 491 | #define pgprot_mhp pgprot_tagged | ||
| 489 | /* | 492 | /* |
| 490 | * DMA allocations for non-coherent devices use what the Arm architecture calls | 493 | * DMA allocations for non-coherent devices use what the Arm architecture calls |
| 491 | * "Normal non-cacheable" memory, which permits speculation, unaligned accesses | 494 | * "Normal non-cacheable" memory, which permits speculation, unaligned accesses |
| @@ -251,6 +251,8 @@ unsigned long get_wchan(struct task_struct *p); · 250 unmodified lines | |||
| 251 | extern struct task_struct *cpu_switch_to(struct task_struct *prev, | 251 | extern struct task_struct *cpu_switch_to(struct task_struct *prev, |
| 252 | struct task_struct *next); | 252 | struct task_struct *next); |
| 253 | 253 | ||
| 254 | asmlinkage void arm64_preempt_schedule_irq(void); | ||
| 255 | |||
| 254 | #define task_pt_regs(p) \ | 256 | #define task_pt_regs(p) \ |
| 255 | ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) | 257 | ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) |
| 256 | 258 | ||
| @@ -796,6 +796,11 @@ · 795 unmodified lines | |||
| 796 | #define ID_AA64MMFR0_PARANGE_48 0x5 | 796 | #define ID_AA64MMFR0_PARANGE_48 0x5 |
| 797 | #define ID_AA64MMFR0_PARANGE_52 0x6 | 797 | #define ID_AA64MMFR0_PARANGE_52 0x6 |
| 798 | 798 | ||
| 799 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT 0x0 | ||
| 800 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE 0x1 | ||
| 801 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN 0x2 | ||
| 802 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MAX 0x7 | ||
| 803 | |||
| 799 | #ifdef CONFIG_ARM64_PA_BITS_52 | 804 | #ifdef CONFIG_ARM64_PA_BITS_52 |
| 800 | #define ID_AA64MMFR0_PARANGE_MAX ID_AA64MMFR0_PARANGE_52 | 805 | #define ID_AA64MMFR0_PARANGE_MAX ID_AA64MMFR0_PARANGE_52 |
| 801 | #else | 806 | #else |
| @@ -961,14 +966,17 @@ · 159 unmodified lines | |||
| 961 | #define ID_PFR1_PROGMOD_SHIFT 0 | 966 | #define ID_PFR1_PROGMOD_SHIFT 0 |
| 962 | 967 | ||
| 963 | #if defined(CONFIG_ARM64_4K_PAGES) | 968 | #if defined(CONFIG_ARM64_4K_PAGES) |
| 964 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT | 969 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT |
| 965 | #define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN4_SUPPORTED | 970 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN4_SUPPORTED |
| 971 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 | ||
| 966 | #elif defined(CONFIG_ARM64_16K_PAGES) | 972 | #elif defined(CONFIG_ARM64_16K_PAGES) |
| 967 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT | 973 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT |
| 968 | #define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN16_SUPPORTED | 974 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN16_SUPPORTED |
| 975 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0xF | ||
| 969 | #elif defined(CONFIG_ARM64_64K_PAGES) | 976 | #elif defined(CONFIG_ARM64_64K_PAGES) |
| 970 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT | 977 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT |
| 971 | #define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN64_SUPPORTED | 978 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN64_SUPPORTED |
| 979 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 | ||
| 972 | #endif | 980 | #endif |
| 973 | 981 | ||
| 974 | #define MVFR2_FPMISC_SHIFT 4 | 982 | #define MVFR2_FPMISC_SHIFT 4 |
| @@ -55,6 +55,8 @@ void arch_setup_new_exec(void); · 54 unmodified lines | |||
| 55 | #define arch_setup_new_exec arch_setup_new_exec | 55 | #define arch_setup_new_exec arch_setup_new_exec |
| 56 | 56 | ||
| 57 | void arch_release_task_struct(struct task_struct *tsk); | 57 | void arch_release_task_struct(struct task_struct *tsk); |
| 58 | int arch_dup_task_struct(struct task_struct *dst, | ||
| 59 | struct task_struct *src); | ||
| 58 | 60 | ||
| 59 | #endif | 61 | #endif |
| 60 | 62 | ||
| @@ -525,6 +525,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { · 524 unmodified lines | |||
| 525 | 0, 0, | 525 | 0, 0, |
| 526 | 1, 0), | 526 | 1, 0), |
| 527 | }, | 527 | }, |
| 528 | #endif | ||
| 529 | #ifdef CONFIG_NVIDIA_CARMEL_CNP_ERRATUM | ||
| 530 | { | ||
| 531 | /* NVIDIA Carmel */ | ||
| 532 | .desc = "NVIDIA Carmel CNP erratum", | ||
| 533 | .capability = ARM64_WORKAROUND_NVIDIA_CARMEL_CNP, | ||
| 534 | ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL), | ||
| 535 | }, | ||
| 528 | #endif | 536 | #endif |
| 529 | { | 537 | { |
| 530 | } | 538 | } |
| @@ -1321,7 +1321,10 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) · 1320 unmodified lines | |||
| 1321 | * may share TLB entries with a CPU stuck in the crashed | 1321 | * may share TLB entries with a CPU stuck in the crashed |
| 1322 | * kernel. | 1322 | * kernel. |
| 1323 | */ | 1323 | */ |
| 1324 | if (is_kdump_kernel()) | 1324 | if (is_kdump_kernel()) |
| 1325 | return false; | ||
| 1326 | |||
| 1327 | if (cpus_have_const_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP)) | ||
| 1325 | return false; | 1328 | return false; |
| 1326 | 1329 | ||
| 1327 | return has_cpuid_feature(entry, scope); | 1330 | return has_cpuid_feature(entry, scope); |
| @@ -353,7 +353,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) · 352 unmodified lines | |||
| 353 | * with the CLIDR_EL1 fields to avoid triggering false warnings | 353 | * with the CLIDR_EL1 fields to avoid triggering false warnings |
| 354 | * when there is a mismatch across the CPUs. Keep track of the | 354 | * when there is a mismatch across the CPUs. Keep track of the |
| 355 | * effective value of the CTR_EL0 in our internal records for | 355 | * effective value of the CTR_EL0 in our internal records for |
| 356 | * acurate sanity check and feature enablement. | 356 | * accurate sanity check and feature enablement. |
| 357 | */ | 357 | */ |
| 358 | info->reg_ctr = read_cpuid_effective_cachetype(); | 358 | info->reg_ctr = read_cpuid_effective_cachetype(); |
| 359 | info->reg_dczid = read_cpuid(DCZID_EL0); | 359 | info->reg_dczid = read_cpuid(DCZID_EL0); |
| @@ -64,5 +64,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, · 63 unmodified lines | |||
| 64 | ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) | 64 | ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) |
| 65 | { | 65 | { |
| 66 | memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count); | 66 | memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count); |
| 67 | *ppos += count; | ||
| 68 | |||
| 67 | return count; | 69 | return count; |
| 68 | } | 70 | } |
| @@ -319,7 +319,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables) · 318 unmodified lines | |||
| 319 | */ | 319 | */ |
| 320 | adrp x5, __idmap_text_end | 320 | adrp x5, __idmap_text_end |
| 321 | clz x5, x5 | 321 | clz x5, x5 |
| 322 | cmp x5, TCR_T0SZ(VA_BITS) // default T0SZ small enough? | 322 | cmp x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough? |
| 323 | b.ge 1f // .. then skip VA range extension | 323 | b.ge 1f // .. then skip VA range extension |
| 324 | 324 | ||
| 325 | adr_l x6, idmap_t0sz | 325 | adr_l x6, idmap_t0sz |
| @@ -655,8 +655,10 @@ SYM_FUNC_END(__secondary_too_slow) · 329 unmodified lines | |||
| 655 | SYM_FUNC_START(__enable_mmu) | 655 | SYM_FUNC_START(__enable_mmu) |
| 656 | mrs x2, ID_AA64MMFR0_EL1 | 656 | mrs x2, ID_AA64MMFR0_EL1 |
| 657 | ubfx x2, x2, #ID_AA64MMFR0_TGRAN_SHIFT, 4 | 657 | ubfx x2, x2, #ID_AA64MMFR0_TGRAN_SHIFT, 4 |
| 658 | cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED | 658 | cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED_MIN |
| 659 | b.ne __no_granule_support | 659 | b.lt __no_granule_support |
| 660 | cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED_MAX | ||
| 661 | b.gt __no_granule_support | ||
| 660 | update_early_cpu_boot_status 0, x2, x3 | 662 | update_early_cpu_boot_status 0, x2, x3 |
| 661 | adrp x2, idmap_pg_dir | 663 | adrp x2, idmap_pg_dir |
| 662 | phys_to_ttbr x1, x1 | 664 | phys_to_ttbr x1, x1 |
| @@ -163,33 +163,36 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases) · 162 unmodified lines | |||
| 163 | } while (1); | 163 | } while (1); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static __init void parse_cmdline(void) | 166 | static __init const u8 *get_bootargs_cmdline(void) |
| 167 | { | 167 | { |
| 168 | if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) { | 168 | const u8 *prop; |
| 169 | const u8 *prop; | 169 | void *fdt; |
| 170 | void *fdt; | 170 | int node; |
| 171 | int node; | ||
| 172 | 171 | ||
| 173 | fdt = get_early_fdt_ptr(); | 172 | fdt = get_early_fdt_ptr(); |
| 174 | if (!fdt) | 173 | if (!fdt) |
| 175 | goto out; | 174 | return NULL; |
| 176 | 175 | ||
| 177 | node = fdt_path_offset(fdt, "/chosen"); | 176 | node = fdt_path_offset(fdt, "/chosen"); |
| 178 | if (node < 0) | 177 | if (node < 0) |
| 179 | goto out; | 178 | return NULL; |
| 180 | 179 | ||
| 181 | prop = fdt_getprop(fdt, node, "bootargs", NULL); | 180 | prop = fdt_getprop(fdt, node, "bootargs", NULL); |
| 182 | if (!prop) | 181 | if (!prop) |
| 183 | goto out; | 182 | return NULL; |
| 184 | 183 | ||
| 185 | __parse_cmdline(prop, true); | 184 | return strlen(prop) ? prop : NULL; |
| 185 | } | ||
| 186 | 186 | ||
| 187 | if (!IS_ENABLED(CONFIG_CMDLINE_EXTEND)) | 187 | static __init void parse_cmdline(void) |
| 188 | return; | 188 | { |
| 189 | } | 189 | const u8 *prop = get_bootargs_cmdline(); |
| 190 | 190 | ||
| 191 | out: | 191 | if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop) |
| 192 | __parse_cmdline(CONFIG_CMDLINE, true); | 192 | __parse_cmdline(CONFIG_CMDLINE, true); |
| 193 | |||
| 194 | if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && prop) | ||
| 195 | __parse_cmdline(prop, true); | ||
| 193 | } | 196 | } |
| 194 | 197 | ||
| 195 | /* Keep checkers quiet */ | 198 | /* Keep checkers quiet */ |
| @@ -101,6 +101,9 @@ KVM_NVHE_ALIAS(__stop___kvm_ex_table); · 100 unmodified lines | |||
| 101 | /* Array containing bases of nVHE per-CPU memory regions. */ | 101 | /* Array containing bases of nVHE per-CPU memory regions. */ |
| 102 | KVM_NVHE_ALIAS(kvm_arm_hyp_percpu_base); | 102 | KVM_NVHE_ALIAS(kvm_arm_hyp_percpu_base); |
| 103 | 103 | ||
| 104 | /* PMU available static key */ | ||
| 105 | KVM_NVHE_ALIAS(kvm_arm_pmu_available); | ||
| 106 | |||
| 104 | #endif /* CONFIG_KVM */ | 107 | #endif /* CONFIG_KVM */ |
| 105 | 108 | ||
| 106 | #endif /* __ARM64_KERNEL_IMAGE_VARS_H */ | 109 | #endif /* __ARM64_KERNEL_IMAGE_VARS_H */ |
| @@ -460,7 +460,7 @@ static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx) · 459 unmodified lines | |||
| 460 | return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx)); | 460 | return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx)); |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | static inline u32 armv8pmu_read_evcntr(int idx) | 463 | static inline u64 armv8pmu_read_evcntr(int idx) |
| 464 | { | 464 | { |
| 465 | u32 counter = ARMV8_IDX_TO_COUNTER(idx); | 465 | u32 counter = ARMV8_IDX_TO_COUNTER(idx); |
| 466 | 466 | ||
| @@ -57,6 +57,8 @@ · 56 unmodified lines | |||
| 57 | #include <asm/processor.h> | 57 | #include <asm/processor.h> |
| 58 | #include <asm/pointer_auth.h> | 58 | #include <asm/pointer_auth.h> |
| 59 | #include <asm/stacktrace.h> | 59 | #include <asm/stacktrace.h> |
| 60 | #include <asm/switch_to.h> | ||
| 61 | #include <asm/system_misc.h> | ||
| 60 | 62 | ||
| 61 | #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) | 63 | #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) |
| 62 | #include <linux/stackprotector.h> | 64 | #include <linux/stackprotector.h> |
| @@ -194,8 +194,9 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) · 193 unmodified lines | |||
| 194 | 194 | ||
| 195 | #ifdef CONFIG_STACKTRACE | 195 | #ifdef CONFIG_STACKTRACE |
| 196 | 196 | ||
| 197 | void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, | 197 | noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, |
| 198 | struct task_struct *task, struct pt_regs *regs) | 198 | void *cookie, struct task_struct *task, |
| 199 | struct pt_regs *regs) | ||
| 199 | { | 200 | { |
| 200 | struct stackframe frame; | 201 | struct stackframe frame; |
| 201 | 202 | ||
| @@ -203,8 +204,8 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, · 1 unmodified line | |||
| 203 | start_backtrace(&frame, regs->regs[29], regs->pc); | 204 | start_backtrace(&frame, regs->regs[29], regs->pc); |
| 204 | else if (task == current) | 205 | else if (task == current) |
| 205 | start_backtrace(&frame, | 206 | start_backtrace(&frame, |
| 206 | (unsigned long)__builtin_frame_address(0), | 207 | (unsigned long)__builtin_frame_address(1), |
| 207 | (unsigned long)arch_stack_walk); | 208 | (unsigned long)__builtin_return_address(0)); |
| 208 | else | 209 | else |
| 209 | start_backtrace(&frame, thread_saved_fp(task), | 210 | start_backtrace(&frame, thread_saved_fp(task), |
| 210 | thread_saved_pc(task)); | 211 | thread_saved_pc(task)); |
| @@ -385,11 +385,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 384 unmodified lines | |||
| 385 | last_ran = this_cpu_ptr(mmu->last_vcpu_ran); | 385 | last_ran = this_cpu_ptr(mmu->last_vcpu_ran); |
| 386 | 386 | ||
| 387 | /* | 387 | /* |
| 388 | * We guarantee that both TLBs and I-cache are private to each | ||
| 389 | * vcpu. If detecting that a vcpu from the same VM has | ||
| 390 | * previously run on the same physical CPU, call into the | ||
| 391 | * hypervisor code to nuke the relevant contexts. | ||
| 392 | * | ||
| 388 | * We might get preempted before the vCPU actually runs, but | 393 | * We might get preempted before the vCPU actually runs, but |
| 389 | * over-invalidation doesn't affect correctness. | 394 | * over-invalidation doesn't affect correctness. |
| 390 | */ | 395 | */ |
| 391 | if (*last_ran != vcpu->vcpu_id) { | 396 | if (*last_ran != vcpu->vcpu_id) { |
| 392 | kvm_call_hyp(__kvm_tlb_flush_local_vmid, mmu); | 397 | kvm_call_hyp(__kvm_flush_cpu_context, mmu); |
| 393 | *last_ran = vcpu->vcpu_id; | 398 | *last_ran = vcpu->vcpu_id; |
| 394 | } | 399 | } |
| 395 | 400 | ||
| @@ -85,8 +85,10 @@ SYM_INNER_LABEL(__guest_exit_panic, SYM_L_GLOBAL) · 84 unmodified lines | |||
| 85 | 85 | ||
| 86 | // If the hyp context is loaded, go straight to hyp_panic | 86 | // If the hyp context is loaded, go straight to hyp_panic |
| 87 | get_loaded_vcpu x0, x1 | 87 | get_loaded_vcpu x0, x1 |
| 88 | cbz x0, hyp_panic | 88 | cbnz x0, 1f |
| 89 | b hyp_panic | ||
| 89 | 90 | ||
| 91 | 1: | ||
| 90 | // The hyp context is saved so make sure it is restored to allow | 92 | // The hyp context is saved so make sure it is restored to allow |
| 91 | // hyp_panic to run at hyp and, subsequently, panic to run in the host. | 93 | // hyp_panic to run at hyp and, subsequently, panic to run in the host. |
| 92 | // This makes use of __guest_exit to avoid duplication but sets the | 94 | // This makes use of __guest_exit to avoid duplication but sets the |
| @@ -94,7 +96,7 @@ SYM_INNER_LABEL(__guest_exit_panic, SYM_L_GLOBAL) · 1 unmodified line | |||
| 94 | // current state is saved to the guest context but it will only be | 96 | // current state is saved to the guest context but it will only be |
| 95 | // accurate if the guest had been completely restored. | 97 | // accurate if the guest had been completely restored. |
| 96 | adr_this_cpu x0, kvm_hyp_ctxt, x1 | 98 | adr_this_cpu x0, kvm_hyp_ctxt, x1 |
| 97 | adr x1, hyp_panic | 99 | adr_l x1, hyp_panic |
| 98 | str x1, [x0, #CPU_XREG_OFFSET(30)] | 100 | str x1, [x0, #CPU_XREG_OFFSET(30)] |
| 99 | 101 | ||
| 100 | get_vcpu_ptr x1, x0 | 102 | get_vcpu_ptr x1, x0 |
| @@ -146,7 +148,7 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) · 45 unmodified lines | |||
| 146 | // Now restore the hyp regs | 148 | // Now restore the hyp regs |
| 147 | restore_callee_saved_regs x2 | 149 | restore_callee_saved_regs x2 |
| 148 | 150 | ||
| 149 | set_loaded_vcpu xzr, x1, x2 | 151 | set_loaded_vcpu xzr, x2, x3 |
| 150 | 152 | ||
| 151 | alternative_if ARM64_HAS_RAS_EXTN | 153 | alternative_if ARM64_HAS_RAS_EXTN |
| 152 | // If we have the RAS extensions we can consume a pending error | 154 | // If we have the RAS extensions we can consume a pending error |
| @@ -90,15 +90,18 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 89 unmodified lines | |||
| 90 | * counter, which could make a PMXEVCNTR_EL0 access UNDEF at | 90 | * counter, which could make a PMXEVCNTR_EL0 access UNDEF at |
| 91 | * EL1 instead of being trapped to EL2. | 91 | * EL1 instead of being trapped to EL2. |
| 92 | */ | 92 | */ |
| 93 | write_sysreg(0, pmselr_el0); | 93 | if (kvm_arm_support_pmu_v3()) { |
| 94 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); | 94 | write_sysreg(0, pmselr_el0); |
| 95 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); | ||
| 96 | } | ||
| 95 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); | 97 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); |
| 96 | } | 98 | } |
| 97 | 99 | ||
| 98 | static inline void __deactivate_traps_common(void) | 100 | static inline void __deactivate_traps_common(void) |
| 99 | { | 101 | { |
| 100 | write_sysreg(0, hstr_el2); | 102 | write_sysreg(0, hstr_el2); |
| 101 | write_sysreg(0, pmuserenr_el0); | 103 | if (kvm_arm_support_pmu_v3()) |
| 104 | write_sysreg(0, pmuserenr_el0); | ||
| 102 | } | 105 | } |
| 103 | 106 | ||
| 104 | static inline void ___activate_traps(struct kvm_vcpu *vcpu) | 107 | static inline void ___activate_traps(struct kvm_vcpu *vcpu) |
| @@ -58,16 +58,24 @@ static void __debug_restore_spe(u64 pmscr_el1) · 57 unmodified lines | |||
| 58 | write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1); | 58 | write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | void __debug_switch_to_guest(struct kvm_vcpu *vcpu) | 61 | void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) |
| 62 | { | 62 | { |
| 63 | /* Disable and flush SPE data generation */ | 63 | /* Disable and flush SPE data generation */ |
| 64 | __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); | 64 | __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); |
| 65 | } | ||
| 66 | |||
| 67 | void __debug_switch_to_guest(struct kvm_vcpu *vcpu) | ||
| 68 | { | ||
| 65 | __debug_switch_to_guest_common(vcpu); | 69 | __debug_switch_to_guest_common(vcpu); |
| 66 | } | 70 | } |
| 67 | 71 | ||
| 68 | void __debug_switch_to_host(struct kvm_vcpu *vcpu) | 72 | void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) |
| 69 | { | 73 | { |
| 70 | __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); | 74 | __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); |
| 75 | } | ||
| 76 | |||
| 77 | void __debug_switch_to_host(struct kvm_vcpu *vcpu) | ||
| 78 | { | ||
| 71 | __debug_switch_to_host_common(vcpu); | 79 | __debug_switch_to_host_common(vcpu); |
| 72 | } | 80 | } |
| 73 | 81 | ||
| @@ -71,7 +71,8 @@ SYM_FUNC_START(__host_enter) · 70 unmodified lines | |||
| 71 | SYM_FUNC_END(__host_enter) | 71 | SYM_FUNC_END(__host_enter) |
| 72 | 72 | ||
| 73 | /* | 73 | /* |
| 74 | * void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par); | 74 | * void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, |
| 75 | * u64 elr, u64 par); | ||
| 75 | */ | 76 | */ |
| 76 | SYM_FUNC_START(__hyp_do_panic) | 77 | SYM_FUNC_START(__hyp_do_panic) |
| 77 | /* Prepare and exit to the host's panic funciton. */ | 78 | /* Prepare and exit to the host's panic funciton. */ |
| @@ -82,9 +83,11 @@ SYM_FUNC_START(__hyp_do_panic) · 4 unmodified lines | |||
| 82 | hyp_kimg_va lr, x6 | 83 | hyp_kimg_va lr, x6 |
| 83 | msr elr_el2, lr | 84 | msr elr_el2, lr |
| 84 | 85 | ||
| 85 | /* Set the panic format string. Use the, now free, LR as scratch. */ | 86 | mov x29, x0 |
| 86 | ldr lr, =__hyp_panic_string | 87 | |
| 87 | hyp_kimg_va lr, x6 | 88 | /* Load the format string into x0 and arguments into x1-7 */ |
| 89 | ldr x0, =__hyp_panic_string | ||
| 90 | hyp_kimg_va x0, x6 | ||
| 88 | 91 | ||
| 89 | /* Load the format arguments into x1-7. */ | 92 | /* Load the format arguments into x1-7. */ |
| 90 | mov x6, x3 | 93 | mov x6, x3 |
| @@ -94,9 +97,7 @@ SYM_FUNC_START(__hyp_do_panic) · 3 unmodified lines | |||
| 94 | mrs x5, hpfar_el2 | 97 | mrs x5, hpfar_el2 |
| 95 | 98 | ||
| 96 | /* Enter the host, conditionally restoring the host context. */ | 99 | /* Enter the host, conditionally restoring the host context. */ |
| 97 | cmp x0, xzr | 100 | cbz x29, __host_enter_without_restoring |
| 98 | mov x0, lr | ||
| 99 | b.eq __host_enter_without_restoring | ||
| 100 | b __host_enter_for_panic | 101 | b __host_enter_for_panic |
| 101 | SYM_FUNC_END(__hyp_do_panic) | 102 | SYM_FUNC_END(__hyp_do_panic) |
| 102 | 103 | ||
| @@ -46,11 +46,11 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) · 45 unmodified lines | |||
| 46 | __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); | 46 | __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static void handle___kvm_tlb_flush_local_vmid(struct kvm_cpu_context *host_ctxt) | 49 | static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ctxt) |
| 50 | { | 50 | { |
| 51 | DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); | 51 | DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); |
| 52 | 52 | ||
| 53 | __kvm_tlb_flush_local_vmid(kern_hyp_va(mmu)); | 53 | __kvm_flush_cpu_context(kern_hyp_va(mmu)); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt) | 56 | static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt) |
| @@ -67,9 +67,9 @@ static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt) · 10 unmodified lines | |||
| 67 | write_sysreg_el2(tmp, SYS_SCTLR); | 67 | write_sysreg_el2(tmp, SYS_SCTLR); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | static void handle___vgic_v3_get_ich_vtr_el2(struct kvm_cpu_context *host_ctxt) | 70 | static void handle___vgic_v3_get_gic_config(struct kvm_cpu_context *host_ctxt) |
| 71 | { | 71 | { |
| 72 | cpu_reg(host_ctxt, 1) = __vgic_v3_get_ich_vtr_el2(); | 72 | cpu_reg(host_ctxt, 1) = __vgic_v3_get_gic_config(); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static void handle___vgic_v3_read_vmcr(struct kvm_cpu_context *host_ctxt) | 75 | static void handle___vgic_v3_read_vmcr(struct kvm_cpu_context *host_ctxt) |
| @@ -115,10 +115,10 @@ static const hcall_t host_hcall[] = { · 39 unmodified lines | |||
| 115 | HANDLE_FUNC(__kvm_flush_vm_context), | 115 | HANDLE_FUNC(__kvm_flush_vm_context), |
| 116 | HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), | 116 | HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), |
| 117 | HANDLE_FUNC(__kvm_tlb_flush_vmid), | 117 | HANDLE_FUNC(__kvm_tlb_flush_vmid), |
| 118 | HANDLE_FUNC(__kvm_tlb_flush_local_vmid), | 118 | HANDLE_FUNC(__kvm_flush_cpu_context), |
| 119 | HANDLE_FUNC(__kvm_timer_set_cntvoff), | 119 | HANDLE_FUNC(__kvm_timer_set_cntvoff), |
| 120 | HANDLE_FUNC(__kvm_enable_ssbs), | 120 | HANDLE_FUNC(__kvm_enable_ssbs), |
| 121 | HANDLE_FUNC(__vgic_v3_get_ich_vtr_el2), | 121 | HANDLE_FUNC(__vgic_v3_get_gic_config), |
| 122 | HANDLE_FUNC(__vgic_v3_read_vmcr), | 122 | HANDLE_FUNC(__vgic_v3_read_vmcr), |
| 123 | HANDLE_FUNC(__vgic_v3_write_vmcr), | 123 | HANDLE_FUNC(__vgic_v3_write_vmcr), |
| 124 | HANDLE_FUNC(__vgic_v3_init_lrs), | 124 | HANDLE_FUNC(__vgic_v3_init_lrs), |
| @@ -192,6 +192,14 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 191 unmodified lines | |||
| 192 | pmu_switch_needed = __pmu_switch_to_guest(host_ctxt); | 192 | pmu_switch_needed = __pmu_switch_to_guest(host_ctxt); |
| 193 | 193 | ||
| 194 | __sysreg_save_state_nvhe(host_ctxt); | 194 | __sysreg_save_state_nvhe(host_ctxt); |
| 195 | /* | ||
| 196 | * We must flush and disable the SPE buffer for nVHE, as | ||
| 197 | * the translation regime(EL1&0) is going to be loaded with | ||
| 198 | * that of the guest. And we must do this before we change the | ||
| 199 | * translation regime to EL2 (via MDCR_EL2_E2PB == 0) and | ||
| 200 | * before we load guest Stage1. | ||
| 201 | */ | ||
| 202 | __debug_save_host_buffers_nvhe(vcpu); | ||
| 195 | 203 | ||
| 196 | __adjust_pc(vcpu); | 204 | __adjust_pc(vcpu); |
| 197 | 205 | ||
| @@ -234,11 +242,12 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 36 unmodified lines | |||
| 234 | if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) | 242 | if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) |
| 235 | __fpsimd_save_fpexc32(vcpu); | 243 | __fpsimd_save_fpexc32(vcpu); |
| 236 | 244 | ||
| 245 | __debug_switch_to_host(vcpu); | ||
| 237 | /* | 246 | /* |
| 238 | * This must come after restoring the host sysregs, since a non-VHE | 247 | * This must come after restoring the host sysregs, since a non-VHE |
| 239 | * system may enable SPE here and make use of the TTBRs. | 248 | * system may enable SPE here and make use of the TTBRs. |
| 240 | */ | 249 | */ |
| 241 | __debug_switch_to_host(vcpu); | 250 | __debug_restore_host_buffers_nvhe(vcpu); |
| 242 | 251 | ||
| 243 | if (pmu_switch_needed) | 252 | if (pmu_switch_needed) |
| 244 | __pmu_switch_to_host(host_ctxt); | 253 | __pmu_switch_to_host(host_ctxt); |
| @@ -257,7 +266,6 @@ void __noreturn hyp_panic(void) · 12 unmodified lines | |||
| 257 | u64 spsr = read_sysreg_el2(SYS_SPSR); | 266 | u64 spsr = read_sysreg_el2(SYS_SPSR); |
| 258 | u64 elr = read_sysreg_el2(SYS_ELR); | 267 | u64 elr = read_sysreg_el2(SYS_ELR); |
| 259 | u64 par = read_sysreg_par(); | 268 | u64 par = read_sysreg_par(); |
| 260 | bool restore_host = true; | ||
| 261 | struct kvm_cpu_context *host_ctxt; | 269 | struct kvm_cpu_context *host_ctxt; |
| 262 | struct kvm_vcpu *vcpu; | 270 | struct kvm_vcpu *vcpu; |
| 263 | 271 | ||
| @@ -271,7 +279,7 @@ void __noreturn hyp_panic(void) · 7 unmodified lines | |||
| 271 | __sysreg_restore_state_nvhe(host_ctxt); | 279 | __sysreg_restore_state_nvhe(host_ctxt); |
| 272 | } | 280 | } |
| 273 | 281 | ||
| 274 | __hyp_do_panic(restore_host, spsr, elr, par); | 282 | __hyp_do_panic(host_ctxt, spsr, elr, par); |
| 275 | unreachable(); | 283 | unreachable(); |
| 276 | } | 284 | } |
| 277 | 285 | ||
| @@ -123,7 +123,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) · 122 unmodified lines | |||
| 123 | __tlb_switch_to_host(&cxt); | 123 | __tlb_switch_to_host(&cxt); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) | 126 | void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu) |
| 127 | { | 127 | { |
| 128 | struct tlb_inv_context cxt; | 128 | struct tlb_inv_context cxt; |
| 129 | 129 | ||
| @@ -131,6 +131,7 @@ void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) · 1 unmodified line | |||
| 131 | __tlb_switch_to_guest(mmu, &cxt); | 131 | __tlb_switch_to_guest(mmu, &cxt); |
| 132 | 132 | ||
| 133 | __tlbi(vmalle1); | 133 | __tlbi(vmalle1); |
| 134 | asm volatile("ic iallu"); | ||
| 134 | dsb(nsh); | 135 | dsb(nsh); |
| 135 | isb(); | 136 | isb(); |
| 136 | 137 | ||
| @@ -223,6 +223,7 @@ static inline int __kvm_pgtable_visit(struct kvm_pgtable_walk_data *data, · 222 unmodified lines | |||
| 223 | goto out; | 223 | goto out; |
| 224 | 224 | ||
| 225 | if (!table) { | 225 | if (!table) { |
| 226 | data->addr = ALIGN_DOWN(data->addr, kvm_granule_size(level)); | ||
| 226 | data->addr += kvm_granule_size(level); | 227 | data->addr += kvm_granule_size(level); |
| 227 | goto out; | 228 | goto out; |
| 228 | } | 229 | } |
| @@ -405,9 +405,45 @@ void __vgic_v3_init_lrs(void) · 404 unmodified lines | |||
| 405 | __gic_v3_set_lr(0, i); | 405 | __gic_v3_set_lr(0, i); |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | u64 __vgic_v3_get_ich_vtr_el2(void) | 408 | /* |
| 409 | * Return the GIC CPU configuration: | ||
| 410 | * - [31:0] ICH_VTR_EL2 | ||
| 411 | * - [62:32] RES0 | ||
| 412 | * - [63] MMIO (GICv2) capable | ||
| 413 | */ | ||
| 414 | u64 __vgic_v3_get_gic_config(void) | ||
| 409 | { | 415 | { |
| 410 | return read_gicreg(ICH_VTR_EL2); | 416 | u64 val, sre = read_gicreg(ICC_SRE_EL1); |
| 417 | unsigned long flags = 0; | ||
| 418 | |||
| 419 | /* | ||
| 420 | * To check whether we have a MMIO-based (GICv2 compatible) | ||
| 421 | * CPU interface, we need to disable the system register | ||
| 422 | * view. To do that safely, we have to prevent any interrupt | ||
| 423 | * from firing (which would be deadly). | ||
| 424 | * | ||
| 425 | * Note that this only makes sense on VHE, as interrupts are | ||
| 426 | * already masked for nVHE as part of the exception entry to | ||
| 427 | * EL2. | ||
| 428 | */ | ||
| 429 | if (has_vhe()) | ||
| 430 | flags = local_daif_save(); | ||
| 431 | |||
| 432 | write_gicreg(0, ICC_SRE_EL1); | ||
| 433 | isb(); | ||
| 434 | |||
| 435 | val = read_gicreg(ICC_SRE_EL1); | ||
| 436 | |||
| 437 | write_gicreg(sre, ICC_SRE_EL1); | ||
| 438 | isb(); | ||
| 439 | |||
| 440 | if (has_vhe()) | ||
| 441 | local_daif_restore(flags); | ||
| 442 | |||
| 443 | val = (val & ICC_SRE_EL1_SRE) ? 0 : (1ULL << 63); | ||
| 444 | val |= read_gicreg(ICH_VTR_EL2); | ||
| 445 | |||
| 446 | return val; | ||
| 411 | } | 447 | } |
| 412 | 448 | ||
| 413 | u64 __vgic_v3_read_vmcr(void) | 449 | u64 __vgic_v3_read_vmcr(void) |
| @@ -127,7 +127,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) · 126 unmodified lines | |||
| 127 | __tlb_switch_to_host(&cxt); | 127 | __tlb_switch_to_host(&cxt); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) | 130 | void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu) |
| 131 | { | 131 | { |
| 132 | struct tlb_inv_context cxt; | 132 | struct tlb_inv_context cxt; |
| 133 | 133 | ||
| @@ -135,6 +135,7 @@ void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) · 1 unmodified line | |||
| 135 | __tlb_switch_to_guest(mmu, &cxt); | 135 | __tlb_switch_to_guest(mmu, &cxt); |
| 136 | 136 | ||
| 137 | __tlbi(vmalle1); | 137 | __tlbi(vmalle1); |
| 138 | asm volatile("ic iallu"); | ||
| 138 | dsb(nsh); | 139 | dsb(nsh); |
| 139 | isb(); | 140 | isb(); |
| 140 | 141 | ||
| @@ -1312,8 +1312,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, · 1311 unmodified lines | |||
| 1312 | * Prevent userspace from creating a memory region outside of the IPA | 1312 | * Prevent userspace from creating a memory region outside of the IPA |
| 1313 | * space addressable by the KVM guest IPA space. | 1313 | * space addressable by the KVM guest IPA space. |
| 1314 | */ | 1314 | */ |
| 1315 | if (memslot->base_gfn + memslot->npages >= | 1315 | if ((memslot->base_gfn + memslot->npages) > (kvm_phys_size(kvm) >> PAGE_SHIFT)) |
| 1316 | (kvm_phys_size(kvm) >> PAGE_SHIFT)) | ||
| 1317 | return -EFAULT; | 1316 | return -EFAULT; |
| 1318 | 1317 | ||
| 1319 | mmap_read_lock(current->mm); | 1318 | mmap_read_lock(current->mm); |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include <asm/kvm_emulate.h> | 12 | #include <asm/kvm_emulate.h> |
| 13 | 13 | ||
| 14 | DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available); | ||
| 15 | |||
| 14 | static int kvm_is_in_guest(void) | 16 | static int kvm_is_in_guest(void) |
| 15 | { | 17 | { |
| 16 | return kvm_get_running_vcpu() != NULL; | 18 | return kvm_get_running_vcpu() != NULL; |
| @@ -48,6 +50,14 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = { · 31 unmodified lines | |||
| 48 | 50 | ||
| 49 | int kvm_perf_init(void) | 51 | int kvm_perf_init(void) |
| 50 | { | 52 | { |
| 53 | /* | ||
| 54 | * Check if HW_PERF_EVENTS are supported by checking the number of | ||
| 55 | * hardware performance counters. This could ensure the presence of | ||
| 56 | * a physical PMU and CONFIG_PERF_EVENT is selected. | ||
| 57 | */ | ||
| 58 | if (IS_ENABLED(CONFIG_ARM_PMU) && perf_num_counters() > 0) | ||
| 59 | static_branch_enable(&kvm_arm_pmu_available); | ||
| 60 | |||
| 51 | return perf_register_guest_info_callbacks(&kvm_guest_cbs); | 61 | return perf_register_guest_info_callbacks(&kvm_guest_cbs); |
| 52 | } | 62 | } |
| 53 | 63 | ||
| @@ -823,16 +823,6 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) · 822 unmodified lines | |||
| 823 | return val & mask; | 823 | return val & mask; |
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | bool kvm_arm_support_pmu_v3(void) | ||
| 827 | { | ||
| 828 | /* | ||
| 829 | * Check if HW_PERF_EVENTS are supported by checking the number of | ||
| 830 | * hardware performance counters. This could ensure the presence of | ||
| 831 | * a physical PMU and CONFIG_PERF_EVENT is selected. | ||
| 832 | */ | ||
| 833 | return (perf_num_counters() > 0); | ||
| 834 | } | ||
| 835 | |||
| 836 | int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) | 826 | int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) |
| 837 | { | 827 | { |
| 838 | if (!kvm_vcpu_has_pmu(vcpu)) | 828 | if (!kvm_vcpu_has_pmu(vcpu)) |
| @@ -311,23 +311,24 @@ int kvm_set_ipa_limit(void) · 310 unmodified lines | |||
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) { | 313 | switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) { |
| 314 | default: | 314 | case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE: |
| 315 | case 1: | ||
| 316 | kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n"); | 315 | kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n"); |
| 317 | return -EINVAL; | 316 | return -EINVAL; |
| 318 | case 0: | 317 | case ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT: |
| 319 | kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n"); | 318 | kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n"); |
| 320 | break; | 319 | break; |
| 321 | case 2: | 320 | case ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN ... ID_AA64MMFR0_TGRAN_2_SUPPORTED_MAX: |
| 322 | kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n"); | 321 | kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n"); |
| 323 | break; | 322 | break; |
| 323 | default: | ||
| 324 | kvm_err("Unsupported value for TGRAN_2, giving up\n"); | ||
| 325 | return -EINVAL; | ||
| 324 | } | 326 | } |
| 325 | 327 | ||
| 326 | kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange); | 328 | kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange); |
| 327 | WARN(kvm_ipa_limit < KVM_PHYS_SHIFT, | 329 | kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit, |
| 328 | "KVM IPA Size Limit (%d bits) is smaller than default size\n", | 330 | ((kvm_ipa_limit < KVM_PHYS_SHIFT) ? |
| 329 | kvm_ipa_limit); | 331 | " (Reduced IPA size, limited VM/VMM compatibility)" : "")); |
| 330 | kvm_info("IPA Size Limit: %d bits\n", kvm_ipa_limit); | ||
| 331 | 332 | ||
| 332 | return 0; | 333 | return 0; |
| 333 | } | 334 | } |
| @@ -356,6 +357,11 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type) · 22 unmodified lines | |||
| 356 | return -EINVAL; | 357 | return -EINVAL; |
| 357 | } else { | 358 | } else { |
| 358 | phys_shift = KVM_PHYS_SHIFT; | 359 | phys_shift = KVM_PHYS_SHIFT; |
| 360 | if (phys_shift > kvm_ipa_limit) { | ||
| 361 | pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n", | ||
| 362 | current->comm); | ||
| 363 | return -EINVAL; | ||
| 364 | } | ||
| 359 | } | 365 | } |
| 360 | 366 | ||
| 361 | mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); | 367 | mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); |
| @@ -574,9 +574,13 @@ early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable); · 573 unmodified lines | |||
| 574 | */ | 574 | */ |
| 575 | int vgic_v3_probe(const struct gic_kvm_info *info) | 575 | int vgic_v3_probe(const struct gic_kvm_info *info) |
| 576 | { | 576 | { |
| 577 | u32 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_ich_vtr_el2); | 577 | u64 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config); |
| 578 | bool has_v2; | ||
| 578 | int ret; | 579 | int ret; |
| 579 | 580 | ||
| 581 | has_v2 = ich_vtr_el2 >> 63; | ||
| 582 | ich_vtr_el2 = (u32)ich_vtr_el2; | ||
| 583 | |||
| 580 | /* | 584 | /* |
| 581 | * The ListRegs field is 5 bits, but there is an architectural | 585 | * The ListRegs field is 5 bits, but there is an architectural |
| 582 | * maximum of 16 list registers. Just ignore bit 4... | 586 | * maximum of 16 list registers. Just ignore bit 4... |
| @@ -594,13 +598,15 @@ int vgic_v3_probe(const struct gic_kvm_info *info) · 11 unmodified lines | |||
| 594 | gicv4_enable ? "en" : "dis"); | 598 | gicv4_enable ? "en" : "dis"); |
| 595 | } | 599 | } |
| 596 | 600 | ||
| 601 | kvm_vgic_global_state.vcpu_base = 0; | ||
| 602 | |||
| 597 | if (!info->vcpu.start) { | 603 | if (!info->vcpu.start) { |
| 598 | kvm_info("GICv3: no GICV resource entry\n"); | 604 | kvm_info("GICv3: no GICV resource entry\n"); |
| 599 | kvm_vgic_global_state.vcpu_base = 0; | 605 | } else if (!has_v2) { |
| 606 | pr_warn(FW_BUG "CPU interface incapable of MMIO access\n"); | ||
| 600 | } else if (!PAGE_ALIGNED(info->vcpu.start)) { | 607 | } else if (!PAGE_ALIGNED(info->vcpu.start)) { |
| 601 | pr_warn("GICV physical address 0x%llx not page aligned\n", | 608 | pr_warn("GICV physical address 0x%llx not page aligned\n", |
| 602 | (unsigned long long)info->vcpu.start); | 609 | (unsigned long long)info->vcpu.start); |
| 603 | kvm_vgic_global_state.vcpu_base = 0; | ||
| 604 | } else { | 610 | } else { |
| 605 | kvm_vgic_global_state.vcpu_base = info->vcpu.start; | 611 | kvm_vgic_global_state.vcpu_base = info->vcpu.start; |
| 606 | kvm_vgic_global_state.can_emulate_gicv2 = true; | 612 | kvm_vgic_global_state.can_emulate_gicv2 = true; |
| @@ -219,17 +219,40 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 218 unmodified lines | |||
| 219 | 219 | ||
| 220 | int pfn_valid(unsigned long pfn) | 220 | int pfn_valid(unsigned long pfn) |
| 221 | { | 221 | { |
| 222 | phys_addr_t addr = pfn << PAGE_SHIFT; | 222 | phys_addr_t addr = PFN_PHYS(pfn); |
| 223 | 223 | ||
| 224 | if ((addr >> PAGE_SHIFT) != pfn) | 224 | /* |
| 225 | * Ensure the upper PAGE_SHIFT bits are clear in the | ||
| 226 | * pfn. Else it might lead to false positives when | ||
| 227 | * some of the upper bits are set, but the lower bits | ||
| 228 | * match a valid pfn. | ||
| 229 | */ | ||
| 230 | if (PHYS_PFN(addr) != pfn) | ||
| 225 | return 0; | 231 | return 0; |
| 226 | 232 | ||
| 227 | #ifdef CONFIG_SPARSEMEM | 233 | #ifdef CONFIG_SPARSEMEM |
| 234 | { | ||
| 235 | struct mem_section *ms; | ||
| 236 | |||
| 228 | if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) | 237 | if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) |
| 229 | return 0; | 238 | return 0; |
| 230 | 239 | ||
| 231 | if (!valid_section(__pfn_to_section(pfn))) | 240 | ms = __pfn_to_section(pfn); |
| 241 | if (!valid_section(ms)) | ||
| 232 | return 0; | 242 | return 0; |
| 243 | |||
| 244 | /* | ||
| 245 | * ZONE_DEVICE memory does not have the memblock entries. | ||
| 246 | * memblock_is_map_memory() check for ZONE_DEVICE based | ||
| 247 | * addresses will always fail. Even the normal hotplugged | ||
| 248 | * memory will never have MEMBLOCK_NOMAP flag set in their | ||
| 249 | * memblock entries. Skip memblock search for all non early | ||
| 250 | * memory sections covering all of hotplug memory including | ||
| 251 | * both normal and ZONE_DEVICE based. | ||
| 252 | */ | ||
| 253 | if (!early_section(ms)) | ||
| 254 | return pfn_section_valid(ms, pfn); | ||
| 255 | } | ||
| 233 | #endif | 256 | #endif |
| 234 | return memblock_is_map_memory(addr); | 257 | return memblock_is_map_memory(addr); |
| 235 | } | 258 | } |
| @@ -40,7 +40,7 @@ · 39 unmodified lines | |||
| 40 | #define NO_BLOCK_MAPPINGS BIT(0) | 40 | #define NO_BLOCK_MAPPINGS BIT(0) |
| 41 | #define NO_CONT_MAPPINGS BIT(1) | 41 | #define NO_CONT_MAPPINGS BIT(1) |
| 42 | 42 | ||
| 43 | u64 idmap_t0sz = TCR_T0SZ(VA_BITS); | 43 | u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN); |
| 44 | u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; | 44 | u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; |
| 45 | 45 | ||
| 46 | u64 __section(".mmuoff.data.write") vabits_actual; | 46 | u64 __section(".mmuoff.data.write") vabits_actual; |
| @@ -512,7 +512,8 @@ static void __init map_mem(pgd_t *pgdp) · 465 unmodified lines | |||
| 512 | * if MTE is present. Otherwise, it has the same attributes as | 512 | * if MTE is present. Otherwise, it has the same attributes as |
| 513 | * PAGE_KERNEL. | 513 | * PAGE_KERNEL. |
| 514 | */ | 514 | */ |
| 515 | __map_memblock(pgdp, start, end, PAGE_KERNEL_TAGGED, flags); | 515 | __map_memblock(pgdp, start, end, pgprot_tagged(PAGE_KERNEL), |
| 516 | flags); | ||
| 516 | } | 517 | } |
| 517 | 518 | ||
| 518 | /* | 519 | /* |
| @@ -1447,6 +1448,22 @@ static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size) · 928 unmodified lines | |||
| 1447 | struct range arch_get_mappable_range(void) | 1448 | struct range arch_get_mappable_range(void) |
| 1448 | { | 1449 | { |
| 1449 | struct range mhp_range; | 1450 | struct range mhp_range; |
| 1451 | u64 start_linear_pa = __pa(_PAGE_OFFSET(vabits_actual)); | ||
| 1452 | u64 end_linear_pa = __pa(PAGE_END - 1); | ||
| 1453 | |||
| 1454 | if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { | ||
| 1455 | /* | ||
| 1456 | * Check for a wrap, it is possible because of randomized linear | ||
| 1457 | * mapping the start physical address is actually bigger than | ||
| 1458 | * the end physical address. In this case set start to zero | ||
| 1459 | * because [0, end_linear_pa] range must still be able to cover | ||
| 1460 | * all addressable physical addresses. | ||
| 1461 | */ | ||
| 1462 | if (start_linear_pa > end_linear_pa) | ||
| 1463 | start_linear_pa = 0; | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | WARN_ON(start_linear_pa > end_linear_pa); | ||
| 1450 | 1467 | ||
| 1451 | /* | 1468 | /* |
| 1452 | * Linear mapping region is the range [PAGE_OFFSET..(PAGE_END - 1)] | 1469 | * Linear mapping region is the range [PAGE_OFFSET..(PAGE_END - 1)] |
| @@ -1454,8 +1471,9 @@ struct range arch_get_mappable_range(void) · 1 unmodified line | |||
| 1454 | * range which can be mapped inside this linear mapping range, must | 1471 | * range which can be mapped inside this linear mapping range, must |
| 1455 | * also be derived from its end points. | 1472 | * also be derived from its end points. |
| 1456 | */ | 1473 | */ |
| 1457 | mhp_range.start = __pa(_PAGE_OFFSET(vabits_actual)); | 1474 | mhp_range.start = start_linear_pa; |
| 1458 | mhp_range.end = __pa(PAGE_END - 1); | 1475 | mhp_range.end = end_linear_pa; |
| 1476 | |||
| 1459 | return mhp_range; | 1477 | return mhp_range; |
| 1460 | } | 1478 | } |
| 1461 | 1479 | ||
| @@ -9,7 +9,7 @@ int arch_check_ftrace_location(struct kprobe *p) · 8 unmodified lines | |||
| 9 | return 0; | 9 | return 0; |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | /* Ftrace callback handler for kprobes -- called under preepmt disabed */ | 12 | /* Ftrace callback handler for kprobes -- called under preepmt disabled */ |
| 13 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, | 13 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, |
| 14 | struct ftrace_ops *ops, struct ftrace_regs *fregs) | 14 | struct ftrace_ops *ops, struct ftrace_regs *fregs) |
| 15 | { | 15 | { |
| @@ -32,7 +32,7 @@ static inline void syscall_rollback(struct task_struct *task, · 31 unmodified lines | |||
| 32 | static inline long syscall_get_error(struct task_struct *task, | 32 | static inline long syscall_get_error(struct task_struct *task, |
| 33 | struct pt_regs *regs) | 33 | struct pt_regs *regs) |
| 34 | { | 34 | { |
| 35 | return regs->r10 == -1 ? regs->r8:0; | 35 | return regs->r10 == -1 ? -regs->r8:0; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | static inline long syscall_get_return_value(struct task_struct *task, | 38 | static inline long syscall_get_return_value(struct task_struct *task, |
| @@ -59,7 +59,7 @@ show_##name(struct device *dev, struct device_attribute *attr, \ · 58 unmodified lines | |||
| 59 | char *buf) \ | 59 | char *buf) \ |
| 60 | { \ | 60 | { \ |
| 61 | u32 cpu=dev->id; \ | 61 | u32 cpu=dev->id; \ |
| 62 | return sprintf(buf, "%lx\n", name[cpu]); \ | 62 | return sprintf(buf, "%llx\n", name[cpu]); \ |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | #define store(name) \ | 65 | #define store(name) \ |
| @@ -86,9 +86,9 @@ store_call_start(struct device *dev, struct device_attribute *attr, · 20 unmodified lines | |||
| 86 | 86 | ||
| 87 | #ifdef ERR_INJ_DEBUG | 87 | #ifdef ERR_INJ_DEBUG |
| 88 | printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu); | 88 | printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu); |
| 89 | printk(KERN_DEBUG "err_type_info=%lx,\n", err_type_info[cpu]); | 89 | printk(KERN_DEBUG "err_type_info=%llx,\n", err_type_info[cpu]); |
| 90 | printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]); | 90 | printk(KERN_DEBUG "err_struct_info=%llx,\n", err_struct_info[cpu]); |
| 91 | printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n", | 91 | printk(KERN_DEBUG "err_data_buffer=%llx, %llx, %llx.\n", |
| 92 | err_data_buffer[cpu].data1, | 92 | err_data_buffer[cpu].data1, |
| 93 | err_data_buffer[cpu].data2, | 93 | err_data_buffer[cpu].data2, |
| 94 | err_data_buffer[cpu].data3); | 94 | err_data_buffer[cpu].data3); |
| @@ -117,8 +117,8 @@ store_call_start(struct device *dev, struct device_attribute *attr, · 22 unmodified lines | |||
| 117 | 117 | ||
| 118 | #ifdef ERR_INJ_DEBUG | 118 | #ifdef ERR_INJ_DEBUG |
| 119 | printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); | 119 | printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); |
| 120 | printk(KERN_DEBUG "capabilities=%lx,\n", capabilities[cpu]); | 120 | printk(KERN_DEBUG "capabilities=%llx,\n", capabilities[cpu]); |
| 121 | printk(KERN_DEBUG "resources=%lx\n", resources[cpu]); | 121 | printk(KERN_DEBUG "resources=%llx\n", resources[cpu]); |
| 122 | #endif | 122 | #endif |
| 123 | return size; | 123 | return size; |
| 124 | } | 124 | } |
| @@ -131,7 +131,7 @@ show_virtual_to_phys(struct device *dev, struct device_attribute *attr, · 6 unmodified lines | |||
| 131 | char *buf) | 131 | char *buf) |
| 132 | { | 132 | { |
| 133 | unsigned int cpu=dev->id; | 133 | unsigned int cpu=dev->id; |
| 134 | return sprintf(buf, "%lx\n", phys_addr[cpu]); | 134 | return sprintf(buf, "%llx\n", phys_addr[cpu]); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static ssize_t | 137 | static ssize_t |
| @@ -145,7 +145,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr, · 7 unmodified lines | |||
| 145 | ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL); | 145 | ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL); |
| 146 | if (ret<=0) { | 146 | if (ret<=0) { |
| 147 | #ifdef ERR_INJ_DEBUG | 147 | #ifdef ERR_INJ_DEBUG |
| 148 | printk("Virtual address %lx is not existing.\n",virt_addr); | 148 | printk("Virtual address %llx is not existing.\n", virt_addr); |
| 149 | #endif | 149 | #endif |
| 150 | return -EINVAL; | 150 | return -EINVAL; |
| 151 | } | 151 | } |
| @@ -163,7 +163,7 @@ show_err_data_buffer(struct device *dev, · 11 unmodified lines | |||
| 163 | { | 163 | { |
| 164 | unsigned int cpu=dev->id; | 164 | unsigned int cpu=dev->id; |
| 165 | 165 | ||
| 166 | return sprintf(buf, "%lx, %lx, %lx\n", | 166 | return sprintf(buf, "%llx, %llx, %llx\n", |
| 167 | err_data_buffer[cpu].data1, | 167 | err_data_buffer[cpu].data1, |
| 168 | err_data_buffer[cpu].data2, | 168 | err_data_buffer[cpu].data2, |
| 169 | err_data_buffer[cpu].data3); | 169 | err_data_buffer[cpu].data3); |
| @@ -178,13 +178,13 @@ store_err_data_buffer(struct device *dev, · 8 unmodified lines | |||
| 178 | int ret; | 178 | int ret; |
| 179 | 179 | ||
| 180 | #ifdef ERR_INJ_DEBUG | 180 | #ifdef ERR_INJ_DEBUG |
| 181 | printk("write err_data_buffer=[%lx,%lx,%lx] on cpu%d\n", | 181 | printk("write err_data_buffer=[%llx,%llx,%llx] on cpu%d\n", |
| 182 | err_data_buffer[cpu].data1, | 182 | err_data_buffer[cpu].data1, |
| 183 | err_data_buffer[cpu].data2, | 183 | err_data_buffer[cpu].data2, |
| 184 | err_data_buffer[cpu].data3, | 184 | err_data_buffer[cpu].data3, |
| 185 | cpu); | 185 | cpu); |
| 186 | #endif | 186 | #endif |
| 187 | ret=sscanf(buf, "%lx, %lx, %lx", | 187 | ret = sscanf(buf, "%llx, %llx, %llx", |
| 188 | &err_data_buffer[cpu].data1, | 188 | &err_data_buffer[cpu].data1, |
| 189 | &err_data_buffer[cpu].data2, | 189 | &err_data_buffer[cpu].data2, |
| 190 | &err_data_buffer[cpu].data3); | 190 | &err_data_buffer[cpu].data3); |
| @@ -1824,7 +1824,7 @@ ia64_mca_cpu_init(void *cpu_data) · 1823 unmodified lines | |||
| 1824 | data = mca_bootmem(); | 1824 | data = mca_bootmem(); |
| 1825 | first_time = 0; | 1825 | first_time = 0; |
| 1826 | } else | 1826 | } else |
| 1827 | data = (void *)__get_free_pages(GFP_KERNEL, | 1827 | data = (void *)__get_free_pages(GFP_ATOMIC, |
| 1828 | get_order(sz)); | 1828 | get_order(sz)); |
| 1829 | if (!data) | 1829 | if (!data) |
| 1830 | panic("Could not allocate MCA memory for cpu %d\n", | 1830 | panic("Could not allocate MCA memory for cpu %d\n", |
| @@ -2013,27 +2013,39 @@ static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data) · 2012 unmodified lines | |||
| 2013 | { | 2013 | { |
| 2014 | struct syscall_get_set_args *args = data; | 2014 | struct syscall_get_set_args *args = data; |
| 2015 | struct pt_regs *pt = args->regs; | 2015 | struct pt_regs *pt = args->regs; |
| 2016 | unsigned long *krbs, cfm, ndirty; | 2016 | unsigned long *krbs, cfm, ndirty, nlocals, nouts; |
| 2017 | int i, count; | 2017 | int i, count; |
| 2018 | 2018 | ||
| 2019 | if (unw_unwind_to_user(info) < 0) | 2019 | if (unw_unwind_to_user(info) < 0) |
| 2020 | return; | 2020 | return; |
| 2021 | 2021 | ||
| 2022 | /* | ||
| 2023 | * We get here via a few paths: | ||
| 2024 | * - break instruction: cfm is shared with caller. | ||
| 2025 | * syscall args are in out= regs, locals are non-empty. | ||
| 2026 | * - epsinstruction: cfm is set by br.call | ||
| 2027 | * locals don't exist. | ||
| 2028 | * | ||
| 2029 | * For both cases argguments are reachable in cfm.sof - cfm.sol. | ||
| 2030 | * CFM: [ ... | sor: 17..14 | sol : 13..7 | sof : 6..0 ] | ||
| 2031 | */ | ||
| 2022 | cfm = pt->cr_ifs; | 2032 | cfm = pt->cr_ifs; |
| 2033 | nlocals = (cfm >> 7) & 0x7f; /* aka sol */ | ||
| 2034 | nouts = (cfm & 0x7f) - nlocals; /* aka sof - sol */ | ||
| 2023 | krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8; | 2035 | krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8; |
| 2024 | ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); | 2036 | ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); |
| 2025 | 2037 | ||
| 2026 | count = 0; | 2038 | count = 0; |
| 2027 | if (in_syscall(pt)) | 2039 | if (in_syscall(pt)) |
| 2028 | count = min_t(int, args->n, cfm & 0x7f); | 2040 | count = min_t(int, args->n, nouts); |
| 2029 | 2041 | ||
| 2042 | /* Iterate over outs. */ | ||
| 2030 | for (i = 0; i < count; i++) { | 2043 | for (i = 0; i < count; i++) { |
| 2044 | int j = ndirty + nlocals + i + args->i; | ||
| 2031 | if (args->rw) | 2045 | if (args->rw) |
| 2032 | *ia64_rse_skip_regs(krbs, ndirty + i + args->i) = | 2046 | *ia64_rse_skip_regs(krbs, j) = args->args[i]; |
| 2033 | args->args[i]; | ||
| 2034 | else | 2047 | else |
| 2035 | args->args[i] = *ia64_rse_skip_regs(krbs, | 2048 | args->args[i] = *ia64_rse_skip_regs(krbs, j); |
| 2036 | ndirty + i + args->i); | ||
| 2037 | } | 2049 | } |
| 2038 | 2050 | ||
| 2039 | if (!args->rw) { | 2051 | if (!args->rw) { |
| @@ -176,7 +176,7 @@ SECTIONS · 175 unmodified lines | |||
| 176 | .fill : { | 176 | .fill : { |
| 177 | FILL(0); | 177 | FILL(0); |
| 178 | BYTE(0); | 178 | BYTE(0); |
| 179 | . = ALIGN(8); | 179 | STRUCT_ALIGN(); |
| 180 | } | 180 | } |
| 181 | __appended_dtb = .; | 181 | __appended_dtb = .; |
| 182 | /* leave space for appended DTB */ | 182 | /* leave space for appended DTB */ |
| @@ -73,9 +73,10 @@ void __patch_exception(int exc, unsigned long addr); · 72 unmodified lines | |||
| 73 | #endif | 73 | #endif |
| 74 | 74 | ||
| 75 | #define OP_RT_RA_MASK 0xffff0000UL | 75 | #define OP_RT_RA_MASK 0xffff0000UL |
| 76 | #define LIS_R2 0x3c020000UL | 76 | #define LIS_R2 (PPC_INST_ADDIS | __PPC_RT(R2)) |
| 77 | #define ADDIS_R2_R12 0x3c4c0000UL | 77 | #define ADDIS_R2_R12 (PPC_INST_ADDIS | __PPC_RT(R2) | __PPC_RA(R12)) |
| 78 | #define ADDI_R2_R2 0x38420000UL | 78 | #define ADDI_R2_R2 (PPC_INST_ADDI | __PPC_RT(R2) | __PPC_RA(R2)) |
| 79 | |||
| 79 | 80 | ||
| 80 | static inline unsigned long ppc_function_entry(void *func) | 81 | static inline unsigned long ppc_function_entry(void *func) |
| 81 | { | 82 | { |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | #include <linux/bug.h> | 7 | #include <linux/bug.h> |
| 8 | #include <asm/cputable.h> | 8 | #include <asm/cputable.h> |
| 9 | 9 | ||
| 10 | static inline bool early_cpu_has_feature(unsigned long feature) | 10 | static __always_inline bool early_cpu_has_feature(unsigned long feature) |
| 11 | { | 11 | { |
| 12 | return !!((CPU_FTRS_ALWAYS & feature) || | 12 | return !!((CPU_FTRS_ALWAYS & feature) || |
| 13 | (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); | 13 | (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); |
| @@ -46,7 +46,7 @@ static __always_inline bool cpu_has_feature(unsigned long feature) · 32 unmodified lines | |||
| 46 | return static_branch_likely(&cpu_feature_keys[i]); | 46 | return static_branch_likely(&cpu_feature_keys[i]); |
| 47 | } | 47 | } |
| 48 | #else | 48 | #else |
| 49 | static inline bool cpu_has_feature(unsigned long feature) | 49 | static __always_inline bool cpu_has_feature(unsigned long feature) |
| 50 | { | 50 | { |
| 51 | return early_cpu_has_feature(feature); | 51 | return early_cpu_has_feature(feature); |
| 52 | } | 52 | } |
| @@ -410,7 +410,6 @@ DECLARE_INTERRUPT_HANDLER(altivec_assist_exception); · 409 unmodified lines | |||
| 410 | DECLARE_INTERRUPT_HANDLER(CacheLockingException); | 410 | DECLARE_INTERRUPT_HANDLER(CacheLockingException); |
| 411 | DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException); | 411 | DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException); |
| 412 | DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException); | 412 | DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException); |
| 413 | DECLARE_INTERRUPT_HANDLER(unrecoverable_exception); | ||
| 414 | DECLARE_INTERRUPT_HANDLER(WatchdogException); | 413 | DECLARE_INTERRUPT_HANDLER(WatchdogException); |
| 415 | DECLARE_INTERRUPT_HANDLER(kernel_bad_stack); | 414 | DECLARE_INTERRUPT_HANDLER(kernel_bad_stack); |
| 416 | 415 | ||
| @@ -437,6 +436,8 @@ DECLARE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode); · 20 unmodified lines | |||
| 437 | 436 | ||
| 438 | DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException); | 437 | DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException); |
| 439 | 438 | ||
| 439 | void unrecoverable_exception(struct pt_regs *regs); | ||
| 440 | |||
| 440 | void replay_system_reset(void); | 441 | void replay_system_reset(void); |
| 441 | void replay_soft_interrupts(void); | 442 | void replay_soft_interrupts(void); |
| 442 | 443 | ||
| @@ -195,7 +195,7 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) · 194 unmodified lines | |||
| 195 | #define TRAP_FLAGS_MASK 0x11 | 195 | #define TRAP_FLAGS_MASK 0x11 |
| 196 | #define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK) | 196 | #define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK) |
| 197 | #define FULL_REGS(regs) (((regs)->trap & 1) == 0) | 197 | #define FULL_REGS(regs) (((regs)->trap & 1) == 0) |
| 198 | #define SET_FULL_REGS(regs) ((regs)->trap |= 1) | 198 | #define SET_FULL_REGS(regs) ((regs)->trap &= ~1) |
| 199 | #endif | 199 | #endif |
| 200 | #define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs)) | 200 | #define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs)) |
| 201 | #define NV_REG_POISON 0xdeadbeefdeadbeefUL | 201 | #define NV_REG_POISON 0xdeadbeefdeadbeefUL |
| @@ -210,7 +210,7 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) · 8 unmodified lines | |||
| 210 | #define TRAP_FLAGS_MASK 0x1F | 210 | #define TRAP_FLAGS_MASK 0x1F |
| 211 | #define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK) | 211 | #define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK) |
| 212 | #define FULL_REGS(regs) (((regs)->trap & 1) == 0) | 212 | #define FULL_REGS(regs) (((regs)->trap & 1) == 0) |
| 213 | #define SET_FULL_REGS(regs) ((regs)->trap |= 1) | 213 | #define SET_FULL_REGS(regs) ((regs)->trap &= ~1) |
| 214 | #define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0) | 214 | #define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0) |
| 215 | #define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0) | 215 | #define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0) |
| 216 | #define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0) | 216 | #define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0) |
| @@ -71,6 +71,16 @@ static inline void disable_kernel_vsx(void) · 70 unmodified lines | |||
| 71 | { | 71 | { |
| 72 | msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); | 72 | msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); |
| 73 | } | 73 | } |
| 74 | #else | ||
| 75 | static inline void enable_kernel_vsx(void) | ||
| 76 | { | ||
| 77 | BUILD_BUG(); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline void disable_kernel_vsx(void) | ||
| 81 | { | ||
| 82 | BUILD_BUG(); | ||
| 83 | } | ||
| 74 | #endif | 84 | #endif |
| 75 | 85 | ||
| 76 | #ifdef CONFIG_SPE | 86 | #ifdef CONFIG_SPE |
| @@ -466,7 +466,7 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real) · 465 unmodified lines | |||
| 466 | 466 | ||
| 467 | ld r10,PACAKMSR(r13) /* get MSR value for kernel */ | 467 | ld r10,PACAKMSR(r13) /* get MSR value for kernel */ |
| 468 | /* MSR[RI] is clear iff using SRR regs */ | 468 | /* MSR[RI] is clear iff using SRR regs */ |
| 469 | .if IHSRR == EXC_HV_OR_STD | 469 | .if IHSRR_IF_HVMODE |
| 470 | BEGIN_FTR_SECTION | 470 | BEGIN_FTR_SECTION |
| 471 | xori r10,r10,MSR_RI | 471 | xori r10,r10,MSR_RI |
| 472 | END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) | 472 | END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) |
| @@ -436,7 +436,6 @@ again: · 435 unmodified lines | |||
| 436 | return ret; | 436 | return ret; |
| 437 | } | 437 | } |
| 438 | 438 | ||
| 439 | void unrecoverable_exception(struct pt_regs *regs); | ||
| 440 | void preempt_schedule_irq(void); | 439 | void preempt_schedule_irq(void); |
| 441 | 440 | ||
| 442 | notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr) | 441 | notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr) |
| @@ -2170,7 +2170,7 @@ DEFINE_INTERRUPT_HANDLER(SPEFloatingPointRoundException) · 2169 unmodified lines | |||
| 2170 | * in the MSR is 0. This indicates that SRR0/1 are live, and that | 2170 | * in the MSR is 0. This indicates that SRR0/1 are live, and that |
| 2171 | * we therefore lost state by taking this exception. | 2171 | * we therefore lost state by taking this exception. |
| 2172 | */ | 2172 | */ |
| 2173 | DEFINE_INTERRUPT_HANDLER(unrecoverable_exception) | 2173 | void unrecoverable_exception(struct pt_regs *regs) |
| 2174 | { | 2174 | { |
| 2175 | pr_emerg("Unrecoverable exception %lx at %lx (msr=%lx)\n", | 2175 | pr_emerg("Unrecoverable exception %lx at %lx (msr=%lx)\n", |
| 2176 | regs->trap, regs->nip, regs->msr); | 2176 | regs->trap, regs->nip, regs->msr); |
| @@ -65,3 +65,14 @@ V_FUNCTION_END(__kernel_clock_getres) · 64 unmodified lines | |||
| 65 | V_FUNCTION_BEGIN(__kernel_time) | 65 | V_FUNCTION_BEGIN(__kernel_time) |
| 66 | cvdso_call_time __c_kernel_time | 66 | cvdso_call_time __c_kernel_time |
| 67 | V_FUNCTION_END(__kernel_time) | 67 | V_FUNCTION_END(__kernel_time) |
| 68 | |||
| 69 | /* Routines for restoring integer registers, called by the compiler. */ | ||
| 70 | /* Called with r11 pointing to the stack header word of the caller of the */ | ||
| 71 | /* function, just beyond the end of the integer restore area. */ | ||
| 72 | _GLOBAL(_restgpr_31_x) | ||
| 73 | _GLOBAL(_rest32gpr_31_x) | ||
| 74 | lwz r0,4(r11) | ||
| 75 | lwz r31,-4(r11) | ||
| 76 | mtlr r0 | ||
| 77 | mr r1,r11 | ||
| 78 | blr | ||
| @@ -93,7 +93,6 @@ config RISCV · 92 unmodified lines | |||
| 93 | select PCI_MSI if PCI | 93 | select PCI_MSI if PCI |
| 94 | select RISCV_INTC | 94 | select RISCV_INTC |
| 95 | select RISCV_TIMER if RISCV_SBI | 95 | select RISCV_TIMER if RISCV_SBI |
| 96 | select SPARSEMEM_STATIC if 32BIT | ||
| 97 | select SPARSE_IRQ | 96 | select SPARSE_IRQ |
| 98 | select SYSCTL_EXCEPTION_TRACE | 97 | select SYSCTL_EXCEPTION_TRACE |
| 99 | select THREAD_INFO_IN_TASK | 98 | select THREAD_INFO_IN_TASK |
| @@ -154,7 +153,8 @@ config ARCH_FLATMEM_ENABLE · 54 unmodified lines | |||
| 154 | config ARCH_SPARSEMEM_ENABLE | 153 | config ARCH_SPARSEMEM_ENABLE |
| 155 | def_bool y | 154 | def_bool y |
| 156 | depends on MMU | 155 | depends on MMU |
| 157 | select SPARSEMEM_VMEMMAP_ENABLE | 156 | select SPARSEMEM_STATIC if 32BIT && SPARSMEM |
| 157 | select SPARSEMEM_VMEMMAP_ENABLE if 64BIT | ||
| 158 | 158 | ||
| 159 | config ARCH_SELECT_MEMORY_MODEL | 159 | config ARCH_SELECT_MEMORY_MODEL |
| 160 | def_bool ARCH_SPARSEMEM_ENABLE | 160 | def_bool ARCH_SPARSEMEM_ENABLE |
| @@ -31,6 +31,8 @@ config SOC_CANAAN · 30 unmodified lines | |||
| 31 | select SIFIVE_PLIC | 31 | select SIFIVE_PLIC |
| 32 | select ARCH_HAS_RESET_CONTROLLER | 32 | select ARCH_HAS_RESET_CONTROLLER |
| 33 | select PINCTRL | 33 | select PINCTRL |
| 34 | select COMMON_CLK | ||
| 35 | select COMMON_CLK_K210 | ||
| 34 | help | 36 | help |
| 35 | This enables support for Canaan Kendryte K210 SoC platform hardware. | 37 | This enables support for Canaan Kendryte K210 SoC platform hardware. |
| 36 | 38 | ||
| @@ -9,4 +9,20 @@ long long __lshrti3(long long a, int b); · 8 unmodified lines | |||
| 9 | long long __ashrti3(long long a, int b); | 9 | long long __ashrti3(long long a, int b); |
| 10 | long long __ashlti3(long long a, int b); | 10 | long long __ashlti3(long long a, int b); |
| 11 | 11 | ||
| 12 | |||
| 13 | #define DECLARE_DO_ERROR_INFO(name) asmlinkage void name(struct pt_regs *regs) | ||
| 14 | |||
| 15 | DECLARE_DO_ERROR_INFO(do_trap_unknown); | ||
| 16 | DECLARE_DO_ERROR_INFO(do_trap_insn_misaligned); | ||
| 17 | DECLARE_DO_ERROR_INFO(do_trap_insn_fault); | ||
| 18 | DECLARE_DO_ERROR_INFO(do_trap_insn_illegal); | ||
| 19 | DECLARE_DO_ERROR_INFO(do_trap_load_fault); | ||
| 20 | DECLARE_DO_ERROR_INFO(do_trap_load_misaligned); | ||
| 21 | DECLARE_DO_ERROR_INFO(do_trap_store_misaligned); | ||
| 22 | DECLARE_DO_ERROR_INFO(do_trap_store_fault); | ||
| 23 | DECLARE_DO_ERROR_INFO(do_trap_ecall_u); | ||
| 24 | DECLARE_DO_ERROR_INFO(do_trap_ecall_s); | ||
| 25 | DECLARE_DO_ERROR_INFO(do_trap_ecall_m); | ||
| 26 | DECLARE_DO_ERROR_INFO(do_trap_break); | ||
| 27 | |||
| 12 | #endif /* _ASM_RISCV_PROTOTYPES_H */ | 28 | #endif /* _ASM_RISCV_PROTOTYPES_H */ |
| @@ -12,4 +12,6 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #include <asm-generic/irq.h> | 13 | #include <asm-generic/irq.h> |
| 14 | 14 | ||
| 15 | extern void __init init_IRQ(void); | ||
| 16 | |||
| 15 | #endif /* _ASM_RISCV_IRQ_H */ | 17 | #endif /* _ASM_RISCV_IRQ_H */ |
| @@ -71,6 +71,7 @@ int riscv_of_processor_hartid(struct device_node *node); · 70 unmodified lines | |||
| 71 | int riscv_of_parent_hartid(struct device_node *node); | 71 | int riscv_of_parent_hartid(struct device_node *node); |
| 72 | 72 | ||
| 73 | extern void riscv_fill_hwcap(void); | 73 | extern void riscv_fill_hwcap(void); |
| 74 | extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); | ||
| 74 | 75 | ||
| 75 | #endif /* __ASSEMBLY__ */ | 76 | #endif /* __ASSEMBLY__ */ |
| 76 | 77 | ||
| @@ -119,6 +119,11 @@ extern int regs_query_register_offset(const char *name); · 118 unmodified lines | |||
| 119 | extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, | 119 | extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, |
| 120 | unsigned int n); | 120 | unsigned int n); |
| 121 | 121 | ||
| 122 | void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | ||
| 123 | unsigned long frame_pointer); | ||
| 124 | int do_syscall_trace_enter(struct pt_regs *regs); | ||
| 125 | void do_syscall_trace_exit(struct pt_regs *regs); | ||
| 126 | |||
| 122 | /** | 127 | /** |
| 123 | * regs_get_register() - get register value from its offset | 128 | * regs_get_register() - get register value from its offset |
| 124 | * @regs: pt_regs from which register value is gotten | 129 | * @regs: pt_regs from which register value is gotten |
| @@ -51,10 +51,10 @@ enum sbi_ext_rfence_fid { · 50 unmodified lines | |||
| 51 | SBI_EXT_RFENCE_REMOTE_FENCE_I = 0, | 51 | SBI_EXT_RFENCE_REMOTE_FENCE_I = 0, |
| 52 | SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, | 52 | SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, |
| 53 | SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, | 53 | SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, |
| 54 | SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, | ||
| 55 | SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, | 54 | SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, |
| 56 | SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, | 55 | SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, |
| 57 | SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, | 56 | SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, |
| 57 | SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, | ||
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | enum sbi_ext_hsm_fid { | 60 | enum sbi_ext_hsm_fid { |
| @@ -88,4 +88,6 @@ static inline int read_current_timer(unsigned long *timer_val) · 87 unmodified lines | |||
| 88 | return 0; | 88 | return 0; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | extern void time_init(void); | ||
| 92 | |||
| 91 | #endif /* _ASM_RISCV_TIMEX_H */ | 93 | #endif /* _ASM_RISCV_TIMEX_H */ |
| @@ -8,6 +8,7 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) · 7 unmodified lines | |||
| 8 | CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) | 8 | CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) |
| 9 | CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) | 9 | CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) |
| 10 | endif | 10 | endif |
| 11 | CFLAGS_syscall_table.o += $(call cc-option,-Wno-override-init,) | ||
| 11 | 12 | ||
| 12 | extra-y += head.o | 13 | extra-y += head.o |
| 13 | extra-y += vmlinux.lds | 14 | extra-y += vmlinux.lds |
| @@ -2,39 +2,41 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | #include <linux/kprobes.h> | 3 | #include <linux/kprobes.h> |
| 4 | 4 | ||
| 5 | /* Ftrace callback handler for kprobes -- called under preepmt disabed */ | 5 | /* Ftrace callback handler for kprobes -- called under preepmt disabled */ |
| 6 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, | 6 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, |
| 7 | struct ftrace_ops *ops, struct ftrace_regs *regs) | 7 | struct ftrace_ops *ops, struct ftrace_regs *fregs) |
| 8 | { | 8 | { |
| 9 | struct kprobe *p; | 9 | struct kprobe *p; |
| 10 | struct pt_regs *regs; | ||
| 10 | struct kprobe_ctlblk *kcb; | 11 | struct kprobe_ctlblk *kcb; |
| 11 | 12 | ||
| 12 | p = get_kprobe((kprobe_opcode_t *)ip); | 13 | p = get_kprobe((kprobe_opcode_t *)ip); |
| 13 | if (unlikely(!p) || kprobe_disabled(p)) | 14 | if (unlikely(!p) || kprobe_disabled(p)) |
| 14 | return; | 15 | return; |
| 15 | 16 | ||
| 17 | regs = ftrace_get_regs(fregs); | ||
| 16 | kcb = get_kprobe_ctlblk(); | 18 | kcb = get_kprobe_ctlblk(); |
| 17 | if (kprobe_running()) { | 19 | if (kprobe_running()) { |
| 18 | kprobes_inc_nmissed_count(p); | 20 | kprobes_inc_nmissed_count(p); |
| 19 | } else { | 21 | } else { |
| 20 | unsigned long orig_ip = instruction_pointer(&(regs->regs)); | 22 | unsigned long orig_ip = instruction_pointer(regs); |
| 21 | 23 | ||
| 22 | instruction_pointer_set(&(regs->regs), ip); | 24 | instruction_pointer_set(regs, ip); |
| 23 | 25 | ||
| 24 | __this_cpu_write(current_kprobe, p); | 26 | __this_cpu_write(current_kprobe, p); |
| 25 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | 27 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
| 26 | if (!p->pre_handler || !p->pre_handler(p, &(regs->regs))) { | 28 | if (!p->pre_handler || !p->pre_handler(p, regs)) { |
| 27 | /* | 29 | /* |
| 28 | * Emulate singlestep (and also recover regs->pc) | 30 | * Emulate singlestep (and also recover regs->pc) |
| 29 | * as if there is a nop | 31 | * as if there is a nop |
| 30 | */ | 32 | */ |
| 31 | instruction_pointer_set(&(regs->regs), | 33 | instruction_pointer_set(regs, |
| 32 | (unsigned long)p->addr + MCOUNT_INSN_SIZE); | 34 | (unsigned long)p->addr + MCOUNT_INSN_SIZE); |
| 33 | if (unlikely(p->post_handler)) { | 35 | if (unlikely(p->post_handler)) { |
| 34 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | 36 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
| 35 | p->post_handler(p, &(regs->regs), 0); | 37 | p->post_handler(p, regs, 0); |
| 36 | } | 38 | } |
| 37 | instruction_pointer_set(&(regs->regs), orig_ip); | 39 | instruction_pointer_set(regs, orig_ip); |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | /* | 42 | /* |
| @@ -256,8 +256,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr) · 255 unmodified lines | |||
| 256 | * normal page fault. | 256 | * normal page fault. |
| 257 | */ | 257 | */ |
| 258 | regs->epc = (unsigned long) cur->addr; | 258 | regs->epc = (unsigned long) cur->addr; |
| 259 | if (!instruction_pointer(regs)) | 259 | BUG_ON(!instruction_pointer(regs)); |
| 260 | BUG(); | ||
| 261 | 260 | ||
| 262 | if (kcb->kprobe_status == KPROBE_REENTER) | 261 | if (kcb->kprobe_status == KPROBE_REENTER) |
| 263 | restore_previous_kprobe(kcb); | 262 | restore_previous_kprobe(kcb); |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <linux/cpu.h> | 10 | #include <linux/cpu.h> |
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 13 | #include <linux/sched/debug.h> | ||
| 13 | #include <linux/sched/task_stack.h> | 14 | #include <linux/sched/task_stack.h> |
| 14 | #include <linux/tick.h> | 15 | #include <linux/tick.h> |
| 15 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
| @@ -116,7 +116,7 @@ void sbi_clear_ipi(void) · 115 unmodified lines | |||
| 116 | EXPORT_SYMBOL(sbi_clear_ipi); | 116 | EXPORT_SYMBOL(sbi_clear_ipi); |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * sbi_set_timer_v01() - Program the timer for next timer event. | 119 | * __sbi_set_timer_v01() - Program the timer for next timer event. |
| 120 | * @stime_value: The value after which next timer event should fire. | 120 | * @stime_value: The value after which next timer event should fire. |
| 121 | * | 121 | * |
| 122 | * Return: None | 122 | * Return: None |
| @@ -147,7 +147,8 @@ static void __init init_resources(void) · 146 unmodified lines | |||
| 147 | bss_res.end = __pa_symbol(__bss_stop) - 1; | 147 | bss_res.end = __pa_symbol(__bss_stop) - 1; |
| 148 | bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; | 148 | bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 149 | 149 | ||
| 150 | mem_res_sz = (memblock.memory.cnt + memblock.reserved.cnt) * sizeof(*mem_res); | 150 | /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */ |
| 151 | mem_res_sz = (memblock.memory.cnt + memblock.reserved.cnt + 1) * sizeof(*mem_res); | ||
| 151 | mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES); | 152 | mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES); |
| 152 | if (!mem_res) | 153 | if (!mem_res) |
| 153 | panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz); | 154 | panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
| 10 | #include <asm/sbi.h> | 10 | #include <asm/sbi.h> |
| 11 | #include <asm/processor.h> | 11 | #include <asm/processor.h> |
| 12 | #include <asm/timex.h> | ||
| 12 | 13 | ||
| 13 | unsigned long riscv_timebase; | 14 | unsigned long riscv_timebase; |
| 14 | EXPORT_SYMBOL_GPL(riscv_timebase); | 15 | EXPORT_SYMBOL_GPL(riscv_timebase); |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
| 19 | 19 | ||
| 20 | #include <asm/asm-prototypes.h> | ||
| 20 | #include <asm/bug.h> | 21 | #include <asm/bug.h> |
| 21 | #include <asm/processor.h> | 22 | #include <asm/processor.h> |
| 22 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
| @@ -155,7 +155,7 @@ static void __init kasan_populate(void *start, void *end) · 154 unmodified lines | |||
| 155 | memset(start, KASAN_SHADOW_INIT, end - start); | 155 | memset(start, KASAN_SHADOW_INIT, end - start); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | void __init kasan_shallow_populate(void *start, void *end) | 158 | static void __init kasan_shallow_populate(void *start, void *end) |
| 159 | { | 159 | { |
| 160 | unsigned long vaddr = (unsigned long)start & PAGE_MASK; | 160 | unsigned long vaddr = (unsigned long)start & PAGE_MASK; |
| 161 | unsigned long vend = PAGE_ALIGN((unsigned long)end); | 161 | unsigned long vend = PAGE_ALIGN((unsigned long)end); |
| @@ -187,6 +187,8 @@ void __init kasan_shallow_populate(void *start, void *end) · 25 unmodified lines | |||
| 187 | } | 187 | } |
| 188 | vaddr += PAGE_SIZE; | 188 | vaddr += PAGE_SIZE; |
| 189 | } | 189 | } |
| 190 | |||
| 191 | local_flush_tlb_all(); | ||
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | void __init kasan_init(void) | 194 | void __init kasan_init(void) |
| @@ -275,9 +275,9 @@ CONFIG_IP_VS_DH=m · 274 unmodified lines | |||
| 275 | CONFIG_IP_VS_SH=m | 275 | CONFIG_IP_VS_SH=m |
| 276 | CONFIG_IP_VS_SED=m | 276 | CONFIG_IP_VS_SED=m |
| 277 | CONFIG_IP_VS_NQ=m | 277 | CONFIG_IP_VS_NQ=m |
| 278 | CONFIG_IP_VS_TWOS=m | ||
| 278 | CONFIG_IP_VS_FTP=m | 279 | CONFIG_IP_VS_FTP=m |
| 279 | CONFIG_IP_VS_PE_SIP=m | 280 | CONFIG_IP_VS_PE_SIP=m |
| 280 | CONFIG_NF_TABLES_IPV4=y | ||
| 281 | CONFIG_NFT_FIB_IPV4=m | 281 | CONFIG_NFT_FIB_IPV4=m |
| 282 | CONFIG_NF_TABLES_ARP=y | 282 | CONFIG_NF_TABLES_ARP=y |
| 283 | CONFIG_IP_NF_IPTABLES=m | 283 | CONFIG_IP_NF_IPTABLES=m |
| @@ -298,7 +298,6 @@ CONFIG_IP_NF_SECURITY=m · 14 unmodified lines | |||
| 298 | CONFIG_IP_NF_ARPTABLES=m | 298 | CONFIG_IP_NF_ARPTABLES=m |
| 299 | CONFIG_IP_NF_ARPFILTER=m | 299 | CONFIG_IP_NF_ARPFILTER=m |
| 300 | CONFIG_IP_NF_ARP_MANGLE=m | 300 | CONFIG_IP_NF_ARP_MANGLE=m |
| 301 | CONFIG_NF_TABLES_IPV6=y | ||
| 302 | CONFIG_NFT_FIB_IPV6=m | 301 | CONFIG_NFT_FIB_IPV6=m |
| 303 | CONFIG_IP6_NF_IPTABLES=m | 302 | CONFIG_IP6_NF_IPTABLES=m |
| 304 | CONFIG_IP6_NF_MATCH_AH=m | 303 | CONFIG_IP6_NF_MATCH_AH=m |
| @@ -481,7 +480,6 @@ CONFIG_NLMON=m · 176 unmodified lines | |||
| 481 | # CONFIG_NET_VENDOR_AQUANTIA is not set | 480 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 482 | # CONFIG_NET_VENDOR_ARC is not set | 481 | # CONFIG_NET_VENDOR_ARC is not set |
| 483 | # CONFIG_NET_VENDOR_ATHEROS is not set | 482 | # CONFIG_NET_VENDOR_ATHEROS is not set |
| 484 | # CONFIG_NET_VENDOR_AURORA is not set | ||
| 485 | # CONFIG_NET_VENDOR_BROADCOM is not set | 483 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 486 | # CONFIG_NET_VENDOR_BROCADE is not set | 484 | # CONFIG_NET_VENDOR_BROCADE is not set |
| 487 | # CONFIG_NET_VENDOR_CADENCE is not set | 485 | # CONFIG_NET_VENDOR_CADENCE is not set |
| @@ -581,7 +579,6 @@ CONFIG_VIRTIO_BALLOON=m · 93 unmodified lines | |||
| 581 | CONFIG_VIRTIO_INPUT=y | 579 | CONFIG_VIRTIO_INPUT=y |
| 582 | CONFIG_VHOST_NET=m | 580 | CONFIG_VHOST_NET=m |
| 583 | CONFIG_VHOST_VSOCK=m | 581 | CONFIG_VHOST_VSOCK=m |
| 584 | # CONFIG_SURFACE_PLATFORMS is not set | ||
| 585 | CONFIG_S390_CCW_IOMMU=y | 582 | CONFIG_S390_CCW_IOMMU=y |
| 586 | CONFIG_S390_AP_IOMMU=y | 583 | CONFIG_S390_AP_IOMMU=y |
| 587 | CONFIG_EXT4_FS=y | 584 | CONFIG_EXT4_FS=y |
| @@ -635,6 +632,7 @@ CONFIG_NTFS_RW=y · 47 unmodified lines | |||
| 635 | CONFIG_PROC_KCORE=y | 632 | CONFIG_PROC_KCORE=y |
| 636 | CONFIG_TMPFS=y | 633 | CONFIG_TMPFS=y |
| 637 | CONFIG_TMPFS_POSIX_ACL=y | 634 | CONFIG_TMPFS_POSIX_ACL=y |
| 635 | CONFIG_TMPFS_INODE64=y | ||
| 638 | CONFIG_HUGETLBFS=y | 636 | CONFIG_HUGETLBFS=y |
| 639 | CONFIG_CONFIGFS_FS=m | 637 | CONFIG_CONFIGFS_FS=m |
| 640 | CONFIG_ECRYPT_FS=m | 638 | CONFIG_ECRYPT_FS=m |
| @@ -714,12 +712,8 @@ CONFIG_CRYPTO_VMAC=m · 73 unmodified lines | |||
| 714 | CONFIG_CRYPTO_CRC32=m | 712 | CONFIG_CRYPTO_CRC32=m |
| 715 | CONFIG_CRYPTO_BLAKE2S=m | 713 | CONFIG_CRYPTO_BLAKE2S=m |
| 716 | CONFIG_CRYPTO_MICHAEL_MIC=m | 714 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 717 | CONFIG_CRYPTO_RMD128=m | ||
| 718 | CONFIG_CRYPTO_RMD160=m | 715 | CONFIG_CRYPTO_RMD160=m |
| 719 | CONFIG_CRYPTO_RMD256=m | ||
| 720 | CONFIG_CRYPTO_RMD320=m | ||
| 721 | CONFIG_CRYPTO_SHA3=m | 716 | CONFIG_CRYPTO_SHA3=m |
| 722 | CONFIG_CRYPTO_TGR192=m | ||
| 723 | CONFIG_CRYPTO_WP512=m | 717 | CONFIG_CRYPTO_WP512=m |
| 724 | CONFIG_CRYPTO_AES_TI=m | 718 | CONFIG_CRYPTO_AES_TI=m |
| 725 | CONFIG_CRYPTO_ANUBIS=m | 719 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -731,7 +725,6 @@ CONFIG_CRYPTO_CAST6=m · 5 unmodified lines | |||
| 731 | CONFIG_CRYPTO_DES=m | 725 | CONFIG_CRYPTO_DES=m |
| 732 | CONFIG_CRYPTO_FCRYPT=m | 726 | CONFIG_CRYPTO_FCRYPT=m |
| 733 | CONFIG_CRYPTO_KHAZAD=m | 727 | CONFIG_CRYPTO_KHAZAD=m |
| 734 | CONFIG_CRYPTO_SALSA20=m | ||
| 735 | CONFIG_CRYPTO_SEED=m | 728 | CONFIG_CRYPTO_SEED=m |
| 736 | CONFIG_CRYPTO_SERPENT=m | 729 | CONFIG_CRYPTO_SERPENT=m |
| 737 | CONFIG_CRYPTO_SM4=m | 730 | CONFIG_CRYPTO_SM4=m |
| @@ -796,12 +789,9 @@ CONFIG_DEBUG_OBJECTS_RCU_HEAD=y · 58 unmodified lines | |||
| 796 | CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y | 789 | CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y |
| 797 | CONFIG_SLUB_DEBUG_ON=y | 790 | CONFIG_SLUB_DEBUG_ON=y |
| 798 | CONFIG_SLUB_STATS=y | 791 | CONFIG_SLUB_STATS=y |
| 799 | CONFIG_DEBUG_KMEMLEAK=y | ||
| 800 | CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y | ||
| 801 | CONFIG_DEBUG_STACK_USAGE=y | 792 | CONFIG_DEBUG_STACK_USAGE=y |
| 802 | CONFIG_DEBUG_VM=y | 793 | CONFIG_DEBUG_VM=y |
| 803 | CONFIG_DEBUG_VM_VMACACHE=y | 794 | CONFIG_DEBUG_VM_VMACACHE=y |
| 804 | CONFIG_DEBUG_VM_RB=y | ||
| 805 | CONFIG_DEBUG_VM_PGFLAGS=y | 795 | CONFIG_DEBUG_VM_PGFLAGS=y |
| 806 | CONFIG_DEBUG_MEMORY_INIT=y | 796 | CONFIG_DEBUG_MEMORY_INIT=y |
| 807 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m | 797 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m |
| @@ -838,6 +828,7 @@ CONFIG_BPF_KPROBE_OVERRIDE=y · 30 unmodified lines | |||
| 838 | CONFIG_HIST_TRIGGERS=y | 828 | CONFIG_HIST_TRIGGERS=y |
| 839 | CONFIG_FTRACE_STARTUP_TEST=y | 829 | CONFIG_FTRACE_STARTUP_TEST=y |
| 840 | # CONFIG_EVENT_TRACE_STARTUP_TEST is not set | 830 | # CONFIG_EVENT_TRACE_STARTUP_TEST is not set |
| 831 | CONFIG_DEBUG_ENTRY=y | ||
| 841 | CONFIG_NOTIFIER_ERROR_INJECTION=m | 832 | CONFIG_NOTIFIER_ERROR_INJECTION=m |
| 842 | CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m | 833 | CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m |
| 843 | CONFIG_FAULT_INJECTION=y | 834 | CONFIG_FAULT_INJECTION=y |
| @@ -861,4 +852,3 @@ CONFIG_PERCPU_TEST=m · 17 unmodified lines | |||
| 861 | CONFIG_ATOMIC64_SELFTEST=y | 852 | CONFIG_ATOMIC64_SELFTEST=y |
| 862 | CONFIG_TEST_BITOPS=m | 853 | CONFIG_TEST_BITOPS=m |
| 863 | CONFIG_TEST_BPF=m | 854 | CONFIG_TEST_BPF=m |
| 864 | CONFIG_DEBUG_ENTRY=y | ||
| @@ -266,9 +266,9 @@ CONFIG_IP_VS_DH=m · 265 unmodified lines | |||
| 266 | CONFIG_IP_VS_SH=m | 266 | CONFIG_IP_VS_SH=m |
| 267 | CONFIG_IP_VS_SED=m | 267 | CONFIG_IP_VS_SED=m |
| 268 | CONFIG_IP_VS_NQ=m | 268 | CONFIG_IP_VS_NQ=m |
| 269 | CONFIG_IP_VS_TWOS=m | ||
| 269 | CONFIG_IP_VS_FTP=m | 270 | CONFIG_IP_VS_FTP=m |
| 270 | CONFIG_IP_VS_PE_SIP=m | 271 | CONFIG_IP_VS_PE_SIP=m |
| 271 | CONFIG_NF_TABLES_IPV4=y | ||
| 272 | CONFIG_NFT_FIB_IPV4=m | 272 | CONFIG_NFT_FIB_IPV4=m |
| 273 | CONFIG_NF_TABLES_ARP=y | 273 | CONFIG_NF_TABLES_ARP=y |
| 274 | CONFIG_IP_NF_IPTABLES=m | 274 | CONFIG_IP_NF_IPTABLES=m |
| @@ -289,7 +289,6 @@ CONFIG_IP_NF_SECURITY=m · 14 unmodified lines | |||
| 289 | CONFIG_IP_NF_ARPTABLES=m | 289 | CONFIG_IP_NF_ARPTABLES=m |
| 290 | CONFIG_IP_NF_ARPFILTER=m | 290 | CONFIG_IP_NF_ARPFILTER=m |
| 291 | CONFIG_IP_NF_ARP_MANGLE=m | 291 | CONFIG_IP_NF_ARP_MANGLE=m |
| 292 | CONFIG_NF_TABLES_IPV6=y | ||
| 293 | CONFIG_NFT_FIB_IPV6=m | 292 | CONFIG_NFT_FIB_IPV6=m |
| 294 | CONFIG_IP6_NF_IPTABLES=m | 293 | CONFIG_IP6_NF_IPTABLES=m |
| 295 | CONFIG_IP6_NF_MATCH_AH=m | 294 | CONFIG_IP6_NF_MATCH_AH=m |
| @@ -473,7 +472,6 @@ CONFIG_NLMON=m · 177 unmodified lines | |||
| 473 | # CONFIG_NET_VENDOR_AQUANTIA is not set | 472 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 474 | # CONFIG_NET_VENDOR_ARC is not set | 473 | # CONFIG_NET_VENDOR_ARC is not set |
| 475 | # CONFIG_NET_VENDOR_ATHEROS is not set | 474 | # CONFIG_NET_VENDOR_ATHEROS is not set |
| 476 | # CONFIG_NET_VENDOR_AURORA is not set | ||
| 477 | # CONFIG_NET_VENDOR_BROADCOM is not set | 475 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 478 | # CONFIG_NET_VENDOR_BROCADE is not set | 476 | # CONFIG_NET_VENDOR_BROCADE is not set |
| 479 | # CONFIG_NET_VENDOR_CADENCE is not set | 477 | # CONFIG_NET_VENDOR_CADENCE is not set |
| @@ -573,7 +571,6 @@ CONFIG_VIRTIO_BALLOON=m · 93 unmodified lines | |||
| 573 | CONFIG_VIRTIO_INPUT=y | 571 | CONFIG_VIRTIO_INPUT=y |
| 574 | CONFIG_VHOST_NET=m | 572 | CONFIG_VHOST_NET=m |
| 575 | CONFIG_VHOST_VSOCK=m | 573 | CONFIG_VHOST_VSOCK=m |
| 576 | # CONFIG_SURFACE_PLATFORMS is not set | ||
| 577 | CONFIG_S390_CCW_IOMMU=y | 574 | CONFIG_S390_CCW_IOMMU=y |
| 578 | CONFIG_S390_AP_IOMMU=y | 575 | CONFIG_S390_AP_IOMMU=y |
| 579 | CONFIG_EXT4_FS=y | 576 | CONFIG_EXT4_FS=y |
| @@ -623,6 +620,7 @@ CONFIG_NTFS_RW=y · 43 unmodified lines | |||
| 623 | CONFIG_PROC_KCORE=y | 620 | CONFIG_PROC_KCORE=y |
| 624 | CONFIG_TMPFS=y | 621 | CONFIG_TMPFS=y |
| 625 | CONFIG_TMPFS_POSIX_ACL=y | 622 | CONFIG_TMPFS_POSIX_ACL=y |
| 623 | CONFIG_TMPFS_INODE64=y | ||
| 626 | CONFIG_HUGETLBFS=y | 624 | CONFIG_HUGETLBFS=y |
| 627 | CONFIG_CONFIGFS_FS=m | 625 | CONFIG_CONFIGFS_FS=m |
| 628 | CONFIG_ECRYPT_FS=m | 626 | CONFIG_ECRYPT_FS=m |
| @@ -703,12 +701,8 @@ CONFIG_CRYPTO_VMAC=m · 74 unmodified lines | |||
| 703 | CONFIG_CRYPTO_CRC32=m | 701 | CONFIG_CRYPTO_CRC32=m |
| 704 | CONFIG_CRYPTO_BLAKE2S=m | 702 | CONFIG_CRYPTO_BLAKE2S=m |
| 705 | CONFIG_CRYPTO_MICHAEL_MIC=m | 703 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 706 | CONFIG_CRYPTO_RMD128=m | ||
| 707 | CONFIG_CRYPTO_RMD160=m | 704 | CONFIG_CRYPTO_RMD160=m |
| 708 | CONFIG_CRYPTO_RMD256=m | ||
| 709 | CONFIG_CRYPTO_RMD320=m | ||
| 710 | CONFIG_CRYPTO_SHA3=m | 705 | CONFIG_CRYPTO_SHA3=m |
| 711 | CONFIG_CRYPTO_TGR192=m | ||
| 712 | CONFIG_CRYPTO_WP512=m | 706 | CONFIG_CRYPTO_WP512=m |
| 713 | CONFIG_CRYPTO_AES_TI=m | 707 | CONFIG_CRYPTO_AES_TI=m |
| 714 | CONFIG_CRYPTO_ANUBIS=m | 708 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -720,7 +714,6 @@ CONFIG_CRYPTO_CAST6=m · 5 unmodified lines | |||
| 720 | CONFIG_CRYPTO_DES=m | 714 | CONFIG_CRYPTO_DES=m |
| 721 | CONFIG_CRYPTO_FCRYPT=m | 715 | CONFIG_CRYPTO_FCRYPT=m |
| 722 | CONFIG_CRYPTO_KHAZAD=m | 716 | CONFIG_CRYPTO_KHAZAD=m |
| 723 | CONFIG_CRYPTO_SALSA20=m | ||
| 724 | CONFIG_CRYPTO_SEED=m | 717 | CONFIG_CRYPTO_SEED=m |
| 725 | CONFIG_CRYPTO_SERPENT=m | 718 | CONFIG_CRYPTO_SERPENT=m |
| 726 | CONFIG_CRYPTO_SM4=m | 719 | CONFIG_CRYPTO_SM4=m |
| @@ -26,7 +26,6 @@ CONFIG_CRASH_DUMP=y · 25 unmodified lines | |||
| 26 | # CONFIG_SECCOMP is not set | 26 | # CONFIG_SECCOMP is not set |
| 27 | # CONFIG_GCC_PLUGINS is not set | 27 | # CONFIG_GCC_PLUGINS is not set |
| 28 | CONFIG_PARTITION_ADVANCED=y | 28 | CONFIG_PARTITION_ADVANCED=y |
| 29 | CONFIG_IBM_PARTITION=y | ||
| 30 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 29 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 31 | # CONFIG_COMPACTION is not set | 30 | # CONFIG_COMPACTION is not set |
| 32 | # CONFIG_MIGRATION is not set | 31 | # CONFIG_MIGRATION is not set |
| @@ -61,11 +60,9 @@ CONFIG_RAW_DRIVER=y · 28 unmodified lines | |||
| 61 | # CONFIG_HID is not set | 60 | # CONFIG_HID is not set |
| 62 | # CONFIG_VIRTIO_MENU is not set | 61 | # CONFIG_VIRTIO_MENU is not set |
| 63 | # CONFIG_VHOST_MENU is not set | 62 | # CONFIG_VHOST_MENU is not set |
| 64 | # CONFIG_SURFACE_PLATFORMS is not set | ||
| 65 | # CONFIG_IOMMU_SUPPORT is not set | 63 | # CONFIG_IOMMU_SUPPORT is not set |
| 66 | # CONFIG_DNOTIFY is not set | 64 | # CONFIG_DNOTIFY is not set |
| 67 | # CONFIG_INOTIFY_USER is not set | 65 | # CONFIG_INOTIFY_USER is not set |
| 68 | CONFIG_CONFIGFS_FS=y | ||
| 69 | # CONFIG_MISC_FILESYSTEMS is not set | 66 | # CONFIG_MISC_FILESYSTEMS is not set |
| 70 | # CONFIG_NETWORK_FILESYSTEMS is not set | 67 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 71 | CONFIG_LSM="yama,loadpin,safesetid,integrity" | 68 | CONFIG_LSM="yama,loadpin,safesetid,integrity" |
| @@ -14,12 +14,12 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | struct s390_idle_data { | 15 | struct s390_idle_data { |
| 16 | seqcount_t seqcount; | 16 | seqcount_t seqcount; |
| 17 | unsigned long long idle_count; | 17 | unsigned long idle_count; |
| 18 | unsigned long long idle_time; | 18 | unsigned long idle_time; |
| 19 | unsigned long long clock_idle_enter; | 19 | unsigned long clock_idle_enter; |
| 20 | unsigned long long clock_idle_exit; | 20 | unsigned long clock_idle_exit; |
| 21 | unsigned long long timer_idle_enter; | 21 | unsigned long timer_idle_enter; |
| 22 | unsigned long long timer_idle_exit; | 22 | unsigned long timer_idle_exit; |
| 23 | unsigned long mt_cycles_enter[8]; | 23 | unsigned long mt_cycles_enter[8]; |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| @@ -202,7 +202,7 @@ extern unsigned int s390_pci_no_rid; · 201 unmodified lines | |||
| 202 | ----------------------------------------------------------------------------- */ | 202 | ----------------------------------------------------------------------------- */ |
| 203 | /* Base stuff */ | 203 | /* Base stuff */ |
| 204 | int zpci_create_device(u32 fid, u32 fh, enum zpci_state state); | 204 | int zpci_create_device(u32 fid, u32 fh, enum zpci_state state); |
| 205 | void zpci_remove_device(struct zpci_dev *zdev); | 205 | void zpci_remove_device(struct zpci_dev *zdev, bool set_error); |
| 206 | int zpci_enable_device(struct zpci_dev *); | 206 | int zpci_enable_device(struct zpci_dev *); |
| 207 | int zpci_disable_device(struct zpci_dev *); | 207 | int zpci_disable_device(struct zpci_dev *); |
| 208 | int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); | 208 | int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); |
| @@ -98,10 +98,10 @@ extern unsigned char ptff_function_mask[16]; · 97 unmodified lines | |||
| 98 | 98 | ||
| 99 | /* Query TOD offset result */ | 99 | /* Query TOD offset result */ |
| 100 | struct ptff_qto { | 100 | struct ptff_qto { |
| 101 | unsigned long long physical_clock; | 101 | unsigned long physical_clock; |
| 102 | unsigned long long tod_offset; | 102 | unsigned long tod_offset; |
| 103 | unsigned long long logical_tod_offset; | 103 | unsigned long logical_tod_offset; |
| 104 | unsigned long long tod_epoch_difference; | 104 | unsigned long tod_epoch_difference; |
| 105 | } __packed; | 105 | } __packed; |
| 106 | 106 | ||
| 107 | static inline int ptff_query(unsigned int nr) | 107 | static inline int ptff_query(unsigned int nr) |
| @@ -151,9 +151,9 @@ struct ptff_qui { · 43 unmodified lines | |||
| 151 | rc; \ | 151 | rc; \ |
| 152 | }) | 152 | }) |
| 153 | 153 | ||
| 154 | static inline unsigned long long local_tick_disable(void) | 154 | static inline unsigned long local_tick_disable(void) |
| 155 | { | 155 | { |
| 156 | unsigned long long old; | 156 | unsigned long old; |
| 157 | 157 | ||
| 158 | old = S390_lowcore.clock_comparator; | 158 | old = S390_lowcore.clock_comparator; |
| 159 | S390_lowcore.clock_comparator = clock_comparator_max; | 159 | S390_lowcore.clock_comparator = clock_comparator_max; |
| @@ -161,7 +161,7 @@ static inline unsigned long long local_tick_disable(void) · 1 unmodified line | |||
| 161 | return old; | 161 | return old; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static inline void local_tick_enable(unsigned long long comp) | 164 | static inline void local_tick_enable(unsigned long comp) |
| 165 | { | 165 | { |
| 166 | S390_lowcore.clock_comparator = comp; | 166 | S390_lowcore.clock_comparator = comp; |
| 167 | set_clock_comparator(S390_lowcore.clock_comparator); | 167 | set_clock_comparator(S390_lowcore.clock_comparator); |
| @@ -169,9 +169,9 @@ static inline void local_tick_enable(unsigned long long comp) · 1 unmodified line | |||
| 169 | 169 | ||
| 170 | #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ | 170 | #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ |
| 171 | 171 | ||
| 172 | typedef unsigned long long cycles_t; | 172 | typedef unsigned long cycles_t; |
| 173 | 173 | ||
| 174 | static inline unsigned long long get_tod_clock(void) | 174 | static inline unsigned long get_tod_clock(void) |
| 175 | { | 175 | { |
| 176 | union tod_clock clk; | 176 | union tod_clock clk; |
| 177 | 177 | ||
| @@ -179,10 +179,10 @@ static inline unsigned long long get_tod_clock(void) · 1 unmodified line | |||
| 179 | return clk.tod; | 179 | return clk.tod; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static inline unsigned long long get_tod_clock_fast(void) | 182 | static inline unsigned long get_tod_clock_fast(void) |
| 183 | { | 183 | { |
| 184 | #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES | 184 | #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES |
| 185 | unsigned long long clk; | 185 | unsigned long clk; |
| 186 | 186 | ||
| 187 | asm volatile("stckf %0" : "=Q" (clk) : : "cc"); | 187 | asm volatile("stckf %0" : "=Q" (clk) : : "cc"); |
| 188 | return clk; | 188 | return clk; |
| @@ -208,9 +208,9 @@ extern union tod_clock tod_clock_base; · 19 unmodified lines | |||
| 208 | * Therefore preemption must be disabled, otherwise the returned | 208 | * Therefore preemption must be disabled, otherwise the returned |
| 209 | * value is not guaranteed to be monotonic. | 209 | * value is not guaranteed to be monotonic. |
| 210 | */ | 210 | */ |
| 211 | static inline unsigned long long get_tod_clock_monotonic(void) | 211 | static inline unsigned long get_tod_clock_monotonic(void) |
| 212 | { | 212 | { |
| 213 | unsigned long long tod; | 213 | unsigned long tod; |
| 214 | 214 | ||
| 215 | preempt_disable_notrace(); | 215 | preempt_disable_notrace(); |
| 216 | tod = get_tod_clock() - tod_clock_base.tod; | 216 | tod = get_tod_clock() - tod_clock_base.tod; |
| @@ -237,7 +237,7 @@ static inline unsigned long long get_tod_clock_monotonic(void) · 20 unmodified lines | |||
| 237 | * -> ns = (th * 125) + ((tl * 125) >> 9); | 237 | * -> ns = (th * 125) + ((tl * 125) >> 9); |
| 238 | * | 238 | * |
| 239 | */ | 239 | */ |
| 240 | static inline unsigned long long tod_to_ns(unsigned long long todval) | 240 | static inline unsigned long tod_to_ns(unsigned long todval) |
| 241 | { | 241 | { |
| 242 | return ((todval >> 9) * 125) + (((todval & 0x1ff) * 125) >> 9); | 242 | return ((todval >> 9) * 125) + (((todval & 0x1ff) * 125) >> 9); |
| 243 | } | 243 | } |
| @@ -249,10 +249,10 @@ static inline unsigned long long tod_to_ns(unsigned long long todval) · 5 unmodified lines | |||
| 249 | * | 249 | * |
| 250 | * Returns: true if a is later than b | 250 | * Returns: true if a is later than b |
| 251 | */ | 251 | */ |
| 252 | static inline int tod_after(unsigned long long a, unsigned long long b) | 252 | static inline int tod_after(unsigned long a, unsigned long b) |
| 253 | { | 253 | { |
| 254 | if (MACHINE_HAS_SCC) | 254 | if (MACHINE_HAS_SCC) |
| 255 | return (long long) a > (long long) b; | 255 | return (long) a > (long) b; |
| 256 | return a > b; | 256 | return a > b; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| @@ -263,10 +263,10 @@ static inline int tod_after(unsigned long long a, unsigned long long b) · 4 unmodified lines | |||
| 263 | * | 263 | * |
| 264 | * Returns: true if a is later than b | 264 | * Returns: true if a is later than b |
| 265 | */ | 265 | */ |
| 266 | static inline int tod_after_eq(unsigned long long a, unsigned long long b) | 266 | static inline int tod_after_eq(unsigned long a, unsigned long b) |
| 267 | { | 267 | { |
| 268 | if (MACHINE_HAS_SCC) | 268 | if (MACHINE_HAS_SCC) |
| 269 | return (long long) a >= (long long) b; | 269 | return (long) a >= (long) b; |
| 270 | return a >= b; | 270 | return a >= b; |
| 271 | } | 271 | } |
| 272 | 272 | ||
File renamed without changes.
| @@ -47,7 +47,7 @@ void account_idle_time_irq(void) · 46 unmodified lines | |||
| 47 | void arch_cpu_idle(void) | 47 | void arch_cpu_idle(void) |
| 48 | { | 48 | { |
| 49 | struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); | 49 | struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); |
| 50 | unsigned long long idle_time; | 50 | unsigned long idle_time; |
| 51 | unsigned long psw_mask; | 51 | unsigned long psw_mask; |
| 52 | 52 | ||
| 53 | /* Wait for external, I/O or machine check interrupt. */ | 53 | /* Wait for external, I/O or machine check interrupt. */ |
| @@ -73,7 +73,7 @@ static ssize_t show_idle_count(struct device *dev, · 19 unmodified lines | |||
| 73 | struct device_attribute *attr, char *buf) | 73 | struct device_attribute *attr, char *buf) |
| 74 | { | 74 | { |
| 75 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | 75 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); |
| 76 | unsigned long long idle_count; | 76 | unsigned long idle_count; |
| 77 | unsigned int seq; | 77 | unsigned int seq; |
| 78 | 78 | ||
| 79 | do { | 79 | do { |
| @@ -82,14 +82,14 @@ static ssize_t show_idle_count(struct device *dev, · 2 unmodified lines | |||
| 82 | if (READ_ONCE(idle->clock_idle_enter)) | 82 | if (READ_ONCE(idle->clock_idle_enter)) |
| 83 | idle_count++; | 83 | idle_count++; |
| 84 | } while (read_seqcount_retry(&idle->seqcount, seq)); | 84 | } while (read_seqcount_retry(&idle->seqcount, seq)); |
| 85 | return sprintf(buf, "%llu\n", idle_count); | 85 | return sprintf(buf, "%lu\n", idle_count); |
| 86 | } | 86 | } |
| 87 | DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); | 87 | DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); |
| 88 | 88 | ||
| 89 | static ssize_t show_idle_time(struct device *dev, | 89 | static ssize_t show_idle_time(struct device *dev, |
| 90 | struct device_attribute *attr, char *buf) | 90 | struct device_attribute *attr, char *buf) |
| 91 | { | 91 | { |
| 92 | unsigned long long now, idle_time, idle_enter, idle_exit, in_idle; | 92 | unsigned long now, idle_time, idle_enter, idle_exit, in_idle; |
| 93 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | 93 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); |
| 94 | unsigned int seq; | 94 | unsigned int seq; |
| 95 | 95 | ||
| @@ -109,14 +109,14 @@ static ssize_t show_idle_time(struct device *dev, · 13 unmodified lines | |||
| 109 | } | 109 | } |
| 110 | } | 110 | } |
| 111 | idle_time += in_idle; | 111 | idle_time += in_idle; |
| 112 | return sprintf(buf, "%llu\n", idle_time >> 12); | 112 | return sprintf(buf, "%lu\n", idle_time >> 12); |
| 113 | } | 113 | } |
| 114 | DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); | 114 | DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); |
| 115 | 115 | ||
| 116 | u64 arch_cpu_idle_time(int cpu) | 116 | u64 arch_cpu_idle_time(int cpu) |
| 117 | { | 117 | { |
| 118 | struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); | 118 | struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); |
| 119 | unsigned long long now, idle_enter, idle_exit, in_idle; | 119 | unsigned long now, idle_enter, idle_exit, in_idle; |
| 120 | unsigned int seq; | 120 | unsigned int seq; |
| 121 | 121 | ||
| 122 | do { | 122 | do { |
| @@ -269,7 +269,7 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type) · 268 unmodified lines | |||
| 269 | case CPUMF_CTR_SET_MAX: | 269 | case CPUMF_CTR_SET_MAX: |
| 270 | /* The counter could not be associated to a counter set */ | 270 | /* The counter could not be associated to a counter set */ |
| 271 | return -EINVAL; | 271 | return -EINVAL; |
| 272 | }; | 272 | } |
| 273 | 273 | ||
| 274 | /* Initialize for using the CPU-measurement counter facility */ | 274 | /* Initialize for using the CPU-measurement counter facility */ |
| 275 | if (!atomic_inc_not_zero(&num_events)) { | 275 | if (!atomic_inc_not_zero(&num_events)) { |
| @@ -26,12 +26,10 @@ · 25 unmodified lines | |||
| 26 | #include <asm/timex.h> | 26 | #include <asm/timex.h> |
| 27 | #include <asm/debug.h> | 27 | #include <asm/debug.h> |
| 28 | 28 | ||
| 29 | #include <asm/perf_cpum_cf_diag.h> | 29 | #include <asm/hwctrset.h> |
| 30 | 30 | ||
| 31 | #define CF_DIAG_CTRSET_DEF 0xfeef /* Counter set header mark */ | 31 | #define CF_DIAG_CTRSET_DEF 0xfeef /* Counter set header mark */ |
| 32 | #define CF_DIAG_MIN_INTERVAL 60 /* Minimum counter set read */ | ||
| 33 | /* interval in seconds */ | 32 | /* interval in seconds */ |
| 34 | static unsigned long cf_diag_interval = CF_DIAG_MIN_INTERVAL; | ||
| 35 | static unsigned int cf_diag_cpu_speed; | 33 | static unsigned int cf_diag_cpu_speed; |
| 36 | static debug_info_t *cf_diag_dbg; | 34 | static debug_info_t *cf_diag_dbg; |
| 37 | 35 | ||
| @@ -729,7 +727,6 @@ static DEFINE_MUTEX(cf_diag_ctrset_mutex); · 691 unmodified lines | |||
| 729 | static struct cf_diag_ctrset { | 727 | static struct cf_diag_ctrset { |
| 730 | unsigned long ctrset; /* Bit mask of counter set to read */ | 728 | unsigned long ctrset; /* Bit mask of counter set to read */ |
| 731 | cpumask_t mask; /* CPU mask to read from */ | 729 | cpumask_t mask; /* CPU mask to read from */ |
| 732 | time64_t lastread; /* Epoch counter set last read */ | ||
| 733 | } cf_diag_ctrset; | 730 | } cf_diag_ctrset; |
| 734 | 731 | ||
| 735 | static void cf_diag_ctrset_clear(void) | 732 | static void cf_diag_ctrset_clear(void) |
| @@ -866,27 +863,16 @@ static int cf_diag_all_read(unsigned long arg) · 130 unmodified lines | |||
| 866 | { | 863 | { |
| 867 | struct cf_diag_call_on_cpu_parm p; | 864 | struct cf_diag_call_on_cpu_parm p; |
| 868 | cpumask_var_t mask; | 865 | cpumask_var_t mask; |
| 869 | time64_t now; | 866 | int rc; |
| 870 | int rc = 0; | ||
| 871 | 867 | ||
| 872 | debug_sprintf_event(cf_diag_dbg, 5, "%s\n", __func__); | 868 | debug_sprintf_event(cf_diag_dbg, 5, "%s\n", __func__); |
| 873 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | 869 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
| 874 | return -ENOMEM; | 870 | return -ENOMEM; |
| 875 | now = ktime_get_seconds(); | 871 | |
| 876 | if (cf_diag_ctrset.lastread + cf_diag_interval > now) { | ||
| 877 | debug_sprintf_event(cf_diag_dbg, 5, "%s now %lld " | ||
| 878 | " lastread %lld\n", __func__, now, | ||
| 879 | cf_diag_ctrset.lastread); | ||
| 880 | rc = -EAGAIN; | ||
| 881 | goto out; | ||
| 882 | } else { | ||
| 883 | cf_diag_ctrset.lastread = now; | ||
| 884 | } | ||
| 885 | p.sets = cf_diag_ctrset.ctrset; | 872 | p.sets = cf_diag_ctrset.ctrset; |
| 886 | cpumask_and(mask, &cf_diag_ctrset.mask, cpu_online_mask); | 873 | cpumask_and(mask, &cf_diag_ctrset.mask, cpu_online_mask); |
| 887 | on_each_cpu_mask(mask, cf_diag_cpu_read, &p, 1); | 874 | on_each_cpu_mask(mask, cf_diag_cpu_read, &p, 1); |
| 888 | rc = cf_diag_all_copy(arg, mask); | 875 | rc = cf_diag_all_copy(arg, mask); |
| 889 | out: | ||
| 890 | free_cpumask_var(mask); | 876 | free_cpumask_var(mask); |
| 891 | debug_sprintf_event(cf_diag_dbg, 5, "%s rc %d\n", __func__, rc); | 877 | debug_sprintf_event(cf_diag_dbg, 5, "%s rc %d\n", __func__, rc); |
| 892 | return rc; | 878 | return rc; |
| @@ -982,7 +968,7 @@ static int cf_diag_all_start(void) · 89 unmodified lines | |||
| 982 | */ | 968 | */ |
| 983 | static size_t cf_diag_needspace(unsigned int sets) | 969 | static size_t cf_diag_needspace(unsigned int sets) |
| 984 | { | 970 | { |
| 985 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | 971 | struct cpu_cf_events *cpuhw = get_cpu_ptr(&cpu_cf_events); |
| 986 | size_t bytes = 0; | 972 | size_t bytes = 0; |
| 987 | int i; | 973 | int i; |
| 988 | 974 | ||
| @@ -998,6 +984,7 @@ static size_t cf_diag_needspace(unsigned int sets) · 9 unmodified lines | |||
| 998 | sizeof(((struct s390_ctrset_cpudata *)0)->no_sets)); | 984 | sizeof(((struct s390_ctrset_cpudata *)0)->no_sets)); |
| 999 | debug_sprintf_event(cf_diag_dbg, 5, "%s bytes %ld\n", __func__, | 985 | debug_sprintf_event(cf_diag_dbg, 5, "%s bytes %ld\n", __func__, |
| 1000 | bytes); | 986 | bytes); |
| 987 | put_cpu_ptr(&cpu_cf_events); | ||
| 1001 | return bytes; | 988 | return bytes; |
| 1002 | } | 989 | } |
| 1003 | 990 | ||
| @@ -68,10 +68,10 @@ EXPORT_SYMBOL(s390_epoch_delta_notifier); · 67 unmodified lines | |||
| 68 | 68 | ||
| 69 | unsigned char ptff_function_mask[16]; | 69 | unsigned char ptff_function_mask[16]; |
| 70 | 70 | ||
| 71 | static unsigned long long lpar_offset; | 71 | static unsigned long lpar_offset; |
| 72 | static unsigned long long initial_leap_seconds; | 72 | static unsigned long initial_leap_seconds; |
| 73 | static unsigned long long tod_steering_end; | 73 | static unsigned long tod_steering_end; |
| 74 | static long long tod_steering_delta; | 74 | static long tod_steering_delta; |
| 75 | 75 | ||
| 76 | /* | 76 | /* |
| 77 | * Get time offsets with PTFF | 77 | * Get time offsets with PTFF |
| @@ -96,7 +96,7 @@ void __init time_early_init(void) · 18 unmodified lines | |||
| 96 | 96 | ||
| 97 | /* get initial leap seconds */ | 97 | /* get initial leap seconds */ |
| 98 | if (ptff_query(PTFF_QUI) && ptff(&qui, sizeof(qui), PTFF_QUI) == 0) | 98 | if (ptff_query(PTFF_QUI) && ptff(&qui, sizeof(qui), PTFF_QUI) == 0) |
| 99 | initial_leap_seconds = (unsigned long long) | 99 | initial_leap_seconds = (unsigned long) |
| 100 | ((long) qui.old_leap * 4096000000L); | 100 | ((long) qui.old_leap * 4096000000L); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| @@ -222,7 +222,7 @@ void __init read_persistent_wall_and_boot_offset(struct timespec64 *wall_time, · 119 unmodified lines | |||
| 222 | 222 | ||
| 223 | static u64 read_tod_clock(struct clocksource *cs) | 223 | static u64 read_tod_clock(struct clocksource *cs) |
| 224 | { | 224 | { |
| 225 | unsigned long long now, adj; | 225 | unsigned long now, adj; |
| 226 | 226 | ||
| 227 | preempt_disable(); /* protect from changes to steering parameters */ | 227 | preempt_disable(); /* protect from changes to steering parameters */ |
| 228 | now = get_tod_clock(); | 228 | now = get_tod_clock(); |
| @@ -362,7 +362,7 @@ static inline int check_sync_clock(void) · 133 unmodified lines | |||
| 362 | * Apply clock delta to the global data structures. | 362 | * Apply clock delta to the global data structures. |
| 363 | * This is called once on the CPU that performed the clock sync. | 363 | * This is called once on the CPU that performed the clock sync. |
| 364 | */ | 364 | */ |
| 365 | static void clock_sync_global(unsigned long long delta) | 365 | static void clock_sync_global(unsigned long delta) |
| 366 | { | 366 | { |
| 367 | unsigned long now, adj; | 367 | unsigned long now, adj; |
| 368 | struct ptff_qto qto; | 368 | struct ptff_qto qto; |
| @@ -378,7 +378,7 @@ static void clock_sync_global(unsigned long long delta) · 9 unmodified lines | |||
| 378 | -(adj >> 15) : (adj >> 15); | 378 | -(adj >> 15) : (adj >> 15); |
| 379 | tod_steering_delta += delta; | 379 | tod_steering_delta += delta; |
| 380 | if ((abs(tod_steering_delta) >> 48) != 0) | 380 | if ((abs(tod_steering_delta) >> 48) != 0) |
| 381 | panic("TOD clock sync offset %lli is too large to drift\n", | 381 | panic("TOD clock sync offset %li is too large to drift\n", |
| 382 | tod_steering_delta); | 382 | tod_steering_delta); |
| 383 | tod_steering_end = now + (abs(tod_steering_delta) << 15); | 383 | tod_steering_end = now + (abs(tod_steering_delta) << 15); |
| 384 | vdso_data->arch_data.tod_steering_end = tod_steering_end; | 384 | vdso_data->arch_data.tod_steering_end = tod_steering_end; |
| @@ -394,7 +394,7 @@ static void clock_sync_global(unsigned long long delta) · 9 unmodified lines | |||
| 394 | * Apply clock delta to the per-CPU data structures of this CPU. | 394 | * Apply clock delta to the per-CPU data structures of this CPU. |
| 395 | * This is called for each online CPU after the call to clock_sync_global. | 395 | * This is called for each online CPU after the call to clock_sync_global. |
| 396 | */ | 396 | */ |
| 397 | static void clock_sync_local(unsigned long long delta) | 397 | static void clock_sync_local(unsigned long delta) |
| 398 | { | 398 | { |
| 399 | /* Add the delta to the clock comparator. */ | 399 | /* Add the delta to the clock comparator. */ |
| 400 | if (S390_lowcore.clock_comparator != clock_comparator_max) { | 400 | if (S390_lowcore.clock_comparator != clock_comparator_max) { |
| @@ -418,7 +418,7 @@ static void __init time_init_wq(void) · 17 unmodified lines | |||
| 418 | struct clock_sync_data { | 418 | struct clock_sync_data { |
| 419 | atomic_t cpus; | 419 | atomic_t cpus; |
| 420 | int in_sync; | 420 | int in_sync; |
| 421 | unsigned long long clock_delta; | 421 | unsigned long clock_delta; |
| 422 | }; | 422 | }; |
| 423 | 423 | ||
| 424 | /* | 424 | /* |
| @@ -538,7 +538,7 @@ static int stpinfo_valid(void) · 113 unmodified lines | |||
| 538 | static int stp_sync_clock(void *data) | 538 | static int stp_sync_clock(void *data) |
| 539 | { | 539 | { |
| 540 | struct clock_sync_data *sync = data; | 540 | struct clock_sync_data *sync = data; |
| 541 | unsigned long long clock_delta, flags; | 541 | u64 clock_delta, flags; |
| 542 | static int first; | 542 | static int first; |
| 543 | int rc; | 543 | int rc; |
| 544 | 544 | ||
| @@ -720,8 +720,8 @@ static ssize_t ctn_id_show(struct device *dev, · 175 unmodified lines | |||
| 720 | 720 | ||
| 721 | mutex_lock(&stp_mutex); | 721 | mutex_lock(&stp_mutex); |
| 722 | if (stpinfo_valid()) | 722 | if (stpinfo_valid()) |
| 723 | ret = sprintf(buf, "%016llx\n", | 723 | ret = sprintf(buf, "%016lx\n", |
| 724 | *(unsigned long long *) stp_info.ctnid); | 724 | *(unsigned long *) stp_info.ctnid); |
| 725 | mutex_unlock(&stp_mutex); | 725 | mutex_unlock(&stp_mutex); |
| 726 | return ret; | 726 | return ret; |
| 727 | } | 727 | } |
| @@ -794,7 +794,7 @@ static ssize_t leap_seconds_scheduled_show(struct device *dev, · 66 unmodified lines | |||
| 794 | if (!stzi.lsoib.p) | 794 | if (!stzi.lsoib.p) |
| 795 | return sprintf(buf, "0,0\n"); | 795 | return sprintf(buf, "0,0\n"); |
| 796 | 796 | ||
| 797 | return sprintf(buf, "%llu,%d\n", | 797 | return sprintf(buf, "%lu,%d\n", |
| 798 | tod_to_ns(stzi.lsoib.nlsout - TOD_UNIX_EPOCH) / NSEC_PER_SEC, | 798 | tod_to_ns(stzi.lsoib.nlsout - TOD_UNIX_EPOCH) / NSEC_PER_SEC, |
| 799 | stzi.lsoib.nlso - stzi.lsoib.also); | 799 | stzi.lsoib.nlso - stzi.lsoib.also); |
| 800 | } | 800 | } |
| @@ -76,8 +76,6 @@ static void cpu_group_map(cpumask_t *dst, struct mask_info *info, unsigned int c · 75 unmodified lines | |||
| 76 | } | 76 | } |
| 77 | info = info->next; | 77 | info = info->next; |
| 78 | } | 78 | } |
| 79 | if (cpumask_empty(&mask)) | ||
| 80 | cpumask_copy(&mask, cpumask_of(cpu)); | ||
| 81 | break; | 79 | break; |
| 82 | case TOPOLOGY_MODE_PACKAGE: | 80 | case TOPOLOGY_MODE_PACKAGE: |
| 83 | cpumask_copy(&mask, cpu_present_mask); | 81 | cpumask_copy(&mask, cpu_present_mask); |
| @@ -214,7 +214,7 @@ void vtime_flush(struct task_struct *tsk) · 213 unmodified lines | |||
| 214 | avg_steal = S390_lowcore.avg_steal_timer / 2; | 214 | avg_steal = S390_lowcore.avg_steal_timer / 2; |
| 215 | if ((s64) steal > 0) { | 215 | if ((s64) steal > 0) { |
| 216 | S390_lowcore.steal_timer = 0; | 216 | S390_lowcore.steal_timer = 0; |
| 217 | account_steal_time(steal); | 217 | account_steal_time(cputime_to_nsecs(steal)); |
| 218 | avg_steal += steal; | 218 | avg_steal += steal; |
| 219 | } | 219 | } |
| 220 | S390_lowcore.avg_steal_timer = avg_steal; | 220 | S390_lowcore.avg_steal_timer = avg_steal; |
| @@ -1287,7 +1287,7 @@ static u64 __calculate_sltime(struct kvm_vcpu *vcpu) · 1286 unmodified lines | |||
| 1287 | /* already expired? */ | 1287 | /* already expired? */ |
| 1288 | if (cputm >> 63) | 1288 | if (cputm >> 63) |
| 1289 | return 0; | 1289 | return 0; |
| 1290 | return min(sltime, tod_to_ns(cputm)); | 1290 | return min_t(u64, sltime, tod_to_ns(cputm)); |
| 1291 | } | 1291 | } |
| 1292 | } else if (cpu_timer_interrupts_enabled(vcpu)) { | 1292 | } else if (cpu_timer_interrupts_enabled(vcpu)) { |
| 1293 | sltime = kvm_s390_get_cpu_timer(vcpu); | 1293 | sltime = kvm_s390_get_cpu_timer(vcpu); |
| @@ -682,16 +682,36 @@ int zpci_disable_device(struct zpci_dev *zdev) · 681 unmodified lines | |||
| 682 | } | 682 | } |
| 683 | EXPORT_SYMBOL_GPL(zpci_disable_device); | 683 | EXPORT_SYMBOL_GPL(zpci_disable_device); |
| 684 | 684 | ||
| 685 | void zpci_remove_device(struct zpci_dev *zdev) | 685 | /* zpci_remove_device - Removes the given zdev from the PCI core |
| 686 | * @zdev: the zdev to be removed from the PCI core | ||
| 687 | * @set_error: if true the device's error state is set to permanent failure | ||
| 688 | * | ||
| 689 | * Sets a zPCI device to a configured but offline state; the zPCI | ||
| 690 | * device is still accessible through its hotplug slot and the zPCI | ||
| 691 | * API but is removed from the common code PCI bus, making it | ||
| 692 | * no longer available to drivers. | ||
| 693 | */ | ||
| 694 | void zpci_remove_device(struct zpci_dev *zdev, bool set_error) | ||
| 686 | { | 695 | { |
| 687 | struct zpci_bus *zbus = zdev->zbus; | 696 | struct zpci_bus *zbus = zdev->zbus; |
| 688 | struct pci_dev *pdev; | 697 | struct pci_dev *pdev; |
| 689 | 698 | ||
| 699 | if (!zdev->zbus->bus) | ||
| 700 | return; | ||
| 701 | |||
| 690 | pdev = pci_get_slot(zbus->bus, zdev->devfn); | 702 | pdev = pci_get_slot(zbus->bus, zdev->devfn); |
| 691 | if (pdev) { | 703 | if (pdev) { |
| 692 | if (pdev->is_virtfn) | 704 | if (set_error) |
| 693 | return zpci_iov_remove_virtfn(pdev, zdev->vfn); | 705 | pdev->error_state = pci_channel_io_perm_failure; |
| 706 | if (pdev->is_virtfn) { | ||
| 707 | zpci_iov_remove_virtfn(pdev, zdev->vfn); | ||
| 708 | /* balance pci_get_slot */ | ||
| 709 | pci_dev_put(pdev); | ||
| 710 | return; | ||
| 711 | } | ||
| 694 | pci_stop_and_remove_bus_device_locked(pdev); | 712 | pci_stop_and_remove_bus_device_locked(pdev); |
| 713 | /* balance pci_get_slot */ | ||
| 714 | pci_dev_put(pdev); | ||
| 695 | } | 715 | } |
| 696 | } | 716 | } |
| 697 | 717 | ||
| @@ -765,7 +785,7 @@ void zpci_release_device(struct kref *kref) · 67 unmodified lines | |||
| 765 | struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); | 785 | struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); |
| 766 | 786 | ||
| 767 | if (zdev->zbus->bus) | 787 | if (zdev->zbus->bus) |
| 768 | zpci_remove_device(zdev); | 788 | zpci_remove_device(zdev, false); |
| 769 | 789 | ||
| 770 | switch (zdev->state) { | 790 | switch (zdev->state) { |
| 771 | case ZPCI_FN_STATE_ONLINE: | 791 | case ZPCI_FN_STATE_ONLINE: |
| @@ -76,13 +76,10 @@ void zpci_event_error(void *data) · 75 unmodified lines | |||
| 76 | static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) | 76 | static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) |
| 77 | { | 77 | { |
| 78 | struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); | 78 | struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); |
| 79 | struct pci_dev *pdev = NULL; | ||
| 80 | enum zpci_state state; | 79 | enum zpci_state state; |
| 80 | struct pci_dev *pdev; | ||
| 81 | int ret; | 81 | int ret; |
| 82 | 82 | ||
| 83 | if (zdev && zdev->zbus->bus) | ||
| 84 | pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); | ||
| 85 | |||
| 86 | zpci_err("avail CCDF:\n"); | 83 | zpci_err("avail CCDF:\n"); |
| 87 | zpci_err_hex(ccdf, sizeof(*ccdf)); | 84 | zpci_err_hex(ccdf, sizeof(*ccdf)); |
| 88 | 85 | ||
| @@ -124,8 +121,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) · 35 unmodified lines | |||
| 124 | case 0x0303: /* Deconfiguration requested */ | 121 | case 0x0303: /* Deconfiguration requested */ |
| 125 | if (!zdev) | 122 | if (!zdev) |
| 126 | break; | 123 | break; |
| 127 | if (pdev) | 124 | zpci_remove_device(zdev, false); |
| 128 | zpci_remove_device(zdev); | ||
| 129 | 125 | ||
| 130 | ret = zpci_disable_device(zdev); | 126 | ret = zpci_disable_device(zdev); |
| 131 | if (ret) | 127 | if (ret) |
| @@ -140,12 +136,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) · 8 unmodified lines | |||
| 140 | case 0x0304: /* Configured -> Standby|Reserved */ | 136 | case 0x0304: /* Configured -> Standby|Reserved */ |
| 141 | if (!zdev) | 137 | if (!zdev) |
| 142 | break; | 138 | break; |
| 143 | if (pdev) { | 139 | /* Give the driver a hint that the function is |
| 144 | /* Give the driver a hint that the function is | 140 | * already unusable. |
| 145 | * already unusable. */ | 141 | */ |
| 146 | pdev->error_state = pci_channel_io_perm_failure; | 142 | zpci_remove_device(zdev, true); |
| 147 | zpci_remove_device(zdev); | ||
| 148 | } | ||
| 149 | 143 | ||
| 150 | zdev->fh = ccdf->fh; | 144 | zdev->fh = ccdf->fh; |
| 151 | zpci_disable_device(zdev); | 145 | zpci_disable_device(zdev); |
| @@ -128,7 +128,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) · 127 unmodified lines | |||
| 128 | regs->ax = -EFAULT; | 128 | regs->ax = -EFAULT; |
| 129 | 129 | ||
| 130 | instrumentation_end(); | 130 | instrumentation_end(); |
| 131 | syscall_exit_to_user_mode(regs); | 131 | local_irq_disable(); |
| 132 | irqentry_exit_to_user_mode(regs); | ||
| 132 | return false; | 133 | return false; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| @@ -210,6 +210,8 @@ SYM_CODE_START(entry_SYSCALL_compat) · 209 unmodified lines | |||
| 210 | /* Switch to the kernel stack */ | 210 | /* Switch to the kernel stack */ |
| 211 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp | 211 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| 212 | 212 | ||
| 213 | SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL) | ||
| 214 | |||
| 213 | /* Construct struct pt_regs on stack */ | 215 | /* Construct struct pt_regs on stack */ |
| 214 | pushq $__USER32_DS /* pt_regs->ss */ | 216 | pushq $__USER32_DS /* pt_regs->ss */ |
| 215 | pushq %r8 /* pt_regs->sp */ | 217 | pushq %r8 /* pt_regs->sp */ |
| @@ -81,7 +81,11 @@ DEFINE_STATIC_CALL_NULL(x86_pmu_swap_task_ctx, *x86_pmu.swap_task_ctx); · 80 unmodified lines | |||
| 81 | DEFINE_STATIC_CALL_NULL(x86_pmu_drain_pebs, *x86_pmu.drain_pebs); | 81 | DEFINE_STATIC_CALL_NULL(x86_pmu_drain_pebs, *x86_pmu.drain_pebs); |
| 82 | DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases); | 82 | DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases); |
| 83 | 83 | ||
| 84 | DEFINE_STATIC_CALL_NULL(x86_pmu_guest_get_msrs, *x86_pmu.guest_get_msrs); | 84 | /* |
| 85 | * This one is magic, it will get called even when PMU init fails (because | ||
| 86 | * there is no PMU), in which case it should simply return NULL. | ||
| 87 | */ | ||
| 88 | DEFINE_STATIC_CALL_RET0(x86_pmu_guest_get_msrs, *x86_pmu.guest_get_msrs); | ||
| 85 | 89 | ||
| 86 | u64 __read_mostly hw_cache_event_ids | 90 | u64 __read_mostly hw_cache_event_ids |
| 87 | [PERF_COUNT_HW_CACHE_MAX] | 91 | [PERF_COUNT_HW_CACHE_MAX] |
| @@ -1944,13 +1948,6 @@ static void _x86_pmu_read(struct perf_event *event) · 1856 unmodified lines | |||
| 1944 | x86_perf_event_update(event); | 1948 | x86_perf_event_update(event); |
| 1945 | } | 1949 | } |
| 1946 | 1950 | ||
| 1947 | static inline struct perf_guest_switch_msr * | ||
| 1948 | perf_guest_get_msrs_nop(int *nr) | ||
| 1949 | { | ||
| 1950 | *nr = 0; | ||
| 1951 | return NULL; | ||
| 1952 | } | ||
| 1953 | |||
| 1954 | static int __init init_hw_perf_events(void) | 1951 | static int __init init_hw_perf_events(void) |
| 1955 | { | 1952 | { |
| 1956 | struct x86_pmu_quirk *quirk; | 1953 | struct x86_pmu_quirk *quirk; |
| @@ -2025,7 +2022,7 @@ static int __init init_hw_perf_events(void) · 68 unmodified lines | |||
| 2025 | x86_pmu.read = _x86_pmu_read; | 2022 | x86_pmu.read = _x86_pmu_read; |
| 2026 | 2023 | ||
| 2027 | if (!x86_pmu.guest_get_msrs) | 2024 | if (!x86_pmu.guest_get_msrs) |
| 2028 | x86_pmu.guest_get_msrs = perf_guest_get_msrs_nop; | 2025 | x86_pmu.guest_get_msrs = (void *)&__static_call_return0; |
| 2029 | 2026 | ||
| 2030 | x86_pmu_static_call_update(); | 2027 | x86_pmu_static_call_update(); |
| 2031 | 2028 | ||
| @@ -3659,11 +3659,16 @@ static int intel_pmu_hw_config(struct perf_event *event) · 3658 unmodified lines | |||
| 3659 | return ret; | 3659 | return ret; |
| 3660 | 3660 | ||
| 3661 | if (event->attr.precise_ip) { | 3661 | if (event->attr.precise_ip) { |
| 3662 | if ((event->attr.config & INTEL_ARCH_EVENT_MASK) == INTEL_FIXED_VLBR_EVENT) | ||
| 3663 | return -EINVAL; | ||
| 3664 | |||
| 3662 | if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) { | 3665 | if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) { |
| 3663 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; | 3666 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; |
| 3664 | if (!(event->attr.sample_type & | 3667 | if (!(event->attr.sample_type & |
| 3665 | ~intel_pmu_large_pebs_flags(event))) | 3668 | ~intel_pmu_large_pebs_flags(event))) { |
| 3666 | event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS; | 3669 | event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS; |
| 3670 | event->attach_state |= PERF_ATTACH_SCHED_CB; | ||
| 3671 | } | ||
| 3667 | } | 3672 | } |
| 3668 | if (x86_pmu.pebs_aliases) | 3673 | if (x86_pmu.pebs_aliases) |
| 3669 | x86_pmu.pebs_aliases(event); | 3674 | x86_pmu.pebs_aliases(event); |
| @@ -3676,6 +3681,7 @@ static int intel_pmu_hw_config(struct perf_event *event) · 6 unmodified lines | |||
| 3676 | ret = intel_pmu_setup_lbr_filter(event); | 3681 | ret = intel_pmu_setup_lbr_filter(event); |
| 3677 | if (ret) | 3682 | if (ret) |
| 3678 | return ret; | 3683 | return ret; |
| 3684 | event->attach_state |= PERF_ATTACH_SCHED_CB; | ||
| 3679 | 3685 | ||
| 3680 | /* | 3686 | /* |
| 3681 | * BTS is set up earlier in this path, so don't account twice | 3687 | * BTS is set up earlier in this path, so don't account twice |
| @@ -2010,7 +2010,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d · 2009 unmodified lines | |||
| 2010 | */ | 2010 | */ |
| 2011 | if (!pebs_status && cpuc->pebs_enabled && | 2011 | if (!pebs_status && cpuc->pebs_enabled && |
| 2012 | !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1))) | 2012 | !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1))) |
| 2013 | pebs_status = cpuc->pebs_enabled; | 2013 | pebs_status = p->status = cpuc->pebs_enabled; |
| 2014 | 2014 | ||
| 2015 | bit = find_first_bit((unsigned long *)&pebs_status, | 2015 | bit = find_first_bit((unsigned long *)&pebs_status, |
| 2016 | x86_pmu.max_pebs_events); | 2016 | x86_pmu.max_pebs_events); |
| @@ -23,6 +23,8 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); · 22 unmodified lines | |||
| 23 | int insn_get_code_seg_params(struct pt_regs *regs); | 23 | int insn_get_code_seg_params(struct pt_regs *regs); |
| 24 | int insn_fetch_from_user(struct pt_regs *regs, | 24 | int insn_fetch_from_user(struct pt_regs *regs, |
| 25 | unsigned char buf[MAX_INSN_SIZE]); | 25 | unsigned char buf[MAX_INSN_SIZE]); |
| 26 | int insn_fetch_from_user_inatomic(struct pt_regs *regs, | ||
| 27 | unsigned char buf[MAX_INSN_SIZE]); | ||
| 26 | bool insn_decode(struct insn *insn, struct pt_regs *regs, | 28 | bool insn_decode(struct insn *insn, struct pt_regs *regs, |
| 27 | unsigned char buf[MAX_INSN_SIZE], int buf_size); | 29 | unsigned char buf[MAX_INSN_SIZE], int buf_size); |
| 28 | 30 | ||
| @@ -884,12 +884,29 @@ struct kvm_hv_syndbg { · 883 unmodified lines | |||
| 884 | u64 options; | 884 | u64 options; |
| 885 | }; | 885 | }; |
| 886 | 886 | ||
| 887 | /* Current state of Hyper-V TSC page clocksource */ | ||
| 888 | enum hv_tsc_page_status { | ||
| 889 | /* TSC page was not set up or disabled */ | ||
| 890 | HV_TSC_PAGE_UNSET = 0, | ||
| 891 | /* TSC page MSR was written by the guest, update pending */ | ||
| 892 | HV_TSC_PAGE_GUEST_CHANGED, | ||
| 893 | /* TSC page MSR was written by KVM userspace, update pending */ | ||
| 894 | HV_TSC_PAGE_HOST_CHANGED, | ||
| 895 | /* TSC page was properly set up and is currently active */ | ||
| 896 | HV_TSC_PAGE_SET, | ||
| 897 | /* TSC page is currently being updated and therefore is inactive */ | ||
| 898 | HV_TSC_PAGE_UPDATING, | ||
| 899 | /* TSC page was set up with an inaccessible GPA */ | ||
| 900 | HV_TSC_PAGE_BROKEN, | ||
| 901 | }; | ||
| 902 | |||
| 887 | /* Hyper-V emulation context */ | 903 | /* Hyper-V emulation context */ |
| 888 | struct kvm_hv { | 904 | struct kvm_hv { |
| 889 | struct mutex hv_lock; | 905 | struct mutex hv_lock; |
| 890 | u64 hv_guest_os_id; | 906 | u64 hv_guest_os_id; |
| 891 | u64 hv_hypercall; | 907 | u64 hv_hypercall; |
| 892 | u64 hv_tsc_page; | 908 | u64 hv_tsc_page; |
| 909 | enum hv_tsc_page_status hv_tsc_page_status; | ||
| 893 | 910 | ||
| 894 | /* Hyper-v based guest crash (NT kernel bugcheck) parameters */ | 911 | /* Hyper-v based guest crash (NT kernel bugcheck) parameters */ |
| 895 | u64 hv_crash_param[HV_X64_MSR_CRASH_PARAMS]; | 912 | u64 hv_crash_param[HV_X64_MSR_CRASH_PARAMS]; |
| @@ -931,6 +948,12 @@ enum kvm_irqchip_mode { · 35 unmodified lines | |||
| 931 | KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */ | 948 | KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */ |
| 932 | }; | 949 | }; |
| 933 | 950 | ||
| 951 | struct kvm_x86_msr_filter { | ||
| 952 | u8 count; | ||
| 953 | bool default_allow:1; | ||
| 954 | struct msr_bitmap_range ranges[16]; | ||
| 955 | }; | ||
| 956 | |||
| 934 | #define APICV_INHIBIT_REASON_DISABLE 0 | 957 | #define APICV_INHIBIT_REASON_DISABLE 0 |
| 935 | #define APICV_INHIBIT_REASON_HYPERV 1 | 958 | #define APICV_INHIBIT_REASON_HYPERV 1 |
| 936 | #define APICV_INHIBIT_REASON_NESTED 2 | 959 | #define APICV_INHIBIT_REASON_NESTED 2 |
| @@ -963,7 +986,7 @@ struct kvm_arch { · 26 unmodified lines | |||
| 963 | struct kvm_pit *vpit; | 986 | struct kvm_pit *vpit; |
| 964 | atomic_t vapics_in_nmi_mode; | 987 | atomic_t vapics_in_nmi_mode; |
| 965 | struct mutex apic_map_lock; | 988 | struct mutex apic_map_lock; |
| 966 | struct kvm_apic_map *apic_map; | 989 | struct kvm_apic_map __rcu *apic_map; |
| 967 | atomic_t apic_map_dirty; | 990 | atomic_t apic_map_dirty; |
| 968 | 991 | ||
| 969 | bool apic_access_page_done; | 992 | bool apic_access_page_done; |
| @@ -1025,18 +1048,13 @@ struct kvm_arch { · 55 unmodified lines | |||
| 1025 | bool guest_can_read_msr_platform_info; | 1048 | bool guest_can_read_msr_platform_info; |
| 1026 | bool exception_payload_enabled; | 1049 | bool exception_payload_enabled; |
| 1027 | 1050 | ||
| 1051 | bool bus_lock_detection_enabled; | ||
| 1052 | |||
| 1028 | /* Deflect RDMSR and WRMSR to user space when they trigger a #GP */ | 1053 | /* Deflect RDMSR and WRMSR to user space when they trigger a #GP */ |
| 1029 | u32 user_space_msr_mask; | 1054 | u32 user_space_msr_mask; |
| 1055 | struct kvm_x86_msr_filter __rcu *msr_filter; | ||
| 1030 | 1056 | ||
| 1031 | struct { | 1057 | struct kvm_pmu_event_filter __rcu *pmu_event_filter; |
| 1032 | u8 count; | ||
| 1033 | bool default_allow:1; | ||
| 1034 | struct msr_bitmap_range ranges[16]; | ||
| 1035 | } msr_filter; | ||
| 1036 | |||
| 1037 | bool bus_lock_detection_enabled; | ||
| 1038 | |||
| 1039 | struct kvm_pmu_event_filter *pmu_event_filter; | ||
| 1040 | struct task_struct *nx_lpage_recovery_thread; | 1058 | struct task_struct *nx_lpage_recovery_thread; |
| 1041 | 1059 | ||
| 1042 | #ifdef CONFIG_X86_64 | 1060 | #ifdef CONFIG_X86_64 |
| @@ -551,15 +551,6 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset, · 550 unmodified lines | |||
| 551 | *size = fpu_kernel_xstate_size; | 551 | *size = fpu_kernel_xstate_size; |
| 552 | } | 552 | } |
| 553 | 553 | ||
| 554 | /* | ||
| 555 | * Thread-synchronous status. | ||
| 556 | * | ||
| 557 | * This is different from the flags in that nobody else | ||
| 558 | * ever touches our thread-synchronous status, so we don't | ||
| 559 | * have to worry about atomic accesses. | ||
| 560 | */ | ||
| 561 | #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ | ||
| 562 | |||
| 563 | static inline void | 554 | static inline void |
| 564 | native_load_sp0(unsigned long sp0) | 555 | native_load_sp0(unsigned long sp0) |
| 565 | { | 556 | { |
| @@ -25,6 +25,7 @@ void __end_SYSENTER_singlestep_region(void); · 24 unmodified lines | |||
| 25 | void entry_SYSENTER_compat(void); | 25 | void entry_SYSENTER_compat(void); |
| 26 | void __end_entry_SYSENTER_compat(void); | 26 | void __end_entry_SYSENTER_compat(void); |
| 27 | void entry_SYSCALL_compat(void); | 27 | void entry_SYSCALL_compat(void); |
| 28 | void entry_SYSCALL_compat_safe_stack(void); | ||
| 28 | void entry_INT80_compat(void); | 29 | void entry_INT80_compat(void); |
| 29 | #ifdef CONFIG_XEN_PV | 30 | #ifdef CONFIG_XEN_PV |
| 30 | void xen_entry_INT80_compat(void); | 31 | void xen_entry_INT80_compat(void); |
| @@ -94,6 +94,8 @@ struct pt_regs { · 93 unmodified lines | |||
| 94 | #include <asm/paravirt_types.h> | 94 | #include <asm/paravirt_types.h> |
| 95 | #endif | 95 | #endif |
| 96 | 96 | ||
| 97 | #include <asm/proto.h> | ||
| 98 | |||
| 97 | struct cpuinfo_x86; | 99 | struct cpuinfo_x86; |
| 98 | struct task_struct; | 100 | struct task_struct; |
| 99 | 101 | ||
| @@ -175,6 +177,19 @@ static inline bool any_64bit_mode(struct pt_regs *regs) · 75 unmodified lines | |||
| 175 | #ifdef CONFIG_X86_64 | 177 | #ifdef CONFIG_X86_64 |
| 176 | #define current_user_stack_pointer() current_pt_regs()->sp | 178 | #define current_user_stack_pointer() current_pt_regs()->sp |
| 177 | #define compat_user_stack_pointer() current_pt_regs()->sp | 179 | #define compat_user_stack_pointer() current_pt_regs()->sp |
| 180 | |||
| 181 | static inline bool ip_within_syscall_gap(struct pt_regs *regs) | ||
| 182 | { | ||
| 183 | bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 && | ||
| 184 | regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack); | ||
| 185 | |||
| 186 | #ifdef CONFIG_IA32_EMULATION | ||
| 187 | ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat && | ||
| 188 | regs->ip < (unsigned long)entry_SYSCALL_compat_safe_stack); | ||
| 189 | #endif | ||
| 190 | |||
| 191 | return ret; | ||
| 192 | } | ||
| 178 | #endif | 193 | #endif |
| 179 | 194 | ||
| 180 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | 195 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) |
| @@ -58,9 +58,8 @@ static __always_inline unsigned long smap_save(void) · 57 unmodified lines | |||
| 58 | unsigned long flags; | 58 | unsigned long flags; |
| 59 | 59 | ||
| 60 | asm volatile ("# smap_save\n\t" | 60 | asm volatile ("# smap_save\n\t" |
| 61 | ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP) | 61 | ALTERNATIVE("", "pushf; pop %0; " __ASM_CLAC "\n\t", |
| 62 | "pushf; pop %0; " __ASM_CLAC "\n\t" | 62 | X86_FEATURE_SMAP) |
| 63 | "1:" | ||
| 64 | : "=rm" (flags) : : "memory", "cc"); | 63 | : "=rm" (flags) : : "memory", "cc"); |
| 65 | 64 | ||
| 66 | return flags; | 65 | return flags; |
| @@ -69,9 +68,8 @@ static __always_inline unsigned long smap_save(void) · 2 unmodified lines | |||
| 69 | static __always_inline void smap_restore(unsigned long flags) | 68 | static __always_inline void smap_restore(unsigned long flags) |
| 70 | { | 69 | { |
| 71 | asm volatile ("# smap_restore\n\t" | 70 | asm volatile ("# smap_restore\n\t" |
| 72 | ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP) | 71 | ALTERNATIVE("", "push %0; popf\n\t", |
| 73 | "push %0; popf\n\t" | 72 | X86_FEATURE_SMAP) |
| 74 | "1:" | ||
| 75 | : : "g" (flags) : "memory", "cc"); | 73 | : : "g" (flags) : "memory", "cc"); |
| 76 | } | 74 | } |
| 77 | 75 | ||
| @@ -205,10 +205,23 @@ static inline int arch_within_stack_frames(const void * const stack, · 204 unmodified lines | |||
| 205 | 205 | ||
| 206 | #endif | 206 | #endif |
| 207 | 207 | ||
| 208 | /* | ||
| 209 | * Thread-synchronous status. | ||
| 210 | * | ||
| 211 | * This is different from the flags in that nobody else | ||
| 212 | * ever touches our thread-synchronous status, so we don't | ||
| 213 | * have to worry about atomic accesses. | ||
| 214 | */ | ||
| 215 | #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ | ||
| 216 | |||
| 217 | #ifndef __ASSEMBLY__ | ||
| 208 | #ifdef CONFIG_COMPAT | 218 | #ifdef CONFIG_COMPAT |
| 209 | #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ | 219 | #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ |
| 220 | |||
| 221 | #define arch_set_restart_data(restart) \ | ||
| 222 | do { restart->arch_data = current_thread_info()->status; } while (0) | ||
| 223 | |||
| 210 | #endif | 224 | #endif |
| 211 | #ifndef __ASSEMBLY__ | ||
| 212 | 225 | ||
| 213 | #ifdef CONFIG_X86_32 | 226 | #ifdef CONFIG_X86_32 |
| 214 | #define in_ia32_syscall() true | 227 | #define in_ia32_syscall() true |
| @@ -2342,6 +2342,11 @@ static int cpuid_to_apicid[] = { · 2341 unmodified lines | |||
| 2342 | [0 ... NR_CPUS - 1] = -1, | 2342 | [0 ... NR_CPUS - 1] = -1, |
| 2343 | }; | 2343 | }; |
| 2344 | 2344 | ||
| 2345 | bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | ||
| 2346 | { | ||
| 2347 | return phys_id == cpuid_to_apicid[cpu]; | ||
| 2348 | } | ||
| 2349 | |||
| 2345 | #ifdef CONFIG_SMP | 2350 | #ifdef CONFIG_SMP |
| 2346 | /** | 2351 | /** |
| 2347 | * apic_id_is_primary_thread - Check whether APIC ID belongs to a primary thread | 2352 | * apic_id_is_primary_thread - Check whether APIC ID belongs to a primary thread |
| @@ -1032,6 +1032,16 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, · 1031 unmodified lines | |||
| 1032 | if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) { | 1032 | if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) { |
| 1033 | irq = mp_irqs[idx].srcbusirq; | 1033 | irq = mp_irqs[idx].srcbusirq; |
| 1034 | legacy = mp_is_legacy_irq(irq); | 1034 | legacy = mp_is_legacy_irq(irq); |
| 1035 | /* | ||
| 1036 | * IRQ2 is unusable for historical reasons on systems which | ||
| 1037 | * have a legacy PIC. See the comment vs. IRQ2 further down. | ||
| 1038 | * | ||
| 1039 | * If this gets removed at some point then the related code | ||
| 1040 | * in lapic_assign_system_vectors() needs to be adjusted as | ||
| 1041 | * well. | ||
| 1042 | */ | ||
| 1043 | if (legacy && irq == PIC_CASCADE_IR) | ||
| 1044 | return -EINVAL; | ||
| 1035 | } | 1045 | } |
| 1036 | 1046 | ||
| 1037 | mutex_lock(&ioapic_mutex); | 1047 | mutex_lock(&ioapic_mutex); |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #include "common.h" | 13 | #include "common.h" |
| 14 | 14 | ||
| 15 | /* Ftrace callback handler for kprobes -- called under preepmt disabed */ | 15 | /* Ftrace callback handler for kprobes -- called under preepmt disabled */ |
| 16 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, | 16 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, |
| 17 | struct ftrace_ops *ops, struct ftrace_regs *fregs) | 17 | struct ftrace_ops *ops, struct ftrace_regs *fregs) |
| 18 | { | 18 | { |
| @@ -836,28 +836,25 @@ static void kvm_kick_cpu(int cpu) · 835 unmodified lines | |||
| 836 | 836 | ||
| 837 | static void kvm_wait(u8 *ptr, u8 val) | 837 | static void kvm_wait(u8 *ptr, u8 val) |
| 838 | { | 838 | { |
| 839 | unsigned long flags; | ||
| 840 | |||
| 841 | if (in_nmi()) | 839 | if (in_nmi()) |
| 842 | return; | 840 | return; |
| 843 | 841 | ||
| 844 | local_irq_save(flags); | ||
| 845 | |||
| 846 | if (READ_ONCE(*ptr) != val) | ||
| 847 | goto out; | ||
| 848 | |||
| 849 | /* | 842 | /* |
| 850 | * halt until it's our turn and kicked. Note that we do safe halt | 843 | * halt until it's our turn and kicked. Note that we do safe halt |
| 851 | * for irq enabled case to avoid hang when lock info is overwritten | 844 | * for irq enabled case to avoid hang when lock info is overwritten |
| 852 | * in irq spinlock slowpath and no spurious interrupt occur to save us. | 845 | * in irq spinlock slowpath and no spurious interrupt occur to save us. |
| 853 | */ | 846 | */ |
| 854 | if (arch_irqs_disabled_flags(flags)) | 847 | if (irqs_disabled()) { |
| 855 | halt(); | 848 | if (READ_ONCE(*ptr) == val) |
| 856 | else | 849 | halt(); |
| 857 | safe_halt(); | 850 | } else { |
| 851 | local_irq_disable(); | ||
| 858 | 852 | ||
| 859 | out: | 853 | if (READ_ONCE(*ptr) == val) |
| 860 | local_irq_restore(flags); | 854 | safe_halt(); |
| 855 | |||
| 856 | local_irq_enable(); | ||
| 857 | } | ||
| 861 | } | 858 | } |
| 862 | 859 | ||
| 863 | #ifdef CONFIG_X86_32 | 860 | #ifdef CONFIG_X86_32 |
| @@ -268,21 +268,20 @@ static void __init kvmclock_init_mem(void) · 267 unmodified lines | |||
| 268 | 268 | ||
| 269 | static int __init kvm_setup_vsyscall_timeinfo(void) | 269 | static int __init kvm_setup_vsyscall_timeinfo(void) |
| 270 | { | 270 | { |
| 271 | #ifdef CONFIG_X86_64 | 271 | kvmclock_init_mem(); |
| 272 | u8 flags; | ||
| 273 | 272 | ||
| 274 | if (!per_cpu(hv_clock_per_cpu, 0) || !kvmclock_vsyscall) | 273 | #ifdef CONFIG_X86_64 |
| 275 | return 0; | 274 | if (per_cpu(hv_clock_per_cpu, 0) && kvmclock_vsyscall) { |
| 275 | u8 flags; | ||
| 276 | 276 | ||
| 277 | flags = pvclock_read_flags(&hv_clock_boot[0].pvti); | 277 | flags = pvclock_read_flags(&hv_clock_boot[0].pvti); |
| 278 | if (!(flags & PVCLOCK_TSC_STABLE_BIT)) | 278 | if (!(flags & PVCLOCK_TSC_STABLE_BIT)) |
| 279 | return 0; | 279 | return 0; |
| 280 | 280 | ||
| 281 | kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK; | 281 | kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK; |
| 282 | } | ||
| 282 | #endif | 283 | #endif |
| 283 | 284 | ||
| 284 | kvmclock_init_mem(); | ||
| 285 | |||
| 286 | return 0; | 285 | return 0; |
| 287 | } | 286 | } |
| 288 | early_initcall(kvm_setup_vsyscall_timeinfo); | 287 | early_initcall(kvm_setup_vsyscall_timeinfo); |
| @@ -121,8 +121,18 @@ static void __init setup_vc_stacks(int cpu) · 120 unmodified lines | |||
| 121 | cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); | 121 | cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static __always_inline bool on_vc_stack(unsigned long sp) | 124 | static __always_inline bool on_vc_stack(struct pt_regs *regs) |
| 125 | { | 125 | { |
| 126 | unsigned long sp = regs->sp; | ||
| 127 | |||
| 128 | /* User-mode RSP is not trusted */ | ||
| 129 | if (user_mode(regs)) | ||
| 130 | return false; | ||
| 131 | |||
| 132 | /* SYSCALL gap still has user-mode RSP */ | ||
| 133 | if (ip_within_syscall_gap(regs)) | ||
| 134 | return false; | ||
| 135 | |||
| 126 | return ((sp >= __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_top_va(VC))); | 136 | return ((sp >= __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_top_va(VC))); |
| 127 | } | 137 | } |
| 128 | 138 | ||
| @@ -144,7 +154,7 @@ void noinstr __sev_es_ist_enter(struct pt_regs *regs) · 15 unmodified lines | |||
| 144 | old_ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]); | 154 | old_ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]); |
| 145 | 155 | ||
| 146 | /* Make room on the IST stack */ | 156 | /* Make room on the IST stack */ |
| 147 | if (on_vc_stack(regs->sp)) | 157 | if (on_vc_stack(regs)) |
| 148 | new_ist = ALIGN_DOWN(regs->sp, 8) - sizeof(old_ist); | 158 | new_ist = ALIGN_DOWN(regs->sp, 8) - sizeof(old_ist); |
| 149 | else | 159 | else |
| 150 | new_ist = old_ist - sizeof(old_ist); | 160 | new_ist = old_ist - sizeof(old_ist); |
| @@ -248,7 +258,7 @@ static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) · 97 unmodified lines | |||
| 248 | int res; | 258 | int res; |
| 249 | 259 | ||
| 250 | if (user_mode(ctxt->regs)) { | 260 | if (user_mode(ctxt->regs)) { |
| 251 | res = insn_fetch_from_user(ctxt->regs, buffer); | 261 | res = insn_fetch_from_user_inatomic(ctxt->regs, buffer); |
| 252 | if (!res) { | 262 | if (!res) { |
| 253 | ctxt->fi.vector = X86_TRAP_PF; | 263 | ctxt->fi.vector = X86_TRAP_PF; |
| 254 | ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER; | 264 | ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER; |
| @@ -1248,13 +1258,12 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs) · 993 unmodified lines | |||
| 1248 | DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) | 1258 | DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) |
| 1249 | { | 1259 | { |
| 1250 | struct sev_es_runtime_data *data = this_cpu_read(runtime_data); | 1260 | struct sev_es_runtime_data *data = this_cpu_read(runtime_data); |
| 1261 | irqentry_state_t irq_state; | ||
| 1251 | struct ghcb_state state; | 1262 | struct ghcb_state state; |
| 1252 | struct es_em_ctxt ctxt; | 1263 | struct es_em_ctxt ctxt; |
| 1253 | enum es_result result; | 1264 | enum es_result result; |
| 1254 | struct ghcb *ghcb; | 1265 | struct ghcb *ghcb; |
| 1255 | 1266 | ||
| 1256 | lockdep_assert_irqs_disabled(); | ||
| 1257 | |||
| 1258 | /* | 1267 | /* |
| 1259 | * Handle #DB before calling into !noinstr code to avoid recursive #DB. | 1268 | * Handle #DB before calling into !noinstr code to avoid recursive #DB. |
| 1260 | */ | 1269 | */ |
| @@ -1263,6 +1272,8 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) · 2 unmodified lines | |||
| 1263 | return; | 1272 | return; |
| 1264 | } | 1273 | } |
| 1265 | 1274 | ||
| 1275 | irq_state = irqentry_nmi_enter(regs); | ||
| 1276 | lockdep_assert_irqs_disabled(); | ||
| 1266 | instrumentation_begin(); | 1277 | instrumentation_begin(); |
| 1267 | 1278 | ||
| 1268 | /* | 1279 | /* |
| @@ -1325,6 +1336,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) · 56 unmodified lines | |||
| 1325 | 1336 | ||
| 1326 | out: | 1337 | out: |
| 1327 | instrumentation_end(); | 1338 | instrumentation_end(); |
| 1339 | irqentry_nmi_exit(regs, irq_state); | ||
| 1328 | 1340 | ||
| 1329 | return; | 1341 | return; |
| 1330 | 1342 | ||
| @@ -766,30 +766,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) · 765 unmodified lines | |||
| 766 | 766 | ||
| 767 | static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) | 767 | static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) |
| 768 | { | 768 | { |
| 769 | /* | ||
| 770 | * This function is fundamentally broken as currently | ||
| 771 | * implemented. | ||
| 772 | * | ||
| 773 | * The idea is that we want to trigger a call to the | ||
| 774 | * restart_block() syscall and that we want in_ia32_syscall(), | ||
| 775 | * in_x32_syscall(), etc. to match whatever they were in the | ||
| 776 | * syscall being restarted. We assume that the syscall | ||
| 777 | * instruction at (regs->ip - 2) matches whatever syscall | ||
| 778 | * instruction we used to enter in the first place. | ||
| 779 | * | ||
| 780 | * The problem is that we can get here when ptrace pokes | ||
| 781 | * syscall-like values into regs even if we're not in a syscall | ||
| 782 | * at all. | ||
| 783 | * | ||
| 784 | * For now, we maintain historical behavior and guess based on | ||
| 785 | * stored state. We could do better by saving the actual | ||
| 786 | * syscall arch in restart_block or (with caveats on x32) by | ||
| 787 | * checking if regs->ip points to 'int $0x80'. The current | ||
| 788 | * behavior is incorrect if a tracer has a different bitness | ||
| 789 | * than the tracee. | ||
| 790 | */ | ||
| 791 | #ifdef CONFIG_IA32_EMULATION | 769 | #ifdef CONFIG_IA32_EMULATION |
| 792 | if (current_thread_info()->status & (TS_COMPAT|TS_I386_REGS_POKED)) | 770 | if (current->restart_block.arch_data & TS_COMPAT) |
| 793 | return __NR_ia32_restart_syscall; | 771 | return __NR_ia32_restart_syscall; |
| 794 | #endif | 772 | #endif |
| 795 | #ifdef CONFIG_X86_X32_ABI | 773 | #ifdef CONFIG_X86_X32_ABI |
| @@ -694,8 +694,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r · 693 unmodified lines | |||
| 694 | * In the SYSCALL entry path the RSP value comes from user-space - don't | 694 | * In the SYSCALL entry path the RSP value comes from user-space - don't |
| 695 | * trust it and switch to the current kernel stack | 695 | * trust it and switch to the current kernel stack |
| 696 | */ | 696 | */ |
| 697 | if (regs->ip >= (unsigned long)entry_SYSCALL_64 && | 697 | if (ip_within_syscall_gap(regs)) { |
| 698 | regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack) { | ||
| 699 | sp = this_cpu_read(cpu_current_top_of_stack); | 698 | sp = this_cpu_read(cpu_current_top_of_stack); |
| 700 | goto sync; | 699 | goto sync; |
| 701 | } | 700 | } |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | #define orc_warn_current(args...) \ | 14 | #define orc_warn_current(args...) \ |
| 15 | ({ \ | 15 | ({ \ |
| 16 | if (state->task == current) \ | 16 | if (state->task == current && !state->error) \ |
| 17 | orc_warn(args); \ | 17 | orc_warn(args); \ |
| 18 | }) | 18 | }) |
| 19 | 19 | ||
| @@ -367,8 +367,8 @@ static bool deref_stack_regs(struct unwind_state *state, unsigned long addr, · 347 unmodified lines | |||
| 367 | if (!stack_access_ok(state, addr, sizeof(struct pt_regs))) | 367 | if (!stack_access_ok(state, addr, sizeof(struct pt_regs))) |
| 368 | return false; | 368 | return false; |
| 369 | 369 | ||
| 370 | *ip = regs->ip; | 370 | *ip = READ_ONCE_NOCHECK(regs->ip); |
| 371 | *sp = regs->sp; | 371 | *sp = READ_ONCE_NOCHECK(regs->sp); |
| 372 | return true; | 372 | return true; |
| 373 | } | 373 | } |
| 374 | 374 | ||
| @@ -380,8 +380,8 @@ static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr · 5 unmodified lines | |||
| 380 | if (!stack_access_ok(state, addr, IRET_FRAME_SIZE)) | 380 | if (!stack_access_ok(state, addr, IRET_FRAME_SIZE)) |
| 381 | return false; | 381 | return false; |
| 382 | 382 | ||
| 383 | *ip = regs->ip; | 383 | *ip = READ_ONCE_NOCHECK(regs->ip); |
| 384 | *sp = regs->sp; | 384 | *sp = READ_ONCE_NOCHECK(regs->sp); |
| 385 | return true; | 385 | return true; |
| 386 | } | 386 | } |
| 387 | 387 | ||
| @@ -402,12 +402,12 @@ static bool get_reg(struct unwind_state *state, unsigned int reg_off, · 14 unmodified lines | |||
| 402 | return false; | 402 | return false; |
| 403 | 403 | ||
| 404 | if (state->full_regs) { | 404 | if (state->full_regs) { |
| 405 | *val = ((unsigned long *)state->regs)[reg]; | 405 | *val = READ_ONCE_NOCHECK(((unsigned long *)state->regs)[reg]); |
| 406 | return true; | 406 | return true; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | if (state->prev_regs) { | 409 | if (state->prev_regs) { |
| 410 | *val = ((unsigned long *)state->prev_regs)[reg]; | 410 | *val = READ_ONCE_NOCHECK(((unsigned long *)state->prev_regs)[reg]); |
| 411 | return true; | 411 | return true; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| @@ -520,10 +520,10 @@ static u64 get_time_ref_counter(struct kvm *kvm) · 519 unmodified lines | |||
| 520 | u64 tsc; | 520 | u64 tsc; |
| 521 | 521 | ||
| 522 | /* | 522 | /* |
| 523 | * The guest has not set up the TSC page or the clock isn't | 523 | * Fall back to get_kvmclock_ns() when TSC page hasn't been set up, |
| 524 | * stable, fall back to get_kvmclock_ns. | 524 | * is broken, disabled or being updated. |
| 525 | */ | 525 | */ |
| 526 | if (!hv->tsc_ref.tsc_sequence) | 526 | if (hv->hv_tsc_page_status != HV_TSC_PAGE_SET) |
| 527 | return div_u64(get_kvmclock_ns(kvm), 100); | 527 | return div_u64(get_kvmclock_ns(kvm), 100); |
| 528 | 528 | ||
| 529 | vcpu = kvm_get_vcpu(kvm, 0); | 529 | vcpu = kvm_get_vcpu(kvm, 0); |
| @@ -1077,6 +1077,21 @@ static bool compute_tsc_page_parameters(struct pvclock_vcpu_time_info *hv_clock, · 547 unmodified lines | |||
| 1077 | return true; | 1077 | return true; |
| 1078 | } | 1078 | } |
| 1079 | 1079 | ||
| 1080 | /* | ||
| 1081 | * Don't touch TSC page values if the guest has opted for TSC emulation after | ||
| 1082 | * migration. KVM doesn't fully support reenlightenment notifications and TSC | ||
| 1083 | * access emulation and Hyper-V is known to expect the values in TSC page to | ||
| 1084 | * stay constant before TSC access emulation is disabled from guest side | ||
| 1085 | * (HV_X64_MSR_TSC_EMULATION_STATUS). KVM userspace is expected to preserve TSC | ||
| 1086 | * frequency and guest visible TSC value across migration (and prevent it when | ||
| 1087 | * TSC scaling is unsupported). | ||
| 1088 | */ | ||
| 1089 | static inline bool tsc_page_update_unsafe(struct kvm_hv *hv) | ||
| 1090 | { | ||
| 1091 | return (hv->hv_tsc_page_status != HV_TSC_PAGE_GUEST_CHANGED) && | ||
| 1092 | hv->hv_tsc_emulation_control; | ||
| 1093 | } | ||
| 1094 | |||
| 1080 | void kvm_hv_setup_tsc_page(struct kvm *kvm, | 1095 | void kvm_hv_setup_tsc_page(struct kvm *kvm, |
| 1081 | struct pvclock_vcpu_time_info *hv_clock) | 1096 | struct pvclock_vcpu_time_info *hv_clock) |
| 1082 | { | 1097 | { |
| @@ -1087,7 +1102,8 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm, · 4 unmodified lines | |||
| 1087 | BUILD_BUG_ON(sizeof(tsc_seq) != sizeof(hv->tsc_ref.tsc_sequence)); | 1102 | BUILD_BUG_ON(sizeof(tsc_seq) != sizeof(hv->tsc_ref.tsc_sequence)); |
| 1088 | BUILD_BUG_ON(offsetof(struct ms_hyperv_tsc_page, tsc_sequence) != 0); | 1103 | BUILD_BUG_ON(offsetof(struct ms_hyperv_tsc_page, tsc_sequence) != 0); |
| 1089 | 1104 | ||
| 1090 | if (!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)) | 1105 | if (hv->hv_tsc_page_status == HV_TSC_PAGE_BROKEN || |
| 1106 | hv->hv_tsc_page_status == HV_TSC_PAGE_UNSET) | ||
| 1091 | return; | 1107 | return; |
| 1092 | 1108 | ||
| 1093 | mutex_lock(&hv->hv_lock); | 1109 | mutex_lock(&hv->hv_lock); |
| @@ -1101,7 +1117,15 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm, · 7 unmodified lines | |||
| 1101 | */ | 1117 | */ |
| 1102 | if (unlikely(kvm_read_guest(kvm, gfn_to_gpa(gfn), | 1118 | if (unlikely(kvm_read_guest(kvm, gfn_to_gpa(gfn), |
| 1103 | &tsc_seq, sizeof(tsc_seq)))) | 1119 | &tsc_seq, sizeof(tsc_seq)))) |
| 1120 | goto out_err; | ||
| 1121 | |||
| 1122 | if (tsc_seq && tsc_page_update_unsafe(hv)) { | ||
| 1123 | if (kvm_read_guest(kvm, gfn_to_gpa(gfn), &hv->tsc_ref, sizeof(hv->tsc_ref))) | ||
| 1124 | goto out_err; | ||
| 1125 | |||
| 1126 | hv->hv_tsc_page_status = HV_TSC_PAGE_SET; | ||
| 1104 | goto out_unlock; | 1127 | goto out_unlock; |
| 1128 | } | ||
| 1105 | 1129 | ||
| 1106 | /* | 1130 | /* |
| 1107 | * While we're computing and writing the parameters, force the | 1131 | * While we're computing and writing the parameters, force the |
| @@ -1110,15 +1134,15 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm, · 2 unmodified lines | |||
| 1110 | hv->tsc_ref.tsc_sequence = 0; | 1134 | hv->tsc_ref.tsc_sequence = 0; |
| 1111 | if (kvm_write_guest(kvm, gfn_to_gpa(gfn), | 1135 | if (kvm_write_guest(kvm, gfn_to_gpa(gfn), |
| 1112 | &hv->tsc_ref, sizeof(hv->tsc_ref.tsc_sequence))) | 1136 | &hv->tsc_ref, sizeof(hv->tsc_ref.tsc_sequence))) |
| 1113 | goto out_unlock; | 1137 | goto out_err; |
| 1114 | 1138 | ||
| 1115 | if (!compute_tsc_page_parameters(hv_clock, &hv->tsc_ref)) | 1139 | if (!compute_tsc_page_parameters(hv_clock, &hv->tsc_ref)) |
| 1116 | goto out_unlock; | 1140 | goto out_err; |
| 1117 | 1141 | ||
| 1118 | /* Ensure sequence is zero before writing the rest of the struct. */ | 1142 | /* Ensure sequence is zero before writing the rest of the struct. */ |
| 1119 | smp_wmb(); | 1143 | smp_wmb(); |
| 1120 | if (kvm_write_guest(kvm, gfn_to_gpa(gfn), &hv->tsc_ref, sizeof(hv->tsc_ref))) | 1144 | if (kvm_write_guest(kvm, gfn_to_gpa(gfn), &hv->tsc_ref, sizeof(hv->tsc_ref))) |
| 1121 | goto out_unlock; | 1145 | goto out_err; |
| 1122 | 1146 | ||
| 1123 | /* | 1147 | /* |
| 1124 | * Now switch to the TSC page mechanism by writing the sequence. | 1148 | * Now switch to the TSC page mechanism by writing the sequence. |
| @@ -1131,8 +1155,45 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm, · 6 unmodified lines | |||
| 1131 | smp_wmb(); | 1155 | smp_wmb(); |
| 1132 | 1156 | ||
| 1133 | hv->tsc_ref.tsc_sequence = tsc_seq; | 1157 | hv->tsc_ref.tsc_sequence = tsc_seq; |
| 1134 | kvm_write_guest(kvm, gfn_to_gpa(gfn), | 1158 | if (kvm_write_guest(kvm, gfn_to_gpa(gfn), |
| 1135 | &hv->tsc_ref, sizeof(hv->tsc_ref.tsc_sequence)); | 1159 | &hv->tsc_ref, sizeof(hv->tsc_ref.tsc_sequence))) |
| 1160 | goto out_err; | ||
| 1161 | |||
| 1162 | hv->hv_tsc_page_status = HV_TSC_PAGE_SET; | ||
| 1163 | goto out_unlock; | ||
| 1164 | |||
| 1165 | out_err: | ||
| 1166 | hv->hv_tsc_page_status = HV_TSC_PAGE_BROKEN; | ||
| 1167 | out_unlock: | ||
| 1168 | mutex_unlock(&hv->hv_lock); | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | void kvm_hv_invalidate_tsc_page(struct kvm *kvm) | ||
| 1172 | { | ||
| 1173 | struct kvm_hv *hv = to_kvm_hv(kvm); | ||
| 1174 | u64 gfn; | ||
| 1175 | |||
| 1176 | if (hv->hv_tsc_page_status == HV_TSC_PAGE_BROKEN || | ||
| 1177 | hv->hv_tsc_page_status == HV_TSC_PAGE_UNSET || | ||
| 1178 | tsc_page_update_unsafe(hv)) | ||
| 1179 | return; | ||
| 1180 | |||
| 1181 | mutex_lock(&hv->hv_lock); | ||
| 1182 | |||
| 1183 | if (!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)) | ||
| 1184 | goto out_unlock; | ||
| 1185 | |||
| 1186 | /* Preserve HV_TSC_PAGE_GUEST_CHANGED/HV_TSC_PAGE_HOST_CHANGED states */ | ||
| 1187 | if (hv->hv_tsc_page_status == HV_TSC_PAGE_SET) | ||
| 1188 | hv->hv_tsc_page_status = HV_TSC_PAGE_UPDATING; | ||
| 1189 | |||
| 1190 | gfn = hv->hv_tsc_page >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT; | ||
| 1191 | |||
| 1192 | hv->tsc_ref.tsc_sequence = 0; | ||
| 1193 | if (kvm_write_guest(kvm, gfn_to_gpa(gfn), | ||
| 1194 | &hv->tsc_ref, sizeof(hv->tsc_ref.tsc_sequence))) | ||
| 1195 | hv->hv_tsc_page_status = HV_TSC_PAGE_BROKEN; | ||
| 1196 | |||
| 1136 | out_unlock: | 1197 | out_unlock: |
| 1137 | mutex_unlock(&hv->hv_lock); | 1198 | mutex_unlock(&hv->hv_lock); |
| 1138 | } | 1199 | } |
| @@ -1193,8 +1254,15 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data, · 54 unmodified lines | |||
| 1193 | } | 1254 | } |
| 1194 | case HV_X64_MSR_REFERENCE_TSC: | 1255 | case HV_X64_MSR_REFERENCE_TSC: |
| 1195 | hv->hv_tsc_page = data; | 1256 | hv->hv_tsc_page = data; |
| 1196 | if (hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE) | 1257 | if (hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE) { |
| 1258 | if (!host) | ||
| 1259 | hv->hv_tsc_page_status = HV_TSC_PAGE_GUEST_CHANGED; | ||
| 1260 | else | ||
| 1261 | hv->hv_tsc_page_status = HV_TSC_PAGE_HOST_CHANGED; | ||
| 1197 | kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); | 1262 | kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); |
| 1263 | } else { | ||
| 1264 | hv->hv_tsc_page_status = HV_TSC_PAGE_UNSET; | ||
| 1265 | } | ||
| 1198 | break; | 1266 | break; |
| 1199 | case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: | 1267 | case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: |
| 1200 | return kvm_hv_msr_set_crash_data(kvm, | 1268 | return kvm_hv_msr_set_crash_data(kvm, |
| @@ -1229,6 +1297,9 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data, · 28 unmodified lines | |||
| 1229 | hv->hv_tsc_emulation_control = data; | 1297 | hv->hv_tsc_emulation_control = data; |
| 1230 | break; | 1298 | break; |
| 1231 | case HV_X64_MSR_TSC_EMULATION_STATUS: | 1299 | case HV_X64_MSR_TSC_EMULATION_STATUS: |
| 1300 | if (data && !host) | ||
| 1301 | return 1; | ||
| 1302 | |||
| 1232 | hv->hv_tsc_emulation_status = data; | 1303 | hv->hv_tsc_emulation_status = data; |
| 1233 | break; | 1304 | break; |
| 1234 | case HV_X64_MSR_TIME_REF_COUNT: | 1305 | case HV_X64_MSR_TIME_REF_COUNT: |
| @@ -133,6 +133,7 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu); · 132 unmodified lines | |||
| 133 | 133 | ||
| 134 | void kvm_hv_setup_tsc_page(struct kvm *kvm, | 134 | void kvm_hv_setup_tsc_page(struct kvm *kvm, |
| 135 | struct pvclock_vcpu_time_info *hv_clock); | 135 | struct pvclock_vcpu_time_info *hv_clock); |
| 136 | void kvm_hv_invalidate_tsc_page(struct kvm *kvm); | ||
| 136 | 137 | ||
| 137 | void kvm_hv_init_vm(struct kvm *kvm); | 138 | void kvm_hv_init_vm(struct kvm *kvm); |
| 138 | void kvm_hv_destroy_vm(struct kvm *kvm); | 139 | void kvm_hv_destroy_vm(struct kvm *kvm); |
| @@ -1642,7 +1642,16 @@ static void apic_timer_expired(struct kvm_lapic *apic, bool from_timer_fn) · 1641 unmodified lines | |||
| 1642 | } | 1642 | } |
| 1643 | 1643 | ||
| 1644 | if (kvm_use_posted_timer_interrupt(apic->vcpu)) { | 1644 | if (kvm_use_posted_timer_interrupt(apic->vcpu)) { |
| 1645 | kvm_wait_lapic_expire(vcpu); | 1645 | /* |
| 1646 | * Ensure the guest's timer has truly expired before posting an | ||
| 1647 | * interrupt. Open code the relevant checks to avoid querying | ||
| 1648 | * lapic_timer_int_injected(), which will be false since the | ||
| 1649 | * interrupt isn't yet injected. Waiting until after injecting | ||
| 1650 | * is not an option since that won't help a posted interrupt. | ||
| 1651 | */ | ||
| 1652 | if (vcpu->arch.apic->lapic_timer.expired_tscdeadline && | ||
| 1653 | vcpu->arch.apic->lapic_timer.timer_advance_ns) | ||
| 1654 | __kvm_wait_lapic_expire(vcpu); | ||
| 1646 | kvm_apic_inject_pending_timer_irqs(apic); | 1655 | kvm_apic_inject_pending_timer_irqs(apic); |
| 1647 | return; | 1656 | return; |
| 1648 | } | 1657 | } |
| @@ -2595,6 +2604,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) · 946 unmodified lines | |||
| 2595 | 2604 | ||
| 2596 | apic_update_ppr(apic); | 2605 | apic_update_ppr(apic); |
| 2597 | hrtimer_cancel(&apic->lapic_timer.timer); | 2606 | hrtimer_cancel(&apic->lapic_timer.timer); |
| 2607 | apic->lapic_timer.expired_tscdeadline = 0; | ||
| 2598 | apic_update_lvtt(apic); | 2608 | apic_update_lvtt(apic); |
| 2599 | apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); | 2609 | apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); |
| 2600 | update_divide_count(apic); | 2610 | update_divide_count(apic); |
| @@ -78,6 +78,11 @@ static inline struct kvm_mmu_page *sptep_to_sp(u64 *sptep) · 77 unmodified lines | |||
| 78 | return to_shadow_page(__pa(sptep)); | 78 | return to_shadow_page(__pa(sptep)); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static inline int kvm_mmu_page_as_id(struct kvm_mmu_page *sp) | ||
| 82 | { | ||
| 83 | return sp->role.smm ? 1 : 0; | ||
| 84 | } | ||
| 85 | |||
| 81 | static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu) | 86 | static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu) |
| 82 | { | 87 | { |
| 83 | /* | 88 | /* |
| @@ -20,6 +20,21 @@ static gfn_t round_gfn_for_level(gfn_t gfn, int level) · 19 unmodified lines | |||
| 20 | return gfn & -KVM_PAGES_PER_HPAGE(level); | 20 | return gfn & -KVM_PAGES_PER_HPAGE(level); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | /* | ||
| 24 | * Return the TDP iterator to the root PT and allow it to continue its | ||
| 25 | * traversal over the paging structure from there. | ||
| 26 | */ | ||
| 27 | void tdp_iter_restart(struct tdp_iter *iter) | ||
| 28 | { | ||
| 29 | iter->yielded_gfn = iter->next_last_level_gfn; | ||
| 30 | iter->level = iter->root_level; | ||
| 31 | |||
| 32 | iter->gfn = round_gfn_for_level(iter->next_last_level_gfn, iter->level); | ||
| 33 | tdp_iter_refresh_sptep(iter); | ||
| 34 | |||
| 35 | iter->valid = true; | ||
| 36 | } | ||
| 37 | |||
| 23 | /* | 38 | /* |
| 24 | * Sets a TDP iterator to walk a pre-order traversal of the paging structure | 39 | * Sets a TDP iterator to walk a pre-order traversal of the paging structure |
| 25 | * rooted at root_pt, starting with the walk to translate next_last_level_gfn. | 40 | * rooted at root_pt, starting with the walk to translate next_last_level_gfn. |
| @@ -31,16 +46,12 @@ void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level, · 5 unmodified lines | |||
| 31 | WARN_ON(root_level > PT64_ROOT_MAX_LEVEL); | 46 | WARN_ON(root_level > PT64_ROOT_MAX_LEVEL); |
| 32 | 47 | ||
| 33 | iter->next_last_level_gfn = next_last_level_gfn; | 48 | iter->next_last_level_gfn = next_last_level_gfn; |
| 34 | iter->yielded_gfn = iter->next_last_level_gfn; | ||
| 35 | iter->root_level = root_level; | 49 | iter->root_level = root_level; |
| 36 | iter->min_level = min_level; | 50 | iter->min_level = min_level; |
| 37 | iter->level = root_level; | 51 | iter->pt_path[iter->root_level - 1] = (tdp_ptep_t)root_pt; |
| 38 | iter->pt_path[iter->level - 1] = (tdp_ptep_t)root_pt; | 52 | iter->as_id = kvm_mmu_page_as_id(sptep_to_sp(root_pt)); |
| 39 | |||
| 40 | iter->gfn = round_gfn_for_level(iter->next_last_level_gfn, iter->level); | ||
| 41 | tdp_iter_refresh_sptep(iter); | ||
| 42 | 53 | ||
| 43 | iter->valid = true; | 54 | tdp_iter_restart(iter); |
| 44 | } | 55 | } |
| 45 | 56 | ||
| 46 | /* | 57 | /* |
| @@ -159,8 +170,3 @@ void tdp_iter_next(struct tdp_iter *iter) · 112 unmodified lines | |||
| 159 | iter->valid = false; | 170 | iter->valid = false; |
| 160 | } | 171 | } |
| 161 | 172 | ||
| 162 | tdp_ptep_t tdp_iter_root_pt(struct tdp_iter *iter) | ||
| 163 | { | ||
| 164 | return iter->pt_path[iter->root_level - 1]; | ||
| 165 | } | ||
| 166 | |||
| @@ -36,6 +36,8 @@ struct tdp_iter { · 35 unmodified lines | |||
| 36 | int min_level; | 36 | int min_level; |
| 37 | /* The iterator's current level within the paging structure */ | 37 | /* The iterator's current level within the paging structure */ |
| 38 | int level; | 38 | int level; |
| 39 | /* The address space ID, i.e. SMM vs. regular. */ | ||
| 40 | int as_id; | ||
| 39 | /* A snapshot of the value at sptep */ | 41 | /* A snapshot of the value at sptep */ |
| 40 | u64 old_spte; | 42 | u64 old_spte; |
| 41 | /* | 43 | /* |
| @@ -62,6 +64,6 @@ tdp_ptep_t spte_to_child_pt(u64 pte, int level); · 20 unmodified lines | |||
| 62 | void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level, | 64 | void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level, |
| 63 | int min_level, gfn_t next_last_level_gfn); | 65 | int min_level, gfn_t next_last_level_gfn); |
| 64 | void tdp_iter_next(struct tdp_iter *iter); | 66 | void tdp_iter_next(struct tdp_iter *iter); |
| 65 | tdp_ptep_t tdp_iter_root_pt(struct tdp_iter *iter); | 67 | void tdp_iter_restart(struct tdp_iter *iter); |
| 66 | 68 | ||
| 67 | #endif /* __KVM_X86_MMU_TDP_ITER_H */ | 69 | #endif /* __KVM_X86_MMU_TDP_ITER_H */ |
| @@ -203,11 +203,6 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, · 202 unmodified lines | |||
| 203 | u64 old_spte, u64 new_spte, int level, | 203 | u64 old_spte, u64 new_spte, int level, |
| 204 | bool shared); | 204 | bool shared); |
| 205 | 205 | ||
| 206 | static int kvm_mmu_page_as_id(struct kvm_mmu_page *sp) | ||
| 207 | { | ||
| 208 | return sp->role.smm ? 1 : 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | static void handle_changed_spte_acc_track(u64 old_spte, u64 new_spte, int level) | 206 | static void handle_changed_spte_acc_track(u64 old_spte, u64 new_spte, int level) |
| 212 | { | 207 | { |
| 213 | bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte); | 208 | bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte); |
| @@ -301,11 +296,16 @@ static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp, · 87 unmodified lines | |||
| 301 | * | 296 | * |
| 302 | * Given a page table that has been removed from the TDP paging structure, | 297 | * Given a page table that has been removed from the TDP paging structure, |
| 303 | * iterates through the page table to clear SPTEs and free child page tables. | 298 | * iterates through the page table to clear SPTEs and free child page tables. |
| 299 | * | ||
| 300 | * Note that pt is passed in as a tdp_ptep_t, but it does not need RCU | ||
| 301 | * protection. Since this thread removed it from the paging structure, | ||
| 302 | * this thread will be responsible for ensuring the page is freed. Hence the | ||
| 303 | * early rcu_dereferences in the function. | ||
| 304 | */ | 304 | */ |
| 305 | static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt, | 305 | static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, |
| 306 | bool shared) | 306 | bool shared) |
| 307 | { | 307 | { |
| 308 | struct kvm_mmu_page *sp = sptep_to_sp(pt); | 308 | struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(pt)); |
| 309 | int level = sp->role.level; | 309 | int level = sp->role.level; |
| 310 | gfn_t base_gfn = sp->gfn; | 310 | gfn_t base_gfn = sp->gfn; |
| 311 | u64 old_child_spte; | 311 | u64 old_child_spte; |
| @@ -318,7 +318,7 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt, · 6 unmodified lines | |||
| 318 | tdp_mmu_unlink_page(kvm, sp, shared); | 318 | tdp_mmu_unlink_page(kvm, sp, shared); |
| 319 | 319 | ||
| 320 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { | 320 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { |
| 321 | sptep = pt + i; | 321 | sptep = rcu_dereference(pt) + i; |
| 322 | gfn = base_gfn + (i * KVM_PAGES_PER_HPAGE(level - 1)); | 322 | gfn = base_gfn + (i * KVM_PAGES_PER_HPAGE(level - 1)); |
| 323 | 323 | ||
| 324 | if (shared) { | 324 | if (shared) { |
| @@ -337,7 +337,18 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt, · 12 unmodified lines | |||
| 337 | cpu_relax(); | 337 | cpu_relax(); |
| 338 | } | 338 | } |
| 339 | } else { | 339 | } else { |
| 340 | /* | ||
| 341 | * If the SPTE is not MMU-present, there is no backing | ||
| 342 | * page associated with the SPTE and so no side effects | ||
| 343 | * that need to be recorded, and exclusive ownership of | ||
| 344 | * mmu_lock ensures the SPTE can't be made present. | ||
| 345 | * Note, zapping MMIO SPTEs is also unnecessary as they | ||
| 346 | * are guarded by the memslots generation, not by being | ||
| 347 | * unreachable. | ||
| 348 | */ | ||
| 340 | old_child_spte = READ_ONCE(*sptep); | 349 | old_child_spte = READ_ONCE(*sptep); |
| 350 | if (!is_shadow_present_pte(old_child_spte)) | ||
| 351 | continue; | ||
| 341 | 352 | ||
| 342 | /* | 353 | /* |
| 343 | * Marking the SPTE as a removed SPTE is not | 354 | * Marking the SPTE as a removed SPTE is not |
| @@ -481,10 +492,6 @@ static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm, · 137 unmodified lines | |||
| 481 | struct tdp_iter *iter, | 492 | struct tdp_iter *iter, |
| 482 | u64 new_spte) | 493 | u64 new_spte) |
| 483 | { | 494 | { |
| 484 | u64 *root_pt = tdp_iter_root_pt(iter); | ||
| 485 | struct kvm_mmu_page *root = sptep_to_sp(root_pt); | ||
| 486 | int as_id = kvm_mmu_page_as_id(root); | ||
| 487 | |||
| 488 | lockdep_assert_held_read(&kvm->mmu_lock); | 495 | lockdep_assert_held_read(&kvm->mmu_lock); |
| 489 | 496 | ||
| 490 | /* | 497 | /* |
| @@ -498,8 +505,8 @@ static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm, · 7 unmodified lines | |||
| 498 | new_spte) != iter->old_spte) | 505 | new_spte) != iter->old_spte) |
| 499 | return false; | 506 | return false; |
| 500 | 507 | ||
| 501 | handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte, | 508 | handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte, |
| 502 | iter->level, true); | 509 | new_spte, iter->level, true); |
| 503 | 510 | ||
| 504 | return true; | 511 | return true; |
| 505 | } | 512 | } |
| @@ -527,7 +534,7 @@ static inline bool tdp_mmu_zap_spte_atomic(struct kvm *kvm, · 21 unmodified lines | |||
| 527 | * here since the SPTE is going from non-present | 534 | * here since the SPTE is going from non-present |
| 528 | * to non-present. | 535 | * to non-present. |
| 529 | */ | 536 | */ |
| 530 | WRITE_ONCE(*iter->sptep, 0); | 537 | WRITE_ONCE(*rcu_dereference(iter->sptep), 0); |
| 531 | 538 | ||
| 532 | return true; | 539 | return true; |
| 533 | } | 540 | } |
| @@ -553,10 +560,6 @@ static inline void __tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, · 19 unmodified lines | |||
| 553 | u64 new_spte, bool record_acc_track, | 560 | u64 new_spte, bool record_acc_track, |
| 554 | bool record_dirty_log) | 561 | bool record_dirty_log) |
| 555 | { | 562 | { |
| 556 | tdp_ptep_t root_pt = tdp_iter_root_pt(iter); | ||
| 557 | struct kvm_mmu_page *root = sptep_to_sp(root_pt); | ||
| 558 | int as_id = kvm_mmu_page_as_id(root); | ||
| 559 | |||
| 560 | lockdep_assert_held_write(&kvm->mmu_lock); | 563 | lockdep_assert_held_write(&kvm->mmu_lock); |
| 561 | 564 | ||
| 562 | /* | 565 | /* |
| @@ -570,13 +573,13 @@ static inline void __tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, · 7 unmodified lines | |||
| 570 | 573 | ||
| 571 | WRITE_ONCE(*rcu_dereference(iter->sptep), new_spte); | 574 | WRITE_ONCE(*rcu_dereference(iter->sptep), new_spte); |
| 572 | 575 | ||
| 573 | __handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte, | 576 | __handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte, |
| 574 | iter->level, false); | 577 | new_spte, iter->level, false); |
| 575 | if (record_acc_track) | 578 | if (record_acc_track) |
| 576 | handle_changed_spte_acc_track(iter->old_spte, new_spte, | 579 | handle_changed_spte_acc_track(iter->old_spte, new_spte, |
| 577 | iter->level); | 580 | iter->level); |
| 578 | if (record_dirty_log) | 581 | if (record_dirty_log) |
| 579 | handle_changed_spte_dirty_log(kvm, as_id, iter->gfn, | 582 | handle_changed_spte_dirty_log(kvm, iter->as_id, iter->gfn, |
| 580 | iter->old_spte, new_spte, | 583 | iter->old_spte, new_spte, |
| 581 | iter->level); | 584 | iter->level); |
| 582 | } | 585 | } |
| @@ -648,9 +651,7 @@ static inline bool tdp_mmu_iter_cond_resched(struct kvm *kvm, · 65 unmodified lines | |||
| 648 | 651 | ||
| 649 | WARN_ON(iter->gfn > iter->next_last_level_gfn); | 652 | WARN_ON(iter->gfn > iter->next_last_level_gfn); |
| 650 | 653 | ||
| 651 | tdp_iter_start(iter, iter->pt_path[iter->root_level - 1], | 654 | tdp_iter_restart(iter); |
| 652 | iter->root_level, iter->min_level, | ||
| 653 | iter->next_last_level_gfn); | ||
| 654 | 655 | ||
| 655 | return true; | 656 | return true; |
| 656 | } | 657 | } |
| @@ -115,13 +115,6 @@ static const struct svm_direct_access_msrs { · 114 unmodified lines | |||
| 115 | { .index = MSR_INVALID, .always = false }, | 115 | { .index = MSR_INVALID, .always = false }, |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | /* enable NPT for AMD64 and X86 with PAE */ | ||
| 119 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) | ||
| 120 | bool npt_enabled = true; | ||
| 121 | #else | ||
| 122 | bool npt_enabled; | ||
| 123 | #endif | ||
| 124 | |||
| 125 | /* | 118 | /* |
| 126 | * These 2 parameters are used to config the controls for Pause-Loop Exiting: | 119 | * These 2 parameters are used to config the controls for Pause-Loop Exiting: |
| 127 | * pause_filter_count: On processors that support Pause filtering(indicated | 120 | * pause_filter_count: On processors that support Pause filtering(indicated |
| @@ -170,9 +163,12 @@ module_param(pause_filter_count_shrink, ushort, 0444); · 42 unmodified lines | |||
| 170 | static unsigned short pause_filter_count_max = KVM_SVM_DEFAULT_PLE_WINDOW_MAX; | 163 | static unsigned short pause_filter_count_max = KVM_SVM_DEFAULT_PLE_WINDOW_MAX; |
| 171 | module_param(pause_filter_count_max, ushort, 0444); | 164 | module_param(pause_filter_count_max, ushort, 0444); |
| 172 | 165 | ||
| 173 | /* allow nested paging (virtualized MMU) for all guests */ | 166 | /* |
| 174 | static int npt = true; | 167 | * Use nested page tables by default. Note, NPT may get forced off by |
| 175 | module_param(npt, int, S_IRUGO); | 168 | * svm_hardware_setup() if it's unsupported by hardware or the host kernel. |
| 169 | */ | ||
| 170 | bool npt_enabled = true; | ||
| 171 | module_param_named(npt, npt_enabled, bool, 0444); | ||
| 176 | 172 | ||
| 177 | /* allow nested virtualization in KVM/SVM */ | 173 | /* allow nested virtualization in KVM/SVM */ |
| 178 | static int nested = true; | 174 | static int nested = true; |
| @@ -988,10 +984,15 @@ static __init int svm_hardware_setup(void) · 809 unmodified lines | |||
| 988 | goto err; | 984 | goto err; |
| 989 | } | 985 | } |
| 990 | 986 | ||
| 991 | if (!boot_cpu_has(X86_FEATURE_NPT)) | 987 | /* |
| 988 | * KVM's MMU doesn't support using 2-level paging for itself, and thus | ||
| 989 | * NPT isn't supported if the host is using 2-level paging since host | ||
| 990 | * CR4 is unchanged on VMRUN. | ||
| 991 | */ | ||
| 992 | if (!IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_X86_PAE)) | ||
| 992 | npt_enabled = false; | 993 | npt_enabled = false; |
| 993 | 994 | ||
| 994 | if (npt_enabled && !npt) | 995 | if (!boot_cpu_has(X86_FEATURE_NPT)) |
| 995 | npt_enabled = false; | 996 | npt_enabled = false; |
| 996 | 997 | ||
| 997 | kvm_configure_mmu(npt_enabled, get_max_npt_level(), PG_LEVEL_1G); | 998 | kvm_configure_mmu(npt_enabled, get_max_npt_level(), PG_LEVEL_1G); |
| @@ -6580,8 +6580,8 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx) · 6579 unmodified lines | |||
| 6580 | int i, nr_msrs; | 6580 | int i, nr_msrs; |
| 6581 | struct perf_guest_switch_msr *msrs; | 6581 | struct perf_guest_switch_msr *msrs; |
| 6582 | 6582 | ||
| 6583 | /* Note, nr_msrs may be garbage if perf_guest_get_msrs() returns NULL. */ | ||
| 6583 | msrs = perf_guest_get_msrs(&nr_msrs); | 6584 | msrs = perf_guest_get_msrs(&nr_msrs); |
| 6584 | |||
| 6585 | if (!msrs) | 6585 | if (!msrs) |
| 6586 | return; | 6586 | return; |
| 6587 | 6587 | ||
| @@ -1526,35 +1526,44 @@ EXPORT_SYMBOL_GPL(kvm_enable_efer_bits); · 1525 unmodified lines | |||
| 1526 | 1526 | ||
| 1527 | bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type) | 1527 | bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type) |
| 1528 | { | 1528 | { |
| 1529 | struct kvm_x86_msr_filter *msr_filter; | ||
| 1530 | struct msr_bitmap_range *ranges; | ||
| 1529 | struct kvm *kvm = vcpu->kvm; | 1531 | struct kvm *kvm = vcpu->kvm; |
| 1530 | struct msr_bitmap_range *ranges = kvm->arch.msr_filter.ranges; | 1532 | bool allowed; |
| 1531 | u32 count = kvm->arch.msr_filter.count; | ||
| 1532 | u32 i; | ||
| 1533 | bool r = kvm->arch.msr_filter.default_allow; | ||
| 1534 | int idx; | 1533 | int idx; |
| 1534 | u32 i; | ||
| 1535 | 1535 | ||
| 1536 | /* MSR filtering not set up or x2APIC enabled, allow everything */ | 1536 | /* x2APIC MSRs do not support filtering. */ |
| 1537 | if (!count || (index >= 0x800 && index <= 0x8ff)) | 1537 | if (index >= 0x800 && index <= 0x8ff) |
| 1538 | return true; | 1538 | return true; |
| 1539 | 1539 | ||
| 1540 | /* Prevent collision with set_msr_filter */ | ||
| 1541 | idx = srcu_read_lock(&kvm->srcu); | 1540 | idx = srcu_read_lock(&kvm->srcu); |
| 1542 | 1541 | ||
| 1543 | for (i = 0; i < count; i++) { | 1542 | msr_filter = srcu_dereference(kvm->arch.msr_filter, &kvm->srcu); |
| 1543 | if (!msr_filter) { | ||
| 1544 | allowed = true; | ||
| 1545 | goto out; | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | allowed = msr_filter->default_allow; | ||
| 1549 | ranges = msr_filter->ranges; | ||
| 1550 | |||
| 1551 | for (i = 0; i < msr_filter->count; i++) { | ||
| 1544 | u32 start = ranges[i].base; | 1552 | u32 start = ranges[i].base; |
| 1545 | u32 end = start + ranges[i].nmsrs; | 1553 | u32 end = start + ranges[i].nmsrs; |
| 1546 | u32 flags = ranges[i].flags; | 1554 | u32 flags = ranges[i].flags; |
| 1547 | unsigned long *bitmap = ranges[i].bitmap; | 1555 | unsigned long *bitmap = ranges[i].bitmap; |
| 1548 | 1556 | ||
| 1549 | if ((index >= start) && (index < end) && (flags & type)) { | 1557 | if ((index >= start) && (index < end) && (flags & type)) { |
| 1550 | r = !!test_bit(index - start, bitmap); | 1558 | allowed = !!test_bit(index - start, bitmap); |
| 1551 | break; | 1559 | break; |
| 1552 | } | 1560 | } |
| 1553 | } | 1561 | } |
| 1554 | 1562 | ||
| 1563 | out: | ||
| 1555 | srcu_read_unlock(&kvm->srcu, idx); | 1564 | srcu_read_unlock(&kvm->srcu, idx); |
| 1556 | 1565 | ||
| 1557 | return r; | 1566 | return allowed; |
| 1558 | } | 1567 | } |
| 1559 | EXPORT_SYMBOL_GPL(kvm_msr_allowed); | 1568 | EXPORT_SYMBOL_GPL(kvm_msr_allowed); |
| 1560 | 1569 | ||
| @@ -2551,6 +2560,8 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) · 990 unmodified lines | |||
| 2551 | struct kvm_vcpu *vcpu; | 2560 | struct kvm_vcpu *vcpu; |
| 2552 | struct kvm_arch *ka = &kvm->arch; | 2561 | struct kvm_arch *ka = &kvm->arch; |
| 2553 | 2562 | ||
| 2563 | kvm_hv_invalidate_tsc_page(kvm); | ||
| 2564 | |||
| 2554 | spin_lock(&ka->pvclock_gtod_sync_lock); | 2565 | spin_lock(&ka->pvclock_gtod_sync_lock); |
| 2555 | kvm_make_mclock_inprogress_request(kvm); | 2566 | kvm_make_mclock_inprogress_request(kvm); |
| 2556 | /* no guest entries from this point */ | 2567 | /* no guest entries from this point */ |
| @@ -5352,25 +5363,34 @@ split_irqchip_unlock: · 2795 unmodified lines | |||
| 5352 | return r; | 5363 | return r; |
| 5353 | } | 5364 | } |
| 5354 | 5365 | ||
| 5355 | static void kvm_clear_msr_filter(struct kvm *kvm) | 5366 | static struct kvm_x86_msr_filter *kvm_alloc_msr_filter(bool default_allow) |
| 5367 | { | ||
| 5368 | struct kvm_x86_msr_filter *msr_filter; | ||
| 5369 | |||
| 5370 | msr_filter = kzalloc(sizeof(*msr_filter), GFP_KERNEL_ACCOUNT); | ||
| 5371 | if (!msr_filter) | ||
| 5372 | return NULL; | ||
| 5373 | |||
| 5374 | msr_filter->default_allow = default_allow; | ||
| 5375 | return msr_filter; | ||
| 5376 | } | ||
| 5377 | |||
| 5378 | static void kvm_free_msr_filter(struct kvm_x86_msr_filter *msr_filter) | ||
| 5356 | { | 5379 | { |
| 5357 | u32 i; | 5380 | u32 i; |
| 5358 | u32 count = kvm->arch.msr_filter.count; | ||
| 5359 | struct msr_bitmap_range ranges[16]; | ||
| 5360 | 5381 | ||
| 5361 | mutex_lock(&kvm->lock); | 5382 | if (!msr_filter) |
| 5362 | kvm->arch.msr_filter.count = 0; | 5383 | return; |
| 5363 | memcpy(ranges, kvm->arch.msr_filter.ranges, count * sizeof(ranges[0])); | 5384 | |
| 5364 | mutex_unlock(&kvm->lock); | 5385 | for (i = 0; i < msr_filter->count; i++) |
| 5365 | synchronize_srcu(&kvm->srcu); | 5386 | kfree(msr_filter->ranges[i].bitmap); |
| 5366 | 5387 | ||
| 5367 | for (i = 0; i < count; i++) | 5388 | kfree(msr_filter); |
| 5368 | kfree(ranges[i].bitmap); | ||
| 5369 | } | 5389 | } |
| 5370 | 5390 | ||
| 5371 | static int kvm_add_msr_filter(struct kvm *kvm, struct kvm_msr_filter_range *user_range) | 5391 | static int kvm_add_msr_filter(struct kvm_x86_msr_filter *msr_filter, |
| 5392 | struct kvm_msr_filter_range *user_range) | ||
| 5372 | { | 5393 | { |
| 5373 | struct msr_bitmap_range *ranges = kvm->arch.msr_filter.ranges; | ||
| 5374 | struct msr_bitmap_range range; | 5394 | struct msr_bitmap_range range; |
| 5375 | unsigned long *bitmap = NULL; | 5395 | unsigned long *bitmap = NULL; |
| 5376 | size_t bitmap_size; | 5396 | size_t bitmap_size; |
| @@ -5404,11 +5424,9 @@ static int kvm_add_msr_filter(struct kvm *kvm, struct kvm_msr_filter_range *user · 27 unmodified lines | |||
| 5404 | goto err; | 5424 | goto err; |
| 5405 | } | 5425 | } |
| 5406 | 5426 | ||
| 5407 | /* Everything ok, add this range identifier to our global pool */ | 5427 | /* Everything ok, add this range identifier. */ |
| 5408 | ranges[kvm->arch.msr_filter.count] = range; | 5428 | msr_filter->ranges[msr_filter->count] = range; |
| 5409 | /* Make sure we filled the array before we tell anyone to walk it */ | 5429 | msr_filter->count++; |
| 5410 | smp_wmb(); | ||
| 5411 | kvm->arch.msr_filter.count++; | ||
| 5412 | 5430 | ||
| 5413 | return 0; | 5431 | return 0; |
| 5414 | err: | 5432 | err: |
| @@ -5419,10 +5437,11 @@ err: · 4 unmodified lines | |||
| 5419 | static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) | 5437 | static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) |
| 5420 | { | 5438 | { |
| 5421 | struct kvm_msr_filter __user *user_msr_filter = argp; | 5439 | struct kvm_msr_filter __user *user_msr_filter = argp; |
| 5440 | struct kvm_x86_msr_filter *new_filter, *old_filter; | ||
| 5422 | struct kvm_msr_filter filter; | 5441 | struct kvm_msr_filter filter; |
| 5423 | bool default_allow; | 5442 | bool default_allow; |
| 5424 | int r = 0; | ||
| 5425 | bool empty = true; | 5443 | bool empty = true; |
| 5444 | int r = 0; | ||
| 5426 | u32 i; | 5445 | u32 i; |
| 5427 | 5446 | ||
| 5428 | if (copy_from_user(&filter, user_msr_filter, sizeof(filter))) | 5447 | if (copy_from_user(&filter, user_msr_filter, sizeof(filter))) |
| @@ -5435,25 +5454,32 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) · 6 unmodified lines | |||
| 5435 | if (empty && !default_allow) | 5454 | if (empty && !default_allow) |
| 5436 | return -EINVAL; | 5455 | return -EINVAL; |
| 5437 | 5456 | ||
| 5438 | kvm_clear_msr_filter(kvm); | 5457 | new_filter = kvm_alloc_msr_filter(default_allow); |
| 5439 | 5458 | if (!new_filter) | |
| 5440 | kvm->arch.msr_filter.default_allow = default_allow; | 5459 | return -ENOMEM; |
| 5441 | 5460 | ||
| 5442 | /* | ||
| 5443 | * Protect from concurrent calls to this function that could trigger | ||
| 5444 | * a TOCTOU violation on kvm->arch.msr_filter.count. | ||
| 5445 | */ | ||
| 5446 | mutex_lock(&kvm->lock); | ||
| 5447 | for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) { | 5461 | for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) { |
| 5448 | r = kvm_add_msr_filter(kvm, &filter.ranges[i]); | 5462 | r = kvm_add_msr_filter(new_filter, &filter.ranges[i]); |
| 5449 | if (r) | 5463 | if (r) { |
| 5450 | break; | 5464 | kvm_free_msr_filter(new_filter); |
| 5465 | return r; | ||
| 5466 | } | ||
| 5451 | } | 5467 | } |
| 5452 | 5468 | ||
| 5469 | mutex_lock(&kvm->lock); | ||
| 5470 | |||
| 5471 | /* The per-VM filter is protected by kvm->lock... */ | ||
| 5472 | old_filter = srcu_dereference_check(kvm->arch.msr_filter, &kvm->srcu, 1); | ||
| 5473 | |||
| 5474 | rcu_assign_pointer(kvm->arch.msr_filter, new_filter); | ||
| 5475 | synchronize_srcu(&kvm->srcu); | ||
| 5476 | |||
| 5477 | kvm_free_msr_filter(old_filter); | ||
| 5478 | |||
| 5453 | kvm_make_all_cpus_request(kvm, KVM_REQ_MSR_FILTER_CHANGED); | 5479 | kvm_make_all_cpus_request(kvm, KVM_REQ_MSR_FILTER_CHANGED); |
| 5454 | mutex_unlock(&kvm->lock); | 5480 | mutex_unlock(&kvm->lock); |
| 5455 | 5481 | ||
| 5456 | return r; | 5482 | return 0; |
| 5457 | } | 5483 | } |
| 5458 | 5484 | ||
| 5459 | long kvm_arch_vm_ioctl(struct file *filp, | 5485 | long kvm_arch_vm_ioctl(struct file *filp, |
| @@ -6603,7 +6629,7 @@ static int kvm_emulate_wbinvd_noskip(struct kvm_vcpu *vcpu) · 1143 unmodified lines | |||
| 6603 | int cpu = get_cpu(); | 6629 | int cpu = get_cpu(); |
| 6604 | 6630 | ||
| 6605 | cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask); | 6631 | cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask); |
| 6606 | smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, | 6632 | on_each_cpu_mask(vcpu->arch.wbinvd_dirty_mask, |
| 6607 | wbinvd_ipi, NULL, 1); | 6633 | wbinvd_ipi, NULL, 1); |
| 6608 | put_cpu(); | 6634 | put_cpu(); |
| 6609 | cpumask_clear(vcpu->arch.wbinvd_dirty_mask); | 6635 | cpumask_clear(vcpu->arch.wbinvd_dirty_mask); |
| @@ -10601,7 +10627,7 @@ void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, · 3991 unmodified lines | |||
| 10601 | return (void __user *)hva; | 10627 | return (void __user *)hva; |
| 10602 | } else { | 10628 | } else { |
| 10603 | if (!slot || !slot->npages) | 10629 | if (!slot || !slot->npages) |
| 10604 | return 0; | 10630 | return NULL; |
| 10605 | 10631 | ||
| 10606 | old_npages = slot->npages; | 10632 | old_npages = slot->npages; |
| 10607 | hva = slot->userspace_addr; | 10633 | hva = slot->userspace_addr; |
| @@ -10634,8 +10660,6 @@ void kvm_arch_pre_destroy_vm(struct kvm *kvm) · 26 unmodified lines | |||
| 10634 | 10660 | ||
| 10635 | void kvm_arch_destroy_vm(struct kvm *kvm) | 10661 | void kvm_arch_destroy_vm(struct kvm *kvm) |
| 10636 | { | 10662 | { |
| 10637 | u32 i; | ||
| 10638 | |||
| 10639 | if (current->mm == kvm->mm) { | 10663 | if (current->mm == kvm->mm) { |
| 10640 | /* | 10664 | /* |
| 10641 | * Free memory regions allocated on behalf of userspace, | 10665 | * Free memory regions allocated on behalf of userspace, |
| @@ -10651,8 +10675,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) · 9 unmodified lines | |||
| 10651 | mutex_unlock(&kvm->slots_lock); | 10675 | mutex_unlock(&kvm->slots_lock); |
| 10652 | } | 10676 | } |
| 10653 | static_call_cond(kvm_x86_vm_destroy)(kvm); | 10677 | static_call_cond(kvm_x86_vm_destroy)(kvm); |
| 10654 | for (i = 0; i < kvm->arch.msr_filter.count; i++) | 10678 | kvm_free_msr_filter(srcu_dereference_check(kvm->arch.msr_filter, &kvm->srcu, 1)); |
| 10655 | kfree(kvm->arch.msr_filter.ranges[i].bitmap); | ||
| 10656 | kvm_pic_destroy(kvm); | 10679 | kvm_pic_destroy(kvm); |
| 10657 | kvm_ioapic_destroy(kvm); | 10680 | kvm_ioapic_destroy(kvm); |
| 10658 | kvm_free_vcpus(kvm); | 10681 | kvm_free_vcpus(kvm); |
| @@ -1415,6 +1415,25 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) · 1414 unmodified lines | |||
| 1415 | } | 1415 | } |
| 1416 | } | 1416 | } |
| 1417 | 1417 | ||
| 1418 | static unsigned long insn_get_effective_ip(struct pt_regs *regs) | ||
| 1419 | { | ||
| 1420 | unsigned long seg_base = 0; | ||
| 1421 | |||
| 1422 | /* | ||
| 1423 | * If not in user-space long mode, a custom code segment could be in | ||
| 1424 | * use. This is true in protected mode (if the process defined a local | ||
| 1425 | * descriptor table), or virtual-8086 mode. In most of the cases | ||
| 1426 | * seg_base will be zero as in USER_CS. | ||
| 1427 | */ | ||
| 1428 | if (!user_64bit_mode(regs)) { | ||
| 1429 | seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); | ||
| 1430 | if (seg_base == -1L) | ||
| 1431 | return 0; | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | return seg_base + regs->ip; | ||
| 1435 | } | ||
| 1436 | |||
| 1418 | /** | 1437 | /** |
| 1419 | * insn_fetch_from_user() - Copy instruction bytes from user-space memory | 1438 | * insn_fetch_from_user() - Copy instruction bytes from user-space memory |
| 1420 | * @regs: Structure with register values as seen when entering kernel mode | 1439 | * @regs: Structure with register values as seen when entering kernel mode |
| @@ -1431,24 +1450,43 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) · 10 unmodified lines | |||
| 1431 | */ | 1450 | */ |
| 1432 | int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) | 1451 | int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) |
| 1433 | { | 1452 | { |
| 1434 | unsigned long seg_base = 0; | 1453 | unsigned long ip; |
| 1435 | int not_copied; | 1454 | int not_copied; |
| 1436 | 1455 | ||
| 1437 | /* | 1456 | ip = insn_get_effective_ip(regs); |
| 1438 | * If not in user-space long mode, a custom code segment could be in | 1457 | if (!ip) |
| 1439 | * use. This is true in protected mode (if the process defined a local | 1458 | return 0; |
| 1440 | * descriptor table), or virtual-8086 mode. In most of the cases | 1459 | |
| 1441 | * seg_base will be zero as in USER_CS. | 1460 | not_copied = copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE); |
| 1442 | */ | ||
| 1443 | if (!user_64bit_mode(regs)) { | ||
| 1444 | seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); | ||
| 1445 | if (seg_base == -1L) | ||
| 1446 | return 0; | ||
| 1447 | } | ||
| 1448 | 1461 | ||
| 1462 | return MAX_INSN_SIZE - not_copied; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | /** | ||
| 1466 | * insn_fetch_from_user_inatomic() - Copy instruction bytes from user-space memory | ||
| 1467 | * while in atomic code | ||
| 1468 | * @regs: Structure with register values as seen when entering kernel mode | ||
| 1469 | * @buf: Array to store the fetched instruction | ||
| 1470 | * | ||
| 1471 | * Gets the linear address of the instruction and copies the instruction bytes | ||
| 1472 | * to the buf. This function must be used in atomic context. | ||
| 1473 | * | ||
| 1474 | * Returns: | ||
| 1475 | * | ||
| 1476 | * Number of instruction bytes copied. | ||
| 1477 | * | ||
| 1478 | * 0 if nothing was copied. | ||
| 1479 | */ | ||
| 1480 | int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) | ||
| 1481 | { | ||
| 1482 | unsigned long ip; | ||
| 1483 | int not_copied; | ||
| 1484 | |||
| 1485 | ip = insn_get_effective_ip(regs); | ||
| 1486 | if (!ip) | ||
| 1487 | return 0; | ||
| 1449 | 1488 | ||
| 1450 | not_copied = copy_from_user(buf, (void __user *)(seg_base + regs->ip), | 1489 | not_copied = __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN_SIZE); |
| 1451 | MAX_INSN_SIZE); | ||
| 1452 | 1490 | ||
| 1453 | return MAX_INSN_SIZE - not_copied; | 1491 | return MAX_INSN_SIZE - not_copied; |
| 1454 | } | 1492 | } |
| @@ -1936,7 +1936,7 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog, · 1935 unmodified lines | |||
| 1936 | * add rsp, 8 // skip eth_type_trans's frame | 1936 | * add rsp, 8 // skip eth_type_trans's frame |
| 1937 | * ret // return to its caller | 1937 | * ret // return to its caller |
| 1938 | */ | 1938 | */ |
| 1939 | int arch_prepare_bpf_trampoline(void *image, void *image_end, | 1939 | int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end, |
| 1940 | const struct btf_func_model *m, u32 flags, | 1940 | const struct btf_func_model *m, u32 flags, |
| 1941 | struct bpf_tramp_progs *tprogs, | 1941 | struct bpf_tramp_progs *tprogs, |
| 1942 | void *orig_call) | 1942 | void *orig_call) |
| @@ -1975,6 +1975,15 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, · 32 unmodified lines | |||
| 1975 | 1975 | ||
| 1976 | save_regs(m, &prog, nr_args, stack_size); | 1976 | save_regs(m, &prog, nr_args, stack_size); |
| 1977 | 1977 | ||
| 1978 | if (flags & BPF_TRAMP_F_CALL_ORIG) { | ||
| 1979 | /* arg1: mov rdi, im */ | ||
| 1980 | emit_mov_imm64(&prog, BPF_REG_1, (long) im >> 32, (u32) (long) im); | ||
| 1981 | if (emit_call(&prog, __bpf_tramp_enter, prog)) { | ||
| 1982 | ret = -EINVAL; | ||
| 1983 | goto cleanup; | ||
| 1984 | } | ||
| 1985 | } | ||
| 1986 | |||
| 1978 | if (fentry->nr_progs) | 1987 | if (fentry->nr_progs) |
| 1979 | if (invoke_bpf(m, &prog, fentry, stack_size)) | 1988 | if (invoke_bpf(m, &prog, fentry, stack_size)) |
| 1980 | return -EINVAL; | 1989 | return -EINVAL; |
| @@ -1993,8 +2002,7 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, · 12 unmodified lines | |||
| 1993 | } | 2002 | } |
| 1994 | 2003 | ||
| 1995 | if (flags & BPF_TRAMP_F_CALL_ORIG) { | 2004 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 1996 | if (fentry->nr_progs || fmod_ret->nr_progs) | 2005 | restore_regs(m, &prog, nr_args, stack_size); |
| 1997 | restore_regs(m, &prog, nr_args, stack_size); | ||
| 1998 | 2006 | ||
| 1999 | /* call original function */ | 2007 | /* call original function */ |
| 2000 | if (emit_call(&prog, orig_call, prog)) { | 2008 | if (emit_call(&prog, orig_call, prog)) { |
| @@ -2003,6 +2011,9 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, · 2 unmodified lines | |||
| 2003 | } | 2011 | } |
| 2004 | /* remember return value in a stack for bpf prog to access */ | 2012 | /* remember return value in a stack for bpf prog to access */ |
| 2005 | emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8); | 2013 | emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8); |
| 2014 | im->ip_after_call = prog; | ||
| 2015 | memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE); | ||
| 2016 | prog += X86_PATCH_SIZE; | ||
| 2006 | } | 2017 | } |
| 2007 | 2018 | ||
| 2008 | if (fmod_ret->nr_progs) { | 2019 | if (fmod_ret->nr_progs) { |
| @@ -2033,9 +2044,17 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, · 24 unmodified lines | |||
| 2033 | * the return value is only updated on the stack and still needs to be | 2044 | * the return value is only updated on the stack and still needs to be |
| 2034 | * restored to R0. | 2045 | * restored to R0. |
| 2035 | */ | 2046 | */ |
| 2036 | if (flags & BPF_TRAMP_F_CALL_ORIG) | 2047 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2048 | im->ip_epilogue = prog; | ||
| 2049 | /* arg1: mov rdi, im */ | ||
| 2050 | emit_mov_imm64(&prog, BPF_REG_1, (long) im >> 32, (u32) (long) im); | ||
| 2051 | if (emit_call(&prog, __bpf_tramp_exit, prog)) { | ||
| 2052 | ret = -EINVAL; | ||
| 2053 | goto cleanup; | ||
| 2054 | } | ||
| 2037 | /* restore original return value back into RAX */ | 2055 | /* restore original return value back into RAX */ |
| 2038 | emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); | 2056 | emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); |
| 2057 | } | ||
| 2039 | 2058 | ||
| 2040 | EMIT1(0x5B); /* pop rbx */ | 2059 | EMIT1(0x5B); /* pop rbx */ |
| 2041 | EMIT1(0xC9); /* leave */ | 2060 | EMIT1(0xC9); /* leave */ |
| @@ -2225,7 +2244,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 183 unmodified lines | |||
| 2225 | padding = true; | 2244 | padding = true; |
| 2226 | goto skip_init_addrs; | 2245 | goto skip_init_addrs; |
| 2227 | } | 2246 | } |
| 2228 | addrs = kmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL); | 2247 | addrs = kvmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL); |
| 2229 | if (!addrs) { | 2248 | if (!addrs) { |
| 2230 | prog = orig_prog; | 2249 | prog = orig_prog; |
| 2231 | goto out_addrs; | 2250 | goto out_addrs; |
| @@ -2317,7 +2336,7 @@ out_image: · 85 unmodified lines | |||
| 2317 | if (image) | 2336 | if (image) |
| 2318 | bpf_prog_fill_jited_linfo(prog, addrs + 1); | 2337 | bpf_prog_fill_jited_linfo(prog, addrs + 1); |
| 2319 | out_addrs: | 2338 | out_addrs: |
| 2320 | kfree(addrs); | 2339 | kvfree(addrs); |
| 2321 | kfree(jit_data); | 2340 | kfree(jit_data); |
| 2322 | prog->aux->jit_data = NULL; | 2341 | prog->aux->jit_data = NULL; |
| 2323 | } | 2342 | } |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
| 28 | MODULE_AUTHOR("Sébastien Hinderer <Sebastien.Hinderer@ens-lyon.org>"); | 28 | MODULE_AUTHOR("Sébastien Hinderer <Sebastien.Hinderer@ens-lyon.org>"); |
| 29 | MODULE_DESCRIPTION("A power_off handler for Iris devices from EuroBraille"); | 29 | MODULE_DESCRIPTION("A power_off handler for Iris devices from EuroBraille"); |
| 30 | MODULE_SUPPORTED_DEVICE("Eurobraille/Iris"); | ||
| 31 | 30 | ||
| 32 | static bool force; | 31 | static bool force; |
| 33 | 32 | ||
| @@ -741,7 +741,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 740 unmodified lines | |||
| 741 | map_ops[i].status = GNTST_general_error; | 741 | map_ops[i].status = GNTST_general_error; |
| 742 | unmap[0].host_addr = map_ops[i].host_addr, | 742 | unmap[0].host_addr = map_ops[i].host_addr, |
| 743 | unmap[0].handle = map_ops[i].handle; | 743 | unmap[0].handle = map_ops[i].handle; |
| 744 | map_ops[i].handle = ~0; | 744 | map_ops[i].handle = INVALID_GRANT_HANDLE; |
| 745 | if (map_ops[i].flags & GNTMAP_device_map) | 745 | if (map_ops[i].flags & GNTMAP_device_map) |
| 746 | unmap[0].dev_bus_addr = map_ops[i].dev_bus_addr; | 746 | unmap[0].dev_bus_addr = map_ops[i].dev_bus_addr; |
| 747 | else | 747 | else |
| @@ -751,7 +751,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 3 unmodified lines | |||
| 751 | kmap_ops[i].status = GNTST_general_error; | 751 | kmap_ops[i].status = GNTST_general_error; |
| 752 | unmap[1].host_addr = kmap_ops[i].host_addr, | 752 | unmap[1].host_addr = kmap_ops[i].host_addr, |
| 753 | unmap[1].handle = kmap_ops[i].handle; | 753 | unmap[1].handle = kmap_ops[i].handle; |
| 754 | kmap_ops[i].handle = ~0; | 754 | kmap_ops[i].handle = INVALID_GRANT_HANDLE; |
| 755 | if (kmap_ops[i].flags & GNTMAP_device_map) | 755 | if (kmap_ops[i].flags & GNTMAP_device_map) |
| 756 | unmap[1].dev_bus_addr = kmap_ops[i].dev_bus_addr; | 756 | unmap[1].dev_bus_addr = kmap_ops[i].dev_bus_addr; |
| 757 | else | 757 | else |
| @@ -776,7 +776,6 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 18 unmodified lines | |||
| 776 | out: | 776 | out: |
| 777 | return ret; | 777 | return ret; |
| 778 | } | 778 | } |
| 779 | EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping); | ||
| 780 | 779 | ||
| 781 | int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, | 780 | int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, |
| 782 | struct gnttab_unmap_grant_ref *kunmap_ops, | 781 | struct gnttab_unmap_grant_ref *kunmap_ops, |
| @@ -802,7 +801,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, · 19 unmodified lines | |||
| 802 | 801 | ||
| 803 | return ret; | 802 | return ret; |
| 804 | } | 803 | } |
| 805 | EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping); | ||
| 806 | 804 | ||
| 807 | #ifdef CONFIG_XEN_DEBUG_FS | 805 | #ifdef CONFIG_XEN_DEBUG_FS |
| 808 | #include <linux/debugfs.h> | 806 | #include <linux/debugfs.h> |
| @@ -33,7 +33,7 @@ static struct biovec_slab { · 32 unmodified lines | |||
| 33 | { .nr_vecs = 16, .name = "biovec-16" }, | 33 | { .nr_vecs = 16, .name = "biovec-16" }, |
| 34 | { .nr_vecs = 64, .name = "biovec-64" }, | 34 | { .nr_vecs = 64, .name = "biovec-64" }, |
| 35 | { .nr_vecs = 128, .name = "biovec-128" }, | 35 | { .nr_vecs = 128, .name = "biovec-128" }, |
| 36 | { .nr_vecs = BIO_MAX_PAGES, .name = "biovec-max" }, | 36 | { .nr_vecs = BIO_MAX_VECS, .name = "biovec-max" }, |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | static struct biovec_slab *biovec_slab(unsigned short nr_vecs) | 39 | static struct biovec_slab *biovec_slab(unsigned short nr_vecs) |
| @@ -46,7 +46,7 @@ static struct biovec_slab *biovec_slab(unsigned short nr_vecs) · 6 unmodified lines | |||
| 46 | return &bvec_slabs[1]; | 46 | return &bvec_slabs[1]; |
| 47 | case 65 ... 128: | 47 | case 65 ... 128: |
| 48 | return &bvec_slabs[2]; | 48 | return &bvec_slabs[2]; |
| 49 | case 129 ... BIO_MAX_PAGES: | 49 | case 129 ... BIO_MAX_VECS: |
| 50 | return &bvec_slabs[3]; | 50 | return &bvec_slabs[3]; |
| 51 | default: | 51 | default: |
| 52 | BUG(); | 52 | BUG(); |
| @@ -151,9 +151,9 @@ out: · 98 unmodified lines | |||
| 151 | 151 | ||
| 152 | void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned short nr_vecs) | 152 | void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned short nr_vecs) |
| 153 | { | 153 | { |
| 154 | BIO_BUG_ON(nr_vecs > BIO_MAX_PAGES); | 154 | BIO_BUG_ON(nr_vecs > BIO_MAX_VECS); |
| 155 | 155 | ||
| 156 | if (nr_vecs == BIO_MAX_PAGES) | 156 | if (nr_vecs == BIO_MAX_VECS) |
| 157 | mempool_free(bv, pool); | 157 | mempool_free(bv, pool); |
| 158 | else if (nr_vecs > BIO_INLINE_VECS) | 158 | else if (nr_vecs > BIO_INLINE_VECS) |
| 159 | kmem_cache_free(biovec_slab(nr_vecs)->slab, bv); | 159 | kmem_cache_free(biovec_slab(nr_vecs)->slab, bv); |
| @@ -186,15 +186,15 @@ struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs, · 26 unmodified lines | |||
| 186 | /* | 186 | /* |
| 187 | * Try a slab allocation first for all smaller allocations. If that | 187 | * Try a slab allocation first for all smaller allocations. If that |
| 188 | * fails and __GFP_DIRECT_RECLAIM is set retry with the mempool. | 188 | * fails and __GFP_DIRECT_RECLAIM is set retry with the mempool. |
| 189 | * The mempool is sized to handle up to BIO_MAX_PAGES entries. | 189 | * The mempool is sized to handle up to BIO_MAX_VECS entries. |
| 190 | */ | 190 | */ |
| 191 | if (*nr_vecs < BIO_MAX_PAGES) { | 191 | if (*nr_vecs < BIO_MAX_VECS) { |
| 192 | struct bio_vec *bvl; | 192 | struct bio_vec *bvl; |
| 193 | 193 | ||
| 194 | bvl = kmem_cache_alloc(bvs->slab, bvec_alloc_gfp(gfp_mask)); | 194 | bvl = kmem_cache_alloc(bvs->slab, bvec_alloc_gfp(gfp_mask)); |
| 195 | if (likely(bvl) || !(gfp_mask & __GFP_DIRECT_RECLAIM)) | 195 | if (likely(bvl) || !(gfp_mask & __GFP_DIRECT_RECLAIM)) |
| 196 | return bvl; | 196 | return bvl; |
| 197 | *nr_vecs = BIO_MAX_PAGES; | 197 | *nr_vecs = BIO_MAX_VECS; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | return mempool_alloc(pool, gfp_mask); | 200 | return mempool_alloc(pool, gfp_mask); |
| @@ -109,6 +109,7 @@ void blkg_rwstat_recursive_sum(struct blkcg_gq *blkg, struct blkcg_policy *pol, · 108 unmodified lines | |||
| 109 | 109 | ||
| 110 | lockdep_assert_held(&blkg->q->queue_lock); | 110 | lockdep_assert_held(&blkg->q->queue_lock); |
| 111 | 111 | ||
| 112 | memset(sum, 0, sizeof(*sum)); | ||
| 112 | rcu_read_lock(); | 113 | rcu_read_lock(); |
| 113 | blkg_for_each_descendant_pre(pos_blkg, pos_css, blkg) { | 114 | blkg_for_each_descendant_pre(pos_blkg, pos_css, blkg) { |
| 114 | struct blkg_rwstat *rwstat; | 115 | struct blkg_rwstat *rwstat; |
| @@ -122,7 +123,7 @@ void blkg_rwstat_recursive_sum(struct blkcg_gq *blkg, struct blkcg_policy *pol, · 7 unmodified lines | |||
| 122 | rwstat = (void *)pos_blkg + off; | 123 | rwstat = (void *)pos_blkg + off; |
| 123 | 124 | ||
| 124 | for (i = 0; i < BLKG_RWSTAT_NR; i++) | 125 | for (i = 0; i < BLKG_RWSTAT_NR; i++) |
| 125 | sum->cnt[i] = blkg_rwstat_read_counter(rwstat, i); | 126 | sum->cnt[i] += blkg_rwstat_read_counter(rwstat, i); |
| 126 | } | 127 | } |
| 127 | rcu_read_unlock(); | 128 | rcu_read_unlock(); |
| 128 | } | 129 | } |
| @@ -219,7 +219,7 @@ static bool blk_crypto_split_bio_if_needed(struct bio **bio_ptr) · 218 unmodified lines | |||
| 219 | 219 | ||
| 220 | bio_for_each_segment(bv, bio, iter) { | 220 | bio_for_each_segment(bv, bio, iter) { |
| 221 | num_sectors += bv.bv_len >> SECTOR_SHIFT; | 221 | num_sectors += bv.bv_len >> SECTOR_SHIFT; |
| 222 | if (++i == BIO_MAX_PAGES) | 222 | if (++i == BIO_MAX_VECS) |
| 223 | break; | 223 | break; |
| 224 | } | 224 | } |
| 225 | if (num_sectors < bio_sectors(bio)) { | 225 | if (num_sectors < bio_sectors(bio)) { |
| @@ -296,7 +296,7 @@ static unsigned int __blkdev_sectors_to_bio_pages(sector_t nr_sects) · 295 unmodified lines | |||
| 296 | { | 296 | { |
| 297 | sector_t pages = DIV_ROUND_UP_SECTOR_T(nr_sects, PAGE_SIZE / 512); | 297 | sector_t pages = DIV_ROUND_UP_SECTOR_T(nr_sects, PAGE_SIZE / 512); |
| 298 | 298 | ||
| 299 | return min(pages, (sector_t)BIO_MAX_PAGES); | 299 | return min(pages, (sector_t)BIO_MAX_VECS); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | static int __blkdev_issue_zero_pages(struct block_device *bdev, | 302 | static int __blkdev_issue_zero_pages(struct block_device *bdev, |
| @@ -249,7 +249,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, · 248 unmodified lines | |||
| 249 | if (!iov_iter_count(iter)) | 249 | if (!iov_iter_count(iter)) |
| 250 | return -EINVAL; | 250 | return -EINVAL; |
| 251 | 251 | ||
| 252 | bio = bio_kmalloc(gfp_mask, iov_iter_npages(iter, BIO_MAX_PAGES)); | 252 | bio = bio_kmalloc(gfp_mask, iov_iter_npages(iter, BIO_MAX_VECS)); |
| 253 | if (!bio) | 253 | if (!bio) |
| 254 | return -ENOMEM; | 254 | return -ENOMEM; |
| 255 | bio->bi_opf |= req_op(rq); | 255 | bio->bi_opf |= req_op(rq); |
| @@ -240,7 +240,7 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, · 239 unmodified lines | |||
| 240 | */ | 240 | */ |
| 241 | if (op == REQ_OP_ZONE_RESET && | 241 | if (op == REQ_OP_ZONE_RESET && |
| 242 | blkdev_allow_reset_all_zones(bdev, sector, nr_sectors)) { | 242 | blkdev_allow_reset_all_zones(bdev, sector, nr_sectors)) { |
| 243 | bio->bi_opf = REQ_OP_ZONE_RESET_ALL; | 243 | bio->bi_opf = REQ_OP_ZONE_RESET_ALL | REQ_SYNC; |
| 244 | break; | 244 | break; |
| 245 | } | 245 | } |
| 246 | 246 | ||
| @@ -318,6 +318,22 @@ int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode, · 71 unmodified lines | |||
| 318 | return 0; | 318 | return 0; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | static int blkdev_truncate_zone_range(struct block_device *bdev, fmode_t mode, | ||
| 322 | const struct blk_zone_range *zrange) | ||
| 323 | { | ||
| 324 | loff_t start, end; | ||
| 325 | |||
| 326 | if (zrange->sector + zrange->nr_sectors <= zrange->sector || | ||
| 327 | zrange->sector + zrange->nr_sectors > get_capacity(bdev->bd_disk)) | ||
| 328 | /* Out of range */ | ||
| 329 | return -EINVAL; | ||
| 330 | |||
| 331 | start = zrange->sector << SECTOR_SHIFT; | ||
| 332 | end = ((zrange->sector + zrange->nr_sectors) << SECTOR_SHIFT) - 1; | ||
| 333 | |||
| 334 | return truncate_bdev_range(bdev, mode, start, end); | ||
| 335 | } | ||
| 336 | |||
| 321 | /* | 337 | /* |
| 322 | * BLKRESETZONE, BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl processing. | 338 | * BLKRESETZONE, BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl processing. |
| 323 | * Called from blkdev_ioctl. | 339 | * Called from blkdev_ioctl. |
| @@ -329,6 +345,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, · 5 unmodified lines | |||
| 329 | struct request_queue *q; | 345 | struct request_queue *q; |
| 330 | struct blk_zone_range zrange; | 346 | struct blk_zone_range zrange; |
| 331 | enum req_opf op; | 347 | enum req_opf op; |
| 348 | int ret; | ||
| 332 | 349 | ||
| 333 | if (!argp) | 350 | if (!argp) |
| 334 | return -EINVAL; | 351 | return -EINVAL; |
| @@ -352,6 +369,11 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, · 17 unmodified lines | |||
| 352 | switch (cmd) { | 369 | switch (cmd) { |
| 353 | case BLKRESETZONE: | 370 | case BLKRESETZONE: |
| 354 | op = REQ_OP_ZONE_RESET; | 371 | op = REQ_OP_ZONE_RESET; |
| 372 | |||
| 373 | /* Invalidate the page cache, including dirty pages. */ | ||
| 374 | ret = blkdev_truncate_zone_range(bdev, mode, &zrange); | ||
| 375 | if (ret) | ||
| 376 | return ret; | ||
| 355 | break; | 377 | break; |
| 356 | case BLKOPENZONE: | 378 | case BLKOPENZONE: |
| 357 | op = REQ_OP_ZONE_OPEN; | 379 | op = REQ_OP_ZONE_OPEN; |
| @@ -366,8 +388,20 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, · 8 unmodified lines | |||
| 366 | return -ENOTTY; | 388 | return -ENOTTY; |
| 367 | } | 389 | } |
| 368 | 390 | ||
| 369 | return blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors, | 391 | ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors, |
| 370 | GFP_KERNEL); | 392 | GFP_KERNEL); |
| 393 | |||
| 394 | /* | ||
| 395 | * Invalidate the page cache again for zone reset: writes can only be | ||
| 396 | * direct for zoned devices so concurrent writes would not add any page | ||
| 397 | * to the page cache after/during reset. The page cache may be filled | ||
| 398 | * again due to concurrent reads though and dropping the pages for | ||
| 399 | * these is fine. | ||
| 400 | */ | ||
| 401 | if (!ret && cmd == BLKRESETZONE) | ||
| 402 | ret = blkdev_truncate_zone_range(bdev, mode, &zrange); | ||
| 403 | |||
| 404 | return ret; | ||
| 371 | } | 405 | } |
| 372 | 406 | ||
| 373 | static inline unsigned long *blk_alloc_zone_bitmap(int node, | 407 | static inline unsigned long *blk_alloc_zone_bitmap(int node, |
| @@ -229,10 +229,10 @@ static struct bio *bounce_clone_bio(struct bio *bio_src) · 228 unmodified lines | |||
| 229 | * - The point of cloning the biovec is to produce a bio with a biovec | 229 | * - The point of cloning the biovec is to produce a bio with a biovec |
| 230 | * the caller can modify: bi_idx and bi_bvec_done should be 0. | 230 | * the caller can modify: bi_idx and bi_bvec_done should be 0. |
| 231 | * | 231 | * |
| 232 | * - The original bio could've had more than BIO_MAX_PAGES biovecs; if | 232 | * - The original bio could've had more than BIO_MAX_VECS biovecs; if |
| 233 | * we tried to clone the whole thing bio_alloc_bioset() would fail. | 233 | * we tried to clone the whole thing bio_alloc_bioset() would fail. |
| 234 | * But the clone should succeed as long as the number of biovecs we | 234 | * But the clone should succeed as long as the number of biovecs we |
| 235 | * actually need to allocate is fewer than BIO_MAX_PAGES. | 235 | * actually need to allocate is fewer than BIO_MAX_VECS. |
| 236 | * | 236 | * |
| 237 | * - Lastly, bi_vcnt should not be looked at or relied upon by code | 237 | * - Lastly, bi_vcnt should not be looked at or relied upon by code |
| 238 | * that does not own the bio - reason being drivers don't use it for | 238 | * that does not own the bio - reason being drivers don't use it for |
| @@ -299,7 +299,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, · 60 unmodified lines | |||
| 299 | int sectors = 0; | 299 | int sectors = 0; |
| 300 | 300 | ||
| 301 | bio_for_each_segment(from, *bio_orig, iter) { | 301 | bio_for_each_segment(from, *bio_orig, iter) { |
| 302 | if (i++ < BIO_MAX_PAGES) | 302 | if (i++ < BIO_MAX_VECS) |
| 303 | sectors += from.bv_len >> 9; | 303 | sectors += from.bv_len >> 9; |
| 304 | if (page_to_pfn(from.bv_page) > q->limits.bounce_pfn) | 304 | if (page_to_pfn(from.bv_page) > q->limits.bounce_pfn) |
| 305 | bounce = true; | 305 | bounce = true; |
| @@ -534,10 +534,8 @@ static void register_disk(struct device *parent, struct gendisk *disk, · 533 unmodified lines | |||
| 534 | kobject_create_and_add("holders", &ddev->kobj); | 534 | kobject_create_and_add("holders", &ddev->kobj); |
| 535 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); | 535 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); |
| 536 | 536 | ||
| 537 | if (disk->flags & GENHD_FL_HIDDEN) { | 537 | if (disk->flags & GENHD_FL_HIDDEN) |
| 538 | dev_set_uevent_suppress(ddev, 0); | ||
| 539 | return; | 538 | return; |
| 540 | } | ||
| 541 | 539 | ||
| 542 | disk_scan_partitions(disk); | 540 | disk_scan_partitions(disk); |
| 543 | 541 | ||
| @@ -99,8 +99,6 @@ static LIST_HEAD(fore200e_boards); · 98 unmodified lines | |||
| 99 | 99 | ||
| 100 | MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen"); | 100 | MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen"); |
| 101 | MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION); | 101 | MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION); |
| 102 | MODULE_SUPPORTED_DEVICE("PCA-200E, SBA-200E"); | ||
| 103 | |||
| 104 | 102 | ||
| 105 | static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = { | 103 | static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = { |
| 106 | { BUFFER_S1_NBR, BUFFER_L1_NBR }, | 104 | { BUFFER_S1_NBR, BUFFER_L1_NBR }, |
| @@ -325,22 +325,22 @@ static void rpm_put_suppliers(struct device *dev) · 324 unmodified lines | |||
| 325 | static int __rpm_callback(int (*cb)(struct device *), struct device *dev) | 325 | static int __rpm_callback(int (*cb)(struct device *), struct device *dev) |
| 326 | __releases(&dev->power.lock) __acquires(&dev->power.lock) | 326 | __releases(&dev->power.lock) __acquires(&dev->power.lock) |
| 327 | { | 327 | { |
| 328 | bool use_links = dev->power.links_count > 0; | ||
| 329 | bool get = false; | ||
| 330 | int retval, idx; | 328 | int retval, idx; |
| 331 | bool put; | 329 | bool use_links = dev->power.links_count > 0; |
| 332 | 330 | ||
| 333 | if (dev->power.irq_safe) { | 331 | if (dev->power.irq_safe) { |
| 334 | spin_unlock(&dev->power.lock); | 332 | spin_unlock(&dev->power.lock); |
| 335 | } else if (!use_links) { | ||
| 336 | spin_unlock_irq(&dev->power.lock); | ||
| 337 | } else { | 333 | } else { |
| 338 | get = dev->power.runtime_status == RPM_RESUMING; | ||
| 339 | |||
| 340 | spin_unlock_irq(&dev->power.lock); | 334 | spin_unlock_irq(&dev->power.lock); |
| 341 | 335 | ||
| 342 | /* Resume suppliers if necessary. */ | 336 | /* |
| 343 | if (get) { | 337 | * Resume suppliers if necessary. |
| 338 | * | ||
| 339 | * The device's runtime PM status cannot change until this | ||
| 340 | * routine returns, so it is safe to read the status outside of | ||
| 341 | * the lock. | ||
| 342 | */ | ||
| 343 | if (use_links && dev->power.runtime_status == RPM_RESUMING) { | ||
| 344 | idx = device_links_read_lock(); | 344 | idx = device_links_read_lock(); |
| 345 | 345 | ||
| 346 | retval = rpm_get_suppliers(dev); | 346 | retval = rpm_get_suppliers(dev); |
| @@ -355,36 +355,24 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) · 8 unmodified lines | |||
| 355 | 355 | ||
| 356 | if (dev->power.irq_safe) { | 356 | if (dev->power.irq_safe) { |
| 357 | spin_lock(&dev->power.lock); | 357 | spin_lock(&dev->power.lock); |
| 358 | return retval; | 358 | } else { |
| 359 | } | 359 | /* |
| 360 | 360 | * If the device is suspending and the callback has returned | |
| 361 | spin_lock_irq(&dev->power.lock); | 361 | * success, drop the usage counters of the suppliers that have |
| 362 | 362 | * been reference counted on its resume. | |
| 363 | if (!use_links) | 363 | * |
| 364 | return retval; | 364 | * Do that if resume fails too. |
| 365 | 365 | */ | |
| 366 | /* | 366 | if (use_links |
| 367 | * If the device is suspending and the callback has returned success, | 367 | && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) |
| 368 | * drop the usage counters of the suppliers that have been reference | 368 | || (dev->power.runtime_status == RPM_RESUMING && retval))) { |
| 369 | * counted on its resume. | 369 | idx = device_links_read_lock(); |
| 370 | * | ||
| 371 | * Do that if the resume fails too. | ||
| 372 | */ | ||
| 373 | put = dev->power.runtime_status == RPM_SUSPENDING && !retval; | ||
| 374 | if (put) | ||
| 375 | __update_runtime_status(dev, RPM_SUSPENDED); | ||
| 376 | else | ||
| 377 | put = get && retval; | ||
| 378 | |||
| 379 | if (put) { | ||
| 380 | spin_unlock_irq(&dev->power.lock); | ||
| 381 | |||
| 382 | idx = device_links_read_lock(); | ||
| 383 | 370 | ||
| 384 | fail: | 371 | fail: |
| 385 | rpm_put_suppliers(dev); | 372 | rpm_put_suppliers(dev); |
| 386 | 373 | ||
| 387 | device_links_read_unlock(idx); | 374 | device_links_read_unlock(idx); |
| 375 | } | ||
| 388 | 376 | ||
| 389 | spin_lock_irq(&dev->power.lock); | 377 | spin_lock_irq(&dev->power.lock); |
| 390 | } | 378 | } |
| @@ -938,6 +938,9 @@ int software_node_register(const struct software_node *node) · 937 unmodified lines | |||
| 938 | if (software_node_to_swnode(node)) | 938 | if (software_node_to_swnode(node)) |
| 939 | return -EEXIST; | 939 | return -EEXIST; |
| 940 | 940 | ||
| 941 | if (node->parent && !parent) | ||
| 942 | return -EINVAL; | ||
| 943 | |||
| 941 | return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); | 944 | return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); |
| 942 | } | 945 | } |
| 943 | EXPORT_SYMBOL_GPL(software_node_register); | 946 | EXPORT_SYMBOL_GPL(software_node_register); |
| @@ -1002,25 +1005,33 @@ EXPORT_SYMBOL_GPL(fwnode_remove_software_node); · 58 unmodified lines | |||
| 1002 | /** | 1005 | /** |
| 1003 | * device_add_software_node - Assign software node to a device | 1006 | * device_add_software_node - Assign software node to a device |
| 1004 | * @dev: The device the software node is meant for. | 1007 | * @dev: The device the software node is meant for. |
| 1005 | * @swnode: The software node. | 1008 | * @node: The software node. |
| 1006 | * | 1009 | * |
| 1007 | * This function will register @swnode and make it the secondary firmware node | 1010 | * This function will make @node the secondary firmware node pointer of @dev. If |
| 1008 | * pointer of @dev. If @dev has no primary node, then @swnode will become the primary | 1011 | * @dev has no primary node, then @node will become the primary node. The |
| 1009 | * node. | 1012 | * function will register @node automatically if it wasn't already registered. |
| 1010 | */ | 1013 | */ |
| 1011 | int device_add_software_node(struct device *dev, const struct software_node *swnode) | 1014 | int device_add_software_node(struct device *dev, const struct software_node *node) |
| 1012 | { | 1015 | { |
| 1016 | struct swnode *swnode; | ||
| 1013 | int ret; | 1017 | int ret; |
| 1014 | 1018 | ||
| 1015 | /* Only one software node per device. */ | 1019 | /* Only one software node per device. */ |
| 1016 | if (dev_to_swnode(dev)) | 1020 | if (dev_to_swnode(dev)) |
| 1017 | return -EBUSY; | 1021 | return -EBUSY; |
| 1018 | 1022 | ||
| 1019 | ret = software_node_register(swnode); | 1023 | swnode = software_node_to_swnode(node); |
| 1020 | if (ret) | 1024 | if (swnode) { |
| 1021 | return ret; | 1025 | kobject_get(&swnode->kobj); |
| 1026 | } else { | ||
| 1027 | ret = software_node_register(node); | ||
| 1028 | if (ret) | ||
| 1029 | return ret; | ||
| 1030 | |||
| 1031 | swnode = software_node_to_swnode(node); | ||
| 1032 | } | ||
| 1022 | 1033 | ||
| 1023 | set_secondary_fwnode(dev, software_node_fwnode(swnode)); | 1034 | set_secondary_fwnode(dev, &swnode->fwnode); |
| 1024 | 1035 | ||
| 1025 | return 0; | 1036 | return 0; |
| 1026 | } | 1037 | } |
| @@ -1324,7 +1324,7 @@ struct bm_extent { · 1323 unmodified lines | |||
| 1324 | * A followup commit may allow even bigger BIO sizes, | 1324 | * A followup commit may allow even bigger BIO sizes, |
| 1325 | * once we thought that through. */ | 1325 | * once we thought that through. */ |
| 1326 | #define DRBD_MAX_BIO_SIZE (1U << 20) | 1326 | #define DRBD_MAX_BIO_SIZE (1U << 20) |
| 1327 | #if DRBD_MAX_BIO_SIZE > (BIO_MAX_PAGES << PAGE_SHIFT) | 1327 | #if DRBD_MAX_BIO_SIZE > (BIO_MAX_VECS << PAGE_SHIFT) |
| 1328 | #error Architecture not supported: DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE | 1328 | #error Architecture not supported: DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE |
| 1329 | #endif | 1329 | #endif |
| 1330 | #define DRBD_MAX_BIO_SIZE_SAFE (1U << 12) /* Works always = 4k */ | 1330 | #define DRBD_MAX_BIO_SIZE_SAFE (1U << 12) /* Works always = 4k */ |
| @@ -5091,7 +5091,6 @@ module_param(floppy, charp, 0); · 5090 unmodified lines | |||
| 5091 | module_param(FLOPPY_IRQ, int, 0); | 5091 | module_param(FLOPPY_IRQ, int, 0); |
| 5092 | module_param(FLOPPY_DMA, int, 0); | 5092 | module_param(FLOPPY_DMA, int, 0); |
| 5093 | MODULE_AUTHOR("Alain L. Knaff"); | 5093 | MODULE_AUTHOR("Alain L. Knaff"); |
| 5094 | MODULE_SUPPORTED_DEVICE("fd"); | ||
| 5095 | MODULE_LICENSE("GPL"); | 5094 | MODULE_LICENSE("GPL"); |
| 5096 | 5095 | ||
| 5097 | /* This doesn't actually get used other than for module information */ | 5096 | /* This doesn't actually get used other than for module information */ |
| @@ -871,6 +871,7 @@ static int rsxx_pci_probe(struct pci_dev *dev, · 870 unmodified lines | |||
| 871 | card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event"); | 871 | card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event"); |
| 872 | if (!card->event_wq) { | 872 | if (!card->event_wq) { |
| 873 | dev_err(CARD_TO_DEV(card), "Failed card event setup.\n"); | 873 | dev_err(CARD_TO_DEV(card), "Failed card event setup.\n"); |
| 874 | st = -ENOMEM; | ||
| 874 | goto failed_event_handler; | 875 | goto failed_event_handler; |
| 875 | } | 876 | } |
| 876 | 877 | ||
| @@ -877,6 +877,7 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 876 unmodified lines | |||
| 877 | if (card->mm_pages[0].desc == NULL || | 877 | if (card->mm_pages[0].desc == NULL || |
| 878 | card->mm_pages[1].desc == NULL) { | 878 | card->mm_pages[1].desc == NULL) { |
| 879 | dev_printk(KERN_ERR, &card->dev->dev, "alloc failed\n"); | 879 | dev_printk(KERN_ERR, &card->dev->dev, "alloc failed\n"); |
| 880 | ret = -ENOMEM; | ||
| 880 | goto failed_alloc; | 881 | goto failed_alloc; |
| 881 | } | 882 | } |
| 882 | reset_page(&card->mm_pages[0]); | 883 | reset_page(&card->mm_pages[0]); |
| @@ -888,8 +889,10 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 5 unmodified lines | |||
| 888 | spin_lock_init(&card->lock); | 889 | spin_lock_init(&card->lock); |
| 889 | 890 | ||
| 890 | card->queue = blk_alloc_queue(NUMA_NO_NODE); | 891 | card->queue = blk_alloc_queue(NUMA_NO_NODE); |
| 891 | if (!card->queue) | 892 | if (!card->queue) { |
| 893 | ret = -ENOMEM; | ||
| 892 | goto failed_alloc; | 894 | goto failed_alloc; |
| 895 | } | ||
| 893 | 896 | ||
| 894 | tasklet_init(&card->tasklet, process_page, (unsigned long)card); | 897 | tasklet_init(&card->tasklet, process_page, (unsigned long)card); |
| 895 | 898 | ||
| @@ -627,7 +627,7 @@ static ssize_t writeback_store(struct device *dev, · 626 unmodified lines | |||
| 627 | struct bio_vec bio_vec; | 627 | struct bio_vec bio_vec; |
| 628 | struct page *page; | 628 | struct page *page; |
| 629 | ssize_t ret = len; | 629 | ssize_t ret = len; |
| 630 | int mode; | 630 | int mode, err; |
| 631 | unsigned long blk_idx = 0; | 631 | unsigned long blk_idx = 0; |
| 632 | 632 | ||
| 633 | if (sysfs_streq(buf, "idle")) | 633 | if (sysfs_streq(buf, "idle")) |
| @@ -638,8 +638,8 @@ static ssize_t writeback_store(struct device *dev, · 4 unmodified lines | |||
| 638 | if (strncmp(buf, PAGE_WB_SIG, sizeof(PAGE_WB_SIG) - 1)) | 638 | if (strncmp(buf, PAGE_WB_SIG, sizeof(PAGE_WB_SIG) - 1)) |
| 639 | return -EINVAL; | 639 | return -EINVAL; |
| 640 | 640 | ||
| 641 | ret = kstrtol(buf + sizeof(PAGE_WB_SIG) - 1, 10, &index); | 641 | if (kstrtol(buf + sizeof(PAGE_WB_SIG) - 1, 10, &index) || |
| 642 | if (ret || index >= nr_pages) | 642 | index >= nr_pages) |
| 643 | return -EINVAL; | 643 | return -EINVAL; |
| 644 | 644 | ||
| 645 | nr_pages = 1; | 645 | nr_pages = 1; |
| @@ -663,7 +663,7 @@ static ssize_t writeback_store(struct device *dev, · 17 unmodified lines | |||
| 663 | goto release_init_lock; | 663 | goto release_init_lock; |
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | while (nr_pages--) { | 666 | for (; nr_pages != 0; index++, nr_pages--) { |
| 667 | struct bio_vec bvec; | 667 | struct bio_vec bvec; |
| 668 | 668 | ||
| 669 | bvec.bv_page = page; | 669 | bvec.bv_page = page; |
| @@ -728,12 +728,17 @@ static ssize_t writeback_store(struct device *dev, · 58 unmodified lines | |||
| 728 | * XXX: A single page IO would be inefficient for write | 728 | * XXX: A single page IO would be inefficient for write |
| 729 | * but it would be not bad as starter. | 729 | * but it would be not bad as starter. |
| 730 | */ | 730 | */ |
| 731 | ret = submit_bio_wait(&bio); | 731 | err = submit_bio_wait(&bio); |
| 732 | if (ret) { | 732 | if (err) { |
| 733 | zram_slot_lock(zram, index); | 733 | zram_slot_lock(zram, index); |
| 734 | zram_clear_flag(zram, index, ZRAM_UNDER_WB); | 734 | zram_clear_flag(zram, index, ZRAM_UNDER_WB); |
| 735 | zram_clear_flag(zram, index, ZRAM_IDLE); | 735 | zram_clear_flag(zram, index, ZRAM_IDLE); |
| 736 | zram_slot_unlock(zram, index); | 736 | zram_slot_unlock(zram, index); |
| 737 | /* | ||
| 738 | * Return last IO error unless every IO were | ||
| 739 | * not suceeded. | ||
| 740 | */ | ||
| 741 | ret = err; | ||
| 737 | continue; | 742 | continue; |
| 738 | } | 743 | } |
| 739 | 744 | ||
| @@ -194,5 +194,4 @@ module_init(rsi_91x_bt_module_init); · 193 unmodified lines | |||
| 194 | module_exit(rsi_91x_bt_module_exit); | 194 | module_exit(rsi_91x_bt_module_exit); |
| 195 | MODULE_AUTHOR("Redpine Signals Inc"); | 195 | MODULE_AUTHOR("Redpine Signals Inc"); |
| 196 | MODULE_DESCRIPTION("RSI BT driver"); | 196 | MODULE_DESCRIPTION("RSI BT driver"); |
| 197 | MODULE_SUPPORTED_DEVICE("RSI-BT"); | ||
| 198 | MODULE_LICENSE("Dual BSD/GPL"); | 197 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -81,9 +81,6 @@ MODULE_DESCRIPTION("Driver for Applicom Profibus card"); · 80 unmodified lines | |||
| 81 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
| 82 | MODULE_ALIAS_MISCDEV(AC_MINOR); | 82 | MODULE_ALIAS_MISCDEV(AC_MINOR); |
| 83 | 83 | ||
| 84 | MODULE_SUPPORTED_DEVICE("ac"); | ||
| 85 | |||
| 86 | |||
| 87 | static struct applicom_board { | 84 | static struct applicom_board { |
| 88 | unsigned long PhysIO; | 85 | unsigned long PhysIO; |
| 89 | void __iomem *RamIO; | 86 | void __iomem *RamIO; |
| @@ -64,7 +64,6 @@ · 63 unmodified lines | |||
| 64 | MODULE_LICENSE("GPL"); | 64 | MODULE_LICENSE("GPL"); |
| 65 | MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); | 65 | MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); |
| 66 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); | 66 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); |
| 67 | MODULE_SUPPORTED_DEVICE("toshiba"); | ||
| 68 | 67 | ||
| 69 | static DEFINE_MUTEX(tosh_mutex); | 68 | static DEFINE_MUTEX(tosh_mutex); |
| 70 | static int tosh_fn; | 69 | static int tosh_fn; |
| @@ -730,7 +730,8 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 729 unmodified lines | |||
| 730 | struct clk_rate_request parent_req = { }; | 730 | struct clk_rate_request parent_req = { }; |
| 731 | struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw); | 731 | struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw); |
| 732 | struct clk_hw *xo, *p0, *p1, *p2; | 732 | struct clk_hw *xo, *p0, *p1, *p2; |
| 733 | unsigned long request, p0_rate; | 733 | unsigned long p0_rate; |
| 734 | u8 mux_div = cgfx->div; | ||
| 734 | int ret; | 735 | int ret; |
| 735 | 736 | ||
| 736 | p0 = cgfx->hws[0]; | 737 | p0 = cgfx->hws[0]; |
| @@ -750,14 +751,15 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 13 unmodified lines | |||
| 750 | return 0; | 751 | return 0; |
| 751 | } | 752 | } |
| 752 | 753 | ||
| 753 | request = req->rate; | 754 | if (mux_div == 0) |
| 754 | if (cgfx->div > 1) | 755 | mux_div = 1; |
| 755 | parent_req.rate = request = request * cgfx->div; | 756 | |
| 757 | parent_req.rate = req->rate * mux_div; | ||
| 756 | 758 | ||
| 757 | /* This has to be a fixed rate PLL */ | 759 | /* This has to be a fixed rate PLL */ |
| 758 | p0_rate = clk_hw_get_rate(p0); | 760 | p0_rate = clk_hw_get_rate(p0); |
| 759 | 761 | ||
| 760 | if (request == p0_rate) { | 762 | if (parent_req.rate == p0_rate) { |
| 761 | req->rate = req->best_parent_rate = p0_rate; | 763 | req->rate = req->best_parent_rate = p0_rate; |
| 762 | req->best_parent_hw = p0; | 764 | req->best_parent_hw = p0; |
| 763 | return 0; | 765 | return 0; |
| @@ -765,7 +767,7 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 1 unmodified line | |||
| 765 | 767 | ||
| 766 | if (req->best_parent_hw == p0) { | 768 | if (req->best_parent_hw == p0) { |
| 767 | /* Are we going back to a previously used rate? */ | 769 | /* Are we going back to a previously used rate? */ |
| 768 | if (clk_hw_get_rate(p2) == request) | 770 | if (clk_hw_get_rate(p2) == parent_req.rate) |
| 769 | req->best_parent_hw = p2; | 771 | req->best_parent_hw = p2; |
| 770 | else | 772 | else |
| 771 | req->best_parent_hw = p1; | 773 | req->best_parent_hw = p1; |
| @@ -780,8 +782,7 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 8 unmodified lines | |||
| 780 | return ret; | 782 | return ret; |
| 781 | 783 | ||
| 782 | req->rate = req->best_parent_rate = parent_req.rate; | 784 | req->rate = req->best_parent_rate = parent_req.rate; |
| 783 | if (cgfx->div > 1) | 785 | req->rate /= mux_div; |
| 784 | req->rate /= cgfx->div; | ||
| 785 | 786 | ||
| 786 | return 0; | 787 | return 0; |
| 787 | } | 788 | } |
| @@ -510,9 +510,12 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = { · 509 unmodified lines | |||
| 510 | .num_clks = ARRAY_SIZE(sm8350_rpmh_clocks), | 510 | .num_clks = ARRAY_SIZE(sm8350_rpmh_clocks), |
| 511 | }; | 511 | }; |
| 512 | 512 | ||
| 513 | /* Resource name must match resource id present in cmd-db */ | ||
| 514 | DEFINE_CLK_RPMH_ARC(sc7280, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 4); | ||
| 515 | |||
| 513 | static struct clk_hw *sc7280_rpmh_clocks[] = { | 516 | static struct clk_hw *sc7280_rpmh_clocks[] = { |
| 514 | [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, | 517 | [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw, |
| 515 | [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, | 518 | [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw, |
| 516 | [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, | 519 | [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, |
| 517 | [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, | 520 | [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, |
| 518 | [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, | 521 | [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, |
| @@ -620,7 +620,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { · 619 unmodified lines | |||
| 620 | .name = "gcc_sdcc1_apps_clk_src", | 620 | .name = "gcc_sdcc1_apps_clk_src", |
| 621 | .parent_data = gcc_parent_data_1, | 621 | .parent_data = gcc_parent_data_1, |
| 622 | .num_parents = 5, | 622 | .num_parents = 5, |
| 623 | .ops = &clk_rcg2_ops, | 623 | .ops = &clk_rcg2_floor_ops, |
| 624 | }, | 624 | }, |
| 625 | }; | 625 | }; |
| 626 | 626 | ||
| @@ -642,7 +642,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { · 15 unmodified lines | |||
| 642 | .name = "gcc_sdcc1_ice_core_clk_src", | 642 | .name = "gcc_sdcc1_ice_core_clk_src", |
| 643 | .parent_data = gcc_parent_data_0, | 643 | .parent_data = gcc_parent_data_0, |
| 644 | .num_parents = 4, | 644 | .num_parents = 4, |
| 645 | .ops = &clk_rcg2_floor_ops, | 645 | .ops = &clk_rcg2_ops, |
| 646 | }, | 646 | }, |
| 647 | }; | 647 | }; |
| 648 | 648 | ||
| @@ -31,7 +31,7 @@ struct stm32_timer_cnt { · 30 unmodified lines | |||
| 31 | struct counter_device counter; | 31 | struct counter_device counter; |
| 32 | struct regmap *regmap; | 32 | struct regmap *regmap; |
| 33 | struct clk *clk; | 33 | struct clk *clk; |
| 34 | u32 ceiling; | 34 | u32 max_arr; |
| 35 | bool enabled; | 35 | bool enabled; |
| 36 | struct stm32_timer_regs bak; | 36 | struct stm32_timer_regs bak; |
| 37 | }; | 37 | }; |
| @@ -44,13 +44,14 @@ struct stm32_timer_cnt { · 6 unmodified lines | |||
| 44 | * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges | 44 | * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges |
| 45 | */ | 45 | */ |
| 46 | enum stm32_count_function { | 46 | enum stm32_count_function { |
| 47 | STM32_COUNT_SLAVE_MODE_DISABLED = -1, | 47 | STM32_COUNT_SLAVE_MODE_DISABLED, |
| 48 | STM32_COUNT_ENCODER_MODE_1, | 48 | STM32_COUNT_ENCODER_MODE_1, |
| 49 | STM32_COUNT_ENCODER_MODE_2, | 49 | STM32_COUNT_ENCODER_MODE_2, |
| 50 | STM32_COUNT_ENCODER_MODE_3, | 50 | STM32_COUNT_ENCODER_MODE_3, |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | static enum counter_count_function stm32_count_functions[] = { | 53 | static enum counter_count_function stm32_count_functions[] = { |
| 54 | [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE, | ||
| 54 | [STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, | 55 | [STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, |
| 55 | [STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, | 56 | [STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, |
| 56 | [STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4, | 57 | [STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4, |
| @@ -73,8 +74,10 @@ static int stm32_count_write(struct counter_device *counter, · 16 unmodified lines | |||
| 73 | const unsigned long val) | 74 | const unsigned long val) |
| 74 | { | 75 | { |
| 75 | struct stm32_timer_cnt *const priv = counter->priv; | 76 | struct stm32_timer_cnt *const priv = counter->priv; |
| 77 | u32 ceiling; | ||
| 76 | 78 | ||
| 77 | if (val > priv->ceiling) | 79 | regmap_read(priv->regmap, TIM_ARR, &ceiling); |
| 80 | if (val > ceiling) | ||
| 78 | return -EINVAL; | 81 | return -EINVAL; |
| 79 | 82 | ||
| 80 | return regmap_write(priv->regmap, TIM_CNT, val); | 83 | return regmap_write(priv->regmap, TIM_CNT, val); |
| @@ -90,6 +93,9 @@ static int stm32_count_function_get(struct counter_device *counter, · 9 unmodified lines | |||
| 90 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | 93 | regmap_read(priv->regmap, TIM_SMCR, &smcr); |
| 91 | 94 | ||
| 92 | switch (smcr & TIM_SMCR_SMS) { | 95 | switch (smcr & TIM_SMCR_SMS) { |
| 96 | case 0: | ||
| 97 | *function = STM32_COUNT_SLAVE_MODE_DISABLED; | ||
| 98 | return 0; | ||
| 93 | case 1: | 99 | case 1: |
| 94 | *function = STM32_COUNT_ENCODER_MODE_1; | 100 | *function = STM32_COUNT_ENCODER_MODE_1; |
| 95 | return 0; | 101 | return 0; |
| @@ -99,9 +105,9 @@ static int stm32_count_function_get(struct counter_device *counter, · 3 unmodified lines | |||
| 99 | case 3: | 105 | case 3: |
| 100 | *function = STM32_COUNT_ENCODER_MODE_3; | 106 | *function = STM32_COUNT_ENCODER_MODE_3; |
| 101 | return 0; | 107 | return 0; |
| 108 | default: | ||
| 109 | return -EINVAL; | ||
| 102 | } | 110 | } |
| 103 | |||
| 104 | return -EINVAL; | ||
| 105 | } | 111 | } |
| 106 | 112 | ||
| 107 | static int stm32_count_function_set(struct counter_device *counter, | 113 | static int stm32_count_function_set(struct counter_device *counter, |
| @@ -112,6 +118,9 @@ static int stm32_count_function_set(struct counter_device *counter, · 4 unmodified lines | |||
| 112 | u32 cr1, sms; | 118 | u32 cr1, sms; |
| 113 | 119 | ||
| 114 | switch (function) { | 120 | switch (function) { |
| 121 | case STM32_COUNT_SLAVE_MODE_DISABLED: | ||
| 122 | sms = 0; | ||
| 123 | break; | ||
| 115 | case STM32_COUNT_ENCODER_MODE_1: | 124 | case STM32_COUNT_ENCODER_MODE_1: |
| 116 | sms = 1; | 125 | sms = 1; |
| 117 | break; | 126 | break; |
| @@ -122,8 +131,7 @@ static int stm32_count_function_set(struct counter_device *counter, · 4 unmodified lines | |||
| 122 | sms = 3; | 131 | sms = 3; |
| 123 | break; | 132 | break; |
| 124 | default: | 133 | default: |
| 125 | sms = 0; | 134 | return -EINVAL; |
| 126 | break; | ||
| 127 | } | 135 | } |
| 128 | 136 | ||
| 129 | /* Store enable status */ | 137 | /* Store enable status */ |
| @@ -131,10 +139,6 @@ static int stm32_count_function_set(struct counter_device *counter, · 1 unmodified line | |||
| 131 | 139 | ||
| 132 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); | 140 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); |
| 133 | 141 | ||
| 134 | /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ | ||
| 135 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); | ||
| 136 | regmap_write(priv->regmap, TIM_ARR, priv->ceiling); | ||
| 137 | |||
| 138 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); | 142 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); |
| 139 | 143 | ||
| 140 | /* Make sure that registers are updated */ | 144 | /* Make sure that registers are updated */ |
| @@ -185,11 +189,13 @@ static ssize_t stm32_count_ceiling_write(struct counter_device *counter, · 44 unmodified lines | |||
| 185 | if (ret) | 189 | if (ret) |
| 186 | return ret; | 190 | return ret; |
| 187 | 191 | ||
| 192 | if (ceiling > priv->max_arr) | ||
| 193 | return -ERANGE; | ||
| 194 | |||
| 188 | /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ | 195 | /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ |
| 189 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); | 196 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); |
| 190 | regmap_write(priv->regmap, TIM_ARR, ceiling); | 197 | regmap_write(priv->regmap, TIM_ARR, ceiling); |
| 191 | 198 | ||
| 192 | priv->ceiling = ceiling; | ||
| 193 | return len; | 199 | return len; |
| 194 | } | 200 | } |
| 195 | 201 | ||
| @@ -274,31 +280,36 @@ static int stm32_action_get(struct counter_device *counter, · 78 unmodified lines | |||
| 274 | size_t function; | 280 | size_t function; |
| 275 | int err; | 281 | int err; |
| 276 | 282 | ||
| 277 | /* Default action mode (e.g. STM32_COUNT_SLAVE_MODE_DISABLED) */ | ||
| 278 | *action = STM32_SYNAPSE_ACTION_NONE; | ||
| 279 | |||
| 280 | err = stm32_count_function_get(counter, count, &function); | 283 | err = stm32_count_function_get(counter, count, &function); |
| 281 | if (err) | 284 | if (err) |
| 282 | return 0; | 285 | return err; |
| 283 | 286 | ||
| 284 | switch (function) { | 287 | switch (function) { |
| 288 | case STM32_COUNT_SLAVE_MODE_DISABLED: | ||
| 289 | /* counts on internal clock when CEN=1 */ | ||
| 290 | *action = STM32_SYNAPSE_ACTION_NONE; | ||
| 291 | return 0; | ||
| 285 | case STM32_COUNT_ENCODER_MODE_1: | 292 | case STM32_COUNT_ENCODER_MODE_1: |
| 286 | /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ | 293 | /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ |
| 287 | if (synapse->signal->id == count->synapses[0].signal->id) | 294 | if (synapse->signal->id == count->synapses[0].signal->id) |
| 288 | *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; | 295 | *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; |
| 289 | break; | 296 | else |
| 297 | *action = STM32_SYNAPSE_ACTION_NONE; | ||
| 298 | return 0; | ||
| 290 | case STM32_COUNT_ENCODER_MODE_2: | 299 | case STM32_COUNT_ENCODER_MODE_2: |
| 291 | /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ | 300 | /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ |
| 292 | if (synapse->signal->id == count->synapses[1].signal->id) | 301 | if (synapse->signal->id == count->synapses[1].signal->id) |
| 293 | *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; | 302 | *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; |
| 294 | break; | 303 | else |
| 304 | *action = STM32_SYNAPSE_ACTION_NONE; | ||
| 305 | return 0; | ||
| 295 | case STM32_COUNT_ENCODER_MODE_3: | 306 | case STM32_COUNT_ENCODER_MODE_3: |
| 296 | /* counts up/down on both TI1FP1 and TI2FP2 edges */ | 307 | /* counts up/down on both TI1FP1 and TI2FP2 edges */ |
| 297 | *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; | 308 | *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; |
| 298 | break; | 309 | return 0; |
| 310 | default: | ||
| 311 | return -EINVAL; | ||
| 299 | } | 312 | } |
| 300 | |||
| 301 | return 0; | ||
| 302 | } | 313 | } |
| 303 | 314 | ||
| 304 | static const struct counter_ops stm32_timer_cnt_ops = { | 315 | static const struct counter_ops stm32_timer_cnt_ops = { |
| @@ -359,7 +370,7 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) · 54 unmodified lines | |||
| 359 | 370 | ||
| 360 | priv->regmap = ddata->regmap; | 371 | priv->regmap = ddata->regmap; |
| 361 | priv->clk = ddata->clk; | 372 | priv->clk = ddata->clk; |
| 362 | priv->ceiling = ddata->max_arr; | 373 | priv->max_arr = ddata->max_arr; |
| 363 | 374 | ||
| 364 | priv->counter.name = dev_name(dev); | 375 | priv->counter.name = dev_name(dev); |
| 365 | priv->counter.parent = dev; | 376 | priv->counter.parent = dev; |
| @@ -103,6 +103,8 @@ static const struct of_device_id whitelist[] __initconst = { · 102 unmodified lines | |||
| 103 | static const struct of_device_id blacklist[] __initconst = { | 103 | static const struct of_device_id blacklist[] __initconst = { |
| 104 | { .compatible = "allwinner,sun50i-h6", }, | 104 | { .compatible = "allwinner,sun50i-h6", }, |
| 105 | 105 | ||
| 106 | { .compatible = "arm,vexpress", }, | ||
| 107 | |||
| 106 | { .compatible = "calxeda,highbank", }, | 108 | { .compatible = "calxeda,highbank", }, |
| 107 | { .compatible = "calxeda,ecx-2000", }, | 109 | { .compatible = "calxeda,ecx-2000", }, |
| 108 | 110 | ||
| @@ -317,9 +317,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) · 316 unmodified lines | |||
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | base = ioremap(res->start, resource_size(res)); | 319 | base = ioremap(res->start, resource_size(res)); |
| 320 | if (IS_ERR(base)) { | 320 | if (!base) { |
| 321 | dev_err(dev, "failed to map resource %pR\n", res); | 321 | dev_err(dev, "failed to map resource %pR\n", res); |
| 322 | ret = PTR_ERR(base); | 322 | ret = -ENOMEM; |
| 323 | goto release_region; | 323 | goto release_region; |
| 324 | } | 324 | } |
| 325 | 325 | ||
| @@ -374,7 +374,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) · 48 unmodified lines | |||
| 374 | error: | 374 | error: |
| 375 | kfree(data); | 375 | kfree(data); |
| 376 | unmap_base: | 376 | unmap_base: |
| 377 | iounmap(data->base); | 377 | iounmap(base); |
| 378 | release_region: | 378 | release_region: |
| 379 | release_mem_region(res->start, resource_size(res)); | 379 | release_mem_region(res->start, resource_size(res)); |
| 380 | return ret; | 380 | return ret; |
| @@ -927,7 +927,7 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) · 926 unmodified lines | |||
| 927 | } | 927 | } |
| 928 | 928 | ||
| 929 | /* first try to find a slot in an existing linked list entry */ | 929 | /* first try to find a slot in an existing linked list entry */ |
| 930 | for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) { | 930 | for (prsv = efi_memreserve_root->next; prsv; ) { |
| 931 | rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB); | 931 | rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB); |
| 932 | index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size); | 932 | index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size); |
| 933 | if (index < rsv->size) { | 933 | if (index < rsv->size) { |
| @@ -937,6 +937,7 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) · 3 unmodified lines | |||
| 937 | memunmap(rsv); | 937 | memunmap(rsv); |
| 938 | return efi_mem_reserve_iomem(addr, size); | 938 | return efi_mem_reserve_iomem(addr, size); |
| 939 | } | 939 | } |
| 940 | prsv = rsv->next; | ||
| 940 | memunmap(rsv); | 941 | memunmap(rsv); |
| 941 | } | 942 | } |
| 942 | 943 | ||
| @@ -24,7 +24,7 @@ efi_status_t check_platform_features(void) · 23 unmodified lines | |||
| 24 | return EFI_SUCCESS; | 24 | return EFI_SUCCESS; |
| 25 | 25 | ||
| 26 | tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_TGRAN_SHIFT) & 0xf; | 26 | tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_TGRAN_SHIFT) & 0xf; |
| 27 | if (tg != ID_AA64MMFR0_TGRAN_SUPPORTED) { | 27 | if (tg < ID_AA64MMFR0_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_TGRAN_SUPPORTED_MAX) { |
| 28 | if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) | 28 | if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) |
| 29 | efi_err("This 64 KB granular kernel is not supported by your CPU\n"); | 29 | efi_err("This 64 KB granular kernel is not supported by your CPU\n"); |
| 30 | else | 30 | else |
| @@ -96,6 +96,18 @@ static void install_memreserve_table(void) · 95 unmodified lines | |||
| 96 | efi_err("Failed to install memreserve config table!\n"); | 96 | efi_err("Failed to install memreserve config table!\n"); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static u32 get_supported_rt_services(void) | ||
| 100 | { | ||
| 101 | const efi_rt_properties_table_t *rt_prop_table; | ||
| 102 | u32 supported = EFI_RT_SUPPORTED_ALL; | ||
| 103 | |||
| 104 | rt_prop_table = get_efi_config_table(EFI_RT_PROPERTIES_TABLE_GUID); | ||
| 105 | if (rt_prop_table) | ||
| 106 | supported &= rt_prop_table->runtime_services_supported; | ||
| 107 | |||
| 108 | return supported; | ||
| 109 | } | ||
| 110 | |||
| 99 | /* | 111 | /* |
| 100 | * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint | 112 | * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint |
| 101 | * that is described in the PE/COFF header. Most of the code is the same | 113 | * that is described in the PE/COFF header. Most of the code is the same |
| @@ -250,6 +262,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, · 148 unmodified lines | |||
| 250 | (prop_tbl->memory_protection_attribute & | 262 | (prop_tbl->memory_protection_attribute & |
| 251 | EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); | 263 | EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); |
| 252 | 264 | ||
| 265 | /* force efi_novamap if SetVirtualAddressMap() is unsupported */ | ||
| 266 | efi_novamap |= !(get_supported_rt_services() & | ||
| 267 | EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP); | ||
| 268 | |||
| 253 | /* hibernation expects the runtime regions to stay in the same place */ | 269 | /* hibernation expects the runtime regions to stay in the same place */ |
| 254 | if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) { | 270 | if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) { |
| 255 | /* | 271 | /* |
| @@ -484,6 +484,10 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), · 483 unmodified lines | |||
| 484 | } | 484 | } |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | break; | ||
| 488 | case EFI_UNSUPPORTED: | ||
| 489 | err = -EOPNOTSUPP; | ||
| 490 | status = EFI_NOT_FOUND; | ||
| 487 | break; | 491 | break; |
| 488 | case EFI_NOT_FOUND: | 492 | case EFI_NOT_FOUND: |
| 489 | break; | 493 | break; |
| @@ -571,6 +571,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, · 570 unmodified lines | |||
| 571 | struct lock_class_key *lock_key, | 571 | struct lock_class_key *lock_key, |
| 572 | struct lock_class_key *request_key) | 572 | struct lock_class_key *request_key) |
| 573 | { | 573 | { |
| 574 | struct fwnode_handle *fwnode = gc->parent ? dev_fwnode(gc->parent) : NULL; | ||
| 574 | unsigned long flags; | 575 | unsigned long flags; |
| 575 | int ret = 0; | 576 | int ret = 0; |
| 576 | unsigned i; | 577 | unsigned i; |
| @@ -594,6 +595,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, · 17 unmodified lines | |||
| 594 | 595 | ||
| 595 | of_gpio_dev_init(gc, gdev); | 596 | of_gpio_dev_init(gc, gdev); |
| 596 | 597 | ||
| 598 | /* | ||
| 599 | * Assign fwnode depending on the result of the previous calls, | ||
| 600 | * if none of them succeed, assign it to the parent's one. | ||
| 601 | */ | ||
| 602 | gdev->dev.fwnode = dev_fwnode(&gdev->dev) ?: fwnode; | ||
| 603 | |||
| 597 | gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL); | 604 | gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL); |
| 598 | if (gdev->id < 0) { | 605 | if (gdev->id < 0) { |
| 599 | ret = gdev->id; | 606 | ret = gdev->id; |
| @@ -4256,7 +4263,8 @@ static int __init gpiolib_dev_init(void) · 3656 unmodified lines | |||
| 4256 | return ret; | 4263 | return ret; |
| 4257 | } | 4264 | } |
| 4258 | 4265 | ||
| 4259 | if (driver_register(&gpio_stub_drv) < 0) { | 4266 | ret = driver_register(&gpio_stub_drv); |
| 4267 | if (ret < 0) { | ||
| 4260 | pr_err("gpiolib: could not register GPIO stub driver\n"); | 4268 | pr_err("gpiolib: could not register GPIO stub driver\n"); |
| 4261 | bus_unregister(&gpio_bus_type); | 4269 | bus_unregister(&gpio_bus_type); |
| 4262 | return ret; | 4270 | return ret; |
| @@ -228,6 +228,7 @@ source "drivers/gpu/drm/arm/Kconfig" · 227 unmodified lines | |||
| 228 | config DRM_RADEON | 228 | config DRM_RADEON |
| 229 | tristate "ATI Radeon" | 229 | tristate "ATI Radeon" |
| 230 | depends on DRM && PCI && MMU | 230 | depends on DRM && PCI && MMU |
| 231 | depends on AGP || !AGP | ||
| 231 | select FW_LOADER | 232 | select FW_LOADER |
| 232 | select DRM_KMS_HELPER | 233 | select DRM_KMS_HELPER |
| 233 | select DRM_TTM | 234 | select DRM_TTM |
| @@ -180,6 +180,7 @@ extern uint amdgpu_smu_memory_pool_size; · 179 unmodified lines | |||
| 180 | extern uint amdgpu_dc_feature_mask; | 180 | extern uint amdgpu_dc_feature_mask; |
| 181 | extern uint amdgpu_dc_debug_mask; | 181 | extern uint amdgpu_dc_debug_mask; |
| 182 | extern uint amdgpu_dm_abm_level; | 182 | extern uint amdgpu_dm_abm_level; |
| 183 | extern int amdgpu_backlight; | ||
| 183 | extern struct amdgpu_mgpu_info mgpu_info; | 184 | extern struct amdgpu_mgpu_info mgpu_info; |
| 184 | extern int amdgpu_ras_enable; | 185 | extern int amdgpu_ras_enable; |
| 185 | extern uint amdgpu_ras_mask; | 186 | extern uint amdgpu_ras_mask; |
| @@ -903,7 +903,7 @@ void amdgpu_acpi_fini(struct amdgpu_device *adev) · 902 unmodified lines | |||
| 903 | */ | 903 | */ |
| 904 | bool amdgpu_acpi_is_s0ix_supported(struct amdgpu_device *adev) | 904 | bool amdgpu_acpi_is_s0ix_supported(struct amdgpu_device *adev) |
| 905 | { | 905 | { |
| 906 | #if defined(CONFIG_AMD_PMC) | 906 | #if defined(CONFIG_AMD_PMC) || defined(CONFIG_AMD_PMC_MODULE) |
| 907 | if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { | 907 | if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { |
| 908 | if (adev->flags & AMD_IS_APU) | 908 | if (adev->flags & AMD_IS_APU) |
| 909 | return true; | 909 | return true; |
| @@ -781,6 +781,10 @@ uint amdgpu_dm_abm_level; · 780 unmodified lines | |||
| 781 | MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); | 781 | MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); |
| 782 | module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); | 782 | module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); |
| 783 | 783 | ||
| 784 | int amdgpu_backlight = -1; | ||
| 785 | MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))"); | ||
| 786 | module_param_named(backlight, amdgpu_backlight, bint, 0444); | ||
| 787 | |||
| 784 | /** | 788 | /** |
| 785 | * DOC: tmz (int) | 789 | * DOC: tmz (int) |
| 786 | * Trusted Memory Zone (TMZ) is a method to protect data being written | 790 | * Trusted Memory Zone (TMZ) is a method to protect data being written |
| @@ -146,7 +146,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, · 145 unmodified lines | |||
| 146 | size = mode_cmd->pitches[0] * height; | 146 | size = mode_cmd->pitches[0] * height; |
| 147 | aligned_size = ALIGN(size, PAGE_SIZE); | 147 | aligned_size = ALIGN(size, PAGE_SIZE); |
| 148 | ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, flags, | 148 | ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, flags, |
| 149 | ttm_bo_type_kernel, NULL, &gobj); | 149 | ttm_bo_type_device, NULL, &gobj); |
| 150 | if (ret) { | 150 | if (ret) { |
| 151 | pr_err("failed to allocate framebuffer (%d)\n", aligned_size); | 151 | pr_err("failed to allocate framebuffer (%d)\n", aligned_size); |
| 152 | return -ENOMEM; | 152 | return -ENOMEM; |
| @@ -2267,6 +2267,11 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) · 2266 unmodified lines | |||
| 2267 | caps->ext_caps->bits.hdr_aux_backlight_control == 1) | 2267 | caps->ext_caps->bits.hdr_aux_backlight_control == 1) |
| 2268 | caps->aux_support = true; | 2268 | caps->aux_support = true; |
| 2269 | 2269 | ||
| 2270 | if (amdgpu_backlight == 0) | ||
| 2271 | caps->aux_support = false; | ||
| 2272 | else if (amdgpu_backlight == 1) | ||
| 2273 | caps->aux_support = true; | ||
| 2274 | |||
| 2270 | /* From the specification (CTA-861-G), for calculating the maximum | 2275 | /* From the specification (CTA-861-G), for calculating the maximum |
| 2271 | * luminance we need to use: | 2276 | * luminance we need to use: |
| 2272 | * Luminance = 50*2**(CV/32) | 2277 | * Luminance = 50*2**(CV/32) |
| @@ -3185,19 +3190,6 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm) · 912 unmodified lines | |||
| 3185 | #endif | 3190 | #endif |
| 3186 | } | 3191 | } |
| 3187 | 3192 | ||
| 3188 | static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness) | ||
| 3189 | { | ||
| 3190 | bool rc; | ||
| 3191 | |||
| 3192 | if (!link) | ||
| 3193 | return 1; | ||
| 3194 | |||
| 3195 | rc = dc_link_set_backlight_level_nits(link, true, brightness, | ||
| 3196 | AUX_BL_DEFAULT_TRANSITION_TIME_MS); | ||
| 3197 | |||
| 3198 | return rc ? 0 : 1; | ||
| 3199 | } | ||
| 3200 | |||
| 3201 | static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, | 3193 | static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, |
| 3202 | unsigned *min, unsigned *max) | 3194 | unsigned *min, unsigned *max) |
| 3203 | { | 3195 | { |
| @@ -3260,9 +3252,10 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) · 56 unmodified lines | |||
| 3260 | brightness = convert_brightness_from_user(&caps, bd->props.brightness); | 3252 | brightness = convert_brightness_from_user(&caps, bd->props.brightness); |
| 3261 | // Change brightness based on AUX property | 3253 | // Change brightness based on AUX property |
| 3262 | if (caps.aux_support) | 3254 | if (caps.aux_support) |
| 3263 | return set_backlight_via_aux(link, brightness); | 3255 | rc = dc_link_set_backlight_level_nits(link, true, brightness, |
| 3264 | 3256 | AUX_BL_DEFAULT_TRANSITION_TIME_MS); | |
| 3265 | rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); | 3257 | else |
| 3258 | rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); | ||
| 3266 | 3259 | ||
| 3267 | return rc ? 0 : 1; | 3260 | return rc ? 0 : 1; |
| 3268 | } | 3261 | } |
| @@ -3270,11 +3263,27 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) · 1 unmodified line | |||
| 3270 | static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd) | 3263 | static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd) |
| 3271 | { | 3264 | { |
| 3272 | struct amdgpu_display_manager *dm = bl_get_data(bd); | 3265 | struct amdgpu_display_manager *dm = bl_get_data(bd); |
| 3273 | int ret = dc_link_get_backlight_level(dm->backlight_link); | 3266 | struct amdgpu_dm_backlight_caps caps; |
| 3267 | |||
| 3268 | amdgpu_dm_update_backlight_caps(dm); | ||
| 3269 | caps = dm->backlight_caps; | ||
| 3270 | |||
| 3271 | if (caps.aux_support) { | ||
| 3272 | struct dc_link *link = (struct dc_link *)dm->backlight_link; | ||
| 3273 | u32 avg, peak; | ||
| 3274 | bool rc; | ||
| 3274 | 3275 | ||
| 3275 | if (ret == DC_ERROR_UNEXPECTED) | 3276 | rc = dc_link_get_backlight_level_nits(link, &avg, &peak); |
| 3276 | return bd->props.brightness; | 3277 | if (!rc) |
| 3277 | return convert_brightness_to_user(&dm->backlight_caps, ret); | 3278 | return bd->props.brightness; |
| 3279 | return convert_brightness_to_user(&caps, avg); | ||
| 3280 | } else { | ||
| 3281 | int ret = dc_link_get_backlight_level(dm->backlight_link); | ||
| 3282 | |||
| 3283 | if (ret == DC_ERROR_UNEXPECTED) | ||
| 3284 | return bd->props.brightness; | ||
| 3285 | return convert_brightness_to_user(&caps, ret); | ||
| 3286 | } | ||
| 3278 | } | 3287 | } |
| 3279 | 3288 | ||
| 3280 | static const struct backlight_ops amdgpu_dm_backlight_ops = { | 3289 | static const struct backlight_ops amdgpu_dm_backlight_ops = { |
| @@ -4716,6 +4725,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 1435 unmodified lines | |||
| 4716 | dc_plane_state->global_alpha_value = plane_info.global_alpha_value; | 4725 | dc_plane_state->global_alpha_value = plane_info.global_alpha_value; |
| 4717 | dc_plane_state->dcc = plane_info.dcc; | 4726 | dc_plane_state->dcc = plane_info.dcc; |
| 4718 | dc_plane_state->layer_index = plane_info.layer_index; // Always returns 0 | 4727 | dc_plane_state->layer_index = plane_info.layer_index; // Always returns 0 |
| 4728 | dc_plane_state->flip_int_enabled = true; | ||
| 4719 | 4729 | ||
| 4720 | /* | 4730 | /* |
| 4721 | * Always set input transfer function, since plane state is refreshed | 4731 | * Always set input transfer function, since plane state is refreshed |
| @@ -2602,7 +2602,6 @@ bool dc_link_set_backlight_level(const struct dc_link *link, · 2601 unmodified lines | |||
| 2602 | if (pipe_ctx->plane_state == NULL) | 2602 | if (pipe_ctx->plane_state == NULL) |
| 2603 | frame_ramp = 0; | 2603 | frame_ramp = 0; |
| 2604 | } else { | 2604 | } else { |
| 2605 | ASSERT(false); | ||
| 2606 | return false; | 2605 | return false; |
| 2607 | } | 2606 | } |
| 2608 | 2607 | ||
| @@ -887,6 +887,7 @@ struct dc_plane_state { · 886 unmodified lines | |||
| 887 | int layer_index; | 887 | int layer_index; |
| 888 | 888 | ||
| 889 | union surface_update_flags update_flags; | 889 | union surface_update_flags update_flags; |
| 890 | bool flip_int_enabled; | ||
| 890 | /* private to DC core */ | 891 | /* private to DC core */ |
| 891 | struct dc_plane_status status; | 892 | struct dc_plane_status status; |
| 892 | struct dc_context *ctx; | 893 | struct dc_context *ctx; |
| @@ -1257,6 +1257,16 @@ void hubp1_soft_reset(struct hubp *hubp, bool reset) · 1256 unmodified lines | |||
| 1257 | REG_UPDATE(DCHUBP_CNTL, HUBP_DISABLE, reset ? 1 : 0); | 1257 | REG_UPDATE(DCHUBP_CNTL, HUBP_DISABLE, reset ? 1 : 0); |
| 1258 | } | 1258 | } |
| 1259 | 1259 | ||
| 1260 | void hubp1_set_flip_int(struct hubp *hubp) | ||
| 1261 | { | ||
| 1262 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | ||
| 1263 | |||
| 1264 | REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT, | ||
| 1265 | SURFACE_FLIP_INT_MASK, 1); | ||
| 1266 | |||
| 1267 | return; | ||
| 1268 | } | ||
| 1269 | |||
| 1260 | void hubp1_init(struct hubp *hubp) | 1270 | void hubp1_init(struct hubp *hubp) |
| 1261 | { | 1271 | { |
| 1262 | //do nothing | 1272 | //do nothing |
| @@ -1290,6 +1300,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = { · 27 unmodified lines | |||
| 1290 | .dmdata_load = NULL, | 1300 | .dmdata_load = NULL, |
| 1291 | .hubp_soft_reset = hubp1_soft_reset, | 1301 | .hubp_soft_reset = hubp1_soft_reset, |
| 1292 | .hubp_in_blank = hubp1_in_blank, | 1302 | .hubp_in_blank = hubp1_in_blank, |
| 1303 | .hubp_set_flip_int = hubp1_set_flip_int, | ||
| 1293 | }; | 1304 | }; |
| 1294 | 1305 | ||
| 1295 | /*****************************************/ | 1306 | /*****************************************/ |
| @@ -74,6 +74,7 @@ · 73 unmodified lines | |||
| 74 | SRI(DCSURF_SURFACE_EARLIEST_INUSE_C, HUBPREQ, id),\ | 74 | SRI(DCSURF_SURFACE_EARLIEST_INUSE_C, HUBPREQ, id),\ |
| 75 | SRI(DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, HUBPREQ, id),\ | 75 | SRI(DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, HUBPREQ, id),\ |
| 76 | SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\ | 76 | SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\ |
| 77 | SRI(DCSURF_SURFACE_FLIP_INTERRUPT, HUBPREQ, id),\ | ||
| 77 | SRI(HUBPRET_CONTROL, HUBPRET, id),\ | 78 | SRI(HUBPRET_CONTROL, HUBPRET, id),\ |
| 78 | SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\ | 79 | SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\ |
| 79 | SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\ | 80 | SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\ |
| @@ -183,6 +184,7 @@ · 103 unmodified lines | |||
| 183 | uint32_t DCSURF_SURFACE_EARLIEST_INUSE_C; \ | 184 | uint32_t DCSURF_SURFACE_EARLIEST_INUSE_C; \ |
| 184 | uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C; \ | 185 | uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C; \ |
| 185 | uint32_t DCSURF_SURFACE_CONTROL; \ | 186 | uint32_t DCSURF_SURFACE_CONTROL; \ |
| 187 | uint32_t DCSURF_SURFACE_FLIP_INTERRUPT; \ | ||
| 186 | uint32_t HUBPRET_CONTROL; \ | 188 | uint32_t HUBPRET_CONTROL; \ |
| 187 | uint32_t DCN_EXPANSION_MODE; \ | 189 | uint32_t DCN_EXPANSION_MODE; \ |
| 188 | uint32_t DCHUBP_REQ_SIZE_CONFIG; \ | 190 | uint32_t DCHUBP_REQ_SIZE_CONFIG; \ |
| @@ -332,6 +334,7 @@ · 143 unmodified lines | |||
| 332 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_META_SURFACE_TMZ_C, mask_sh),\ | 334 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_META_SURFACE_TMZ_C, mask_sh),\ |
| 333 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\ | 335 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\ |
| 334 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ | 336 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ |
| 337 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK, mask_sh),\ | ||
| 335 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\ | 338 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\ |
| 336 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\ | 339 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\ |
| 337 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ | 340 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ |
| @@ -531,6 +534,7 @@ · 193 unmodified lines | |||
| 531 | type PRIMARY_SURFACE_DCC_IND_64B_BLK;\ | 534 | type PRIMARY_SURFACE_DCC_IND_64B_BLK;\ |
| 532 | type SECONDARY_SURFACE_DCC_EN;\ | 535 | type SECONDARY_SURFACE_DCC_EN;\ |
| 533 | type SECONDARY_SURFACE_DCC_IND_64B_BLK;\ | 536 | type SECONDARY_SURFACE_DCC_IND_64B_BLK;\ |
| 537 | type SURFACE_FLIP_INT_MASK;\ | ||
| 534 | type DET_BUF_PLANE1_BASE_ADDRESS;\ | 538 | type DET_BUF_PLANE1_BASE_ADDRESS;\ |
| 535 | type CROSSBAR_SRC_CB_B;\ | 539 | type CROSSBAR_SRC_CB_B;\ |
| 536 | type CROSSBAR_SRC_CR_R;\ | 540 | type CROSSBAR_SRC_CR_R;\ |
| @@ -777,4 +781,6 @@ void hubp1_read_state_common(struct hubp *hubp); · 240 unmodified lines | |||
| 777 | bool hubp1_in_blank(struct hubp *hubp); | 781 | bool hubp1_in_blank(struct hubp *hubp); |
| 778 | void hubp1_soft_reset(struct hubp *hubp, bool reset); | 782 | void hubp1_soft_reset(struct hubp *hubp, bool reset); |
| 779 | 783 | ||
| 784 | void hubp1_set_flip_int(struct hubp *hubp); | ||
| 785 | |||
| 780 | #endif | 786 | #endif |
| @@ -2196,6 +2196,13 @@ static void dcn10_enable_plane( · 2195 unmodified lines | |||
| 2196 | if (dc->debug.sanity_checks) { | 2196 | if (dc->debug.sanity_checks) { |
| 2197 | hws->funcs.verify_allow_pstate_change_high(dc); | 2197 | hws->funcs.verify_allow_pstate_change_high(dc); |
| 2198 | } | 2198 | } |
| 2199 | |||
| 2200 | if (!pipe_ctx->top_pipe | ||
| 2201 | && pipe_ctx->plane_state | ||
| 2202 | && pipe_ctx->plane_state->flip_int_enabled | ||
| 2203 | && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int) | ||
| 2204 | pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp); | ||
| 2205 | |||
| 2199 | } | 2206 | } |
| 2200 | 2207 | ||
| 2201 | void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx) | 2208 | void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx) |
| @@ -1597,6 +1597,7 @@ static struct hubp_funcs dcn20_hubp_funcs = { · 1596 unmodified lines | |||
| 1597 | .validate_dml_output = hubp2_validate_dml_output, | 1597 | .validate_dml_output = hubp2_validate_dml_output, |
| 1598 | .hubp_in_blank = hubp1_in_blank, | 1598 | .hubp_in_blank = hubp1_in_blank, |
| 1599 | .hubp_soft_reset = hubp1_soft_reset, | 1599 | .hubp_soft_reset = hubp1_soft_reset, |
| 1600 | .hubp_set_flip_int = hubp1_set_flip_int, | ||
| 1600 | }; | 1601 | }; |
| 1601 | 1602 | ||
| 1602 | 1603 | ||
| @@ -1146,6 +1146,12 @@ void dcn20_enable_plane( · 1145 unmodified lines | |||
| 1146 | pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt); | 1146 | pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt); |
| 1147 | } | 1147 | } |
| 1148 | 1148 | ||
| 1149 | if (!pipe_ctx->top_pipe | ||
| 1150 | && pipe_ctx->plane_state | ||
| 1151 | && pipe_ctx->plane_state->flip_int_enabled | ||
| 1152 | && pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int) | ||
| 1153 | pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp); | ||
| 1154 | |||
| 1149 | // if (dc->debug.sanity_checks) { | 1155 | // if (dc->debug.sanity_checks) { |
| 1150 | // dcn10_verify_allow_pstate_change_high(dc); | 1156 | // dcn10_verify_allow_pstate_change_high(dc); |
| 1151 | // } | 1157 | // } |
| @@ -1501,38 +1507,8 @@ static void dcn20_update_dchubp_dpp( · 349 unmodified lines | |||
| 1501 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed | 1507 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed |
| 1502 | || pipe_ctx->stream->update_flags.bits.gamut_remap | 1508 | || pipe_ctx->stream->update_flags.bits.gamut_remap |
| 1503 | || pipe_ctx->stream->update_flags.bits.out_csc) { | 1509 | || pipe_ctx->stream->update_flags.bits.out_csc) { |
| 1504 | struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; | 1510 | /* dpp/cm gamut remap*/ |
| 1505 | 1511 | dc->hwss.program_gamut_remap(pipe_ctx); | |
| 1506 | if (mpc->funcs->set_gamut_remap) { | ||
| 1507 | int i; | ||
| 1508 | int mpcc_id = hubp->inst; | ||
| 1509 | struct mpc_grph_gamut_adjustment adjust; | ||
| 1510 | bool enable_remap_dpp = false; | ||
| 1511 | |||
| 1512 | memset(&adjust, 0, sizeof(adjust)); | ||
| 1513 | adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; | ||
| 1514 | |||
| 1515 | /* save the enablement of gamut remap for dpp */ | ||
| 1516 | enable_remap_dpp = pipe_ctx->stream->gamut_remap_matrix.enable_remap; | ||
| 1517 | |||
| 1518 | /* force bypass gamut remap for dpp/cm */ | ||
| 1519 | pipe_ctx->stream->gamut_remap_matrix.enable_remap = false; | ||
| 1520 | dc->hwss.program_gamut_remap(pipe_ctx); | ||
| 1521 | |||
| 1522 | /* restore gamut remap flag and use this remap into mpc */ | ||
| 1523 | pipe_ctx->stream->gamut_remap_matrix.enable_remap = enable_remap_dpp; | ||
| 1524 | |||
| 1525 | /* build remap matrix for top plane if enabled */ | ||
| 1526 | if (enable_remap_dpp && pipe_ctx->top_pipe == NULL) { | ||
| 1527 | adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; | ||
| 1528 | for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) | ||
| 1529 | adjust.temperature_matrix[i] = | ||
| 1530 | pipe_ctx->stream->gamut_remap_matrix.matrix[i]; | ||
| 1531 | } | ||
| 1532 | mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust); | ||
| 1533 | } else | ||
| 1534 | /* dpp/cm gamut remap*/ | ||
| 1535 | dc->hwss.program_gamut_remap(pipe_ctx); | ||
| 1536 | 1512 | ||
| 1537 | /*call the dcn2 method which uses mpc csc*/ | 1513 | /*call the dcn2 method which uses mpc csc*/ |
| 1538 | dc->hwss.program_output_csc(dc, | 1514 | dc->hwss.program_output_csc(dc, |
| @@ -838,6 +838,7 @@ static struct hubp_funcs dcn21_hubp_funcs = { · 837 unmodified lines | |||
| 838 | .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl, | 838 | .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl, |
| 839 | .hubp_init = hubp21_init, | 839 | .hubp_init = hubp21_init, |
| 840 | .validate_dml_output = hubp21_validate_dml_output, | 840 | .validate_dml_output = hubp21_validate_dml_output, |
| 841 | .hubp_set_flip_int = hubp1_set_flip_int, | ||
| 841 | }; | 842 | }; |
| 842 | 843 | ||
| 843 | bool hubp21_construct( | 844 | bool hubp21_construct( |
| @@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 295 unmodified lines | |||
| 296 | .num_banks = 8, | 296 | .num_banks = 8, |
| 297 | .num_chans = 4, | 297 | .num_chans = 4, |
| 298 | .vmm_page_size_bytes = 4096, | 298 | .vmm_page_size_bytes = 4096, |
| 299 | .dram_clock_change_latency_us = 11.72, | 299 | .dram_clock_change_latency_us = 23.84, |
| 300 | .return_bus_width_bytes = 64, | 300 | .return_bus_width_bytes = 64, |
| 301 | .dispclk_dppclk_vco_speed_mhz = 3600, | 301 | .dispclk_dppclk_vco_speed_mhz = 3600, |
| 302 | .xfc_bus_transport_time_us = 4, | 302 | .xfc_bus_transport_time_us = 4, |
| @@ -1062,8 +1062,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s · 759 unmodified lines | |||
| 1062 | { | 1062 | { |
| 1063 | int i; | 1063 | int i; |
| 1064 | 1064 | ||
| 1065 | DC_FP_START(); | ||
| 1066 | |||
| 1067 | if (dc->bb_overrides.sr_exit_time_ns) { | 1065 | if (dc->bb_overrides.sr_exit_time_ns) { |
| 1068 | for (i = 0; i < WM_SET_COUNT; i++) { | 1066 | for (i = 0; i < WM_SET_COUNT; i++) { |
| 1069 | dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = | 1067 | dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = |
| @@ -1088,8 +1086,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s · 18 unmodified lines | |||
| 1088 | dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; | 1086 | dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; |
| 1089 | } | 1087 | } |
| 1090 | } | 1088 | } |
| 1091 | |||
| 1092 | DC_FP_END(); | ||
| 1093 | } | 1089 | } |
| 1094 | 1090 | ||
| 1095 | void dcn21_calculate_wm( | 1091 | void dcn21_calculate_wm( |
| @@ -1339,7 +1335,7 @@ static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc, · 243 unmodified lines | |||
| 1339 | int vlevel = 0; | 1335 | int vlevel = 0; |
| 1340 | int pipe_split_from[MAX_PIPES]; | 1336 | int pipe_split_from[MAX_PIPES]; |
| 1341 | int pipe_cnt = 0; | 1337 | int pipe_cnt = 0; |
| 1342 | display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); | 1338 | display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); |
| 1343 | DC_LOGGER_INIT(dc->ctx->logger); | 1339 | DC_LOGGER_INIT(dc->ctx->logger); |
| 1344 | 1340 | ||
| 1345 | BW_VAL_TRACE_COUNT(); | 1341 | BW_VAL_TRACE_COUNT(); |
| @@ -1599,6 +1595,11 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 253 unmodified lines | |||
| 1599 | dcn2_1_soc.num_chans = bw_params->num_channels; | 1595 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1600 | 1596 | ||
| 1601 | ASSERT(clk_table->num_entries); | 1597 | ASSERT(clk_table->num_entries); |
| 1598 | /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */ | ||
| 1599 | for (i = 0; i < dcn2_1_soc.num_states + 1; i++) { | ||
| 1600 | clock_limits[i] = dcn2_1_soc.clock_limits[i]; | ||
| 1601 | } | ||
| 1602 | |||
| 1602 | for (i = 0; i < clk_table->num_entries; i++) { | 1603 | for (i = 0; i < clk_table->num_entries; i++) { |
| 1603 | /* loop backwards*/ | 1604 | /* loop backwards*/ |
| 1604 | for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { | 1605 | for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { |
| @@ -113,6 +113,7 @@ bool cm3_helper_translate_curve_to_hw_format( · 112 unmodified lines | |||
| 113 | struct pwl_result_data *rgb_resulted; | 113 | struct pwl_result_data *rgb_resulted; |
| 114 | struct pwl_result_data *rgb; | 114 | struct pwl_result_data *rgb; |
| 115 | struct pwl_result_data *rgb_plus_1; | 115 | struct pwl_result_data *rgb_plus_1; |
| 116 | struct pwl_result_data *rgb_minus_1; | ||
| 116 | struct fixed31_32 end_value; | 117 | struct fixed31_32 end_value; |
| 117 | 118 | ||
| 118 | int32_t region_start, region_end; | 119 | int32_t region_start, region_end; |
| @@ -140,7 +141,7 @@ bool cm3_helper_translate_curve_to_hw_format( · 21 unmodified lines | |||
| 140 | region_start = -MAX_LOW_POINT; | 141 | region_start = -MAX_LOW_POINT; |
| 141 | region_end = NUMBER_REGIONS - MAX_LOW_POINT; | 142 | region_end = NUMBER_REGIONS - MAX_LOW_POINT; |
| 142 | } else { | 143 | } else { |
| 143 | /* 10 segments | 144 | /* 11 segments |
| 144 | * segment is from 2^-10 to 2^0 | 145 | * segment is from 2^-10 to 2^0 |
| 145 | * There are less than 256 points, for optimization | 146 | * There are less than 256 points, for optimization |
| 146 | */ | 147 | */ |
| @@ -154,9 +155,10 @@ bool cm3_helper_translate_curve_to_hw_format( · 7 unmodified lines | |||
| 154 | seg_distr[7] = 4; | 155 | seg_distr[7] = 4; |
| 155 | seg_distr[8] = 4; | 156 | seg_distr[8] = 4; |
| 156 | seg_distr[9] = 4; | 157 | seg_distr[9] = 4; |
| 158 | seg_distr[10] = 1; | ||
| 157 | 159 | ||
| 158 | region_start = -10; | 160 | region_start = -10; |
| 159 | region_end = 0; | 161 | region_end = 1; |
| 160 | } | 162 | } |
| 161 | 163 | ||
| 162 | for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) | 164 | for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) |
| @@ -189,6 +191,10 @@ bool cm3_helper_translate_curve_to_hw_format( · 26 unmodified lines | |||
| 189 | rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; | 191 | rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; |
| 190 | rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; | 192 | rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; |
| 191 | 193 | ||
| 194 | rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red; | ||
| 195 | rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green; | ||
| 196 | rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue; | ||
| 197 | |||
| 192 | // All 3 color channels have same x | 198 | // All 3 color channels have same x |
| 193 | corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), | 199 | corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), |
| 194 | dc_fixpt_from_int(region_start)); | 200 | dc_fixpt_from_int(region_start)); |
| @@ -259,15 +265,18 @@ bool cm3_helper_translate_curve_to_hw_format( · 64 unmodified lines | |||
| 259 | 265 | ||
| 260 | rgb = rgb_resulted; | 266 | rgb = rgb_resulted; |
| 261 | rgb_plus_1 = rgb_resulted + 1; | 267 | rgb_plus_1 = rgb_resulted + 1; |
| 268 | rgb_minus_1 = rgb; | ||
| 262 | 269 | ||
| 263 | i = 1; | 270 | i = 1; |
| 264 | while (i != hw_points + 1) { | 271 | while (i != hw_points + 1) { |
| 265 | if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) | 272 | if (i >= hw_points - 1) { |
| 266 | rgb_plus_1->red = rgb->red; | 273 | if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) |
| 267 | if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) | 274 | rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red); |
| 268 | rgb_plus_1->green = rgb->green; | 275 | if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) |
| 269 | if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) | 276 | rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green); |
| 270 | rgb_plus_1->blue = rgb->blue; | 277 | if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) |
| 278 | rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue); | ||
| 279 | } | ||
| 271 | 280 | ||
| 272 | rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); | 281 | rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); |
| 273 | rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); | 282 | rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); |
| @@ -283,6 +292,7 @@ bool cm3_helper_translate_curve_to_hw_format( · 9 unmodified lines | |||
| 283 | } | 292 | } |
| 284 | 293 | ||
| 285 | ++rgb_plus_1; | 294 | ++rgb_plus_1; |
| 295 | rgb_minus_1 = rgb; | ||
| 286 | ++rgb; | 296 | ++rgb; |
| 287 | ++i; | 297 | ++i; |
| 288 | } | 298 | } |
| @@ -511,6 +511,7 @@ static struct hubp_funcs dcn30_hubp_funcs = { · 510 unmodified lines | |||
| 511 | .hubp_init = hubp3_init, | 511 | .hubp_init = hubp3_init, |
| 512 | .hubp_in_blank = hubp1_in_blank, | 512 | .hubp_in_blank = hubp1_in_blank, |
| 513 | .hubp_soft_reset = hubp1_soft_reset, | 513 | .hubp_soft_reset = hubp1_soft_reset, |
| 514 | .hubp_set_flip_int = hubp1_set_flip_int, | ||
| 514 | }; | 515 | }; |
| 515 | 516 | ||
| 516 | bool hubp3_construct( | 517 | bool hubp3_construct( |
| @@ -2508,6 +2508,19 @@ static const struct resource_funcs dcn30_res_pool_funcs = { · 2507 unmodified lines | |||
| 2508 | .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, | 2508 | .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, |
| 2509 | }; | 2509 | }; |
| 2510 | 2510 | ||
| 2511 | #define CTX ctx | ||
| 2512 | |||
| 2513 | #define REG(reg_name) \ | ||
| 2514 | (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) | ||
| 2515 | |||
| 2516 | static uint32_t read_pipe_fuses(struct dc_context *ctx) | ||
| 2517 | { | ||
| 2518 | uint32_t value = REG_READ(CC_DC_PIPE_DIS); | ||
| 2519 | /* Support for max 6 pipes */ | ||
| 2520 | value = value & 0x3f; | ||
| 2521 | return value; | ||
| 2522 | } | ||
| 2523 | |||
| 2511 | static bool dcn30_resource_construct( | 2524 | static bool dcn30_resource_construct( |
| 2512 | uint8_t num_virtual_links, | 2525 | uint8_t num_virtual_links, |
| 2513 | struct dc *dc, | 2526 | struct dc *dc, |
| @@ -2517,6 +2530,15 @@ static bool dcn30_resource_construct( · 3 unmodified lines | |||
| 2517 | struct dc_context *ctx = dc->ctx; | 2530 | struct dc_context *ctx = dc->ctx; |
| 2518 | struct irq_service_init_data init_data; | 2531 | struct irq_service_init_data init_data; |
| 2519 | struct ddc_service_init_data ddc_init_data; | 2532 | struct ddc_service_init_data ddc_init_data; |
| 2533 | uint32_t pipe_fuses = read_pipe_fuses(ctx); | ||
| 2534 | uint32_t num_pipes = 0; | ||
| 2535 | |||
| 2536 | if (!(pipe_fuses == 0 || pipe_fuses == 0x3e)) { | ||
| 2537 | BREAK_TO_DEBUGGER(); | ||
| 2538 | dm_error("DC: Unexpected fuse recipe for navi2x !\n"); | ||
| 2539 | /* fault to single pipe */ | ||
| 2540 | pipe_fuses = 0x3e; | ||
| 2541 | } | ||
| 2520 | 2542 | ||
| 2521 | DC_FP_START(); | 2543 | DC_FP_START(); |
| 2522 | 2544 | ||
| @@ -2650,6 +2672,15 @@ static bool dcn30_resource_construct( · 127 unmodified lines | |||
| 2650 | /* PP Lib and SMU interfaces */ | 2672 | /* PP Lib and SMU interfaces */ |
| 2651 | init_soc_bounding_box(dc, pool); | 2673 | init_soc_bounding_box(dc, pool); |
| 2652 | 2674 | ||
| 2675 | num_pipes = dcn3_0_ip.max_num_dpp; | ||
| 2676 | |||
| 2677 | for (i = 0; i < dcn3_0_ip.max_num_dpp; i++) | ||
| 2678 | if (pipe_fuses & 1 << i) | ||
| 2679 | num_pipes--; | ||
| 2680 | |||
| 2681 | dcn3_0_ip.max_num_dpp = num_pipes; | ||
| 2682 | dcn3_0_ip.max_num_otg = num_pipes; | ||
| 2683 | |||
| 2653 | dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30); | 2684 | dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30); |
| 2654 | 2685 | ||
| 2655 | /* IRQ */ | 2686 | /* IRQ */ |
| @@ -1619,12 +1619,106 @@ static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b · 1618 unmodified lines | |||
| 1619 | dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); | 1619 | dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); |
| 1620 | } | 1620 | } |
| 1621 | 1621 | ||
| 1622 | static void calculate_wm_set_for_vlevel( | ||
| 1623 | int vlevel, | ||
| 1624 | struct wm_range_table_entry *table_entry, | ||
| 1625 | struct dcn_watermarks *wm_set, | ||
| 1626 | struct display_mode_lib *dml, | ||
| 1627 | display_e2e_pipe_params_st *pipes, | ||
| 1628 | int pipe_cnt) | ||
| 1629 | { | ||
| 1630 | double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; | ||
| 1631 | |||
| 1632 | ASSERT(vlevel < dml->soc.num_states); | ||
| 1633 | /* only pipe 0 is read for voltage and dcf/soc clocks */ | ||
| 1634 | pipes[0].clks_cfg.voltage = vlevel; | ||
| 1635 | pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; | ||
| 1636 | pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; | ||
| 1637 | |||
| 1638 | dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; | ||
| 1639 | dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; | ||
| 1640 | dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; | ||
| 1641 | |||
| 1642 | wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; | ||
| 1643 | wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; | ||
| 1644 | wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; | ||
| 1645 | wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; | ||
| 1646 | wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; | ||
| 1647 | wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; | ||
| 1648 | wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; | ||
| 1649 | wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; | ||
| 1650 | dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; | ||
| 1651 | |||
| 1652 | } | ||
| 1653 | |||
| 1654 | static void dcn301_calculate_wm_and_dlg( | ||
| 1655 | struct dc *dc, struct dc_state *context, | ||
| 1656 | display_e2e_pipe_params_st *pipes, | ||
| 1657 | int pipe_cnt, | ||
| 1658 | int vlevel_req) | ||
| 1659 | { | ||
| 1660 | int i, pipe_idx; | ||
| 1661 | int vlevel, vlevel_max; | ||
| 1662 | struct wm_range_table_entry *table_entry; | ||
| 1663 | struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; | ||
| 1664 | |||
| 1665 | ASSERT(bw_params); | ||
| 1666 | |||
| 1667 | vlevel_max = bw_params->clk_table.num_entries - 1; | ||
| 1668 | |||
| 1669 | /* WM Set D */ | ||
| 1670 | table_entry = &bw_params->wm_table.entries[WM_D]; | ||
| 1671 | if (table_entry->wm_type == WM_TYPE_RETRAINING) | ||
| 1672 | vlevel = 0; | ||
| 1673 | else | ||
| 1674 | vlevel = vlevel_max; | ||
| 1675 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, | ||
| 1676 | &context->bw_ctx.dml, pipes, pipe_cnt); | ||
| 1677 | /* WM Set C */ | ||
| 1678 | table_entry = &bw_params->wm_table.entries[WM_C]; | ||
| 1679 | vlevel = min(max(vlevel_req, 2), vlevel_max); | ||
| 1680 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, | ||
| 1681 | &context->bw_ctx.dml, pipes, pipe_cnt); | ||
| 1682 | /* WM Set B */ | ||
| 1683 | table_entry = &bw_params->wm_table.entries[WM_B]; | ||
| 1684 | vlevel = min(max(vlevel_req, 1), vlevel_max); | ||
| 1685 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, | ||
| 1686 | &context->bw_ctx.dml, pipes, pipe_cnt); | ||
| 1687 | |||
| 1688 | /* WM Set A */ | ||
| 1689 | table_entry = &bw_params->wm_table.entries[WM_A]; | ||
| 1690 | vlevel = min(vlevel_req, vlevel_max); | ||
| 1691 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, | ||
| 1692 | &context->bw_ctx.dml, pipes, pipe_cnt); | ||
| 1693 | |||
| 1694 | for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { | ||
| 1695 | if (!context->res_ctx.pipe_ctx[i].stream) | ||
| 1696 | continue; | ||
| 1697 | |||
| 1698 | pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); | ||
| 1699 | pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); | ||
| 1700 | |||
| 1701 | if (dc->config.forced_clocks) { | ||
| 1702 | pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; | ||
| 1703 | pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; | ||
| 1704 | } | ||
| 1705 | if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) | ||
| 1706 | pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; | ||
| 1707 | if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) | ||
| 1708 | pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; | ||
| 1709 | |||
| 1710 | pipe_idx++; | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); | ||
| 1714 | } | ||
| 1715 | |||
| 1622 | static struct resource_funcs dcn301_res_pool_funcs = { | 1716 | static struct resource_funcs dcn301_res_pool_funcs = { |
| 1623 | .destroy = dcn301_destroy_resource_pool, | 1717 | .destroy = dcn301_destroy_resource_pool, |
| 1624 | .link_enc_create = dcn301_link_encoder_create, | 1718 | .link_enc_create = dcn301_link_encoder_create, |
| 1625 | .panel_cntl_create = dcn301_panel_cntl_create, | 1719 | .panel_cntl_create = dcn301_panel_cntl_create, |
| 1626 | .validate_bandwidth = dcn30_validate_bandwidth, | 1720 | .validate_bandwidth = dcn30_validate_bandwidth, |
| 1627 | .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg, | 1721 | .calculate_wm_and_dlg = dcn301_calculate_wm_and_dlg, |
| 1628 | .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, | 1722 | .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, |
| 1629 | .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, | 1723 | .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, |
| 1630 | .add_stream_to_ctx = dcn30_add_stream_to_ctx, | 1724 | .add_stream_to_ctx = dcn30_add_stream_to_ctx, |
| @@ -191,6 +191,8 @@ struct hubp_funcs { · 190 unmodified lines | |||
| 191 | bool (*hubp_in_blank)(struct hubp *hubp); | 191 | bool (*hubp_in_blank)(struct hubp *hubp); |
| 192 | void (*hubp_soft_reset)(struct hubp *hubp, bool reset); | 192 | void (*hubp_soft_reset)(struct hubp *hubp, bool reset); |
| 193 | 193 | ||
| 194 | void (*hubp_set_flip_int)(struct hubp *hubp); | ||
| 195 | |||
| 194 | }; | 196 | }; |
| 195 | 197 | ||
| 196 | #endif | 198 | #endif |
| @@ -5216,10 +5216,10 @@ static int smu7_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, · 5215 unmodified lines | |||
| 5216 | for (j = 0; j < dep_sclk_table->count; j++) { | 5216 | for (j = 0; j < dep_sclk_table->count; j++) { |
| 5217 | valid_entry = false; | 5217 | valid_entry = false; |
| 5218 | for (k = 0; k < watermarks->num_wm_sets; k++) { | 5218 | for (k = 0; k < watermarks->num_wm_sets; k++) { |
| 5219 | if (dep_sclk_table->entries[i].clk / 10 >= watermarks->wm_clk_ranges[k].wm_min_eng_clk_in_khz && | 5219 | if (dep_sclk_table->entries[i].clk >= watermarks->wm_clk_ranges[k].wm_min_eng_clk_in_khz / 10 && |
| 5220 | dep_sclk_table->entries[i].clk / 10 < watermarks->wm_clk_ranges[k].wm_max_eng_clk_in_khz && | 5220 | dep_sclk_table->entries[i].clk < watermarks->wm_clk_ranges[k].wm_max_eng_clk_in_khz / 10 && |
| 5221 | dep_mclk_table->entries[i].clk / 10 >= watermarks->wm_clk_ranges[k].wm_min_mem_clk_in_khz && | 5221 | dep_mclk_table->entries[i].clk >= watermarks->wm_clk_ranges[k].wm_min_mem_clk_in_khz / 10 && |
| 5222 | dep_mclk_table->entries[i].clk / 10 < watermarks->wm_clk_ranges[k].wm_max_mem_clk_in_khz) { | 5222 | dep_mclk_table->entries[i].clk < watermarks->wm_clk_ranges[k].wm_max_mem_clk_in_khz / 10) { |
| 5223 | valid_entry = true; | 5223 | valid_entry = true; |
| 5224 | table->DisplayWatermark[i][j] = watermarks->wm_clk_ranges[k].wm_set_id; | 5224 | table->DisplayWatermark[i][j] = watermarks->wm_clk_ranges[k].wm_set_id; |
| 5225 | break; | 5225 | break; |
| @@ -1505,6 +1505,48 @@ static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr, · 1504 unmodified lines | |||
| 1505 | return 0; | 1505 | return 0; |
| 1506 | } | 1506 | } |
| 1507 | 1507 | ||
| 1508 | static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) | ||
| 1509 | { | ||
| 1510 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | ||
| 1511 | struct vega10_hwmgr *data = | ||
| 1512 | (struct vega10_hwmgr *)(hwmgr->backend); | ||
| 1513 | uint32_t pcie_gen = 0, pcie_width = 0; | ||
| 1514 | PPTable_t *pp_table = &(data->smc_state_table.pp_table); | ||
| 1515 | int i; | ||
| 1516 | |||
| 1517 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) | ||
| 1518 | pcie_gen = 3; | ||
| 1519 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | ||
| 1520 | pcie_gen = 2; | ||
| 1521 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) | ||
| 1522 | pcie_gen = 1; | ||
| 1523 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) | ||
| 1524 | pcie_gen = 0; | ||
| 1525 | |||
| 1526 | if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) | ||
| 1527 | pcie_width = 6; | ||
| 1528 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) | ||
| 1529 | pcie_width = 5; | ||
| 1530 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) | ||
| 1531 | pcie_width = 4; | ||
| 1532 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) | ||
| 1533 | pcie_width = 3; | ||
| 1534 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) | ||
| 1535 | pcie_width = 2; | ||
| 1536 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) | ||
| 1537 | pcie_width = 1; | ||
| 1538 | |||
| 1539 | for (i = 0; i < NUM_LINK_LEVELS; i++) { | ||
| 1540 | if (pp_table->PcieGenSpeed[i] > pcie_gen) | ||
| 1541 | pp_table->PcieGenSpeed[i] = pcie_gen; | ||
| 1542 | |||
| 1543 | if (pp_table->PcieLaneCount[i] > pcie_width) | ||
| 1544 | pp_table->PcieLaneCount[i] = pcie_width; | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | return 0; | ||
| 1548 | } | ||
| 1549 | |||
| 1508 | static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr) | 1550 | static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr) |
| 1509 | { | 1551 | { |
| 1510 | int result = -1; | 1552 | int result = -1; |
| @@ -2556,6 +2598,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) · 1045 unmodified lines | |||
| 2556 | "Failed to initialize Link Level!", | 2598 | "Failed to initialize Link Level!", |
| 2557 | return result); | 2599 | return result); |
| 2558 | 2600 | ||
| 2601 | result = vega10_override_pcie_parameters(hwmgr); | ||
| 2602 | PP_ASSERT_WITH_CODE(!result, | ||
| 2603 | "Failed to override pcie parameters!", | ||
| 2604 | return result); | ||
| 2605 | |||
| 2559 | result = vega10_populate_all_graphic_levels(hwmgr); | 2606 | result = vega10_populate_all_graphic_levels(hwmgr); |
| 2560 | PP_ASSERT_WITH_CODE(!result, | 2607 | PP_ASSERT_WITH_CODE(!result, |
| 2561 | "Failed to initialize Graphics Level!", | 2608 | "Failed to initialize Graphics Level!", |
| @@ -2922,6 +2969,7 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap) · 360 unmodified lines | |||
| 2922 | return 0; | 2969 | return 0; |
| 2923 | } | 2970 | } |
| 2924 | 2971 | ||
| 2972 | |||
| 2925 | static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable) | 2973 | static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable) |
| 2926 | { | 2974 | { |
| 2927 | struct vega10_hwmgr *data = hwmgr->backend; | 2975 | struct vega10_hwmgr *data = hwmgr->backend; |
| @@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) · 480 unmodified lines | |||
| 481 | dpm_state->hard_max_level = 0xffff; | 481 | dpm_state->hard_max_level = 0xffff; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) | ||
| 485 | { | ||
| 486 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | ||
| 487 | struct vega12_hwmgr *data = | ||
| 488 | (struct vega12_hwmgr *)(hwmgr->backend); | ||
| 489 | uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; | ||
| 490 | PPTable_t *pp_table = &(data->smc_state_table.pp_table); | ||
| 491 | int i; | ||
| 492 | int ret; | ||
| 493 | |||
| 494 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) | ||
| 495 | pcie_gen = 3; | ||
| 496 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | ||
| 497 | pcie_gen = 2; | ||
| 498 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) | ||
| 499 | pcie_gen = 1; | ||
| 500 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) | ||
| 501 | pcie_gen = 0; | ||
| 502 | |||
| 503 | if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) | ||
| 504 | pcie_width = 6; | ||
| 505 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) | ||
| 506 | pcie_width = 5; | ||
| 507 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) | ||
| 508 | pcie_width = 4; | ||
| 509 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) | ||
| 510 | pcie_width = 3; | ||
| 511 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) | ||
| 512 | pcie_width = 2; | ||
| 513 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) | ||
| 514 | pcie_width = 1; | ||
| 515 | |||
| 516 | /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 | ||
| 517 | * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 | ||
| 518 | * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 | ||
| 519 | */ | ||
| 520 | for (i = 0; i < NUM_LINK_LEVELS; i++) { | ||
| 521 | pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : | ||
| 522 | pp_table->PcieGenSpeed[i]; | ||
| 523 | pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : | ||
| 524 | pp_table->PcieLaneCount[i]; | ||
| 525 | |||
| 526 | if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != | ||
| 527 | pp_table->PcieLaneCount[i]) { | ||
| 528 | smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; | ||
| 529 | ret = smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 530 | PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, | ||
| 531 | NULL); | ||
| 532 | PP_ASSERT_WITH_CODE(!ret, | ||
| 533 | "[OverridePcieParameters] Attempt to override pcie params failed!", | ||
| 534 | return ret); | ||
| 535 | } | ||
| 536 | |||
| 537 | /* update the pptable */ | ||
| 538 | pp_table->PcieGenSpeed[i] = pcie_gen_arg; | ||
| 539 | pp_table->PcieLaneCount[i] = pcie_width_arg; | ||
| 540 | } | ||
| 541 | |||
| 542 | return 0; | ||
| 543 | } | ||
| 544 | |||
| 484 | static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, | 545 | static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, |
| 485 | PPCLK_e clk_id, uint32_t *num_of_levels) | 546 | PPCLK_e clk_id, uint32_t *num_of_levels) |
| 486 | { | 547 | { |
| @@ -968,6 +1029,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) · 481 unmodified lines | |||
| 968 | "Failed to enable all smu features!", | 1029 | "Failed to enable all smu features!", |
| 969 | return result); | 1030 | return result); |
| 970 | 1031 | ||
| 1032 | result = vega12_override_pcie_parameters(hwmgr); | ||
| 1033 | PP_ASSERT_WITH_CODE(!result, | ||
| 1034 | "[EnableDPMTasks] Failed to override pcie parameters!", | ||
| 1035 | return result); | ||
| 1036 | |||
| 971 | tmp_result = vega12_power_control_set_level(hwmgr); | 1037 | tmp_result = vega12_power_control_set_level(hwmgr); |
| 972 | PP_ASSERT_WITH_CODE(!tmp_result, | 1038 | PP_ASSERT_WITH_CODE(!tmp_result, |
| 973 | "Failed to power control set level!", | 1039 | "Failed to power control set level!", |
| @@ -831,7 +831,9 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) · 830 unmodified lines | |||
| 831 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | 831 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); |
| 832 | struct vega20_hwmgr *data = | 832 | struct vega20_hwmgr *data = |
| 833 | (struct vega20_hwmgr *)(hwmgr->backend); | 833 | (struct vega20_hwmgr *)(hwmgr->backend); |
| 834 | uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; | 834 | uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; |
| 835 | PPTable_t *pp_table = &(data->smc_state_table.pp_table); | ||
| 836 | int i; | ||
| 835 | int ret; | 837 | int ret; |
| 836 | 838 | ||
| 837 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) | 839 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) |
| @@ -860,17 +862,27 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) · 22 unmodified lines | |||
| 860 | * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 | 862 | * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 |
| 861 | * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 | 863 | * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 |
| 862 | */ | 864 | */ |
| 863 | smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; | 865 | for (i = 0; i < NUM_LINK_LEVELS; i++) { |
| 864 | ret = smum_send_msg_to_smc_with_parameter(hwmgr, | 866 | pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : |
| 865 | PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, | 867 | pp_table->PcieGenSpeed[i]; |
| 866 | NULL); | 868 | pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : |
| 867 | PP_ASSERT_WITH_CODE(!ret, | 869 | pp_table->PcieLaneCount[i]; |
| 868 | "[OverridePcieParameters] Attempt to override pcie params failed!", | 870 | |
| 869 | return ret); | 871 | if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != |
| 872 | pp_table->PcieLaneCount[i]) { | ||
| 873 | smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; | ||
| 874 | ret = smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 875 | PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, | ||
| 876 | NULL); | ||
| 877 | PP_ASSERT_WITH_CODE(!ret, | ||
| 878 | "[OverridePcieParameters] Attempt to override pcie params failed!", | ||
| 879 | return ret); | ||
| 880 | } | ||
| 870 | 881 | ||
| 871 | data->pcie_parameters_override = true; | 882 | /* update the pptable */ |
| 872 | data->pcie_gen_level1 = pcie_gen; | 883 | pp_table->PcieGenSpeed[i] = pcie_gen_arg; |
| 873 | data->pcie_width_level1 = pcie_width; | 884 | pp_table->PcieLaneCount[i] = pcie_width_arg; |
| 885 | } | ||
| 874 | 886 | ||
| 875 | return 0; | 887 | return 0; |
| 876 | } | 888 | } |
| @@ -3319,9 +3331,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 2442 unmodified lines | |||
| 3319 | data->od8_settings.od8_settings_array; | 3331 | data->od8_settings.od8_settings_array; |
| 3320 | OverDriveTable_t *od_table = | 3332 | OverDriveTable_t *od_table = |
| 3321 | &(data->smc_state_table.overdrive_table); | 3333 | &(data->smc_state_table.overdrive_table); |
| 3322 | struct phm_ppt_v3_information *pptable_information = | 3334 | PPTable_t *pptable = &(data->smc_state_table.pp_table); |
| 3323 | (struct phm_ppt_v3_information *)hwmgr->pptable; | ||
| 3324 | PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable; | ||
| 3325 | struct pp_clock_levels_with_latency clocks; | 3335 | struct pp_clock_levels_with_latency clocks; |
| 3326 | struct vega20_single_dpm_table *fclk_dpm_table = | 3336 | struct vega20_single_dpm_table *fclk_dpm_table = |
| 3327 | &(data->dpm_table.fclk_table); | 3337 | &(data->dpm_table.fclk_table); |
| @@ -3420,13 +3430,9 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 92 unmodified lines | |||
| 3420 | current_lane_width = | 3430 | current_lane_width = |
| 3421 | vega20_get_current_pcie_link_width_level(hwmgr); | 3431 | vega20_get_current_pcie_link_width_level(hwmgr); |
| 3422 | for (i = 0; i < NUM_LINK_LEVELS; i++) { | 3432 | for (i = 0; i < NUM_LINK_LEVELS; i++) { |
| 3423 | if (i == 1 && data->pcie_parameters_override) { | 3433 | gen_speed = pptable->PcieGenSpeed[i]; |
| 3424 | gen_speed = data->pcie_gen_level1; | 3434 | lane_width = pptable->PcieLaneCount[i]; |
| 3425 | lane_width = data->pcie_width_level1; | 3435 | |
| 3426 | } else { | ||
| 3427 | gen_speed = pptable->PcieGenSpeed[i]; | ||
| 3428 | lane_width = pptable->PcieLaneCount[i]; | ||
| 3429 | } | ||
| 3430 | size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, | 3436 | size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, |
| 3431 | (gen_speed == 0) ? "2.5GT/s," : | 3437 | (gen_speed == 0) ? "2.5GT/s," : |
| 3432 | (gen_speed == 1) ? "5.0GT/s," : | 3438 | (gen_speed == 1) ? "5.0GT/s," : |
| @@ -2048,7 +2048,7 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) · 2047 unmodified lines | |||
| 2048 | 2048 | ||
| 2049 | if (shadow) | 2049 | if (shadow) |
| 2050 | vfree(shadow); | 2050 | vfree(shadow); |
| 2051 | else | 2051 | else if (fb_helper->buffer) |
| 2052 | drm_client_buffer_vunmap(fb_helper->buffer); | 2052 | drm_client_buffer_vunmap(fb_helper->buffer); |
| 2053 | 2053 | ||
| 2054 | drm_client_framebuffer_delete(fb_helper->buffer); | 2054 | drm_client_framebuffer_delete(fb_helper->buffer); |
| @@ -357,13 +357,14 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, · 356 unmodified lines | |||
| 357 | if (--shmem->vmap_use_count > 0) | 357 | if (--shmem->vmap_use_count > 0) |
| 358 | return; | 358 | return; |
| 359 | 359 | ||
| 360 | if (obj->import_attach) | 360 | if (obj->import_attach) { |
| 361 | dma_buf_vunmap(obj->import_attach->dmabuf, map); | 361 | dma_buf_vunmap(obj->import_attach->dmabuf, map); |
| 362 | else | 362 | } else { |
| 363 | vunmap(shmem->vaddr); | 363 | vunmap(shmem->vaddr); |
| 364 | drm_gem_shmem_put_pages(shmem); | ||
| 365 | } | ||
| 364 | 366 | ||
| 365 | shmem->vaddr = NULL; | 367 | shmem->vaddr = NULL; |
| 366 | drm_gem_shmem_put_pages(shmem); | ||
| 367 | } | 368 | } |
| 368 | 369 | ||
| 369 | /* | 370 | /* |
| @@ -525,14 +526,28 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) · 155 unmodified lines | |||
| 525 | struct drm_gem_object *obj = vma->vm_private_data; | 526 | struct drm_gem_object *obj = vma->vm_private_data; |
| 526 | struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); | 527 | struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); |
| 527 | loff_t num_pages = obj->size >> PAGE_SHIFT; | 528 | loff_t num_pages = obj->size >> PAGE_SHIFT; |
| 529 | vm_fault_t ret; | ||
| 528 | struct page *page; | 530 | struct page *page; |
| 531 | pgoff_t page_offset; | ||
| 529 | 532 | ||
| 530 | if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages)) | 533 | /* We don't use vmf->pgoff since that has the fake offset */ |
| 531 | return VM_FAULT_SIGBUS; | 534 | page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; |
| 532 | 535 | ||
| 533 | page = shmem->pages[vmf->pgoff]; | 536 | mutex_lock(&shmem->pages_lock); |
| 534 | 537 | ||
| 535 | return vmf_insert_page(vma, vmf->address, page); | 538 | if (page_offset >= num_pages || |
| 539 | WARN_ON_ONCE(!shmem->pages) || | ||
| 540 | shmem->madv < 0) { | ||
| 541 | ret = VM_FAULT_SIGBUS; | ||
| 542 | } else { | ||
| 543 | page = shmem->pages[page_offset]; | ||
| 544 | |||
| 545 | ret = vmf_insert_page(vma, vmf->address, page); | ||
| 546 | } | ||
| 547 | |||
| 548 | mutex_unlock(&shmem->pages_lock); | ||
| 549 | |||
| 550 | return ret; | ||
| 536 | } | 551 | } |
| 537 | 552 | ||
| 538 | static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) | 553 | static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) |
| @@ -581,9 +596,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) · 42 unmodified lines | |||
| 581 | struct drm_gem_shmem_object *shmem; | 596 | struct drm_gem_shmem_object *shmem; |
| 582 | int ret; | 597 | int ret; |
| 583 | 598 | ||
| 584 | /* Remove the fake offset */ | ||
| 585 | vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); | ||
| 586 | |||
| 587 | if (obj->import_attach) { | 599 | if (obj->import_attach) { |
| 588 | /* Drop the reference drm_gem_mmap_obj() acquired.*/ | 600 | /* Drop the reference drm_gem_mmap_obj() acquired.*/ |
| 589 | drm_gem_object_put(obj); | 601 | drm_gem_object_put(obj); |
| @@ -99,6 +99,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd, · 98 unmodified lines | |||
| 99 | if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) | 99 | if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) |
| 100 | return -EFAULT; | 100 | return -EFAULT; |
| 101 | 101 | ||
| 102 | memset(&v, 0, sizeof(v)); | ||
| 103 | |||
| 102 | v = (struct drm_version) { | 104 | v = (struct drm_version) { |
| 103 | .name_len = v32.name_len, | 105 | .name_len = v32.name_len, |
| 104 | .name = compat_ptr(v32.name), | 106 | .name = compat_ptr(v32.name), |
| @@ -137,6 +139,9 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, · 32 unmodified lines | |||
| 137 | 139 | ||
| 138 | if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) | 140 | if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) |
| 139 | return -EFAULT; | 141 | return -EFAULT; |
| 142 | |||
| 143 | memset(&uq, 0, sizeof(uq)); | ||
| 144 | |||
| 140 | uq = (struct drm_unique){ | 145 | uq = (struct drm_unique){ |
| 141 | .unique_len = uq32.unique_len, | 146 | .unique_len = uq32.unique_len, |
| 142 | .unique = compat_ptr(uq32.unique), | 147 | .unique = compat_ptr(uq32.unique), |
| @@ -265,6 +270,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, · 122 unmodified lines | |||
| 265 | if (copy_from_user(&c32, argp, sizeof(c32))) | 270 | if (copy_from_user(&c32, argp, sizeof(c32))) |
| 266 | return -EFAULT; | 271 | return -EFAULT; |
| 267 | 272 | ||
| 273 | memset(&client, 0, sizeof(client)); | ||
| 274 | |||
| 268 | client.idx = c32.idx; | 275 | client.idx = c32.idx; |
| 269 | 276 | ||
| 270 | err = drm_ioctl_kernel(file, drm_getclient, &client, 0); | 277 | err = drm_ioctl_kernel(file, drm_getclient, &client, 0); |
| @@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, · 581 unmodified lines | |||
| 852 | if (copy_from_user(&req32, argp, sizeof(req32))) | 859 | if (copy_from_user(&req32, argp, sizeof(req32))) |
| 853 | return -EFAULT; | 860 | return -EFAULT; |
| 854 | 861 | ||
| 862 | memset(&req, 0, sizeof(req)); | ||
| 863 | |||
| 855 | req.request.type = req32.request.type; | 864 | req.request.type = req32.request.type; |
| 856 | req.request.sequence = req32.request.sequence; | 865 | req.request.sequence = req32.request.sequence; |
| 857 | req.request.signal = req32.request.signal; | 866 | req.request.signal = req32.request.signal; |
| @@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd, · 31 unmodified lines | |||
| 889 | struct drm_mode_fb_cmd2 req64; | 898 | struct drm_mode_fb_cmd2 req64; |
| 890 | int err; | 899 | int err; |
| 891 | 900 | ||
| 901 | memset(&req64, 0, sizeof(req64)); | ||
| 902 | |||
| 892 | if (copy_from_user(&req64, argp, | 903 | if (copy_from_user(&req64, argp, |
| 893 | offsetof(drm_mode_fb_cmd232_t, modifier))) | 904 | offsetof(drm_mode_fb_cmd232_t, modifier))) |
| 894 | return -EFAULT; | 905 | return -EFAULT; |
| @@ -713,9 +713,12 @@ static int engine_setup_common(struct intel_engine_cs *engine) · 712 unmodified lines | |||
| 713 | goto err_status; | 713 | goto err_status; |
| 714 | } | 714 | } |
| 715 | 715 | ||
| 716 | err = intel_engine_init_cmd_parser(engine); | ||
| 717 | if (err) | ||
| 718 | goto err_cmd_parser; | ||
| 719 | |||
| 716 | intel_engine_init_active(engine, ENGINE_PHYSICAL); | 720 | intel_engine_init_active(engine, ENGINE_PHYSICAL); |
| 717 | intel_engine_init_execlists(engine); | 721 | intel_engine_init_execlists(engine); |
| 718 | intel_engine_init_cmd_parser(engine); | ||
| 719 | intel_engine_init__pm(engine); | 722 | intel_engine_init__pm(engine); |
| 720 | intel_engine_init_retire(engine); | 723 | intel_engine_init_retire(engine); |
| 721 | 724 | ||
| @@ -732,6 +735,8 @@ static int engine_setup_common(struct intel_engine_cs *engine) · 10 unmodified lines | |||
| 732 | 735 | ||
| 733 | return 0; | 736 | return 0; |
| 734 | 737 | ||
| 738 | err_cmd_parser: | ||
| 739 | intel_breadcrumbs_free(engine->breadcrumbs); | ||
| 735 | err_status: | 740 | err_status: |
| 736 | cleanup_status_page(engine); | 741 | cleanup_status_page(engine); |
| 737 | return err; | 742 | return err; |
| @@ -940,7 +940,7 @@ static void fini_hash_table(struct intel_engine_cs *engine) · 939 unmodified lines | |||
| 940 | * struct intel_engine_cs based on whether the platform requires software | 940 | * struct intel_engine_cs based on whether the platform requires software |
| 941 | * command parsing. | 941 | * command parsing. |
| 942 | */ | 942 | */ |
| 943 | void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) | 943 | int intel_engine_init_cmd_parser(struct intel_engine_cs *engine) |
| 944 | { | 944 | { |
| 945 | const struct drm_i915_cmd_table *cmd_tables; | 945 | const struct drm_i915_cmd_table *cmd_tables; |
| 946 | int cmd_table_count; | 946 | int cmd_table_count; |
| @@ -948,7 +948,7 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) · 1 unmodified line | |||
| 948 | 948 | ||
| 949 | if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) && | 949 | if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) && |
| 950 | engine->class == COPY_ENGINE_CLASS)) | 950 | engine->class == COPY_ENGINE_CLASS)) |
| 951 | return; | 951 | return 0; |
| 952 | 952 | ||
| 953 | switch (engine->class) { | 953 | switch (engine->class) { |
| 954 | case RENDER_CLASS: | 954 | case RENDER_CLASS: |
| @@ -1013,19 +1013,19 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) · 58 unmodified lines | |||
| 1013 | break; | 1013 | break; |
| 1014 | default: | 1014 | default: |
| 1015 | MISSING_CASE(engine->class); | 1015 | MISSING_CASE(engine->class); |
| 1016 | return; | 1016 | goto out; |
| 1017 | } | 1017 | } |
| 1018 | 1018 | ||
| 1019 | if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) { | 1019 | if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) { |
| 1020 | drm_err(&engine->i915->drm, | 1020 | drm_err(&engine->i915->drm, |
| 1021 | "%s: command descriptions are not sorted\n", | 1021 | "%s: command descriptions are not sorted\n", |
| 1022 | engine->name); | 1022 | engine->name); |
| 1023 | return; | 1023 | goto out; |
| 1024 | } | 1024 | } |
| 1025 | if (!validate_regs_sorted(engine)) { | 1025 | if (!validate_regs_sorted(engine)) { |
| 1026 | drm_err(&engine->i915->drm, | 1026 | drm_err(&engine->i915->drm, |
| 1027 | "%s: registers are not sorted\n", engine->name); | 1027 | "%s: registers are not sorted\n", engine->name); |
| 1028 | return; | 1028 | goto out; |
| 1029 | } | 1029 | } |
| 1030 | 1030 | ||
| 1031 | ret = init_hash_table(engine, cmd_tables, cmd_table_count); | 1031 | ret = init_hash_table(engine, cmd_tables, cmd_table_count); |
| @@ -1033,10 +1033,17 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) · 1 unmodified line | |||
| 1033 | drm_err(&engine->i915->drm, | 1033 | drm_err(&engine->i915->drm, |
| 1034 | "%s: initialised failed!\n", engine->name); | 1034 | "%s: initialised failed!\n", engine->name); |
| 1035 | fini_hash_table(engine); | 1035 | fini_hash_table(engine); |
| 1036 | return; | 1036 | goto out; |
| 1037 | } | 1037 | } |
| 1038 | 1038 | ||
| 1039 | engine->flags |= I915_ENGINE_USING_CMD_PARSER; | 1039 | engine->flags |= I915_ENGINE_USING_CMD_PARSER; |
| 1040 | |||
| 1041 | out: | ||
| 1042 | if (intel_engine_requires_cmd_parser(engine) && | ||
| 1043 | !intel_engine_using_cmd_parser(engine)) | ||
| 1044 | return -EINVAL; | ||
| 1045 | |||
| 1046 | return 0; | ||
| 1040 | } | 1047 | } |
| 1041 | 1048 | ||
| 1042 | /** | 1049 | /** |
| @@ -1952,7 +1952,7 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type); · 1951 unmodified lines | |||
| 1952 | 1952 | ||
| 1953 | /* i915_cmd_parser.c */ | 1953 | /* i915_cmd_parser.c */ |
| 1954 | int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); | 1954 | int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); |
| 1955 | void intel_engine_init_cmd_parser(struct intel_engine_cs *engine); | 1955 | int intel_engine_init_cmd_parser(struct intel_engine_cs *engine); |
| 1956 | void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine); | 1956 | void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine); |
| 1957 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, | 1957 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, |
| 1958 | struct i915_vma *batch, | 1958 | struct i915_vma *batch, |
| @@ -603,7 +603,6 @@ static int append_oa_sample(struct i915_perf_stream *stream, · 602 unmodified lines | |||
| 603 | { | 603 | { |
| 604 | int report_size = stream->oa_buffer.format_size; | 604 | int report_size = stream->oa_buffer.format_size; |
| 605 | struct drm_i915_perf_record_header header; | 605 | struct drm_i915_perf_record_header header; |
| 606 | u32 sample_flags = stream->sample_flags; | ||
| 607 | 606 | ||
| 608 | header.type = DRM_I915_PERF_RECORD_SAMPLE; | 607 | header.type = DRM_I915_PERF_RECORD_SAMPLE; |
| 609 | header.pad = 0; | 608 | header.pad = 0; |
| @@ -617,10 +616,8 @@ static int append_oa_sample(struct i915_perf_stream *stream, · 7 unmodified lines | |||
| 617 | return -EFAULT; | 616 | return -EFAULT; |
| 618 | buf += sizeof(header); | 617 | buf += sizeof(header); |
| 619 | 618 | ||
| 620 | if (sample_flags & SAMPLE_OA_REPORT) { | 619 | if (copy_to_user(buf, report, report_size)) |
| 621 | if (copy_to_user(buf, report, report_size)) | 620 | return -EFAULT; |
| 622 | return -EFAULT; | ||
| 623 | } | ||
| 624 | 621 | ||
| 625 | (*offset) += header.size; | 622 | (*offset) += header.size; |
| 626 | 623 | ||
| @@ -2682,7 +2679,7 @@ static void i915_oa_stream_enable(struct i915_perf_stream *stream) · 2055 unmodified lines | |||
| 2682 | 2679 | ||
| 2683 | stream->perf->ops.oa_enable(stream); | 2680 | stream->perf->ops.oa_enable(stream); |
| 2684 | 2681 | ||
| 2685 | if (stream->periodic) | 2682 | if (stream->sample_flags & SAMPLE_OA_REPORT) |
| 2686 | hrtimer_start(&stream->poll_check_timer, | 2683 | hrtimer_start(&stream->poll_check_timer, |
| 2687 | ns_to_ktime(stream->poll_oa_period), | 2684 | ns_to_ktime(stream->poll_oa_period), |
| 2688 | HRTIMER_MODE_REL_PINNED); | 2685 | HRTIMER_MODE_REL_PINNED); |
| @@ -2745,7 +2742,7 @@ static void i915_oa_stream_disable(struct i915_perf_stream *stream) · 56 unmodified lines | |||
| 2745 | { | 2742 | { |
| 2746 | stream->perf->ops.oa_disable(stream); | 2743 | stream->perf->ops.oa_disable(stream); |
| 2747 | 2744 | ||
| 2748 | if (stream->periodic) | 2745 | if (stream->sample_flags & SAMPLE_OA_REPORT) |
| 2749 | hrtimer_cancel(&stream->poll_check_timer); | 2746 | hrtimer_cancel(&stream->poll_check_timer); |
| 2750 | } | 2747 | } |
| 2751 | 2748 | ||
| @@ -3028,7 +3025,7 @@ static ssize_t i915_perf_read(struct file *file, · 276 unmodified lines | |||
| 3028 | * disabled stream as an error. In particular it might otherwise lead | 3025 | * disabled stream as an error. In particular it might otherwise lead |
| 3029 | * to a deadlock for blocking file descriptors... | 3026 | * to a deadlock for blocking file descriptors... |
| 3030 | */ | 3027 | */ |
| 3031 | if (!stream->enabled) | 3028 | if (!stream->enabled || !(stream->sample_flags & SAMPLE_OA_REPORT)) |
| 3032 | return -EIO; | 3029 | return -EIO; |
| 3033 | 3030 | ||
| 3034 | if (!(file->f_flags & O_NONBLOCK)) { | 3031 | if (!(file->f_flags & O_NONBLOCK)) { |
| @@ -3316,7 +3316,18 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 3315 unmodified lines | |||
| 3316 | 3316 | ||
| 3317 | #define ILK_DISPLAY_CHICKEN1 _MMIO(0x42000) | 3317 | #define ILK_DISPLAY_CHICKEN1 _MMIO(0x42000) |
| 3318 | #define ILK_FBCQ_DIS (1 << 22) | 3318 | #define ILK_FBCQ_DIS (1 << 22) |
| 3319 | #define ILK_PABSTRETCH_DIS (1 << 21) | 3319 | #define ILK_PABSTRETCH_DIS REG_BIT(21) |
| 3320 | #define ILK_SABSTRETCH_DIS REG_BIT(20) | ||
| 3321 | #define IVB_PRI_STRETCH_MAX_MASK REG_GENMASK(21, 20) | ||
| 3322 | #define IVB_PRI_STRETCH_MAX_X8 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 0) | ||
| 3323 | #define IVB_PRI_STRETCH_MAX_X4 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 1) | ||
| 3324 | #define IVB_PRI_STRETCH_MAX_X2 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 2) | ||
| 3325 | #define IVB_PRI_STRETCH_MAX_X1 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 3) | ||
| 3326 | #define IVB_SPR_STRETCH_MAX_MASK REG_GENMASK(19, 18) | ||
| 3327 | #define IVB_SPR_STRETCH_MAX_X8 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 0) | ||
| 3328 | #define IVB_SPR_STRETCH_MAX_X4 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 1) | ||
| 3329 | #define IVB_SPR_STRETCH_MAX_X2 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 2) | ||
| 3330 | #define IVB_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 3) | ||
| 3320 | 3331 | ||
| 3321 | 3332 | ||
| 3322 | /* | 3333 | /* |
| @@ -8039,6 +8050,16 @@ enum { · 4716 unmodified lines | |||
| 8039 | 8050 | ||
| 8040 | #define _CHICKEN_PIPESL_1_A 0x420b0 | 8051 | #define _CHICKEN_PIPESL_1_A 0x420b0 |
| 8041 | #define _CHICKEN_PIPESL_1_B 0x420b4 | 8052 | #define _CHICKEN_PIPESL_1_B 0x420b4 |
| 8053 | #define HSW_PRI_STRETCH_MAX_MASK REG_GENMASK(28, 27) | ||
| 8054 | #define HSW_PRI_STRETCH_MAX_X8 REG_FIELD_PREP(HSW_PRI_STRETCH_MAX_MASK, 0) | ||
| 8055 | #define HSW_PRI_STRETCH_MAX_X4 REG_FIELD_PREP(HSW_PRI_STRETCH_MAX_MASK, 1) | ||
| 8056 | #define HSW_PRI_STRETCH_MAX_X2 REG_FIELD_PREP(HSW_PRI_STRETCH_MAX_MASK, 2) | ||
| 8057 | #define HSW_PRI_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_PRI_STRETCH_MAX_MASK, 3) | ||
| 8058 | #define HSW_SPR_STRETCH_MAX_MASK REG_GENMASK(26, 25) | ||
| 8059 | #define HSW_SPR_STRETCH_MAX_X8 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 0) | ||
| 8060 | #define HSW_SPR_STRETCH_MAX_X4 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 1) | ||
| 8061 | #define HSW_SPR_STRETCH_MAX_X2 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 2) | ||
| 8062 | #define HSW_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3) | ||
| 8042 | #define HSW_FBCQ_DIS (1 << 22) | 8063 | #define HSW_FBCQ_DIS (1 << 22) |
| 8043 | #define BDW_DPRS_MASK_VBLANK_SRD (1 << 0) | 8064 | #define BDW_DPRS_MASK_VBLANK_SRD (1 << 0) |
| 8044 | #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) | 8065 | #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) |
| @@ -7245,11 +7245,16 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) · 7244 unmodified lines | |||
| 7245 | intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, | 7245 | intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, |
| 7246 | intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); | 7246 | intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); |
| 7247 | 7247 | ||
| 7248 | /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ | ||
| 7249 | for_each_pipe(dev_priv, pipe) { | 7248 | for_each_pipe(dev_priv, pipe) { |
| 7249 | /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ | ||
| 7250 | intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), | 7250 | intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), |
| 7251 | intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe)) | | 7251 | intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe)) | |
| 7252 | BDW_DPRS_MASK_VBLANK_SRD); | 7252 | BDW_DPRS_MASK_VBLANK_SRD); |
| 7253 | |||
| 7254 | /* Undocumented but fixes async flip + VT-d corruption */ | ||
| 7255 | if (intel_vtd_active()) | ||
| 7256 | intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), | ||
| 7257 | HSW_PRI_STRETCH_MAX_MASK, HSW_PRI_STRETCH_MAX_X1); | ||
| 7253 | } | 7258 | } |
| 7254 | 7259 | ||
| 7255 | /* WaVSRefCountFullforceMissDisable:bdw */ | 7260 | /* WaVSRefCountFullforceMissDisable:bdw */ |
| @@ -7285,11 +7290,20 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) · 29 unmodified lines | |||
| 7285 | 7290 | ||
| 7286 | static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) | 7291 | static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7287 | { | 7292 | { |
| 7293 | enum pipe pipe; | ||
| 7294 | |||
| 7288 | /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ | 7295 | /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ |
| 7289 | intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), | 7296 | intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), |
| 7290 | intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A)) | | 7297 | intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A)) | |
| 7291 | HSW_FBCQ_DIS); | 7298 | HSW_FBCQ_DIS); |
| 7292 | 7299 | ||
| 7300 | for_each_pipe(dev_priv, pipe) { | ||
| 7301 | /* Undocumented but fixes async flip + VT-d corruption */ | ||
| 7302 | if (intel_vtd_active()) | ||
| 7303 | intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), | ||
| 7304 | HSW_PRI_STRETCH_MAX_MASK, HSW_PRI_STRETCH_MAX_X1); | ||
| 7305 | } | ||
| 7306 | |||
| 7293 | /* This is required by WaCatErrorRejectionIssue:hsw */ | 7307 | /* This is required by WaCatErrorRejectionIssue:hsw */ |
| 7294 | intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | 7308 | intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, |
| 7295 | intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | 7309 | intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
| @@ -482,6 +482,16 @@ static int meson_probe_remote(struct platform_device *pdev, · 481 unmodified lines | |||
| 482 | return count; | 482 | return count; |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | static void meson_drv_shutdown(struct platform_device *pdev) | ||
| 486 | { | ||
| 487 | struct meson_drm *priv = dev_get_drvdata(&pdev->dev); | ||
| 488 | struct drm_device *drm = priv->drm; | ||
| 489 | |||
| 490 | DRM_DEBUG_DRIVER("\n"); | ||
| 491 | drm_kms_helper_poll_fini(drm); | ||
| 492 | drm_atomic_helper_shutdown(drm); | ||
| 493 | } | ||
| 494 | |||
| 485 | static int meson_drv_probe(struct platform_device *pdev) | 495 | static int meson_drv_probe(struct platform_device *pdev) |
| 486 | { | 496 | { |
| 487 | struct component_match *match = NULL; | 497 | struct component_match *match = NULL; |
| @@ -553,6 +563,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = { · 65 unmodified lines | |||
| 553 | 563 | ||
| 554 | static struct platform_driver meson_drm_platform_driver = { | 564 | static struct platform_driver meson_drm_platform_driver = { |
| 555 | .probe = meson_drv_probe, | 565 | .probe = meson_drv_probe, |
| 566 | .shutdown = meson_drv_shutdown, | ||
| 556 | .driver = { | 567 | .driver = { |
| 557 | .name = "meson-drm", | 568 | .name = "meson-drm", |
| 558 | .of_match_table = dt_match, | 569 | .of_match_table = dt_match, |
| @@ -551,12 +551,17 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) · 550 unmodified lines | |||
| 551 | 551 | ||
| 552 | if (!ttm_dma) | 552 | if (!ttm_dma) |
| 553 | return; | 553 | return; |
| 554 | if (!ttm_dma->pages) { | ||
| 555 | NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma); | ||
| 556 | return; | ||
| 557 | } | ||
| 554 | 558 | ||
| 555 | /* Don't waste time looping if the object is coherent */ | 559 | /* Don't waste time looping if the object is coherent */ |
| 556 | if (nvbo->force_coherent) | 560 | if (nvbo->force_coherent) |
| 557 | return; | 561 | return; |
| 558 | 562 | ||
| 559 | for (i = 0; i < ttm_dma->num_pages; ++i) { | 563 | i = 0; |
| 564 | while (i < ttm_dma->num_pages) { | ||
| 560 | struct page *p = ttm_dma->pages[i]; | 565 | struct page *p = ttm_dma->pages[i]; |
| 561 | size_t num_pages = 1; | 566 | size_t num_pages = 1; |
| 562 | 567 | ||
| @@ -582,12 +587,17 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) · 19 unmodified lines | |||
| 582 | 587 | ||
| 583 | if (!ttm_dma) | 588 | if (!ttm_dma) |
| 584 | return; | 589 | return; |
| 590 | if (!ttm_dma->pages) { | ||
| 591 | NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma); | ||
| 592 | return; | ||
| 593 | } | ||
| 585 | 594 | ||
| 586 | /* Don't waste time looping if the object is coherent */ | 595 | /* Don't waste time looping if the object is coherent */ |
| 587 | if (nvbo->force_coherent) | 596 | if (nvbo->force_coherent) |
| 588 | return; | 597 | return; |
| 589 | 598 | ||
| 590 | for (i = 0; i < ttm_dma->num_pages; ++i) { | 599 | i = 0; |
| 600 | while (i < ttm_dma->num_pages) { | ||
| 591 | struct page *p = ttm_dma->pages[i]; | 601 | struct page *p = ttm_dma->pages[i]; |
| 592 | size_t num_pages = 1; | 602 | size_t num_pages = 1; |
| 593 | 603 | ||
| @@ -2149,11 +2149,12 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc, · 2148 unmodified lines | |||
| 2149 | const struct mipi_dsi_msg *msg) | 2149 | const struct mipi_dsi_msg *msg) |
| 2150 | { | 2150 | { |
| 2151 | struct mipi_dsi_packet pkt; | 2151 | struct mipi_dsi_packet pkt; |
| 2152 | int ret; | ||
| 2152 | u32 r; | 2153 | u32 r; |
| 2153 | 2154 | ||
| 2154 | r = mipi_dsi_create_packet(&pkt, msg); | 2155 | ret = mipi_dsi_create_packet(&pkt, msg); |
| 2155 | if (r < 0) | 2156 | if (ret < 0) |
| 2156 | return r; | 2157 | return ret; |
| 2157 | 2158 | ||
| 2158 | WARN_ON(!dsi_bus_is_locked(dsi)); | 2159 | WARN_ON(!dsi_bus_is_locked(dsi)); |
| 2159 | 2160 | ||
| @@ -328,6 +328,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc, · 327 unmodified lines | |||
| 328 | 328 | ||
| 329 | head.id = i; | 329 | head.id = i; |
| 330 | head.flags = 0; | 330 | head.flags = 0; |
| 331 | head.surface_id = 0; | ||
| 331 | oldcount = qdev->monitors_config->count; | 332 | oldcount = qdev->monitors_config->count; |
| 332 | if (crtc->state->active) { | 333 | if (crtc->state->active) { |
| 333 | struct drm_display_mode *mode = &crtc->mode; | 334 | struct drm_display_mode *mode = &crtc->mode; |
| @@ -321,7 +321,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, · 320 unmodified lines | |||
| 321 | int type, struct qxl_release **release, | 321 | int type, struct qxl_release **release, |
| 322 | struct qxl_bo **rbo) | 322 | struct qxl_bo **rbo) |
| 323 | { | 323 | { |
| 324 | struct qxl_bo *bo; | 324 | struct qxl_bo *bo, *free_bo = NULL; |
| 325 | int idr_ret; | 325 | int idr_ret; |
| 326 | int ret = 0; | 326 | int ret = 0; |
| 327 | union qxl_release_info *info; | 327 | union qxl_release_info *info; |
| @@ -347,7 +347,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, · 19 unmodified lines | |||
| 347 | 347 | ||
| 348 | mutex_lock(&qdev->release_mutex); | 348 | mutex_lock(&qdev->release_mutex); |
| 349 | if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { | 349 | if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { |
| 350 | qxl_bo_unref(&qdev->current_release_bo[cur_idx]); | 350 | free_bo = qdev->current_release_bo[cur_idx]; |
| 351 | qdev->current_release_bo_offset[cur_idx] = 0; | 351 | qdev->current_release_bo_offset[cur_idx] = 0; |
| 352 | qdev->current_release_bo[cur_idx] = NULL; | 352 | qdev->current_release_bo[cur_idx] = NULL; |
| 353 | } | 353 | } |
| @@ -355,6 +355,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, · 1 unmodified line | |||
| 355 | ret = qxl_release_bo_alloc(qdev, &qdev->current_release_bo[cur_idx]); | 355 | ret = qxl_release_bo_alloc(qdev, &qdev->current_release_bo[cur_idx]); |
| 356 | if (ret) { | 356 | if (ret) { |
| 357 | mutex_unlock(&qdev->release_mutex); | 357 | mutex_unlock(&qdev->release_mutex); |
| 358 | if (free_bo) { | ||
| 359 | qxl_bo_unpin(free_bo); | ||
| 360 | qxl_bo_unref(&free_bo); | ||
| 361 | } | ||
| 358 | qxl_release_free(qdev, *release); | 362 | qxl_release_free(qdev, *release); |
| 359 | return ret; | 363 | return ret; |
| 360 | } | 364 | } |
| @@ -370,6 +374,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, · 9 unmodified lines | |||
| 370 | *rbo = bo; | 374 | *rbo = bo; |
| 371 | 375 | ||
| 372 | mutex_unlock(&qdev->release_mutex); | 376 | mutex_unlock(&qdev->release_mutex); |
| 377 | if (free_bo) { | ||
| 378 | qxl_bo_unpin(free_bo); | ||
| 379 | qxl_bo_unref(&free_bo); | ||
| 380 | } | ||
| 373 | 381 | ||
| 374 | ret = qxl_release_list_add(*release, bo); | 382 | ret = qxl_release_list_add(*release, bo); |
| 375 | qxl_bo_unref(&bo); | 383 | qxl_bo_unref(&bo); |
| @@ -574,6 +574,8 @@ struct radeon_gem { · 573 unmodified lines | |||
| 574 | struct list_head objects; | 574 | struct list_head objects; |
| 575 | }; | 575 | }; |
| 576 | 576 | ||
| 577 | extern const struct drm_gem_object_funcs radeon_gem_object_funcs; | ||
| 578 | |||
| 577 | int radeon_gem_init(struct radeon_device *rdev); | 579 | int radeon_gem_init(struct radeon_device *rdev); |
| 578 | void radeon_gem_fini(struct radeon_device *rdev); | 580 | void radeon_gem_fini(struct radeon_device *rdev); |
| 579 | int radeon_gem_object_create(struct radeon_device *rdev, unsigned long size, | 581 | int radeon_gem_object_create(struct radeon_device *rdev, unsigned long size, |
| @@ -43,7 +43,7 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj); · 42 unmodified lines | |||
| 43 | int radeon_gem_prime_pin(struct drm_gem_object *obj); | 43 | int radeon_gem_prime_pin(struct drm_gem_object *obj); |
| 44 | void radeon_gem_prime_unpin(struct drm_gem_object *obj); | 44 | void radeon_gem_prime_unpin(struct drm_gem_object *obj); |
| 45 | 45 | ||
| 46 | static const struct drm_gem_object_funcs radeon_gem_object_funcs; | 46 | const struct drm_gem_object_funcs radeon_gem_object_funcs; |
| 47 | 47 | ||
| 48 | static void radeon_gem_object_free(struct drm_gem_object *gobj) | 48 | static void radeon_gem_object_free(struct drm_gem_object *gobj) |
| 49 | { | 49 | { |
| @@ -227,7 +227,7 @@ static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) · 177 unmodified lines | |||
| 227 | return r; | 227 | return r; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | static const struct drm_gem_object_funcs radeon_gem_object_funcs = { | 230 | const struct drm_gem_object_funcs radeon_gem_object_funcs = { |
| 231 | .free = radeon_gem_object_free, | 231 | .free = radeon_gem_object_free, |
| 232 | .open = radeon_gem_object_open, | 232 | .open = radeon_gem_object_open, |
| 233 | .close = radeon_gem_object_close, | 233 | .close = radeon_gem_object_close, |
| @@ -56,6 +56,8 @@ struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev, · 55 unmodified lines | |||
| 56 | if (ret) | 56 | if (ret) |
| 57 | return ERR_PTR(ret); | 57 | return ERR_PTR(ret); |
| 58 | 58 | ||
| 59 | bo->tbo.base.funcs = &radeon_gem_object_funcs; | ||
| 60 | |||
| 59 | mutex_lock(&rdev->gem.mutex); | 61 | mutex_lock(&rdev->gem.mutex); |
| 60 | list_add_tail(&bo->list, &rdev->gem.objects); | 62 | list_add_tail(&bo->list, &rdev->gem.objects); |
| 61 | mutex_unlock(&rdev->gem.mutex); | 63 | mutex_unlock(&rdev->gem.mutex); |
| @@ -83,6 +83,7 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); · 82 unmodified lines | |||
| 83 | 83 | ||
| 84 | struct gm12u320_device { | 84 | struct gm12u320_device { |
| 85 | struct drm_device dev; | 85 | struct drm_device dev; |
| 86 | struct device *dmadev; | ||
| 86 | struct drm_simple_display_pipe pipe; | 87 | struct drm_simple_display_pipe pipe; |
| 87 | struct drm_connector conn; | 88 | struct drm_connector conn; |
| 88 | unsigned char *cmd_buf; | 89 | unsigned char *cmd_buf; |
| @@ -601,6 +602,22 @@ static const uint64_t gm12u320_pipe_modifiers[] = { · 512 unmodified lines | |||
| 601 | DRM_FORMAT_MOD_INVALID | 602 | DRM_FORMAT_MOD_INVALID |
| 602 | }; | 603 | }; |
| 603 | 604 | ||
| 605 | /* | ||
| 606 | * FIXME: Dma-buf sharing requires DMA support by the importing device. | ||
| 607 | * This function is a workaround to make USB devices work as well. | ||
| 608 | * See todo.rst for how to fix the issue in the dma-buf framework. | ||
| 609 | */ | ||
| 610 | static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev, | ||
| 611 | struct dma_buf *dma_buf) | ||
| 612 | { | ||
| 613 | struct gm12u320_device *gm12u320 = to_gm12u320(dev); | ||
| 614 | |||
| 615 | if (!gm12u320->dmadev) | ||
| 616 | return ERR_PTR(-ENODEV); | ||
| 617 | |||
| 618 | return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev); | ||
| 619 | } | ||
| 620 | |||
| 604 | DEFINE_DRM_GEM_FOPS(gm12u320_fops); | 621 | DEFINE_DRM_GEM_FOPS(gm12u320_fops); |
| 605 | 622 | ||
| 606 | static const struct drm_driver gm12u320_drm_driver = { | 623 | static const struct drm_driver gm12u320_drm_driver = { |
| @@ -614,6 +631,7 @@ static const struct drm_driver gm12u320_drm_driver = { · 7 unmodified lines | |||
| 614 | 631 | ||
| 615 | .fops = &gm12u320_fops, | 632 | .fops = &gm12u320_fops, |
| 616 | DRM_GEM_SHMEM_DRIVER_OPS, | 633 | DRM_GEM_SHMEM_DRIVER_OPS, |
| 634 | .gem_prime_import = gm12u320_gem_prime_import, | ||
| 617 | }; | 635 | }; |
| 618 | 636 | ||
| 619 | static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { | 637 | static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { |
| @@ -640,15 +658,18 @@ static int gm12u320_usb_probe(struct usb_interface *interface, · 20 unmodified lines | |||
| 640 | struct gm12u320_device, dev); | 658 | struct gm12u320_device, dev); |
| 641 | if (IS_ERR(gm12u320)) | 659 | if (IS_ERR(gm12u320)) |
| 642 | return PTR_ERR(gm12u320); | 660 | return PTR_ERR(gm12u320); |
| 661 | dev = &gm12u320->dev; | ||
| 662 | |||
| 663 | gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); | ||
| 664 | if (!gm12u320->dmadev) | ||
| 665 | drm_warn(dev, "buffer sharing not supported"); /* not an error */ | ||
| 643 | 666 | ||
| 644 | INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); | 667 | INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); |
| 645 | mutex_init(&gm12u320->fb_update.lock); | 668 | mutex_init(&gm12u320->fb_update.lock); |
| 646 | 669 | ||
| 647 | dev = &gm12u320->dev; | ||
| 648 | |||
| 649 | ret = drmm_mode_config_init(dev); | 670 | ret = drmm_mode_config_init(dev); |
| 650 | if (ret) | 671 | if (ret) |
| 651 | return ret; | 672 | goto err_put_device; |
| 652 | 673 | ||
| 653 | dev->mode_config.min_width = GM12U320_USER_WIDTH; | 674 | dev->mode_config.min_width = GM12U320_USER_WIDTH; |
| 654 | dev->mode_config.max_width = GM12U320_USER_WIDTH; | 675 | dev->mode_config.max_width = GM12U320_USER_WIDTH; |
| @@ -658,15 +679,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface, · 3 unmodified lines | |||
| 658 | 679 | ||
| 659 | ret = gm12u320_usb_alloc(gm12u320); | 680 | ret = gm12u320_usb_alloc(gm12u320); |
| 660 | if (ret) | 681 | if (ret) |
| 661 | return ret; | 682 | goto err_put_device; |
| 662 | 683 | ||
| 663 | ret = gm12u320_set_ecomode(gm12u320); | 684 | ret = gm12u320_set_ecomode(gm12u320); |
| 664 | if (ret) | 685 | if (ret) |
| 665 | return ret; | 686 | goto err_put_device; |
| 666 | 687 | ||
| 667 | ret = gm12u320_conn_init(gm12u320); | 688 | ret = gm12u320_conn_init(gm12u320); |
| 668 | if (ret) | 689 | if (ret) |
| 669 | return ret; | 690 | goto err_put_device; |
| 670 | 691 | ||
| 671 | ret = drm_simple_display_pipe_init(&gm12u320->dev, | 692 | ret = drm_simple_display_pipe_init(&gm12u320->dev, |
| 672 | &gm12u320->pipe, | 693 | &gm12u320->pipe, |
| @@ -676,24 +697,31 @@ static int gm12u320_usb_probe(struct usb_interface *interface, · 3 unmodified lines | |||
| 676 | gm12u320_pipe_modifiers, | 697 | gm12u320_pipe_modifiers, |
| 677 | &gm12u320->conn); | 698 | &gm12u320->conn); |
| 678 | if (ret) | 699 | if (ret) |
| 679 | return ret; | 700 | goto err_put_device; |
| 680 | 701 | ||
| 681 | drm_mode_config_reset(dev); | 702 | drm_mode_config_reset(dev); |
| 682 | 703 | ||
| 683 | usb_set_intfdata(interface, dev); | 704 | usb_set_intfdata(interface, dev); |
| 684 | ret = drm_dev_register(dev, 0); | 705 | ret = drm_dev_register(dev, 0); |
| 685 | if (ret) | 706 | if (ret) |
| 686 | return ret; | 707 | goto err_put_device; |
| 687 | 708 | ||
| 688 | drm_fbdev_generic_setup(dev, 0); | 709 | drm_fbdev_generic_setup(dev, 0); |
| 689 | 710 | ||
| 690 | return 0; | 711 | return 0; |
| 712 | |||
| 713 | err_put_device: | ||
| 714 | put_device(gm12u320->dmadev); | ||
| 715 | return ret; | ||
| 691 | } | 716 | } |
| 692 | 717 | ||
| 693 | static void gm12u320_usb_disconnect(struct usb_interface *interface) | 718 | static void gm12u320_usb_disconnect(struct usb_interface *interface) |
| 694 | { | 719 | { |
| 695 | struct drm_device *dev = usb_get_intfdata(interface); | 720 | struct drm_device *dev = usb_get_intfdata(interface); |
| 721 | struct gm12u320_device *gm12u320 = to_gm12u320(dev); | ||
| 696 | 722 | ||
| 723 | put_device(gm12u320->dmadev); | ||
| 724 | gm12u320->dmadev = NULL; | ||
| 697 | drm_dev_unplug(dev); | 725 | drm_dev_unplug(dev); |
| 698 | drm_atomic_helper_shutdown(dev); | 726 | drm_atomic_helper_shutdown(dev); |
| 699 | } | 727 | } |
| @@ -136,7 +136,8 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, · 135 unmodified lines | |||
| 136 | struct ttm_bo_device *bdev = bo->bdev; | 136 | struct ttm_bo_device *bdev = bo->bdev; |
| 137 | struct ttm_resource_manager *man; | 137 | struct ttm_resource_manager *man; |
| 138 | 138 | ||
| 139 | dma_resv_assert_held(bo->base.resv); | 139 | if (!bo->deleted) |
| 140 | dma_resv_assert_held(bo->base.resv); | ||
| 140 | 141 | ||
| 141 | if (bo->pin_count) { | 142 | if (bo->pin_count) { |
| 142 | ttm_bo_del_from_lru(bo); | 143 | ttm_bo_del_from_lru(bo); |
| @@ -508,8 +509,11 @@ static void ttm_bo_release(struct kref *kref) · 365 unmodified lines | |||
| 508 | * Make pinned bos immediately available to | 509 | * Make pinned bos immediately available to |
| 509 | * shrinkers, now that they are queued for | 510 | * shrinkers, now that they are queued for |
| 510 | * destruction. | 511 | * destruction. |
| 512 | * | ||
| 513 | * FIXME: QXL is triggering this. Can be removed when the | ||
| 514 | * driver is fixed. | ||
| 511 | */ | 515 | */ |
| 512 | if (WARN_ON(bo->pin_count)) { | 516 | if (WARN_ON_ONCE(bo->pin_count)) { |
| 513 | bo->pin_count = 0; | 517 | bo->pin_count = 0; |
| 514 | ttm_bo_move_to_lru_tail(bo, &bo->mem, NULL); | 518 | ttm_bo_move_to_lru_tail(bo, &bo->mem, NULL); |
| 515 | } | 519 | } |
| @@ -268,13 +268,13 @@ static void ttm_pool_type_init(struct ttm_pool_type *pt, struct ttm_pool *pool, · 267 unmodified lines | |||
| 268 | /* Remove a pool_type from the global shrinker list and free all pages */ | 268 | /* Remove a pool_type from the global shrinker list and free all pages */ |
| 269 | static void ttm_pool_type_fini(struct ttm_pool_type *pt) | 269 | static void ttm_pool_type_fini(struct ttm_pool_type *pt) |
| 270 | { | 270 | { |
| 271 | struct page *p, *tmp; | 271 | struct page *p; |
| 272 | 272 | ||
| 273 | mutex_lock(&shrinker_lock); | 273 | mutex_lock(&shrinker_lock); |
| 274 | list_del(&pt->shrinker_list); | 274 | list_del(&pt->shrinker_list); |
| 275 | mutex_unlock(&shrinker_lock); | 275 | mutex_unlock(&shrinker_lock); |
| 276 | 276 | ||
| 277 | list_for_each_entry_safe(p, tmp, &pt->pages, lru) | 277 | while ((p = ttm_pool_type_take(pt))) |
| 278 | ttm_pool_free_page(pt->pool, pt->caching, pt->order, p); | 278 | ttm_pool_free_page(pt->pool, pt->caching, pt->order, p); |
| 279 | } | 279 | } |
| 280 | 280 | ||
| @@ -32,6 +32,22 @@ static int udl_usb_resume(struct usb_interface *interface) · 31 unmodified lines | |||
| 32 | return drm_mode_config_helper_resume(dev); | 32 | return drm_mode_config_helper_resume(dev); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | /* | ||
| 36 | * FIXME: Dma-buf sharing requires DMA support by the importing device. | ||
| 37 | * This function is a workaround to make USB devices work as well. | ||
| 38 | * See todo.rst for how to fix the issue in the dma-buf framework. | ||
| 39 | */ | ||
| 40 | static struct drm_gem_object *udl_driver_gem_prime_import(struct drm_device *dev, | ||
| 41 | struct dma_buf *dma_buf) | ||
| 42 | { | ||
| 43 | struct udl_device *udl = to_udl(dev); | ||
| 44 | |||
| 45 | if (!udl->dmadev) | ||
| 46 | return ERR_PTR(-ENODEV); | ||
| 47 | |||
| 48 | return drm_gem_prime_import_dev(dev, dma_buf, udl->dmadev); | ||
| 49 | } | ||
| 50 | |||
| 35 | DEFINE_DRM_GEM_FOPS(udl_driver_fops); | 51 | DEFINE_DRM_GEM_FOPS(udl_driver_fops); |
| 36 | 52 | ||
| 37 | static const struct drm_driver driver = { | 53 | static const struct drm_driver driver = { |
| @@ -40,6 +56,7 @@ static const struct drm_driver driver = { · 2 unmodified lines | |||
| 40 | /* GEM hooks */ | 56 | /* GEM hooks */ |
| 41 | .fops = &udl_driver_fops, | 57 | .fops = &udl_driver_fops, |
| 42 | DRM_GEM_SHMEM_DRIVER_OPS, | 58 | DRM_GEM_SHMEM_DRIVER_OPS, |
| 59 | .gem_prime_import = udl_driver_gem_prime_import, | ||
| 43 | 60 | ||
| 44 | .name = DRIVER_NAME, | 61 | .name = DRIVER_NAME, |
| 45 | .desc = DRIVER_DESC, | 62 | .desc = DRIVER_DESC, |
| @@ -50,6 +50,7 @@ struct urb_list { · 49 unmodified lines | |||
| 50 | struct udl_device { | 50 | struct udl_device { |
| 51 | struct drm_device drm; | 51 | struct drm_device drm; |
| 52 | struct device *dev; | 52 | struct device *dev; |
| 53 | struct device *dmadev; | ||
| 53 | 54 | ||
| 54 | struct drm_simple_display_pipe display_pipe; | 55 | struct drm_simple_display_pipe display_pipe; |
| 55 | 56 | ||
| @@ -315,6 +315,10 @@ int udl_init(struct udl_device *udl) · 314 unmodified lines | |||
| 315 | 315 | ||
| 316 | DRM_DEBUG("\n"); | 316 | DRM_DEBUG("\n"); |
| 317 | 317 | ||
| 318 | udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); | ||
| 319 | if (!udl->dmadev) | ||
| 320 | drm_warn(dev, "buffer sharing not supported"); /* not an error */ | ||
| 321 | |||
| 318 | mutex_init(&udl->gem_lock); | 322 | mutex_init(&udl->gem_lock); |
| 319 | 323 | ||
| 320 | if (!udl_parse_vendor_descriptor(udl)) { | 324 | if (!udl_parse_vendor_descriptor(udl)) { |
| @@ -343,12 +347,18 @@ int udl_init(struct udl_device *udl) · 22 unmodified lines | |||
| 343 | err: | 347 | err: |
| 344 | if (udl->urbs.count) | 348 | if (udl->urbs.count) |
| 345 | udl_free_urb_list(dev); | 349 | udl_free_urb_list(dev); |
| 350 | put_device(udl->dmadev); | ||
| 346 | DRM_ERROR("%d\n", ret); | 351 | DRM_ERROR("%d\n", ret); |
| 347 | return ret; | 352 | return ret; |
| 348 | } | 353 | } |
| 349 | 354 | ||
| 350 | int udl_drop_usb(struct drm_device *dev) | 355 | int udl_drop_usb(struct drm_device *dev) |
| 351 | { | 356 | { |
| 357 | struct udl_device *udl = to_udl(dev); | ||
| 358 | |||
| 352 | udl_free_urb_list(dev); | 359 | udl_free_urb_list(dev); |
| 360 | put_device(udl->dmadev); | ||
| 361 | udl->dmadev = NULL; | ||
| 362 | |||
| 353 | return 0; | 363 | return 0; |
| 354 | } | 364 | } |
| @@ -500,8 +500,6 @@ vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, · 499 unmodified lines | |||
| 500 | vm_fault_t ret; | 500 | vm_fault_t ret; |
| 501 | pgoff_t fault_page_size; | 501 | pgoff_t fault_page_size; |
| 502 | bool write = vmf->flags & FAULT_FLAG_WRITE; | 502 | bool write = vmf->flags & FAULT_FLAG_WRITE; |
| 503 | bool is_cow_mapping = | ||
| 504 | (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; | ||
| 505 | 503 | ||
| 506 | switch (pe_size) { | 504 | switch (pe_size) { |
| 507 | case PE_SIZE_PMD: | 505 | case PE_SIZE_PMD: |
| @@ -518,7 +516,7 @@ vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, · 10 unmodified lines | |||
| 518 | } | 516 | } |
| 519 | 517 | ||
| 520 | /* Always do write dirty-tracking and COW on PTE level. */ | 518 | /* Always do write dirty-tracking and COW on PTE level. */ |
| 521 | if (write && (READ_ONCE(vbo->dirty) || is_cow_mapping)) | 519 | if (write && (READ_ONCE(vbo->dirty) || is_cow_mapping(vma->vm_flags))) |
| 522 | return VM_FAULT_FALLBACK; | 520 | return VM_FAULT_FALLBACK; |
| 523 | 521 | ||
| 524 | ret = ttm_bo_vm_reserve(bo, vmf); | 522 | ret = ttm_bo_vm_reserve(bo, vmf); |
| @@ -49,7 +49,7 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) · 48 unmodified lines | |||
| 49 | vma->vm_ops = &vmw_vm_ops; | 49 | vma->vm_ops = &vmw_vm_ops; |
| 50 | 50 | ||
| 51 | /* Use VM_PFNMAP rather than VM_MIXEDMAP if not a COW mapping */ | 51 | /* Use VM_PFNMAP rather than VM_MIXEDMAP if not a COW mapping */ |
| 52 | if ((vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) != VM_MAYWRITE) | 52 | if (!is_cow_mapping(vma->vm_flags)) |
| 53 | vma->vm_flags = (vma->vm_flags & ~VM_MIXEDMAP) | VM_PFNMAP; | 53 | vma->vm_flags = (vma->vm_flags & ~VM_MIXEDMAP) | VM_PFNMAP; |
| 54 | 54 | ||
| 55 | return 0; | 55 | return 0; |
| @@ -266,6 +266,8 @@ config ADI_AXI_ADC · 265 unmodified lines | |||
| 266 | select IIO_BUFFER | 266 | select IIO_BUFFER |
| 267 | select IIO_BUFFER_HW_CONSUMER | 267 | select IIO_BUFFER_HW_CONSUMER |
| 268 | select IIO_BUFFER_DMAENGINE | 268 | select IIO_BUFFER_DMAENGINE |
| 269 | depends on HAS_IOMEM | ||
| 270 | depends on OF | ||
| 269 | help | 271 | help |
| 270 | Say yes here to build support for Analog Devices Generic | 272 | Say yes here to build support for Analog Devices Generic |
| 271 | AXI ADC IP core. The IP core is used for interfacing with | 273 | AXI ADC IP core. The IP core is used for interfacing with |
| @@ -923,6 +925,7 @@ config STM32_ADC_CORE · 651 unmodified lines | |||
| 923 | depends on ARCH_STM32 || COMPILE_TEST | 925 | depends on ARCH_STM32 || COMPILE_TEST |
| 924 | depends on OF | 926 | depends on OF |
| 925 | depends on REGULATOR | 927 | depends on REGULATOR |
| 928 | depends on HAS_IOMEM | ||
| 926 | select IIO_BUFFER | 929 | select IIO_BUFFER |
| 927 | select MFD_STM32_TIMERS | 930 | select MFD_STM32_TIMERS |
| 928 | select IIO_STM32_TIMER_TRIGGER | 931 | select IIO_STM32_TIMER_TRIGGER |
| @@ -918,7 +918,7 @@ static int ab8500_gpadc_read_raw(struct iio_dev *indio_dev, · 917 unmodified lines | |||
| 918 | return processed; | 918 | return processed; |
| 919 | 919 | ||
| 920 | /* Return millivolt or milliamps or millicentigrades */ | 920 | /* Return millivolt or milliamps or millicentigrades */ |
| 921 | *val = processed * 1000; | 921 | *val = processed; |
| 922 | return IIO_VAL_INT; | 922 | return IIO_VAL_INT; |
| 923 | } | 923 | } |
| 924 | 924 | ||
| @@ -91,7 +91,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val, · 90 unmodified lines | |||
| 91 | int ret; | 91 | int ret; |
| 92 | int i; | 92 | int i; |
| 93 | int bits_per_word = ad7949_adc->resolution; | 93 | int bits_per_word = ad7949_adc->resolution; |
| 94 | int mask = GENMASK(ad7949_adc->resolution, 0); | 94 | int mask = GENMASK(ad7949_adc->resolution - 1, 0); |
| 95 | struct spi_message msg; | 95 | struct spi_message msg; |
| 96 | struct spi_transfer tx[] = { | 96 | struct spi_transfer tx[] = { |
| 97 | { | 97 | { |
| @@ -597,7 +597,7 @@ static const struct vadc_channels vadc_chans[] = { · 596 unmodified lines | |||
| 597 | VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1) | 597 | VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1) |
| 598 | 598 | ||
| 599 | VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0) | 599 | VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0) |
| 600 | VADC_CHAN_NO_SCALE(LR_MUX2_BAT_ID, 0) | 600 | VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0, SCALE_DEFAULT) |
| 601 | VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0) | 601 | VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0) |
| 602 | VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0) | 602 | VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0) |
| 603 | VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0) | 603 | VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0) |
| @@ -551,6 +551,8 @@ static irqreturn_t mpu3050_trigger_handler(int irq, void *p) · 550 unmodified lines | |||
| 551 | MPU3050_FIFO_R, | 551 | MPU3050_FIFO_R, |
| 552 | &fifo_values[offset], | 552 | &fifo_values[offset], |
| 553 | toread); | 553 | toread); |
| 554 | if (ret) | ||
| 555 | goto out_trigger_unlock; | ||
| 554 | 556 | ||
| 555 | dev_dbg(mpu3050->dev, | 557 | dev_dbg(mpu3050->dev, |
| 556 | "%04x %04x %04x %04x %04x\n", | 558 | "%04x %04x %04x %04x %04x\n", |
| @@ -15,7 +15,10 @@ · 14 unmodified lines | |||
| 15 | struct hid_humidity_state { | 15 | struct hid_humidity_state { |
| 16 | struct hid_sensor_common common_attributes; | 16 | struct hid_sensor_common common_attributes; |
| 17 | struct hid_sensor_hub_attribute_info humidity_attr; | 17 | struct hid_sensor_hub_attribute_info humidity_attr; |
| 18 | s32 humidity_data; | 18 | struct { |
| 19 | s32 humidity_data; | ||
| 20 | u64 timestamp __aligned(8); | ||
| 21 | } scan; | ||
| 19 | int scale_pre_decml; | 22 | int scale_pre_decml; |
| 20 | int scale_post_decml; | 23 | int scale_post_decml; |
| 21 | int scale_precision; | 24 | int scale_precision; |
| @@ -125,9 +128,8 @@ static int humidity_proc_event(struct hid_sensor_hub_device *hsdev, · 103 unmodified lines | |||
| 125 | struct hid_humidity_state *humid_st = iio_priv(indio_dev); | 128 | struct hid_humidity_state *humid_st = iio_priv(indio_dev); |
| 126 | 129 | ||
| 127 | if (atomic_read(&humid_st->common_attributes.data_ready)) | 130 | if (atomic_read(&humid_st->common_attributes.data_ready)) |
| 128 | iio_push_to_buffers_with_timestamp(indio_dev, | 131 | iio_push_to_buffers_with_timestamp(indio_dev, &humid_st->scan, |
| 129 | &humid_st->humidity_data, | 132 | iio_get_time_ns(indio_dev)); |
| 130 | iio_get_time_ns(indio_dev)); | ||
| 131 | 133 | ||
| 132 | return 0; | 134 | return 0; |
| 133 | } | 135 | } |
| @@ -142,7 +144,7 @@ static int humidity_capture_sample(struct hid_sensor_hub_device *hsdev, · 8 unmodified lines | |||
| 142 | 144 | ||
| 143 | switch (usage_id) { | 145 | switch (usage_id) { |
| 144 | case HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY: | 146 | case HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY: |
| 145 | humid_st->humidity_data = *(s32 *)raw_data; | 147 | humid_st->scan.humidity_data = *(s32 *)raw_data; |
| 146 | 148 | ||
| 147 | return 0; | 149 | return 0; |
| 148 | default: | 150 | default: |
| @@ -462,8 +462,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) · 461 unmodified lines | |||
| 462 | if (ret) | 462 | if (ret) |
| 463 | goto err_ret; | 463 | goto err_ret; |
| 464 | 464 | ||
| 465 | ret = sscanf(indio_dev->name, "adis%u\n", &device_id); | 465 | if (sscanf(indio_dev->name, "adis%u\n", &device_id) != 1) { |
| 466 | if (ret != 1) { | ||
| 467 | ret = -EINVAL; | 466 | ret = -EINVAL; |
| 468 | goto err_ret; | 467 | goto err_ret; |
| 469 | } | 468 | } |
| @@ -23,6 +23,9 @@ struct prox_state { · 22 unmodified lines | |||
| 23 | struct hid_sensor_common common_attributes; | 23 | struct hid_sensor_common common_attributes; |
| 24 | struct hid_sensor_hub_attribute_info prox_attr; | 24 | struct hid_sensor_hub_attribute_info prox_attr; |
| 25 | u32 human_presence; | 25 | u32 human_presence; |
| 26 | int scale_pre_decml; | ||
| 27 | int scale_post_decml; | ||
| 28 | int scale_precision; | ||
| 26 | }; | 29 | }; |
| 27 | 30 | ||
| 28 | /* Channel definitions */ | 31 | /* Channel definitions */ |
| @@ -93,8 +96,9 @@ static int prox_read_raw(struct iio_dev *indio_dev, · 64 unmodified lines | |||
| 93 | ret_type = IIO_VAL_INT; | 96 | ret_type = IIO_VAL_INT; |
| 94 | break; | 97 | break; |
| 95 | case IIO_CHAN_INFO_SCALE: | 98 | case IIO_CHAN_INFO_SCALE: |
| 96 | *val = prox_state->prox_attr.units; | 99 | *val = prox_state->scale_pre_decml; |
| 97 | ret_type = IIO_VAL_INT; | 100 | *val2 = prox_state->scale_post_decml; |
| 101 | ret_type = prox_state->scale_precision; | ||
| 98 | break; | 102 | break; |
| 99 | case IIO_CHAN_INFO_OFFSET: | 103 | case IIO_CHAN_INFO_OFFSET: |
| 100 | *val = hid_sensor_convert_exponent( | 104 | *val = hid_sensor_convert_exponent( |
| @@ -234,6 +238,11 @@ static int prox_parse_report(struct platform_device *pdev, · 133 unmodified lines | |||
| 234 | HID_USAGE_SENSOR_HUMAN_PRESENCE, | 238 | HID_USAGE_SENSOR_HUMAN_PRESENCE, |
| 235 | &st->common_attributes.sensitivity); | 239 | &st->common_attributes.sensitivity); |
| 236 | 240 | ||
| 241 | st->scale_precision = hid_sensor_format_scale( | ||
| 242 | hsdev->usage, | ||
| 243 | &st->prox_attr, | ||
| 244 | &st->scale_pre_decml, &st->scale_post_decml); | ||
| 245 | |||
| 237 | return ret; | 246 | return ret; |
| 238 | } | 247 | } |
| 239 | 248 | ||
| @@ -15,7 +15,10 @@ · 14 unmodified lines | |||
| 15 | struct temperature_state { | 15 | struct temperature_state { |
| 16 | struct hid_sensor_common common_attributes; | 16 | struct hid_sensor_common common_attributes; |
| 17 | struct hid_sensor_hub_attribute_info temperature_attr; | 17 | struct hid_sensor_hub_attribute_info temperature_attr; |
| 18 | s32 temperature_data; | 18 | struct { |
| 19 | s32 temperature_data; | ||
| 20 | u64 timestamp __aligned(8); | ||
| 21 | } scan; | ||
| 19 | int scale_pre_decml; | 22 | int scale_pre_decml; |
| 20 | int scale_post_decml; | 23 | int scale_post_decml; |
| 21 | int scale_precision; | 24 | int scale_precision; |
| @@ -32,7 +35,7 @@ static const struct iio_chan_spec temperature_channels[] = { · 10 unmodified lines | |||
| 32 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | | 35 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | |
| 33 | BIT(IIO_CHAN_INFO_HYSTERESIS), | 36 | BIT(IIO_CHAN_INFO_HYSTERESIS), |
| 34 | }, | 37 | }, |
| 35 | IIO_CHAN_SOFT_TIMESTAMP(3), | 38 | IIO_CHAN_SOFT_TIMESTAMP(1), |
| 36 | }; | 39 | }; |
| 37 | 40 | ||
| 38 | /* Adjust channel real bits based on report descriptor */ | 41 | /* Adjust channel real bits based on report descriptor */ |
| @@ -123,9 +126,8 @@ static int temperature_proc_event(struct hid_sensor_hub_device *hsdev, · 84 unmodified lines | |||
| 123 | struct temperature_state *temp_st = iio_priv(indio_dev); | 126 | struct temperature_state *temp_st = iio_priv(indio_dev); |
| 124 | 127 | ||
| 125 | if (atomic_read(&temp_st->common_attributes.data_ready)) | 128 | if (atomic_read(&temp_st->common_attributes.data_ready)) |
| 126 | iio_push_to_buffers_with_timestamp(indio_dev, | 129 | iio_push_to_buffers_with_timestamp(indio_dev, &temp_st->scan, |
| 127 | &temp_st->temperature_data, | 130 | iio_get_time_ns(indio_dev)); |
| 128 | iio_get_time_ns(indio_dev)); | ||
| 129 | 131 | ||
| 130 | return 0; | 132 | return 0; |
| 131 | } | 133 | } |
| @@ -140,7 +142,7 @@ static int temperature_capture_sample(struct hid_sensor_hub_device *hsdev, · 8 unmodified lines | |||
| 140 | 142 | ||
| 141 | switch (usage_id) { | 143 | switch (usage_id) { |
| 142 | case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE: | 144 | case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE: |
| 143 | temp_st->temperature_data = *(s32 *)raw_data; | 145 | temp_st->scan.temperature_data = *(s32 *)raw_data; |
| 144 | return 0; | 146 | return 0; |
| 145 | default: | 147 | default: |
| 146 | return -EINVAL; | 148 | return -EINVAL; |
| @@ -3610,13 +3610,13 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) · 3609 unmodified lines | |||
| 3610 | ep->com.local_addr.ss_family == AF_INET) { | 3610 | ep->com.local_addr.ss_family == AF_INET) { |
| 3611 | err = cxgb4_remove_server_filter( | 3611 | err = cxgb4_remove_server_filter( |
| 3612 | ep->com.dev->rdev.lldi.ports[0], ep->stid, | 3612 | ep->com.dev->rdev.lldi.ports[0], ep->stid, |
| 3613 | ep->com.dev->rdev.lldi.rxq_ids[0], 0); | 3613 | ep->com.dev->rdev.lldi.rxq_ids[0], false); |
| 3614 | } else { | 3614 | } else { |
| 3615 | struct sockaddr_in6 *sin6; | 3615 | struct sockaddr_in6 *sin6; |
| 3616 | c4iw_init_wr_wait(ep->com.wr_waitp); | 3616 | c4iw_init_wr_wait(ep->com.wr_waitp); |
| 3617 | err = cxgb4_remove_server( | 3617 | err = cxgb4_remove_server( |
| 3618 | ep->com.dev->rdev.lldi.ports[0], ep->stid, | 3618 | ep->com.dev->rdev.lldi.ports[0], ep->stid, |
| 3619 | ep->com.dev->rdev.lldi.rxq_ids[0], 0); | 3619 | ep->com.dev->rdev.lldi.rxq_ids[0], true); |
| 3620 | if (err) | 3620 | if (err) |
| 3621 | goto done; | 3621 | goto done; |
| 3622 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, ep->com.wr_waitp, | 3622 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, ep->com.wr_waitp, |
| @@ -1194,8 +1194,10 @@ static void hns_roce_cmq_init_regs(struct hns_roce_dev *hr_dev, bool ring_type) · 1193 unmodified lines | |||
| 1194 | upper_32_bits(dma)); | 1194 | upper_32_bits(dma)); |
| 1195 | roce_write(hr_dev, ROCEE_TX_CMQ_DEPTH_REG, | 1195 | roce_write(hr_dev, ROCEE_TX_CMQ_DEPTH_REG, |
| 1196 | (u32)ring->desc_num >> HNS_ROCE_CMQ_DESC_NUM_S); | 1196 | (u32)ring->desc_num >> HNS_ROCE_CMQ_DESC_NUM_S); |
| 1197 | roce_write(hr_dev, ROCEE_TX_CMQ_HEAD_REG, 0); | 1197 | |
| 1198 | /* Make sure to write tail first and then head */ | ||
| 1198 | roce_write(hr_dev, ROCEE_TX_CMQ_TAIL_REG, 0); | 1199 | roce_write(hr_dev, ROCEE_TX_CMQ_TAIL_REG, 0); |
| 1200 | roce_write(hr_dev, ROCEE_TX_CMQ_HEAD_REG, 0); | ||
| 1199 | } else { | 1201 | } else { |
| 1200 | roce_write(hr_dev, ROCEE_RX_CMQ_BASEADDR_L_REG, (u32)dma); | 1202 | roce_write(hr_dev, ROCEE_RX_CMQ_BASEADDR_L_REG, (u32)dma); |
| 1201 | roce_write(hr_dev, ROCEE_RX_CMQ_BASEADDR_H_REG, | 1203 | roce_write(hr_dev, ROCEE_RX_CMQ_BASEADDR_H_REG, |
| @@ -1116,7 +1116,7 @@ static void devx_obj_build_destroy_cmd(void *in, void *out, void *din, · 1115 unmodified lines | |||
| 1116 | case MLX5_CMD_OP_CREATE_MKEY: | 1116 | case MLX5_CMD_OP_CREATE_MKEY: |
| 1117 | MLX5_SET(destroy_mkey_in, din, opcode, | 1117 | MLX5_SET(destroy_mkey_in, din, opcode, |
| 1118 | MLX5_CMD_OP_DESTROY_MKEY); | 1118 | MLX5_CMD_OP_DESTROY_MKEY); |
| 1119 | MLX5_SET(destroy_mkey_in, in, mkey_index, *obj_id); | 1119 | MLX5_SET(destroy_mkey_in, din, mkey_index, *obj_id); |
| 1120 | break; | 1120 | break; |
| 1121 | case MLX5_CMD_OP_CREATE_CQ: | 1121 | case MLX5_CMD_OP_CREATE_CQ: |
| 1122 | MLX5_SET(destroy_cq_in, din, opcode, MLX5_CMD_OP_DESTROY_CQ); | 1122 | MLX5_SET(destroy_cq_in, din, opcode, MLX5_CMD_OP_DESTROY_CQ); |
| @@ -1078,7 +1078,7 @@ static int _create_kernel_qp(struct mlx5_ib_dev *dev, · 1077 unmodified lines | |||
| 1078 | 1078 | ||
| 1079 | qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc); | 1079 | qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc); |
| 1080 | MLX5_SET(qpc, qpc, uar_page, uar_index); | 1080 | MLX5_SET(qpc, qpc, uar_page, uar_index); |
| 1081 | MLX5_SET(qpc, qpc, ts_format, MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT); | 1081 | MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(dev->mdev)); |
| 1082 | MLX5_SET(qpc, qpc, log_page_size, qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT); | 1082 | MLX5_SET(qpc, qpc, log_page_size, qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT); |
| 1083 | 1083 | ||
| 1084 | /* Set "fast registration enabled" for all kernel QPs */ | 1084 | /* Set "fast registration enabled" for all kernel QPs */ |
| @@ -1188,7 +1188,8 @@ static int get_rq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq) · 103 unmodified lines | |||
| 1188 | } | 1188 | } |
| 1189 | return MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING; | 1189 | return MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING; |
| 1190 | } | 1190 | } |
| 1191 | return MLX5_RQC_TIMESTAMP_FORMAT_DEFAULT; | 1191 | return fr_supported ? MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING : |
| 1192 | MLX5_RQC_TIMESTAMP_FORMAT_DEFAULT; | ||
| 1192 | } | 1193 | } |
| 1193 | 1194 | ||
| 1194 | static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq) | 1195 | static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq) |
| @@ -1206,7 +1207,8 @@ static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq) · 11 unmodified lines | |||
| 1206 | } | 1207 | } |
| 1207 | return MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING; | 1208 | return MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING; |
| 1208 | } | 1209 | } |
| 1209 | return MLX5_SQC_TIMESTAMP_FORMAT_DEFAULT; | 1210 | return fr_supported ? MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING : |
| 1211 | MLX5_SQC_TIMESTAMP_FORMAT_DEFAULT; | ||
| 1210 | } | 1212 | } |
| 1211 | 1213 | ||
| 1212 | static int get_qp_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq, | 1214 | static int get_qp_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq, |
| @@ -1217,7 +1219,8 @@ static int get_qp_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq, · 4 unmodified lines | |||
| 1217 | MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING || | 1219 | MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING || |
| 1218 | MLX5_CAP_ROCE(dev->mdev, qp_ts_format) == | 1220 | MLX5_CAP_ROCE(dev->mdev, qp_ts_format) == |
| 1219 | MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME; | 1221 | MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME; |
| 1220 | int ts_format = MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT; | 1222 | int ts_format = fr_supported ? MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING : |
| 1223 | MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT; | ||
| 1221 | 1224 | ||
| 1222 | if (recv_cq && | 1225 | if (recv_cq && |
| 1223 | recv_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) | 1226 | recv_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) |
| @@ -1930,6 +1933,7 @@ static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 706 unmodified lines | |||
| 1930 | if (qp->flags & IB_QP_CREATE_MANAGED_RECV) | 1933 | if (qp->flags & IB_QP_CREATE_MANAGED_RECV) |
| 1931 | MLX5_SET(qpc, qpc, cd_slave_receive, 1); | 1934 | MLX5_SET(qpc, qpc, cd_slave_receive, 1); |
| 1932 | 1935 | ||
| 1936 | MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(dev->mdev)); | ||
| 1933 | MLX5_SET(qpc, qpc, rq_type, MLX5_SRQ_RQ); | 1937 | MLX5_SET(qpc, qpc, rq_type, MLX5_SRQ_RQ); |
| 1934 | MLX5_SET(qpc, qpc, no_sq, 1); | 1938 | MLX5_SET(qpc, qpc, no_sq, 1); |
| 1935 | MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn); | 1939 | MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn); |
| @@ -4873,6 +4877,7 @@ static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd, · 2937 unmodified lines | |||
| 4873 | struct mlx5_ib_dev *dev; | 4877 | struct mlx5_ib_dev *dev; |
| 4874 | int has_net_offloads; | 4878 | int has_net_offloads; |
| 4875 | __be64 *rq_pas0; | 4879 | __be64 *rq_pas0; |
| 4880 | int ts_format; | ||
| 4876 | void *in; | 4881 | void *in; |
| 4877 | void *rqc; | 4882 | void *rqc; |
| 4878 | void *wq; | 4883 | void *wq; |
| @@ -4881,6 +4886,10 @@ static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd, · 2 unmodified lines | |||
| 4881 | 4886 | ||
| 4882 | dev = to_mdev(pd->device); | 4887 | dev = to_mdev(pd->device); |
| 4883 | 4888 | ||
| 4889 | ts_format = get_rq_ts_format(dev, to_mcq(init_attr->cq)); | ||
| 4890 | if (ts_format < 0) | ||
| 4891 | return ts_format; | ||
| 4892 | |||
| 4884 | inlen = MLX5_ST_SZ_BYTES(create_rq_in) + sizeof(u64) * rwq->rq_num_pas; | 4893 | inlen = MLX5_ST_SZ_BYTES(create_rq_in) + sizeof(u64) * rwq->rq_num_pas; |
| 4885 | in = kvzalloc(inlen, GFP_KERNEL); | 4894 | in = kvzalloc(inlen, GFP_KERNEL); |
| 4886 | if (!in) | 4895 | if (!in) |
| @@ -4890,6 +4899,7 @@ static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd, · 3 unmodified lines | |||
| 4890 | rqc = MLX5_ADDR_OF(create_rq_in, in, ctx); | 4899 | rqc = MLX5_ADDR_OF(create_rq_in, in, ctx); |
| 4891 | MLX5_SET(rqc, rqc, mem_rq_type, | 4900 | MLX5_SET(rqc, rqc, mem_rq_type, |
| 4892 | MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE); | 4901 | MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE); |
| 4902 | MLX5_SET(rqc, rqc, ts_format, ts_format); | ||
| 4893 | MLX5_SET(rqc, rqc, user_index, rwq->user_index); | 4903 | MLX5_SET(rqc, rqc, user_index, rwq->user_index); |
| 4894 | MLX5_SET(rqc, rqc, cqn, to_mcq(init_attr->cq)->mcq.cqn); | 4904 | MLX5_SET(rqc, rqc, cqn, to_mcq(init_attr->cq)->mcq.cqn); |
| 4895 | MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST); | 4905 | MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST); |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 27 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
| 28 | MODULE_DESCRIPTION("Joystick device interfaces"); | 28 | MODULE_DESCRIPTION("Joystick device interfaces"); |
| 29 | MODULE_SUPPORTED_DEVICE("input/js"); | ||
| 30 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
| 31 | 30 | ||
| 32 | #define JOYDEV_MINOR_BASE 0 | 31 | #define JOYDEV_MINOR_BASE 0 |
| @@ -2714,7 +2714,6 @@ static int __init early_amd_iommu_init(void) · 2713 unmodified lines | |||
| 2714 | struct acpi_table_header *ivrs_base; | 2714 | struct acpi_table_header *ivrs_base; |
| 2715 | int i, remap_cache_sz, ret; | 2715 | int i, remap_cache_sz, ret; |
| 2716 | acpi_status status; | 2716 | acpi_status status; |
| 2717 | u32 pci_id; | ||
| 2718 | 2717 | ||
| 2719 | if (!amd_iommu_detected) | 2718 | if (!amd_iommu_detected) |
| 2720 | return -ENODEV; | 2719 | return -ENODEV; |
| @@ -2804,16 +2803,6 @@ static int __init early_amd_iommu_init(void) · 83 unmodified lines | |||
| 2804 | if (ret) | 2803 | if (ret) |
| 2805 | goto out; | 2804 | goto out; |
| 2806 | 2805 | ||
| 2807 | /* Disable IOMMU if there's Stoney Ridge graphics */ | ||
| 2808 | for (i = 0; i < 32; i++) { | ||
| 2809 | pci_id = read_pci_config(0, i, 0, 0); | ||
| 2810 | if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) { | ||
| 2811 | pr_info("Disable IOMMU on Stoney Ridge\n"); | ||
| 2812 | amd_iommu_disabled = true; | ||
| 2813 | break; | ||
| 2814 | } | ||
| 2815 | } | ||
| 2816 | |||
| 2817 | /* Disable any previously enabled IOMMUs */ | 2806 | /* Disable any previously enabled IOMMUs */ |
| 2818 | if (!is_kdump_kernel() || amd_iommu_disabled) | 2807 | if (!is_kdump_kernel() || amd_iommu_disabled) |
| 2819 | disable_iommus(); | 2808 | disable_iommus(); |
| @@ -2880,6 +2869,7 @@ static bool detect_ivrs(void) · 60 unmodified lines | |||
| 2880 | { | 2869 | { |
| 2881 | struct acpi_table_header *ivrs_base; | 2870 | struct acpi_table_header *ivrs_base; |
| 2882 | acpi_status status; | 2871 | acpi_status status; |
| 2872 | int i; | ||
| 2883 | 2873 | ||
| 2884 | status = acpi_get_table("IVRS", 0, &ivrs_base); | 2874 | status = acpi_get_table("IVRS", 0, &ivrs_base); |
| 2885 | if (status == AE_NOT_FOUND) | 2875 | if (status == AE_NOT_FOUND) |
| @@ -2892,6 +2882,17 @@ static bool detect_ivrs(void) · 6 unmodified lines | |||
| 2892 | 2882 | ||
| 2893 | acpi_put_table(ivrs_base); | 2883 | acpi_put_table(ivrs_base); |
| 2894 | 2884 | ||
| 2885 | /* Don't use IOMMU if there is Stoney Ridge graphics */ | ||
| 2886 | for (i = 0; i < 32; i++) { | ||
| 2887 | u32 pci_id; | ||
| 2888 | |||
| 2889 | pci_id = read_pci_config(0, i, 0, 0); | ||
| 2890 | if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) { | ||
| 2891 | pr_info("Disable IOMMU on Stoney Ridge\n"); | ||
| 2892 | return false; | ||
| 2893 | } | ||
| 2894 | } | ||
| 2895 | |||
| 2895 | /* Make sure ACS will be enabled during PCI probe */ | 2896 | /* Make sure ACS will be enabled during PCI probe */ |
| 2896 | pci_request_acs(); | 2897 | pci_request_acs(); |
| 2897 | 2898 | ||
| @@ -2918,12 +2919,12 @@ static int __init state_next(void) · 20 unmodified lines | |||
| 2918 | } | 2919 | } |
| 2919 | break; | 2920 | break; |
| 2920 | case IOMMU_IVRS_DETECTED: | 2921 | case IOMMU_IVRS_DETECTED: |
| 2921 | ret = early_amd_iommu_init(); | 2922 | if (amd_iommu_disabled) { |
| 2922 | init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED; | ||
| 2923 | if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) { | ||
| 2924 | pr_info("AMD IOMMU disabled\n"); | ||
| 2925 | init_state = IOMMU_CMDLINE_DISABLED; | 2923 | init_state = IOMMU_CMDLINE_DISABLED; |
| 2926 | ret = -EINVAL; | 2924 | ret = -EINVAL; |
| 2925 | } else { | ||
| 2926 | ret = early_amd_iommu_init(); | ||
| 2927 | init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED; | ||
| 2927 | } | 2928 | } |
| 2928 | break; | 2929 | break; |
| 2929 | case IOMMU_ACPI_FINISHED: | 2930 | case IOMMU_ACPI_FINISHED: |
| @@ -3001,8 +3002,11 @@ int __init amd_iommu_prepare(void) · 71 unmodified lines | |||
| 3001 | amd_iommu_irq_remap = true; | 3002 | amd_iommu_irq_remap = true; |
| 3002 | 3003 | ||
| 3003 | ret = iommu_go_to_state(IOMMU_ACPI_FINISHED); | 3004 | ret = iommu_go_to_state(IOMMU_ACPI_FINISHED); |
| 3004 | if (ret) | 3005 | if (ret) { |
| 3006 | amd_iommu_irq_remap = false; | ||
| 3005 | return ret; | 3007 | return ret; |
| 3008 | } | ||
| 3009 | |||
| 3006 | return amd_iommu_irq_remap ? 0 : -ENODEV; | 3010 | return amd_iommu_irq_remap ? 0 : -ENODEV; |
| 3007 | } | 3011 | } |
| 3008 | 3012 | ||
| @@ -849,12 +849,11 @@ static struct iommu_device *tegra_smmu_probe_device(struct device *dev) · 848 unmodified lines | |||
| 849 | smmu = tegra_smmu_find(args.np); | 849 | smmu = tegra_smmu_find(args.np); |
| 850 | if (smmu) { | 850 | if (smmu) { |
| 851 | err = tegra_smmu_configure(smmu, dev, &args); | 851 | err = tegra_smmu_configure(smmu, dev, &args); |
| 852 | of_node_put(args.np); | ||
| 853 | 852 | ||
| 854 | if (err < 0) | 853 | if (err < 0) { |
| 854 | of_node_put(args.np); | ||
| 855 | return ERR_PTR(err); | 855 | return ERR_PTR(err); |
| 856 | 856 | } | |
| 857 | break; | ||
| 858 | } | 857 | } |
| 859 | 858 | ||
| 860 | of_node_put(args.np); | 859 | of_node_put(args.np); |
| @@ -8,7 +8,6 @@ config IRQCHIP · 7 unmodified lines | |||
| 8 | config ARM_GIC | 8 | config ARM_GIC |
| 9 | bool | 9 | bool |
| 10 | select IRQ_DOMAIN_HIERARCHY | 10 | select IRQ_DOMAIN_HIERARCHY |
| 11 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 12 | select GENERIC_IRQ_EFFECTIVE_AFF_MASK | 11 | select GENERIC_IRQ_EFFECTIVE_AFF_MASK |
| 13 | 12 | ||
| 14 | config ARM_GIC_PM | 13 | config ARM_GIC_PM |
| @@ -33,7 +32,6 @@ config GIC_NON_BANKED · 18 unmodified lines | |||
| 33 | 32 | ||
| 34 | config ARM_GIC_V3 | 33 | config ARM_GIC_V3 |
| 35 | bool | 34 | bool |
| 36 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 37 | select IRQ_DOMAIN_HIERARCHY | 35 | select IRQ_DOMAIN_HIERARCHY |
| 38 | select PARTITION_PERCPU | 36 | select PARTITION_PERCPU |
| 39 | select GENERIC_IRQ_EFFECTIVE_AFF_MASK | 37 | select GENERIC_IRQ_EFFECTIVE_AFF_MASK |
| @@ -64,7 +62,6 @@ config ARM_NVIC · 24 unmodified lines | |||
| 64 | config ARM_VIC | 62 | config ARM_VIC |
| 65 | bool | 63 | bool |
| 66 | select IRQ_DOMAIN | 64 | select IRQ_DOMAIN |
| 67 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 68 | 65 | ||
| 69 | config ARM_VIC_NR | 66 | config ARM_VIC_NR |
| 70 | int | 67 | int |
| @@ -99,14 +96,12 @@ config ATMEL_AIC_IRQ · 28 unmodified lines | |||
| 99 | bool | 96 | bool |
| 100 | select GENERIC_IRQ_CHIP | 97 | select GENERIC_IRQ_CHIP |
| 101 | select IRQ_DOMAIN | 98 | select IRQ_DOMAIN |
| 102 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 103 | select SPARSE_IRQ | 99 | select SPARSE_IRQ |
| 104 | 100 | ||
| 105 | config ATMEL_AIC5_IRQ | 101 | config ATMEL_AIC5_IRQ |
| 106 | bool | 102 | bool |
| 107 | select GENERIC_IRQ_CHIP | 103 | select GENERIC_IRQ_CHIP |
| 108 | select IRQ_DOMAIN | 104 | select IRQ_DOMAIN |
| 109 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 110 | select SPARSE_IRQ | 105 | select SPARSE_IRQ |
| 111 | 106 | ||
| 112 | config I8259 | 107 | config I8259 |
| @@ -153,7 +148,6 @@ config DW_APB_ICTL · 40 unmodified lines | |||
| 153 | config FARADAY_FTINTC010 | 148 | config FARADAY_FTINTC010 |
| 154 | bool | 149 | bool |
| 155 | select IRQ_DOMAIN | 150 | select IRQ_DOMAIN |
| 156 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 157 | select SPARSE_IRQ | 151 | select SPARSE_IRQ |
| 158 | 152 | ||
| 159 | config HISILICON_IRQ_MBIGEN | 153 | config HISILICON_IRQ_MBIGEN |
| @@ -169,7 +163,6 @@ config IMGPDC_IRQ · 9 unmodified lines | |||
| 169 | config IXP4XX_IRQ | 163 | config IXP4XX_IRQ |
| 170 | bool | 164 | bool |
| 171 | select IRQ_DOMAIN | 165 | select IRQ_DOMAIN |
| 172 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 173 | select SPARSE_IRQ | 166 | select SPARSE_IRQ |
| 174 | 167 | ||
| 175 | config MADERA_IRQ | 168 | config MADERA_IRQ |
| @@ -186,7 +179,6 @@ config CLPS711X_IRQCHIP · 10 unmodified lines | |||
| 186 | bool | 179 | bool |
| 187 | depends on ARCH_CLPS711X | 180 | depends on ARCH_CLPS711X |
| 188 | select IRQ_DOMAIN | 181 | select IRQ_DOMAIN |
| 189 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 190 | select SPARSE_IRQ | 182 | select SPARSE_IRQ |
| 191 | default y | 183 | default y |
| 192 | 184 | ||
| @@ -205,7 +197,6 @@ config OMAP_IRQCHIP · 12 unmodified lines | |||
| 205 | config ORION_IRQCHIP | 197 | config ORION_IRQCHIP |
| 206 | bool | 198 | bool |
| 207 | select IRQ_DOMAIN | 199 | select IRQ_DOMAIN |
| 208 | select GENERIC_IRQ_MULTI_HANDLER | ||
| 209 | 200 | ||
| 210 | config PIC32_EVIC | 201 | config PIC32_EVIC |
| 211 | bool | 202 | bool |
| @@ -179,5 +179,6 @@ err_free_tcu: · 178 unmodified lines | |||
| 179 | } | 179 | } |
| 180 | IRQCHIP_DECLARE(jz4740_tcu_irq, "ingenic,jz4740-tcu", ingenic_tcu_irq_init); | 180 | IRQCHIP_DECLARE(jz4740_tcu_irq, "ingenic,jz4740-tcu", ingenic_tcu_irq_init); |
| 181 | IRQCHIP_DECLARE(jz4725b_tcu_irq, "ingenic,jz4725b-tcu", ingenic_tcu_irq_init); | 181 | IRQCHIP_DECLARE(jz4725b_tcu_irq, "ingenic,jz4725b-tcu", ingenic_tcu_irq_init); |
| 182 | IRQCHIP_DECLARE(jz4760_tcu_irq, "ingenic,jz4760-tcu", ingenic_tcu_irq_init); | ||
| 182 | IRQCHIP_DECLARE(jz4770_tcu_irq, "ingenic,jz4770-tcu", ingenic_tcu_irq_init); | 183 | IRQCHIP_DECLARE(jz4770_tcu_irq, "ingenic,jz4770-tcu", ingenic_tcu_irq_init); |
| 183 | IRQCHIP_DECLARE(x1000_tcu_irq, "ingenic,x1000-tcu", ingenic_tcu_irq_init); | 184 | IRQCHIP_DECLARE(x1000_tcu_irq, "ingenic,x1000-tcu", ingenic_tcu_irq_init); |
| @@ -155,6 +155,7 @@ static int __init intc_2chip_of_init(struct device_node *node, · 154 unmodified lines | |||
| 155 | { | 155 | { |
| 156 | return ingenic_intc_of_init(node, 2); | 156 | return ingenic_intc_of_init(node, 2); |
| 157 | } | 157 | } |
| 158 | IRQCHIP_DECLARE(jz4760_intc, "ingenic,jz4760-intc", intc_2chip_of_init); | ||
| 158 | IRQCHIP_DECLARE(jz4770_intc, "ingenic,jz4770-intc", intc_2chip_of_init); | 159 | IRQCHIP_DECLARE(jz4770_intc, "ingenic,jz4770-intc", intc_2chip_of_init); |
| 159 | IRQCHIP_DECLARE(jz4775_intc, "ingenic,jz4775-intc", intc_2chip_of_init); | 160 | IRQCHIP_DECLARE(jz4775_intc, "ingenic,jz4775-intc", intc_2chip_of_init); |
| 160 | IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", intc_2chip_of_init); | 161 | IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", intc_2chip_of_init); |
| @@ -721,7 +721,7 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) · 720 unmodified lines | |||
| 721 | * Return value: CAPI result code | 721 | * Return value: CAPI result code |
| 722 | */ | 722 | */ |
| 723 | 723 | ||
| 724 | u16 capi20_get_manufacturer(u32 contr, u8 *buf) | 724 | u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) |
| 725 | { | 725 | { |
| 726 | struct capi_ctr *ctr; | 726 | struct capi_ctr *ctr; |
| 727 | u16 ret; | 727 | u16 ret; |
| @@ -787,7 +787,7 @@ u16 capi20_get_version(u32 contr, struct capi_version *verp) · 59 unmodified lines | |||
| 787 | * Return value: CAPI result code | 787 | * Return value: CAPI result code |
| 788 | */ | 788 | */ |
| 789 | 789 | ||
| 790 | u16 capi20_get_serial(u32 contr, u8 *serial) | 790 | u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]) |
| 791 | { | 791 | { |
| 792 | struct capi_ctr *ctr; | 792 | struct capi_ctr *ctr; |
| 793 | u16 ret; | 793 | u16 ret; |
| @@ -694,7 +694,7 @@ isac_release(struct isac_hw *isac) · 693 unmodified lines | |||
| 694 | { | 694 | { |
| 695 | if (isac->type & IPAC_TYPE_ISACX) | 695 | if (isac->type & IPAC_TYPE_ISACX) |
| 696 | WriteISAC(isac, ISACX_MASK, 0xff); | 696 | WriteISAC(isac, ISACX_MASK, 0xff); |
| 697 | else | 697 | else if (isac->type != 0) |
| 698 | WriteISAC(isac, ISAC_MASK, 0xff); | 698 | WriteISAC(isac, ISAC_MASK, 0xff); |
| 699 | if (isac->dch.timer.function != NULL) { | 699 | if (isac->dch.timer.function != NULL) { |
| 700 | del_timer(&isac->dch.timer); | 700 | del_timer(&isac->dch.timer); |
| @@ -51,10 +51,8 @@ static ssize_t ttyname_store(struct device *dev, · 50 unmodified lines | |||
| 51 | 51 | ||
| 52 | if (size) { | 52 | if (size) { |
| 53 | ttyname = kmemdup_nul(buf, size, GFP_KERNEL); | 53 | ttyname = kmemdup_nul(buf, size, GFP_KERNEL); |
| 54 | if (!ttyname) { | 54 | if (!ttyname) |
| 55 | ret = -ENOMEM; | 55 | return -ENOMEM; |
| 56 | goto out_unlock; | ||
| 57 | } | ||
| 58 | } else { | 56 | } else { |
| 59 | ttyname = NULL; | 57 | ttyname = NULL; |
| 60 | } | 58 | } |
| @@ -69,7 +67,6 @@ static ssize_t ttyname_store(struct device *dev, · 8 unmodified lines | |||
| 69 | 67 | ||
| 70 | trigger_data->ttyname = ttyname; | 68 | trigger_data->ttyname = ttyname; |
| 71 | 69 | ||
| 72 | out_unlock: | ||
| 73 | mutex_unlock(&trigger_data->mutex); | 70 | mutex_unlock(&trigger_data->mutex); |
| 74 | 71 | ||
| 75 | if (ttyname && !running) | 72 | if (ttyname && !running) |
| @@ -125,12 +122,12 @@ static void ledtrig_tty_work(struct work_struct *work) · 49 unmodified lines | |||
| 125 | 122 | ||
| 126 | if (icount.rx != trigger_data->rx || | 123 | if (icount.rx != trigger_data->rx || |
| 127 | icount.tx != trigger_data->tx) { | 124 | icount.tx != trigger_data->tx) { |
| 128 | led_set_brightness(trigger_data->led_cdev, LED_ON); | 125 | led_set_brightness_sync(trigger_data->led_cdev, LED_ON); |
| 129 | 126 | ||
| 130 | trigger_data->rx = icount.rx; | 127 | trigger_data->rx = icount.rx; |
| 131 | trigger_data->tx = icount.tx; | 128 | trigger_data->tx = icount.tx; |
| 132 | } else { | 129 | } else { |
| 133 | led_set_brightness(trigger_data->led_cdev, LED_OFF); | 130 | led_set_brightness_sync(trigger_data->led_cdev, LED_OFF); |
| 134 | } | 131 | } |
| 135 | 132 | ||
| 136 | out: | 133 | out: |
| @@ -965,7 +965,7 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, · 964 unmodified lines | |||
| 965 | q->limits.max_hw_sectors = UINT_MAX; | 965 | q->limits.max_hw_sectors = UINT_MAX; |
| 966 | q->limits.max_sectors = UINT_MAX; | 966 | q->limits.max_sectors = UINT_MAX; |
| 967 | q->limits.max_segment_size = UINT_MAX; | 967 | q->limits.max_segment_size = UINT_MAX; |
| 968 | q->limits.max_segments = BIO_MAX_PAGES; | 968 | q->limits.max_segments = BIO_MAX_VECS; |
| 969 | blk_queue_max_discard_sectors(q, UINT_MAX); | 969 | blk_queue_max_discard_sectors(q, UINT_MAX); |
| 970 | q->limits.discard_granularity = 512; | 970 | q->limits.discard_granularity = 512; |
| 971 | q->limits.io_min = block_size; | 971 | q->limits.io_min = block_size; |
| @@ -229,7 +229,7 @@ static DEFINE_SPINLOCK(dm_crypt_clients_lock); · 228 unmodified lines | |||
| 229 | static unsigned dm_crypt_clients_n = 0; | 229 | static unsigned dm_crypt_clients_n = 0; |
| 230 | static volatile unsigned long dm_crypt_pages_per_client; | 230 | static volatile unsigned long dm_crypt_pages_per_client; |
| 231 | #define DM_CRYPT_MEMORY_PERCENT 2 | 231 | #define DM_CRYPT_MEMORY_PERCENT 2 |
| 232 | #define DM_CRYPT_MIN_PAGES_PER_CLIENT (BIO_MAX_PAGES * 16) | 232 | #define DM_CRYPT_MIN_PAGES_PER_CLIENT (BIO_MAX_VECS * 16) |
| 233 | 233 | ||
| 234 | static void clone_init(struct dm_crypt_io *, struct bio *); | 234 | static void clone_init(struct dm_crypt_io *, struct bio *); |
| 235 | static void kcryptd_queue_crypt(struct dm_crypt_io *io); | 235 | static void kcryptd_queue_crypt(struct dm_crypt_io *io); |
| @@ -3246,7 +3246,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 3010 unmodified lines | |||
| 3246 | ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + additional_req_size, | 3246 | ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + additional_req_size, |
| 3247 | ARCH_KMALLOC_MINALIGN); | 3247 | ARCH_KMALLOC_MINALIGN); |
| 3248 | 3248 | ||
| 3249 | ret = mempool_init(&cc->page_pool, BIO_MAX_PAGES, crypt_page_alloc, crypt_page_free, cc); | 3249 | ret = mempool_init(&cc->page_pool, BIO_MAX_VECS, crypt_page_alloc, crypt_page_free, cc); |
| 3250 | if (ret) { | 3250 | if (ret) { |
| 3251 | ti->error = "Cannot allocate page mempool"; | 3251 | ti->error = "Cannot allocate page mempool"; |
| 3252 | goto bad; | 3252 | goto bad; |
| @@ -3373,9 +3373,9 @@ static int crypt_map(struct dm_target *ti, struct bio *bio) · 120 unmodified lines | |||
| 3373 | /* | 3373 | /* |
| 3374 | * Check if bio is too large, split as needed. | 3374 | * Check if bio is too large, split as needed. |
| 3375 | */ | 3375 | */ |
| 3376 | if (unlikely(bio->bi_iter.bi_size > (BIO_MAX_PAGES << PAGE_SHIFT)) && | 3376 | if (unlikely(bio->bi_iter.bi_size > (BIO_MAX_VECS << PAGE_SHIFT)) && |
| 3377 | (bio_data_dir(bio) == WRITE || cc->on_disk_tag_size)) | 3377 | (bio_data_dir(bio) == WRITE || cc->on_disk_tag_size)) |
| 3378 | dm_accept_partial_bio(bio, ((BIO_MAX_PAGES << PAGE_SHIFT) >> SECTOR_SHIFT)); | 3378 | dm_accept_partial_bio(bio, ((BIO_MAX_VECS << PAGE_SHIFT) >> SECTOR_SHIFT)); |
| 3379 | 3379 | ||
| 3380 | /* | 3380 | /* |
| 3381 | * Ensure that bio is a multiple of internal sector encryption size | 3381 | * Ensure that bio is a multiple of internal sector encryption size |
| @@ -1892,10 +1892,10 @@ restart: · 1891 unmodified lines | |||
| 1892 | list_add(&g->lru, &wbl.list); | 1892 | list_add(&g->lru, &wbl.list); |
| 1893 | wbl.size++; | 1893 | wbl.size++; |
| 1894 | g->write_in_progress = true; | 1894 | g->write_in_progress = true; |
| 1895 | g->wc_list_contiguous = BIO_MAX_PAGES; | 1895 | g->wc_list_contiguous = BIO_MAX_VECS; |
| 1896 | f = g; | 1896 | f = g; |
| 1897 | e->wc_list_contiguous++; | 1897 | e->wc_list_contiguous++; |
| 1898 | if (unlikely(e->wc_list_contiguous == BIO_MAX_PAGES)) { | 1898 | if (unlikely(e->wc_list_contiguous == BIO_MAX_VECS)) { |
| 1899 | if (unlikely(wc->writeback_all)) { | 1899 | if (unlikely(wc->writeback_all)) { |
| 1900 | next_node = rb_next(&f->rb_node); | 1900 | next_node = rb_next(&f->rb_node); |
| 1901 | if (likely(next_node)) | 1901 | if (likely(next_node)) |
| @@ -735,7 +735,7 @@ static void r5l_submit_current_io(struct r5l_log *log) · 734 unmodified lines | |||
| 735 | 735 | ||
| 736 | static struct bio *r5l_bio_alloc(struct r5l_log *log) | 736 | static struct bio *r5l_bio_alloc(struct r5l_log *log) |
| 737 | { | 737 | { |
| 738 | struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, &log->bs); | 738 | struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_VECS, &log->bs); |
| 739 | 739 | ||
| 740 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); | 740 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); |
| 741 | bio_set_dev(bio, log->rdev->bdev); | 741 | bio_set_dev(bio, log->rdev->bdev); |
| @@ -1634,7 +1634,7 @@ static int r5l_recovery_allocate_ra_pool(struct r5l_log *log, · 892 unmodified lines | |||
| 1634 | { | 1634 | { |
| 1635 | struct page *page; | 1635 | struct page *page; |
| 1636 | 1636 | ||
| 1637 | ctx->ra_bio = bio_alloc_bioset(GFP_KERNEL, BIO_MAX_PAGES, &log->bs); | 1637 | ctx->ra_bio = bio_alloc_bioset(GFP_KERNEL, BIO_MAX_VECS, &log->bs); |
| 1638 | if (!ctx->ra_bio) | 1638 | if (!ctx->ra_bio) |
| 1639 | return -ENOMEM; | 1639 | return -ENOMEM; |
| 1640 | 1640 | ||
| @@ -496,7 +496,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io) · 495 unmodified lines | |||
| 496 | if (!bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0)) { | 496 | if (!bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0)) { |
| 497 | struct bio *prev = bio; | 497 | struct bio *prev = bio; |
| 498 | 498 | ||
| 499 | bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, | 499 | bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_VECS, |
| 500 | &ppl_conf->bs); | 500 | &ppl_conf->bs); |
| 501 | bio->bi_opf = prev->bi_opf; | 501 | bio->bi_opf = prev->bi_opf; |
| 502 | bio->bi_write_hint = prev->bi_write_hint; | 502 | bio->bi_write_hint = prev->bi_write_hint; |
| @@ -430,4 +430,3 @@ MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); · 429 unmodified lines | |||
| 430 | MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); | 430 | MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); |
| 431 | MODULE_DESCRIPTION("FireDTV DVB Driver"); | 431 | MODULE_DESCRIPTION("FireDTV DVB Driver"); |
| 432 | MODULE_LICENSE("GPL"); | 432 | MODULE_LICENSE("GPL"); |
| 433 | MODULE_SUPPORTED_DEVICE("FireDTV DVB"); | ||
| @@ -41,7 +41,6 @@ MODULE_PARM_DESC(debug, · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | MODULE_AUTHOR("Andy Walls"); | 42 | MODULE_AUTHOR("Andy Walls"); |
| 43 | MODULE_DESCRIPTION("CX23418 ALSA Interface"); | 43 | MODULE_DESCRIPTION("CX23418 ALSA Interface"); |
| 44 | MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder"); | ||
| 45 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
| 46 | 45 | ||
| 47 | MODULE_VERSION(CX18_VERSION); | 46 | MODULE_VERSION(CX18_VERSION); |
| @@ -232,7 +232,6 @@ MODULE_PARM_DESC(cx18_first_minor, · 231 unmodified lines | |||
| 232 | 232 | ||
| 233 | MODULE_AUTHOR("Hans Verkuil"); | 233 | MODULE_AUTHOR("Hans Verkuil"); |
| 234 | MODULE_DESCRIPTION("CX23418 driver"); | 234 | MODULE_DESCRIPTION("CX23418 driver"); |
| 235 | MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder"); | ||
| 236 | MODULE_LICENSE("GPL"); | 235 | MODULE_LICENSE("GPL"); |
| 237 | 236 | ||
| 238 | MODULE_VERSION(CX18_VERSION); | 237 | MODULE_VERSION(CX18_VERSION); |
| @@ -104,7 +104,6 @@ MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s)."); · 103 unmodified lines | |||
| 104 | MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards"); | 104 | MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards"); |
| 105 | MODULE_AUTHOR("Hiep Huynh"); | 105 | MODULE_AUTHOR("Hiep Huynh"); |
| 106 | MODULE_LICENSE("GPL"); | 106 | MODULE_LICENSE("GPL"); |
| 107 | MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); /* "{{Conexant,23881}," */ | ||
| 108 | 107 | ||
| 109 | static unsigned int debug; | 108 | static unsigned int debug; |
| 110 | module_param(debug, int, 0644); | 109 | module_param(debug, int, 0644); |
| @@ -98,7 +98,6 @@ MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); · 97 unmodified lines | |||
| 98 | MODULE_LICENSE("GPL v2"); | 98 | MODULE_LICENSE("GPL v2"); |
| 99 | MODULE_VERSION(CX88_VERSION); | 99 | MODULE_VERSION(CX88_VERSION); |
| 100 | 100 | ||
| 101 | MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}"); | ||
| 102 | static unsigned int debug; | 101 | static unsigned int debug; |
| 103 | module_param(debug, int, 0644); | 102 | module_param(debug, int, 0644); |
| 104 | MODULE_PARM_DESC(debug, "enable debug messages"); | 103 | MODULE_PARM_DESC(debug, "enable debug messages"); |
| @@ -38,7 +38,6 @@ MODULE_PARM_DESC(index, · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | MODULE_AUTHOR("Andy Walls"); | 39 | MODULE_AUTHOR("Andy Walls"); |
| 40 | MODULE_DESCRIPTION("CX23415/CX23416 ALSA Interface"); | 40 | MODULE_DESCRIPTION("CX23415/CX23416 ALSA Interface"); |
| 41 | MODULE_SUPPORTED_DEVICE("CX23415/CX23416 MPEG2 encoder"); | ||
| 42 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
| 43 | 42 | ||
| 44 | MODULE_VERSION(IVTV_VERSION); | 43 | MODULE_VERSION(IVTV_VERSION); |
| @@ -275,9 +275,6 @@ MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first car · 274 unmodified lines | |||
| 275 | 275 | ||
| 276 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); | 276 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); |
| 277 | MODULE_DESCRIPTION("CX23415/CX23416 driver"); | 277 | MODULE_DESCRIPTION("CX23415/CX23416 driver"); |
| 278 | MODULE_SUPPORTED_DEVICE | ||
| 279 | ("CX23415/CX23416 MPEG2 encoder (WinTV PVR-150/250/350/500,\n" | ||
| 280 | "\t\t\tYuan MPG series and similar)"); | ||
| 281 | MODULE_LICENSE("GPL"); | 278 | MODULE_LICENSE("GPL"); |
| 282 | 279 | ||
| 283 | MODULE_VERSION(IVTV_VERSION); | 280 | MODULE_VERSION(IVTV_VERSION); |
| @@ -1269,6 +1269,5 @@ late_initcall_sync(sta2x11_vip_init_module); · 1268 unmodified lines | |||
| 1269 | MODULE_DESCRIPTION("STA2X11 Video Input Port driver"); | 1269 | MODULE_DESCRIPTION("STA2X11 Video Input Port driver"); |
| 1270 | MODULE_AUTHOR("Wind River"); | 1270 | MODULE_AUTHOR("Wind River"); |
| 1271 | MODULE_LICENSE("GPL v2"); | 1271 | MODULE_LICENSE("GPL v2"); |
| 1272 | MODULE_SUPPORTED_DEVICE("sta2x11 video input"); | ||
| 1273 | MODULE_VERSION(DRV_VERSION); | 1272 | MODULE_VERSION(DRV_VERSION); |
| 1274 | MODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl); | 1273 | MODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl); |
| @@ -1363,4 +1363,3 @@ module_platform_driver(atmel_isi_driver); · 1362 unmodified lines | |||
| 1363 | MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>"); | 1363 | MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>"); |
| 1364 | MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux"); | 1364 | MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux"); |
| 1365 | MODULE_LICENSE("GPL"); | 1365 | MODULE_LICENSE("GPL"); |
| 1366 | MODULE_SUPPORTED_DEVICE("video"); | ||
| @@ -330,4 +330,3 @@ module_platform_driver(atmel_isc_driver); · 329 unmodified lines | |||
| 330 | MODULE_AUTHOR("Songjun Wu"); | 330 | MODULE_AUTHOR("Songjun Wu"); |
| 331 | MODULE_DESCRIPTION("The V4L2 driver for Atmel-ISC"); | 331 | MODULE_DESCRIPTION("The V4L2 driver for Atmel-ISC"); |
| 332 | MODULE_LICENSE("GPL v2"); | 332 | MODULE_LICENSE("GPL v2"); |
| 333 | MODULE_SUPPORTED_DEVICE("video"); | ||
| @@ -44,10 +44,6 @@ · 43 unmodified lines | |||
| 44 | MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); | 44 | MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); |
| 45 | MODULE_DESCRIPTION("Marvell 88ALP01 CMOS Camera Controller driver"); | 45 | MODULE_DESCRIPTION("Marvell 88ALP01 CMOS Camera Controller driver"); |
| 46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
| 47 | MODULE_SUPPORTED_DEVICE("Video"); | ||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | 47 | ||
| 52 | struct cafe_camera { | 48 | struct cafe_camera { |
| 53 | int registered; /* Fully initialized? */ | 49 | int registered; /* Fully initialized? */ |
| @@ -1288,7 +1288,6 @@ static void rkisp1_params_config_parameter(struct rkisp1_params *params) · 1287 unmodified lines | |||
| 1288 | memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); | 1288 | memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); |
| 1289 | rkisp1_hst_config(params, &hst); | 1289 | rkisp1_hst_config(params, &hst); |
| 1290 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP, | 1290 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP, |
| 1291 | ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK | | ||
| 1292 | rkisp1_hst_params_default_config.mode); | 1291 | rkisp1_hst_params_default_config.mode); |
| 1293 | 1292 | ||
| 1294 | /* set the range */ | 1293 | /* set the range */ |
| @@ -2149,4 +2149,3 @@ MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>"); · 2148 unmodified lines | |||
| 2149 | MODULE_AUTHOR("Hugues Fruchet <hugues.fruchet@st.com>"); | 2149 | MODULE_AUTHOR("Hugues Fruchet <hugues.fruchet@st.com>"); |
| 2150 | MODULE_DESCRIPTION("STMicroelectronics STM32 Digital Camera Memory Interface driver"); | 2150 | MODULE_DESCRIPTION("STMicroelectronics STM32 Digital Camera Memory Interface driver"); |
| 2151 | MODULE_LICENSE("GPL"); | 2151 | MODULE_LICENSE("GPL"); |
| 2152 | MODULE_SUPPORTED_DEVICE("video"); | ||
| @@ -245,7 +245,7 @@ static int vsp1_du_pipeline_setup_brx(struct vsp1_device *vsp1, · 244 unmodified lines | |||
| 245 | brx = &vsp1->bru->entity; | 245 | brx = &vsp1->bru->entity; |
| 246 | else if (pipe->brx && !drm_pipe->force_brx_release) | 246 | else if (pipe->brx && !drm_pipe->force_brx_release) |
| 247 | brx = pipe->brx; | 247 | brx = pipe->brx; |
| 248 | else if (!vsp1->bru->entity.pipe) | 248 | else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe) |
| 249 | brx = &vsp1->bru->entity; | 249 | brx = &vsp1->bru->entity; |
| 250 | else | 250 | else |
| 251 | brx = &vsp1->brs->entity; | 251 | brx = &vsp1->brs->entity; |
| @@ -462,9 +462,9 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1, · 210 unmodified lines | |||
| 462 | * make sure it is present in the pipeline's list of entities if it | 462 | * make sure it is present in the pipeline's list of entities if it |
| 463 | * wasn't already. | 463 | * wasn't already. |
| 464 | */ | 464 | */ |
| 465 | if (!use_uif) { | 465 | if (drm_pipe->uif && !use_uif) { |
| 466 | drm_pipe->uif->pipe = NULL; | 466 | drm_pipe->uif->pipe = NULL; |
| 467 | } else if (!drm_pipe->uif->pipe) { | 467 | } else if (drm_pipe->uif && !drm_pipe->uif->pipe) { |
| 468 | drm_pipe->uif->pipe = pipe; | 468 | drm_pipe->uif->pipe = pipe; |
| 469 | list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities); | 469 | list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities); |
| 470 | } | 470 | } |
| @@ -5,6 +5,7 @@ obj-y += keymaps/ · 4 unmodified lines | |||
| 5 | obj-$(CONFIG_RC_CORE) += rc-core.o | 5 | obj-$(CONFIG_RC_CORE) += rc-core.o |
| 6 | rc-core-y := rc-main.o rc-ir-raw.o | 6 | rc-core-y := rc-main.o rc-ir-raw.o |
| 7 | rc-core-$(CONFIG_LIRC) += lirc_dev.o | 7 | rc-core-$(CONFIG_LIRC) += lirc_dev.o |
| 8 | rc-core-$(CONFIG_MEDIA_CEC_RC) += keymaps/rc-cec.o | ||
| 8 | rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o | 9 | rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o |
| 9 | obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o | 10 | obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o |
| 10 | obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o | 11 | obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o |
| @@ -21,7 +21,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ · 20 unmodified lines | |||
| 21 | rc-behold.o \ | 21 | rc-behold.o \ |
| 22 | rc-behold-columbus.o \ | 22 | rc-behold-columbus.o \ |
| 23 | rc-budget-ci-old.o \ | 23 | rc-budget-ci-old.o \ |
| 24 | rc-cec.o \ | ||
| 25 | rc-cinergy-1400.o \ | 24 | rc-cinergy-1400.o \ |
| 26 | rc-cinergy.o \ | 25 | rc-cinergy.o \ |
| 27 | rc-d680-dmb.o \ | 26 | rc-d680-dmb.o \ |
| @@ -1,5 +1,15 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | /* Keytable for the CEC remote control | 2 | /* Keytable for the CEC remote control |
| 3 | * | ||
| 4 | * This keymap is unusual in that it can't be built as a module, | ||
| 5 | * instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC | ||
| 6 | * is set. This is because it can be called from drm_dp_cec_set_edid() via | ||
| 7 | * cec_register_adapter() in an asynchronous context, and it is not | ||
| 8 | * allowed to use request_module() to load rc-cec.ko in that case. | ||
| 9 | * | ||
| 10 | * Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we | ||
| 11 | * just compile this keymap into the rc-core module and never as a | ||
| 12 | * separate module. | ||
| 3 | * | 13 | * |
| 4 | * Copyright (c) 2015 by Kamil Debski | 14 | * Copyright (c) 2015 by Kamil Debski |
| 5 | */ | 15 | */ |
| @@ -152,7 +162,7 @@ static struct rc_map_table cec[] = { · 146 unmodified lines | |||
| 152 | /* 0x77-0xff: Reserved */ | 162 | /* 0x77-0xff: Reserved */ |
| 153 | }; | 163 | }; |
| 154 | 164 | ||
| 155 | static struct rc_map_list cec_map = { | 165 | struct rc_map_list cec_map = { |
| 156 | .map = { | 166 | .map = { |
| 157 | .scan = cec, | 167 | .scan = cec, |
| 158 | .size = ARRAY_SIZE(cec), | 168 | .size = ARRAY_SIZE(cec), |
| @@ -160,19 +170,3 @@ static struct rc_map_list cec_map = { · 1 unmodified line | |||
| 160 | .name = RC_MAP_CEC, | 170 | .name = RC_MAP_CEC, |
| 161 | } | 171 | } |
| 162 | }; | 172 | }; |
| 163 | |||
| 164 | static int __init init_rc_map_cec(void) | ||
| 165 | { | ||
| 166 | return rc_map_register(&cec_map); | ||
| 167 | } | ||
| 168 | |||
| 169 | static void __exit exit_rc_map_cec(void) | ||
| 170 | { | ||
| 171 | rc_map_unregister(&cec_map); | ||
| 172 | } | ||
| 173 | |||
| 174 | module_init(init_rc_map_cec); | ||
| 175 | module_exit(exit_rc_map_cec); | ||
| 176 | |||
| 177 | MODULE_LICENSE("GPL"); | ||
| 178 | MODULE_AUTHOR("Kamil Debski"); | ||
| @@ -2069,6 +2069,9 @@ static int __init rc_core_init(void) · 2068 unmodified lines | |||
| 2069 | 2069 | ||
| 2070 | led_trigger_register_simple("rc-feedback", &led_feedback); | 2070 | led_trigger_register_simple("rc-feedback", &led_feedback); |
| 2071 | rc_map_register(&empty_map); | 2071 | rc_map_register(&empty_map); |
| 2072 | #ifdef CONFIG_MEDIA_CEC_RC | ||
| 2073 | rc_map_register(&cec_map); | ||
| 2074 | #endif | ||
| 2072 | 2075 | ||
| 2073 | return 0; | 2076 | return 0; |
| 2074 | } | 2077 | } |
| @@ -2078,6 +2081,9 @@ static void __exit rc_core_exit(void) · 3 unmodified lines | |||
| 2078 | lirc_dev_exit(); | 2081 | lirc_dev_exit(); |
| 2079 | class_unregister(&rc_class); | 2082 | class_unregister(&rc_class); |
| 2080 | led_trigger_unregister_simple(led_feedback); | 2083 | led_trigger_unregister_simple(led_feedback); |
| 2084 | #ifdef CONFIG_MEDIA_CEC_RC | ||
| 2085 | rc_map_unregister(&cec_map); | ||
| 2086 | #endif | ||
| 2081 | rc_map_unregister(&empty_map); | 2087 | rc_map_unregister(&empty_map); |
| 2082 | } | 2088 | } |
| 2083 | 2089 | ||
| @@ -56,7 +56,6 @@ MODULE_PARM_DESC(flicker_mode, "Flicker frequency (0 (disabled), " __stringify(5 · 55 unmodified lines | |||
| 56 | 56 | ||
| 57 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); | 57 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); |
| 58 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); | 58 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); |
| 59 | MODULE_SUPPORTED_DEVICE("video"); | ||
| 60 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
| 61 | MODULE_VERSION(CPIA_VERSION); | 60 | MODULE_VERSION(CPIA_VERSION); |
| 62 | 61 | ||
| @@ -51,7 +51,6 @@ MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s)."); · 50 unmodified lines | |||
| 51 | MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards"); | 51 | MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards"); |
| 52 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | 52 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
| 53 | MODULE_LICENSE("GPL v2"); | 53 | MODULE_LICENSE("GPL v2"); |
| 54 | MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},{{Trident,tm6000},{{Trident,tm6010}"); | ||
| 55 | static unsigned int debug; | 54 | static unsigned int debug; |
| 56 | module_param(debug, int, 0644); | 55 | module_param(debug, int, 0644); |
| 57 | MODULE_PARM_DESC(debug, "enable debug messages"); | 56 | MODULE_PARM_DESC(debug, "enable debug messages"); |
| @@ -23,8 +23,6 @@ MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV ca · 22 unmodified lines | |||
| 23 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | 23 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
| 24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
| 25 | 25 | ||
| 26 | MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},{{Trident, tm6000},{{Trident, tm6010}"); | ||
| 27 | |||
| 28 | static int debug; | 26 | static int debug; |
| 29 | 27 | ||
| 30 | module_param(debug, int, 0644); | 28 | module_param(debug, int, 0644); |
| @@ -371,7 +371,7 @@ void usbtv_audio_free(struct usbtv *usbtv) · 370 unmodified lines | |||
| 371 | cancel_work_sync(&usbtv->snd_trigger); | 371 | cancel_work_sync(&usbtv->snd_trigger); |
| 372 | 372 | ||
| 373 | if (usbtv->snd && usbtv->udev) { | 373 | if (usbtv->snd && usbtv->udev) { |
| 374 | snd_card_free(usbtv->snd); | 374 | snd_card_free_when_closed(usbtv->snd); |
| 375 | usbtv->snd = NULL; | 375 | usbtv->snd = NULL; |
| 376 | } | 376 | } |
| 377 | } | 377 | } |
| @@ -72,7 +72,8 @@ static const struct dmi_system_id dmi_platform_info[] = { · 71 unmodified lines | |||
| 72 | {} | 72 | {} |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | static const struct resource intel_quark_i2c_res[] = { | 75 | /* This is used as a place holder and will be modified at run-time */ |
| 76 | static struct resource intel_quark_i2c_res[] = { | ||
| 76 | [INTEL_QUARK_IORES_MEM] = { | 77 | [INTEL_QUARK_IORES_MEM] = { |
| 77 | .flags = IORESOURCE_MEM, | 78 | .flags = IORESOURCE_MEM, |
| 78 | }, | 79 | }, |
| @@ -85,7 +86,8 @@ static struct mfd_cell_acpi_match intel_quark_acpi_match_i2c = { · 6 unmodified lines | |||
| 85 | .adr = MFD_ACPI_MATCH_I2C, | 86 | .adr = MFD_ACPI_MATCH_I2C, |
| 86 | }; | 87 | }; |
| 87 | 88 | ||
| 88 | static const struct resource intel_quark_gpio_res[] = { | 89 | /* This is used as a place holder and will be modified at run-time */ |
| 90 | static struct resource intel_quark_gpio_res[] = { | ||
| 89 | [INTEL_QUARK_IORES_MEM] = { | 91 | [INTEL_QUARK_IORES_MEM] = { |
| 90 | .flags = IORESOURCE_MEM, | 92 | .flags = IORESOURCE_MEM, |
| 91 | }, | 93 | }, |
| @@ -950,6 +950,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, · 949 unmodified lines | |||
| 950 | if (!fl->cctx->rpdev) | 950 | if (!fl->cctx->rpdev) |
| 951 | return -EPIPE; | 951 | return -EPIPE; |
| 952 | 952 | ||
| 953 | if (handle == FASTRPC_INIT_HANDLE && !kernel) { | ||
| 954 | dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n", handle); | ||
| 955 | return -EPERM; | ||
| 956 | } | ||
| 957 | |||
| 953 | ctx = fastrpc_context_alloc(fl, kernel, sc, args); | 958 | ctx = fastrpc_context_alloc(fl, kernel, sc, args); |
| 954 | if (IS_ERR(ctx)) | 959 | if (IS_ERR(ctx)) |
| 955 | return PTR_ERR(ctx); | 960 | return PTR_ERR(ctx); |
| @@ -992,7 +992,6 @@ void hl_debugfs_add_device(struct hl_device *hdev) · 991 unmodified lines | |||
| 992 | struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; | 992 | struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; |
| 993 | int count = ARRAY_SIZE(hl_debugfs_list); | 993 | int count = ARRAY_SIZE(hl_debugfs_list); |
| 994 | struct hl_debugfs_entry *entry; | 994 | struct hl_debugfs_entry *entry; |
| 995 | struct dentry *ent; | ||
| 996 | int i; | 995 | int i; |
| 997 | 996 | ||
| 998 | dev_entry->hdev = hdev; | 997 | dev_entry->hdev = hdev; |
| @@ -1105,13 +1104,11 @@ void hl_debugfs_add_device(struct hl_device *hdev) · 106 unmodified lines | |||
| 1105 | &hl_security_violations_fops); | 1104 | &hl_security_violations_fops); |
| 1106 | 1105 | ||
| 1107 | for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { | 1106 | for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { |
| 1108 | 1107 | debugfs_create_file(hl_debugfs_list[i].name, | |
| 1109 | ent = debugfs_create_file(hl_debugfs_list[i].name, | ||
| 1110 | 0444, | 1108 | 0444, |
| 1111 | dev_entry->root, | 1109 | dev_entry->root, |
| 1112 | entry, | 1110 | entry, |
| 1113 | &hl_debugfs_fops); | 1111 | &hl_debugfs_fops); |
| 1114 | entry->dent = ent; | ||
| 1115 | entry->info_ent = &hl_debugfs_list[i]; | 1112 | entry->info_ent = &hl_debugfs_list[i]; |
| 1116 | entry->dev_entry = dev_entry; | 1113 | entry->dev_entry = dev_entry; |
| 1117 | } | 1114 | } |
| @@ -93,12 +93,19 @@ void hl_hpriv_put(struct hl_fpriv *hpriv) · 92 unmodified lines | |||
| 93 | static int hl_device_release(struct inode *inode, struct file *filp) | 93 | static int hl_device_release(struct inode *inode, struct file *filp) |
| 94 | { | 94 | { |
| 95 | struct hl_fpriv *hpriv = filp->private_data; | 95 | struct hl_fpriv *hpriv = filp->private_data; |
| 96 | struct hl_device *hdev = hpriv->hdev; | ||
| 97 | |||
| 98 | filp->private_data = NULL; | ||
| 99 | |||
| 100 | if (!hdev) { | ||
| 101 | pr_crit("Closing FD after device was removed. Memory leak will occur and it is advised to reboot.\n"); | ||
| 102 | put_pid(hpriv->taskpid); | ||
| 103 | return 0; | ||
| 104 | } | ||
| 96 | 105 | ||
| 97 | hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr); | 106 | hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr); |
| 98 | hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr); | 107 | hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr); |
| 99 | 108 | ||
| 100 | filp->private_data = NULL; | ||
| 101 | |||
| 102 | hl_hpriv_put(hpriv); | 109 | hl_hpriv_put(hpriv); |
| 103 | 110 | ||
| 104 | return 0; | 111 | return 0; |
| @@ -107,15 +114,20 @@ static int hl_device_release(struct inode *inode, struct file *filp) · 2 unmodified lines | |||
| 107 | static int hl_device_release_ctrl(struct inode *inode, struct file *filp) | 114 | static int hl_device_release_ctrl(struct inode *inode, struct file *filp) |
| 108 | { | 115 | { |
| 109 | struct hl_fpriv *hpriv = filp->private_data; | 116 | struct hl_fpriv *hpriv = filp->private_data; |
| 110 | struct hl_device *hdev; | 117 | struct hl_device *hdev = hpriv->hdev; |
| 111 | 118 | ||
| 112 | filp->private_data = NULL; | 119 | filp->private_data = NULL; |
| 113 | 120 | ||
| 114 | hdev = hpriv->hdev; | 121 | if (!hdev) { |
| 122 | pr_err("Closing FD after device was removed\n"); | ||
| 123 | goto out; | ||
| 124 | } | ||
| 115 | 125 | ||
| 116 | mutex_lock(&hdev->fpriv_list_lock); | 126 | mutex_lock(&hdev->fpriv_list_lock); |
| 117 | list_del(&hpriv->dev_node); | 127 | list_del(&hpriv->dev_node); |
| 118 | mutex_unlock(&hdev->fpriv_list_lock); | 128 | mutex_unlock(&hdev->fpriv_list_lock); |
| 129 | out: | ||
| 130 | put_pid(hpriv->taskpid); | ||
| 119 | 131 | ||
| 120 | kfree(hpriv); | 132 | kfree(hpriv); |
| 121 | 133 | ||
| @@ -134,8 +146,14 @@ static int hl_device_release_ctrl(struct inode *inode, struct file *filp) · 12 unmodified lines | |||
| 134 | static int hl_mmap(struct file *filp, struct vm_area_struct *vma) | 146 | static int hl_mmap(struct file *filp, struct vm_area_struct *vma) |
| 135 | { | 147 | { |
| 136 | struct hl_fpriv *hpriv = filp->private_data; | 148 | struct hl_fpriv *hpriv = filp->private_data; |
| 149 | struct hl_device *hdev = hpriv->hdev; | ||
| 137 | unsigned long vm_pgoff; | 150 | unsigned long vm_pgoff; |
| 138 | 151 | ||
| 152 | if (!hdev) { | ||
| 153 | pr_err_ratelimited("Trying to mmap after device was removed! Please close FD\n"); | ||
| 154 | return -ENODEV; | ||
| 155 | } | ||
| 156 | |||
| 139 | vm_pgoff = vma->vm_pgoff; | 157 | vm_pgoff = vma->vm_pgoff; |
| 140 | vma->vm_pgoff = HL_MMAP_OFFSET_VALUE_GET(vm_pgoff); | 158 | vma->vm_pgoff = HL_MMAP_OFFSET_VALUE_GET(vm_pgoff); |
| 141 | 159 | ||
| @@ -883,6 +901,16 @@ wait_for_processes: · 741 unmodified lines | |||
| 883 | return -EBUSY; | 901 | return -EBUSY; |
| 884 | } | 902 | } |
| 885 | 903 | ||
| 904 | static void device_disable_open_processes(struct hl_device *hdev) | ||
| 905 | { | ||
| 906 | struct hl_fpriv *hpriv; | ||
| 907 | |||
| 908 | mutex_lock(&hdev->fpriv_list_lock); | ||
| 909 | list_for_each_entry(hpriv, &hdev->fpriv_list, dev_node) | ||
| 910 | hpriv->hdev = NULL; | ||
| 911 | mutex_unlock(&hdev->fpriv_list_lock); | ||
| 912 | } | ||
| 913 | |||
| 886 | /* | 914 | /* |
| 887 | * hl_device_reset - reset the device | 915 | * hl_device_reset - reset the device |
| 888 | * | 916 | * |
| @@ -1556,8 +1584,10 @@ void hl_device_fini(struct hl_device *hdev) · 667 unmodified lines | |||
| 1556 | HL_PENDING_RESET_LONG_SEC); | 1584 | HL_PENDING_RESET_LONG_SEC); |
| 1557 | 1585 | ||
| 1558 | rc = device_kill_open_processes(hdev, HL_PENDING_RESET_LONG_SEC); | 1586 | rc = device_kill_open_processes(hdev, HL_PENDING_RESET_LONG_SEC); |
| 1559 | if (rc) | 1587 | if (rc) { |
| 1560 | dev_crit(hdev->dev, "Failed to kill all open processes\n"); | 1588 | dev_crit(hdev->dev, "Failed to kill all open processes\n"); |
| 1589 | device_disable_open_processes(hdev); | ||
| 1590 | } | ||
| 1561 | 1591 | ||
| 1562 | hl_cb_pool_fini(hdev); | 1592 | hl_cb_pool_fini(hdev); |
| 1563 | 1593 | ||
| @@ -1465,12 +1465,10 @@ struct hl_info_list { · 1464 unmodified lines | |||
| 1465 | 1465 | ||
| 1466 | /** | 1466 | /** |
| 1467 | * struct hl_debugfs_entry - debugfs dentry wrapper. | 1467 | * struct hl_debugfs_entry - debugfs dentry wrapper. |
| 1468 | * @dent: base debugfs entry structure. | ||
| 1469 | * @info_ent: dentry realted ops. | 1468 | * @info_ent: dentry realted ops. |
| 1470 | * @dev_entry: ASIC specific debugfs manager. | 1469 | * @dev_entry: ASIC specific debugfs manager. |
| 1471 | */ | 1470 | */ |
| 1472 | struct hl_debugfs_entry { | 1471 | struct hl_debugfs_entry { |
| 1473 | struct dentry *dent; | ||
| 1474 | const struct hl_info_list *info_ent; | 1472 | const struct hl_info_list *info_ent; |
| 1475 | struct hl_dbg_device_entry *dev_entry; | 1473 | struct hl_dbg_device_entry *dev_entry; |
| 1476 | }; | 1474 | }; |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | |||
| 5 | * All Rights Reserved. | 5 | * All Rights Reserved. |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define pr_fmt(fmt) "habanalabs: " fmt | ||
| 9 | |||
| 8 | #include <uapi/misc/habanalabs.h> | 10 | #include <uapi/misc/habanalabs.h> |
| 9 | #include "habanalabs.h" | 11 | #include "habanalabs.h" |
| 10 | 12 | ||
| @@ -682,6 +684,11 @@ long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) · 671 unmodified lines | |||
| 682 | const struct hl_ioctl_desc *ioctl = NULL; | 684 | const struct hl_ioctl_desc *ioctl = NULL; |
| 683 | unsigned int nr = _IOC_NR(cmd); | 685 | unsigned int nr = _IOC_NR(cmd); |
| 684 | 686 | ||
| 687 | if (!hdev) { | ||
| 688 | pr_err_ratelimited("Sending ioctl after device was removed! Please close FD\n"); | ||
| 689 | return -ENODEV; | ||
| 690 | } | ||
| 691 | |||
| 685 | if ((nr >= HL_COMMAND_START) && (nr < HL_COMMAND_END)) { | 692 | if ((nr >= HL_COMMAND_START) && (nr < HL_COMMAND_END)) { |
| 686 | ioctl = &hl_ioctls[nr]; | 693 | ioctl = &hl_ioctls[nr]; |
| 687 | } else { | 694 | } else { |
| @@ -700,6 +707,11 @@ long hl_ioctl_control(struct file *filep, unsigned int cmd, unsigned long arg) · 12 unmodified lines | |||
| 700 | const struct hl_ioctl_desc *ioctl = NULL; | 707 | const struct hl_ioctl_desc *ioctl = NULL; |
| 701 | unsigned int nr = _IOC_NR(cmd); | 708 | unsigned int nr = _IOC_NR(cmd); |
| 702 | 709 | ||
| 710 | if (!hdev) { | ||
| 711 | pr_err_ratelimited("Sending ioctl after device was removed! Please close FD\n"); | ||
| 712 | return -ENODEV; | ||
| 713 | } | ||
| 714 | |||
| 703 | if (nr == _IOC_NR(HL_IOCTL_INFO)) { | 715 | if (nr == _IOC_NR(HL_IOCTL_INFO)) { |
| 704 | ioctl = &hl_ioctls_control[nr]; | 716 | ioctl = &hl_ioctls_control[nr]; |
| 705 | } else { | 717 | } else { |
| @@ -47,7 +47,7 @@ inline u32 hl_cq_inc_ptr(u32 ptr) · 46 unmodified lines | |||
| 47 | * Increment ptr by 1. If it reaches the number of event queue | 47 | * Increment ptr by 1. If it reaches the number of event queue |
| 48 | * entries, set it to 0 | 48 | * entries, set it to 0 |
| 49 | */ | 49 | */ |
| 50 | inline u32 hl_eq_inc_ptr(u32 ptr) | 50 | static inline u32 hl_eq_inc_ptr(u32 ptr) |
| 51 | { | 51 | { |
| 52 | ptr++; | 52 | ptr++; |
| 53 | if (unlikely(ptr == HL_EQ_LENGTH)) | 53 | if (unlikely(ptr == HL_EQ_LENGTH)) |
| @@ -499,18 +499,32 @@ static void hl_mmu_pa_page_with_offset(struct hl_ctx *ctx, u64 virt_addr, · 498 unmodified lines | |||
| 499 | else /* HL_VA_RANGE_TYPE_DRAM */ | 499 | else /* HL_VA_RANGE_TYPE_DRAM */ |
| 500 | p = &prop->dmmu; | 500 | p = &prop->dmmu; |
| 501 | 501 | ||
| 502 | /* | 502 | if ((hops->range_type == HL_VA_RANGE_TYPE_DRAM) && |
| 503 | * find the correct hop shift field in hl_mmu_properties structure | 503 | !is_power_of_2(prop->dram_page_size)) { |
| 504 | * in order to determine the right maks for the page offset. | 504 | u32 bit; |
| 505 | */ | 505 | u64 page_offset_mask; |
| 506 | hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift); | 506 | u64 phys_addr_mask; |
| 507 | p = (char *)p + hop0_shift_off; | 507 | |
| 508 | p = (char *)p + ((hops->used_hops - 1) * sizeof(u64)); | 508 | bit = __ffs64((u64)prop->dram_page_size); |
| 509 | hop_shift = *(u64 *)p; | 509 | page_offset_mask = ((1ull << bit) - 1); |
| 510 | offset_mask = (1ull << hop_shift) - 1; | 510 | phys_addr_mask = ~page_offset_mask; |
| 511 | addr_mask = ~(offset_mask); | 511 | *phys_addr = (tmp_phys_addr & phys_addr_mask) | |
| 512 | *phys_addr = (tmp_phys_addr & addr_mask) | | 512 | (virt_addr & page_offset_mask); |
| 513 | (virt_addr & offset_mask); | 513 | } else { |
| 514 | /* | ||
| 515 | * find the correct hop shift field in hl_mmu_properties | ||
| 516 | * structure in order to determine the right masks | ||
| 517 | * for the page offset. | ||
| 518 | */ | ||
| 519 | hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift); | ||
| 520 | p = (char *)p + hop0_shift_off; | ||
| 521 | p = (char *)p + ((hops->used_hops - 1) * sizeof(u64)); | ||
| 522 | hop_shift = *(u64 *)p; | ||
| 523 | offset_mask = (1ull << hop_shift) - 1; | ||
| 524 | addr_mask = ~(offset_mask); | ||
| 525 | *phys_addr = (tmp_phys_addr & addr_mask) | | ||
| 526 | (virt_addr & offset_mask); | ||
| 527 | } | ||
| 514 | } | 528 | } |
| 515 | 529 | ||
| 516 | int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr) | 530 | int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr) |
| @@ -140,6 +140,7 @@ static const struct of_device_id pvpanic_mmio_match[] = { · 139 unmodified lines | |||
| 140 | { .compatible = "qemu,pvpanic-mmio", }, | 140 | { .compatible = "qemu,pvpanic-mmio", }, |
| 141 | {} | 141 | {} |
| 142 | }; | 142 | }; |
| 143 | MODULE_DEVICE_TABLE(of, pvpanic_mmio_match); | ||
| 143 | 144 | ||
| 144 | static const struct acpi_device_id pvpanic_device_ids[] = { | 145 | static const struct acpi_device_id pvpanic_device_ids[] = { |
| 145 | { "QEMU0001", 0 }, | 146 | { "QEMU0001", 0 }, |
| @@ -399,11 +399,6 @@ void mmc_remove_card(struct mmc_card *card) · 398 unmodified lines | |||
| 399 | mmc_remove_card_debugfs(card); | 399 | mmc_remove_card_debugfs(card); |
| 400 | #endif | 400 | #endif |
| 401 | 401 | ||
| 402 | if (host->cqe_enabled) { | ||
| 403 | host->cqe_ops->cqe_disable(host); | ||
| 404 | host->cqe_enabled = false; | ||
| 405 | } | ||
| 406 | |||
| 407 | if (mmc_card_present(card)) { | 402 | if (mmc_card_present(card)) { |
| 408 | if (mmc_host_is_spi(card->host)) { | 403 | if (mmc_host_is_spi(card->host)) { |
| 409 | pr_info("%s: SPI card removed\n", | 404 | pr_info("%s: SPI card removed\n", |
| @@ -416,6 +411,10 @@ void mmc_remove_card(struct mmc_card *card) · 6 unmodified lines | |||
| 416 | of_node_put(card->dev.of_node); | 411 | of_node_put(card->dev.of_node); |
| 417 | } | 412 | } |
| 418 | 413 | ||
| 414 | if (host->cqe_enabled) { | ||
| 415 | host->cqe_ops->cqe_disable(host); | ||
| 416 | host->cqe_enabled = false; | ||
| 417 | } | ||
| 418 | |||
| 419 | put_device(&card->dev); | 419 | put_device(&card->dev); |
| 420 | } | 420 | } |
| 421 | |||
| @@ -423,10 +423,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) · 422 unmodified lines | |||
| 423 | 423 | ||
| 424 | /* EXT_CSD value is in units of 10ms, but we store in ms */ | 424 | /* EXT_CSD value is in units of 10ms, but we store in ms */ |
| 425 | card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; | 425 | card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; |
| 426 | /* Some eMMC set the value too low so set a minimum */ | ||
| 427 | if (card->ext_csd.part_time && | ||
| 428 | card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) | ||
| 429 | card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; | ||
| 430 | 426 | ||
| 431 | /* Sleep / awake timeout in 100ns units */ | 427 | /* Sleep / awake timeout in 100ns units */ |
| 432 | if (sa_shift > 0 && sa_shift <= 0x17) | 428 | if (sa_shift > 0 && sa_shift <= 0x17) |
| @@ -616,6 +612,17 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) · 183 unmodified lines | |||
| 616 | card->ext_csd.data_sector_size = 512; | 612 | card->ext_csd.data_sector_size = 512; |
| 617 | } | 613 | } |
| 618 | 614 | ||
| 615 | /* | ||
| 616 | * GENERIC_CMD6_TIME is to be used "unless a specific timeout is defined | ||
| 617 | * when accessing a specific field", so use it here if there is no | ||
| 618 | * PARTITION_SWITCH_TIME. | ||
| 619 | */ | ||
| 620 | if (!card->ext_csd.part_time) | ||
| 621 | card->ext_csd.part_time = card->ext_csd.generic_cmd6_time; | ||
| 622 | /* Some eMMC set the value too low so set a minimum */ | ||
| 623 | if (card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) | ||
| 624 | card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; | ||
| 625 | |||
| 619 | /* eMMC v5 or later */ | 626 | /* eMMC v5 or later */ |
| 620 | if (card->ext_csd.rev >= 7) { | 627 | if (card->ext_csd.rev >= 7) { |
| 621 | memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], | 628 | memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], |
| @@ -1242,7 +1242,11 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) · 1241 unmodified lines | |||
| 1242 | if (!cmd->busy_timeout) | 1242 | if (!cmd->busy_timeout) |
| 1243 | cmd->busy_timeout = 10 * MSEC_PER_SEC; | 1243 | cmd->busy_timeout = 10 * MSEC_PER_SEC; |
| 1244 | 1244 | ||
| 1245 | clks = (unsigned long long)cmd->busy_timeout * host->cclk; | 1245 | if (cmd->busy_timeout > host->mmc->max_busy_timeout) |
| 1246 | clks = (unsigned long long)host->mmc->max_busy_timeout * host->cclk; | ||
| 1247 | else | ||
| 1248 | clks = (unsigned long long)cmd->busy_timeout * host->cclk; | ||
| 1249 | |||
| 1246 | do_div(clks, MSEC_PER_SEC); | 1250 | do_div(clks, MSEC_PER_SEC); |
| 1247 | writel_relaxed(clks, host->base + MMCIDATATIMER); | 1251 | writel_relaxed(clks, host->base + MMCIDATATIMER); |
| 1248 | } | 1252 | } |
| @@ -2151,6 +2155,10 @@ static int mmci_probe(struct amba_device *dev, · 902 unmodified lines | |||
| 2151 | mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | 2155 | mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; |
| 2152 | } | 2156 | } |
| 2153 | 2157 | ||
| 2158 | /* Variants with mandatory busy timeout in HW needs R1B responses. */ | ||
| 2159 | if (variant->busy_timeout) | ||
| 2160 | mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | ||
| 2161 | |||
| 2154 | /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ | 2162 | /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ |
| 2155 | host->stop_abort.opcode = MMC_STOP_TRANSMISSION; | 2163 | host->stop_abort.opcode = MMC_STOP_TRANSMISSION; |
| 2156 | host->stop_abort.arg = 0; | 2164 | host->stop_abort.arg = 0; |
| @@ -32,7 +32,6 @@ · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); | 33 | MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); |
| 34 | MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets"); | 34 | MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets"); |
| 35 | MODULE_SUPPORTED_DEVICE(DRIVER_NAME); | ||
| 36 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
| 37 | MODULE_VERSION("2.1"); | 36 | MODULE_VERSION("2.1"); |
| 38 | 37 | ||
| @@ -127,6 +127,8 @@ static int com20020pci_probe(struct pci_dev *pdev, · 126 unmodified lines | |||
| 127 | int i, ioaddr, ret; | 127 | int i, ioaddr, ret; |
| 128 | struct resource *r; | 128 | struct resource *r; |
| 129 | 129 | ||
| 130 | ret = 0; | ||
| 131 | |||
| 130 | if (pci_enable_device(pdev)) | 132 | if (pci_enable_device(pdev)) |
| 131 | return -EIO; | 133 | return -EIO; |
| 132 | 134 | ||
| @@ -139,6 +141,8 @@ static int com20020pci_probe(struct pci_dev *pdev, · 6 unmodified lines | |||
| 139 | priv->ci = ci; | 141 | priv->ci = ci; |
| 140 | mm = &ci->misc_map; | 142 | mm = &ci->misc_map; |
| 141 | 143 | ||
| 144 | pci_set_drvdata(pdev, priv); | ||
| 145 | |||
| 142 | INIT_LIST_HEAD(&priv->list_dev); | 146 | INIT_LIST_HEAD(&priv->list_dev); |
| 143 | 147 | ||
| 144 | if (mm->size) { | 148 | if (mm->size) { |
| @@ -161,7 +165,7 @@ static int com20020pci_probe(struct pci_dev *pdev, · 16 unmodified lines | |||
| 161 | dev = alloc_arcdev(device); | 165 | dev = alloc_arcdev(device); |
| 162 | if (!dev) { | 166 | if (!dev) { |
| 163 | ret = -ENOMEM; | 167 | ret = -ENOMEM; |
| 164 | goto out_port; | 168 | break; |
| 165 | } | 169 | } |
| 166 | dev->dev_port = i; | 170 | dev->dev_port = i; |
| 167 | 171 | ||
| @@ -178,7 +182,7 @@ static int com20020pci_probe(struct pci_dev *pdev, · 10 unmodified lines | |||
| 178 | pr_err("IO region %xh-%xh already allocated\n", | 182 | pr_err("IO region %xh-%xh already allocated\n", |
| 179 | ioaddr, ioaddr + cm->size - 1); | 183 | ioaddr, ioaddr + cm->size - 1); |
| 180 | ret = -EBUSY; | 184 | ret = -EBUSY; |
| 181 | goto out_port; | 185 | goto err_free_arcdev; |
| 182 | } | 186 | } |
| 183 | 187 | ||
| 184 | /* Dummy access after Reset | 188 | /* Dummy access after Reset |
| @@ -216,18 +220,18 @@ static int com20020pci_probe(struct pci_dev *pdev, · 31 unmodified lines | |||
| 216 | if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { | 220 | if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { |
| 217 | pr_err("IO address %Xh is empty!\n", ioaddr); | 221 | pr_err("IO address %Xh is empty!\n", ioaddr); |
| 218 | ret = -EIO; | 222 | ret = -EIO; |
| 219 | goto out_port; | 223 | goto err_free_arcdev; |
| 220 | } | 224 | } |
| 221 | if (com20020_check(dev)) { | 225 | if (com20020_check(dev)) { |
| 222 | ret = -EIO; | 226 | ret = -EIO; |
| 223 | goto out_port; | 227 | goto err_free_arcdev; |
| 224 | } | 228 | } |
| 225 | 229 | ||
| 226 | card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), | 230 | card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), |
| 227 | GFP_KERNEL); | 231 | GFP_KERNEL); |
| 228 | if (!card) { | 232 | if (!card) { |
| 229 | ret = -ENOMEM; | 233 | ret = -ENOMEM; |
| 230 | goto out_port; | 234 | goto err_free_arcdev; |
| 231 | } | 235 | } |
| 232 | 236 | ||
| 233 | card->index = i; | 237 | card->index = i; |
| @@ -253,29 +257,29 @@ static int com20020pci_probe(struct pci_dev *pdev, · 19 unmodified lines | |||
| 253 | 257 | ||
| 254 | ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); | 258 | ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); |
| 255 | if (ret) | 259 | if (ret) |
| 256 | goto out_port; | 260 | goto err_free_arcdev; |
| 257 | 261 | ||
| 258 | ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); | 262 | ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); |
| 259 | if (ret) | 263 | if (ret) |
| 260 | goto out_port; | 264 | goto err_free_arcdev; |
| 261 | 265 | ||
| 262 | dev_set_drvdata(&dev->dev, card); | 266 | dev_set_drvdata(&dev->dev, card); |
| 263 | 267 | ||
| 264 | ret = com20020_found(dev, IRQF_SHARED); | 268 | ret = com20020_found(dev, IRQF_SHARED); |
| 265 | if (ret) | 269 | if (ret) |
| 266 | goto out_port; | 270 | goto err_free_arcdev; |
| 267 | 271 | ||
| 268 | devm_arcnet_led_init(dev, dev->dev_id, i); | 272 | devm_arcnet_led_init(dev, dev->dev_id, i); |
| 269 | 273 | ||
| 270 | list_add(&card->list, &priv->list_dev); | 274 | list_add(&card->list, &priv->list_dev); |
| 271 | } | 275 | continue; |
| 272 | 276 | ||
| 273 | pci_set_drvdata(pdev, priv); | 277 | err_free_arcdev: |
| 274 | 278 | free_arcdev(dev); | |
| 275 | return 0; | 279 | break; |
| 276 | 280 | } | |
| 277 | out_port: | 281 | if (ret) |
| 278 | com20020pci_remove(pdev); | 282 | com20020pci_remove(pdev); |
| 279 | return ret; | 283 | return ret; |
| 280 | } | 284 | } |
| 281 | 285 | ||
| @@ -3978,15 +3978,11 @@ static int bond_neigh_init(struct neighbour *n) · 3977 unmodified lines | |||
| 3978 | 3978 | ||
| 3979 | rcu_read_lock(); | 3979 | rcu_read_lock(); |
| 3980 | slave = bond_first_slave_rcu(bond); | 3980 | slave = bond_first_slave_rcu(bond); |
| 3981 | if (!slave) { | 3981 | if (!slave) |
| 3982 | ret = -EINVAL; | ||
| 3983 | goto out; | 3982 | goto out; |
| 3984 | } | ||
| 3985 | slave_ops = slave->dev->netdev_ops; | 3983 | slave_ops = slave->dev->netdev_ops; |
| 3986 | if (!slave_ops->ndo_neigh_setup) { | 3984 | if (!slave_ops->ndo_neigh_setup) |
| 3987 | ret = -EINVAL; | ||
| 3988 | goto out; | 3985 | goto out; |
| 3989 | } | ||
| 3990 | 3986 | ||
| 3991 | /* TODO: find another way [1] to implement this. | 3987 | /* TODO: find another way [1] to implement this. |
| 3992 | * Passing a zeroed structure is fragile, | 3988 | * Passing a zeroed structure is fragile, |
| @@ -212,18 +212,6 @@ static const struct can_bittiming_const c_can_bittiming_const = { · 211 unmodified lines | |||
| 212 | .brp_inc = 1, | 212 | .brp_inc = 1, |
| 213 | }; | 213 | }; |
| 214 | 214 | ||
| 215 | static inline void c_can_pm_runtime_enable(const struct c_can_priv *priv) | ||
| 216 | { | ||
| 217 | if (priv->device) | ||
| 218 | pm_runtime_enable(priv->device); | ||
| 219 | } | ||
| 220 | |||
| 221 | static inline void c_can_pm_runtime_disable(const struct c_can_priv *priv) | ||
| 222 | { | ||
| 223 | if (priv->device) | ||
| 224 | pm_runtime_disable(priv->device); | ||
| 225 | } | ||
| 226 | |||
| 227 | static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv) | 215 | static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv) |
| 228 | { | 216 | { |
| 229 | if (priv->device) | 217 | if (priv->device) |
| @@ -1335,7 +1323,6 @@ static const struct net_device_ops c_can_netdev_ops = { · 1105 unmodified lines | |||
| 1335 | 1323 | ||
| 1336 | int register_c_can_dev(struct net_device *dev) | 1324 | int register_c_can_dev(struct net_device *dev) |
| 1337 | { | 1325 | { |
| 1338 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 1339 | int err; | 1326 | int err; |
| 1340 | 1327 | ||
| 1341 | /* Deactivate pins to prevent DRA7 DCAN IP from being | 1328 | /* Deactivate pins to prevent DRA7 DCAN IP from being |
| @@ -1345,28 +1332,19 @@ int register_c_can_dev(struct net_device *dev) · 3 unmodified lines | |||
| 1345 | */ | 1332 | */ |
| 1346 | pinctrl_pm_select_sleep_state(dev->dev.parent); | 1333 | pinctrl_pm_select_sleep_state(dev->dev.parent); |
| 1347 | 1334 | ||
| 1348 | c_can_pm_runtime_enable(priv); | ||
| 1349 | |||
| 1350 | dev->flags |= IFF_ECHO; /* we support local echo */ | 1335 | dev->flags |= IFF_ECHO; /* we support local echo */ |
| 1351 | dev->netdev_ops = &c_can_netdev_ops; | 1336 | dev->netdev_ops = &c_can_netdev_ops; |
| 1352 | 1337 | ||
| 1353 | err = register_candev(dev); | 1338 | err = register_candev(dev); |
| 1354 | if (err) | 1339 | if (!err) |
| 1355 | c_can_pm_runtime_disable(priv); | ||
| 1356 | else | ||
| 1357 | devm_can_led_init(dev); | 1340 | devm_can_led_init(dev); |
| 1358 | |||
| 1359 | return err; | 1341 | return err; |
| 1360 | } | 1342 | } |
| 1361 | EXPORT_SYMBOL_GPL(register_c_can_dev); | 1343 | EXPORT_SYMBOL_GPL(register_c_can_dev); |
| 1362 | 1344 | ||
| 1363 | void unregister_c_can_dev(struct net_device *dev) | 1345 | void unregister_c_can_dev(struct net_device *dev) |
| 1364 | { | 1346 | { |
| 1365 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 1366 | |||
| 1367 | unregister_candev(dev); | 1347 | unregister_candev(dev); |
| 1368 | |||
| 1369 | c_can_pm_runtime_disable(priv); | ||
| 1370 | } | 1348 | } |
| 1371 | EXPORT_SYMBOL_GPL(unregister_c_can_dev); | 1349 | EXPORT_SYMBOL_GPL(unregister_c_can_dev); |
| 1372 | 1350 | ||
| @@ -239,12 +239,13 @@ static void c_can_pci_remove(struct pci_dev *pdev) · 238 unmodified lines | |||
| 239 | { | 239 | { |
| 240 | struct net_device *dev = pci_get_drvdata(pdev); | 240 | struct net_device *dev = pci_get_drvdata(pdev); |
| 241 | struct c_can_priv *priv = netdev_priv(dev); | 241 | struct c_can_priv *priv = netdev_priv(dev); |
| 242 | void __iomem *addr = priv->base; | ||
| 242 | 243 | ||
| 243 | unregister_c_can_dev(dev); | 244 | unregister_c_can_dev(dev); |
| 244 | 245 | ||
| 245 | free_c_can_dev(dev); | 246 | free_c_can_dev(dev); |
| 246 | 247 | ||
| 247 | pci_iounmap(pdev, priv->base); | 248 | pci_iounmap(pdev, addr); |
| 248 | pci_disable_msi(pdev); | 249 | pci_disable_msi(pdev); |
| 249 | pci_clear_master(pdev); | 250 | pci_clear_master(pdev); |
| 250 | pci_release_regions(pdev); | 251 | pci_release_regions(pdev); |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
| 30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/pm_runtime.h> | ||
| 32 | #include <linux/clk.h> | 33 | #include <linux/clk.h> |
| 33 | #include <linux/of.h> | 34 | #include <linux/of.h> |
| 34 | #include <linux/of_device.h> | 35 | #include <linux/of_device.h> |
| @@ -386,6 +387,7 @@ static int c_can_plat_probe(struct platform_device *pdev) · 351 unmodified lines | |||
| 386 | platform_set_drvdata(pdev, dev); | 387 | platform_set_drvdata(pdev, dev); |
| 387 | SET_NETDEV_DEV(dev, &pdev->dev); | 388 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 388 | 389 | ||
| 390 | pm_runtime_enable(priv->device); | ||
| 389 | ret = register_c_can_dev(dev); | 391 | ret = register_c_can_dev(dev); |
| 390 | if (ret) { | 392 | if (ret) { |
| 391 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", | 393 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", |
| @@ -398,6 +400,7 @@ static int c_can_plat_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 398 | return 0; | 400 | return 0; |
| 399 | 401 | ||
| 400 | exit_free_device: | 402 | exit_free_device: |
| 403 | pm_runtime_disable(priv->device); | ||
| 401 | free_c_can_dev(dev); | 404 | free_c_can_dev(dev); |
| 402 | exit: | 405 | exit: |
| 403 | dev_err(&pdev->dev, "probe failed\n"); | 406 | dev_err(&pdev->dev, "probe failed\n"); |
| @@ -408,9 +411,10 @@ exit: · 4 unmodified lines | |||
| 408 | static int c_can_plat_remove(struct platform_device *pdev) | 411 | static int c_can_plat_remove(struct platform_device *pdev) |
| 409 | { | 412 | { |
| 410 | struct net_device *dev = platform_get_drvdata(pdev); | 413 | struct net_device *dev = platform_get_drvdata(pdev); |
| 414 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 411 | 415 | ||
| 412 | unregister_c_can_dev(dev); | 416 | unregister_c_can_dev(dev); |
| 413 | 417 | pm_runtime_disable(priv->device); | |
| 414 | free_c_can_dev(dev); | 418 | free_c_can_dev(dev); |
| 415 | 419 | ||
| 416 | return 0; | 420 | return 0; |
| @@ -355,6 +355,7 @@ static void can_dellink(struct net_device *dev, struct list_head *head) · 354 unmodified lines | |||
| 355 | 355 | ||
| 356 | struct rtnl_link_ops can_link_ops __read_mostly = { | 356 | struct rtnl_link_ops can_link_ops __read_mostly = { |
| 357 | .kind = "can", | 357 | .kind = "can", |
| 358 | .netns_refund = true, | ||
| 358 | .maxtype = IFLA_CAN_MAX, | 359 | .maxtype = IFLA_CAN_MAX, |
| 359 | .policy = can_policy, | 360 | .policy = can_policy, |
| 360 | .setup = can_setup, | 361 | .setup = can_setup, |
| @@ -697,9 +697,15 @@ static int flexcan_chip_disable(struct flexcan_priv *priv) · 696 unmodified lines | |||
| 697 | static int flexcan_chip_freeze(struct flexcan_priv *priv) | 697 | static int flexcan_chip_freeze(struct flexcan_priv *priv) |
| 698 | { | 698 | { |
| 699 | struct flexcan_regs __iomem *regs = priv->regs; | 699 | struct flexcan_regs __iomem *regs = priv->regs; |
| 700 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; | 700 | unsigned int timeout; |
| 701 | u32 bitrate = priv->can.bittiming.bitrate; | ||
| 701 | u32 reg; | 702 | u32 reg; |
| 702 | 703 | ||
| 704 | if (bitrate) | ||
| 705 | timeout = 1000 * 1000 * 10 / bitrate; | ||
| 706 | else | ||
| 707 | timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 708 | |||
| 703 | reg = priv->read(®s->mcr); | 709 | reg = priv->read(®s->mcr); |
| 704 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; | 710 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; |
| 705 | priv->write(reg, ®s->mcr); | 711 | priv->write(reg, ®s->mcr); |
| @@ -57,6 +57,7 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices"); · 56 unmodified lines | |||
| 57 | #define KVASER_PCIEFD_KCAN_STAT_REG 0x418 | 57 | #define KVASER_PCIEFD_KCAN_STAT_REG 0x418 |
| 58 | #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c | 58 | #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c |
| 59 | #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420 | 59 | #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420 |
| 60 | #define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424 | ||
| 60 | #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428 | 61 | #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428 |
| 61 | #define KVASER_PCIEFD_KCAN_PWM_REG 0x430 | 62 | #define KVASER_PCIEFD_KCAN_PWM_REG 0x430 |
| 62 | /* Loopback control register */ | 63 | /* Loopback control register */ |
| @@ -949,6 +950,9 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) · 886 unmodified lines | |||
| 949 | timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, | 950 | timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, |
| 950 | 0); | 951 | 0); |
| 951 | 952 | ||
| 953 | /* Disable Bus load reporting */ | ||
| 954 | iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG); | ||
| 955 | |||
| 952 | tx_npackets = ioread32(can->reg_base + | 956 | tx_npackets = ioread32(can->reg_base + |
| 953 | KVASER_PCIEFD_KCAN_TX_NPACKETS_REG); | 957 | KVASER_PCIEFD_KCAN_TX_NPACKETS_REG); |
| 954 | if (((tx_npackets >> KVASER_PCIEFD_KCAN_TX_NPACKETS_MAX_SHIFT) & | 958 | if (((tx_npackets >> KVASER_PCIEFD_KCAN_TX_NPACKETS_MAX_SHIFT) & |
| @@ -501,9 +501,6 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota) · 500 unmodified lines | |||
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | while ((rxfs & RXFS_FFL_MASK) && (quota > 0)) { | 503 | while ((rxfs & RXFS_FFL_MASK) && (quota > 0)) { |
| 504 | if (rxfs & RXFS_RFL) | ||
| 505 | netdev_warn(dev, "Rx FIFO 0 Message Lost\n"); | ||
| 506 | |||
| 507 | m_can_read_fifo(dev, rxfs); | 504 | m_can_read_fifo(dev, rxfs); |
| 508 | 505 | ||
| 509 | quota--; | 506 | quota--; |
| @@ -876,7 +873,7 @@ static int m_can_rx_peripheral(struct net_device *dev) · 366 unmodified lines | |||
| 876 | { | 873 | { |
| 877 | struct m_can_classdev *cdev = netdev_priv(dev); | 874 | struct m_can_classdev *cdev = netdev_priv(dev); |
| 878 | 875 | ||
| 879 | m_can_rx_handler(dev, 1); | 876 | m_can_rx_handler(dev, M_CAN_NAPI_WEIGHT); |
| 880 | 877 | ||
| 881 | m_can_enable_all_interrupts(cdev); | 878 | m_can_enable_all_interrupts(cdev); |
| 882 | 879 | ||
| @@ -21,7 +21,6 @@ · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | 22 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); |
| 23 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards"); | 23 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards"); |
| 24 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe/M.2 FD CAN cards"); | ||
| 25 | MODULE_LICENSE("GPL v2"); | 24 | MODULE_LICENSE("GPL v2"); |
| 26 | 25 | ||
| 27 | #define PCIEFD_DRV_NAME "peak_pciefd" | 26 | #define PCIEFD_DRV_NAME "peak_pciefd" |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>"); | 22 | MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>"); |
| 23 | MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe/104P CAN cards"); | 23 | MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe/104P CAN cards"); |
| 24 | MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe/104P CAN card"); | ||
| 25 | MODULE_LICENSE("GPL v2"); | 24 | MODULE_LICENSE("GPL v2"); |
| 26 | 25 | ||
| 27 | #define EMS_PCI_V1_MAX_CHAN 2 | 26 | #define EMS_PCI_V1_MAX_CHAN 2 |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | MODULE_AUTHOR("Markus Plessing <plessing@ems-wuensche.com>"); | 22 | MODULE_AUTHOR("Markus Plessing <plessing@ems-wuensche.com>"); |
| 23 | MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-CARD cards"); | 23 | MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-CARD cards"); |
| 24 | MODULE_SUPPORTED_DEVICE("EMS CPC-CARD CAN card"); | ||
| 25 | MODULE_LICENSE("GPL v2"); | 24 | MODULE_LICENSE("GPL v2"); |
| 26 | 25 | ||
| 27 | #define EMS_PCMCIA_MAX_CHAN 2 | 26 | #define EMS_PCMCIA_MAX_CHAN 2 |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>"); | 34 | MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>"); |
| 35 | MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards"); | 35 | MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards"); |
| 36 | MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card"); | ||
| 37 | MODULE_LICENSE("GPL v2"); | 36 | MODULE_LICENSE("GPL v2"); |
| 38 | 37 | ||
| 39 | #define MAX_NO_OF_CHANNELS 4 /* max no of channels on a single card */ | 38 | #define MAX_NO_OF_CHANNELS 4 /* max no of channels on a single card */ |
| @@ -24,8 +24,6 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | 25 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); |
| 26 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); | 26 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); |
| 27 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards"); | ||
| 28 | MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards"); | ||
| 29 | MODULE_LICENSE("GPL v2"); | 27 | MODULE_LICENSE("GPL v2"); |
| 30 | 28 | ||
| 31 | #define DRV_NAME "peak_pci" | 29 | #define DRV_NAME "peak_pci" |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | |||
| 22 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | 22 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); |
| 23 | MODULE_DESCRIPTION("CAN driver for PEAK-System PCAN-PC Cards"); | 23 | MODULE_DESCRIPTION("CAN driver for PEAK-System PCAN-PC Cards"); |
| 24 | MODULE_LICENSE("GPL v2"); | 24 | MODULE_LICENSE("GPL v2"); |
| 25 | MODULE_SUPPORTED_DEVICE("PEAK PCAN-PC Card"); | ||
| 26 | 25 | ||
| 27 | /* PEAK-System PCMCIA driver name */ | 26 | /* PEAK-System PCMCIA driver name */ |
| 28 | #define PCC_NAME "peak_pcmcia" | 27 | #define PCC_NAME "peak_pcmcia" |
| @@ -25,18 +25,6 @@ · 24 unmodified lines | |||
| 25 | MODULE_AUTHOR("Pavel Cheblakov <P.B.Cheblakov@inp.nsk.su>"); | 25 | MODULE_AUTHOR("Pavel Cheblakov <P.B.Cheblakov@inp.nsk.su>"); |
| 26 | MODULE_DESCRIPTION("Socket-CAN driver for PLX90xx PCI-bridge cards with " | 26 | MODULE_DESCRIPTION("Socket-CAN driver for PLX90xx PCI-bridge cards with " |
| 27 | "the SJA1000 chips"); | 27 | "the SJA1000 chips"); |
| 28 | MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " | ||
| 29 | "Adlink PCI-7841/cPCI-7841 SE, " | ||
| 30 | "Marathon CAN-bus-PCI, " | ||
| 31 | "Marathon CAN-bus-PCIe, " | ||
| 32 | "TEWS TECHNOLOGIES TPMC810, " | ||
| 33 | "esd CAN-PCI/CPCI/PCI104/200, " | ||
| 34 | "esd CAN-PCI/PMC/266, " | ||
| 35 | "esd CAN-PCIe/2000, " | ||
| 36 | "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), " | ||
| 37 | "IXXAT PC-I 04/PCI, " | ||
| 38 | "ELCUS CAN-200-PCI, " | ||
| 39 | "ASEM DUAL CAN-RAW") | ||
| 40 | MODULE_LICENSE("GPL v2"); | 28 | MODULE_LICENSE("GPL v2"); |
| 41 | 29 | ||
| 42 | #define PLX_PCI_MAX_CHAN 2 | 30 | #define PLX_PCI_MAX_CHAN 2 |
| @@ -73,6 +73,7 @@ config CAN_KVASER_USB · 72 unmodified lines | |||
| 73 | - Kvaser Memorator Pro 5xHS | 73 | - Kvaser Memorator Pro 5xHS |
| 74 | - Kvaser USBcan Light 4xHS | 74 | - Kvaser USBcan Light 4xHS |
| 75 | - Kvaser USBcan Pro 2xHS v2 | 75 | - Kvaser USBcan Pro 2xHS v2 |
| 76 | - Kvaser USBcan Pro 4xHS | ||
| 76 | - Kvaser USBcan Pro 5xHS | 77 | - Kvaser USBcan Pro 5xHS |
| 77 | - Kvaser U100 | 78 | - Kvaser U100 |
| 78 | - Kvaser U100P | 79 | - Kvaser U100P |
| @@ -86,8 +86,9 @@ · 85 unmodified lines | |||
| 86 | #define USB_U100_PRODUCT_ID 273 | 86 | #define USB_U100_PRODUCT_ID 273 |
| 87 | #define USB_U100P_PRODUCT_ID 274 | 87 | #define USB_U100P_PRODUCT_ID 274 |
| 88 | #define USB_U100S_PRODUCT_ID 275 | 88 | #define USB_U100S_PRODUCT_ID 275 |
| 89 | #define USB_USBCAN_PRO_4HS_PRODUCT_ID 276 | ||
| 89 | #define USB_HYDRA_PRODUCT_ID_END \ | 90 | #define USB_HYDRA_PRODUCT_ID_END \ |
| 90 | USB_U100S_PRODUCT_ID | 91 | USB_USBCAN_PRO_4HS_PRODUCT_ID |
| 91 | 92 | ||
| 92 | static inline bool kvaser_is_leaf(const struct usb_device_id *id) | 93 | static inline bool kvaser_is_leaf(const struct usb_device_id *id) |
| 93 | { | 94 | { |
| @@ -193,6 +194,7 @@ static const struct usb_device_id kvaser_usb_table[] = { · 99 unmodified lines | |||
| 193 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) }, | 194 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) }, |
| 194 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) }, | 195 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) }, |
| 195 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) }, | 196 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) }, |
| 197 | { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID) }, | ||
| 196 | { } | 198 | { } |
| 197 | }; | 199 | }; |
| 198 | MODULE_DEVICE_TABLE(usb, kvaser_usb_table); | 200 | MODULE_DEVICE_TABLE(usb, kvaser_usb_table); |
| @@ -18,8 +18,6 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #include "pcan_usb_core.h" | 19 | #include "pcan_usb_core.h" |
| 20 | 20 | ||
| 21 | MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB adapter"); | ||
| 22 | |||
| 23 | /* PCAN-USB Endpoints */ | 21 | /* PCAN-USB Endpoints */ |
| 24 | #define PCAN_USB_EP_CMDOUT 1 | 22 | #define PCAN_USB_EP_CMDOUT 1 |
| 25 | #define PCAN_USB_EP_CMDIN (PCAN_USB_EP_CMDOUT | USB_DIR_IN) | 23 | #define PCAN_USB_EP_CMDIN (PCAN_USB_EP_CMDOUT | USB_DIR_IN) |
| @@ -16,9 +16,6 @@ · 15 unmodified lines | |||
| 16 | #include "pcan_usb_core.h" | 16 | #include "pcan_usb_core.h" |
| 17 | #include "pcan_usb_pro.h" | 17 | #include "pcan_usb_pro.h" |
| 18 | 18 | ||
| 19 | MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB FD adapter"); | ||
| 20 | MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB Pro FD adapter"); | ||
| 21 | |||
| 22 | #define PCAN_USBPROFD_CHANNEL_COUNT 2 | 19 | #define PCAN_USBPROFD_CHANNEL_COUNT 2 |
| 23 | #define PCAN_USBFD_CHANNEL_COUNT 1 | 20 | #define PCAN_USBFD_CHANNEL_COUNT 1 |
| 24 | 21 | ||
| @@ -17,8 +17,6 @@ · 16 unmodified lines | |||
| 17 | #include "pcan_usb_core.h" | 17 | #include "pcan_usb_core.h" |
| 18 | #include "pcan_usb_pro.h" | 18 | #include "pcan_usb_pro.h" |
| 19 | 19 | ||
| 20 | MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB Pro adapter"); | ||
| 21 | |||
| 22 | #define PCAN_USBPRO_CHANNEL_COUNT 2 | 20 | #define PCAN_USBPRO_CHANNEL_COUNT 2 |
| 23 | 21 | ||
| 24 | /* PCAN-USB Pro adapter internal clock (MHz) */ | 22 | /* PCAN-USB Pro adapter internal clock (MHz) */ |
| @@ -1108,13 +1108,6 @@ static int b53_setup(struct dsa_switch *ds) · 1107 unmodified lines | |||
| 1108 | b53_disable_port(ds, port); | 1108 | b53_disable_port(ds, port); |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | /* Let DSA handle the case were multiple bridges span the same switch | ||
| 1112 | * device and different VLAN awareness settings are requested, which | ||
| 1113 | * would be breaking filtering semantics for any of the other bridge | ||
| 1114 | * devices. (not hardware supported) | ||
| 1115 | */ | ||
| 1116 | ds->vlan_filtering_is_global = true; | ||
| 1117 | |||
| 1118 | return b53_setup_devlink_resources(ds); | 1111 | return b53_setup_devlink_resources(ds); |
| 1119 | } | 1112 | } |
| 1120 | 1113 | ||
| @@ -2669,6 +2662,13 @@ struct b53_device *b53_switch_alloc(struct device *base, · 1548 unmodified lines | |||
| 2669 | ds->ops = &b53_switch_ops; | 2662 | ds->ops = &b53_switch_ops; |
| 2670 | ds->untag_bridge_pvid = true; | 2663 | ds->untag_bridge_pvid = true; |
| 2671 | dev->vlan_enabled = true; | 2664 | dev->vlan_enabled = true; |
| 2665 | /* Let DSA handle the case were multiple bridges span the same switch | ||
| 2666 | * device and different VLAN awareness settings are requested, which | ||
| 2667 | * would be breaking filtering semantics for any of the other bridge | ||
| 2668 | * devices. (not hardware supported) | ||
| 2669 | */ | ||
| 2670 | ds->vlan_filtering_is_global = true; | ||
| 2671 | |||
| 2672 | mutex_init(&dev->reg_mutex); | 2672 | mutex_init(&dev->reg_mutex); |
| 2673 | mutex_init(&dev->stats_mutex); | 2673 | mutex_init(&dev->stats_mutex); |
| 2674 | 2674 | ||
| @@ -144,7 +144,10 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) · 143 unmodified lines | |||
| 144 | /* Force link status for IMP port */ | 144 | /* Force link status for IMP port */ |
| 145 | reg = core_readl(priv, offset); | 145 | reg = core_readl(priv, offset); |
| 146 | reg |= (MII_SW_OR | LINK_STS); | 146 | reg |= (MII_SW_OR | LINK_STS); |
| 147 | reg &= ~GMII_SPEED_UP_2G; | 147 | if (priv->type == BCM4908_DEVICE_ID) |
| 148 | reg |= GMII_SPEED_UP_2G; | ||
| 149 | else | ||
| 150 | reg &= ~GMII_SPEED_UP_2G; | ||
| 148 | core_writel(priv, reg, offset); | 151 | core_writel(priv, reg, offset); |
| 149 | 152 | ||
| 150 | /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ | 153 | /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ |
| @@ -661,8 +664,10 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port) · 510 unmodified lines | |||
| 661 | * in bits 15:8 and the patch level in bits 7:0 which is exactly what | 664 | * in bits 15:8 and the patch level in bits 7:0 which is exactly what |
| 662 | * the REG_PHY_REVISION register layout is. | 665 | * the REG_PHY_REVISION register layout is. |
| 663 | */ | 666 | */ |
| 664 | 667 | if (priv->int_phy_mask & BIT(port)) | |
| 665 | return priv->hw_params.gphy_rev; | 668 | return priv->hw_params.gphy_rev; |
| 669 | else | ||
| 670 | return 0; | ||
| 666 | } | 671 | } |
| 667 | 672 | ||
| 668 | static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port, | 673 | static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port, |
| @@ -436,34 +436,32 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) · 435 unmodified lines | |||
| 436 | TD_DM_DRVP(8) | TD_DM_DRVN(8)); | 436 | TD_DM_DRVP(8) | TD_DM_DRVN(8)); |
| 437 | 437 | ||
| 438 | /* Setup core clock for MT7530 */ | 438 | /* Setup core clock for MT7530 */ |
| 439 | if (!trgint) { | 439 | /* Disable MT7530 core clock */ |
| 440 | /* Disable MT7530 core clock */ | 440 | core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); |
| 441 | core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); | ||
| 442 | |||
| 443 | /* Disable PLL, since phy_device has not yet been created | ||
| 444 | * provided for phy_[read,write]_mmd_indirect is called, we | ||
| 445 | * provide our own core_write_mmd_indirect to complete this | ||
| 446 | * function. | ||
| 447 | */ | ||
| 448 | core_write_mmd_indirect(priv, | ||
| 449 | CORE_GSWPLL_GRP1, | ||
| 450 | MDIO_MMD_VEND2, | ||
| 451 | 0); | ||
| 452 | |||
| 453 | /* Set core clock into 500Mhz */ | ||
| 454 | core_write(priv, CORE_GSWPLL_GRP2, | ||
| 455 | RG_GSWPLL_POSDIV_500M(1) | | ||
| 456 | RG_GSWPLL_FBKDIV_500M(25)); | ||
| 457 | 441 | ||
| 458 | /* Enable PLL */ | 442 | /* Disable PLL, since phy_device has not yet been created |
| 459 | core_write(priv, CORE_GSWPLL_GRP1, | 443 | * provided for phy_[read,write]_mmd_indirect is called, we |
| 460 | RG_GSWPLL_EN_PRE | | 444 | * provide our own core_write_mmd_indirect to complete this |
| 461 | RG_GSWPLL_POSDIV_200M(2) | | 445 | * function. |
| 462 | RG_GSWPLL_FBKDIV_200M(32)); | 446 | */ |
| 463 | 447 | core_write_mmd_indirect(priv, | |
| 464 | /* Enable MT7530 core clock */ | 448 | CORE_GSWPLL_GRP1, |
| 465 | core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); | 449 | MDIO_MMD_VEND2, |
| 466 | } | 450 | 0); |
| 451 | |||
| 452 | /* Set core clock into 500Mhz */ | ||
| 453 | core_write(priv, CORE_GSWPLL_GRP2, | ||
| 454 | RG_GSWPLL_POSDIV_500M(1) | | ||
| 455 | RG_GSWPLL_FBKDIV_500M(25)); | ||
| 456 | |||
| 457 | /* Enable PLL */ | ||
| 458 | core_write(priv, CORE_GSWPLL_GRP1, | ||
| 459 | RG_GSWPLL_EN_PRE | | ||
| 460 | RG_GSWPLL_POSDIV_200M(2) | | ||
| 461 | RG_GSWPLL_FBKDIV_200M(32)); | ||
| 462 | |||
| 463 | /* Enable MT7530 core clock */ | ||
| 464 | core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); | ||
| 467 | 465 | ||
| 468 | /* Setup the MT7530 TRGMII Tx Clock */ | 466 | /* Setup the MT7530 TRGMII Tx Clock */ |
| 469 | core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); | 467 | core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); |
| @@ -54,7 +54,7 @@ config B44_PCI · 53 unmodified lines | |||
| 54 | config BCM4908_ENET | 54 | config BCM4908_ENET |
| 55 | tristate "Broadcom BCM4908 internal mac support" | 55 | tristate "Broadcom BCM4908 internal mac support" |
| 56 | depends on ARCH_BCM4908 || COMPILE_TEST | 56 | depends on ARCH_BCM4908 || COMPILE_TEST |
| 57 | default y | 57 | default y if ARCH_BCM4908 |
| 58 | help | 58 | help |
| 59 | This driver supports Ethernet controller integrated into Broadcom | 59 | This driver supports Ethernet controller integrated into Broadcom |
| 60 | BCM4908 family SoCs. | 60 | BCM4908 family SoCs. |
| @@ -722,7 +722,7 @@ static int chcr_ktls_cpl_set_tcb_rpl(struct adapter *adap, unsigned char *input) · 721 unmodified lines | |||
| 722 | kvfree(tx_info); | 722 | kvfree(tx_info); |
| 723 | return 0; | 723 | return 0; |
| 724 | } | 724 | } |
| 725 | tx_info->open_state = false; | 725 | tx_info->open_state = CH_KTLS_OPEN_SUCCESS; |
| 726 | spin_unlock(&tx_info->lock); | 726 | spin_unlock(&tx_info->lock); |
| 727 | 727 | ||
| 728 | complete(&tx_info->completion); | 728 | complete(&tx_info->completion); |
| @@ -1337,6 +1337,7 @@ static int ftgmac100_poll(struct napi_struct *napi, int budget) · 1336 unmodified lines | |||
| 1337 | */ | 1337 | */ |
| 1338 | if (unlikely(priv->need_mac_restart)) { | 1338 | if (unlikely(priv->need_mac_restart)) { |
| 1339 | ftgmac100_start_hw(priv); | 1339 | ftgmac100_start_hw(priv); |
| 1340 | priv->need_mac_restart = false; | ||
| 1340 | 1341 | ||
| 1341 | /* Re-enable "bad" interrupts */ | 1342 | /* Re-enable "bad" interrupts */ |
| 1342 | iowrite32(FTGMAC100_INT_BAD, | 1343 | iowrite32(FTGMAC100_INT_BAD, |
| @@ -899,6 +899,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) · 898 unmodified lines | |||
| 899 | } else { | 899 | } else { |
| 900 | data &= ~IGP02E1000_PM_D0_LPLU; | 900 | data &= ~IGP02E1000_PM_D0_LPLU; |
| 901 | ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); | 901 | ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); |
| 902 | if (ret_val) | ||
| 903 | return ret_val; | ||
| 902 | /* LPLU and SmartSpeed are mutually exclusive. LPLU is used | 904 | /* LPLU and SmartSpeed are mutually exclusive. LPLU is used |
| 903 | * during Dx states where the power conservation is most | 905 | * during Dx states where the power conservation is most |
| 904 | * important. During driver activity we should enable | 906 | * important. During driver activity we should enable |
| @@ -1,8 +1,8 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* Copyright(c) 1999 - 2018 Intel Corporation. */ | 2 | /* Copyright(c) 1999 - 2018 Intel Corporation. */ |
| 3 | 3 | ||
| 4 | #ifndef _E1000_HW_H_ | 4 | #ifndef _E1000E_HW_H_ |
| 5 | #define _E1000_HW_H_ | 5 | #define _E1000E_HW_H_ |
| 6 | 6 | ||
| 7 | #include "regs.h" | 7 | #include "regs.h" |
| 8 | #include "defines.h" | 8 | #include "defines.h" |
| @@ -714,4 +714,4 @@ struct e1000_hw { · 705 unmodified lines | |||
| 714 | #include "80003es2lan.h" | 714 | #include "80003es2lan.h" |
| 715 | #include "ich8lan.h" | 715 | #include "ich8lan.h" |
| 716 | 716 | ||
| 717 | #endif | 717 | #endif /* _E1000E_HW_H_ */ |
| @@ -5975,15 +5975,19 @@ static void e1000_reset_task(struct work_struct *work) · 5974 unmodified lines | |||
| 5975 | struct e1000_adapter *adapter; | 5975 | struct e1000_adapter *adapter; |
| 5976 | adapter = container_of(work, struct e1000_adapter, reset_task); | 5976 | adapter = container_of(work, struct e1000_adapter, reset_task); |
| 5977 | 5977 | ||
| 5978 | rtnl_lock(); | ||
| 5978 | /* don't run the task if already down */ | 5979 | /* don't run the task if already down */ |
| 5979 | if (test_bit(__E1000_DOWN, &adapter->state)) | 5980 | if (test_bit(__E1000_DOWN, &adapter->state)) { |
| 5981 | rtnl_unlock(); | ||
| 5980 | return; | 5982 | return; |
| 5983 | } | ||
| 5981 | 5984 | ||
| 5982 | if (!(adapter->flags & FLAG_RESTART_NOW)) { | 5985 | if (!(adapter->flags & FLAG_RESTART_NOW)) { |
| 5983 | e1000e_dump(adapter); | 5986 | e1000e_dump(adapter); |
| 5984 | e_err("Reset adapter unexpectedly\n"); | 5987 | e_err("Reset adapter unexpectedly\n"); |
| 5985 | } | 5988 | } |
| 5986 | e1000e_reinit_locked(adapter); | 5989 | e1000e_reinit_locked(adapter); |
| 5990 | rtnl_unlock(); | ||
| 5987 | } | 5991 | } |
| 5988 | 5992 | ||
| 5989 | /** | 5993 | /** |
| @@ -3258,6 +3258,17 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring) · 3257 unmodified lines | |||
| 3258 | return 0; | 3258 | return 0; |
| 3259 | } | 3259 | } |
| 3260 | 3260 | ||
| 3261 | /** | ||
| 3262 | * i40e_rx_offset - Return expected offset into page to access data | ||
| 3263 | * @rx_ring: Ring we are requesting offset of | ||
| 3264 | * | ||
| 3265 | * Returns the offset value for ring into the data buffer. | ||
| 3266 | */ | ||
| 3267 | static unsigned int i40e_rx_offset(struct i40e_ring *rx_ring) | ||
| 3268 | { | ||
| 3269 | return ring_uses_build_skb(rx_ring) ? I40E_SKB_PAD : 0; | ||
| 3270 | } | ||
| 3271 | |||
| 3261 | /** | 3272 | /** |
| 3262 | * i40e_configure_rx_ring - Configure a receive ring context | 3273 | * i40e_configure_rx_ring - Configure a receive ring context |
| 3263 | * @ring: The Rx ring to configure | 3274 | * @ring: The Rx ring to configure |
| @@ -3369,6 +3380,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) · 105 unmodified lines | |||
| 3369 | else | 3380 | else |
| 3370 | set_ring_build_skb_enabled(ring); | 3381 | set_ring_build_skb_enabled(ring); |
| 3371 | 3382 | ||
| 3383 | ring->rx_offset = i40e_rx_offset(ring); | ||
| 3384 | |||
| 3372 | /* cache tail for quicker writes, and clear the reg before use */ | 3385 | /* cache tail for quicker writes, and clear the reg before use */ |
| 3373 | ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q); | 3386 | ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q); |
| 3374 | writel(0, ring->tail); | 3387 | writel(0, ring->tail); |
| @@ -1569,17 +1569,6 @@ void i40e_free_rx_resources(struct i40e_ring *rx_ring) · 1568 unmodified lines | |||
| 1569 | } | 1569 | } |
| 1570 | } | 1570 | } |
| 1571 | 1571 | ||
| 1572 | /** | ||
| 1573 | * i40e_rx_offset - Return expected offset into page to access data | ||
| 1574 | * @rx_ring: Ring we are requesting offset of | ||
| 1575 | * | ||
| 1576 | * Returns the offset value for ring into the data buffer. | ||
| 1577 | */ | ||
| 1578 | static unsigned int i40e_rx_offset(struct i40e_ring *rx_ring) | ||
| 1579 | { | ||
| 1580 | return ring_uses_build_skb(rx_ring) ? I40E_SKB_PAD : 0; | ||
| 1581 | } | ||
| 1582 | |||
| 1583 | /** | 1572 | /** |
| 1584 | * i40e_setup_rx_descriptors - Allocate Rx descriptors | 1573 | * i40e_setup_rx_descriptors - Allocate Rx descriptors |
| 1585 | * @rx_ring: Rx descriptor ring (for a specific queue) to setup | 1574 | * @rx_ring: Rx descriptor ring (for a specific queue) to setup |
| @@ -1608,7 +1597,6 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) · 22 unmodified lines | |||
| 1608 | rx_ring->next_to_alloc = 0; | 1597 | rx_ring->next_to_alloc = 0; |
| 1609 | rx_ring->next_to_clean = 0; | 1598 | rx_ring->next_to_clean = 0; |
| 1610 | rx_ring->next_to_use = 0; | 1599 | rx_ring->next_to_use = 0; |
| 1611 | rx_ring->rx_offset = i40e_rx_offset(rx_ring); | ||
| 1612 | 1600 | ||
| 1613 | /* XDP RX-queue info only needed for RX rings exposed to XDP */ | 1601 | /* XDP RX-queue info only needed for RX rings exposed to XDP */ |
| 1614 | if (rx_ring->vsi->type == I40E_VSI_MAIN) { | 1602 | if (rx_ring->vsi->type == I40E_VSI_MAIN) { |
| @@ -274,6 +274,22 @@ ice_setup_tx_ctx(struct ice_ring *ring, struct ice_tlan_ctx *tlan_ctx, u16 pf_q) · 273 unmodified lines | |||
| 274 | tlan_ctx->legacy_int = ICE_TX_LEGACY; | 274 | tlan_ctx->legacy_int = ICE_TX_LEGACY; |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | /** | ||
| 278 | * ice_rx_offset - Return expected offset into page to access data | ||
| 279 | * @rx_ring: Ring we are requesting offset of | ||
| 280 | * | ||
| 281 | * Returns the offset value for ring into the data buffer. | ||
| 282 | */ | ||
| 283 | static unsigned int ice_rx_offset(struct ice_ring *rx_ring) | ||
| 284 | { | ||
| 285 | if (ice_ring_uses_build_skb(rx_ring)) | ||
| 286 | return ICE_SKB_PAD; | ||
| 287 | else if (ice_is_xdp_ena_vsi(rx_ring->vsi)) | ||
| 288 | return XDP_PACKET_HEADROOM; | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 277 | /** | 293 | /** |
| 278 | * ice_setup_rx_ctx - Configure a receive ring context | 294 | * ice_setup_rx_ctx - Configure a receive ring context |
| 279 | * @ring: The Rx ring to configure | 295 | * @ring: The Rx ring to configure |
| @@ -413,11 +429,15 @@ int ice_setup_rx_ctx(struct ice_ring *ring) · 133 unmodified lines | |||
| 413 | else | 429 | else |
| 414 | ice_set_ring_build_skb_ena(ring); | 430 | ice_set_ring_build_skb_ena(ring); |
| 415 | 431 | ||
| 432 | ring->rx_offset = ice_rx_offset(ring); | ||
| 433 | |||
| 416 | /* init queue specific tail register */ | 434 | /* init queue specific tail register */ |
| 417 | ring->tail = hw->hw_addr + QRX_TAIL(pf_q); | 435 | ring->tail = hw->hw_addr + QRX_TAIL(pf_q); |
| 418 | writel(0, ring->tail); | 436 | writel(0, ring->tail); |
| 419 | 437 | ||
| 420 | if (ring->xsk_pool) { | 438 | if (ring->xsk_pool) { |
| 439 | bool ok; | ||
| 440 | |||
| 421 | if (!xsk_buff_can_alloc(ring->xsk_pool, num_bufs)) { | 441 | if (!xsk_buff_can_alloc(ring->xsk_pool, num_bufs)) { |
| 422 | dev_warn(dev, "XSK buffer pool does not provide enough addresses to fill %d buffers on Rx ring %d\n", | 442 | dev_warn(dev, "XSK buffer pool does not provide enough addresses to fill %d buffers on Rx ring %d\n", |
| 423 | num_bufs, ring->q_index); | 443 | num_bufs, ring->q_index); |
| @@ -426,8 +446,8 @@ int ice_setup_rx_ctx(struct ice_ring *ring) · 2 unmodified lines | |||
| 426 | return 0; | 446 | return 0; |
| 427 | } | 447 | } |
| 428 | 448 | ||
| 429 | err = ice_alloc_rx_bufs_zc(ring, num_bufs); | 449 | ok = ice_alloc_rx_bufs_zc(ring, num_bufs); |
| 430 | if (err) | 450 | if (!ok) |
| 431 | dev_info(dev, "Failed to allocate some buffers on XSK buffer pool enabled Rx ring %d (pf_q %d)\n", | 451 | dev_info(dev, "Failed to allocate some buffers on XSK buffer pool enabled Rx ring %d (pf_q %d)\n", |
| 432 | ring->q_index, pf_q); | 452 | ring->q_index, pf_q); |
| 433 | return 0; | 453 | return 0; |
| @@ -443,22 +443,6 @@ void ice_free_rx_ring(struct ice_ring *rx_ring) · 442 unmodified lines | |||
| 443 | } | 443 | } |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | /** | ||
| 447 | * ice_rx_offset - Return expected offset into page to access data | ||
| 448 | * @rx_ring: Ring we are requesting offset of | ||
| 449 | * | ||
| 450 | * Returns the offset value for ring into the data buffer. | ||
| 451 | */ | ||
| 452 | static unsigned int ice_rx_offset(struct ice_ring *rx_ring) | ||
| 453 | { | ||
| 454 | if (ice_ring_uses_build_skb(rx_ring)) | ||
| 455 | return ICE_SKB_PAD; | ||
| 456 | else if (ice_is_xdp_ena_vsi(rx_ring->vsi)) | ||
| 457 | return XDP_PACKET_HEADROOM; | ||
| 458 | |||
| 459 | return 0; | ||
| 460 | } | ||
| 461 | |||
| 462 | /** | 446 | /** |
| 463 | * ice_setup_rx_ring - Allocate the Rx descriptors | 447 | * ice_setup_rx_ring - Allocate the Rx descriptors |
| 464 | * @rx_ring: the Rx ring to set up | 448 | * @rx_ring: the Rx ring to set up |
| @@ -493,7 +477,6 @@ int ice_setup_rx_ring(struct ice_ring *rx_ring) · 28 unmodified lines | |||
| 493 | 477 | ||
| 494 | rx_ring->next_to_use = 0; | 478 | rx_ring->next_to_use = 0; |
| 495 | rx_ring->next_to_clean = 0; | 479 | rx_ring->next_to_clean = 0; |
| 496 | rx_ring->rx_offset = ice_rx_offset(rx_ring); | ||
| 497 | 480 | ||
| 498 | if (ice_is_xdp_ena_vsi(rx_ring->vsi)) | 481 | if (ice_is_xdp_ena_vsi(rx_ring->vsi)) |
| 499 | WRITE_ONCE(rx_ring->xdp_prog, rx_ring->vsi->xdp_prog); | 482 | WRITE_ONCE(rx_ring->xdp_prog, rx_ring->vsi->xdp_prog); |
| @@ -358,18 +358,18 @@ xsk_pool_if_up: · 357 unmodified lines | |||
| 358 | * This function allocates a number of Rx buffers from the fill ring | 358 | * This function allocates a number of Rx buffers from the fill ring |
| 359 | * or the internal recycle mechanism and places them on the Rx ring. | 359 | * or the internal recycle mechanism and places them on the Rx ring. |
| 360 | * | 360 | * |
| 361 | * Returns false if all allocations were successful, true if any fail. | 361 | * Returns true if all allocations were successful, false if any fail. |
| 362 | */ | 362 | */ |
| 363 | bool ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, u16 count) | 363 | bool ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, u16 count) |
| 364 | { | 364 | { |
| 365 | union ice_32b_rx_flex_desc *rx_desc; | 365 | union ice_32b_rx_flex_desc *rx_desc; |
| 366 | u16 ntu = rx_ring->next_to_use; | 366 | u16 ntu = rx_ring->next_to_use; |
| 367 | struct ice_rx_buf *rx_buf; | 367 | struct ice_rx_buf *rx_buf; |
| 368 | bool ret = false; | 368 | bool ok = true; |
| 369 | dma_addr_t dma; | 369 | dma_addr_t dma; |
| 370 | 370 | ||
| 371 | if (!count) | 371 | if (!count) |
| 372 | return false; | 372 | return true; |
| 373 | 373 | ||
| 374 | rx_desc = ICE_RX_DESC(rx_ring, ntu); | 374 | rx_desc = ICE_RX_DESC(rx_ring, ntu); |
| 375 | rx_buf = &rx_ring->rx_buf[ntu]; | 375 | rx_buf = &rx_ring->rx_buf[ntu]; |
| @@ -377,7 +377,7 @@ bool ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, u16 count) · 1 unmodified line | |||
| 377 | do { | 377 | do { |
| 378 | rx_buf->xdp = xsk_buff_alloc(rx_ring->xsk_pool); | 378 | rx_buf->xdp = xsk_buff_alloc(rx_ring->xsk_pool); |
| 379 | if (!rx_buf->xdp) { | 379 | if (!rx_buf->xdp) { |
| 380 | ret = true; | 380 | ok = false; |
| 381 | break; | 381 | break; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| @@ -402,7 +402,7 @@ bool ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, u16 count) · 18 unmodified lines | |||
| 402 | ice_release_rx_desc(rx_ring, ntu); | 402 | ice_release_rx_desc(rx_ring, ntu); |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | return ret; | 405 | return ok; |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | /** | 408 | /** |
| @@ -1,8 +1,8 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* Copyright(c) 2007 - 2018 Intel Corporation. */ | 2 | /* Copyright(c) 2007 - 2018 Intel Corporation. */ |
| 3 | 3 | ||
| 4 | #ifndef _E1000_HW_H_ | 4 | #ifndef _E1000_IGB_HW_H_ |
| 5 | #define _E1000_HW_H_ | 5 | #define _E1000_IGB_HW_H_ |
| 6 | 6 | ||
| 7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
| 8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
| @@ -551,4 +551,4 @@ s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); · 542 unmodified lines | |||
| 551 | 551 | ||
| 552 | void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); | 552 | void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); |
| 553 | void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); | 553 | void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); |
| 554 | #endif /* _E1000_HW_H_ */ | 554 | #endif /* _E1000_IGB_HW_H_ */ |
| @@ -748,8 +748,8 @@ void igb_ptp_suspend(struct igb_adapter *adapter); · 747 unmodified lines | |||
| 748 | void igb_ptp_rx_hang(struct igb_adapter *adapter); | 748 | void igb_ptp_rx_hang(struct igb_adapter *adapter); |
| 749 | void igb_ptp_tx_hang(struct igb_adapter *adapter); | 749 | void igb_ptp_tx_hang(struct igb_adapter *adapter); |
| 750 | void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); | 750 | void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); |
| 751 | void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, | 751 | int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, |
| 752 | struct sk_buff *skb); | 752 | struct sk_buff *skb); |
| 753 | int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); | 753 | int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| 754 | int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); | 754 | int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| 755 | void igb_set_flag_queue_pairs(struct igb_adapter *, const u32); | 755 | void igb_set_flag_queue_pairs(struct igb_adapter *, const u32); |
| @@ -8214,7 +8214,8 @@ static void igb_reuse_rx_page(struct igb_ring *rx_ring, · 8213 unmodified lines | |||
| 8214 | new_buff->pagecnt_bias = old_buff->pagecnt_bias; | 8214 | new_buff->pagecnt_bias = old_buff->pagecnt_bias; |
| 8215 | } | 8215 | } |
| 8216 | 8216 | ||
| 8217 | static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer) | 8217 | static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, |
| 8218 | int rx_buf_pgcnt) | ||
| 8218 | { | 8219 | { |
| 8219 | unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; | 8220 | unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; |
| 8220 | struct page *page = rx_buffer->page; | 8221 | struct page *page = rx_buffer->page; |
| @@ -8225,7 +8226,7 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer) · 4 unmodified lines | |||
| 8225 | 8226 | ||
| 8226 | #if (PAGE_SIZE < 8192) | 8227 | #if (PAGE_SIZE < 8192) |
| 8227 | /* if we are only owner of page we can reuse it */ | 8228 | /* if we are only owner of page we can reuse it */ |
| 8228 | if (unlikely((page_ref_count(page) - pagecnt_bias) > 1)) | 8229 | if (unlikely((rx_buf_pgcnt - pagecnt_bias) > 1)) |
| 8229 | return false; | 8230 | return false; |
| 8230 | #else | 8231 | #else |
| 8231 | #define IGB_LAST_OFFSET \ | 8232 | #define IGB_LAST_OFFSET \ |
| @@ -8301,9 +8302,10 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring, · 69 unmodified lines | |||
| 8301 | return NULL; | 8302 | return NULL; |
| 8302 | 8303 | ||
| 8303 | if (unlikely(igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))) { | 8304 | if (unlikely(igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))) { |
| 8304 | igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb); | 8305 | if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb)) { |
| 8305 | xdp->data += IGB_TS_HDR_LEN; | 8306 | xdp->data += IGB_TS_HDR_LEN; |
| 8306 | size -= IGB_TS_HDR_LEN; | 8307 | size -= IGB_TS_HDR_LEN; |
| 8308 | } | ||
| 8307 | } | 8309 | } |
| 8308 | 8310 | ||
| 8309 | /* Determine available headroom for copy */ | 8311 | /* Determine available headroom for copy */ |
| @@ -8364,8 +8366,8 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring, · 54 unmodified lines | |||
| 8364 | 8366 | ||
| 8365 | /* pull timestamp out of packet data */ | 8367 | /* pull timestamp out of packet data */ |
| 8366 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { | 8368 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { |
| 8367 | igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb); | 8369 | if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb)) |
| 8368 | __skb_pull(skb, IGB_TS_HDR_LEN); | 8370 | __skb_pull(skb, IGB_TS_HDR_LEN); |
| 8369 | } | 8371 | } |
| 8370 | 8372 | ||
| 8371 | /* update buffer offset */ | 8373 | /* update buffer offset */ |
| @@ -8614,11 +8616,17 @@ static unsigned int igb_rx_offset(struct igb_ring *rx_ring) · 242 unmodified lines | |||
| 8614 | } | 8616 | } |
| 8615 | 8617 | ||
| 8616 | static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring, | 8618 | static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring, |
| 8617 | const unsigned int size) | 8619 | const unsigned int size, int *rx_buf_pgcnt) |
| 8618 | { | 8620 | { |
| 8619 | struct igb_rx_buffer *rx_buffer; | 8621 | struct igb_rx_buffer *rx_buffer; |
| 8620 | 8622 | ||
| 8621 | rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; | 8623 | rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; |
| 8624 | *rx_buf_pgcnt = | ||
| 8625 | #if (PAGE_SIZE < 8192) | ||
| 8626 | page_count(rx_buffer->page); | ||
| 8627 | #else | ||
| 8628 | 0; | ||
| 8629 | #endif | ||
| 8622 | prefetchw(rx_buffer->page); | 8630 | prefetchw(rx_buffer->page); |
| 8623 | 8631 | ||
| 8624 | /* we are reusing so sync this buffer for CPU use */ | 8632 | /* we are reusing so sync this buffer for CPU use */ |
| @@ -8634,9 +8642,9 @@ static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring, · 9 unmodified lines | |||
| 8634 | } | 8642 | } |
| 8635 | 8643 | ||
| 8636 | static void igb_put_rx_buffer(struct igb_ring *rx_ring, | 8644 | static void igb_put_rx_buffer(struct igb_ring *rx_ring, |
| 8637 | struct igb_rx_buffer *rx_buffer) | 8645 | struct igb_rx_buffer *rx_buffer, int rx_buf_pgcnt) |
| 8638 | { | 8646 | { |
| 8639 | if (igb_can_reuse_rx_page(rx_buffer)) { | 8647 | if (igb_can_reuse_rx_page(rx_buffer, rx_buf_pgcnt)) { |
| 8640 | /* hand second half of page back to the ring */ | 8648 | /* hand second half of page back to the ring */ |
| 8641 | igb_reuse_rx_page(rx_ring, rx_buffer); | 8649 | igb_reuse_rx_page(rx_ring, rx_buffer); |
| 8642 | } else { | 8650 | } else { |
| @@ -8664,6 +8672,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) · 21 unmodified lines | |||
| 8664 | unsigned int xdp_xmit = 0; | 8672 | unsigned int xdp_xmit = 0; |
| 8665 | struct xdp_buff xdp; | 8673 | struct xdp_buff xdp; |
| 8666 | u32 frame_sz = 0; | 8674 | u32 frame_sz = 0; |
| 8675 | int rx_buf_pgcnt; | ||
| 8667 | 8676 | ||
| 8668 | /* Frame size depend on rx_ring setup when PAGE_SIZE=4K */ | 8677 | /* Frame size depend on rx_ring setup when PAGE_SIZE=4K */ |
| 8669 | #if (PAGE_SIZE < 8192) | 8678 | #if (PAGE_SIZE < 8192) |
| @@ -8693,7 +8702,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) · 23 unmodified lines | |||
| 8693 | */ | 8702 | */ |
| 8694 | dma_rmb(); | 8703 | dma_rmb(); |
| 8695 | 8704 | ||
| 8696 | rx_buffer = igb_get_rx_buffer(rx_ring, size); | 8705 | rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt); |
| 8697 | 8706 | ||
| 8698 | /* retrieve a buffer from the ring */ | 8707 | /* retrieve a buffer from the ring */ |
| 8699 | if (!skb) { | 8708 | if (!skb) { |
| @@ -8736,7 +8745,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) · 36 unmodified lines | |||
| 8736 | break; | 8745 | break; |
| 8737 | } | 8746 | } |
| 8738 | 8747 | ||
| 8739 | igb_put_rx_buffer(rx_ring, rx_buffer); | 8748 | igb_put_rx_buffer(rx_ring, rx_buffer, rx_buf_pgcnt); |
| 8740 | cleaned_count++; | 8749 | cleaned_count++; |
| 8741 | 8750 | ||
| 8742 | /* fetch next buffer in frame if non-eop */ | 8751 | /* fetch next buffer in frame if non-eop */ |
| @@ -856,6 +856,9 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) · 855 unmodified lines | |||
| 856 | dev_kfree_skb_any(skb); | 856 | dev_kfree_skb_any(skb); |
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | #define IGB_RET_PTP_DISABLED 1 | ||
| 860 | #define IGB_RET_PTP_INVALID 2 | ||
| 861 | |||
| 859 | /** | 862 | /** |
| 860 | * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp | 863 | * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp |
| 861 | * @q_vector: Pointer to interrupt specific structure | 864 | * @q_vector: Pointer to interrupt specific structure |
| @@ -864,19 +867,29 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) · 2 unmodified lines | |||
| 864 | * | 867 | * |
| 865 | * This function is meant to retrieve a timestamp from the first buffer of an | 868 | * This function is meant to retrieve a timestamp from the first buffer of an |
| 866 | * incoming frame. The value is stored in little endian format starting on | 869 | * incoming frame. The value is stored in little endian format starting on |
| 867 | * byte 8. | 870 | * byte 8 |
| 871 | * | ||
| 872 | * Returns: 0 if success, nonzero if failure | ||
| 868 | **/ | 873 | **/ |
| 869 | void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, | 874 | int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, |
| 870 | struct sk_buff *skb) | 875 | struct sk_buff *skb) |
| 871 | { | 876 | { |
| 872 | __le64 *regval = (__le64 *)va; | ||
| 873 | struct igb_adapter *adapter = q_vector->adapter; | 877 | struct igb_adapter *adapter = q_vector->adapter; |
| 878 | __le64 *regval = (__le64 *)va; | ||
| 874 | int adjust = 0; | 879 | int adjust = 0; |
| 875 | 880 | ||
| 881 | if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) | ||
| 882 | return IGB_RET_PTP_DISABLED; | ||
| 883 | |||
| 876 | /* The timestamp is recorded in little endian format. | 884 | /* The timestamp is recorded in little endian format. |
| 877 | * DWORD: 0 1 2 3 | 885 | * DWORD: 0 1 2 3 |
| 878 | * Field: Reserved Reserved SYSTIML SYSTIMH | 886 | * Field: Reserved Reserved SYSTIML SYSTIMH |
| 879 | */ | 887 | */ |
| 888 | |||
| 889 | /* check reserved dwords are zero, be/le doesn't matter for zero */ | ||
| 890 | if (regval[0]) | ||
| 891 | return IGB_RET_PTP_INVALID; | ||
| 892 | |||
| 880 | igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), | 893 | igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), |
| 881 | le64_to_cpu(regval[1])); | 894 | le64_to_cpu(regval[1])); |
| 882 | 895 | ||
| @@ -896,6 +909,8 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, · 13 unmodified lines | |||
| 896 | } | 909 | } |
| 897 | skb_hwtstamps(skb)->hwtstamp = | 910 | skb_hwtstamps(skb)->hwtstamp = |
| 898 | ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); | 911 | ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); |
| 912 | |||
| 913 | return 0; | ||
| 899 | } | 914 | } |
| 900 | 915 | ||
| 901 | /** | 916 | /** |
| @@ -906,13 +921,15 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, · 4 unmodified lines | |||
| 906 | * This function is meant to retrieve a timestamp from the internal registers | 921 | * This function is meant to retrieve a timestamp from the internal registers |
| 907 | * of the adapter and store it in the skb. | 922 | * of the adapter and store it in the skb. |
| 908 | **/ | 923 | **/ |
| 909 | void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, | 924 | void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb) |
| 910 | struct sk_buff *skb) | ||
| 911 | { | 925 | { |
| 912 | struct igb_adapter *adapter = q_vector->adapter; | 926 | struct igb_adapter *adapter = q_vector->adapter; |
| 913 | struct e1000_hw *hw = &adapter->hw; | 927 | struct e1000_hw *hw = &adapter->hw; |
| 914 | u64 regval; | ||
| 915 | int adjust = 0; | 928 | int adjust = 0; |
| 929 | u64 regval; | ||
| 930 | |||
| 931 | if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) | ||
| 932 | return; | ||
| 916 | 933 | ||
| 917 | /* If this bit is set, then the RX registers contain the time stamp. No | 934 | /* If this bit is set, then the RX registers contain the time stamp. No |
| 918 | * other packet will be time stamped until we read these registers, so | 935 | * other packet will be time stamped until we read these registers, so |
| @@ -547,7 +547,7 @@ void igc_ptp_init(struct igc_adapter *adapter); · 546 unmodified lines | |||
| 547 | void igc_ptp_reset(struct igc_adapter *adapter); | 547 | void igc_ptp_reset(struct igc_adapter *adapter); |
| 548 | void igc_ptp_suspend(struct igc_adapter *adapter); | 548 | void igc_ptp_suspend(struct igc_adapter *adapter); |
| 549 | void igc_ptp_stop(struct igc_adapter *adapter); | 549 | void igc_ptp_stop(struct igc_adapter *adapter); |
| 550 | void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va, | 550 | void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, __le32 *va, |
| 551 | struct sk_buff *skb); | 551 | struct sk_buff *skb); |
| 552 | int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); | 552 | int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| 553 | int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); | 553 | int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| @@ -1711,6 +1711,9 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, · 1710 unmodified lines | |||
| 1711 | Autoneg); | 1711 | Autoneg); |
| 1712 | } | 1712 | } |
| 1713 | 1713 | ||
| 1714 | /* Set pause flow control settings */ | ||
| 1715 | ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); | ||
| 1716 | |||
| 1714 | switch (hw->fc.requested_mode) { | 1717 | switch (hw->fc.requested_mode) { |
| 1715 | case igc_fc_full: | 1718 | case igc_fc_full: |
| 1716 | ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); | 1719 | ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); |
| @@ -1725,9 +1728,7 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, · 8 unmodified lines | |||
| 1725 | Asym_Pause); | 1728 | Asym_Pause); |
| 1726 | break; | 1729 | break; |
| 1727 | default: | 1730 | default: |
| 1728 | ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); | 1731 | break; |
| 1729 | ethtool_link_ksettings_add_link_mode(cmd, advertising, | ||
| 1730 | Asym_Pause); | ||
| 1731 | } | 1732 | } |
| 1732 | 1733 | ||
| 1733 | status = pm_runtime_suspended(&adapter->pdev->dev) ? | 1734 | status = pm_runtime_suspended(&adapter->pdev->dev) ? |
| @@ -3831,10 +3831,19 @@ static void igc_reset_task(struct work_struct *work) · 3830 unmodified lines | |||
| 3831 | 3831 | ||
| 3832 | adapter = container_of(work, struct igc_adapter, reset_task); | 3832 | adapter = container_of(work, struct igc_adapter, reset_task); |
| 3833 | 3833 | ||
| 3834 | rtnl_lock(); | ||
| 3835 | /* If we're already down or resetting, just bail */ | ||
| 3836 | if (test_bit(__IGC_DOWN, &adapter->state) || | ||
| 3837 | test_bit(__IGC_RESETTING, &adapter->state)) { | ||
| 3838 | rtnl_unlock(); | ||
| 3839 | return; | ||
| 3840 | } | ||
| 3841 | |||
| 3834 | igc_rings_dump(adapter); | 3842 | igc_rings_dump(adapter); |
| 3835 | igc_regs_dump(adapter); | 3843 | igc_regs_dump(adapter); |
| 3836 | netdev_err(adapter->netdev, "Reset adapter\n"); | 3844 | netdev_err(adapter->netdev, "Reset adapter\n"); |
| 3837 | igc_reinit_locked(adapter); | 3845 | igc_reinit_locked(adapter); |
| 3846 | rtnl_unlock(); | ||
| 3838 | } | 3847 | } |
| 3839 | 3848 | ||
| 3840 | /** | 3849 | /** |
| @@ -152,46 +152,54 @@ static void igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter, · 151 unmodified lines | |||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | /** | 154 | /** |
| 155 | * igc_ptp_rx_pktstamp - retrieve Rx per packet timestamp | 155 | * igc_ptp_rx_pktstamp - Retrieve timestamp from Rx packet buffer |
| 156 | * @q_vector: Pointer to interrupt specific structure | 156 | * @q_vector: Pointer to interrupt specific structure |
| 157 | * @va: Pointer to address containing Rx buffer | 157 | * @va: Pointer to address containing Rx buffer |
| 158 | * @skb: Buffer containing timestamp and packet | 158 | * @skb: Buffer containing timestamp and packet |
| 159 | * | 159 | * |
| 160 | * This function is meant to retrieve the first timestamp from the | 160 | * This function retrieves the timestamp saved in the beginning of packet |
| 161 | * first buffer of an incoming frame. The value is stored in little | 161 | * buffer. While two timestamps are available, one in timer0 reference and the |
| 162 | * endian format starting on byte 0. There's a second timestamp | 162 | * other in timer1 reference, this function considers only the timestamp in |
| 163 | * starting on byte 8. | 163 | * timer0 reference. |
| 164 | **/ | 164 | */ |
| 165 | void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va, | 165 | void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, __le32 *va, |
| 166 | struct sk_buff *skb) | 166 | struct sk_buff *skb) |
| 167 | { | 167 | { |
| 168 | struct igc_adapter *adapter = q_vector->adapter; | 168 | struct igc_adapter *adapter = q_vector->adapter; |
| 169 | __le64 *regval = (__le64 *)va; | 169 | u64 regval; |
| 170 | int adjust = 0; | 170 | int adjust; |
| 171 | 171 | ||
| 172 | /* The timestamp is recorded in little endian format. | 172 | /* Timestamps are saved in little endian at the beginning of the packet |
| 173 | * DWORD: | 0 | 1 | 2 | 3 | 173 | * buffer following the layout: |
| 174 | * Field: | Timer0 Low | Timer0 High | Timer1 Low | Timer1 High | 174 | * |
| 175 | * DWORD: | 0 | 1 | 2 | 3 | | ||
| 176 | * Field: | Timer1 SYSTIML | Timer1 SYSTIMH | Timer0 SYSTIML | Timer0 SYSTIMH | | ||
| 177 | * | ||
| 178 | * SYSTIML holds the nanoseconds part while SYSTIMH holds the seconds | ||
| 179 | * part of the timestamp. | ||
| 175 | */ | 180 | */ |
| 176 | igc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), | 181 | regval = le32_to_cpu(va[2]); |
| 177 | le64_to_cpu(regval[0])); | 182 | regval |= (u64)le32_to_cpu(va[3]) << 32; |
| 178 | 183 | igc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); | |
| 179 | /* adjust timestamp for the RX latency based on link speed */ | 184 | |
| 180 | if (adapter->hw.mac.type == igc_i225) { | 185 | /* Adjust timestamp for the RX latency based on link speed */ |
| 181 | switch (adapter->link_speed) { | 186 | switch (adapter->link_speed) { |
| 182 | case SPEED_10: | 187 | case SPEED_10: |
| 183 | adjust = IGC_I225_RX_LATENCY_10; | 188 | adjust = IGC_I225_RX_LATENCY_10; |
| 184 | break; | 189 | break; |
| 185 | case SPEED_100: | 190 | case SPEED_100: |
| 186 | adjust = IGC_I225_RX_LATENCY_100; | 191 | adjust = IGC_I225_RX_LATENCY_100; |
| 187 | break; | 192 | break; |
| 188 | case SPEED_1000: | 193 | case SPEED_1000: |
| 189 | adjust = IGC_I225_RX_LATENCY_1000; | 194 | adjust = IGC_I225_RX_LATENCY_1000; |
| 190 | break; | 195 | break; |
| 191 | case SPEED_2500: | 196 | case SPEED_2500: |
| 192 | adjust = IGC_I225_RX_LATENCY_2500; | 197 | adjust = IGC_I225_RX_LATENCY_2500; |
| 193 | break; | 198 | break; |
| 194 | } | 199 | default: |
| 200 | adjust = 0; | ||
| 201 | netdev_warn_once(adapter->netdev, "Imprecise timestamp\n"); | ||
| 202 | break; | ||
| 195 | } | 203 | } |
| 196 | skb_hwtstamps(skb)->hwtstamp = | 204 | skb_hwtstamps(skb)->hwtstamp = |
| 197 | ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); | 205 | ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); |
| @@ -4118,6 +4118,8 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, · 4117 unmodified lines | |||
| 4118 | #endif | 4118 | #endif |
| 4119 | } | 4119 | } |
| 4120 | 4120 | ||
| 4121 | ring->rx_offset = ixgbe_rx_offset(ring); | ||
| 4122 | |||
| 4121 | if (ring->xsk_pool && hw->mac.type != ixgbe_mac_82599EB) { | 4123 | if (ring->xsk_pool && hw->mac.type != ixgbe_mac_82599EB) { |
| 4122 | u32 xsk_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); | 4124 | u32 xsk_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); |
| 4123 | 4125 | ||
| @@ -6578,7 +6580,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, · 2454 unmodified lines | |||
| 6578 | 6580 | ||
| 6579 | rx_ring->next_to_clean = 0; | 6581 | rx_ring->next_to_clean = 0; |
| 6580 | rx_ring->next_to_use = 0; | 6582 | rx_ring->next_to_use = 0; |
| 6581 | rx_ring->rx_offset = ixgbe_rx_offset(rx_ring); | ||
| 6582 | 6583 | ||
| 6583 | /* XDP RX-queue info */ | 6584 | /* XDP RX-queue info */ |
| 6584 | if (xdp_rxq_info_reg(&rx_ring->xdp_rxq, adapter->netdev, | 6585 | if (xdp_rxq_info_reg(&rx_ring->xdp_rxq, adapter->netdev, |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | config NET_VENDOR_MARVELL | 6 | config NET_VENDOR_MARVELL |
| 7 | bool "Marvell devices" | 7 | bool "Marvell devices" |
| 8 | default y | 8 | default y |
| 9 | depends on PCI || CPU_PXA168 || MV64X60 || PPC32 || PLAT_ORION || INET || COMPILE_TEST | 9 | depends on PCI || CPU_PXA168 || PPC32 || PLAT_ORION || INET || COMPILE_TEST |
| 10 | help | 10 | help |
| 11 | If you have a network (Ethernet) card belonging to this class, say Y. | 11 | If you have a network (Ethernet) card belonging to this class, say Y. |
| 12 | 12 | ||
| @@ -19,7 +19,7 @@ if NET_VENDOR_MARVELL · 6 unmodified lines | |||
| 19 | 19 | ||
| 20 | config MV643XX_ETH | 20 | config MV643XX_ETH |
| 21 | tristate "Marvell Discovery (643XX) and Orion ethernet support" | 21 | tristate "Marvell Discovery (643XX) and Orion ethernet support" |
| 22 | depends on MV64X60 || PPC32 || PLAT_ORION || COMPILE_TEST | 22 | depends on PPC32 || PLAT_ORION || COMPILE_TEST |
| 23 | depends on INET | 23 | depends on INET |
| 24 | select PHYLIB | 24 | select PHYLIB |
| 25 | select MVMDIO | 25 | select MVMDIO |
| @@ -2684,7 +2684,7 @@ static const struct of_device_id mv643xx_eth_shared_ids[] = { · 2683 unmodified lines | |||
| 2684 | MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids); | 2684 | MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids); |
| 2685 | #endif | 2685 | #endif |
| 2686 | 2686 | ||
| 2687 | #if defined(CONFIG_OF_IRQ) && !defined(CONFIG_MV64X60) | 2687 | #ifdef CONFIG_OF_IRQ |
| 2688 | #define mv643xx_eth_property(_np, _name, _v) \ | 2688 | #define mv643xx_eth_property(_np, _name, _v) \ |
| 2689 | do { \ | 2689 | do { \ |
| 2690 | u32 tmp; \ | 2690 | u32 tmp; \ |
| @@ -13499,8 +13499,6 @@ static struct npc_mcam_kex npc_mkex_default = { · 13498 unmodified lines | |||
| 13499 | [NPC_LT_LC_IP] = { | 13499 | [NPC_LT_LC_IP] = { |
| 13500 | /* SIP+DIP: 8 bytes, KW2[63:0] */ | 13500 | /* SIP+DIP: 8 bytes, KW2[63:0] */ |
| 13501 | KEX_LD_CFG(0x07, 0xc, 0x1, 0x0, 0x10), | 13501 | KEX_LD_CFG(0x07, 0xc, 0x1, 0x0, 0x10), |
| 13502 | /* TOS: 1 byte, KW1[63:56] */ | ||
| 13503 | KEX_LD_CFG(0x0, 0x1, 0x1, 0x0, 0xf), | ||
| 13504 | }, | 13502 | }, |
| 13505 | /* Layer C: IPv6 */ | 13503 | /* Layer C: IPv6 */ |
| 13506 | [NPC_LT_LC_IP6] = { | 13504 | [NPC_LT_LC_IP6] = { |
| @@ -2462,8 +2462,10 @@ static void rvu_unregister_interrupts(struct rvu *rvu) · 2461 unmodified lines | |||
| 2462 | INTR_MASK(rvu->hw->total_pfs) & ~1ULL); | 2462 | INTR_MASK(rvu->hw->total_pfs) & ~1ULL); |
| 2463 | 2463 | ||
| 2464 | for (irq = 0; irq < rvu->num_vec; irq++) { | 2464 | for (irq = 0; irq < rvu->num_vec; irq++) { |
| 2465 | if (rvu->irq_allocated[irq]) | 2465 | if (rvu->irq_allocated[irq]) { |
| 2466 | free_irq(pci_irq_vector(rvu->pdev, irq), rvu); | 2466 | free_irq(pci_irq_vector(rvu->pdev, irq), rvu); |
| 2467 | rvu->irq_allocated[irq] = false; | ||
| 2468 | } | ||
| 2467 | } | 2469 | } |
| 2468 | 2470 | ||
| 2469 | pci_free_irq_vectors(rvu->pdev); | 2471 | pci_free_irq_vectors(rvu->pdev); |
| @@ -2975,8 +2977,8 @@ static void rvu_remove(struct pci_dev *pdev) · 505 unmodified lines | |||
| 2975 | struct rvu *rvu = pci_get_drvdata(pdev); | 2977 | struct rvu *rvu = pci_get_drvdata(pdev); |
| 2976 | 2978 | ||
| 2977 | rvu_dbg_exit(rvu); | 2979 | rvu_dbg_exit(rvu); |
| 2978 | rvu_unregister_interrupts(rvu); | ||
| 2979 | rvu_unregister_dl(rvu); | 2980 | rvu_unregister_dl(rvu); |
| 2981 | rvu_unregister_interrupts(rvu); | ||
| 2980 | rvu_flr_wq_destroy(rvu); | 2982 | rvu_flr_wq_destroy(rvu); |
| 2981 | rvu_cgx_exit(rvu); | 2983 | rvu_cgx_exit(rvu); |
| 2982 | rvu_fwdata_exit(rvu); | 2984 | rvu_fwdata_exit(rvu); |
| @@ -682,6 +682,7 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, · 681 unmodified lines | |||
| 682 | u8 *intf, u8 *ena); | 682 | u8 *intf, u8 *ena); |
| 683 | bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature); | 683 | bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature); |
| 684 | u32 rvu_cgx_get_fifolen(struct rvu *rvu); | 684 | u32 rvu_cgx_get_fifolen(struct rvu *rvu); |
| 685 | void *rvu_first_cgx_pdata(struct rvu *rvu); | ||
| 685 | 686 | ||
| 686 | int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf, | 687 | int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf, |
| 687 | int type); | 688 | int type); |
| @@ -89,6 +89,21 @@ void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu) · 88 unmodified lines | |||
| 89 | return rvu->cgx_idmap[cgx_id]; | 89 | return rvu->cgx_idmap[cgx_id]; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* Return first enabled CGX instance if none are enabled then return NULL */ | ||
| 93 | void *rvu_first_cgx_pdata(struct rvu *rvu) | ||
| 94 | { | ||
| 95 | int first_enabled_cgx = 0; | ||
| 96 | void *cgxd = NULL; | ||
| 97 | |||
| 98 | for (; first_enabled_cgx < rvu->cgx_cnt_max; first_enabled_cgx++) { | ||
| 99 | cgxd = rvu_cgx_pdata(first_enabled_cgx, rvu); | ||
| 100 | if (cgxd) | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | |||
| 104 | return cgxd; | ||
| 105 | } | ||
| 106 | |||
| 92 | /* Based on P2X connectivity find mapped NIX block for a PF */ | 107 | /* Based on P2X connectivity find mapped NIX block for a PF */ |
| 93 | static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf, | 108 | static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf, |
| 94 | int cgx_id, int lmac_id) | 109 | int cgx_id, int lmac_id) |
| @@ -711,10 +726,9 @@ int rvu_mbox_handler_cgx_features_get(struct rvu *rvu, · 616 unmodified lines | |||
| 711 | u32 rvu_cgx_get_fifolen(struct rvu *rvu) | 726 | u32 rvu_cgx_get_fifolen(struct rvu *rvu) |
| 712 | { | 727 | { |
| 713 | struct mac_ops *mac_ops; | 728 | struct mac_ops *mac_ops; |
| 714 | int rvu_def_cgx_id = 0; | ||
| 715 | u32 fifo_len; | 729 | u32 fifo_len; |
| 716 | 730 | ||
| 717 | mac_ops = get_mac_ops(rvu_cgx_pdata(rvu_def_cgx_id, rvu)); | 731 | mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu)); |
| 718 | fifo_len = mac_ops ? mac_ops->fifo_len : 0; | 732 | fifo_len = mac_ops ? mac_ops->fifo_len : 0; |
| 719 | 733 | ||
| 720 | return fifo_len; | 734 | return fifo_len; |
| @@ -234,12 +234,14 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 233 unmodified lines | |||
| 234 | char __user *buffer, | 234 | char __user *buffer, |
| 235 | size_t count, loff_t *ppos) | 235 | size_t count, loff_t *ppos) |
| 236 | { | 236 | { |
| 237 | int index, off = 0, flag = 0, go_back = 0, off_prev; | 237 | int index, off = 0, flag = 0, go_back = 0, len = 0; |
| 238 | struct rvu *rvu = filp->private_data; | 238 | struct rvu *rvu = filp->private_data; |
| 239 | int lf, pf, vf, pcifunc; | 239 | int lf, pf, vf, pcifunc; |
| 240 | struct rvu_block block; | 240 | struct rvu_block block; |
| 241 | int bytes_not_copied; | 241 | int bytes_not_copied; |
| 242 | int lf_str_size = 12; | ||
| 242 | int buf_size = 2048; | 243 | int buf_size = 2048; |
| 244 | char *lfs; | ||
| 243 | char *buf; | 245 | char *buf; |
| 244 | 246 | ||
| 245 | /* don't allow partial reads */ | 247 | /* don't allow partial reads */ |
| @@ -249,12 +251,20 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 3 unmodified lines | |||
| 249 | buf = kzalloc(buf_size, GFP_KERNEL); | 251 | buf = kzalloc(buf_size, GFP_KERNEL); |
| 250 | if (!buf) | 252 | if (!buf) |
| 251 | return -ENOSPC; | 253 | return -ENOSPC; |
| 252 | off += scnprintf(&buf[off], buf_size - 1 - off, "\npcifunc\t\t"); | 254 | |
| 255 | lfs = kzalloc(lf_str_size, GFP_KERNEL); | ||
| 256 | if (!lfs) { | ||
| 257 | kfree(buf); | ||
| 258 | return -ENOMEM; | ||
| 259 | } | ||
| 260 | off += scnprintf(&buf[off], buf_size - 1 - off, "%-*s", lf_str_size, | ||
| 261 | "pcifunc"); | ||
| 253 | for (index = 0; index < BLK_COUNT; index++) | 262 | for (index = 0; index < BLK_COUNT; index++) |
| 254 | if (strlen(rvu->hw->block[index].name)) | 263 | if (strlen(rvu->hw->block[index].name)) { |
| 255 | off += scnprintf(&buf[off], buf_size - 1 - off, | 264 | off += scnprintf(&buf[off], buf_size - 1 - off, |
| 256 | "%*s\t", (index - 1) * 2, | 265 | "%-*s", lf_str_size, |
| 257 | rvu->hw->block[index].name); | 266 | rvu->hw->block[index].name); |
| 267 | } | ||
| 258 | off += scnprintf(&buf[off], buf_size - 1 - off, "\n"); | 268 | off += scnprintf(&buf[off], buf_size - 1 - off, "\n"); |
| 259 | for (pf = 0; pf < rvu->hw->total_pfs; pf++) { | 269 | for (pf = 0; pf < rvu->hw->total_pfs; pf++) { |
| 260 | for (vf = 0; vf <= rvu->hw->total_vfs; vf++) { | 270 | for (vf = 0; vf <= rvu->hw->total_vfs; vf++) { |
| @@ -263,14 +273,15 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 2 unmodified lines | |||
| 263 | continue; | 273 | continue; |
| 264 | 274 | ||
| 265 | if (vf) { | 275 | if (vf) { |
| 276 | sprintf(lfs, "PF%d:VF%d", pf, vf - 1); | ||
| 266 | go_back = scnprintf(&buf[off], | 277 | go_back = scnprintf(&buf[off], |
| 267 | buf_size - 1 - off, | 278 | buf_size - 1 - off, |
| 268 | "PF%d:VF%d\t\t", pf, | 279 | "%-*s", lf_str_size, lfs); |
| 269 | vf - 1); | ||
| 270 | } else { | 280 | } else { |
| 281 | sprintf(lfs, "PF%d", pf); | ||
| 271 | go_back = scnprintf(&buf[off], | 282 | go_back = scnprintf(&buf[off], |
| 272 | buf_size - 1 - off, | 283 | buf_size - 1 - off, |
| 273 | "PF%d\t\t", pf); | 284 | "%-*s", lf_str_size, lfs); |
| 274 | } | 285 | } |
| 275 | 286 | ||
| 276 | off += go_back; | 287 | off += go_back; |
| @@ -278,20 +289,22 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 1 unmodified line | |||
| 278 | block = rvu->hw->block[index]; | 289 | block = rvu->hw->block[index]; |
| 279 | if (!strlen(block.name)) | 290 | if (!strlen(block.name)) |
| 280 | continue; | 291 | continue; |
| 281 | off_prev = off; | 292 | len = 0; |
| 293 | lfs[len] = '\0'; | ||
| 282 | for (lf = 0; lf < block.lf.max; lf++) { | 294 | for (lf = 0; lf < block.lf.max; lf++) { |
| 283 | if (block.fn_map[lf] != pcifunc) | 295 | if (block.fn_map[lf] != pcifunc) |
| 284 | continue; | 296 | continue; |
| 285 | flag = 1; | 297 | flag = 1; |
| 286 | off += scnprintf(&buf[off], buf_size - 1 | 298 | len += sprintf(&lfs[len], "%d,", lf); |
| 287 | - off, "%3d,", lf); | ||
| 288 | } | 299 | } |
| 289 | if (flag && off_prev != off) | 300 | |
| 290 | off--; | 301 | if (flag) |
| 291 | else | 302 | len--; |
| 292 | go_back++; | 303 | lfs[len] = '\0'; |
| 293 | off += scnprintf(&buf[off], buf_size - 1 - off, | 304 | off += scnprintf(&buf[off], buf_size - 1 - off, |
| 294 | "\t"); | 305 | "%-*s", lf_str_size, lfs); |
| 306 | if (!strlen(lfs)) | ||
| 307 | go_back += lf_str_size; | ||
| 295 | } | 308 | } |
| 296 | if (!flag) | 309 | if (!flag) |
| 297 | off -= go_back; | 310 | off -= go_back; |
| @@ -303,6 +316,7 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 5 unmodified lines | |||
| 303 | } | 316 | } |
| 304 | 317 | ||
| 305 | bytes_not_copied = copy_to_user(buffer, buf, off); | 318 | bytes_not_copied = copy_to_user(buffer, buf, off); |
| 319 | kfree(lfs); | ||
| 306 | kfree(buf); | 320 | kfree(buf); |
| 307 | 321 | ||
| 308 | if (bytes_not_copied) | 322 | if (bytes_not_copied) |
| @@ -319,7 +333,6 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused) · 10 unmodified lines | |||
| 319 | struct rvu *rvu = filp->private; | 333 | struct rvu *rvu = filp->private; |
| 320 | struct pci_dev *pdev = NULL; | 334 | struct pci_dev *pdev = NULL; |
| 321 | struct mac_ops *mac_ops; | 335 | struct mac_ops *mac_ops; |
| 322 | int rvu_def_cgx_id = 0; | ||
| 323 | char cgx[10], lmac[10]; | 336 | char cgx[10], lmac[10]; |
| 324 | struct rvu_pfvf *pfvf; | 337 | struct rvu_pfvf *pfvf; |
| 325 | int pf, domain, blkid; | 338 | int pf, domain, blkid; |
| @@ -327,7 +340,10 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused) · 1 unmodified line | |||
| 327 | u16 pcifunc; | 340 | u16 pcifunc; |
| 328 | 341 | ||
| 329 | domain = 2; | 342 | domain = 2; |
| 330 | mac_ops = get_mac_ops(rvu_cgx_pdata(rvu_def_cgx_id, rvu)); | 343 | mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu)); |
| 344 | /* There can be no CGX devices at all */ | ||
| 345 | if (!mac_ops) | ||
| 346 | return 0; | ||
| 331 | seq_printf(filp, "PCI dev\t\tRVU PF Func\tNIX block\t%s\tLMAC\n", | 347 | seq_printf(filp, "PCI dev\t\tRVU PF Func\tNIX block\t%s\tLMAC\n", |
| 332 | mac_ops->name); | 348 | mac_ops->name); |
| 333 | for (pf = 0; pf < rvu->hw->total_pfs; pf++) { | 349 | for (pf = 0; pf < rvu->hw->total_pfs; pf++) { |
| @@ -1818,7 +1834,6 @@ static void rvu_dbg_cgx_init(struct rvu *rvu) · 1484 unmodified lines | |||
| 1818 | { | 1834 | { |
| 1819 | struct mac_ops *mac_ops; | 1835 | struct mac_ops *mac_ops; |
| 1820 | unsigned long lmac_bmap; | 1836 | unsigned long lmac_bmap; |
| 1821 | int rvu_def_cgx_id = 0; | ||
| 1822 | int i, lmac_id; | 1837 | int i, lmac_id; |
| 1823 | char dname[20]; | 1838 | char dname[20]; |
| 1824 | void *cgx; | 1839 | void *cgx; |
| @@ -1826,7 +1841,7 @@ static void rvu_dbg_cgx_init(struct rvu *rvu) · 1 unmodified line | |||
| 1826 | if (!cgx_get_cgxcnt_max()) | 1841 | if (!cgx_get_cgxcnt_max()) |
| 1827 | return; | 1842 | return; |
| 1828 | 1843 | ||
| 1829 | mac_ops = get_mac_ops(rvu_cgx_pdata(rvu_def_cgx_id, rvu)); | 1844 | mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu)); |
| 1830 | if (!mac_ops) | 1845 | if (!mac_ops) |
| 1831 | return; | 1846 | return; |
| 1832 | 1847 | ||
| @@ -2630,7 +2630,7 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg) · 2629 unmodified lines | |||
| 2630 | struct nix_rx_flowkey_alg *field; | 2630 | struct nix_rx_flowkey_alg *field; |
| 2631 | struct nix_rx_flowkey_alg tmp; | 2631 | struct nix_rx_flowkey_alg tmp; |
| 2632 | u32 key_type, valid_key; | 2632 | u32 key_type, valid_key; |
| 2633 | int l4_key_offset; | 2633 | int l4_key_offset = 0; |
| 2634 | 2634 | ||
| 2635 | if (!alg) | 2635 | if (!alg) |
| 2636 | return -EINVAL; | 2636 | return -EINVAL; |
| @@ -2521,10 +2521,10 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu, · 2520 unmodified lines | |||
| 2521 | index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); | 2521 | index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); |
| 2522 | if (index >= mcam->bmap_entries) | 2522 | if (index >= mcam->bmap_entries) |
| 2523 | break; | 2523 | break; |
| 2524 | entry = index + 1; | ||
| 2524 | if (mcam->entry2cntr_map[index] != req->cntr) | 2525 | if (mcam->entry2cntr_map[index] != req->cntr) |
| 2525 | continue; | 2526 | continue; |
| 2526 | 2527 | ||
| 2527 | entry = index + 1; | ||
| 2528 | npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, | 2528 | npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, |
| 2529 | index, req->cntr); | 2529 | index, req->cntr); |
| 2530 | } | 2530 | } |
| @@ -262,17 +262,19 @@ int otx2_get_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc, · 261 unmodified lines | |||
| 262 | int otx2_get_all_flows(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc, | 262 | int otx2_get_all_flows(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc, |
| 263 | u32 *rule_locs) | 263 | u32 *rule_locs) |
| 264 | { | 264 | { |
| 265 | u32 rule_cnt = nfc->rule_cnt; | ||
| 265 | u32 location = 0; | 266 | u32 location = 0; |
| 266 | int idx = 0; | 267 | int idx = 0; |
| 267 | int err = 0; | 268 | int err = 0; |
| 268 | 269 | ||
| 269 | nfc->data = pfvf->flow_cfg->ntuple_max_flows; | 270 | nfc->data = pfvf->flow_cfg->ntuple_max_flows; |
| 270 | while ((!err || err == -ENOENT) && idx < nfc->rule_cnt) { | 271 | while ((!err || err == -ENOENT) && idx < rule_cnt) { |
| 271 | err = otx2_get_flow(pfvf, nfc, location); | 272 | err = otx2_get_flow(pfvf, nfc, location); |
| 272 | if (!err) | 273 | if (!err) |
| 273 | rule_locs[idx++] = location; | 274 | rule_locs[idx++] = location; |
| 274 | location++; | 275 | location++; |
| 275 | } | 276 | } |
| 277 | nfc->rule_cnt = rule_cnt; | ||
| 276 | 278 | ||
| 277 | return err; | 279 | return err; |
| 278 | } | 280 | } |
| @@ -1672,6 +1672,7 @@ int otx2_stop(struct net_device *netdev) · 1671 unmodified lines | |||
| 1672 | struct otx2_nic *pf = netdev_priv(netdev); | 1672 | struct otx2_nic *pf = netdev_priv(netdev); |
| 1673 | struct otx2_cq_poll *cq_poll = NULL; | 1673 | struct otx2_cq_poll *cq_poll = NULL; |
| 1674 | struct otx2_qset *qset = &pf->qset; | 1674 | struct otx2_qset *qset = &pf->qset; |
| 1675 | struct otx2_rss_info *rss; | ||
| 1675 | int qidx, vec, wrk; | 1676 | int qidx, vec, wrk; |
| 1676 | 1677 | ||
| 1677 | netif_carrier_off(netdev); | 1678 | netif_carrier_off(netdev); |
| @@ -1684,6 +1685,10 @@ int otx2_stop(struct net_device *netdev) · 6 unmodified lines | |||
| 1684 | /* First stop packet Rx/Tx */ | 1685 | /* First stop packet Rx/Tx */ |
| 1685 | otx2_rxtx_enable(pf, false); | 1686 | otx2_rxtx_enable(pf, false); |
| 1686 | 1687 | ||
| 1688 | /* Clear RSS enable flag */ | ||
| 1689 | rss = &pf->hw.rss_info; | ||
| 1690 | rss->enable = false; | ||
| 1691 | |||
| 1687 | /* Cleanup Queue IRQ */ | 1692 | /* Cleanup Queue IRQ */ |
| 1688 | vec = pci_irq_vector(pf->pdev, | 1693 | vec = pci_irq_vector(pf->pdev, |
| 1689 | pf->hw.nix_msixoff + NIX_LF_QINT_VEC_START); | 1694 | pf->hw.nix_msixoff + NIX_LF_QINT_VEC_START); |
| @@ -1544,8 +1544,8 @@ static int pxa168_eth_remove(struct platform_device *pdev) · 1543 unmodified lines | |||
| 1544 | clk_disable_unprepare(pep->clk); | 1544 | clk_disable_unprepare(pep->clk); |
| 1545 | mdiobus_unregister(pep->smi_bus); | 1545 | mdiobus_unregister(pep->smi_bus); |
| 1546 | mdiobus_free(pep->smi_bus); | 1546 | mdiobus_free(pep->smi_bus); |
| 1547 | unregister_netdev(dev); | ||
| 1548 | cancel_work_sync(&pep->tx_timeout_task); | 1547 | cancel_work_sync(&pep->tx_timeout_task); |
| 1548 | unregister_netdev(dev); | ||
| 1549 | free_netdev(dev); | 1549 | free_netdev(dev); |
| 1550 | return 0; | 1550 | return 0; |
| 1551 | } | 1551 | } |
| @@ -92,14 +92,15 @@ struct page_pool; · 91 unmodified lines | |||
| 92 | MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0) | 92 | MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0) |
| 93 | #define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) | 93 | #define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) |
| 94 | 94 | ||
| 95 | #define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2) | 95 | #define MLX5_ALIGN_MTTS(mtts) (ALIGN(mtts, 8)) |
| 96 | #define MLX5_ALIGNED_MTTS_OCTW(mtts) ((mtts) / 2) | ||
| 97 | #define MLX5_MTT_OCTW(mtts) (MLX5_ALIGNED_MTTS_OCTW(MLX5_ALIGN_MTTS(mtts))) | ||
| 96 | /* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between | 98 | /* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between |
| 97 | * WQEs, This page will absorb write overflow by the hardware, when | 99 | * WQEs, This page will absorb write overflow by the hardware, when |
| 98 | * receiving packets larger than MTU. These oversize packets are | 100 | * receiving packets larger than MTU. These oversize packets are |
| 99 | * dropped by the driver at a later stage. | 101 | * dropped by the driver at a later stage. |
| 100 | */ | 102 | */ |
| 101 | #define MLX5E_REQUIRED_WQE_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE + 1, 8)) | 103 | #define MLX5E_REQUIRED_WQE_MTTS (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1)) |
| 102 | #define MLX5E_LOG_ALIGNED_MPWQE_PPW (ilog2(MLX5E_REQUIRED_WQE_MTTS)) | ||
| 103 | #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS) | 104 | #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS) |
| 104 | #define MLX5E_MAX_RQ_NUM_MTTS \ | 105 | #define MLX5E_MAX_RQ_NUM_MTTS \ |
| 105 | ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ | 106 | ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ |
| @@ -1181,7 +1181,8 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) · 1180 unmodified lines | |||
| 1181 | 1181 | ||
| 1182 | mlx5e_tc_match_to_reg_get_match(spec, CTSTATE_TO_REG, | 1182 | mlx5e_tc_match_to_reg_get_match(spec, CTSTATE_TO_REG, |
| 1183 | &ctstate, &ctstate_mask); | 1183 | &ctstate, &ctstate_mask); |
| 1184 | if (ctstate_mask) | 1184 | |
| 1185 | if ((ctstate & ctstate_mask) == MLX5_CT_STATE_TRK_BIT) | ||
| 1185 | return -EOPNOTSUPP; | 1186 | return -EOPNOTSUPP; |
| 1186 | 1187 | ||
| 1187 | ctstate_mask |= MLX5_CT_STATE_TRK_BIT; | 1188 | ctstate_mask |= MLX5_CT_STATE_TRK_BIT; |
| @@ -685,14 +685,14 @@ int mlx5e_tc_tun_route_lookup(struct mlx5e_priv *priv, · 684 unmodified lines | |||
| 685 | u16 vport_num; | 685 | u16 vport_num; |
| 686 | int err = 0; | 686 | int err = 0; |
| 687 | 687 | ||
| 688 | if (flow_attr->ip_version == 4) { | 688 | if (flow_attr->tun_ip_version == 4) { |
| 689 | /* Addresses are swapped for decap */ | 689 | /* Addresses are swapped for decap */ |
| 690 | attr.fl.fl4.saddr = esw_attr->rx_tun_attr->dst_ip.v4; | 690 | attr.fl.fl4.saddr = esw_attr->rx_tun_attr->dst_ip.v4; |
| 691 | attr.fl.fl4.daddr = esw_attr->rx_tun_attr->src_ip.v4; | 691 | attr.fl.fl4.daddr = esw_attr->rx_tun_attr->src_ip.v4; |
| 692 | err = mlx5e_route_lookup_ipv4_get(priv, priv->netdev, &attr); | 692 | err = mlx5e_route_lookup_ipv4_get(priv, priv->netdev, &attr); |
| 693 | } | 693 | } |
| 694 | #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) | 694 | #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) |
| 695 | else if (flow_attr->ip_version == 6) { | 695 | else if (flow_attr->tun_ip_version == 6) { |
| 696 | /* Addresses are swapped for decap */ | 696 | /* Addresses are swapped for decap */ |
| 697 | attr.fl.fl6.saddr = esw_attr->rx_tun_attr->dst_ip.v6; | 697 | attr.fl.fl6.saddr = esw_attr->rx_tun_attr->dst_ip.v6; |
| 698 | attr.fl.fl6.daddr = esw_attr->rx_tun_attr->src_ip.v6; | 698 | attr.fl.fl6.daddr = esw_attr->rx_tun_attr->src_ip.v6; |
| @@ -718,10 +718,10 @@ int mlx5e_tc_tun_route_lookup(struct mlx5e_priv *priv, · 19 unmodified lines | |||
| 718 | esw_attr->rx_tun_attr->decap_vport = vport_num; | 718 | esw_attr->rx_tun_attr->decap_vport = vport_num; |
| 719 | 719 | ||
| 720 | out: | 720 | out: |
| 721 | if (flow_attr->ip_version == 4) | 721 | if (flow_attr->tun_ip_version == 4) |
| 722 | mlx5e_route_lookup_ipv4_put(&attr); | 722 | mlx5e_route_lookup_ipv4_put(&attr); |
| 723 | #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) | 723 | #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) |
| 724 | else if (flow_attr->ip_version == 6) | 724 | else if (flow_attr->tun_ip_version == 6) |
| 725 | mlx5e_route_lookup_ipv6_put(&attr); | 725 | mlx5e_route_lookup_ipv6_put(&attr); |
| 726 | #endif | 726 | #endif |
| 727 | return err; | 727 | return err; |
| @@ -90,6 +90,7 @@ int mlx5e_tc_set_attr_rx_tun(struct mlx5e_tc_flow *flow, · 89 unmodified lines | |||
| 90 | * required to establish routing. | 90 | * required to establish routing. |
| 91 | */ | 91 | */ |
| 92 | flow_flag_set(flow, TUN_RX); | 92 | flow_flag_set(flow, TUN_RX); |
| 93 | flow->attr->tun_ip_version = ip_version; | ||
| 93 | return 0; | 94 | return 0; |
| 94 | } | 95 | } |
| 95 | 96 | ||
| @@ -1092,7 +1093,7 @@ int mlx5e_attach_decap_route(struct mlx5e_priv *priv, · 996 unmodified lines | |||
| 1092 | if (err || !esw_attr->rx_tun_attr->decap_vport) | 1093 | if (err || !esw_attr->rx_tun_attr->decap_vport) |
| 1093 | goto out; | 1094 | goto out; |
| 1094 | 1095 | ||
| 1095 | key.ip_version = attr->ip_version; | 1096 | key.ip_version = attr->tun_ip_version; |
| 1096 | if (key.ip_version == 4) | 1097 | if (key.ip_version == 4) |
| 1097 | key.endpoint_ip.v4 = esw_attr->rx_tun_attr->dst_ip.v4; | 1098 | key.endpoint_ip.v4 = esw_attr->rx_tun_attr->dst_ip.v4; |
| 1098 | else | 1099 | else |
| @@ -227,6 +227,10 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv, · 226 unmodified lines | |||
| 227 | option_key = (struct geneve_opt *)&enc_opts.key->data[0]; | 227 | option_key = (struct geneve_opt *)&enc_opts.key->data[0]; |
| 228 | option_mask = (struct geneve_opt *)&enc_opts.mask->data[0]; | 228 | option_mask = (struct geneve_opt *)&enc_opts.mask->data[0]; |
| 229 | 229 | ||
| 230 | if (option_mask->opt_class == 0 && option_mask->type == 0 && | ||
| 231 | !memchr_inv(option_mask->opt_data, 0, option_mask->length * 4)) | ||
| 232 | return 0; | ||
| 233 | |||
| 230 | if (option_key->length > max_tlv_option_data_len) { | 234 | if (option_key->length > max_tlv_option_data_len) { |
| 231 | NL_SET_ERR_MSG_MOD(extack, | 235 | NL_SET_ERR_MSG_MOD(extack, |
| 232 | "Matching on GENEVE options: unsupported option len"); | 236 | "Matching on GENEVE options: unsupported option len"); |
| @@ -1887,6 +1887,7 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev, · 1886 unmodified lines | |||
| 1887 | { | 1887 | { |
| 1888 | struct mlx5e_priv *priv = netdev_priv(netdev); | 1888 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 1889 | struct mlx5_core_dev *mdev = priv->mdev; | 1889 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1890 | int err; | ||
| 1890 | 1891 | ||
| 1891 | if (!MLX5_CAP_GEN(mdev, cqe_compression)) | 1892 | if (!MLX5_CAP_GEN(mdev, cqe_compression)) |
| 1892 | return -EOPNOTSUPP; | 1893 | return -EOPNOTSUPP; |
| @@ -1896,7 +1897,10 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev, · 3 unmodified lines | |||
| 1896 | return -EINVAL; | 1897 | return -EINVAL; |
| 1897 | } | 1898 | } |
| 1898 | 1899 | ||
| 1899 | mlx5e_modify_rx_cqe_compression_locked(priv, enable); | 1900 | err = mlx5e_modify_rx_cqe_compression_locked(priv, enable); |
| 1901 | if (err) | ||
| 1902 | return err; | ||
| 1903 | |||
| 1900 | priv->channels.params.rx_cqe_compress_def = enable; | 1904 | priv->channels.params.rx_cqe_compress_def = enable; |
| 1901 | 1905 | ||
| 1902 | return 0; | 1906 | return 0; |
| @@ -2014,8 +2018,13 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable) · 111 unmodified lines | |||
| 2014 | */ | 2018 | */ |
| 2015 | 2019 | ||
| 2016 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { | 2020 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 2021 | struct mlx5e_params old_params; | ||
| 2022 | |||
| 2023 | old_params = priv->channels.params; | ||
| 2017 | priv->channels.params = new_channels.params; | 2024 | priv->channels.params = new_channels.params; |
| 2018 | err = mlx5e_num_channels_changed(priv); | 2025 | err = mlx5e_num_channels_changed(priv); |
| 2026 | if (err) | ||
| 2027 | priv->channels.params = old_params; | ||
| 2019 | goto out; | 2028 | goto out; |
| 2020 | } | 2029 | } |
| 2021 | 2030 | ||
| @@ -334,9 +334,9 @@ static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq · 333 unmodified lines | |||
| 334 | rq->wqe_overflow.addr); | 334 | rq->wqe_overflow.addr); |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix) | 337 | static u64 mlx5e_get_mpwqe_offset(u16 wqe_ix) |
| 338 | { | 338 | { |
| 339 | return (wqe_ix << MLX5E_LOG_ALIGNED_MPWQE_PPW) << PAGE_SHIFT; | 339 | return MLX5E_REQUIRED_MTTS(wqe_ix) << PAGE_SHIFT; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | static void mlx5e_init_frags_partition(struct mlx5e_rq *rq) | 342 | static void mlx5e_init_frags_partition(struct mlx5e_rq *rq) |
| @@ -577,7 +577,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, · 234 unmodified lines | |||
| 577 | mlx5_wq_ll_get_wqe(&rq->mpwqe.wq, i); | 577 | mlx5_wq_ll_get_wqe(&rq->mpwqe.wq, i); |
| 578 | u32 byte_count = | 578 | u32 byte_count = |
| 579 | rq->mpwqe.num_strides << rq->mpwqe.log_stride_sz; | 579 | rq->mpwqe.num_strides << rq->mpwqe.log_stride_sz; |
| 580 | u64 dma_offset = mlx5e_get_mpwqe_offset(rq, i); | 580 | u64 dma_offset = mlx5e_get_mpwqe_offset(i); |
| 581 | 581 | ||
| 582 | wqe->data[0].addr = cpu_to_be64(dma_offset + rq->buff.headroom); | 582 | wqe->data[0].addr = cpu_to_be64(dma_offset + rq->buff.headroom); |
| 583 | wqe->data[0].byte_count = cpu_to_be32(byte_count); | 583 | wqe->data[0].byte_count = cpu_to_be32(byte_count); |
| @@ -2368,8 +2368,9 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5e_params *params, · 1784 unmodified lines | |||
| 2368 | { | 2368 | { |
| 2369 | switch (params->rq_wq_type) { | 2369 | switch (params->rq_wq_type) { |
| 2370 | case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: | 2370 | case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: |
| 2371 | return order_base_2(MLX5E_UMR_WQEBBS) + | 2371 | return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, |
| 2372 | mlx5e_get_rq_log_wq_sz(rqp->rqc); | 2372 | order_base_2(MLX5E_UMR_WQEBBS) + |
| 2373 | mlx5e_get_rq_log_wq_sz(rqp->rqc)); | ||
| 2373 | default: /* MLX5_WQ_TYPE_CYCLIC */ | 2374 | default: /* MLX5_WQ_TYPE_CYCLIC */ |
| 2374 | return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE; | 2375 | return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE; |
| 2375 | } | 2376 | } |
| @@ -2502,8 +2503,10 @@ void mlx5e_close_channels(struct mlx5e_channels *chs) · 126 unmodified lines | |||
| 2502 | { | 2503 | { |
| 2503 | int i; | 2504 | int i; |
| 2504 | 2505 | ||
| 2505 | if (chs->port_ptp) | 2506 | if (chs->port_ptp) { |
| 2506 | mlx5e_port_ptp_close(chs->port_ptp); | 2507 | mlx5e_port_ptp_close(chs->port_ptp); |
| 2508 | chs->port_ptp = NULL; | ||
| 2509 | } | ||
| 2507 | 2510 | ||
| 2508 | for (i = 0; i < chs->num; i++) | 2511 | for (i = 0; i < chs->num; i++) |
| 2509 | mlx5e_close_channel(chs->c[i]); | 2512 | mlx5e_close_channel(chs->c[i]); |
| @@ -3818,6 +3821,15 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) · 1308 unmodified lines | |||
| 3818 | for (j = 0; j < priv->max_opened_tc; j++) { | 3821 | for (j = 0; j < priv->max_opened_tc; j++) { |
| 3819 | struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j]; | 3822 | struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j]; |
| 3820 | 3823 | ||
| 3824 | s->tx_packets += sq_stats->packets; | ||
| 3825 | s->tx_bytes += sq_stats->bytes; | ||
| 3826 | s->tx_dropped += sq_stats->dropped; | ||
| 3827 | } | ||
| 3828 | } | ||
| 3829 | if (priv->port_ptp_opened) { | ||
| 3830 | for (i = 0; i < priv->max_opened_tc; i++) { | ||
| 3831 | struct mlx5e_sq_stats *sq_stats = &priv->port_ptp_stats.sq[i]; | ||
| 3832 | |||
| 3821 | s->tx_packets += sq_stats->packets; | 3833 | s->tx_packets += sq_stats->packets; |
| 3822 | s->tx_bytes += sq_stats->bytes; | 3834 | s->tx_bytes += sq_stats->bytes; |
| 3823 | s->tx_dropped += sq_stats->dropped; | 3835 | s->tx_dropped += sq_stats->dropped; |
| @@ -3845,10 +3857,17 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) · 21 unmodified lines | |||
| 3845 | } | 3857 | } |
| 3846 | 3858 | ||
| 3847 | if (mlx5e_is_uplink_rep(priv)) { | 3859 | if (mlx5e_is_uplink_rep(priv)) { |
| 3860 | struct mlx5e_vport_stats *vstats = &priv->stats.vport; | ||
| 3861 | |||
| 3848 | stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok); | 3862 | stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok); |
| 3849 | stats->rx_bytes = PPORT_802_3_GET(pstats, a_octets_received_ok); | 3863 | stats->rx_bytes = PPORT_802_3_GET(pstats, a_octets_received_ok); |
| 3850 | stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok); | 3864 | stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok); |
| 3851 | stats->tx_bytes = PPORT_802_3_GET(pstats, a_octets_transmitted_ok); | 3865 | stats->tx_bytes = PPORT_802_3_GET(pstats, a_octets_transmitted_ok); |
| 3866 | |||
| 3867 | /* vport multicast also counts packets that are dropped due to steering | ||
| 3868 | * or rx out of buffer | ||
| 3869 | */ | ||
| 3870 | stats->multicast = VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); | ||
| 3852 | } else { | 3871 | } else { |
| 3853 | mlx5e_fold_sw_stats64(priv, stats); | 3872 | mlx5e_fold_sw_stats64(priv, stats); |
| 3854 | } | 3873 | } |
| @@ -4734,8 +4753,10 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog) · 879 unmodified lines | |||
| 4734 | struct mlx5e_channel *c = priv->channels.c[i]; | 4753 | struct mlx5e_channel *c = priv->channels.c[i]; |
| 4735 | 4754 | ||
| 4736 | mlx5e_rq_replace_xdp_prog(&c->rq, prog); | 4755 | mlx5e_rq_replace_xdp_prog(&c->rq, prog); |
| 4737 | if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) | 4756 | if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) { |
| 4757 | bpf_prog_inc(prog); | ||
| 4738 | mlx5e_rq_replace_xdp_prog(&c->xskrq, prog); | 4758 | mlx5e_rq_replace_xdp_prog(&c->xskrq, prog); |
| 4759 | } | ||
| 4739 | } | 4760 | } |
| 4740 | 4761 | ||
| 4741 | unlock: | 4762 | unlock: |
| @@ -5011,6 +5032,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 · 269 unmodified lines | |||
| 5011 | priv->max_nch); | 5032 | priv->max_nch); |
| 5012 | params->num_tc = 1; | 5033 | params->num_tc = 1; |
| 5013 | 5034 | ||
| 5035 | /* Set an initial non-zero value, so that mlx5e_select_queue won't | ||
| 5036 | * divide by zero if called before first activating channels. | ||
| 5037 | */ | ||
| 5038 | priv->num_tc_x_num_ch = params->num_channels * params->num_tc; | ||
| 5039 | |||
| 5014 | /* SQ */ | 5040 | /* SQ */ |
| 5015 | params->log_sq_size = is_kdump_kernel() ? | 5041 | params->log_sq_size = is_kdump_kernel() ? |
| 5016 | MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE : | 5042 | MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE : |
| @@ -5522,8 +5548,6 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, · 505 unmodified lines | |||
| 5522 | struct net_device *netdev, | 5548 | struct net_device *netdev, |
| 5523 | struct mlx5_core_dev *mdev) | 5549 | struct mlx5_core_dev *mdev) |
| 5524 | { | 5550 | { |
| 5525 | memset(priv, 0, sizeof(*priv)); | ||
| 5526 | |||
| 5527 | /* priv init */ | 5551 | /* priv init */ |
| 5528 | priv->mdev = mdev; | 5552 | priv->mdev = mdev; |
| 5529 | priv->netdev = netdev; | 5553 | priv->netdev = netdev; |
| @@ -5556,12 +5580,18 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) · 26 unmodified lines | |||
| 5556 | { | 5580 | { |
| 5557 | int i; | 5581 | int i; |
| 5558 | 5582 | ||
| 5583 | /* bail if change profile failed and also rollback failed */ | ||
| 5584 | if (!priv->mdev) | ||
| 5585 | return; | ||
| 5586 | |||
| 5559 | destroy_workqueue(priv->wq); | 5587 | destroy_workqueue(priv->wq); |
| 5560 | free_cpumask_var(priv->scratchpad.cpumask); | 5588 | free_cpumask_var(priv->scratchpad.cpumask); |
| 5561 | 5589 | ||
| 5562 | for (i = 0; i < priv->htb.max_qos_sqs; i++) | 5590 | for (i = 0; i < priv->htb.max_qos_sqs; i++) |
| 5563 | kfree(priv->htb.qos_sq_stats[i]); | 5591 | kfree(priv->htb.qos_sq_stats[i]); |
| 5564 | kvfree(priv->htb.qos_sq_stats); | 5592 | kvfree(priv->htb.qos_sq_stats); |
| 5593 | |||
| 5594 | memset(priv, 0, sizeof(*priv)); | ||
| 5565 | } | 5595 | } |
| 5566 | 5596 | ||
| 5567 | struct net_device * | 5597 | struct net_device * |
| @@ -5678,11 +5708,10 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv) · 110 unmodified lines | |||
| 5678 | } | 5708 | } |
| 5679 | 5709 | ||
| 5680 | static int | 5710 | static int |
| 5681 | mlx5e_netdev_attach_profile(struct mlx5e_priv *priv, | 5711 | mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mdev, |
| 5682 | const struct mlx5e_profile *new_profile, void *new_ppriv) | 5712 | const struct mlx5e_profile *new_profile, void *new_ppriv) |
| 5683 | { | 5713 | { |
| 5684 | struct net_device *netdev = priv->netdev; | 5714 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 5685 | struct mlx5_core_dev *mdev = priv->mdev; | ||
| 5686 | int err; | 5715 | int err; |
| 5687 | 5716 | ||
| 5688 | err = mlx5e_priv_init(priv, netdev, mdev); | 5717 | err = mlx5e_priv_init(priv, netdev, mdev); |
| @@ -5695,10 +5724,16 @@ mlx5e_netdev_attach_profile(struct mlx5e_priv *priv, · 6 unmodified lines | |||
| 5695 | priv->ppriv = new_ppriv; | 5724 | priv->ppriv = new_ppriv; |
| 5696 | err = new_profile->init(priv->mdev, priv->netdev); | 5725 | err = new_profile->init(priv->mdev, priv->netdev); |
| 5697 | if (err) | 5726 | if (err) |
| 5698 | return err; | 5727 | goto priv_cleanup; |
| 5699 | err = mlx5e_attach_netdev(priv); | 5728 | err = mlx5e_attach_netdev(priv); |
| 5700 | if (err) | 5729 | if (err) |
| 5701 | new_profile->cleanup(priv); | 5730 | goto profile_cleanup; |
| 5731 | return err; | ||
| 5732 | |||
| 5733 | profile_cleanup: | ||
| 5734 | new_profile->cleanup(priv); | ||
| 5735 | priv_cleanup: | ||
| 5736 | mlx5e_priv_cleanup(priv); | ||
| 5702 | return err; | 5737 | return err; |
| 5703 | } | 5738 | } |
| 5704 | 5739 | ||
| @@ -5707,13 +5742,14 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, · 2 unmodified lines | |||
| 5707 | { | 5742 | { |
| 5708 | unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); | 5743 | unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); |
| 5709 | const struct mlx5e_profile *orig_profile = priv->profile; | 5744 | const struct mlx5e_profile *orig_profile = priv->profile; |
| 5745 | struct net_device *netdev = priv->netdev; | ||
| 5746 | struct mlx5_core_dev *mdev = priv->mdev; | ||
| 5710 | void *orig_ppriv = priv->ppriv; | 5747 | void *orig_ppriv = priv->ppriv; |
| 5711 | int err, rollback_err; | 5748 | int err, rollback_err; |
| 5712 | 5749 | ||
| 5713 | /* sanity */ | 5750 | /* sanity */ |
| 5714 | if (new_max_nch != priv->max_nch) { | 5751 | if (new_max_nch != priv->max_nch) { |
| 5715 | netdev_warn(priv->netdev, | 5752 | netdev_warn(netdev, "%s: Replacing profile with different max channels\n", |
| 5716 | "%s: Replacing profile with different max channels\n", | ||
| 5717 | __func__); | 5753 | __func__); |
| 5718 | return -EINVAL; | 5754 | return -EINVAL; |
| 5719 | } | 5755 | } |
| @@ -5723,22 +5759,19 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, · 3 unmodified lines | |||
| 5723 | priv->profile->cleanup(priv); | 5759 | priv->profile->cleanup(priv); |
| 5724 | mlx5e_priv_cleanup(priv); | 5760 | mlx5e_priv_cleanup(priv); |
| 5725 | 5761 | ||
| 5726 | err = mlx5e_netdev_attach_profile(priv, new_profile, new_ppriv); | 5762 | err = mlx5e_netdev_attach_profile(netdev, mdev, new_profile, new_ppriv); |
| 5727 | if (err) { /* roll back to original profile */ | 5763 | if (err) { /* roll back to original profile */ |
| 5728 | netdev_warn(priv->netdev, "%s: new profile init failed, %d\n", | 5764 | netdev_warn(netdev, "%s: new profile init failed, %d\n", __func__, err); |
| 5729 | __func__, err); | ||
| 5730 | goto rollback; | 5765 | goto rollback; |
| 5731 | } | 5766 | } |
| 5732 | 5767 | ||
| 5733 | return 0; | 5768 | return 0; |
| 5734 | 5769 | ||
| 5735 | rollback: | 5770 | rollback: |
| 5736 | rollback_err = mlx5e_netdev_attach_profile(priv, orig_profile, orig_ppriv); | 5771 | rollback_err = mlx5e_netdev_attach_profile(netdev, mdev, orig_profile, orig_ppriv); |
| 5737 | if (rollback_err) { | 5772 | if (rollback_err) |
| 5738 | netdev_err(priv->netdev, | 5773 | netdev_err(netdev, "%s: failed to rollback to orig profile, %d\n", |
| 5739 | "%s: failed to rollback to orig profile, %d\n", | ||
| 5740 | __func__, rollback_err); | 5774 | __func__, rollback_err); |
| 5741 | } | ||
| 5742 | return err; | 5775 | return err; |
| 5743 | } | 5776 | } |
| 5744 | 5777 | ||
| @@ -501,7 +501,6 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) · 500 unmodified lines | |||
| 501 | struct mlx5e_icosq *sq = rq->icosq; | 501 | struct mlx5e_icosq *sq = rq->icosq; |
| 502 | struct mlx5_wq_cyc *wq = &sq->wq; | 502 | struct mlx5_wq_cyc *wq = &sq->wq; |
| 503 | struct mlx5e_umr_wqe *umr_wqe; | 503 | struct mlx5e_umr_wqe *umr_wqe; |
| 504 | u16 xlt_offset = ix << (MLX5E_LOG_ALIGNED_MPWQE_PPW - 1); | ||
| 505 | u16 pi; | 504 | u16 pi; |
| 506 | int err; | 505 | int err; |
| 507 | int i; | 506 | int i; |
| @@ -532,7 +531,8 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) · 24 unmodified lines | |||
| 532 | umr_wqe->ctrl.opmod_idx_opcode = | 531 | umr_wqe->ctrl.opmod_idx_opcode = |
| 533 | cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) | | 532 | cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) | |
| 534 | MLX5_OPCODE_UMR); | 533 | MLX5_OPCODE_UMR); |
| 535 | umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); | 534 | umr_wqe->uctrl.xlt_offset = |
| 535 | cpu_to_be16(MLX5_ALIGNED_MTTS_OCTW(MLX5E_REQUIRED_MTTS(ix))); | ||
| 536 | 536 | ||
| 537 | sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) { | 537 | sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) { |
| 538 | .wqe_type = MLX5E_ICOSQ_WQE_UMR_RX, | 538 | .wqe_type = MLX5E_ICOSQ_WQE_UMR_RX, |
| @@ -2357,6 +2357,16 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, · 2356 unmodified lines | |||
| 2357 | spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3; | 2357 | spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3; |
| 2358 | } | 2358 | } |
| 2359 | } | 2359 | } |
| 2360 | /* Currenlty supported only for MPLS over UDP */ | ||
| 2361 | if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS) && | ||
| 2362 | !netif_is_bareudp(filter_dev)) { | ||
| 2363 | NL_SET_ERR_MSG_MOD(extack, | ||
| 2364 | "Matching on MPLS is supported only for MPLS over UDP"); | ||
| 2365 | netdev_err(priv->netdev, | ||
| 2366 | "Matching on MPLS is supported only for MPLS over UDP\n"); | ||
| 2367 | return -EOPNOTSUPP; | ||
| 2368 | } | ||
| 2369 | |||
| 2360 | return 0; | 2370 | return 0; |
| 2361 | } | 2371 | } |
| 2362 | 2372 | ||
| @@ -2960,6 +2970,37 @@ static int is_action_keys_supported(const struct flow_action_entry *act, · 597 unmodified lines | |||
| 2960 | return 0; | 2970 | return 0; |
| 2961 | } | 2971 | } |
| 2962 | 2972 | ||
| 2973 | static bool modify_tuple_supported(bool modify_tuple, bool ct_clear, | ||
| 2974 | bool ct_flow, struct netlink_ext_ack *extack, | ||
| 2975 | struct mlx5e_priv *priv, | ||
| 2976 | struct mlx5_flow_spec *spec) | ||
| 2977 | { | ||
| 2978 | if (!modify_tuple || ct_clear) | ||
| 2979 | return true; | ||
| 2980 | |||
| 2981 | if (ct_flow) { | ||
| 2982 | NL_SET_ERR_MSG_MOD(extack, | ||
| 2983 | "can't offload tuple modification with non-clear ct()"); | ||
| 2984 | netdev_info(priv->netdev, | ||
| 2985 | "can't offload tuple modification with non-clear ct()"); | ||
| 2986 | return false; | ||
| 2987 | } | ||
| 2988 | |||
| 2989 | /* Add ct_state=-trk match so it will be offloaded for non ct flows | ||
| 2990 | * (or after clear action), as otherwise, since the tuple is changed, | ||
| 2991 | * we can't restore ct state | ||
| 2992 | */ | ||
| 2993 | if (mlx5_tc_ct_add_no_trk_match(spec)) { | ||
| 2994 | NL_SET_ERR_MSG_MOD(extack, | ||
| 2995 | "can't offload tuple modification with ct matches and no ct(clear) action"); | ||
| 2996 | netdev_info(priv->netdev, | ||
| 2997 | "can't offload tuple modification with ct matches and no ct(clear) action"); | ||
| 2998 | return false; | ||
| 2999 | } | ||
| 3000 | |||
| 3001 | return true; | ||
| 3002 | } | ||
| 3003 | |||
| 2963 | static bool modify_header_match_supported(struct mlx5e_priv *priv, | 3004 | static bool modify_header_match_supported(struct mlx5e_priv *priv, |
| 2964 | struct mlx5_flow_spec *spec, | 3005 | struct mlx5_flow_spec *spec, |
| 2965 | struct flow_action *flow_action, | 3006 | struct flow_action *flow_action, |
| @@ -2998,18 +3039,9 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv, · 32 unmodified lines | |||
| 2998 | return err; | 3039 | return err; |
| 2999 | } | 3040 | } |
| 3000 | 3041 | ||
| 3001 | /* Add ct_state=-trk match so it will be offloaded for non ct flows | 3042 | if (!modify_tuple_supported(modify_tuple, ct_clear, ct_flow, extack, |
| 3002 | * (or after clear action), as otherwise, since the tuple is changed, | 3043 | priv, spec)) |
| 3003 | * we can't restore ct state | ||
| 3004 | */ | ||
| 3005 | if (!ct_clear && modify_tuple && | ||
| 3006 | mlx5_tc_ct_add_no_trk_match(spec)) { | ||
| 3007 | NL_SET_ERR_MSG_MOD(extack, | ||
| 3008 | "can't offload tuple modify header with ct matches"); | ||
| 3009 | netdev_info(priv->netdev, | ||
| 3010 | "can't offload tuple modify header with ct matches"); | ||
| 3011 | return false; | 3044 | return false; |
| 3012 | } | ||
| 3013 | 3045 | ||
| 3014 | ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); | 3046 | ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); |
| 3015 | if (modify_ip_header && ip_proto != IPPROTO_TCP && | 3047 | if (modify_ip_header && ip_proto != IPPROTO_TCP && |
| @@ -4512,7 +4544,8 @@ static int apply_police_params(struct mlx5e_priv *priv, u64 rate, · 1496 unmodified lines | |||
| 4512 | */ | 4544 | */ |
| 4513 | if (rate) { | 4545 | if (rate) { |
| 4514 | rate = (rate * BITS_PER_BYTE) + 500000; | 4546 | rate = (rate * BITS_PER_BYTE) + 500000; |
| 4515 | rate_mbps = max_t(u64, do_div(rate, 1000000), 1); | 4547 | do_div(rate, 1000000); |
| 4548 | rate_mbps = max_t(u32, rate, 1); | ||
| 4516 | } | 4549 | } |
| 4517 | 4550 | ||
| 4518 | err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps); | 4551 | err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps); |
| @@ -79,6 +79,7 @@ struct mlx5_flow_attr { · 78 unmodified lines | |||
| 79 | u8 inner_match_level; | 79 | u8 inner_match_level; |
| 80 | u8 outer_match_level; | 80 | u8 outer_match_level; |
| 81 | u8 ip_version; | 81 | u8 ip_version; |
| 82 | u8 tun_ip_version; | ||
| 82 | u32 flags; | 83 | u32 flags; |
| 83 | union { | 84 | union { |
| 84 | struct mlx5_esw_flow_attr esw_attr[0]; | 85 | struct mlx5_esw_flow_attr esw_attr[0]; |
| @@ -550,7 +550,8 @@ esw_setup_dests(struct mlx5_flow_destination *dest, · 549 unmodified lines | |||
| 550 | 550 | ||
| 551 | if (!mlx5_eswitch_termtbl_required(esw, attr, flow_act, spec) && | 551 | if (!mlx5_eswitch_termtbl_required(esw, attr, flow_act, spec) && |
| 552 | MLX5_CAP_GEN(esw_attr->in_mdev, reg_c_preserve) && | 552 | MLX5_CAP_GEN(esw_attr->in_mdev, reg_c_preserve) && |
| 553 | mlx5_eswitch_vport_match_metadata_enabled(esw)) | 553 | mlx5_eswitch_vport_match_metadata_enabled(esw) && |
| 554 | MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level)) | ||
| 554 | attr->flags |= MLX5_ESW_ATTR_FLAG_SRC_REWRITE; | 555 | attr->flags |= MLX5_ESW_ATTR_FLAG_SRC_REWRITE; |
| 555 | 556 | ||
| 556 | if (attr->dest_ft) { | 557 | if (attr->dest_ft) { |
| @@ -575,6 +575,7 @@ static int mlx5_fpga_conn_create_qp(struct mlx5_fpga_conn *conn, · 574 unmodified lines | |||
| 575 | MLX5_SET(qpc, qpc, log_sq_size, ilog2(conn->qp.sq.size)); | 575 | MLX5_SET(qpc, qpc, log_sq_size, ilog2(conn->qp.sq.size)); |
| 576 | MLX5_SET(qpc, qpc, cqn_snd, conn->cq.mcq.cqn); | 576 | MLX5_SET(qpc, qpc, cqn_snd, conn->cq.mcq.cqn); |
| 577 | MLX5_SET(qpc, qpc, cqn_rcv, conn->cq.mcq.cqn); | 577 | MLX5_SET(qpc, qpc, cqn_rcv, conn->cq.mcq.cqn); |
| 578 | MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(mdev)); | ||
| 578 | MLX5_SET64(qpc, qpc, dbr_addr, conn->qp.wq_ctrl.db.dma); | 579 | MLX5_SET64(qpc, qpc, dbr_addr, conn->qp.wq_ctrl.db.dma); |
| 579 | if (MLX5_CAP_GEN(mdev, cqe_version) == 1) | 580 | if (MLX5_CAP_GEN(mdev, cqe_version) == 1) |
| 580 | MLX5_SET(qpc, qpc, user_index, 0xFFFFFF); | 581 | MLX5_SET(qpc, qpc, user_index, 0xFFFFFF); |
| @@ -233,6 +233,7 @@ int mlx5i_create_underlay_qp(struct mlx5e_priv *priv) · 232 unmodified lines | |||
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); | 235 | qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); |
| 236 | MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(priv->mdev)); | ||
| 236 | MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD); | 237 | MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD); |
| 237 | MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); | 238 | MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); |
| 238 | MLX5_SET(qpc, qpc, ulp_stateless_offload_mode, | 239 | MLX5_SET(qpc, qpc, ulp_stateless_offload_mode, |
| @@ -694,6 +695,7 @@ static int mlx5i_check_required_hca_cap(struct mlx5_core_dev *mdev) · 455 unmodified lines | |||
| 694 | static void mlx5_rdma_netdev_free(struct net_device *netdev) | 695 | static void mlx5_rdma_netdev_free(struct net_device *netdev) |
| 695 | { | 696 | { |
| 696 | struct mlx5e_priv *priv = mlx5i_epriv(netdev); | 697 | struct mlx5e_priv *priv = mlx5i_epriv(netdev); |
| 698 | struct mlx5_core_dev *mdev = priv->mdev; | ||
| 697 | struct mlx5i_priv *ipriv = priv->ppriv; | 699 | struct mlx5i_priv *ipriv = priv->ppriv; |
| 698 | const struct mlx5e_profile *profile = priv->profile; | 700 | const struct mlx5e_profile *profile = priv->profile; |
| 699 | 701 | ||
| @@ -702,7 +704,7 @@ static void mlx5_rdma_netdev_free(struct net_device *netdev) · 2 unmodified lines | |||
| 702 | 704 | ||
| 703 | if (!ipriv->sub_interface) { | 705 | if (!ipriv->sub_interface) { |
| 704 | mlx5i_pkey_qpn_ht_cleanup(netdev); | 706 | mlx5i_pkey_qpn_ht_cleanup(netdev); |
| 705 | mlx5e_destroy_mdev_resources(priv->mdev); | 707 | mlx5e_destroy_mdev_resources(mdev); |
| 706 | } | 708 | } |
| 707 | } | 709 | } |
| 708 | 710 | ||
| @@ -495,15 +495,15 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 494 unmodified lines | |||
| 495 | return -EINVAL; | 495 | return -EINVAL; |
| 496 | 496 | ||
| 497 | field_select = MLX5_MTPPS_FS_ENABLE; | 497 | field_select = MLX5_MTPPS_FS_ENABLE; |
| 498 | pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT, rq->perout.index); | ||
| 499 | if (pin < 0) | ||
| 500 | return -EBUSY; | ||
| 501 | |||
| 498 | if (on) { | 502 | if (on) { |
| 499 | bool rt_mode = mlx5_real_time_mode(mdev); | 503 | bool rt_mode = mlx5_real_time_mode(mdev); |
| 500 | u32 nsec; | 504 | u32 nsec; |
| 501 | s64 sec; | 505 | s64 sec; |
| 502 | 506 | ||
| 503 | pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT, rq->perout.index); | ||
| 504 | if (pin < 0) | ||
| 505 | return -EBUSY; | ||
| 506 | |||
| 507 | pin_mode = MLX5_PIN_MODE_OUT; | 507 | pin_mode = MLX5_PIN_MODE_OUT; |
| 508 | pattern = MLX5_OUT_PATTERN_PERIODIC; | 508 | pattern = MLX5_OUT_PATTERN_PERIODIC; |
| 509 | ts.tv_sec = rq->perout.period.sec; | 509 | ts.tv_sec = rq->perout.period.sec; |
| @@ -181,15 +181,13 @@ static int mlx5_sf_dev_vhca_arm_all(struct mlx5_sf_dev_table *table) · 180 unmodified lines | |||
| 181 | u16 max_functions; | 181 | u16 max_functions; |
| 182 | u16 function_id; | 182 | u16 function_id; |
| 183 | int err = 0; | 183 | int err = 0; |
| 184 | bool ecpu; | ||
| 185 | int i; | 184 | int i; |
| 186 | 185 | ||
| 187 | max_functions = mlx5_sf_max_functions(dev); | 186 | max_functions = mlx5_sf_max_functions(dev); |
| 188 | function_id = MLX5_CAP_GEN(dev, sf_base_id); | 187 | function_id = MLX5_CAP_GEN(dev, sf_base_id); |
| 189 | ecpu = mlx5_read_embedded_cpu(dev); | ||
| 190 | /* Arm the vhca context as the vhca event notifier */ | 188 | /* Arm the vhca context as the vhca event notifier */ |
| 191 | for (i = 0; i < max_functions; i++) { | 189 | for (i = 0; i < max_functions; i++) { |
| 192 | err = mlx5_vhca_event_arm(dev, function_id, ecpu); | 190 | err = mlx5_vhca_event_arm(dev, function_id); |
| 193 | if (err) | 191 | if (err) |
| 194 | return err; | 192 | return err; |
| 195 | 193 | ||
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | #include "sf.h" | 6 | #include "sf.h" |
| 7 | #include "mlx5_ifc_vhca_event.h" | 7 | #include "mlx5_ifc_vhca_event.h" |
| 8 | #include "ecpf.h" | 8 | #include "ecpf.h" |
| 9 | #include "vhca_event.h" | ||
| 10 | #include "mlx5_core.h" | ||
| 9 | 11 | ||
| 10 | struct mlx5_sf_hw { | 12 | struct mlx5_sf_hw { |
| 11 | u32 usr_sfnum; | 13 | u32 usr_sfnum; |
| @@ -17,7 +19,6 @@ struct mlx5_sf_hw_table { · 5 unmodified lines | |||
| 17 | struct mlx5_core_dev *dev; | 19 | struct mlx5_core_dev *dev; |
| 18 | struct mlx5_sf_hw *sfs; | 20 | struct mlx5_sf_hw *sfs; |
| 19 | int max_local_functions; | 21 | int max_local_functions; |
| 20 | u8 ecpu: 1; | ||
| 21 | struct mutex table_lock; /* Serializes sf deletion and vhca state change handler. */ | 22 | struct mutex table_lock; /* Serializes sf deletion and vhca state change handler. */ |
| 22 | struct notifier_block vhca_nb; | 23 | struct notifier_block vhca_nb; |
| 23 | }; | 24 | }; |
| @@ -63,7 +64,7 @@ int mlx5_sf_hw_table_sf_alloc(struct mlx5_core_dev *dev, u32 usr_sfnum) · 39 unmodified lines | |||
| 63 | } | 64 | } |
| 64 | if (sw_id == -ENOSPC) { | 65 | if (sw_id == -ENOSPC) { |
| 65 | err = -ENOSPC; | 66 | err = -ENOSPC; |
| 66 | goto err; | 67 | goto exist_err; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | hw_fn_id = mlx5_sf_sw_to_hw_id(table->dev, sw_id); | 70 | hw_fn_id = mlx5_sf_sw_to_hw_id(table->dev, sw_id); |
| @@ -71,7 +72,7 @@ int mlx5_sf_hw_table_sf_alloc(struct mlx5_core_dev *dev, u32 usr_sfnum) · 1 unmodified line | |||
| 71 | if (err) | 72 | if (err) |
| 72 | goto err; | 73 | goto err; |
| 73 | 74 | ||
| 74 | err = mlx5_modify_vhca_sw_id(dev, hw_fn_id, table->ecpu, usr_sfnum); | 75 | err = mlx5_modify_vhca_sw_id(dev, hw_fn_id, usr_sfnum); |
| 75 | if (err) | 76 | if (err) |
| 76 | goto vhca_err; | 77 | goto vhca_err; |
| 77 | 78 | ||
| @@ -117,7 +118,7 @@ void mlx5_sf_hw_table_sf_deferred_free(struct mlx5_core_dev *dev, u16 id) · 39 unmodified lines | |||
| 117 | 118 | ||
| 118 | hw_fn_id = mlx5_sf_sw_to_hw_id(dev, id); | 119 | hw_fn_id = mlx5_sf_sw_to_hw_id(dev, id); |
| 119 | mutex_lock(&table->table_lock); | 120 | mutex_lock(&table->table_lock); |
| 120 | err = mlx5_cmd_query_vhca_state(dev, hw_fn_id, table->ecpu, out, sizeof(out)); | 121 | err = mlx5_cmd_query_vhca_state(dev, hw_fn_id, out, sizeof(out)); |
| 121 | if (err) | 122 | if (err) |
| 122 | goto err; | 123 | goto err; |
| 123 | state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state); | 124 | state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state); |
| @@ -163,7 +164,6 @@ int mlx5_sf_hw_table_init(struct mlx5_core_dev *dev) · 39 unmodified lines | |||
| 163 | table->dev = dev; | 164 | table->dev = dev; |
| 164 | table->sfs = sfs; | 165 | table->sfs = sfs; |
| 165 | table->max_local_functions = max_functions; | 166 | table->max_local_functions = max_functions; |
| 166 | table->ecpu = mlx5_read_embedded_cpu(dev); | ||
| 167 | dev->priv.sf_hw_table = table; | 167 | dev->priv.sf_hw_table = table; |
| 168 | mlx5_core_dbg(dev, "SF HW table: max sfs = %d\n", max_functions); | 168 | mlx5_core_dbg(dev, "SF HW table: max sfs = %d\n", max_functions); |
| 169 | return 0; | 169 | return 0; |
| @@ -20,7 +20,7 @@ struct mlx5_ifc_vhca_state_context_bits { · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | u8 sw_function_id[0x20]; | 21 | u8 sw_function_id[0x20]; |
| 22 | 22 | ||
| 23 | u8 reserved_at_40[0x80]; | 23 | u8 reserved_at_40[0x40]; |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | struct mlx5_ifc_query_vhca_state_out_bits { | 26 | struct mlx5_ifc_query_vhca_state_out_bits { |
| @@ -19,52 +19,51 @@ struct mlx5_vhca_event_work { · 18 unmodified lines | |||
| 19 | struct mlx5_vhca_state_event event; | 19 | struct mlx5_vhca_state_event event; |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | int mlx5_cmd_query_vhca_state(struct mlx5_core_dev *dev, u16 function_id, | 22 | int mlx5_cmd_query_vhca_state(struct mlx5_core_dev *dev, u16 function_id, u32 *out, u32 outlen) |
| 23 | bool ecpu, u32 *out, u32 outlen) | ||
| 24 | { | 23 | { |
| 25 | u32 in[MLX5_ST_SZ_DW(query_vhca_state_in)] = {}; | 24 | u32 in[MLX5_ST_SZ_DW(query_vhca_state_in)] = {}; |
| 26 | 25 | ||
| 27 | MLX5_SET(query_vhca_state_in, in, opcode, MLX5_CMD_OP_QUERY_VHCA_STATE); | 26 | MLX5_SET(query_vhca_state_in, in, opcode, MLX5_CMD_OP_QUERY_VHCA_STATE); |
| 28 | MLX5_SET(query_vhca_state_in, in, function_id, function_id); | 27 | MLX5_SET(query_vhca_state_in, in, function_id, function_id); |
| 29 | MLX5_SET(query_vhca_state_in, in, embedded_cpu_function, ecpu); | 28 | MLX5_SET(query_vhca_state_in, in, embedded_cpu_function, 0); |
| 30 | 29 | ||
| 31 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); | 30 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); |
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | static int mlx5_cmd_modify_vhca_state(struct mlx5_core_dev *dev, u16 function_id, | 33 | static int mlx5_cmd_modify_vhca_state(struct mlx5_core_dev *dev, u16 function_id, |
| 35 | bool ecpu, u32 *in, u32 inlen) | 34 | u32 *in, u32 inlen) |
| 36 | { | 35 | { |
| 37 | u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {}; | 36 | u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {}; |
| 38 | 37 | ||
| 39 | MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE); | 38 | MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE); |
| 40 | MLX5_SET(modify_vhca_state_in, in, function_id, function_id); | 39 | MLX5_SET(modify_vhca_state_in, in, function_id, function_id); |
| 41 | MLX5_SET(modify_vhca_state_in, in, embedded_cpu_function, ecpu); | 40 | MLX5_SET(modify_vhca_state_in, in, embedded_cpu_function, 0); |
| 42 | 41 | ||
| 43 | return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); | 42 | return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); |
| 44 | } | 43 | } |
| 45 | 44 | ||
| 46 | int mlx5_modify_vhca_sw_id(struct mlx5_core_dev *dev, u16 function_id, bool ecpu, u32 sw_fn_id) | 45 | int mlx5_modify_vhca_sw_id(struct mlx5_core_dev *dev, u16 function_id, u32 sw_fn_id) |
| 47 | { | 46 | { |
| 48 | u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {}; | 47 | u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {}; |
| 49 | u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {}; | 48 | u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {}; |
| 50 | 49 | ||
| 51 | MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE); | 50 | MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE); |
| 52 | MLX5_SET(modify_vhca_state_in, in, function_id, function_id); | 51 | MLX5_SET(modify_vhca_state_in, in, function_id, function_id); |
| 53 | MLX5_SET(modify_vhca_state_in, in, embedded_cpu_function, ecpu); | 52 | MLX5_SET(modify_vhca_state_in, in, embedded_cpu_function, 0); |
| 54 | MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.sw_function_id, 1); | 53 | MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.sw_function_id, 1); |
| 55 | MLX5_SET(modify_vhca_state_in, in, vhca_state_context.sw_function_id, sw_fn_id); | 54 | MLX5_SET(modify_vhca_state_in, in, vhca_state_context.sw_function_id, sw_fn_id); |
| 56 | 55 | ||
| 57 | return mlx5_cmd_exec_inout(dev, modify_vhca_state, in, out); | 56 | return mlx5_cmd_exec_inout(dev, modify_vhca_state, in, out); |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id, bool ecpu) | 59 | int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id) |
| 61 | { | 60 | { |
| 62 | u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {}; | 61 | u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {}; |
| 63 | 62 | ||
| 64 | MLX5_SET(modify_vhca_state_in, in, vhca_state_context.arm_change_event, 1); | 63 | MLX5_SET(modify_vhca_state_in, in, vhca_state_context.arm_change_event, 1); |
| 65 | MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.arm_change_event, 1); | 64 | MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.arm_change_event, 1); |
| 66 | 65 | ||
| 67 | return mlx5_cmd_modify_vhca_state(dev, function_id, ecpu, in, sizeof(in)); | 66 | return mlx5_cmd_modify_vhca_state(dev, function_id, in, sizeof(in)); |
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | static void | 69 | static void |
| @@ -73,7 +72,7 @@ mlx5_vhca_event_notify(struct mlx5_core_dev *dev, struct mlx5_vhca_state_event * · 2 unmodified lines | |||
| 73 | u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {}; | 72 | u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {}; |
| 74 | int err; | 73 | int err; |
| 75 | 74 | ||
| 76 | err = mlx5_cmd_query_vhca_state(dev, event->function_id, event->ecpu, out, sizeof(out)); | 75 | err = mlx5_cmd_query_vhca_state(dev, event->function_id, out, sizeof(out)); |
| 77 | if (err) | 76 | if (err) |
| 78 | return; | 77 | return; |
| 79 | 78 | ||
| @@ -82,7 +81,7 @@ mlx5_vhca_event_notify(struct mlx5_core_dev *dev, struct mlx5_vhca_state_event * · 2 unmodified lines | |||
| 82 | event->new_vhca_state = MLX5_GET(query_vhca_state_out, out, | 81 | event->new_vhca_state = MLX5_GET(query_vhca_state_out, out, |
| 83 | vhca_state_context.vhca_state); | 82 | vhca_state_context.vhca_state); |
| 84 | 83 | ||
| 85 | mlx5_vhca_event_arm(dev, event->function_id, event->ecpu); | 84 | mlx5_vhca_event_arm(dev, event->function_id); |
| 86 | 85 | ||
| 87 | blocking_notifier_call_chain(&dev->priv.vhca_state_notifier->n_head, 0, event); | 86 | blocking_notifier_call_chain(&dev->priv.vhca_state_notifier->n_head, 0, event); |
| 88 | } | 87 | } |
| @@ -94,6 +93,7 @@ static void mlx5_vhca_state_work_handler(struct work_struct *_work) · 5 unmodified lines | |||
| 94 | struct mlx5_core_dev *dev = notifier->dev; | 93 | struct mlx5_core_dev *dev = notifier->dev; |
| 95 | 94 | ||
| 96 | mlx5_vhca_event_notify(dev, &work->event); | 95 | mlx5_vhca_event_notify(dev, &work->event); |
| 96 | kfree(work); | ||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static int | 99 | static int |
| @@ -110,7 +110,6 @@ mlx5_vhca_state_change_notifier(struct notifier_block *nb, unsigned long type, v · 10 unmodified lines | |||
| 110 | INIT_WORK(&work->work, &mlx5_vhca_state_work_handler); | 110 | INIT_WORK(&work->work, &mlx5_vhca_state_work_handler); |
| 111 | work->notifier = notifier; | 111 | work->notifier = notifier; |
| 112 | work->event.function_id = be16_to_cpu(eqe->data.vhca_state.function_id); | 112 | work->event.function_id = be16_to_cpu(eqe->data.vhca_state.function_id); |
| 113 | work->event.ecpu = be16_to_cpu(eqe->data.vhca_state.ec_function); | ||
| 114 | mlx5_events_work_enqueue(notifier->dev, &work->work); | 113 | mlx5_events_work_enqueue(notifier->dev, &work->work); |
| 115 | return NOTIFY_OK; | 114 | return NOTIFY_OK; |
| 116 | } | 115 | } |
| @@ -10,7 +10,6 @@ struct mlx5_vhca_state_event { · 9 unmodified lines | |||
| 10 | u16 function_id; | 10 | u16 function_id; |
| 11 | u16 sw_function_id; | 11 | u16 sw_function_id; |
| 12 | u8 new_vhca_state; | 12 | u8 new_vhca_state; |
| 13 | bool ecpu; | ||
| 14 | }; | 13 | }; |
| 15 | 14 | ||
| 16 | static inline bool mlx5_vhca_event_supported(const struct mlx5_core_dev *dev) | 15 | static inline bool mlx5_vhca_event_supported(const struct mlx5_core_dev *dev) |
| @@ -25,10 +24,10 @@ void mlx5_vhca_event_start(struct mlx5_core_dev *dev); · 8 unmodified lines | |||
| 25 | void mlx5_vhca_event_stop(struct mlx5_core_dev *dev); | 24 | void mlx5_vhca_event_stop(struct mlx5_core_dev *dev); |
| 26 | int mlx5_vhca_event_notifier_register(struct mlx5_core_dev *dev, struct notifier_block *nb); | 25 | int mlx5_vhca_event_notifier_register(struct mlx5_core_dev *dev, struct notifier_block *nb); |
| 27 | void mlx5_vhca_event_notifier_unregister(struct mlx5_core_dev *dev, struct notifier_block *nb); | 26 | void mlx5_vhca_event_notifier_unregister(struct mlx5_core_dev *dev, struct notifier_block *nb); |
| 28 | int mlx5_modify_vhca_sw_id(struct mlx5_core_dev *dev, u16 function_id, bool ecpu, u32 sw_fn_id); | 27 | int mlx5_modify_vhca_sw_id(struct mlx5_core_dev *dev, u16 function_id, u32 sw_fn_id); |
| 29 | int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id, bool ecpu); | 28 | int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id); |
| 30 | int mlx5_cmd_query_vhca_state(struct mlx5_core_dev *dev, u16 function_id, | 29 | int mlx5_cmd_query_vhca_state(struct mlx5_core_dev *dev, u16 function_id, |
| 31 | bool ecpu, u32 *out, u32 outlen); | 30 | u32 *out, u32 outlen); |
| 32 | #else | 31 | #else |
| 33 | 32 | ||
| 34 | static inline void mlx5_vhca_state_cap_handle(struct mlx5_core_dev *dev, void *set_hca_cap) | 33 | static inline void mlx5_vhca_state_cap_handle(struct mlx5_core_dev *dev, void *set_hca_cap) |
| @@ -169,6 +169,7 @@ static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev, · 168 unmodified lines | |||
| 169 | MLX5_SET(qpc, qpc, log_rq_size, ilog2(dr_qp->rq.wqe_cnt)); | 169 | MLX5_SET(qpc, qpc, log_rq_size, ilog2(dr_qp->rq.wqe_cnt)); |
| 170 | MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ); | 170 | MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ); |
| 171 | MLX5_SET(qpc, qpc, log_sq_size, ilog2(dr_qp->sq.wqe_cnt)); | 171 | MLX5_SET(qpc, qpc, log_sq_size, ilog2(dr_qp->sq.wqe_cnt)); |
| 172 | MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(mdev)); | ||
| 172 | MLX5_SET64(qpc, qpc, dbr_addr, dr_qp->wq_ctrl.db.dma); | 173 | MLX5_SET64(qpc, qpc, dbr_addr, dr_qp->wq_ctrl.db.dma); |
| 173 | if (MLX5_CAP_GEN(mdev, cqe_version) == 1) | 174 | if (MLX5_CAP_GEN(mdev, cqe_version) == 1) |
| 174 | MLX5_SET(qpc, qpc, user_index, 0xFFFFFF); | 175 | MLX5_SET(qpc, qpc, user_index, 0xFFFFFF); |
| @@ -264,8 +264,8 @@ static void dr_ste_v1_set_miss_addr(u8 *hw_ste_p, u64 miss_addr) · 263 unmodified lines | |||
| 264 | static u64 dr_ste_v1_get_miss_addr(u8 *hw_ste_p) | 264 | static u64 dr_ste_v1_get_miss_addr(u8 *hw_ste_p) |
| 265 | { | 265 | { |
| 266 | u64 index = | 266 | u64 index = |
| 267 | (MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6) | | 267 | ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6) | |
| 268 | MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32) << 26); | 268 | ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32)) << 26); |
| 269 | 269 | ||
| 270 | return index << 6; | 270 | return index << 6; |
| 271 | } | 271 | } |
| @@ -327,8 +327,14 @@ int nfp_compile_flow_metadata(struct nfp_app *app, · 326 unmodified lines | |||
| 327 | goto err_free_ctx_entry; | 327 | goto err_free_ctx_entry; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | /* Do net allocate a mask-id for pre_tun_rules. These flows are used to | ||
| 331 | * configure the pre_tun table and are never actually send to the | ||
| 332 | * firmware as an add-flow message. This causes the mask-id allocation | ||
| 333 | * on the firmware to get out of sync if allocated here. | ||
| 334 | */ | ||
| 330 | new_mask_id = 0; | 335 | new_mask_id = 0; |
| 331 | if (!nfp_check_mask_add(app, nfp_flow->mask_data, | 336 | if (!nfp_flow->pre_tun_rule.dev && |
| 337 | !nfp_check_mask_add(app, nfp_flow->mask_data, | ||
| 332 | nfp_flow->meta.mask_len, | 338 | nfp_flow->meta.mask_len, |
| 333 | &nfp_flow->meta.flags, &new_mask_id)) { | 339 | &nfp_flow->meta.flags, &new_mask_id)) { |
| 334 | NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot allocate a new mask id"); | 340 | NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot allocate a new mask id"); |
| @@ -359,7 +365,8 @@ int nfp_compile_flow_metadata(struct nfp_app *app, · 24 unmodified lines | |||
| 359 | goto err_remove_mask; | 365 | goto err_remove_mask; |
| 360 | } | 366 | } |
| 361 | 367 | ||
| 362 | if (!nfp_check_mask_remove(app, nfp_flow->mask_data, | 368 | if (!nfp_flow->pre_tun_rule.dev && |
| 369 | !nfp_check_mask_remove(app, nfp_flow->mask_data, | ||
| 363 | nfp_flow->meta.mask_len, | 370 | nfp_flow->meta.mask_len, |
| 364 | NULL, &new_mask_id)) { | 371 | NULL, &new_mask_id)) { |
| 365 | NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot release mask id"); | 372 | NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot release mask id"); |
| @@ -374,8 +381,10 @@ int nfp_compile_flow_metadata(struct nfp_app *app, · 8 unmodified lines | |||
| 374 | return 0; | 381 | return 0; |
| 375 | 382 | ||
| 376 | err_remove_mask: | 383 | err_remove_mask: |
| 377 | nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, | 384 | if (!nfp_flow->pre_tun_rule.dev) |
| 378 | NULL, &new_mask_id); | 385 | nfp_check_mask_remove(app, nfp_flow->mask_data, |
| 386 | nfp_flow->meta.mask_len, | ||
| 387 | NULL, &new_mask_id); | ||
| 379 | err_remove_rhash: | 388 | err_remove_rhash: |
| 380 | WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, | 389 | WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, |
| 381 | &ctx_entry->ht_node, | 390 | &ctx_entry->ht_node, |
| @@ -406,9 +415,10 @@ int nfp_modify_flow_metadata(struct nfp_app *app, · 24 unmodified lines | |||
| 406 | 415 | ||
| 407 | __nfp_modify_flow_metadata(priv, nfp_flow); | 416 | __nfp_modify_flow_metadata(priv, nfp_flow); |
| 408 | 417 | ||
| 409 | nfp_check_mask_remove(app, nfp_flow->mask_data, | 418 | if (!nfp_flow->pre_tun_rule.dev) |
| 410 | nfp_flow->meta.mask_len, &nfp_flow->meta.flags, | 419 | nfp_check_mask_remove(app, nfp_flow->mask_data, |
| 411 | &new_mask_id); | 420 | nfp_flow->meta.mask_len, &nfp_flow->meta.flags, |
| 421 | &new_mask_id); | ||
| 412 | 422 | ||
| 413 | /* Update flow payload with mask ids. */ | 423 | /* Update flow payload with mask ids. */ |
| 414 | nfp_flow->unmasked_data[NFP_FL_MASK_ID_LOCATION] = new_mask_id; | 424 | nfp_flow->unmasked_data[NFP_FL_MASK_ID_LOCATION] = new_mask_id; |
| @@ -1142,6 +1142,12 @@ nfp_flower_validate_pre_tun_rule(struct nfp_app *app, · 1141 unmodified lines | |||
| 1142 | return -EOPNOTSUPP; | 1142 | return -EOPNOTSUPP; |
| 1143 | } | 1143 | } |
| 1144 | 1144 | ||
| 1145 | if (!(key_layer & NFP_FLOWER_LAYER_IPV4) && | ||
| 1146 | !(key_layer & NFP_FLOWER_LAYER_IPV6)) { | ||
| 1147 | NL_SET_ERR_MSG_MOD(extack, "unsupported pre-tunnel rule: match on ipv4/ipv6 eth_type must be present"); | ||
| 1148 | return -EOPNOTSUPP; | ||
| 1149 | } | ||
| 1150 | |||
| 1145 | /* Skip fields known to exist. */ | 1151 | /* Skip fields known to exist. */ |
| 1146 | mask += sizeof(struct nfp_flower_meta_tci); | 1152 | mask += sizeof(struct nfp_flower_meta_tci); |
| 1147 | ext += sizeof(struct nfp_flower_meta_tci); | 1153 | ext += sizeof(struct nfp_flower_meta_tci); |
| @@ -1152,6 +1158,13 @@ nfp_flower_validate_pre_tun_rule(struct nfp_app *app, · 4 unmodified lines | |||
| 1152 | mask += sizeof(struct nfp_flower_in_port); | 1158 | mask += sizeof(struct nfp_flower_in_port); |
| 1153 | ext += sizeof(struct nfp_flower_in_port); | 1159 | ext += sizeof(struct nfp_flower_in_port); |
| 1154 | 1160 | ||
| 1161 | /* Ensure destination MAC address matches pre_tun_dev. */ | ||
| 1162 | mac = (struct nfp_flower_mac_mpls *)ext; | ||
| 1163 | if (memcmp(&mac->mac_dst[0], flow->pre_tun_rule.dev->dev_addr, 6)) { | ||
| 1164 | NL_SET_ERR_MSG_MOD(extack, "unsupported pre-tunnel rule: dest MAC must match output dev MAC"); | ||
| 1165 | return -EOPNOTSUPP; | ||
| 1166 | } | ||
| 1167 | |||
| 1155 | /* Ensure destination MAC address is fully matched. */ | 1168 | /* Ensure destination MAC address is fully matched. */ |
| 1156 | mac = (struct nfp_flower_mac_mpls *)mask; | 1169 | mac = (struct nfp_flower_mac_mpls *)mask; |
| 1157 | if (!is_broadcast_ether_addr(&mac->mac_dst[0])) { | 1170 | if (!is_broadcast_ether_addr(&mac->mac_dst[0])) { |
| @@ -1159,6 +1172,11 @@ nfp_flower_validate_pre_tun_rule(struct nfp_app *app, · 1 unmodified line | |||
| 1159 | return -EOPNOTSUPP; | 1172 | return -EOPNOTSUPP; |
| 1160 | } | 1173 | } |
| 1161 | 1174 | ||
| 1175 | if (mac->mpls_lse) { | ||
| 1176 | NL_SET_ERR_MSG_MOD(extack, "unsupported pre-tunnel rule: MPLS not supported"); | ||
| 1177 | return -EOPNOTSUPP; | ||
| 1178 | } | ||
| 1179 | |||
| 1162 | mask += sizeof(struct nfp_flower_mac_mpls); | 1180 | mask += sizeof(struct nfp_flower_mac_mpls); |
| 1163 | ext += sizeof(struct nfp_flower_mac_mpls); | 1181 | ext += sizeof(struct nfp_flower_mac_mpls); |
| 1164 | if (key_layer & NFP_FLOWER_LAYER_IPV4 || | 1182 | if (key_layer & NFP_FLOWER_LAYER_IPV4 || |
| @@ -16,8 +16,9 @@ · 15 unmodified lines | |||
| 16 | #define NFP_FL_MAX_ROUTES 32 | 16 | #define NFP_FL_MAX_ROUTES 32 |
| 17 | 17 | ||
| 18 | #define NFP_TUN_PRE_TUN_RULE_LIMIT 32 | 18 | #define NFP_TUN_PRE_TUN_RULE_LIMIT 32 |
| 19 | #define NFP_TUN_PRE_TUN_RULE_DEL 0x1 | 19 | #define NFP_TUN_PRE_TUN_RULE_DEL BIT(0) |
| 20 | #define NFP_TUN_PRE_TUN_IDX_BIT 0x8 | 20 | #define NFP_TUN_PRE_TUN_IDX_BIT BIT(3) |
| 21 | #define NFP_TUN_PRE_TUN_IPV6_BIT BIT(7) | ||
| 21 | 22 | ||
| 22 | /** | 23 | /** |
| 23 | * struct nfp_tun_pre_run_rule - rule matched before decap | 24 | * struct nfp_tun_pre_run_rule - rule matched before decap |
| @@ -1268,6 +1269,7 @@ int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app, · 1244 unmodified lines | |||
| 1268 | { | 1269 | { |
| 1269 | struct nfp_flower_priv *app_priv = app->priv; | 1270 | struct nfp_flower_priv *app_priv = app->priv; |
| 1270 | struct nfp_tun_offloaded_mac *mac_entry; | 1271 | struct nfp_tun_offloaded_mac *mac_entry; |
| 1272 | struct nfp_flower_meta_tci *key_meta; | ||
| 1271 | struct nfp_tun_pre_tun_rule payload; | 1273 | struct nfp_tun_pre_tun_rule payload; |
| 1272 | struct net_device *internal_dev; | 1274 | struct net_device *internal_dev; |
| 1273 | int err; | 1275 | int err; |
| @@ -1290,6 +1292,15 @@ int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app, · 16 unmodified lines | |||
| 1290 | if (!mac_entry) | 1292 | if (!mac_entry) |
| 1291 | return -ENOENT; | 1293 | return -ENOENT; |
| 1292 | 1294 | ||
| 1295 | /* Set/clear IPV6 bit. cpu_to_be16() swap will lead to MSB being | ||
| 1296 | * set/clear for port_idx. | ||
| 1297 | */ | ||
| 1298 | key_meta = (struct nfp_flower_meta_tci *)flow->unmasked_data; | ||
| 1299 | if (key_meta->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV6) | ||
| 1300 | mac_entry->index |= NFP_TUN_PRE_TUN_IPV6_BIT; | ||
| 1301 | else | ||
| 1302 | mac_entry->index &= ~NFP_TUN_PRE_TUN_IPV6_BIT; | ||
| 1303 | |||
| 1293 | payload.port_idx = cpu_to_be16(mac_entry->index); | 1304 | payload.port_idx = cpu_to_be16(mac_entry->index); |
| 1294 | 1305 | ||
| 1295 | /* Copy mac id and vlan to flow - dev may not exist at delete time. */ | 1306 | /* Copy mac id and vlan to flow - dev may not exist at delete time. */ |
| @@ -1083,15 +1083,18 @@ static int ionic_tx(struct ionic_queue *q, struct sk_buff *skb) · 1082 unmodified lines | |||
| 1083 | static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) | 1083 | static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) |
| 1084 | { | 1084 | { |
| 1085 | struct ionic_tx_stats *stats = q_to_tx_stats(q); | 1085 | struct ionic_tx_stats *stats = q_to_tx_stats(q); |
| 1086 | int ndescs; | ||
| 1086 | int err; | 1087 | int err; |
| 1087 | 1088 | ||
| 1088 | /* If TSO, need roundup(skb->len/mss) descs */ | 1089 | /* Each desc is mss long max, so a descriptor for each gso_seg */ |
| 1089 | if (skb_is_gso(skb)) | 1090 | if (skb_is_gso(skb)) |
| 1090 | return (skb->len / skb_shinfo(skb)->gso_size) + 1; | 1091 | ndescs = skb_shinfo(skb)->gso_segs; |
| 1092 | else | ||
| 1093 | ndescs = 1; | ||
| 1091 | 1094 | ||
| 1092 | /* If non-TSO, just need 1 desc and nr_frags sg elems */ | 1095 | /* If non-TSO, just need 1 desc and nr_frags sg elems */ |
| 1093 | if (skb_shinfo(skb)->nr_frags <= q->max_sg_elems) | 1096 | if (skb_shinfo(skb)->nr_frags <= q->max_sg_elems) |
| 1094 | return 1; | 1097 | return ndescs; |
| 1095 | 1098 | ||
| 1096 | /* Too many frags, so linearize */ | 1099 | /* Too many frags, so linearize */ |
| 1097 | err = skb_linearize(skb); | 1100 | err = skb_linearize(skb); |
| @@ -1100,8 +1103,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) · 2 unmodified lines | |||
| 1100 | 1103 | ||
| 1101 | stats->linearize++; | 1104 | stats->linearize++; |
| 1102 | 1105 | ||
| 1103 | /* Need 1 desc and zero sg elems */ | 1106 | return ndescs; |
| 1104 | return 1; | ||
| 1105 | } | 1107 | } |
| 1106 | 1108 | ||
| 1107 | static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs) | 1109 | static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs) |
| @@ -1425,6 +1425,7 @@ void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter) · 1424 unmodified lines | |||
| 1425 | 1425 | ||
| 1426 | if (fw_dump->tmpl_hdr == NULL || current_version > prev_version) { | 1426 | if (fw_dump->tmpl_hdr == NULL || current_version > prev_version) { |
| 1427 | vfree(fw_dump->tmpl_hdr); | 1427 | vfree(fw_dump->tmpl_hdr); |
| 1428 | fw_dump->tmpl_hdr = NULL; | ||
| 1428 | 1429 | ||
| 1429 | if (qlcnic_83xx_md_check_extended_dump_capability(adapter)) | 1430 | if (qlcnic_83xx_md_check_extended_dump_capability(adapter)) |
| 1430 | extended = !qlcnic_83xx_extend_md_capab(adapter); | 1431 | extended = !qlcnic_83xx_extend_md_capab(adapter); |
| @@ -1443,6 +1444,8 @@ void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter) · 12 unmodified lines | |||
| 1443 | struct qlcnic_83xx_dump_template_hdr *hdr; | 1444 | struct qlcnic_83xx_dump_template_hdr *hdr; |
| 1444 | 1445 | ||
| 1445 | hdr = fw_dump->tmpl_hdr; | 1446 | hdr = fw_dump->tmpl_hdr; |
| 1447 | if (!hdr) | ||
| 1448 | return; | ||
| 1446 | hdr->drv_cap_mask = 0x1f; | 1449 | hdr->drv_cap_mask = 0x1f; |
| 1447 | fw_dump->cap_mask = 0x1f; | 1450 | fw_dump->cap_mask = 0x1f; |
| 1448 | dev_info(&pdev->dev, | 1451 | dev_info(&pdev->dev, |
| @@ -4654,6 +4654,9 @@ static void rtl8169_down(struct rtl8169_private *tp) · 4653 unmodified lines | |||
| 4654 | 4654 | ||
| 4655 | rtl8169_update_counters(tp); | 4655 | rtl8169_update_counters(tp); |
| 4656 | 4656 | ||
| 4657 | pci_clear_master(tp->pci_dev); | ||
| 4658 | rtl_pci_commit(tp); | ||
| 4659 | |||
| 4657 | rtl8169_cleanup(tp, true); | 4660 | rtl8169_cleanup(tp, true); |
| 4658 | 4661 | ||
| 4659 | rtl_prepare_power_down(tp); | 4662 | rtl_prepare_power_down(tp); |
| @@ -4661,6 +4664,7 @@ static void rtl8169_down(struct rtl8169_private *tp) · 1 unmodified line | |||
| 4661 | 4664 | ||
| 4662 | static void rtl8169_up(struct rtl8169_private *tp) | 4665 | static void rtl8169_up(struct rtl8169_private *tp) |
| 4663 | { | 4666 | { |
| 4667 | pci_set_master(tp->pci_dev); | ||
| 4664 | phy_resume(tp->phydev); | 4668 | phy_resume(tp->phydev); |
| 4665 | rtl8169_init_phy(tp); | 4669 | rtl8169_init_phy(tp); |
| 4666 | napi_enable(&tp->napi); | 4670 | napi_enable(&tp->napi); |
| @@ -5315,8 +5319,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 648 unmodified lines | |||
| 5315 | 5319 | ||
| 5316 | rtl_hw_reset(tp); | 5320 | rtl_hw_reset(tp); |
| 5317 | 5321 | ||
| 5318 | pci_set_master(pdev); | ||
| 5319 | |||
| 5320 | rc = rtl_alloc_irq(tp); | 5322 | rc = rtl_alloc_irq(tp); |
| 5321 | if (rc < 0) { | 5323 | if (rc < 0) { |
| 5322 | dev_err(&pdev->dev, "Can't allocate interrupt\n"); | 5324 | dev_err(&pdev->dev, "Can't allocate interrupt\n"); |
| @@ -1715,14 +1715,17 @@ static int netsec_netdev_init(struct net_device *ndev) · 1714 unmodified lines | |||
| 1715 | goto err1; | 1715 | goto err1; |
| 1716 | 1716 | ||
| 1717 | /* set phy power down */ | 1717 | /* set phy power down */ |
| 1718 | data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR) | | 1718 | data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR); |
| 1719 | BMCR_PDOWN; | 1719 | netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, |
| 1720 | netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); | 1720 | data | BMCR_PDOWN); |
| 1721 | 1721 | ||
| 1722 | ret = netsec_reset_hardware(priv, true); | 1722 | ret = netsec_reset_hardware(priv, true); |
| 1723 | if (ret) | 1723 | if (ret) |
| 1724 | goto err2; | 1724 | goto err2; |
| 1725 | 1725 | ||
| 1726 | /* Restore phy power state */ | ||
| 1727 | netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); | ||
| 1728 | |||
| 1726 | spin_lock_init(&priv->desc_ring[NETSEC_RING_TX].lock); | 1729 | spin_lock_init(&priv->desc_ring[NETSEC_RING_TX].lock); |
| 1727 | spin_lock_init(&priv->desc_ring[NETSEC_RING_RX].lock); | 1730 | spin_lock_init(&priv->desc_ring[NETSEC_RING_RX].lock); |
| 1728 | 1731 | ||
| @@ -1214,6 +1214,8 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 1213 unmodified lines | |||
| 1214 | plat_dat->init = sun8i_dwmac_init; | 1214 | plat_dat->init = sun8i_dwmac_init; |
| 1215 | plat_dat->exit = sun8i_dwmac_exit; | 1215 | plat_dat->exit = sun8i_dwmac_exit; |
| 1216 | plat_dat->setup = sun8i_dwmac_setup; | 1216 | plat_dat->setup = sun8i_dwmac_setup; |
| 1217 | plat_dat->tx_fifo_size = 4096; | ||
| 1218 | plat_dat->rx_fifo_size = 16384; | ||
| 1217 | 1219 | ||
| 1218 | ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); | 1220 | ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); |
| 1219 | if (ret) | 1221 | if (ret) |
| @@ -1880,7 +1880,7 @@ static int axienet_probe(struct platform_device *pdev) · 1879 unmodified lines | |||
| 1880 | if (IS_ERR(lp->regs)) { | 1880 | if (IS_ERR(lp->regs)) { |
| 1881 | dev_err(&pdev->dev, "could not map Axi Ethernet regs.\n"); | 1881 | dev_err(&pdev->dev, "could not map Axi Ethernet regs.\n"); |
| 1882 | ret = PTR_ERR(lp->regs); | 1882 | ret = PTR_ERR(lp->regs); |
| 1883 | goto free_netdev; | 1883 | goto cleanup_clk; |
| 1884 | } | 1884 | } |
| 1885 | lp->regs_start = ethres->start; | 1885 | lp->regs_start = ethres->start; |
| 1886 | 1886 | ||
| @@ -1958,18 +1958,18 @@ static int axienet_probe(struct platform_device *pdev) · 71 unmodified lines | |||
| 1958 | break; | 1958 | break; |
| 1959 | default: | 1959 | default: |
| 1960 | ret = -EINVAL; | 1960 | ret = -EINVAL; |
| 1961 | goto free_netdev; | 1961 | goto cleanup_clk; |
| 1962 | } | 1962 | } |
| 1963 | } else { | 1963 | } else { |
| 1964 | ret = of_get_phy_mode(pdev->dev.of_node, &lp->phy_mode); | 1964 | ret = of_get_phy_mode(pdev->dev.of_node, &lp->phy_mode); |
| 1965 | if (ret) | 1965 | if (ret) |
| 1966 | goto free_netdev; | 1966 | goto cleanup_clk; |
| 1967 | } | 1967 | } |
| 1968 | if (lp->switch_x_sgmii && lp->phy_mode != PHY_INTERFACE_MODE_SGMII && | 1968 | if (lp->switch_x_sgmii && lp->phy_mode != PHY_INTERFACE_MODE_SGMII && |
| 1969 | lp->phy_mode != PHY_INTERFACE_MODE_1000BASEX) { | 1969 | lp->phy_mode != PHY_INTERFACE_MODE_1000BASEX) { |
| 1970 | dev_err(&pdev->dev, "xlnx,switch-x-sgmii only supported with SGMII or 1000BaseX\n"); | 1970 | dev_err(&pdev->dev, "xlnx,switch-x-sgmii only supported with SGMII or 1000BaseX\n"); |
| 1971 | ret = -EINVAL; | 1971 | ret = -EINVAL; |
| 1972 | goto free_netdev; | 1972 | goto cleanup_clk; |
| 1973 | } | 1973 | } |
| 1974 | 1974 | ||
| 1975 | /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ | 1975 | /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ |
| @@ -1982,7 +1982,7 @@ static int axienet_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 1982 | dev_err(&pdev->dev, | 1982 | dev_err(&pdev->dev, |
| 1983 | "unable to get DMA resource\n"); | 1983 | "unable to get DMA resource\n"); |
| 1984 | of_node_put(np); | 1984 | of_node_put(np); |
| 1985 | goto free_netdev; | 1985 | goto cleanup_clk; |
| 1986 | } | 1986 | } |
| 1987 | lp->dma_regs = devm_ioremap_resource(&pdev->dev, | 1987 | lp->dma_regs = devm_ioremap_resource(&pdev->dev, |
| 1988 | &dmares); | 1988 | &dmares); |
| @@ -2002,12 +2002,12 @@ static int axienet_probe(struct platform_device *pdev) · 13 unmodified lines | |||
| 2002 | if (IS_ERR(lp->dma_regs)) { | 2002 | if (IS_ERR(lp->dma_regs)) { |
| 2003 | dev_err(&pdev->dev, "could not map DMA regs\n"); | 2003 | dev_err(&pdev->dev, "could not map DMA regs\n"); |
| 2004 | ret = PTR_ERR(lp->dma_regs); | 2004 | ret = PTR_ERR(lp->dma_regs); |
| 2005 | goto free_netdev; | 2005 | goto cleanup_clk; |
| 2006 | } | 2006 | } |
| 2007 | if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) { | 2007 | if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) { |
| 2008 | dev_err(&pdev->dev, "could not determine irqs\n"); | 2008 | dev_err(&pdev->dev, "could not determine irqs\n"); |
| 2009 | ret = -ENOMEM; | 2009 | ret = -ENOMEM; |
| 2010 | goto free_netdev; | 2010 | goto cleanup_clk; |
| 2011 | } | 2011 | } |
| 2012 | 2012 | ||
| 2013 | /* Autodetect the need for 64-bit DMA pointers. | 2013 | /* Autodetect the need for 64-bit DMA pointers. |
| @@ -2037,7 +2037,7 @@ static int axienet_probe(struct platform_device *pdev) · 23 unmodified lines | |||
| 2037 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); | 2037 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); |
| 2038 | if (ret) { | 2038 | if (ret) { |
| 2039 | dev_err(&pdev->dev, "No suitable DMA available\n"); | 2039 | dev_err(&pdev->dev, "No suitable DMA available\n"); |
| 2040 | goto free_netdev; | 2040 | goto cleanup_clk; |
| 2041 | } | 2041 | } |
| 2042 | 2042 | ||
| 2043 | /* Check for Ethernet core IRQ (optional) */ | 2043 | /* Check for Ethernet core IRQ (optional) */ |
| @@ -2068,12 +2068,12 @@ static int axienet_probe(struct platform_device *pdev) · 24 unmodified lines | |||
| 2068 | if (!lp->phy_node) { | 2068 | if (!lp->phy_node) { |
| 2069 | dev_err(&pdev->dev, "phy-handle required for 1000BaseX/SGMII\n"); | 2069 | dev_err(&pdev->dev, "phy-handle required for 1000BaseX/SGMII\n"); |
| 2070 | ret = -EINVAL; | 2070 | ret = -EINVAL; |
| 2071 | goto free_netdev; | 2071 | goto cleanup_mdio; |
| 2072 | } | 2072 | } |
| 2073 | lp->pcs_phy = of_mdio_find_device(lp->phy_node); | 2073 | lp->pcs_phy = of_mdio_find_device(lp->phy_node); |
| 2074 | if (!lp->pcs_phy) { | 2074 | if (!lp->pcs_phy) { |
| 2075 | ret = -EPROBE_DEFER; | 2075 | ret = -EPROBE_DEFER; |
| 2076 | goto free_netdev; | 2076 | goto cleanup_mdio; |
| 2077 | } | 2077 | } |
| 2078 | lp->phylink_config.pcs_poll = true; | 2078 | lp->phylink_config.pcs_poll = true; |
| 2079 | } | 2079 | } |
| @@ -2087,17 +2087,30 @@ static int axienet_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 2087 | if (IS_ERR(lp->phylink)) { | 2087 | if (IS_ERR(lp->phylink)) { |
| 2088 | ret = PTR_ERR(lp->phylink); | 2088 | ret = PTR_ERR(lp->phylink); |
| 2089 | dev_err(&pdev->dev, "phylink_create error (%i)\n", ret); | 2089 | dev_err(&pdev->dev, "phylink_create error (%i)\n", ret); |
| 2090 | goto free_netdev; | 2090 | goto cleanup_mdio; |
| 2091 | } | 2091 | } |
| 2092 | 2092 | ||
| 2093 | ret = register_netdev(lp->ndev); | 2093 | ret = register_netdev(lp->ndev); |
| 2094 | if (ret) { | 2094 | if (ret) { |
| 2095 | dev_err(lp->dev, "register_netdev() error (%i)\n", ret); | 2095 | dev_err(lp->dev, "register_netdev() error (%i)\n", ret); |
| 2096 | goto free_netdev; | 2096 | goto cleanup_phylink; |
| 2097 | } | 2097 | } |
| 2098 | 2098 | ||
| 2099 | return 0; | 2099 | return 0; |
| 2100 | 2100 | ||
| 2101 | cleanup_phylink: | ||
| 2102 | phylink_destroy(lp->phylink); | ||
| 2103 | |||
| 2104 | cleanup_mdio: | ||
| 2105 | if (lp->pcs_phy) | ||
| 2106 | put_device(&lp->pcs_phy->dev); | ||
| 2107 | if (lp->mii_bus) | ||
| 2108 | axienet_mdio_teardown(lp); | ||
| 2109 | of_node_put(lp->phy_node); | ||
| 2110 | |||
| 2111 | cleanup_clk: | ||
| 2112 | clk_disable_unprepare(lp->clk); | ||
| 2113 | |||
| 2101 | free_netdev: | 2114 | free_netdev: |
| 2102 | free_netdev(ndev); | 2115 | free_netdev(ndev); |
| 2103 | 2116 | ||
| @@ -2167,7 +2167,6 @@ static void __exit scc_cleanup_driver(void) · 2166 unmodified lines | |||
| 2167 | 2167 | ||
| 2168 | MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>"); | 2168 | MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>"); |
| 2169 | MODULE_DESCRIPTION("AX.25 Device Driver for Z8530 based HDLC cards"); | 2169 | MODULE_DESCRIPTION("AX.25 Device Driver for Z8530 based HDLC cards"); |
| 2170 | MODULE_SUPPORTED_DEVICE("Z8530 based SCC cards for Amateur Radio"); | ||
| 2171 | MODULE_LICENSE("GPL"); | 2170 | MODULE_LICENSE("GPL"); |
| 2172 | module_init(scc_init_driver); | 2171 | module_init(scc_init_driver); |
| 2173 | module_exit(scc_cleanup_driver); | 2172 | module_exit(scc_cleanup_driver); |
| @@ -174,21 +174,23 @@ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, · 173 unmodified lines | |||
| 174 | : field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK); | 174 | : field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK); |
| 175 | if (mem->offset > offset_max || | 175 | if (mem->offset > offset_max || |
| 176 | ipa->mem_offset > offset_max - mem->offset) { | 176 | ipa->mem_offset > offset_max - mem->offset) { |
| 177 | dev_err(dev, "IPv%c %s%s table region offset too large " | 177 | dev_err(dev, "IPv%c %s%s table region offset too large\n", |
| 178 | "(0x%04x + 0x%04x > 0x%04x)\n", | 178 | ipv6 ? '6' : '4', hashed ? "hashed " : "", |
| 179 | ipv6 ? '6' : '4', hashed ? "hashed " : "", | 179 | route ? "route" : "filter"); |
| 180 | route ? "route" : "filter", | 180 | dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", |
| 181 | ipa->mem_offset, mem->offset, offset_max); | 181 | ipa->mem_offset, mem->offset, offset_max); |
| 182 | |||
| 182 | return false; | 183 | return false; |
| 183 | } | 184 | } |
| 184 | 185 | ||
| 185 | if (mem->offset > ipa->mem_size || | 186 | if (mem->offset > ipa->mem_size || |
| 186 | mem->size > ipa->mem_size - mem->offset) { | 187 | mem->size > ipa->mem_size - mem->offset) { |
| 187 | dev_err(dev, "IPv%c %s%s table region out of range " | 188 | dev_err(dev, "IPv%c %s%s table region out of range\n", |
| 188 | "(0x%04x + 0x%04x > 0x%04x)\n", | 189 | ipv6 ? '6' : '4', hashed ? "hashed " : "", |
| 189 | ipv6 ? '6' : '4', hashed ? "hashed " : "", | 190 | route ? "route" : "filter"); |
| 190 | route ? "route" : "filter", | 191 | dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", |
| 191 | mem->offset, mem->size, ipa->mem_size); | 192 | mem->offset, mem->size, ipa->mem_size); |
| 193 | |||
| 192 | return false; | 194 | return false; |
| 193 | } | 195 | } |
| 194 | 196 | ||
| @@ -204,22 +206,36 @@ static bool ipa_cmd_header_valid(struct ipa *ipa) · 9 unmodified lines | |||
| 204 | u32 size_max; | 206 | u32 size_max; |
| 205 | u32 size; | 207 | u32 size; |
| 206 | 208 | ||
| 209 | /* In ipa_cmd_hdr_init_local_add() we record the offset and size | ||
| 210 | * of the header table memory area. Make sure the offset and size | ||
| 211 | * fit in the fields that need to hold them, and that the entire | ||
| 212 | * range is within the overall IPA memory range. | ||
| 213 | */ | ||
| 207 | offset_max = field_max(HDR_INIT_LOCAL_FLAGS_HDR_ADDR_FMASK); | 214 | offset_max = field_max(HDR_INIT_LOCAL_FLAGS_HDR_ADDR_FMASK); |
| 208 | if (mem->offset > offset_max || | 215 | if (mem->offset > offset_max || |
| 209 | ipa->mem_offset > offset_max - mem->offset) { | 216 | ipa->mem_offset > offset_max - mem->offset) { |
| 210 | dev_err(dev, "header table region offset too large " | 217 | dev_err(dev, "header table region offset too large\n"); |
| 211 | "(0x%04x + 0x%04x > 0x%04x)\n", | 218 | dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", |
| 212 | ipa->mem_offset + mem->offset, offset_max); | 219 | ipa->mem_offset, mem->offset, offset_max); |
| 220 | |||
| 213 | return false; | 221 | return false; |
| 214 | } | 222 | } |
| 215 | 223 | ||
| 216 | size_max = field_max(HDR_INIT_LOCAL_FLAGS_TABLE_SIZE_FMASK); | 224 | size_max = field_max(HDR_INIT_LOCAL_FLAGS_TABLE_SIZE_FMASK); |
| 217 | size = ipa->mem[IPA_MEM_MODEM_HEADER].size; | 225 | size = ipa->mem[IPA_MEM_MODEM_HEADER].size; |
| 218 | size += ipa->mem[IPA_MEM_AP_HEADER].size; | 226 | size += ipa->mem[IPA_MEM_AP_HEADER].size; |
| 219 | if (mem->offset > ipa->mem_size || size > ipa->mem_size - mem->offset) { | 227 | |
| 220 | dev_err(dev, "header table region out of range " | 228 | if (size > size_max) { |
| 221 | "(0x%04x + 0x%04x > 0x%04x)\n", | 229 | dev_err(dev, "header table region size too large\n"); |
| 222 | mem->offset, size, ipa->mem_size); | 230 | dev_err(dev, " (0x%04x > 0x%08x)\n", size, size_max); |
| 231 | |||
| 232 | return false; | ||
| 233 | } | ||
| 234 | if (size > ipa->mem_size || mem->offset > ipa->mem_size - size) { | ||
| 235 | dev_err(dev, "header table region out of range\n"); | ||
| 236 | dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", | ||
| 237 | mem->offset, size, ipa->mem_size); | ||
| 238 | |||
| 223 | return false; | 239 | return false; |
| 224 | } | 240 | } |
| 225 | 241 | ||
| @@ -249,6 +249,7 @@ static const struct qmi_msg_handler ipa_server_msg_handlers[] = { · 248 unmodified lines | |||
| 249 | .decoded_size = IPA_QMI_DRIVER_INIT_COMPLETE_REQ_SZ, | 249 | .decoded_size = IPA_QMI_DRIVER_INIT_COMPLETE_REQ_SZ, |
| 250 | .fn = ipa_server_driver_init_complete, | 250 | .fn = ipa_server_driver_init_complete, |
| 251 | }, | 251 | }, |
| 252 | { }, | ||
| 252 | }; | 253 | }; |
| 253 | 254 | ||
| 254 | /* Handle an INIT_DRIVER response message from the modem. */ | 255 | /* Handle an INIT_DRIVER response message from the modem. */ |
| @@ -269,6 +270,7 @@ static const struct qmi_msg_handler ipa_client_msg_handlers[] = { · 14 unmodified lines | |||
| 269 | .decoded_size = IPA_QMI_INIT_DRIVER_RSP_SZ, | 270 | .decoded_size = IPA_QMI_INIT_DRIVER_RSP_SZ, |
| 270 | .fn = ipa_client_init_driver, | 271 | .fn = ipa_client_init_driver, |
| 271 | }, | 272 | }, |
| 273 | { }, | ||
| 272 | }; | 274 | }; |
| 273 | 275 | ||
| 274 | /* Return a pointer to an init modem driver request structure, which contains | 276 | /* Return a pointer to an init modem driver request structure, which contains |
| @@ -342,6 +342,10 @@ static int bcm54xx_config_init(struct phy_device *phydev) · 341 unmodified lines | |||
| 342 | bcm54xx_adjust_rxrefclk(phydev); | 342 | bcm54xx_adjust_rxrefclk(phydev); |
| 343 | 343 | ||
| 344 | switch (BRCM_PHY_MODEL(phydev)) { | 344 | switch (BRCM_PHY_MODEL(phydev)) { |
| 345 | case PHY_ID_BCM50610: | ||
| 346 | case PHY_ID_BCM50610M: | ||
| 347 | err = bcm54xx_config_clock_delay(phydev); | ||
| 348 | break; | ||
| 345 | case PHY_ID_BCM54210E: | 349 | case PHY_ID_BCM54210E: |
| 346 | err = bcm54210e_config_init(phydev); | 350 | err = bcm54210e_config_init(phydev); |
| 347 | break; | 351 | break; |
| @@ -399,6 +403,11 @@ static int bcm54xx_resume(struct phy_device *phydev) · 51 unmodified lines | |||
| 399 | if (ret < 0) | 403 | if (ret < 0) |
| 400 | return ret; | 404 | return ret; |
| 401 | 405 | ||
| 406 | /* Upon exiting power down, the PHY remains in an internal reset state | ||
| 407 | * for 40us | ||
| 408 | */ | ||
| 409 | fsleep(40); | ||
| 410 | |||
| 402 | return bcm54xx_config_init(phydev); | 411 | return bcm54xx_config_init(phydev); |
| 403 | } | 412 | } |
| 404 | 413 | ||
| @@ -477,7 +477,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, · 476 unmodified lines | |||
| 477 | err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, | 477 | err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, |
| 478 | state->interface); | 478 | state->interface); |
| 479 | if (err < 0) | 479 | if (err < 0) |
| 480 | phylink_err(pl, "mac_prepare failed: %pe\n", | 480 | phylink_err(pl, "mac_finish failed: %pe\n", |
| 481 | ERR_PTR(err)); | 481 | ERR_PTR(err)); |
| 482 | } | 482 | } |
| 483 | } | 483 | } |
| @@ -387,6 +387,8 @@ static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *i · 386 unmodified lines | |||
| 387 | 387 | ||
| 388 | err = register_netdev(dev); | 388 | err = register_netdev(dev); |
| 389 | if (err) { | 389 | if (err) { |
| 390 | /* Set disconnected flag so that disconnect() returns early. */ | ||
| 391 | pnd->disconnected = 1; | ||
| 390 | usb_driver_release_interface(&usbpn_driver, data_intf); | 392 | usb_driver_release_interface(&usbpn_driver, data_intf); |
| 391 | goto out; | 393 | goto out; |
| 392 | } | 394 | } |
| @@ -6553,7 +6553,10 @@ static int rtl_ops_init(struct r8152 *tp) · 6552 unmodified lines | |||
| 6553 | ops->in_nway = rtl8153_in_nway; | 6553 | ops->in_nway = rtl8153_in_nway; |
| 6554 | ops->hw_phy_cfg = r8153_hw_phy_cfg; | 6554 | ops->hw_phy_cfg = r8153_hw_phy_cfg; |
| 6555 | ops->autosuspend_en = rtl8153_runtime_enable; | 6555 | ops->autosuspend_en = rtl8153_runtime_enable; |
| 6556 | tp->rx_buf_sz = 32 * 1024; | 6556 | if (tp->udev->speed < USB_SPEED_SUPER) |
| 6557 | tp->rx_buf_sz = 16 * 1024; | ||
| 6558 | else | ||
| 6559 | tp->rx_buf_sz = 32 * 1024; | ||
| 6557 | tp->eee_en = true; | 6560 | tp->eee_en = true; |
| 6558 | tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; | 6561 | tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; |
| 6559 | break; | 6562 | break; |
| @@ -302,8 +302,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) · 301 unmodified lines | |||
| 302 | if (rxq < rcv->real_num_rx_queues) { | 302 | if (rxq < rcv->real_num_rx_queues) { |
| 303 | rq = &rcv_priv->rq[rxq]; | 303 | rq = &rcv_priv->rq[rxq]; |
| 304 | rcv_xdp = rcu_access_pointer(rq->xdp_prog); | 304 | rcv_xdp = rcu_access_pointer(rq->xdp_prog); |
| 305 | if (rcv_xdp) | 305 | skb_record_rx_queue(skb, rxq); |
| 306 | skb_record_rx_queue(skb, rxq); | ||
| 307 | } | 306 | } |
| 308 | 307 | ||
| 309 | skb_tx_timestamp(skb); | 308 | skb_tx_timestamp(skb); |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | struct x25_state { | 24 | struct x25_state { |
| 25 | x25_hdlc_proto settings; | 25 | x25_hdlc_proto settings; |
| 26 | bool up; | ||
| 27 | spinlock_t up_lock; /* Protects "up" */ | ||
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); | 30 | static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); |
| @@ -104,6 +106,8 @@ static void x25_data_transmit(struct net_device *dev, struct sk_buff *skb) · 75 unmodified lines | |||
| 104 | 106 | ||
| 105 | static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) | 107 | static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) |
| 106 | { | 108 | { |
| 109 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 110 | struct x25_state *x25st = state(hdlc); | ||
| 107 | int result; | 111 | int result; |
| 108 | 112 | ||
| 109 | /* There should be a pseudo header of 1 byte added by upper layers. | 113 | /* There should be a pseudo header of 1 byte added by upper layers. |
| @@ -114,11 +118,19 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) · 4 unmodified lines | |||
| 114 | return NETDEV_TX_OK; | 118 | return NETDEV_TX_OK; |
| 115 | } | 119 | } |
| 116 | 120 | ||
| 121 | spin_lock_bh(&x25st->up_lock); | ||
| 122 | if (!x25st->up) { | ||
| 123 | spin_unlock_bh(&x25st->up_lock); | ||
| 124 | kfree_skb(skb); | ||
| 125 | return NETDEV_TX_OK; | ||
| 126 | } | ||
| 127 | |||
| 117 | switch (skb->data[0]) { | 128 | switch (skb->data[0]) { |
| 118 | case X25_IFACE_DATA: /* Data to be transmitted */ | 129 | case X25_IFACE_DATA: /* Data to be transmitted */ |
| 119 | skb_pull(skb, 1); | 130 | skb_pull(skb, 1); |
| 120 | if ((result = lapb_data_request(dev, skb)) != LAPB_OK) | 131 | if ((result = lapb_data_request(dev, skb)) != LAPB_OK) |
| 121 | dev_kfree_skb(skb); | 132 | dev_kfree_skb(skb); |
| 133 | spin_unlock_bh(&x25st->up_lock); | ||
| 122 | return NETDEV_TX_OK; | 134 | return NETDEV_TX_OK; |
| 123 | 135 | ||
| 124 | case X25_IFACE_CONNECT: | 136 | case X25_IFACE_CONNECT: |
| @@ -147,6 +159,7 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) · 22 unmodified lines | |||
| 147 | break; | 159 | break; |
| 148 | } | 160 | } |
| 149 | 161 | ||
| 162 | spin_unlock_bh(&x25st->up_lock); | ||
| 150 | dev_kfree_skb(skb); | 163 | dev_kfree_skb(skb); |
| 151 | return NETDEV_TX_OK; | 164 | return NETDEV_TX_OK; |
| 152 | } | 165 | } |
| @@ -164,6 +177,7 @@ static int x25_open(struct net_device *dev) · 11 unmodified lines | |||
| 164 | .data_transmit = x25_data_transmit, | 177 | .data_transmit = x25_data_transmit, |
| 165 | }; | 178 | }; |
| 166 | hdlc_device *hdlc = dev_to_hdlc(dev); | 179 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 180 | struct x25_state *x25st = state(hdlc); | ||
| 167 | struct lapb_parms_struct params; | 181 | struct lapb_parms_struct params; |
| 168 | int result; | 182 | int result; |
| 169 | 183 | ||
| @@ -190,6 +204,10 @@ static int x25_open(struct net_device *dev) · 20 unmodified lines | |||
| 190 | if (result != LAPB_OK) | 204 | if (result != LAPB_OK) |
| 191 | return -EINVAL; | 205 | return -EINVAL; |
| 192 | 206 | ||
| 207 | spin_lock_bh(&x25st->up_lock); | ||
| 208 | x25st->up = true; | ||
| 209 | spin_unlock_bh(&x25st->up_lock); | ||
| 210 | |||
| 193 | return 0; | 211 | return 0; |
| 194 | } | 212 | } |
| 195 | 213 | ||
| @@ -197,6 +215,13 @@ static int x25_open(struct net_device *dev) · 1 unmodified line | |||
| 197 | 215 | ||
| 198 | static void x25_close(struct net_device *dev) | 216 | static void x25_close(struct net_device *dev) |
| 199 | { | 217 | { |
| 218 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 219 | struct x25_state *x25st = state(hdlc); | ||
| 220 | |||
| 221 | spin_lock_bh(&x25st->up_lock); | ||
| 222 | x25st->up = false; | ||
| 223 | spin_unlock_bh(&x25st->up_lock); | ||
| 224 | |||
| 200 | lapb_unregister(dev); | 225 | lapb_unregister(dev); |
| 201 | } | 226 | } |
| 202 | 227 | ||
| @@ -205,15 +230,28 @@ static void x25_close(struct net_device *dev) · 2 unmodified lines | |||
| 205 | static int x25_rx(struct sk_buff *skb) | 230 | static int x25_rx(struct sk_buff *skb) |
| 206 | { | 231 | { |
| 207 | struct net_device *dev = skb->dev; | 232 | struct net_device *dev = skb->dev; |
| 233 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 234 | struct x25_state *x25st = state(hdlc); | ||
| 208 | 235 | ||
| 209 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 236 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
| 210 | dev->stats.rx_dropped++; | 237 | dev->stats.rx_dropped++; |
| 211 | return NET_RX_DROP; | 238 | return NET_RX_DROP; |
| 212 | } | 239 | } |
| 213 | 240 | ||
| 214 | if (lapb_data_received(dev, skb) == LAPB_OK) | 241 | spin_lock_bh(&x25st->up_lock); |
| 242 | if (!x25st->up) { | ||
| 243 | spin_unlock_bh(&x25st->up_lock); | ||
| 244 | kfree_skb(skb); | ||
| 245 | dev->stats.rx_dropped++; | ||
| 246 | return NET_RX_DROP; | ||
| 247 | } | ||
| 248 | |||
| 249 | if (lapb_data_received(dev, skb) == LAPB_OK) { | ||
| 250 | spin_unlock_bh(&x25st->up_lock); | ||
| 215 | return NET_RX_SUCCESS; | 251 | return NET_RX_SUCCESS; |
| 252 | } | ||
| 216 | 253 | ||
| 254 | spin_unlock_bh(&x25st->up_lock); | ||
| 217 | dev->stats.rx_errors++; | 255 | dev->stats.rx_errors++; |
| 218 | dev_kfree_skb_any(skb); | 256 | dev_kfree_skb_any(skb); |
| 219 | return NET_RX_DROP; | 257 | return NET_RX_DROP; |
| @@ -298,6 +336,8 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) · 78 unmodified lines | |||
| 298 | return result; | 336 | return result; |
| 299 | 337 | ||
| 300 | memcpy(&state(hdlc)->settings, &new_settings, size); | 338 | memcpy(&state(hdlc)->settings, &new_settings, size); |
| 339 | state(hdlc)->up = false; | ||
| 340 | spin_lock_init(&state(hdlc)->up_lock); | ||
| 301 | 341 | ||
| 302 | /* There's no header_ops so hard_header_len should be 0. */ | 342 | /* There's no header_ops so hard_header_len should be 0. */ |
| 303 | dev->hard_header_len = 0; | 343 | dev->hard_header_len = 0; |
| @@ -28,7 +28,6 @@ · 27 unmodified lines | |||
| 28 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); | 28 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); |
| 29 | MODULE_AUTHOR("Jouni Malinen <j@w1.fi>"); | 29 | MODULE_AUTHOR("Jouni Malinen <j@w1.fi>"); |
| 30 | MODULE_DESCRIPTION("Driver for IEEE 802.11b wireless cards based on ADMtek ADM8211"); | 30 | MODULE_DESCRIPTION("Driver for IEEE 802.11b wireless cards based on ADMtek ADM8211"); |
| 31 | MODULE_SUPPORTED_DEVICE("ADM8211"); | ||
| 32 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
| 33 | 32 | ||
| 34 | static unsigned int tx_ring_size __read_mostly = 16; | 33 | static unsigned int tx_ring_size __read_mostly = 16; |
| @@ -90,7 +90,6 @@ MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); · 89 unmodified lines | |||
| 90 | MODULE_AUTHOR("Jiri Slaby"); | 90 | MODULE_AUTHOR("Jiri Slaby"); |
| 91 | MODULE_AUTHOR("Nick Kossifidis"); | 91 | MODULE_AUTHOR("Nick Kossifidis"); |
| 92 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); | 92 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); |
| 93 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | ||
| 94 | MODULE_LICENSE("Dual BSD/GPL"); | 93 | MODULE_LICENSE("Dual BSD/GPL"); |
| 95 | 94 | ||
| 96 | static int ath5k_init(struct ieee80211_hw *hw); | 95 | static int ath5k_init(struct ieee80211_hw *hw); |
| @@ -34,7 +34,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); · 33 unmodified lines | |||
| 34 | 34 | ||
| 35 | MODULE_AUTHOR("Atheros Communications"); | 35 | MODULE_AUTHOR("Atheros Communications"); |
| 36 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | 36 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); |
| 37 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
| 38 | MODULE_LICENSE("Dual BSD/GPL"); | 37 | MODULE_LICENSE("Dual BSD/GPL"); |
| 39 | 38 | ||
| 40 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) | 39 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) |
| @@ -37,7 +37,6 @@ static char *dev_info = "ath9k"; · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | MODULE_AUTHOR("Atheros Communications"); | 38 | MODULE_AUTHOR("Atheros Communications"); |
| 39 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | 39 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); |
| 40 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
| 41 | MODULE_LICENSE("Dual BSD/GPL"); | 40 | MODULE_LICENSE("Dual BSD/GPL"); |
| 42 | 41 | ||
| 43 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | 42 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; |
| @@ -75,7 +75,6 @@ · 74 unmodified lines | |||
| 75 | MODULE_AUTHOR("Simon Kelley"); | 75 | MODULE_AUTHOR("Simon Kelley"); |
| 76 | MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); | 76 | MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); |
| 77 | MODULE_LICENSE("GPL"); | 77 | MODULE_LICENSE("GPL"); |
| 78 | MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards"); | ||
| 79 | 78 | ||
| 80 | /* The name of the firmware file to be loaded | 79 | /* The name of the firmware file to be loaded |
| 81 | over-rides any automatic selection */ | 80 | over-rides any automatic selection */ |
| @@ -57,7 +57,6 @@ · 56 unmodified lines | |||
| 57 | MODULE_AUTHOR("Simon Kelley"); | 57 | MODULE_AUTHOR("Simon Kelley"); |
| 58 | MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); | 58 | MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); |
| 59 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
| 60 | MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards"); | ||
| 61 | 60 | ||
| 62 | /*====================================================================*/ | 61 | /*====================================================================*/ |
| 63 | 62 | ||
| @@ -16,7 +16,6 @@ · 15 unmodified lines | |||
| 16 | MODULE_AUTHOR("Simon Kelley"); | 16 | MODULE_AUTHOR("Simon Kelley"); |
| 17 | MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); | 17 | MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); |
| 18 | MODULE_LICENSE("GPL"); | 18 | MODULE_LICENSE("GPL"); |
| 19 | MODULE_SUPPORTED_DEVICE("Atmel at76c506 PCI wireless cards"); | ||
| 20 | 19 | ||
| 21 | static const struct pci_device_id card_ids[] = { | 20 | static const struct pci_device_id card_ids[] = { |
| 22 | { 0x1114, 0x0506, PCI_ANY_ID, PCI_ANY_ID }, | 21 | { 0x1114, 0x0506, PCI_ANY_ID, PCI_ANY_ID }, |
| @@ -87,7 +87,6 @@ static int n_adapters_found; · 86 unmodified lines | |||
| 87 | 87 | ||
| 88 | MODULE_AUTHOR("Broadcom Corporation"); | 88 | MODULE_AUTHOR("Broadcom Corporation"); |
| 89 | MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); | 89 | MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); |
| 90 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); | ||
| 91 | MODULE_LICENSE("Dual BSD/GPL"); | 90 | MODULE_LICENSE("Dual BSD/GPL"); |
| 92 | /* This needs to be adjusted when brcms_firmwares changes */ | 91 | /* This needs to be adjusted when brcms_firmwares changes */ |
| 93 | MODULE_FIRMWARE("brcm/bcm43xx-0.fw"); | 92 | MODULE_FIRMWARE("brcm/bcm43xx-0.fw"); |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | MODULE_AUTHOR("Broadcom Corporation"); | 13 | MODULE_AUTHOR("Broadcom Corporation"); |
| 14 | MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities."); | 14 | MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities."); |
| 15 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); | ||
| 16 | MODULE_LICENSE("Dual BSD/GPL"); | 15 | MODULE_LICENSE("Dual BSD/GPL"); |
| 17 | 16 | ||
| 18 | struct sk_buff *brcmu_pkt_buf_get_skb(uint len) | 17 | struct sk_buff *brcmu_pkt_buf_get_skb(uint len) |
| @@ -251,7 +251,6 @@ MODULE_AUTHOR("Benjamin Reed"); · 250 unmodified lines | |||
| 251 | MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards. " | 251 | MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards. " |
| 252 | "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs."); | 252 | "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs."); |
| 253 | MODULE_LICENSE("Dual BSD/GPL"); | 253 | MODULE_LICENSE("Dual BSD/GPL"); |
| 254 | MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350"); | ||
| 255 | module_param_hw_array(io, int, ioport, NULL, 0); | 254 | module_param_hw_array(io, int, ioport, NULL, 0); |
| 256 | module_param_hw_array(irq, int, irq, NULL, 0); | 255 | module_param_hw_array(irq, int, irq, NULL, 0); |
| 257 | module_param_array(rates, int, NULL, 0); | 256 | module_param_array(rates, int, NULL, 0); |
| @@ -47,7 +47,6 @@ MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet " · 46 unmodified lines | |||
| 47 | "cards. This is the module that links the PCMCIA card " | 47 | "cards. This is the module that links the PCMCIA card " |
| 48 | "with the airo module."); | 48 | "with the airo module."); |
| 49 | MODULE_LICENSE("Dual BSD/GPL"); | 49 | MODULE_LICENSE("Dual BSD/GPL"); |
| 50 | MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards"); | ||
| 51 | 50 | ||
| 52 | /*====================================================================*/ | 51 | /*====================================================================*/ |
| 53 | 52 | ||
| @@ -26,7 +26,6 @@ static char *dev_info = "hostap_cs"; · 25 unmodified lines | |||
| 26 | MODULE_AUTHOR("Jouni Malinen"); | 26 | MODULE_AUTHOR("Jouni Malinen"); |
| 27 | MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " | 27 | MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " |
| 28 | "cards (PC Card)."); | 28 | "cards (PC Card)."); |
| 29 | MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)"); | ||
| 30 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
| 31 | 30 | ||
| 32 | 31 | ||
| @@ -27,7 +27,6 @@ static char *dev_info = "hostap_pci"; · 26 unmodified lines | |||
| 27 | MODULE_AUTHOR("Jouni Malinen"); | 27 | MODULE_AUTHOR("Jouni Malinen"); |
| 28 | MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN " | 28 | MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN " |
| 29 | "PCI cards."); | 29 | "PCI cards."); |
| 30 | MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards"); | ||
| 31 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
| 32 | 31 | ||
| 33 | 32 | ||
| @@ -30,7 +30,6 @@ static char *dev_info = "hostap_plx"; · 29 unmodified lines | |||
| 30 | MODULE_AUTHOR("Jouni Malinen"); | 30 | MODULE_AUTHOR("Jouni Malinen"); |
| 31 | MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " | 31 | MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " |
| 32 | "cards (PLX)."); | 32 | "cards (PLX)."); |
| 33 | MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)"); | ||
| 34 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
| 35 | 34 | ||
| 36 | 35 | ||
| @@ -1821,7 +1821,6 @@ static const struct pci_device_id rt2400pci_device_table[] = { · 1820 unmodified lines | |||
| 1821 | MODULE_AUTHOR(DRV_PROJECT); | 1821 | MODULE_AUTHOR(DRV_PROJECT); |
| 1822 | MODULE_VERSION(DRV_VERSION); | 1822 | MODULE_VERSION(DRV_VERSION); |
| 1823 | MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver."); | 1823 | MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver."); |
| 1824 | MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards"); | ||
| 1825 | MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); | 1824 | MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); |
| 1826 | MODULE_LICENSE("GPL"); | 1825 | MODULE_LICENSE("GPL"); |
| 1827 | 1826 | ||
| @@ -2119,7 +2119,6 @@ static const struct pci_device_id rt2500pci_device_table[] = { · 2118 unmodified lines | |||
| 2119 | MODULE_AUTHOR(DRV_PROJECT); | 2119 | MODULE_AUTHOR(DRV_PROJECT); |
| 2120 | MODULE_VERSION(DRV_VERSION); | 2120 | MODULE_VERSION(DRV_VERSION); |
| 2121 | MODULE_DESCRIPTION("Ralink RT2500 PCI & PCMCIA Wireless LAN driver."); | 2121 | MODULE_DESCRIPTION("Ralink RT2500 PCI & PCMCIA Wireless LAN driver."); |
| 2122 | MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards"); | ||
| 2123 | MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); | 2122 | MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); |
| 2124 | MODULE_LICENSE("GPL"); | 2123 | MODULE_LICENSE("GPL"); |
| 2125 | 2124 | ||
| @@ -1956,7 +1956,6 @@ static const struct usb_device_id rt2500usb_device_table[] = { · 1955 unmodified lines | |||
| 1956 | MODULE_AUTHOR(DRV_PROJECT); | 1956 | MODULE_AUTHOR(DRV_PROJECT); |
| 1957 | MODULE_VERSION(DRV_VERSION); | 1957 | MODULE_VERSION(DRV_VERSION); |
| 1958 | MODULE_DESCRIPTION("Ralink RT2500 USB Wireless LAN driver."); | 1958 | MODULE_DESCRIPTION("Ralink RT2500 USB Wireless LAN driver."); |
| 1959 | MODULE_SUPPORTED_DEVICE("Ralink RT2570 USB chipset based cards"); | ||
| 1960 | MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); | 1959 | MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); |
| 1961 | MODULE_LICENSE("GPL"); | 1960 | MODULE_LICENSE("GPL"); |
| 1962 | 1961 | ||
| @@ -439,7 +439,6 @@ static const struct pci_device_id rt2800pci_device_table[] = { · 438 unmodified lines | |||
| 439 | MODULE_AUTHOR(DRV_PROJECT); | 439 | MODULE_AUTHOR(DRV_PROJECT); |
| 440 | MODULE_VERSION(DRV_VERSION); | 440 | MODULE_VERSION(DRV_VERSION); |
| 441 | MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver."); | 441 | MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver."); |
| 442 | MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards"); | ||
| 443 | MODULE_FIRMWARE(FIRMWARE_RT2860); | 442 | MODULE_FIRMWARE(FIRMWARE_RT2860); |
| 444 | MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); | 443 | MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); |
| 445 | MODULE_LICENSE("GPL"); | 444 | MODULE_LICENSE("GPL"); |
| @@ -1248,7 +1248,6 @@ static const struct usb_device_id rt2800usb_device_table[] = { · 1247 unmodified lines | |||
| 1248 | MODULE_AUTHOR(DRV_PROJECT); | 1248 | MODULE_AUTHOR(DRV_PROJECT); |
| 1249 | MODULE_VERSION(DRV_VERSION); | 1249 | MODULE_VERSION(DRV_VERSION); |
| 1250 | MODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver."); | 1250 | MODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver."); |
| 1251 | MODULE_SUPPORTED_DEVICE("Ralink RT2870 USB chipset based cards"); | ||
| 1252 | MODULE_DEVICE_TABLE(usb, rt2800usb_device_table); | 1251 | MODULE_DEVICE_TABLE(usb, rt2800usb_device_table); |
| 1253 | MODULE_FIRMWARE(FIRMWARE_RT2870); | 1252 | MODULE_FIRMWARE(FIRMWARE_RT2870); |
| 1254 | MODULE_LICENSE("GPL"); | 1253 | MODULE_LICENSE("GPL"); |
| @@ -2993,8 +2993,6 @@ static const struct pci_device_id rt61pci_device_table[] = { · 2992 unmodified lines | |||
| 2993 | MODULE_AUTHOR(DRV_PROJECT); | 2993 | MODULE_AUTHOR(DRV_PROJECT); |
| 2994 | MODULE_VERSION(DRV_VERSION); | 2994 | MODULE_VERSION(DRV_VERSION); |
| 2995 | MODULE_DESCRIPTION("Ralink RT61 PCI & PCMCIA Wireless LAN driver."); | 2995 | MODULE_DESCRIPTION("Ralink RT61 PCI & PCMCIA Wireless LAN driver."); |
| 2996 | MODULE_SUPPORTED_DEVICE("Ralink RT2561, RT2561s & RT2661 " | ||
| 2997 | "PCI & PCMCIA chipset based cards"); | ||
| 2998 | MODULE_DEVICE_TABLE(pci, rt61pci_device_table); | 2996 | MODULE_DEVICE_TABLE(pci, rt61pci_device_table); |
| 2999 | MODULE_FIRMWARE(FIRMWARE_RT2561); | 2997 | MODULE_FIRMWARE(FIRMWARE_RT2561); |
| 3000 | MODULE_FIRMWARE(FIRMWARE_RT2561s); | 2998 | MODULE_FIRMWARE(FIRMWARE_RT2561s); |
| @@ -2513,7 +2513,6 @@ static const struct usb_device_id rt73usb_device_table[] = { · 2512 unmodified lines | |||
| 2513 | MODULE_AUTHOR(DRV_PROJECT); | 2513 | MODULE_AUTHOR(DRV_PROJECT); |
| 2514 | MODULE_VERSION(DRV_VERSION); | 2514 | MODULE_VERSION(DRV_VERSION); |
| 2515 | MODULE_DESCRIPTION("Ralink RT73 USB Wireless LAN driver."); | 2515 | MODULE_DESCRIPTION("Ralink RT73 USB Wireless LAN driver."); |
| 2516 | MODULE_SUPPORTED_DEVICE("Ralink RT2571W & RT2671 USB chipset based cards"); | ||
| 2517 | MODULE_DEVICE_TABLE(usb, rt73usb_device_table); | 2516 | MODULE_DEVICE_TABLE(usb, rt73usb_device_table); |
| 2518 | MODULE_FIRMWARE(FIRMWARE_RT2571); | 2517 | MODULE_FIRMWARE(FIRMWARE_RT2571); |
| 2519 | MODULE_LICENSE("GPL"); | 2518 | MODULE_LICENSE("GPL"); |
| @@ -441,6 +441,5 @@ module_init(rsi_91x_hal_module_init); · 440 unmodified lines | |||
| 441 | module_exit(rsi_91x_hal_module_exit); | 441 | module_exit(rsi_91x_hal_module_exit); |
| 442 | MODULE_AUTHOR("Redpine Signals Inc"); | 442 | MODULE_AUTHOR("Redpine Signals Inc"); |
| 443 | MODULE_DESCRIPTION("Station driver for RSI 91x devices"); | 443 | MODULE_DESCRIPTION("Station driver for RSI 91x devices"); |
| 444 | MODULE_SUPPORTED_DEVICE("RSI-91x"); | ||
| 445 | MODULE_VERSION("0.1"); | 444 | MODULE_VERSION("0.1"); |
| 446 | MODULE_LICENSE("Dual BSD/GPL"); | 445 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -1571,7 +1571,6 @@ module_exit(rsi_module_exit); · 1570 unmodified lines | |||
| 1571 | 1571 | ||
| 1572 | MODULE_AUTHOR("Redpine Signals Inc"); | 1572 | MODULE_AUTHOR("Redpine Signals Inc"); |
| 1573 | MODULE_DESCRIPTION("Common SDIO layer for RSI drivers"); | 1573 | MODULE_DESCRIPTION("Common SDIO layer for RSI drivers"); |
| 1574 | MODULE_SUPPORTED_DEVICE("RSI-91x"); | ||
| 1575 | MODULE_DEVICE_TABLE(sdio, rsi_dev_table); | 1574 | MODULE_DEVICE_TABLE(sdio, rsi_dev_table); |
| 1576 | MODULE_FIRMWARE(FIRMWARE_RSI9113); | 1575 | MODULE_FIRMWARE(FIRMWARE_RSI9113); |
| 1577 | MODULE_VERSION("0.1"); | 1576 | MODULE_VERSION("0.1"); |
| @@ -928,7 +928,6 @@ module_usb_driver(rsi_driver); · 927 unmodified lines | |||
| 928 | 928 | ||
| 929 | MODULE_AUTHOR("Redpine Signals Inc"); | 929 | MODULE_AUTHOR("Redpine Signals Inc"); |
| 930 | MODULE_DESCRIPTION("Common USB layer for RSI drivers"); | 930 | MODULE_DESCRIPTION("Common USB layer for RSI drivers"); |
| 931 | MODULE_SUPPORTED_DEVICE("RSI-91x"); | ||
| 932 | MODULE_DEVICE_TABLE(usb, rsi_dev_table); | 931 | MODULE_DEVICE_TABLE(usb, rsi_dev_table); |
| 933 | MODULE_FIRMWARE(FIRMWARE_RSI9113); | 932 | MODULE_FIRMWARE(FIRMWARE_RSI9113); |
| 934 | MODULE_VERSION("0.1"); | 933 | MODULE_VERSION("0.1"); |
| @@ -380,6 +380,7 @@ bool nvme_cancel_request(struct request *req, void *data, bool reserved) · 379 unmodified lines | |||
| 380 | return true; | 380 | return true; |
| 381 | 381 | ||
| 382 | nvme_req(req)->status = NVME_SC_HOST_ABORTED_CMD; | 382 | nvme_req(req)->status = NVME_SC_HOST_ABORTED_CMD; |
| 383 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; | ||
| 383 | blk_mq_complete_request(req); | 384 | blk_mq_complete_request(req); |
| 384 | return true; | 385 | return true; |
| 385 | } | 386 | } |
| @@ -1225,28 +1226,12 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) · 839 unmodified lines | |||
| 1225 | queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); | 1226 | queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); |
| 1226 | } | 1227 | } |
| 1227 | 1228 | ||
| 1228 | static int nvme_keep_alive(struct nvme_ctrl *ctrl) | ||
| 1229 | { | ||
| 1230 | struct request *rq; | ||
| 1231 | |||
| 1232 | rq = nvme_alloc_request(ctrl->admin_q, &ctrl->ka_cmd, | ||
| 1233 | BLK_MQ_REQ_RESERVED); | ||
| 1234 | if (IS_ERR(rq)) | ||
| 1235 | return PTR_ERR(rq); | ||
| 1236 | |||
| 1237 | rq->timeout = ctrl->kato * HZ; | ||
| 1238 | rq->end_io_data = ctrl; | ||
| 1239 | |||
| 1240 | blk_execute_rq_nowait(NULL, rq, 0, nvme_keep_alive_end_io); | ||
| 1241 | |||
| 1242 | return 0; | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | static void nvme_keep_alive_work(struct work_struct *work) | 1229 | static void nvme_keep_alive_work(struct work_struct *work) |
| 1246 | { | 1230 | { |
| 1247 | struct nvme_ctrl *ctrl = container_of(to_delayed_work(work), | 1231 | struct nvme_ctrl *ctrl = container_of(to_delayed_work(work), |
| 1248 | struct nvme_ctrl, ka_work); | 1232 | struct nvme_ctrl, ka_work); |
| 1249 | bool comp_seen = ctrl->comp_seen; | 1233 | bool comp_seen = ctrl->comp_seen; |
| 1234 | struct request *rq; | ||
| 1250 | 1235 | ||
| 1251 | if ((ctrl->ctratt & NVME_CTRL_ATTR_TBKAS) && comp_seen) { | 1236 | if ((ctrl->ctratt & NVME_CTRL_ATTR_TBKAS) && comp_seen) { |
| 1252 | dev_dbg(ctrl->device, | 1237 | dev_dbg(ctrl->device, |
| @@ -1256,12 +1241,18 @@ static void nvme_keep_alive_work(struct work_struct *work) · 3 unmodified lines | |||
| 1256 | return; | 1241 | return; |
| 1257 | } | 1242 | } |
| 1258 | 1243 | ||
| 1259 | if (nvme_keep_alive(ctrl)) { | 1244 | rq = nvme_alloc_request(ctrl->admin_q, &ctrl->ka_cmd, |
| 1245 | BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT); | ||
| 1246 | if (IS_ERR(rq)) { | ||
| 1260 | /* allocation failure, reset the controller */ | 1247 | /* allocation failure, reset the controller */ |
| 1261 | dev_err(ctrl->device, "keep-alive failed\n"); | 1248 | dev_err(ctrl->device, "keep-alive failed: %ld\n", PTR_ERR(rq)); |
| 1262 | nvme_reset_ctrl(ctrl); | 1249 | nvme_reset_ctrl(ctrl); |
| 1263 | return; | 1250 | return; |
| 1264 | } | 1251 | } |
| 1252 | |||
| 1253 | rq->timeout = ctrl->kato * HZ; | ||
| 1254 | rq->end_io_data = ctrl; | ||
| 1255 | blk_execute_rq_nowait(NULL, rq, 0, nvme_keep_alive_end_io); | ||
| 1265 | } | 1256 | } |
| 1266 | 1257 | ||
| 1267 | static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) | 1258 | static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) |
| @@ -1440,7 +1431,7 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, · 172 unmodified lines | |||
| 1440 | goto out_free_id; | 1431 | goto out_free_id; |
| 1441 | } | 1432 | } |
| 1442 | 1433 | ||
| 1443 | error = -ENODEV; | 1434 | error = NVME_SC_INVALID_NS | NVME_SC_DNR; |
| 1444 | if ((*id)->ncap == 0) /* namespace not allocated or attached */ | 1435 | if ((*id)->ncap == 0) /* namespace not allocated or attached */ |
| 1445 | goto out_free_id; | 1436 | goto out_free_id; |
| 1446 | 1437 | ||
| @@ -1963,30 +1954,18 @@ static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns) · 516 unmodified lines | |||
| 1963 | blk_queue_max_write_zeroes_sectors(queue, UINT_MAX); | 1954 | blk_queue_max_write_zeroes_sectors(queue, UINT_MAX); |
| 1964 | } | 1955 | } |
| 1965 | 1956 | ||
| 1966 | static void nvme_config_write_zeroes(struct gendisk *disk, struct nvme_ns *ns) | 1957 | /* |
| 1958 | * Even though NVMe spec explicitly states that MDTS is not applicable to the | ||
| 1959 | * write-zeroes, we are cautious and limit the size to the controllers | ||
| 1960 | * max_hw_sectors value, which is based on the MDTS field and possibly other | ||
| 1961 | * limiting factors. | ||
| 1962 | */ | ||
| 1963 | static void nvme_config_write_zeroes(struct request_queue *q, | ||
| 1964 | struct nvme_ctrl *ctrl) | ||
| 1967 | { | 1965 | { |
| 1968 | u64 max_blocks; | 1966 | if ((ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) && |
| 1969 | 1967 | !(ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) | |
| 1970 | if (!(ns->ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) || | 1968 | blk_queue_max_write_zeroes_sectors(q, ctrl->max_hw_sectors); |
| 1971 | (ns->ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) | ||
| 1972 | return; | ||
| 1973 | /* | ||
| 1974 | * Even though NVMe spec explicitly states that MDTS is not | ||
| 1975 | * applicable to the write-zeroes:- "The restriction does not apply to | ||
| 1976 | * commands that do not transfer data between the host and the | ||
| 1977 | * controller (e.g., Write Uncorrectable ro Write Zeroes command).". | ||
| 1978 | * In order to be more cautious use controller's max_hw_sectors value | ||
| 1979 | * to configure the maximum sectors for the write-zeroes which is | ||
| 1980 | * configured based on the controller's MDTS field in the | ||
| 1981 | * nvme_init_identify() if available. | ||
| 1982 | */ | ||
| 1983 | if (ns->ctrl->max_hw_sectors == UINT_MAX) | ||
| 1984 | max_blocks = (u64)USHRT_MAX + 1; | ||
| 1985 | else | ||
| 1986 | max_blocks = ns->ctrl->max_hw_sectors + 1; | ||
| 1987 | |||
| 1988 | blk_queue_max_write_zeroes_sectors(disk->queue, | ||
| 1989 | nvme_lba_to_sect(ns, max_blocks)); | ||
| 1990 | } | 1969 | } |
| 1991 | 1970 | ||
| 1992 | static bool nvme_ns_ids_valid(struct nvme_ns_ids *ids) | 1971 | static bool nvme_ns_ids_valid(struct nvme_ns_ids *ids) |
| @@ -2158,7 +2137,7 @@ static void nvme_update_disk_info(struct gendisk *disk, · 165 unmodified lines | |||
| 2158 | set_capacity_and_notify(disk, capacity); | 2137 | set_capacity_and_notify(disk, capacity); |
| 2159 | 2138 | ||
| 2160 | nvme_config_discard(disk, ns); | 2139 | nvme_config_discard(disk, ns); |
| 2161 | nvme_config_write_zeroes(disk, ns); | 2140 | nvme_config_write_zeroes(disk->queue, ns->ctrl); |
| 2162 | 2141 | ||
| 2163 | set_disk_ro(disk, (id->nsattr & NVME_NS_ATTR_RO) || | 2142 | set_disk_ro(disk, (id->nsattr & NVME_NS_ATTR_RO) || |
| 2164 | test_bit(NVME_NS_FORCE_RO, &ns->flags)); | 2143 | test_bit(NVME_NS_FORCE_RO, &ns->flags)); |
| @@ -4038,7 +4017,7 @@ static void nvme_ns_remove_by_nsid(struct nvme_ctrl *ctrl, u32 nsid) · 1873 unmodified lines | |||
| 4038 | static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids) | 4017 | static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids) |
| 4039 | { | 4018 | { |
| 4040 | struct nvme_id_ns *id; | 4019 | struct nvme_id_ns *id; |
| 4041 | int ret = -ENODEV; | 4020 | int ret = NVME_SC_INVALID_NS | NVME_SC_DNR; |
| 4042 | 4021 | ||
| 4043 | if (test_bit(NVME_NS_DEAD, &ns->flags)) | 4022 | if (test_bit(NVME_NS_DEAD, &ns->flags)) |
| 4044 | goto out; | 4023 | goto out; |
| @@ -4047,7 +4026,7 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids) · 2 unmodified lines | |||
| 4047 | if (ret) | 4026 | if (ret) |
| 4048 | goto out; | 4027 | goto out; |
| 4049 | 4028 | ||
| 4050 | ret = -ENODEV; | 4029 | ret = NVME_SC_INVALID_NS | NVME_SC_DNR; |
| 4051 | if (!nvme_ns_ids_equal(&ns->head->ids, ids)) { | 4030 | if (!nvme_ns_ids_equal(&ns->head->ids, ids)) { |
| 4052 | dev_err(ns->ctrl->device, | 4031 | dev_err(ns->ctrl->device, |
| 4053 | "identifiers changed for nsid %d\n", ns->head->ns_id); | 4032 | "identifiers changed for nsid %d\n", ns->head->ns_id); |
| @@ -4065,7 +4044,7 @@ out: · 11 unmodified lines | |||
| 4065 | * | 4044 | * |
| 4066 | * TODO: we should probably schedule a delayed retry here. | 4045 | * TODO: we should probably schedule a delayed retry here. |
| 4067 | */ | 4046 | */ |
| 4068 | if (ret && ret != -ENOMEM && !(ret > 0 && !(ret & NVME_SC_DNR))) | 4047 | if (ret > 0 && (ret & NVME_SC_DNR)) |
| 4069 | nvme_ns_remove(ns); | 4048 | nvme_ns_remove(ns); |
| 4070 | } | 4049 | } |
| 4071 | 4050 | ||
| @@ -4095,6 +4074,12 @@ static void nvme_validate_or_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 23 unmodified lines | |||
| 4095 | nsid); | 4074 | nsid); |
| 4096 | break; | 4075 | break; |
| 4097 | } | 4076 | } |
| 4077 | if (!nvme_multi_css(ctrl)) { | ||
| 4078 | dev_warn(ctrl->device, | ||
| 4079 | "command set not reported for nsid: %d\n", | ||
| 4080 | nsid); | ||
| 4081 | break; | ||
| 4082 | } | ||
| 4098 | nvme_alloc_ns(ctrl, nsid, &ids); | 4083 | nvme_alloc_ns(ctrl, nsid, &ids); |
| 4099 | break; | 4084 | break; |
| 4100 | default: | 4085 | default: |
| @@ -18,6 +18,13 @@ · 17 unmodified lines | |||
| 18 | /* default is -1: the fail fast mechanism is disabled */ | 18 | /* default is -1: the fail fast mechanism is disabled */ |
| 19 | #define NVMF_DEF_FAIL_FAST_TMO -1 | 19 | #define NVMF_DEF_FAIL_FAST_TMO -1 |
| 20 | 20 | ||
| 21 | /* | ||
| 22 | * Reserved one command for internal usage. This command is used for sending | ||
| 23 | * the connect command, as well as for the keep alive command on the admin | ||
| 24 | * queue once live. | ||
| 25 | */ | ||
| 26 | #define NVMF_RESERVED_TAGS 1 | ||
| 27 | |||
| 21 | /* | 28 | /* |
| 22 | * Define a host as seen by the target. We allocate one at boot, but also | 29 | * Define a host as seen by the target. We allocate one at boot, but also |
| 23 | * allow the override it when creating controllers. This is both to provide | 30 | * allow the override it when creating controllers. This is both to provide |
| @@ -1956,7 +1956,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) · 1955 unmodified lines | |||
| 1956 | sizeof(op->rsp_iu), DMA_FROM_DEVICE); | 1956 | sizeof(op->rsp_iu), DMA_FROM_DEVICE); |
| 1957 | 1957 | ||
| 1958 | if (opstate == FCPOP_STATE_ABORTED) | 1958 | if (opstate == FCPOP_STATE_ABORTED) |
| 1959 | status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); | 1959 | status = cpu_to_le16(NVME_SC_HOST_ABORTED_CMD << 1); |
| 1960 | else if (freq->status) { | 1960 | else if (freq->status) { |
| 1961 | status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); | 1961 | status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); |
| 1962 | dev_info(ctrl->ctrl.device, | 1962 | dev_info(ctrl->ctrl.device, |
| @@ -2055,7 +2055,7 @@ done: · 92 unmodified lines | |||
| 2055 | nvme_fc_complete_rq(rq); | 2055 | nvme_fc_complete_rq(rq); |
| 2056 | 2056 | ||
| 2057 | check_error: | 2057 | check_error: |
| 2058 | if (terminate_assoc) | 2058 | if (terminate_assoc && ctrl->ctrl.state != NVME_CTRL_RESETTING) |
| 2059 | queue_work(nvme_reset_wq, &ctrl->ioerr_work); | 2059 | queue_work(nvme_reset_wq, &ctrl->ioerr_work); |
| 2060 | } | 2060 | } |
| 2061 | 2061 | ||
| @@ -2443,6 +2443,7 @@ nvme_fc_terminate_exchange(struct request *req, void *data, bool reserved) · 381 unmodified lines | |||
| 2443 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); | 2443 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); |
| 2444 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(req); | 2444 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(req); |
| 2445 | 2445 | ||
| 2446 | op->nreq.flags |= NVME_REQ_CANCELLED; | ||
| 2446 | __nvme_fc_abort_op(ctrl, op); | 2447 | __nvme_fc_abort_op(ctrl, op); |
| 2447 | return true; | 2448 | return true; |
| 2448 | } | 2449 | } |
| @@ -2862,7 +2863,7 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl) · 413 unmodified lines | |||
| 2862 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); | 2863 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); |
| 2863 | ctrl->tag_set.ops = &nvme_fc_mq_ops; | 2864 | ctrl->tag_set.ops = &nvme_fc_mq_ops; |
| 2864 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; | 2865 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; |
| 2865 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ | 2866 | ctrl->tag_set.reserved_tags = NVMF_RESERVED_TAGS; |
| 2866 | ctrl->tag_set.numa_node = ctrl->ctrl.numa_node; | 2867 | ctrl->tag_set.numa_node = ctrl->ctrl.numa_node; |
| 2867 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; | 2868 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
| 2868 | ctrl->tag_set.cmd_size = | 2869 | ctrl->tag_set.cmd_size = |
| @@ -3484,7 +3485,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · 615 unmodified lines | |||
| 3484 | memset(&ctrl->admin_tag_set, 0, sizeof(ctrl->admin_tag_set)); | 3485 | memset(&ctrl->admin_tag_set, 0, sizeof(ctrl->admin_tag_set)); |
| 3485 | ctrl->admin_tag_set.ops = &nvme_fc_admin_mq_ops; | 3486 | ctrl->admin_tag_set.ops = &nvme_fc_admin_mq_ops; |
| 3486 | ctrl->admin_tag_set.queue_depth = NVME_AQ_MQ_TAG_DEPTH; | 3487 | ctrl->admin_tag_set.queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 3487 | ctrl->admin_tag_set.reserved_tags = 2; /* fabric connect + Keep-Alive */ | 3488 | ctrl->admin_tag_set.reserved_tags = NVMF_RESERVED_TAGS; |
| 3488 | ctrl->admin_tag_set.numa_node = ctrl->ctrl.numa_node; | 3489 | ctrl->admin_tag_set.numa_node = ctrl->ctrl.numa_node; |
| 3489 | ctrl->admin_tag_set.cmd_size = | 3490 | ctrl->admin_tag_set.cmd_size = |
| 3490 | struct_size((struct nvme_fcp_op_w_sgl *)NULL, priv, | 3491 | struct_size((struct nvme_fcp_op_w_sgl *)NULL, priv, |
| @@ -3246,6 +3246,7 @@ static const struct pci_device_id nvme_id_table[] = { · 3245 unmodified lines | |||
| 3246 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, | 3246 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, |
| 3247 | { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ | 3247 | { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ |
| 3248 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | | 3248 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
| 3249 | NVME_QUIRK_DISABLE_WRITE_ZEROES| | ||
| 3249 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 3250 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3250 | { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ | 3251 | { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ |
| 3251 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 3252 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| @@ -736,8 +736,11 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl *ctrl) · 735 unmodified lines | |||
| 736 | return ret; | 736 | return ret; |
| 737 | 737 | ||
| 738 | ctrl->ctrl.queue_count = nr_io_queues + 1; | 738 | ctrl->ctrl.queue_count = nr_io_queues + 1; |
| 739 | if (ctrl->ctrl.queue_count < 2) | 739 | if (ctrl->ctrl.queue_count < 2) { |
| 740 | return 0; | 740 | dev_err(ctrl->ctrl.device, |
| 741 | "unable to set any I/O queues\n"); | ||
| 742 | return -ENOMEM; | ||
| 743 | } | ||
| 741 | 744 | ||
| 742 | dev_info(ctrl->ctrl.device, | 745 | dev_info(ctrl->ctrl.device, |
| 743 | "creating %d I/O queues.\n", nr_io_queues); | 746 | "creating %d I/O queues.\n", nr_io_queues); |
| @@ -798,7 +801,7 @@ static struct blk_mq_tag_set *nvme_rdma_alloc_tagset(struct nvme_ctrl *nctrl, · 54 unmodified lines | |||
| 798 | memset(set, 0, sizeof(*set)); | 801 | memset(set, 0, sizeof(*set)); |
| 799 | set->ops = &nvme_rdma_admin_mq_ops; | 802 | set->ops = &nvme_rdma_admin_mq_ops; |
| 800 | set->queue_depth = NVME_AQ_MQ_TAG_DEPTH; | 803 | set->queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 801 | set->reserved_tags = 2; /* connect + keep-alive */ | 804 | set->reserved_tags = NVMF_RESERVED_TAGS; |
| 802 | set->numa_node = nctrl->numa_node; | 805 | set->numa_node = nctrl->numa_node; |
| 803 | set->cmd_size = sizeof(struct nvme_rdma_request) + | 806 | set->cmd_size = sizeof(struct nvme_rdma_request) + |
| 804 | NVME_RDMA_DATA_SGL_SIZE; | 807 | NVME_RDMA_DATA_SGL_SIZE; |
| @@ -811,7 +814,7 @@ static struct blk_mq_tag_set *nvme_rdma_alloc_tagset(struct nvme_ctrl *nctrl, · 6 unmodified lines | |||
| 811 | memset(set, 0, sizeof(*set)); | 814 | memset(set, 0, sizeof(*set)); |
| 812 | set->ops = &nvme_rdma_mq_ops; | 815 | set->ops = &nvme_rdma_mq_ops; |
| 813 | set->queue_depth = nctrl->sqsize + 1; | 816 | set->queue_depth = nctrl->sqsize + 1; |
| 814 | set->reserved_tags = 1; /* fabric connect */ | 817 | set->reserved_tags = NVMF_RESERVED_TAGS; |
| 815 | set->numa_node = nctrl->numa_node; | 818 | set->numa_node = nctrl->numa_node; |
| 816 | set->flags = BLK_MQ_F_SHOULD_MERGE; | 819 | set->flags = BLK_MQ_F_SHOULD_MERGE; |
| 817 | set->cmd_size = sizeof(struct nvme_rdma_request) + | 820 | set->cmd_size = sizeof(struct nvme_rdma_request) + |
| @@ -287,7 +287,7 @@ static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req, · 286 unmodified lines | |||
| 287 | * directly, otherwise queue io_work. Also, only do that if we | 287 | * directly, otherwise queue io_work. Also, only do that if we |
| 288 | * are on the same cpu, so we don't introduce contention. | 288 | * are on the same cpu, so we don't introduce contention. |
| 289 | */ | 289 | */ |
| 290 | if (queue->io_cpu == __smp_processor_id() && | 290 | if (queue->io_cpu == raw_smp_processor_id() && |
| 291 | sync && empty && mutex_trylock(&queue->send_mutex)) { | 291 | sync && empty && mutex_trylock(&queue->send_mutex)) { |
| 292 | queue->more_requests = !last; | 292 | queue->more_requests = !last; |
| 293 | nvme_tcp_send_all(queue); | 293 | nvme_tcp_send_all(queue); |
| @@ -568,6 +568,13 @@ static int nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req, · 274 unmodified lines | |||
| 568 | req->pdu_len = le32_to_cpu(pdu->r2t_length); | 568 | req->pdu_len = le32_to_cpu(pdu->r2t_length); |
| 569 | req->pdu_sent = 0; | 569 | req->pdu_sent = 0; |
| 570 | 570 | ||
| 571 | if (unlikely(!req->pdu_len)) { | ||
| 572 | dev_err(queue->ctrl->ctrl.device, | ||
| 573 | "req %d r2t len is %u, probably a bug...\n", | ||
| 574 | rq->tag, req->pdu_len); | ||
| 575 | return -EPROTO; | ||
| 576 | } | ||
| 577 | |||
| 571 | if (unlikely(req->data_sent + req->pdu_len > req->data_len)) { | 578 | if (unlikely(req->data_sent + req->pdu_len > req->data_len)) { |
| 572 | dev_err(queue->ctrl->ctrl.device, | 579 | dev_err(queue->ctrl->ctrl.device, |
| 573 | "req %d r2t len %u exceeded data len %u (%zu sent)\n", | 580 | "req %d r2t len %u exceeded data len %u (%zu sent)\n", |
| @@ -1575,7 +1582,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl, · 1001 unmodified lines | |||
| 1575 | memset(set, 0, sizeof(*set)); | 1582 | memset(set, 0, sizeof(*set)); |
| 1576 | set->ops = &nvme_tcp_admin_mq_ops; | 1583 | set->ops = &nvme_tcp_admin_mq_ops; |
| 1577 | set->queue_depth = NVME_AQ_MQ_TAG_DEPTH; | 1584 | set->queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 1578 | set->reserved_tags = 2; /* connect + keep-alive */ | 1585 | set->reserved_tags = NVMF_RESERVED_TAGS; |
| 1579 | set->numa_node = nctrl->numa_node; | 1586 | set->numa_node = nctrl->numa_node; |
| 1580 | set->flags = BLK_MQ_F_BLOCKING; | 1587 | set->flags = BLK_MQ_F_BLOCKING; |
| 1581 | set->cmd_size = sizeof(struct nvme_tcp_request); | 1588 | set->cmd_size = sizeof(struct nvme_tcp_request); |
| @@ -1587,7 +1594,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl, · 5 unmodified lines | |||
| 1587 | memset(set, 0, sizeof(*set)); | 1594 | memset(set, 0, sizeof(*set)); |
| 1588 | set->ops = &nvme_tcp_mq_ops; | 1595 | set->ops = &nvme_tcp_mq_ops; |
| 1589 | set->queue_depth = nctrl->sqsize + 1; | 1596 | set->queue_depth = nctrl->sqsize + 1; |
| 1590 | set->reserved_tags = 1; /* fabric connect */ | 1597 | set->reserved_tags = NVMF_RESERVED_TAGS; |
| 1591 | set->numa_node = nctrl->numa_node; | 1598 | set->numa_node = nctrl->numa_node; |
| 1592 | set->flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING; | 1599 | set->flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING; |
| 1593 | set->cmd_size = sizeof(struct nvme_tcp_request); | 1600 | set->cmd_size = sizeof(struct nvme_tcp_request); |
| @@ -1745,8 +1752,11 @@ static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl) · 151 unmodified lines | |||
| 1745 | return ret; | 1752 | return ret; |
| 1746 | 1753 | ||
| 1747 | ctrl->queue_count = nr_io_queues + 1; | 1754 | ctrl->queue_count = nr_io_queues + 1; |
| 1748 | if (ctrl->queue_count < 2) | 1755 | if (ctrl->queue_count < 2) { |
| 1749 | return 0; | 1756 | dev_err(ctrl->device, |
| 1757 | "unable to set any I/O queues\n"); | ||
| 1758 | return -ENOMEM; | ||
| 1759 | } | ||
| 1750 | 1760 | ||
| 1751 | dev_info(ctrl->device, | 1761 | dev_info(ctrl->device, |
| 1752 | "creating %d I/O queues.\n", nr_io_queues); | 1762 | "creating %d I/O queues.\n", nr_io_queues); |
| @@ -9,7 +9,13 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | int nvme_revalidate_zones(struct nvme_ns *ns) | 10 | int nvme_revalidate_zones(struct nvme_ns *ns) |
| 11 | { | 11 | { |
| 12 | return blk_revalidate_disk_zones(ns->disk, NULL); | 12 | struct request_queue *q = ns->queue; |
| 13 | int ret; | ||
| 14 | |||
| 15 | ret = blk_revalidate_disk_zones(ns->disk, NULL); | ||
| 16 | if (!ret) | ||
| 17 | blk_queue_max_zone_append_sectors(q, ns->ctrl->max_zone_append); | ||
| 18 | return ret; | ||
| 13 | } | 19 | } |
| 14 | 20 | ||
| 15 | static int nvme_set_max_append(struct nvme_ctrl *ctrl) | 21 | static int nvme_set_max_append(struct nvme_ctrl *ctrl) |
| @@ -107,7 +113,6 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf) · 91 unmodified lines | |||
| 107 | blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); | 113 | blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); |
| 108 | blk_queue_max_open_zones(q, le32_to_cpu(id->mor) + 1); | 114 | blk_queue_max_open_zones(q, le32_to_cpu(id->mor) + 1); |
| 109 | blk_queue_max_active_zones(q, le32_to_cpu(id->mar) + 1); | 115 | blk_queue_max_active_zones(q, le32_to_cpu(id->mar) + 1); |
| 110 | blk_queue_max_zone_append_sectors(q, ns->ctrl->max_zone_append); | ||
| 111 | free_data: | 116 | free_data: |
| 112 | kfree(id); | 117 | kfree(id); |
| 113 | return status; | 118 | return status; |
| @@ -1118,9 +1118,20 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl) · 1117 unmodified lines | |||
| 1118 | { | 1118 | { |
| 1119 | lockdep_assert_held(&ctrl->lock); | 1119 | lockdep_assert_held(&ctrl->lock); |
| 1120 | 1120 | ||
| 1121 | if (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || | 1121 | /* |
| 1122 | nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES || | 1122 | * Only I/O controllers should verify iosqes,iocqes. |
| 1123 | nvmet_cc_mps(ctrl->cc) != 0 || | 1123 | * Strictly speaking, the spec says a discovery controller |
| 1124 | * should verify iosqes,iocqes are zeroed, however that | ||
| 1125 | * would break backwards compatibility, so don't enforce it. | ||
| 1126 | */ | ||
| 1127 | if (ctrl->subsys->type != NVME_NQN_DISC && | ||
| 1128 | (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || | ||
| 1129 | nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES)) { | ||
| 1130 | ctrl->csts = NVME_CSTS_CFS; | ||
| 1131 | return; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | if (nvmet_cc_mps(ctrl->cc) != 0 || | ||
| 1124 | nvmet_cc_ams(ctrl->cc) != 0 || | 1135 | nvmet_cc_ams(ctrl->cc) != 0 || |
| 1125 | nvmet_cc_css(ctrl->cc) != 0) { | 1136 | nvmet_cc_css(ctrl->cc) != 0) { |
| 1126 | ctrl->csts = NVME_CSTS_CFS; | 1137 | ctrl->csts = NVME_CSTS_CFS; |
| @@ -349,7 +349,7 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl) · 348 unmodified lines | |||
| 349 | memset(&ctrl->admin_tag_set, 0, sizeof(ctrl->admin_tag_set)); | 349 | memset(&ctrl->admin_tag_set, 0, sizeof(ctrl->admin_tag_set)); |
| 350 | ctrl->admin_tag_set.ops = &nvme_loop_admin_mq_ops; | 350 | ctrl->admin_tag_set.ops = &nvme_loop_admin_mq_ops; |
| 351 | ctrl->admin_tag_set.queue_depth = NVME_AQ_MQ_TAG_DEPTH; | 351 | ctrl->admin_tag_set.queue_depth = NVME_AQ_MQ_TAG_DEPTH; |
| 352 | ctrl->admin_tag_set.reserved_tags = 2; /* connect + keep-alive */ | 352 | ctrl->admin_tag_set.reserved_tags = NVMF_RESERVED_TAGS; |
| 353 | ctrl->admin_tag_set.numa_node = ctrl->ctrl.numa_node; | 353 | ctrl->admin_tag_set.numa_node = ctrl->ctrl.numa_node; |
| 354 | ctrl->admin_tag_set.cmd_size = sizeof(struct nvme_loop_iod) + | 354 | ctrl->admin_tag_set.cmd_size = sizeof(struct nvme_loop_iod) + |
| 355 | NVME_INLINE_SG_CNT * sizeof(struct scatterlist); | 355 | NVME_INLINE_SG_CNT * sizeof(struct scatterlist); |
| @@ -520,7 +520,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl) · 164 unmodified lines | |||
| 520 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); | 520 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); |
| 521 | ctrl->tag_set.ops = &nvme_loop_mq_ops; | 521 | ctrl->tag_set.ops = &nvme_loop_mq_ops; |
| 522 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; | 522 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; |
| 523 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ | 523 | ctrl->tag_set.reserved_tags = NVMF_RESERVED_TAGS; |
| 524 | ctrl->tag_set.numa_node = ctrl->ctrl.numa_node; | 524 | ctrl->tag_set.numa_node = ctrl->ctrl.numa_node; |
| 525 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; | 525 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
| 526 | ctrl->tag_set.cmd_size = sizeof(struct nvme_loop_iod) + | 526 | ctrl->tag_set.cmd_size = sizeof(struct nvme_loop_iod) + |
| @@ -50,9 +50,9 @@ static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| 52 | * nvmet_passthru_map_sg is limitted to using a single bio so limit | 52 | * nvmet_passthru_map_sg is limitted to using a single bio so limit |
| 53 | * the mdts based on BIO_MAX_PAGES as well | 53 | * the mdts based on BIO_MAX_VECS as well |
| 54 | */ | 54 | */ |
| 55 | max_hw_sectors = min_not_zero(BIO_MAX_PAGES << (PAGE_SHIFT - 9), | 55 | max_hw_sectors = min_not_zero(BIO_MAX_VECS << (PAGE_SHIFT - 9), |
| 56 | max_hw_sectors); | 56 | max_hw_sectors); |
| 57 | 57 | ||
| 58 | page_shift = NVME_CAP_MPSMIN(ctrl->cap) + 12; | 58 | page_shift = NVME_CAP_MPSMIN(ctrl->cap) + 12; |
| @@ -191,7 +191,7 @@ static int nvmet_passthru_map_sg(struct nvmet_req *req, struct request *rq) · 132 unmodified lines | |||
| 191 | struct bio *bio; | 191 | struct bio *bio; |
| 192 | int i; | 192 | int i; |
| 193 | 193 | ||
| 194 | if (req->sg_cnt > BIO_MAX_PAGES) | 194 | if (req->sg_cnt > BIO_MAX_VECS) |
| 195 | return -EINVAL; | 195 | return -EINVAL; |
| 196 | 196 | ||
| 197 | if (req->transfer_len <= NVMET_MAX_INLINE_DATA_LEN) { | 197 | if (req->transfer_len <= NVMET_MAX_INLINE_DATA_LEN) { |
| @@ -802,9 +802,8 @@ static void nvmet_rdma_write_data_done(struct ib_cq *cq, struct ib_wc *wc) · 801 unmodified lines | |||
| 802 | nvmet_req_uninit(&rsp->req); | 802 | nvmet_req_uninit(&rsp->req); |
| 803 | nvmet_rdma_release_rsp(rsp); | 803 | nvmet_rdma_release_rsp(rsp); |
| 804 | if (wc->status != IB_WC_WR_FLUSH_ERR) { | 804 | if (wc->status != IB_WC_WR_FLUSH_ERR) { |
| 805 | pr_info("RDMA WRITE for CQE 0x%p failed with status %s (%d).\n", | 805 | pr_info("RDMA WRITE for CQE failed with status %s (%d).\n", |
| 806 | wc->wr_cqe, ib_wc_status_msg(wc->status), | 806 | ib_wc_status_msg(wc->status), wc->status); |
| 807 | wc->status); | ||
| 808 | nvmet_rdma_error_comp(queue); | 807 | nvmet_rdma_error_comp(queue); |
| 809 | } | 808 | } |
| 810 | return; | 809 | return; |
| @@ -1098,11 +1098,11 @@ static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue) · 1097 unmodified lines | |||
| 1098 | cmd->rbytes_done += ret; | 1098 | cmd->rbytes_done += ret; |
| 1099 | } | 1099 | } |
| 1100 | 1100 | ||
| 1101 | nvmet_tcp_unmap_pdu_iovec(cmd); | ||
| 1101 | if (queue->data_digest) { | 1102 | if (queue->data_digest) { |
| 1102 | nvmet_tcp_prep_recv_ddgst(cmd); | 1103 | nvmet_tcp_prep_recv_ddgst(cmd); |
| 1103 | return 0; | 1104 | return 0; |
| 1104 | } | 1105 | } |
| 1105 | nvmet_tcp_unmap_pdu_iovec(cmd); | ||
| 1106 | 1106 | ||
| 1107 | if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED) && | 1107 | if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED) && |
| 1108 | cmd->rbytes_done == cmd->req.transfer_len) { | 1108 | cmd->rbytes_done == cmd->req.transfer_len) { |
| @@ -1492,7 +1492,11 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table, · 1491 unmodified lines | |||
| 1492 | 1492 | ||
| 1493 | mutex_lock(&opp_table->lock); | 1493 | mutex_lock(&opp_table->lock); |
| 1494 | list_for_each_entry(temp, &opp_table->opp_list, node) { | 1494 | list_for_each_entry(temp, &opp_table->opp_list, node) { |
| 1495 | if (dynamic == temp->dynamic) { | 1495 | /* |
| 1496 | * Refcount must be dropped only once for each OPP by OPP core, | ||
| 1497 | * do that with help of "removed" flag. | ||
| 1498 | */ | ||
| 1499 | if (!temp->removed && dynamic == temp->dynamic) { | ||
| 1496 | opp = temp; | 1500 | opp = temp; |
| 1497 | break; | 1501 | break; |
| 1498 | } | 1502 | } |
| @@ -1502,10 +1506,27 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table, · 3 unmodified lines | |||
| 1502 | return opp; | 1506 | return opp; |
| 1503 | } | 1507 | } |
| 1504 | 1508 | ||
| 1505 | bool _opp_remove_all_static(struct opp_table *opp_table) | 1509 | /* |
| 1510 | * Can't call dev_pm_opp_put() from under the lock as debugfs removal needs to | ||
| 1511 | * happen lock less to avoid circular dependency issues. This routine must be | ||
| 1512 | * called without the opp_table->lock held. | ||
| 1513 | */ | ||
| 1514 | static void _opp_remove_all(struct opp_table *opp_table, bool dynamic) | ||
| 1506 | { | 1515 | { |
| 1507 | struct dev_pm_opp *opp; | 1516 | struct dev_pm_opp *opp; |
| 1508 | 1517 | ||
| 1518 | while ((opp = _opp_get_next(opp_table, dynamic))) { | ||
| 1519 | opp->removed = true; | ||
| 1520 | dev_pm_opp_put(opp); | ||
| 1521 | |||
| 1522 | /* Drop the references taken by dev_pm_opp_add() */ | ||
| 1523 | if (dynamic) | ||
| 1524 | dev_pm_opp_put_opp_table(opp_table); | ||
| 1525 | } | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | bool _opp_remove_all_static(struct opp_table *opp_table) | ||
| 1529 | { | ||
| 1509 | mutex_lock(&opp_table->lock); | 1530 | mutex_lock(&opp_table->lock); |
| 1510 | 1531 | ||
| 1511 | if (!opp_table->parsed_static_opps) { | 1532 | if (!opp_table->parsed_static_opps) { |
| @@ -1520,13 +1541,7 @@ bool _opp_remove_all_static(struct opp_table *opp_table) · 8 unmodified lines | |||
| 1520 | 1541 | ||
| 1521 | mutex_unlock(&opp_table->lock); | 1542 | mutex_unlock(&opp_table->lock); |
| 1522 | 1543 | ||
| 1523 | /* | 1544 | _opp_remove_all(opp_table, false); |
| 1524 | * Can't remove the OPP from under the lock, debugfs removal needs to | ||
| 1525 | * happen lock less to avoid circular dependency issues. | ||
| 1526 | */ | ||
| 1527 | while ((opp = _opp_get_next(opp_table, false))) | ||
| 1528 | dev_pm_opp_put(opp); | ||
| 1529 | |||
| 1530 | return true; | 1545 | return true; |
| 1531 | } | 1546 | } |
| 1532 | 1547 | ||
| @@ -1539,25 +1554,12 @@ bool _opp_remove_all_static(struct opp_table *opp_table) · 6 unmodified lines | |||
| 1539 | void dev_pm_opp_remove_all_dynamic(struct device *dev) | 1554 | void dev_pm_opp_remove_all_dynamic(struct device *dev) |
| 1540 | { | 1555 | { |
| 1541 | struct opp_table *opp_table; | 1556 | struct opp_table *opp_table; |
| 1542 | struct dev_pm_opp *opp; | ||
| 1543 | int count = 0; | ||
| 1544 | 1557 | ||
| 1545 | opp_table = _find_opp_table(dev); | 1558 | opp_table = _find_opp_table(dev); |
| 1546 | if (IS_ERR(opp_table)) | 1559 | if (IS_ERR(opp_table)) |
| 1547 | return; | 1560 | return; |
| 1548 | 1561 | ||
| 1549 | /* | 1562 | _opp_remove_all(opp_table, true); |
| 1550 | * Can't remove the OPP from under the lock, debugfs removal needs to | ||
| 1551 | * happen lock less to avoid circular dependency issues. | ||
| 1552 | */ | ||
| 1553 | while ((opp = _opp_get_next(opp_table, true))) { | ||
| 1554 | dev_pm_opp_put(opp); | ||
| 1555 | count++; | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | /* Drop the references taken by dev_pm_opp_add() */ | ||
| 1559 | while (count--) | ||
| 1560 | dev_pm_opp_put_opp_table(opp_table); | ||
| 1561 | 1563 | ||
| 1562 | /* Drop the reference taken by _find_opp_table() */ | 1564 | /* Drop the reference taken by _find_opp_table() */ |
| 1563 | dev_pm_opp_put_opp_table(opp_table); | 1565 | dev_pm_opp_put_opp_table(opp_table); |
| @@ -56,6 +56,7 @@ extern struct list_head opp_tables, lazy_opp_tables; · 55 unmodified lines | |||
| 56 | * @dynamic: not-created from static DT entries. | 56 | * @dynamic: not-created from static DT entries. |
| 57 | * @turbo: true if turbo (boost) OPP | 57 | * @turbo: true if turbo (boost) OPP |
| 58 | * @suspend: true if suspend OPP | 58 | * @suspend: true if suspend OPP |
| 59 | * @removed: flag indicating that OPP's reference is dropped by OPP core. | ||
| 59 | * @pstate: Device's power domain's performance state. | 60 | * @pstate: Device's power domain's performance state. |
| 60 | * @rate: Frequency in hertz | 61 | * @rate: Frequency in hertz |
| 61 | * @level: Performance level | 62 | * @level: Performance level |
| @@ -78,6 +79,7 @@ struct dev_pm_opp { · 16 unmodified lines | |||
| 78 | bool dynamic; | 79 | bool dynamic; |
| 79 | bool turbo; | 80 | bool turbo; |
| 80 | bool suspend; | 81 | bool suspend; |
| 82 | bool removed; | ||
| 81 | unsigned int pstate; | 83 | unsigned int pstate; |
| 82 | unsigned long rate; | 84 | unsigned long rate; |
| 83 | unsigned int level; | 85 | unsigned int level; |
| @@ -241,6 +241,5 @@ module_platform_driver_probe(amiga_parallel_driver, amiga_parallel_probe); · 240 unmodified lines | |||
| 241 | 241 | ||
| 242 | MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); | 242 | MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); |
| 243 | MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); | 243 | MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); |
| 244 | MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port"); | ||
| 245 | MODULE_LICENSE("GPL"); | 244 | MODULE_LICENSE("GPL"); |
| 246 | MODULE_ALIAS("platform:amiga-parallel"); | 245 | MODULE_ALIAS("platform:amiga-parallel"); |
| @@ -218,7 +218,6 @@ static void __exit parport_atari_exit(void) · 217 unmodified lines | |||
| 218 | 218 | ||
| 219 | MODULE_AUTHOR("Andreas Schwab"); | 219 | MODULE_AUTHOR("Andreas Schwab"); |
| 220 | MODULE_DESCRIPTION("Parport Driver for Atari builtin Port"); | 220 | MODULE_DESCRIPTION("Parport Driver for Atari builtin Port"); |
| 221 | MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port"); | ||
| 222 | MODULE_LICENSE("GPL"); | 221 | MODULE_LICENSE("GPL"); |
| 223 | 222 | ||
| 224 | module_init(parport_atari_init) | 223 | module_init(parport_atari_init) |
| @@ -41,7 +41,6 @@ · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | MODULE_AUTHOR("Helge Deller <deller@gmx.de>"); | 42 | MODULE_AUTHOR("Helge Deller <deller@gmx.de>"); |
| 43 | MODULE_DESCRIPTION("HP-PARISC PC-style parallel port driver"); | 43 | MODULE_DESCRIPTION("HP-PARISC PC-style parallel port driver"); |
| 44 | MODULE_SUPPORTED_DEVICE("integrated PC-style parallel port"); | ||
| 45 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
| 46 | 45 | ||
| 47 | 46 | ||
| @@ -359,7 +359,6 @@ static void __exit parport_mfc3_exit(void) · 358 unmodified lines | |||
| 359 | 359 | ||
| 360 | MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); | 360 | MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); |
| 361 | MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Parallel Port"); | 361 | MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Parallel Port"); |
| 362 | MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port"); | ||
| 363 | MODULE_LICENSE("GPL"); | 362 | MODULE_LICENSE("GPL"); |
| 364 | 363 | ||
| 365 | module_init(parport_mfc3_init) | 364 | module_init(parport_mfc3_init) |
| @@ -377,6 +377,5 @@ module_platform_driver(bpp_sbus_driver); · 376 unmodified lines | |||
| 377 | 377 | ||
| 378 | MODULE_AUTHOR("Derrick J Brashear"); | 378 | MODULE_AUTHOR("Derrick J Brashear"); |
| 379 | MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); | 379 | MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); |
| 380 | MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); | ||
| 381 | MODULE_VERSION("2.0"); | 380 | MODULE_VERSION("2.0"); |
| 382 | MODULE_LICENSE("GPL"); | 381 | MODULE_LICENSE("GPL"); |
| @@ -34,12 +34,11 @@ static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr, · 33 unmodified lines | |||
| 34 | if (nbytes >= MAX_DRC_NAME_LEN) | 34 | if (nbytes >= MAX_DRC_NAME_LEN) |
| 35 | return 0; | 35 | return 0; |
| 36 | 36 | ||
| 37 | memcpy(drc_name, buf, nbytes); | 37 | strscpy(drc_name, buf, nbytes + 1); |
| 38 | 38 | ||
| 39 | end = strchr(drc_name, '\n'); | 39 | end = strchr(drc_name, '\n'); |
| 40 | if (!end) | 40 | if (end) |
| 41 | end = &drc_name[nbytes]; | 41 | *end = '\0'; |
| 42 | *end = '\0'; | ||
| 43 | 42 | ||
| 44 | rc = dlpar_add_slot(drc_name); | 43 | rc = dlpar_add_slot(drc_name); |
| 45 | if (rc) | 44 | if (rc) |
| @@ -65,12 +64,11 @@ static ssize_t remove_slot_store(struct kobject *kobj, · 19 unmodified lines | |||
| 65 | if (nbytes >= MAX_DRC_NAME_LEN) | 64 | if (nbytes >= MAX_DRC_NAME_LEN) |
| 66 | return 0; | 65 | return 0; |
| 67 | 66 | ||
| 68 | memcpy(drc_name, buf, nbytes); | 67 | strscpy(drc_name, buf, nbytes + 1); |
| 69 | 68 | ||
| 70 | end = strchr(drc_name, '\n'); | 69 | end = strchr(drc_name, '\n'); |
| 71 | if (!end) | 70 | if (end) |
| 72 | end = &drc_name[nbytes]; | 71 | *end = '\0'; |
| 73 | *end = '\0'; | ||
| 74 | 72 | ||
| 75 | rc = dlpar_remove_slot(drc_name); | 73 | rc = dlpar_remove_slot(drc_name); |
| 76 | if (rc) | 74 | if (rc) |
| @@ -93,8 +93,9 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) · 92 unmodified lines | |||
| 93 | pci_dev_put(pdev); | 93 | pci_dev_put(pdev); |
| 94 | return -EBUSY; | 94 | return -EBUSY; |
| 95 | } | 95 | } |
| 96 | pci_dev_put(pdev); | ||
| 96 | 97 | ||
| 97 | zpci_remove_device(zdev); | 98 | zpci_remove_device(zdev, false); |
| 98 | 99 | ||
| 99 | rc = zpci_disable_device(zdev); | 100 | rc = zpci_disable_device(zdev); |
| 100 | if (rc) | 101 | if (rc) |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <xen/platform_pci.h> | 26 | #include <xen/platform_pci.h> |
| 27 | 27 | ||
| 28 | #include <asm/xen/swiotlb-xen.h> | 28 | #include <asm/xen/swiotlb-xen.h> |
| 29 | #define INVALID_GRANT_REF (0) | 29 | |
| 30 | #define INVALID_EVTCHN (-1) | 30 | #define INVALID_EVTCHN (-1) |
| 31 | 31 | ||
| 32 | struct pci_bus_entry { | 32 | struct pci_bus_entry { |
| @@ -42,7 +42,7 @@ struct pcifront_device { · 9 unmodified lines | |||
| 42 | struct list_head root_buses; | 42 | struct list_head root_buses; |
| 43 | 43 | ||
| 44 | int evtchn; | 44 | int evtchn; |
| 45 | int gnt_ref; | 45 | grant_ref_t gnt_ref; |
| 46 | 46 | ||
| 47 | int irq; | 47 | int irq; |
| 48 | 48 | ||
| @@ -681,6 +681,7 @@ static int dmc620_pmu_device_probe(struct platform_device *pdev) · 680 unmodified lines | |||
| 681 | if (!name) { | 681 | if (!name) { |
| 682 | dev_err(&pdev->dev, | 682 | dev_err(&pdev->dev, |
| 683 | "Create name failed, PMU @%pa\n", &res->start); | 683 | "Create name failed, PMU @%pa\n", &res->start); |
| 684 | ret = -ENOMEM; | ||
| 684 | goto out_teardown_dev; | 685 | goto out_teardown_dev; |
| 685 | } | 686 | } |
| 686 | 687 | ||
| @@ -1173,15 +1173,20 @@ config INTEL_PMC_CORE · 1172 unmodified lines | |||
| 1173 | depends on PCI | 1173 | depends on PCI |
| 1174 | help | 1174 | help |
| 1175 | The Intel Platform Controller Hub for Intel Core SoCs provides access | 1175 | The Intel Platform Controller Hub for Intel Core SoCs provides access |
| 1176 | to Power Management Controller registers via a PCI interface. This | 1176 | to Power Management Controller registers via various interfaces. This |
| 1177 | driver can utilize debugging capabilities and supported features as | 1177 | driver can utilize debugging capabilities and supported features as |
| 1178 | exposed by the Power Management Controller. | 1178 | exposed by the Power Management Controller. It also may perform some |
| 1179 | tasks in the PMC in order to enable transition into the SLPS0 state. | ||
| 1180 | It should be selected on all Intel platforms supported by the driver. | ||
| 1179 | 1181 | ||
| 1180 | Supported features: | 1182 | Supported features: |
| 1181 | - SLP_S0_RESIDENCY counter | 1183 | - SLP_S0_RESIDENCY counter |
| 1182 | - PCH IP Power Gating status | 1184 | - PCH IP Power Gating status |
| 1183 | - LTR Ignore | 1185 | - LTR Ignore / LTR Show |
| 1184 | - MPHY/PLL gating status (Sunrisepoint PCH only) | 1186 | - MPHY/PLL gating status (Sunrisepoint PCH only) |
| 1187 | - SLPS0 Debug registers (Cannonlake/Icelake PCH) | ||
| 1188 | - Low Power Mode registers (Tigerlake and beyond) | ||
| 1189 | - PMC quirks as needed to enable SLPS0/S0ix | ||
| 1185 | 1190 | ||
| 1186 | config INTEL_PMT_CLASS | 1191 | config INTEL_PMT_CLASS |
| 1187 | tristate | 1192 | tristate |
| @@ -185,5 +185,8 @@ void exit_enum_attributes(void) · 184 unmodified lines | |||
| 185 | sysfs_remove_group(wmi_priv.enumeration_data[instance_id].attr_name_kobj, | 185 | sysfs_remove_group(wmi_priv.enumeration_data[instance_id].attr_name_kobj, |
| 186 | &enumeration_attr_group); | 186 | &enumeration_attr_group); |
| 187 | } | 187 | } |
| 188 | wmi_priv.enumeration_instances_count = 0; | ||
| 189 | |||
| 188 | kfree(wmi_priv.enumeration_data); | 190 | kfree(wmi_priv.enumeration_data); |
| 191 | wmi_priv.enumeration_data = NULL; | ||
| 189 | } | 192 | } |
| @@ -175,5 +175,8 @@ void exit_int_attributes(void) · 174 unmodified lines | |||
| 175 | sysfs_remove_group(wmi_priv.integer_data[instance_id].attr_name_kobj, | 175 | sysfs_remove_group(wmi_priv.integer_data[instance_id].attr_name_kobj, |
| 176 | &integer_attr_group); | 176 | &integer_attr_group); |
| 177 | } | 177 | } |
| 178 | wmi_priv.integer_instances_count = 0; | ||
| 179 | |||
| 178 | kfree(wmi_priv.integer_data); | 180 | kfree(wmi_priv.integer_data); |
| 181 | wmi_priv.integer_data = NULL; | ||
| 179 | } | 182 | } |
| @@ -183,5 +183,8 @@ void exit_po_attributes(void) · 182 unmodified lines | |||
| 183 | sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj, | 183 | sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj, |
| 184 | &po_attr_group); | 184 | &po_attr_group); |
| 185 | } | 185 | } |
| 186 | wmi_priv.po_instances_count = 0; | ||
| 187 | |||
| 186 | kfree(wmi_priv.po_data); | 188 | kfree(wmi_priv.po_data); |
| 189 | wmi_priv.po_data = NULL; | ||
| 187 | } | 190 | } |
| @@ -155,5 +155,8 @@ void exit_str_attributes(void) · 154 unmodified lines | |||
| 155 | sysfs_remove_group(wmi_priv.str_data[instance_id].attr_name_kobj, | 155 | sysfs_remove_group(wmi_priv.str_data[instance_id].attr_name_kobj, |
| 156 | &str_attr_group); | 156 | &str_attr_group); |
| 157 | } | 157 | } |
| 158 | wmi_priv.str_instances_count = 0; | ||
| 159 | |||
| 158 | kfree(wmi_priv.str_data); | 160 | kfree(wmi_priv.str_data); |
| 161 | wmi_priv.str_data = NULL; | ||
| 159 | } | 162 | } |
| @@ -210,25 +210,17 @@ static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot); · 209 unmodified lines | |||
| 210 | */ | 210 | */ |
| 211 | static int create_attributes_level_sysfs_files(void) | 211 | static int create_attributes_level_sysfs_files(void) |
| 212 | { | 212 | { |
| 213 | int ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); | 213 | int ret; |
| 214 | 214 | ||
| 215 | if (ret) { | 215 | ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); |
| 216 | pr_debug("could not create reset_bios file\n"); | 216 | if (ret) |
| 217 | return ret; | 217 | return ret; |
| 218 | } | ||
| 219 | 218 | ||
| 220 | ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); | 219 | ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); |
| 221 | if (ret) { | 220 | if (ret) |
| 222 | pr_debug("could not create changing_pending_reboot file\n"); | 221 | return ret; |
| 223 | sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); | ||
| 224 | } | ||
| 225 | return ret; | ||
| 226 | } | ||
| 227 | 222 | ||
| 228 | static void release_reset_bios_data(void) | 223 | return 0; |
| 229 | { | ||
| 230 | sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); | ||
| 231 | sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); | ||
| 232 | } | 224 | } |
| 233 | 225 | ||
| 234 | static ssize_t wmi_sysman_attr_show(struct kobject *kobj, struct attribute *attr, | 226 | static ssize_t wmi_sysman_attr_show(struct kobject *kobj, struct attribute *attr, |
| @@ -373,8 +365,6 @@ static void destroy_attribute_objs(struct kset *kset) · 138 unmodified lines | |||
| 373 | */ | 365 | */ |
| 374 | static void release_attributes_data(void) | 366 | static void release_attributes_data(void) |
| 375 | { | 367 | { |
| 376 | release_reset_bios_data(); | ||
| 377 | |||
| 378 | mutex_lock(&wmi_priv.mutex); | 368 | mutex_lock(&wmi_priv.mutex); |
| 379 | exit_enum_attributes(); | 369 | exit_enum_attributes(); |
| 380 | exit_int_attributes(); | 370 | exit_int_attributes(); |
| @@ -386,11 +376,13 @@ static void release_attributes_data(void) · 5 unmodified lines | |||
| 386 | wmi_priv.authentication_dir_kset = NULL; | 376 | wmi_priv.authentication_dir_kset = NULL; |
| 387 | } | 377 | } |
| 388 | if (wmi_priv.main_dir_kset) { | 378 | if (wmi_priv.main_dir_kset) { |
| 379 | sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); | ||
| 380 | sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); | ||
| 389 | destroy_attribute_objs(wmi_priv.main_dir_kset); | 381 | destroy_attribute_objs(wmi_priv.main_dir_kset); |
| 390 | kset_unregister(wmi_priv.main_dir_kset); | 382 | kset_unregister(wmi_priv.main_dir_kset); |
| 383 | wmi_priv.main_dir_kset = NULL; | ||
| 391 | } | 384 | } |
| 392 | mutex_unlock(&wmi_priv.mutex); | 385 | mutex_unlock(&wmi_priv.mutex); |
| 393 | |||
| 394 | } | 386 | } |
| 395 | 387 | ||
| 396 | /** | 388 | /** |
| @@ -497,7 +489,6 @@ nextobj: · 100 unmodified lines | |||
| 497 | 489 | ||
| 498 | err_attr_init: | 490 | err_attr_init: |
| 499 | mutex_unlock(&wmi_priv.mutex); | 491 | mutex_unlock(&wmi_priv.mutex); |
| 500 | release_attributes_data(); | ||
| 501 | kfree(obj); | 492 | kfree(obj); |
| 502 | return retval; | 493 | return retval; |
| 503 | } | 494 | } |
| @@ -513,102 +504,91 @@ static int __init sysman_init(void) · 9 unmodified lines | |||
| 513 | } | 504 | } |
| 514 | 505 | ||
| 515 | ret = init_bios_attr_set_interface(); | 506 | ret = init_bios_attr_set_interface(); |
| 516 | if (ret || !wmi_priv.bios_attr_wdev) { | 507 | if (ret) |
| 517 | pr_debug("failed to initialize set interface\n"); | 508 | return ret; |
| 518 | goto fail_set_interface; | ||
| 519 | } | ||
| 520 | 509 | ||
| 521 | ret = init_bios_attr_pass_interface(); | 510 | ret = init_bios_attr_pass_interface(); |
| 522 | if (ret || !wmi_priv.password_attr_wdev) { | 511 | if (ret) |
| 523 | pr_debug("failed to initialize pass interface\n"); | 512 | goto err_exit_bios_attr_set_interface; |
| 524 | goto fail_pass_interface; | 513 | |
| 514 | if (!wmi_priv.bios_attr_wdev || !wmi_priv.password_attr_wdev) { | ||
| 515 | pr_debug("failed to find set or pass interface\n"); | ||
| 516 | ret = -ENODEV; | ||
| 517 | goto err_exit_bios_attr_pass_interface; | ||
| 525 | } | 518 | } |
| 526 | 519 | ||
| 527 | ret = class_register(&firmware_attributes_class); | 520 | ret = class_register(&firmware_attributes_class); |
| 528 | if (ret) | 521 | if (ret) |
| 529 | goto fail_class; | 522 | goto err_exit_bios_attr_pass_interface; |
| 530 | 523 | ||
| 531 | wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), | 524 | wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), |
| 532 | NULL, "%s", DRIVER_NAME); | 525 | NULL, "%s", DRIVER_NAME); |
| 533 | if (IS_ERR(wmi_priv.class_dev)) { | 526 | if (IS_ERR(wmi_priv.class_dev)) { |
| 534 | ret = PTR_ERR(wmi_priv.class_dev); | 527 | ret = PTR_ERR(wmi_priv.class_dev); |
| 535 | goto fail_classdev; | 528 | goto err_unregister_class; |
| 536 | } | 529 | } |
| 537 | 530 | ||
| 538 | wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL, | 531 | wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL, |
| 539 | &wmi_priv.class_dev->kobj); | 532 | &wmi_priv.class_dev->kobj); |
| 540 | if (!wmi_priv.main_dir_kset) { | 533 | if (!wmi_priv.main_dir_kset) { |
| 541 | ret = -ENOMEM; | 534 | ret = -ENOMEM; |
| 542 | goto fail_main_kset; | 535 | goto err_destroy_classdev; |
| 543 | } | 536 | } |
| 544 | 537 | ||
| 545 | wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL, | 538 | wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL, |
| 546 | &wmi_priv.class_dev->kobj); | 539 | &wmi_priv.class_dev->kobj); |
| 547 | if (!wmi_priv.authentication_dir_kset) { | 540 | if (!wmi_priv.authentication_dir_kset) { |
| 548 | ret = -ENOMEM; | 541 | ret = -ENOMEM; |
| 549 | goto fail_authentication_kset; | 542 | goto err_release_attributes_data; |
| 550 | } | 543 | } |
| 551 | 544 | ||
| 552 | ret = create_attributes_level_sysfs_files(); | 545 | ret = create_attributes_level_sysfs_files(); |
| 553 | if (ret) { | 546 | if (ret) { |
| 554 | pr_debug("could not create reset BIOS attribute\n"); | 547 | pr_debug("could not create reset BIOS attribute\n"); |
| 555 | goto fail_reset_bios; | 548 | goto err_release_attributes_data; |
| 556 | } | 549 | } |
| 557 | 550 | ||
| 558 | ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); | 551 | ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); |
| 559 | if (ret) { | 552 | if (ret) { |
| 560 | pr_debug("failed to populate enumeration type attributes\n"); | 553 | pr_debug("failed to populate enumeration type attributes\n"); |
| 561 | goto fail_create_group; | 554 | goto err_release_attributes_data; |
| 562 | } | 555 | } |
| 563 | 556 | ||
| 564 | ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); | 557 | ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); |
| 565 | if (ret) { | 558 | if (ret) { |
| 566 | pr_debug("failed to populate integer type attributes\n"); | 559 | pr_debug("failed to populate integer type attributes\n"); |
| 567 | goto fail_create_group; | 560 | goto err_release_attributes_data; |
| 568 | } | 561 | } |
| 569 | 562 | ||
| 570 | ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); | 563 | ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); |
| 571 | if (ret) { | 564 | if (ret) { |
| 572 | pr_debug("failed to populate string type attributes\n"); | 565 | pr_debug("failed to populate string type attributes\n"); |
| 573 | goto fail_create_group; | 566 | goto err_release_attributes_data; |
| 574 | } | 567 | } |
| 575 | 568 | ||
| 576 | ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); | 569 | ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); |
| 577 | if (ret) { | 570 | if (ret) { |
| 578 | pr_debug("failed to populate pass object type attributes\n"); | 571 | pr_debug("failed to populate pass object type attributes\n"); |
| 579 | goto fail_create_group; | 572 | goto err_release_attributes_data; |
| 580 | } | 573 | } |
| 581 | 574 | ||
| 582 | return 0; | 575 | return 0; |
| 583 | 576 | ||
| 584 | fail_create_group: | 577 | err_release_attributes_data: |
| 585 | release_attributes_data(); | 578 | release_attributes_data(); |
| 586 | 579 | ||
| 587 | fail_reset_bios: | 580 | err_destroy_classdev: |
| 588 | if (wmi_priv.authentication_dir_kset) { | ||
| 589 | kset_unregister(wmi_priv.authentication_dir_kset); | ||
| 590 | wmi_priv.authentication_dir_kset = NULL; | ||
| 591 | } | ||
| 592 | |||
| 593 | fail_authentication_kset: | ||
| 594 | if (wmi_priv.main_dir_kset) { | ||
| 595 | kset_unregister(wmi_priv.main_dir_kset); | ||
| 596 | wmi_priv.main_dir_kset = NULL; | ||
| 597 | } | ||
| 598 | |||
| 599 | fail_main_kset: | ||
| 600 | device_destroy(&firmware_attributes_class, MKDEV(0, 0)); | 581 | device_destroy(&firmware_attributes_class, MKDEV(0, 0)); |
| 601 | 582 | ||
| 602 | fail_classdev: | 583 | err_unregister_class: |
| 603 | class_unregister(&firmware_attributes_class); | 584 | class_unregister(&firmware_attributes_class); |
| 604 | 585 | ||
| 605 | fail_class: | 586 | err_exit_bios_attr_pass_interface: |
| 606 | exit_bios_attr_pass_interface(); | 587 | exit_bios_attr_pass_interface(); |
| 607 | 588 | ||
| 608 | fail_pass_interface: | 589 | err_exit_bios_attr_set_interface: |
| 609 | exit_bios_attr_set_interface(); | 590 | exit_bios_attr_set_interface(); |
| 610 | 591 | ||
| 611 | fail_set_interface: | ||
| 612 | return ret; | 592 | return ret; |
| 613 | } | 593 | } |
| 614 | 594 | ||
| @@ -90,6 +90,13 @@ static const struct dmi_system_id button_array_table[] = { · 89 unmodified lines | |||
| 90 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"), | 90 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"), |
| 91 | }, | 91 | }, |
| 92 | }, | 92 | }, |
| 93 | { | ||
| 94 | .ident = "Lenovo ThinkPad X1 Tablet Gen 2", | ||
| 95 | .matches = { | ||
| 96 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 97 | DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), | ||
| 98 | }, | ||
| 99 | }, | ||
| 93 | { } | 100 | { } |
| 94 | }; | 101 | }; |
| 95 | 102 | ||
| @@ -48,8 +48,16 @@ static const struct key_entry intel_vbtn_keymap[] = { · 47 unmodified lines | |||
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | static const struct key_entry intel_vbtn_switchmap[] = { | 50 | static const struct key_entry intel_vbtn_switchmap[] = { |
| 51 | { KE_SW, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ | 51 | /* |
| 52 | { KE_SW, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ | 52 | * SW_DOCK should only be reported for docking stations, but DSDTs using the |
| 53 | * intel-vbtn code, always seem to use this for 2-in-1s / convertibles and set | ||
| 54 | * SW_DOCK=1 when in laptop-mode (in tandem with setting SW_TABLET_MODE=0). | ||
| 55 | * This causes userspace to think the laptop is docked to a port-replicator | ||
| 56 | * and to disable suspend-on-lid-close, which is undesirable. | ||
| 57 | * Map the dock events to KEY_IGNORE to avoid this broken SW_DOCK reporting. | ||
| 58 | */ | ||
| 59 | { KE_IGNORE, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ | ||
| 60 | { KE_IGNORE, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ | ||
| 53 | { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ | 61 | { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ |
| 54 | { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ | 62 | { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ |
| 55 | { KE_END } | 63 | { KE_END } |
| @@ -863,34 +863,45 @@ out_unlock: · 862 unmodified lines | |||
| 863 | } | 863 | } |
| 864 | DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); | 864 | DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); |
| 865 | 865 | ||
| 866 | static ssize_t pmc_core_ltr_ignore_write(struct file *file, | 866 | static int pmc_core_send_ltr_ignore(u32 value) |
| 867 | const char __user *userbuf, | ||
| 868 | size_t count, loff_t *ppos) | ||
| 869 | { | 867 | { |
| 870 | struct pmc_dev *pmcdev = &pmc; | 868 | struct pmc_dev *pmcdev = &pmc; |
| 871 | const struct pmc_reg_map *map = pmcdev->map; | 869 | const struct pmc_reg_map *map = pmcdev->map; |
| 872 | u32 val, buf_size, fd; | 870 | u32 reg; |
| 873 | int err; | 871 | int err = 0; |
| 874 | |||
| 875 | buf_size = count < 64 ? count : 64; | ||
| 876 | |||
| 877 | err = kstrtou32_from_user(userbuf, buf_size, 10, &val); | ||
| 878 | if (err) | ||
| 879 | return err; | ||
| 880 | 872 | ||
| 881 | mutex_lock(&pmcdev->lock); | 873 | mutex_lock(&pmcdev->lock); |
| 882 | 874 | ||
| 883 | if (val > map->ltr_ignore_max) { | 875 | if (value > map->ltr_ignore_max) { |
| 884 | err = -EINVAL; | 876 | err = -EINVAL; |
| 885 | goto out_unlock; | 877 | goto out_unlock; |
| 886 | } | 878 | } |
| 887 | 879 | ||
| 888 | fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); | 880 | reg = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); |
| 889 | fd |= (1U << val); | 881 | reg |= BIT(value); |
| 890 | pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd); | 882 | pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, reg); |
| 891 | 883 | ||
| 892 | out_unlock: | 884 | out_unlock: |
| 893 | mutex_unlock(&pmcdev->lock); | 885 | mutex_unlock(&pmcdev->lock); |
| 886 | |||
| 887 | return err; | ||
| 888 | } | ||
| 889 | |||
| 890 | static ssize_t pmc_core_ltr_ignore_write(struct file *file, | ||
| 891 | const char __user *userbuf, | ||
| 892 | size_t count, loff_t *ppos) | ||
| 893 | { | ||
| 894 | u32 buf_size, value; | ||
| 895 | int err; | ||
| 896 | |||
| 897 | buf_size = min_t(u32, count, 64); | ||
| 898 | |||
| 899 | err = kstrtou32_from_user(userbuf, buf_size, 10, &value); | ||
| 900 | if (err) | ||
| 901 | return err; | ||
| 902 | |||
| 903 | err = pmc_core_send_ltr_ignore(value); | ||
| 904 | |||
| 894 | return err == 0 ? count : err; | 905 | return err == 0 ? count : err; |
| 895 | } | 906 | } |
| 896 | 907 | ||
| @@ -1244,6 +1255,15 @@ static int pmc_core_probe(struct platform_device *pdev) · 347 unmodified lines | |||
| 1244 | pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); | 1255 | pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); |
| 1245 | dmi_check_system(pmc_core_dmi_table); | 1256 | dmi_check_system(pmc_core_dmi_table); |
| 1246 | 1257 | ||
| 1258 | /* | ||
| 1259 | * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when | ||
| 1260 | * a cable is attached. Tell the PMC to ignore it. | ||
| 1261 | */ | ||
| 1262 | if (pmcdev->map == &tgl_reg_map) { | ||
| 1263 | dev_dbg(&pdev->dev, "ignoring GBE LTR\n"); | ||
| 1264 | pmc_core_send_ltr_ignore(3); | ||
| 1265 | } | ||
| 1266 | |||
| 1247 | pmc_core_dbgfs_register(pmcdev); | 1267 | pmc_core_dbgfs_register(pmcdev); |
| 1248 | 1268 | ||
| 1249 | device_initialized = true; | 1269 | device_initialized = true; |
| @@ -173,7 +173,7 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry, · 172 unmodified lines | |||
| 173 | struct intel_pmt_namespace *ns, | 173 | struct intel_pmt_namespace *ns, |
| 174 | struct device *parent) | 174 | struct device *parent) |
| 175 | { | 175 | { |
| 176 | struct resource res; | 176 | struct resource res = {0}; |
| 177 | struct device *dev; | 177 | struct device *dev; |
| 178 | int ret; | 178 | int ret; |
| 179 | 179 | ||
| @@ -23,18 +23,17 @@ · 22 unmodified lines | |||
| 23 | #define CRASH_TYPE_OOBMSM 1 | 23 | #define CRASH_TYPE_OOBMSM 1 |
| 24 | 24 | ||
| 25 | /* Control Flags */ | 25 | /* Control Flags */ |
| 26 | #define CRASHLOG_FLAG_DISABLE BIT(27) | 26 | #define CRASHLOG_FLAG_DISABLE BIT(28) |
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * Bits 28 and 29 control the state of bit 31. | 29 | * Bits 29 and 30 control the state of bit 31. |
| 30 | * | 30 | * |
| 31 | * Bit 28 will clear bit 31, if set, allowing a new crashlog to be captured. | 31 | * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured. |
| 32 | * Bit 29 will immediately trigger a crashlog to be generated, setting bit 31. | 32 | * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31. |
| 33 | * Bit 30 is read-only and reserved as 0. | ||
| 34 | * Bit 31 is the read-only status with a 1 indicating log is complete. | 33 | * Bit 31 is the read-only status with a 1 indicating log is complete. |
| 35 | */ | 34 | */ |
| 36 | #define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(28) | 35 | #define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(29) |
| 37 | #define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(29) | 36 | #define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(30) |
| 38 | #define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31) | 37 | #define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31) |
| 39 | #define CRASHLOG_FLAG_TRIGGER_MASK GENMASK(31, 28) | 38 | #define CRASHLOG_FLAG_TRIGGER_MASK GENMASK(31, 28) |
| 40 | 39 | ||
| @@ -4081,13 +4081,19 @@ static bool hotkey_notify_6xxx(const u32 hkey, · 4080 unmodified lines | |||
| 4081 | 4081 | ||
| 4082 | case TP_HKEY_EV_KEY_NUMLOCK: | 4082 | case TP_HKEY_EV_KEY_NUMLOCK: |
| 4083 | case TP_HKEY_EV_KEY_FN: | 4083 | case TP_HKEY_EV_KEY_FN: |
| 4084 | case TP_HKEY_EV_KEY_FN_ESC: | ||
| 4085 | /* key press events, we just ignore them as long as the EC | 4084 | /* key press events, we just ignore them as long as the EC |
| 4086 | * is still reporting them in the normal keyboard stream */ | 4085 | * is still reporting them in the normal keyboard stream */ |
| 4087 | *send_acpi_ev = false; | 4086 | *send_acpi_ev = false; |
| 4088 | *ignore_acpi_ev = true; | 4087 | *ignore_acpi_ev = true; |
| 4089 | return true; | 4088 | return true; |
| 4090 | 4089 | ||
| 4090 | case TP_HKEY_EV_KEY_FN_ESC: | ||
| 4091 | /* Get the media key status to foce the status LED to update */ | ||
| 4092 | acpi_evalf(hkey_handle, NULL, "GMKS", "v"); | ||
| 4093 | *send_acpi_ev = false; | ||
| 4094 | *ignore_acpi_ev = true; | ||
| 4095 | return true; | ||
| 4096 | |||
| 4091 | case TP_HKEY_EV_TABLET_CHANGED: | 4097 | case TP_HKEY_EV_TABLET_CHANGED: |
| 4092 | tpacpi_input_send_tabletsw(); | 4098 | tpacpi_input_send_tabletsw(); |
| 4093 | hotkey_tablet_mode_notify_change(); | 4099 | hotkey_tablet_mode_notify_change(); |
| @@ -9845,6 +9851,11 @@ static struct ibm_struct lcdshadow_driver_data = { · 5751 unmodified lines | |||
| 9845 | * Thinkpad sensor interfaces | 9851 | * Thinkpad sensor interfaces |
| 9846 | */ | 9852 | */ |
| 9847 | 9853 | ||
| 9854 | #define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ | ||
| 9855 | #define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */ | ||
| 9856 | #define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */ | ||
| 9857 | #define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */ | ||
| 9858 | |||
| 9848 | #define DYTC_CMD_GET 2 /* To get current IC function and mode */ | 9859 | #define DYTC_CMD_GET 2 /* To get current IC function and mode */ |
| 9849 | #define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */ | 9860 | #define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */ |
| 9850 | 9861 | ||
| @@ -9855,6 +9866,7 @@ static bool has_palmsensor; · 4 unmodified lines | |||
| 9855 | static bool has_lapsensor; | 9866 | static bool has_lapsensor; |
| 9856 | static bool palm_state; | 9867 | static bool palm_state; |
| 9857 | static bool lap_state; | 9868 | static bool lap_state; |
| 9869 | static int dytc_version; | ||
| 9858 | 9870 | ||
| 9859 | static int dytc_command(int command, int *output) | 9871 | static int dytc_command(int command, int *output) |
| 9860 | { | 9872 | { |
| @@ -9869,6 +9881,33 @@ static int dytc_command(int command, int *output) · 8 unmodified lines | |||
| 9869 | return 0; | 9881 | return 0; |
| 9870 | } | 9882 | } |
| 9871 | 9883 | ||
| 9884 | static int dytc_get_version(void) | ||
| 9885 | { | ||
| 9886 | int err, output; | ||
| 9887 | |||
| 9888 | /* Check if we've been called before - and just return cached value */ | ||
| 9889 | if (dytc_version) | ||
| 9890 | return dytc_version; | ||
| 9891 | |||
| 9892 | /* Otherwise query DYTC and extract version information */ | ||
| 9893 | err = dytc_command(DYTC_CMD_QUERY, &output); | ||
| 9894 | /* | ||
| 9895 | * If support isn't available (ENODEV) then don't return an error | ||
| 9896 | * and don't create the sysfs group | ||
| 9897 | */ | ||
| 9898 | if (err == -ENODEV) | ||
| 9899 | return 0; | ||
| 9900 | /* For all other errors we can flag the failure */ | ||
| 9901 | if (err) | ||
| 9902 | return err; | ||
| 9903 | |||
| 9904 | /* Check DYTC is enabled and supports mode setting */ | ||
| 9905 | if (output & BIT(DYTC_QUERY_ENABLE_BIT)) | ||
| 9906 | dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; | ||
| 9907 | |||
| 9908 | return 0; | ||
| 9909 | } | ||
| 9910 | |||
| 9872 | static int lapsensor_get(bool *present, bool *state) | 9911 | static int lapsensor_get(bool *present, bool *state) |
| 9873 | { | 9912 | { |
| 9874 | int output, err; | 9913 | int output, err; |
| @@ -9974,7 +10013,18 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) · 99 unmodified lines | |||
| 9974 | if (err) | 10013 | if (err) |
| 9975 | return err; | 10014 | return err; |
| 9976 | } | 10015 | } |
| 9977 | if (has_lapsensor) { | 10016 | |
| 10017 | /* Check if we know the DYTC version, if we don't then get it */ | ||
| 10018 | if (!dytc_version) { | ||
| 10019 | err = dytc_get_version(); | ||
| 10020 | if (err) | ||
| 10021 | return err; | ||
| 10022 | } | ||
| 10023 | /* | ||
| 10024 | * Platforms before DYTC version 5 claim to have a lap sensor, but it doesn't work, so we | ||
| 10025 | * ignore them | ||
| 10026 | */ | ||
| 10027 | if (has_lapsensor && (dytc_version >= 5)) { | ||
| 9978 | err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); | 10028 | err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); |
| 9979 | if (err) | 10029 | if (err) |
| 9980 | return err; | 10030 | return err; |
| @@ -9999,14 +10049,9 @@ static struct ibm_struct proxsensor_driver_data = { · 18 unmodified lines | |||
| 9999 | * DYTC Platform Profile interface | 10049 | * DYTC Platform Profile interface |
| 10000 | */ | 10050 | */ |
| 10001 | 10051 | ||
| 10002 | #define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ | ||
| 10003 | #define DYTC_CMD_SET 1 /* To enable/disable IC function mode */ | 10052 | #define DYTC_CMD_SET 1 /* To enable/disable IC function mode */ |
| 10004 | #define DYTC_CMD_RESET 0x1ff /* To reset back to default */ | 10053 | #define DYTC_CMD_RESET 0x1ff /* To reset back to default */ |
| 10005 | 10054 | ||
| 10006 | #define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */ | ||
| 10007 | #define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */ | ||
| 10008 | #define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */ | ||
| 10009 | |||
| 10010 | #define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */ | 10055 | #define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */ |
| 10011 | #define DYTC_GET_MODE_BIT 12 /* Bits 12-15 - mode setting */ | 10056 | #define DYTC_GET_MODE_BIT 12 /* Bits 12-15 - mode setting */ |
| 10012 | 10057 | ||
| @@ -10142,8 +10187,13 @@ static int dytc_profile_set(struct platform_profile_handler *pprof, · 129 unmodified lines | |||
| 10142 | return err; | 10187 | return err; |
| 10143 | 10188 | ||
| 10144 | if (profile == PLATFORM_PROFILE_BALANCED) { | 10189 | if (profile == PLATFORM_PROFILE_BALANCED) { |
| 10145 | /* To get back to balanced mode we just issue a reset command */ | 10190 | /* |
| 10146 | err = dytc_command(DYTC_CMD_RESET, &output); | 10191 | * To get back to balanced mode we need to issue a reset command. |
| 10192 | * Note we still need to disable CQL mode before hand and re-enable | ||
| 10193 | * it afterwards, otherwise dytc_lapmode gets reset to 0 and stays | ||
| 10194 | * stuck at 0 for aprox. 30 minutes. | ||
| 10195 | */ | ||
| 10196 | err = dytc_cql_command(DYTC_CMD_RESET, &output); | ||
| 10147 | if (err) | 10197 | if (err) |
| 10148 | goto unlock; | 10198 | goto unlock; |
| 10149 | } else { | 10199 | } else { |
| @@ -10211,28 +10261,28 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) · 61 unmodified lines | |||
| 10211 | if (err) | 10261 | if (err) |
| 10212 | return err; | 10262 | return err; |
| 10213 | 10263 | ||
| 10264 | /* Check if we know the DYTC version, if we don't then get it */ | ||
| 10265 | if (!dytc_version) { | ||
| 10266 | err = dytc_get_version(); | ||
| 10267 | if (err) | ||
| 10268 | return err; | ||
| 10269 | } | ||
| 10214 | /* Check DYTC is enabled and supports mode setting */ | 10270 | /* Check DYTC is enabled and supports mode setting */ |
| 10215 | if (output & BIT(DYTC_QUERY_ENABLE_BIT)) { | 10271 | if (dytc_version >= 5) { |
| 10216 | /* Only DYTC v5.0 and later has this feature. */ | 10272 | dbg_printk(TPACPI_DBG_INIT, |
| 10217 | int dytc_version; | 10273 | "DYTC version %d: thermal mode available\n", dytc_version); |
| 10218 | 10274 | /* Create platform_profile structure and register */ | |
| 10219 | dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; | 10275 | err = platform_profile_register(&dytc_profile); |
| 10220 | if (dytc_version >= 5) { | 10276 | /* |
| 10221 | dbg_printk(TPACPI_DBG_INIT, | 10277 | * If for some reason platform_profiles aren't enabled |
| 10222 | "DYTC version %d: thermal mode available\n", dytc_version); | 10278 | * don't quit terminally. |
| 10223 | /* Create platform_profile structure and register */ | 10279 | */ |
| 10224 | err = platform_profile_register(&dytc_profile); | 10280 | if (err) |
| 10225 | /* | 10281 | return 0; |
| 10226 | * If for some reason platform_profiles aren't enabled | ||
| 10227 | * don't quit terminally. | ||
| 10228 | */ | ||
| 10229 | if (err) | ||
| 10230 | return 0; | ||
| 10231 | 10282 | ||
| 10232 | dytc_profile_available = true; | 10283 | dytc_profile_available = true; |
| 10233 | /* Ensure initial values are correct */ | 10284 | /* Ensure initial values are correct */ |
| 10234 | dytc_profile_refresh(); | 10285 | dytc_profile_refresh(); |
| 10235 | } | ||
| 10236 | } | 10286 | } |
| 10237 | return 0; | 10287 | return 0; |
| 10238 | } | 10288 | } |
| @@ -189,15 +189,16 @@ int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) · 188 unmodified lines | |||
| 189 | tmr_add = ptp_qoriq->tmr_add; | 189 | tmr_add = ptp_qoriq->tmr_add; |
| 190 | adj = tmr_add; | 190 | adj = tmr_add; |
| 191 | 191 | ||
| 192 | /* calculate diff as adj*(scaled_ppm/65536)/1000000 | 192 | /* |
| 193 | * and round() to the nearest integer | 193 | * Calculate diff and round() to the nearest integer |
| 194 | * | ||
| 195 | * diff = adj * (ppb / 1000000000) | ||
| 196 | * = adj * scaled_ppm / 65536000000 | ||
| 194 | */ | 197 | */ |
| 195 | adj *= scaled_ppm; | 198 | diff = mul_u64_u64_div_u64(adj, scaled_ppm, 32768000000); |
| 196 | diff = div_u64(adj, 8000000); | 199 | diff = DIV64_U64_ROUND_UP(diff, 2); |
| 197 | diff = (diff >> 13) + ((diff >> 12) & 1); | ||
| 198 | 200 | ||
| 199 | tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; | 201 | tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; |
| 200 | |||
| 201 | ptp_qoriq->write(®s->ctrl_regs->tmr_add, tmr_add); | 202 | ptp_qoriq->write(®s->ctrl_regs->tmr_add, tmr_add); |
| 202 | 203 | ||
| 203 | return 0; | 204 | return 0; |
| @@ -41,7 +41,7 @@ struct mt6315_chip { · 40 unmodified lines | |||
| 41 | .type = REGULATOR_VOLTAGE, \ | 41 | .type = REGULATOR_VOLTAGE, \ |
| 42 | .id = _bid, \ | 42 | .id = _bid, \ |
| 43 | .owner = THIS_MODULE, \ | 43 | .owner = THIS_MODULE, \ |
| 44 | .n_voltages = 0xbf, \ | 44 | .n_voltages = 0xc0, \ |
| 45 | .linear_ranges = mt_volt_range1, \ | 45 | .linear_ranges = mt_volt_range1, \ |
| 46 | .n_linear_ranges = ARRAY_SIZE(mt_volt_range1), \ | 46 | .n_linear_ranges = ARRAY_SIZE(mt_volt_range1), \ |
| 47 | .vsel_reg = _vsel, \ | 47 | .vsel_reg = _vsel, \ |
| @@ -69,7 +69,7 @@ static unsigned int mt6315_map_mode(u32 mode) · 21 unmodified lines | |||
| 69 | case MT6315_BUCK_MODE_LP: | 69 | case MT6315_BUCK_MODE_LP: |
| 70 | return REGULATOR_MODE_IDLE; | 70 | return REGULATOR_MODE_IDLE; |
| 71 | default: | 71 | default: |
| 72 | return -EINVAL; | 72 | return REGULATOR_MODE_INVALID; |
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | 75 | ||
| @@ -797,6 +797,14 @@ static int pca9450_i2c_probe(struct i2c_client *i2c, · 796 unmodified lines | |||
| 797 | return ret; | 797 | return ret; |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | /* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */ | ||
| 801 | ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS, | ||
| 802 | BUCK123_PRESET_EN); | ||
| 803 | if (ret) { | ||
| 804 | dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret); | ||
| 805 | return ret; | ||
| 806 | } | ||
| 807 | |||
| 800 | /* Set reset behavior on assertion of WDOG_B signal */ | 808 | /* Set reset behavior on assertion of WDOG_B signal */ |
| 801 | ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL, | 809 | ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL, |
| 802 | WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12); | 810 | WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12); |
| @@ -814,7 +822,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c, · 11 unmodified lines | |||
| 814 | 822 | ||
| 815 | if (IS_ERR(pca9450->sd_vsel_gpio)) { | 823 | if (IS_ERR(pca9450->sd_vsel_gpio)) { |
| 816 | dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); | 824 | dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); |
| 817 | return ret; | 825 | return PTR_ERR(pca9450->sd_vsel_gpio); |
| 818 | } | 826 | } |
| 819 | 827 | ||
| 820 | dev_info(&i2c->dev, "%s probed.\n", | 828 | dev_info(&i2c->dev, "%s probed.\n", |
| @@ -726,8 +726,8 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = { · 725 unmodified lines | |||
| 726 | static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { | 726 | static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { |
| 727 | .regulator_type = VRM, | 727 | .regulator_type = VRM, |
| 728 | .ops = &rpmh_regulator_vrm_ops, | 728 | .ops = &rpmh_regulator_vrm_ops, |
| 729 | .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 16000), | 729 | .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000), |
| 730 | .n_voltages = 5, | 730 | .n_voltages = 236, |
| 731 | .pmic_mode_map = pmic_mode_map_pmic5_smps, | 731 | .pmic_mode_map = pmic_mode_map_pmic5_smps, |
| 732 | .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, | 732 | .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, |
| 733 | }; | 733 | }; |
| @@ -901,7 +901,7 @@ static const struct rpmh_vreg_init_data pm8350_vreg_data[] = { · 167 unmodified lines | |||
| 901 | }; | 901 | }; |
| 902 | 902 | ||
| 903 | static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = { | 903 | static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = { |
| 904 | RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"), | 904 | RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps515, "vdd-s1"), |
| 905 | RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), | 905 | RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"), |
| 906 | RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), | 906 | RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"), |
| 907 | RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"), | 907 | RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"), |
| @@ -153,9 +153,9 @@ static int rt4831_regulator_probe(struct platform_device *pdev) · 152 unmodified lines | |||
| 153 | int i, ret; | 153 | int i, ret; |
| 154 | 154 | ||
| 155 | regmap = dev_get_regmap(pdev->dev.parent, NULL); | 155 | regmap = dev_get_regmap(pdev->dev.parent, NULL); |
| 156 | if (IS_ERR(regmap)) { | 156 | if (!regmap) { |
| 157 | dev_err(&pdev->dev, "Failed to init regmap\n"); | 157 | dev_err(&pdev->dev, "Failed to init regmap\n"); |
| 158 | return PTR_ERR(regmap); | 158 | return -ENODEV; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | /* Configure DSV mode to normal by default */ | 161 | /* Configure DSV mode to normal by default */ |
| @@ -63,7 +63,6 @@ void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); · 62 unmodified lines | |||
| 63 | MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>"); | 63 | MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>"); |
| 64 | MODULE_DESCRIPTION("Linux on S/390 DASD device driver," | 64 | MODULE_DESCRIPTION("Linux on S/390 DASD device driver," |
| 65 | " Copyright IBM Corp. 2000"); | 65 | " Copyright IBM Corp. 2000"); |
| 66 | MODULE_SUPPORTED_DEVICE("dasd"); | ||
| 67 | MODULE_LICENSE("GPL"); | 66 | MODULE_LICENSE("GPL"); |
| 68 | 67 | ||
| 69 | /* | 68 | /* |
| @@ -3052,7 +3051,8 @@ static blk_status_t do_dasd_request(struct blk_mq_hw_ctx *hctx, · 2982 unmodified lines | |||
| 3052 | 3051 | ||
| 3053 | basedev = block->base; | 3052 | basedev = block->base; |
| 3054 | spin_lock_irq(&dq->lock); | 3053 | spin_lock_irq(&dq->lock); |
| 3055 | if (basedev->state < DASD_STATE_READY) { | 3054 | if (basedev->state < DASD_STATE_READY || |
| 3055 | test_bit(DASD_FLAG_OFFLINE, &basedev->flags)) { | ||
| 3056 | DBF_DEV_EVENT(DBF_ERR, basedev, | 3056 | DBF_DEV_EVENT(DBF_ERR, basedev, |
| 3057 | "device not ready for request %p", req); | 3057 | "device not ready for request %p", req); |
| 3058 | rc = BLK_STS_IOERR; | 3058 | rc = BLK_STS_IOERR; |
| @@ -3487,8 +3487,6 @@ void dasd_generic_remove(struct ccw_device *cdev) · 428 unmodified lines | |||
| 3487 | struct dasd_device *device; | 3487 | struct dasd_device *device; |
| 3488 | struct dasd_block *block; | 3488 | struct dasd_block *block; |
| 3489 | 3489 | ||
| 3490 | cdev->handler = NULL; | ||
| 3491 | |||
| 3492 | device = dasd_device_from_cdev(cdev); | 3490 | device = dasd_device_from_cdev(cdev); |
| 3493 | if (IS_ERR(device)) { | 3491 | if (IS_ERR(device)) { |
| 3494 | dasd_remove_sysfs_files(cdev); | 3492 | dasd_remove_sysfs_files(cdev); |
| @@ -3507,6 +3505,7 @@ void dasd_generic_remove(struct ccw_device *cdev) · 12 unmodified lines | |||
| 3507 | * no quite down yet. | 3505 | * no quite down yet. |
| 3508 | */ | 3506 | */ |
| 3509 | dasd_set_target_state(device, DASD_STATE_NEW); | 3507 | dasd_set_target_state(device, DASD_STATE_NEW); |
| 3508 | cdev->handler = NULL; | ||
| 3510 | /* dasd_delete_device destroys the device reference. */ | 3509 | /* dasd_delete_device destroys the device reference. */ |
| 3511 | block = device->block; | 3510 | block = device->block; |
| 3512 | dasd_delete_device(device); | 3511 | dasd_delete_device(device); |
| @@ -424,8 +424,10 @@ tty3270_update(struct timer_list *t) · 423 unmodified lines | |||
| 424 | * last output position matches the start address | 424 | * last output position matches the start address |
| 425 | * of this line. | 425 | * of this line. |
| 426 | */ | 426 | */ |
| 427 | if (s->string[1] == sba[0] && s->string[2] == sba[1]) | 427 | if (s->string[1] == sba[0] && s->string[2] == sba[1]) { |
| 428 | str += 3, len -= 3; | 428 | str += 3; |
| 429 | len -= 3; | ||
| 430 | } | ||
| 429 | if (raw3270_request_add_data(wrq, str, len) != 0) | 431 | if (raw3270_request_add_data(wrq, str, len) != 0) |
| 430 | break; | 432 | break; |
| 431 | list_del_init(&s->update); | 433 | list_del_init(&s->update); |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
| 18 | #include <linux/reboot.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/asm-offsets.h> | 20 | #include <asm/asm-offsets.h> |
| 20 | #include <asm/ipl.h> | 21 | #include <asm/ipl.h> |
| @@ -238,6 +239,28 @@ static int __init zcore_reipl_init(void) · 217 unmodified lines | |||
| 238 | return 0; | 239 | return 0; |
| 239 | } | 240 | } |
| 240 | 241 | ||
| 242 | static int zcore_reboot_and_on_panic_handler(struct notifier_block *self, | ||
| 243 | unsigned long event, | ||
| 244 | void *data) | ||
| 245 | { | ||
| 246 | if (hsa_available) | ||
| 247 | release_hsa(); | ||
| 248 | |||
| 249 | return NOTIFY_OK; | ||
| 250 | } | ||
| 251 | |||
| 252 | static struct notifier_block zcore_reboot_notifier = { | ||
| 253 | .notifier_call = zcore_reboot_and_on_panic_handler, | ||
| 254 | /* we need to be notified before reipl and kdump */ | ||
| 255 | .priority = INT_MAX, | ||
| 256 | }; | ||
| 257 | |||
| 258 | static struct notifier_block zcore_on_panic_notifier = { | ||
| 259 | .notifier_call = zcore_reboot_and_on_panic_handler, | ||
| 260 | /* we need to be notified before reipl and kdump */ | ||
| 261 | .priority = INT_MAX, | ||
| 262 | }; | ||
| 263 | |||
| 241 | static int __init zcore_init(void) | 264 | static int __init zcore_init(void) |
| 242 | { | 265 | { |
| 243 | unsigned char arch; | 266 | unsigned char arch; |
| @@ -293,28 +316,15 @@ static int __init zcore_init(void) · 49 unmodified lines | |||
| 293 | goto fail; | 316 | goto fail; |
| 294 | 317 | ||
| 295 | zcore_dir = debugfs_create_dir("zcore" , NULL); | 318 | zcore_dir = debugfs_create_dir("zcore" , NULL); |
| 296 | if (!zcore_dir) { | ||
| 297 | rc = -ENOMEM; | ||
| 298 | goto fail; | ||
| 299 | } | ||
| 300 | zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, | 319 | zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, |
| 301 | NULL, &zcore_reipl_fops); | 320 | NULL, &zcore_reipl_fops); |
| 302 | if (!zcore_reipl_file) { | ||
| 303 | rc = -ENOMEM; | ||
| 304 | goto fail_dir; | ||
| 305 | } | ||
| 306 | zcore_hsa_file = debugfs_create_file("hsa", S_IRUSR|S_IWUSR, zcore_dir, | 321 | zcore_hsa_file = debugfs_create_file("hsa", S_IRUSR|S_IWUSR, zcore_dir, |
| 307 | NULL, &zcore_hsa_fops); | 322 | NULL, &zcore_hsa_fops); |
| 308 | if (!zcore_hsa_file) { | ||
| 309 | rc = -ENOMEM; | ||
| 310 | goto fail_reipl_file; | ||
| 311 | } | ||
| 312 | return 0; | ||
| 313 | 323 | ||
| 314 | fail_reipl_file: | 324 | register_reboot_notifier(&zcore_reboot_notifier); |
| 315 | debugfs_remove(zcore_reipl_file); | 325 | atomic_notifier_chain_register(&panic_notifier_list, &zcore_on_panic_notifier); |
| 316 | fail_dir: | 326 | |
| 317 | debugfs_remove(zcore_dir); | 327 | return 0; |
| 318 | fail: | 328 | fail: |
| 319 | diag308(DIAG308_REL_HSA, NULL); | 329 | diag308(DIAG308_REL_HSA, NULL); |
| 320 | return rc; | 330 | return rc; |
| @@ -47,7 +47,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) · 46 unmodified lines | |||
| 47 | orb = &private->orb; | 47 | orb = &private->orb; |
| 48 | cc = stsch(sch->schid, &schib); | 48 | cc = stsch(sch->schid, &schib); |
| 49 | 49 | ||
| 50 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " | 50 | printk(KERN_WARNING "cio: ccw device timeout occurred at %lx, " |
| 51 | "device information:\n", get_tod_clock()); | 51 | "device information:\n", get_tod_clock()); |
| 52 | printk(KERN_WARNING "cio: orb:\n"); | 52 | printk(KERN_WARNING "cio: orb:\n"); |
| 53 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | 53 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, |
| @@ -543,7 +543,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, · 542 unmodified lines | |||
| 543 | if (ret) | 543 | if (ret) |
| 544 | return ret; | 544 | return ret; |
| 545 | 545 | ||
| 546 | return copy_to_user((void __user *)arg, &info, minsz); | 546 | return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; |
| 547 | } | 547 | } |
| 548 | case VFIO_DEVICE_GET_REGION_INFO: | 548 | case VFIO_DEVICE_GET_REGION_INFO: |
| 549 | { | 549 | { |
| @@ -561,7 +561,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, · 11 unmodified lines | |||
| 561 | if (ret) | 561 | if (ret) |
| 562 | return ret; | 562 | return ret; |
| 563 | 563 | ||
| 564 | return copy_to_user((void __user *)arg, &info, minsz); | 564 | return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; |
| 565 | } | 565 | } |
| 566 | case VFIO_DEVICE_GET_IRQ_INFO: | 566 | case VFIO_DEVICE_GET_IRQ_INFO: |
| 567 | { | 567 | { |
| @@ -582,7 +582,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, · 14 unmodified lines | |||
| 582 | if (info.count == -1) | 582 | if (info.count == -1) |
| 583 | return -EINVAL; | 583 | return -EINVAL; |
| 584 | 584 | ||
| 585 | return copy_to_user((void __user *)arg, &info, minsz); | 585 | return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; |
| 586 | } | 586 | } |
| 587 | case VFIO_DEVICE_SET_IRQS: | 587 | case VFIO_DEVICE_SET_IRQS: |
| 588 | { | 588 | { |
| @@ -1286,7 +1286,7 @@ static int vfio_ap_mdev_get_device_info(unsigned long arg) · 1285 unmodified lines | |||
| 1286 | info.num_regions = 0; | 1286 | info.num_regions = 0; |
| 1287 | info.num_irqs = 0; | 1287 | info.num_irqs = 0; |
| 1288 | 1288 | ||
| 1289 | return copy_to_user((void __user *)arg, &info, minsz); | 1289 | return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; |
| 1290 | } | 1290 | } |
| 1291 | 1291 | ||
| 1292 | static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev, | 1292 | static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev, |
| @@ -50,7 +50,6 @@ MODULE_PARM_DESC(sol_compat, · 49 unmodified lines | |||
| 50 | MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); | 50 | MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); |
| 51 | MODULE_DESCRIPTION("7-Segment Display driver for Sun Microsystems CP1400/1500"); | 51 | MODULE_DESCRIPTION("7-Segment Display driver for Sun Microsystems CP1400/1500"); |
| 52 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
| 53 | MODULE_SUPPORTED_DEVICE("d7s"); | ||
| 54 | 53 | ||
| 55 | struct d7s { | 54 | struct d7s { |
| 56 | void __iomem *regs; | 55 | void __iomem *regs; |
| @@ -80,7 +80,6 @@ · 79 unmodified lines | |||
| 80 | MODULE_AUTHOR("Hewlett-Packard Company"); | 80 | MODULE_AUTHOR("Hewlett-Packard Company"); |
| 81 | MODULE_DESCRIPTION("Driver for HP Smart Array Controller version " \ | 81 | MODULE_DESCRIPTION("Driver for HP Smart Array Controller version " \ |
| 82 | HPSA_DRIVER_VERSION); | 82 | HPSA_DRIVER_VERSION); |
| 83 | MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers"); | ||
| 84 | MODULE_VERSION(HPSA_DRIVER_VERSION); | 83 | MODULE_VERSION(HPSA_DRIVER_VERSION); |
| 85 | MODULE_LICENSE("GPL"); | 84 | MODULE_LICENSE("GPL"); |
| 86 | MODULE_ALIAS("cciss"); | 85 | MODULE_ALIAS("cciss"); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/bsg-lib.h> | 21 | #include <linux/bsg-lib.h> |
| 22 | #include <asm/firmware.h> | 22 | #include <asm/firmware.h> |
| 23 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
| 24 | #include <asm/rtas.h> | ||
| 24 | #include <asm/vio.h> | 25 | #include <asm/vio.h> |
| 25 | #include <scsi/scsi.h> | 26 | #include <scsi/scsi.h> |
| 26 | #include <scsi/scsi_cmnd.h> | 27 | #include <scsi/scsi_cmnd.h> |
| @@ -158,6 +159,9 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *); · 131 unmodified lines | |||
| 158 | static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *); | 159 | static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *); |
| 159 | static void ibmvfc_tgt_move_login(struct ibmvfc_target *); | 160 | static void ibmvfc_tgt_move_login(struct ibmvfc_target *); |
| 160 | 161 | ||
| 162 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *); | ||
| 163 | static void ibmvfc_init_sub_crqs(struct ibmvfc_host *); | ||
| 164 | |||
| 161 | static const char *unknown_error = "unknown error"; | 165 | static const char *unknown_error = "unknown error"; |
| 162 | 166 | ||
| 163 | static long h_reg_sub_crq(unsigned long unit_address, unsigned long ioba, | 167 | static long h_reg_sub_crq(unsigned long unit_address, unsigned long ioba, |
| @@ -899,6 +903,9 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) · 735 unmodified lines | |||
| 899 | { | 903 | { |
| 900 | int rc = 0; | 904 | int rc = 0; |
| 901 | struct vio_dev *vdev = to_vio_dev(vhost->dev); | 905 | struct vio_dev *vdev = to_vio_dev(vhost->dev); |
| 906 | unsigned long flags; | ||
| 907 | |||
| 908 | ibmvfc_release_sub_crqs(vhost); | ||
| 902 | 909 | ||
| 903 | /* Re-enable the CRQ */ | 910 | /* Re-enable the CRQ */ |
| 904 | do { | 911 | do { |
| @@ -910,6 +917,15 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) · 5 unmodified lines | |||
| 910 | if (rc) | 917 | if (rc) |
| 911 | dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc); | 918 | dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc); |
| 912 | 919 | ||
| 920 | spin_lock_irqsave(vhost->host->host_lock, flags); | ||
| 921 | spin_lock(vhost->crq.q_lock); | ||
| 922 | vhost->do_enquiry = 1; | ||
| 923 | vhost->using_channels = 0; | ||
| 924 | spin_unlock(vhost->crq.q_lock); | ||
| 925 | spin_unlock_irqrestore(vhost->host->host_lock, flags); | ||
| 926 | |||
| 927 | ibmvfc_init_sub_crqs(vhost); | ||
| 928 | |||
| 913 | return rc; | 929 | return rc; |
| 914 | } | 930 | } |
| 915 | 931 | ||
| @@ -926,8 +942,8 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 10 unmodified lines | |||
| 926 | unsigned long flags; | 942 | unsigned long flags; |
| 927 | struct vio_dev *vdev = to_vio_dev(vhost->dev); | 943 | struct vio_dev *vdev = to_vio_dev(vhost->dev); |
| 928 | struct ibmvfc_queue *crq = &vhost->crq; | 944 | struct ibmvfc_queue *crq = &vhost->crq; |
| 929 | struct ibmvfc_queue *scrq; | 945 | |
| 930 | int i; | 946 | ibmvfc_release_sub_crqs(vhost); |
| 931 | 947 | ||
| 932 | /* Close the CRQ */ | 948 | /* Close the CRQ */ |
| 933 | do { | 949 | do { |
| @@ -947,16 +963,6 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 13 unmodified lines | |||
| 947 | memset(crq->msgs.crq, 0, PAGE_SIZE); | 963 | memset(crq->msgs.crq, 0, PAGE_SIZE); |
| 948 | crq->cur = 0; | 964 | crq->cur = 0; |
| 949 | 965 | ||
| 950 | if (vhost->scsi_scrqs.scrqs) { | ||
| 951 | for (i = 0; i < nr_scsi_hw_queues; i++) { | ||
| 952 | scrq = &vhost->scsi_scrqs.scrqs[i]; | ||
| 953 | spin_lock(scrq->q_lock); | ||
| 954 | memset(scrq->msgs.scrq, 0, PAGE_SIZE); | ||
| 955 | scrq->cur = 0; | ||
| 956 | spin_unlock(scrq->q_lock); | ||
| 957 | } | ||
| 958 | } | ||
| 959 | |||
| 960 | /* And re-open it again */ | 966 | /* And re-open it again */ |
| 961 | rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, | 967 | rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, |
| 962 | crq->msg_token, PAGE_SIZE); | 968 | crq->msg_token, PAGE_SIZE); |
| @@ -966,9 +972,12 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) · 3 unmodified lines | |||
| 966 | dev_warn(vhost->dev, "Partner adapter not ready\n"); | 972 | dev_warn(vhost->dev, "Partner adapter not ready\n"); |
| 967 | else if (rc != 0) | 973 | else if (rc != 0) |
| 968 | dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc); | 974 | dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc); |
| 975 | |||
| 969 | spin_unlock(vhost->crq.q_lock); | 976 | spin_unlock(vhost->crq.q_lock); |
| 970 | spin_unlock_irqrestore(vhost->host->host_lock, flags); | 977 | spin_unlock_irqrestore(vhost->host->host_lock, flags); |
| 971 | 978 | ||
| 979 | ibmvfc_init_sub_crqs(vhost); | ||
| 980 | |||
| 972 | return rc; | 981 | return rc; |
| 973 | } | 982 | } |
| 974 | 983 | ||
| @@ -5642,7 +5651,8 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, · 4667 unmodified lines | |||
| 5642 | rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE, | 5651 | rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE, |
| 5643 | &scrq->cookie, &scrq->hw_irq); | 5652 | &scrq->cookie, &scrq->hw_irq); |
| 5644 | 5653 | ||
| 5645 | if (rc) { | 5654 | /* H_CLOSED indicates successful register, but no CRQ partner */ |
| 5655 | if (rc && rc != H_CLOSED) { | ||
| 5646 | dev_warn(dev, "Error registering sub-crq: %d\n", rc); | 5656 | dev_warn(dev, "Error registering sub-crq: %d\n", rc); |
| 5647 | if (rc == H_PARAMETER) | 5657 | if (rc == H_PARAMETER) |
| 5648 | dev_warn_once(dev, "Firmware may not support MQ\n"); | 5658 | dev_warn_once(dev, "Firmware may not support MQ\n"); |
| @@ -5675,8 +5685,8 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, · 26 unmodified lines | |||
| 5675 | 5685 | ||
| 5676 | irq_failed: | 5686 | irq_failed: |
| 5677 | do { | 5687 | do { |
| 5678 | plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); | 5688 | rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); |
| 5679 | } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); | 5689 | } while (rtas_busy_delay(rc)); |
| 5680 | reg_failed: | 5690 | reg_failed: |
| 5681 | ibmvfc_free_queue(vhost, scrq); | 5691 | ibmvfc_free_queue(vhost, scrq); |
| 5682 | LEAVE; | 5692 | LEAVE; |
| @@ -5694,6 +5704,7 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index) · 11 unmodified lines | |||
| 5694 | 5704 | ||
| 5695 | free_irq(scrq->irq, scrq); | 5705 | free_irq(scrq->irq, scrq); |
| 5696 | irq_dispose_mapping(scrq->irq); | 5706 | irq_dispose_mapping(scrq->irq); |
| 5707 | scrq->irq = 0; | ||
| 5697 | 5708 | ||
| 5698 | do { | 5709 | do { |
| 5699 | rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, | 5710 | rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, |
| @@ -5707,17 +5718,21 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index) · 7 unmodified lines | |||
| 5707 | LEAVE; | 5718 | LEAVE; |
| 5708 | } | 5719 | } |
| 5709 | 5720 | ||
| 5710 | static int ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) | 5721 | static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) |
| 5711 | { | 5722 | { |
| 5712 | int i, j; | 5723 | int i, j; |
| 5713 | 5724 | ||
| 5714 | ENTER; | 5725 | ENTER; |
| 5726 | if (!vhost->mq_enabled) | ||
| 5727 | return; | ||
| 5715 | 5728 | ||
| 5716 | vhost->scsi_scrqs.scrqs = kcalloc(nr_scsi_hw_queues, | 5729 | vhost->scsi_scrqs.scrqs = kcalloc(nr_scsi_hw_queues, |
| 5717 | sizeof(*vhost->scsi_scrqs.scrqs), | 5730 | sizeof(*vhost->scsi_scrqs.scrqs), |
| 5718 | GFP_KERNEL); | 5731 | GFP_KERNEL); |
| 5719 | if (!vhost->scsi_scrqs.scrqs) | 5732 | if (!vhost->scsi_scrqs.scrqs) { |
| 5720 | return -1; | 5733 | vhost->do_enquiry = 0; |
| 5734 | return; | ||
| 5735 | } | ||
| 5721 | 5736 | ||
| 5722 | for (i = 0; i < nr_scsi_hw_queues; i++) { | 5737 | for (i = 0; i < nr_scsi_hw_queues; i++) { |
| 5723 | if (ibmvfc_register_scsi_channel(vhost, i)) { | 5738 | if (ibmvfc_register_scsi_channel(vhost, i)) { |
| @@ -5726,13 +5741,12 @@ static int ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) · 2 unmodified lines | |||
| 5726 | kfree(vhost->scsi_scrqs.scrqs); | 5741 | kfree(vhost->scsi_scrqs.scrqs); |
| 5727 | vhost->scsi_scrqs.scrqs = NULL; | 5742 | vhost->scsi_scrqs.scrqs = NULL; |
| 5728 | vhost->scsi_scrqs.active_queues = 0; | 5743 | vhost->scsi_scrqs.active_queues = 0; |
| 5729 | LEAVE; | 5744 | vhost->do_enquiry = 0; |
| 5730 | return -1; | 5745 | break; |
| 5731 | } | 5746 | } |
| 5732 | } | 5747 | } |
| 5733 | 5748 | ||
| 5734 | LEAVE; | 5749 | LEAVE; |
| 5735 | return 0; | ||
| 5736 | } | 5750 | } |
| 5737 | 5751 | ||
| 5738 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost) | 5752 | static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost) |
| @@ -5770,6 +5784,8 @@ static void ibmvfc_free_mem(struct ibmvfc_host *vhost) · 31 unmodified lines | |||
| 5770 | vhost->disc_buf_dma); | 5784 | vhost->disc_buf_dma); |
| 5771 | dma_free_coherent(vhost->dev, sizeof(*vhost->login_buf), | 5785 | dma_free_coherent(vhost->dev, sizeof(*vhost->login_buf), |
| 5772 | vhost->login_buf, vhost->login_buf_dma); | 5786 | vhost->login_buf, vhost->login_buf_dma); |
| 5787 | dma_free_coherent(vhost->dev, sizeof(*vhost->channel_setup_buf), | ||
| 5788 | vhost->channel_setup_buf, vhost->channel_setup_dma); | ||
| 5773 | dma_pool_destroy(vhost->sg_pool); | 5789 | dma_pool_destroy(vhost->sg_pool); |
| 5774 | ibmvfc_free_queue(vhost, async_q); | 5790 | ibmvfc_free_queue(vhost, async_q); |
| 5775 | LEAVE; | 5791 | LEAVE; |
| @@ -5999,11 +6015,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id) · 223 unmodified lines | |||
| 5999 | goto remove_shost; | 6015 | goto remove_shost; |
| 6000 | } | 6016 | } |
| 6001 | 6017 | ||
| 6002 | if (vhost->mq_enabled) { | 6018 | ibmvfc_init_sub_crqs(vhost); |
| 6003 | rc = ibmvfc_init_sub_crqs(vhost); | ||
| 6004 | if (rc) | ||
| 6005 | dev_warn(dev, "Failed to allocate Sub-CRQs. rc=%d\n", rc); | ||
| 6006 | } | ||
| 6007 | 6019 | ||
| 6008 | if (shost_to_fc_host(shost)->rqst_q) | 6020 | if (shost_to_fc_host(shost)->rqst_q) |
| 6009 | blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1); | 6021 | blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1); |
| @@ -2421,7 +2421,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, · 2420 unmodified lines | |||
| 2421 | memset(dstbuf, 0, 33); | 2421 | memset(dstbuf, 0, 33); |
| 2422 | size = (nbytes < 32) ? nbytes : 32; | 2422 | size = (nbytes < 32) ? nbytes : 32; |
| 2423 | if (copy_from_user(dstbuf, buf, size)) | 2423 | if (copy_from_user(dstbuf, buf, size)) |
| 2424 | return 0; | 2424 | return -EFAULT; |
| 2425 | 2425 | ||
| 2426 | if (dent == phba->debug_InjErrLBA) { | 2426 | if (dent == phba->debug_InjErrLBA) { |
| 2427 | if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') && | 2427 | if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') && |
| @@ -2430,7 +2430,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, · 2 unmodified lines | |||
| 2430 | } | 2430 | } |
| 2431 | 2431 | ||
| 2432 | if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp))) | 2432 | if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp))) |
| 2433 | return 0; | 2433 | return -EINVAL; |
| 2434 | 2434 | ||
| 2435 | if (dent == phba->debug_writeGuard) | 2435 | if (dent == phba->debug_writeGuard) |
| 2436 | phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp; | 2436 | phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp; |
| @@ -413,7 +413,7 @@ mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, · 412 unmodified lines | |||
| 413 | * And add this object to port_table_list. | 413 | * And add this object to port_table_list. |
| 414 | */ | 414 | */ |
| 415 | if (!ioc->multipath_on_hba) { | 415 | if (!ioc->multipath_on_hba) { |
| 416 | port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); | 416 | port = kzalloc(sizeof(struct hba_port), GFP_ATOMIC); |
| 417 | if (!port) | 417 | if (!port) |
| 418 | return NULL; | 418 | return NULL; |
| 419 | 419 | ||
| @@ -2273,12 +2273,12 @@ static void myrs_cleanup(struct myrs_hba *cs) · 2272 unmodified lines | |||
| 2273 | if (cs->mmio_base) { | 2273 | if (cs->mmio_base) { |
| 2274 | cs->disable_intr(cs); | 2274 | cs->disable_intr(cs); |
| 2275 | iounmap(cs->mmio_base); | 2275 | iounmap(cs->mmio_base); |
| 2276 | cs->mmio_base = NULL; | ||
| 2276 | } | 2277 | } |
| 2277 | if (cs->irq) | 2278 | if (cs->irq) |
| 2278 | free_irq(cs->irq, cs); | 2279 | free_irq(cs->irq, cs); |
| 2279 | if (cs->io_addr) | 2280 | if (cs->io_addr) |
| 2280 | release_region(cs->io_addr, 0x80); | 2281 | release_region(cs->io_addr, 0x80); |
| 2281 | iounmap(cs->mmio_base); | ||
| 2282 | pci_set_drvdata(pdev, NULL); | 2282 | pci_set_drvdata(pdev, NULL); |
| 2283 | pci_disable_device(pdev); | 2283 | pci_disable_device(pdev); |
| 2284 | scsi_host_put(cs->host); | 2284 | scsi_host_put(cs->host); |
| @@ -55,7 +55,6 @@ · 54 unmodified lines | |||
| 55 | 55 | ||
| 56 | MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"); | 56 | MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"); |
| 57 | MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"); | 57 | MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"); |
| 58 | MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); | ||
| 59 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
| 60 | 59 | ||
| 61 | #include "nsp_io.h" | 60 | #include "nsp_io.h" |
| @@ -116,7 +116,6 @@ · 115 unmodified lines | |||
| 116 | (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ | 116 | (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ |
| 117 | QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) | 117 | QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) |
| 118 | #endif | 118 | #endif |
| 119 | #endif | ||
| 120 | 119 | ||
| 121 | #define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ | 120 | #define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ |
| 122 | ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ | 121 | ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ |
| @@ -244,6 +243,7 @@ struct ctio_to_2xxx { · 121 unmodified lines | |||
| 244 | #ifndef CTIO_RET_TYPE | 243 | #ifndef CTIO_RET_TYPE |
| 245 | #define CTIO_RET_TYPE 0x17 /* CTIO return entry */ | 244 | #define CTIO_RET_TYPE 0x17 /* CTIO return entry */ |
| 246 | #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ | 245 | #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ |
| 246 | #endif | ||
| 247 | 247 | ||
| 248 | struct fcp_hdr { | 248 | struct fcp_hdr { |
| 249 | uint8_t r_ctl; | 249 | uint8_t r_ctl; |
| @@ -280,27 +280,28 @@ static int sd_zbc_update_wp_offset_cb(struct blk_zone *zone, unsigned int idx, · 279 unmodified lines | |||
| 280 | static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) | 280 | static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) |
| 281 | { | 281 | { |
| 282 | struct scsi_disk *sdkp; | 282 | struct scsi_disk *sdkp; |
| 283 | unsigned long flags; | ||
| 283 | unsigned int zno; | 284 | unsigned int zno; |
| 284 | int ret; | 285 | int ret; |
| 285 | 286 | ||
| 286 | sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); | 287 | sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); |
| 287 | 288 | ||
| 288 | spin_lock_bh(&sdkp->zones_wp_offset_lock); | 289 | spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); |
| 289 | for (zno = 0; zno < sdkp->nr_zones; zno++) { | 290 | for (zno = 0; zno < sdkp->nr_zones; zno++) { |
| 290 | if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) | 291 | if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) |
| 291 | continue; | 292 | continue; |
| 292 | 293 | ||
| 293 | spin_unlock_bh(&sdkp->zones_wp_offset_lock); | 294 | spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); |
| 294 | ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, | 295 | ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, |
| 295 | SD_BUF_SIZE, | 296 | SD_BUF_SIZE, |
| 296 | zno * sdkp->zone_blocks, true); | 297 | zno * sdkp->zone_blocks, true); |
| 297 | spin_lock_bh(&sdkp->zones_wp_offset_lock); | 298 | spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); |
| 298 | if (!ret) | 299 | if (!ret) |
| 299 | sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, | 300 | sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, |
| 300 | zno, sd_zbc_update_wp_offset_cb, | 301 | zno, sd_zbc_update_wp_offset_cb, |
| 301 | sdkp); | 302 | sdkp); |
| 302 | } | 303 | } |
| 303 | spin_unlock_bh(&sdkp->zones_wp_offset_lock); | 304 | spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); |
| 304 | 305 | ||
| 305 | scsi_device_put(sdkp->device); | 306 | scsi_device_put(sdkp->device); |
| 306 | } | 307 | } |
| @@ -324,6 +325,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, · 17 unmodified lines | |||
| 324 | struct request *rq = cmd->request; | 325 | struct request *rq = cmd->request; |
| 325 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | 326 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
| 326 | unsigned int wp_offset, zno = blk_rq_zone_no(rq); | 327 | unsigned int wp_offset, zno = blk_rq_zone_no(rq); |
| 328 | unsigned long flags; | ||
| 327 | blk_status_t ret; | 329 | blk_status_t ret; |
| 328 | 330 | ||
| 329 | ret = sd_zbc_cmnd_checks(cmd); | 331 | ret = sd_zbc_cmnd_checks(cmd); |
| @@ -337,7 +339,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, · 7 unmodified lines | |||
| 337 | if (!blk_req_zone_write_trylock(rq)) | 339 | if (!blk_req_zone_write_trylock(rq)) |
| 338 | return BLK_STS_ZONE_RESOURCE; | 340 | return BLK_STS_ZONE_RESOURCE; |
| 339 | 341 | ||
| 340 | spin_lock_bh(&sdkp->zones_wp_offset_lock); | 342 | spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); |
| 341 | wp_offset = sdkp->zones_wp_offset[zno]; | 343 | wp_offset = sdkp->zones_wp_offset[zno]; |
| 342 | switch (wp_offset) { | 344 | switch (wp_offset) { |
| 343 | case SD_ZBC_INVALID_WP_OFST: | 345 | case SD_ZBC_INVALID_WP_OFST: |
| @@ -366,7 +368,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, · 22 unmodified lines | |||
| 366 | 368 | ||
| 367 | *lba += wp_offset; | 369 | *lba += wp_offset; |
| 368 | } | 370 | } |
| 369 | spin_unlock_bh(&sdkp->zones_wp_offset_lock); | 371 | spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); |
| 370 | if (ret) | 372 | if (ret) |
| 371 | blk_req_zone_write_unlock(rq); | 373 | blk_req_zone_write_unlock(rq); |
| 372 | return ret; | 374 | return ret; |
| @@ -445,6 +447,7 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd, · 72 unmodified lines | |||
| 445 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | 447 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
| 446 | unsigned int zno = blk_rq_zone_no(rq); | 448 | unsigned int zno = blk_rq_zone_no(rq); |
| 447 | enum req_opf op = req_op(rq); | 449 | enum req_opf op = req_op(rq); |
| 450 | unsigned long flags; | ||
| 448 | 451 | ||
| 449 | /* | 452 | /* |
| 450 | * If we got an error for a command that needs updating the write | 453 | * If we got an error for a command that needs updating the write |
| @@ -452,7 +455,7 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd, · 1 unmodified line | |||
| 452 | * invalid to force an update from disk the next time a zone append | 455 | * invalid to force an update from disk the next time a zone append |
| 453 | * command is issued. | 456 | * command is issued. |
| 454 | */ | 457 | */ |
| 455 | spin_lock_bh(&sdkp->zones_wp_offset_lock); | 458 | spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); |
| 456 | 459 | ||
| 457 | if (result && op != REQ_OP_ZONE_RESET_ALL) { | 460 | if (result && op != REQ_OP_ZONE_RESET_ALL) { |
| 458 | if (op == REQ_OP_ZONE_APPEND) { | 461 | if (op == REQ_OP_ZONE_APPEND) { |
| @@ -496,7 +499,7 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd, · 37 unmodified lines | |||
| 496 | } | 499 | } |
| 497 | 500 | ||
| 498 | unlock_wp_offset: | 501 | unlock_wp_offset: |
| 499 | spin_unlock_bh(&sdkp->zones_wp_offset_lock); | 502 | spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); |
| 500 | 503 | ||
| 501 | return good_bytes; | 504 | return good_bytes; |
| 502 | } | 505 | } |
| @@ -48,7 +48,6 @@ · 47 unmodified lines | |||
| 48 | MODULE_AUTHOR("Microsemi"); | 48 | MODULE_AUTHOR("Microsemi"); |
| 49 | MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version " | 49 | MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version " |
| 50 | DRIVER_VERSION); | 50 | DRIVER_VERSION); |
| 51 | MODULE_SUPPORTED_DEVICE("Microsemi Smart Family Controllers"); | ||
| 52 | MODULE_VERSION(DRIVER_VERSION); | 51 | MODULE_VERSION(DRIVER_VERSION); |
| 53 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
| 54 | 53 | ||
| @@ -1269,8 +1269,8 @@ static int st_open(struct inode *inode, struct file *filp) · 1268 unmodified lines | |||
| 1269 | spin_lock(&st_use_lock); | 1269 | spin_lock(&st_use_lock); |
| 1270 | if (STp->in_use) { | 1270 | if (STp->in_use) { |
| 1271 | spin_unlock(&st_use_lock); | 1271 | spin_unlock(&st_use_lock); |
| 1272 | scsi_tape_put(STp); | ||
| 1273 | DEBC_printk(STp, "Device already in use.\n"); | 1272 | DEBC_printk(STp, "Device already in use.\n"); |
| 1273 | scsi_tape_put(STp); | ||
| 1274 | return (-EBUSY); | 1274 | return (-EBUSY); |
| 1275 | } | 1275 | } |
| 1276 | 1276 | ||
| @@ -911,7 +911,7 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm) · 910 unmodified lines | |||
| 911 | if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc) | 911 | if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc) |
| 912 | return; | 912 | return; |
| 913 | 913 | ||
| 914 | if (lpm & !hba->vreg_info.vcc->enabled) | 914 | if (lpm && !hba->vreg_info.vcc->enabled) |
| 915 | regulator_set_mode(hba->vreg_info.vccq2->reg, | 915 | regulator_set_mode(hba->vreg_info.vccq2->reg, |
| 916 | REGULATOR_MODE_IDLE); | 916 | REGULATOR_MODE_IDLE); |
| 917 | else if (!lpm) | 917 | else if (!lpm) |
| @@ -253,12 +253,17 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba) · 252 unmodified lines | |||
| 253 | { | 253 | { |
| 254 | int ret = 0; | 254 | int ret = 0; |
| 255 | struct ufs_qcom_host *host = ufshcd_get_variant(hba); | 255 | struct ufs_qcom_host *host = ufshcd_get_variant(hba); |
| 256 | bool reenable_intr = false; | ||
| 256 | 257 | ||
| 257 | if (!host->core_reset) { | 258 | if (!host->core_reset) { |
| 258 | dev_warn(hba->dev, "%s: reset control not set\n", __func__); | 259 | dev_warn(hba->dev, "%s: reset control not set\n", __func__); |
| 259 | goto out; | 260 | goto out; |
| 260 | } | 261 | } |
| 261 | 262 | ||
| 263 | reenable_intr = hba->is_irq_enabled; | ||
| 264 | disable_irq(hba->irq); | ||
| 265 | hba->is_irq_enabled = false; | ||
| 266 | |||
| 262 | ret = reset_control_assert(host->core_reset); | 267 | ret = reset_control_assert(host->core_reset); |
| 263 | if (ret) { | 268 | if (ret) { |
| 264 | dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n", | 269 | dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n", |
| @@ -280,6 +285,11 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba) · 15 unmodified lines | |||
| 280 | 285 | ||
| 281 | usleep_range(1000, 1100); | 286 | usleep_range(1000, 1100); |
| 282 | 287 | ||
| 288 | if (reenable_intr) { | ||
| 289 | enable_irq(hba->irq); | ||
| 290 | hba->is_irq_enabled = true; | ||
| 291 | } | ||
| 292 | |||
| 283 | out: | 293 | out: |
| 284 | return ret; | 294 | return ret; |
| 285 | } | 295 | } |
| @@ -95,8 +95,6 @@ · 94 unmodified lines | |||
| 95 | 16, 4, buf, __len, false); \ | 95 | 16, 4, buf, __len, false); \ |
| 96 | } while (0) | 96 | } while (0) |
| 97 | 97 | ||
| 98 | static bool early_suspend; | ||
| 99 | |||
| 100 | int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, | 98 | int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, |
| 101 | const char *prefix) | 99 | const char *prefix) |
| 102 | { | 100 | { |
| @@ -1535,7 +1533,7 @@ static ssize_t ufshcd_clkscale_enable_show(struct device *dev, · 1432 unmodified lines | |||
| 1535 | { | 1533 | { |
| 1536 | struct ufs_hba *hba = dev_get_drvdata(dev); | 1534 | struct ufs_hba *hba = dev_get_drvdata(dev); |
| 1537 | 1535 | ||
| 1538 | return snprintf(buf, PAGE_SIZE, "%d\n", hba->clk_scaling.is_enabled); | 1536 | return sysfs_emit(buf, "%d\n", hba->clk_scaling.is_enabled); |
| 1539 | } | 1537 | } |
| 1540 | 1538 | ||
| 1541 | static ssize_t ufshcd_clkscale_enable_store(struct device *dev, | 1539 | static ssize_t ufshcd_clkscale_enable_store(struct device *dev, |
| @@ -4987,6 +4985,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) · 3445 unmodified lines | |||
| 4987 | * UFS device needs urgent BKOPs. | 4985 | * UFS device needs urgent BKOPs. |
| 4988 | */ | 4986 | */ |
| 4989 | if (!hba->pm_op_in_progress && | 4987 | if (!hba->pm_op_in_progress && |
| 4988 | !ufshcd_eh_in_progress(hba) && | ||
| 4990 | ufshcd_is_exception_event(lrbp->ucd_rsp_ptr) && | 4989 | ufshcd_is_exception_event(lrbp->ucd_rsp_ptr) && |
| 4991 | schedule_work(&hba->eeh_work)) { | 4990 | schedule_work(&hba->eeh_work)) { |
| 4992 | /* | 4991 | /* |
| @@ -5784,13 +5783,20 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) · 791 unmodified lines | |||
| 5784 | ufshcd_suspend_clkscaling(hba); | 5783 | ufshcd_suspend_clkscaling(hba); |
| 5785 | ufshcd_clk_scaling_allow(hba, false); | 5784 | ufshcd_clk_scaling_allow(hba, false); |
| 5786 | } | 5785 | } |
| 5786 | ufshcd_scsi_block_requests(hba); | ||
| 5787 | /* Drain ufshcd_queuecommand() */ | ||
| 5788 | down_write(&hba->clk_scaling_lock); | ||
| 5789 | up_write(&hba->clk_scaling_lock); | ||
| 5790 | cancel_work_sync(&hba->eeh_work); | ||
| 5787 | } | 5791 | } |
| 5788 | 5792 | ||
| 5789 | static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) | 5793 | static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) |
| 5790 | { | 5794 | { |
| 5795 | ufshcd_scsi_unblock_requests(hba); | ||
| 5791 | ufshcd_release(hba); | 5796 | ufshcd_release(hba); |
| 5792 | if (ufshcd_is_clkscaling_supported(hba)) | 5797 | if (ufshcd_is_clkscaling_supported(hba)) |
| 5793 | ufshcd_clk_scaling_suspend(hba, false); | 5798 | ufshcd_clk_scaling_suspend(hba, false); |
| 5799 | ufshcd_clear_ua_wluns(hba); | ||
| 5794 | pm_runtime_put(hba->dev); | 5800 | pm_runtime_put(hba->dev); |
| 5795 | } | 5801 | } |
| 5796 | 5802 | ||
| @@ -5882,8 +5888,8 @@ static void ufshcd_err_handler(struct work_struct *work) · 85 unmodified lines | |||
| 5882 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 5888 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 5883 | ufshcd_err_handling_prepare(hba); | 5889 | ufshcd_err_handling_prepare(hba); |
| 5884 | spin_lock_irqsave(hba->host->host_lock, flags); | 5890 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 5885 | ufshcd_scsi_block_requests(hba); | 5891 | if (hba->ufshcd_state != UFSHCD_STATE_ERROR) |
| 5886 | hba->ufshcd_state = UFSHCD_STATE_RESET; | 5892 | hba->ufshcd_state = UFSHCD_STATE_RESET; |
| 5887 | 5893 | ||
| 5888 | /* Complete requests that have door-bell cleared by h/w */ | 5894 | /* Complete requests that have door-bell cleared by h/w */ |
| 5889 | ufshcd_complete_requests(hba); | 5895 | ufshcd_complete_requests(hba); |
| @@ -6042,12 +6048,8 @@ skip_err_handling: · 152 unmodified lines | |||
| 6042 | } | 6048 | } |
| 6043 | ufshcd_clear_eh_in_progress(hba); | 6049 | ufshcd_clear_eh_in_progress(hba); |
| 6044 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 6050 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 6045 | ufshcd_scsi_unblock_requests(hba); | ||
| 6046 | ufshcd_err_handling_unprepare(hba); | 6051 | ufshcd_err_handling_unprepare(hba); |
| 6047 | up(&hba->host_sem); | 6052 | up(&hba->host_sem); |
| 6048 | |||
| 6049 | if (!err && needs_reset) | ||
| 6050 | ufshcd_clear_ua_wluns(hba); | ||
| 6051 | } | 6053 | } |
| 6052 | 6054 | ||
| 6053 | /** | 6055 | /** |
| @@ -7858,6 +7860,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) · 1804 unmodified lines | |||
| 7858 | unsigned long flags; | 7860 | unsigned long flags; |
| 7859 | ktime_t start = ktime_get(); | 7861 | ktime_t start = ktime_get(); |
| 7860 | 7862 | ||
| 7863 | hba->ufshcd_state = UFSHCD_STATE_RESET; | ||
| 7864 | |||
| 7861 | ret = ufshcd_link_startup(hba); | 7865 | ret = ufshcd_link_startup(hba); |
| 7862 | if (ret) | 7866 | if (ret) |
| 7863 | goto out; | 7867 | goto out; |
| @@ -8972,11 +8976,6 @@ int ufshcd_system_suspend(struct ufs_hba *hba) · 1108 unmodified lines | |||
| 8972 | int ret = 0; | 8976 | int ret = 0; |
| 8973 | ktime_t start = ktime_get(); | 8977 | ktime_t start = ktime_get(); |
| 8974 | 8978 | ||
| 8975 | if (!hba) { | ||
| 8976 | early_suspend = true; | ||
| 8977 | return 0; | ||
| 8978 | } | ||
| 8979 | |||
| 8980 | down(&hba->host_sem); | 8979 | down(&hba->host_sem); |
| 8981 | 8980 | ||
| 8982 | if (!hba->is_powered) | 8981 | if (!hba->is_powered) |
| @@ -9028,14 +9027,6 @@ int ufshcd_system_resume(struct ufs_hba *hba) · 45 unmodified lines | |||
| 9028 | int ret = 0; | 9027 | int ret = 0; |
| 9029 | ktime_t start = ktime_get(); | 9028 | ktime_t start = ktime_get(); |
| 9030 | 9029 | ||
| 9031 | if (!hba) | ||
| 9032 | return -EINVAL; | ||
| 9033 | |||
| 9034 | if (unlikely(early_suspend)) { | ||
| 9035 | early_suspend = false; | ||
| 9036 | down(&hba->host_sem); | ||
| 9037 | } | ||
| 9038 | |||
| 9039 | if (!hba->is_powered || pm_runtime_suspended(hba->dev)) | 9030 | if (!hba->is_powered || pm_runtime_suspended(hba->dev)) |
| 9040 | /* | 9031 | /* |
| 9041 | * Let the runtime resume take care of resuming | 9032 | * Let the runtime resume take care of resuming |
| @@ -9068,9 +9059,6 @@ int ufshcd_runtime_suspend(struct ufs_hba *hba) · 26 unmodified lines | |||
| 9068 | int ret = 0; | 9059 | int ret = 0; |
| 9069 | ktime_t start = ktime_get(); | 9060 | ktime_t start = ktime_get(); |
| 9070 | 9061 | ||
| 9071 | if (!hba) | ||
| 9072 | return -EINVAL; | ||
| 9073 | |||
| 9074 | if (!hba->is_powered) | 9062 | if (!hba->is_powered) |
| 9075 | goto out; | 9063 | goto out; |
| 9076 | else | 9064 | else |
| @@ -9109,9 +9097,6 @@ int ufshcd_runtime_resume(struct ufs_hba *hba) · 32 unmodified lines | |||
| 9109 | int ret = 0; | 9097 | int ret = 0; |
| 9110 | ktime_t start = ktime_get(); | 9098 | ktime_t start = ktime_get(); |
| 9111 | 9099 | ||
| 9112 | if (!hba) | ||
| 9113 | return -EINVAL; | ||
| 9114 | |||
| 9115 | if (!hba->is_powered) | 9100 | if (!hba->is_powered) |
| 9116 | goto out; | 9101 | goto out; |
| 9117 | else | 9102 | else |
| @@ -17,8 +17,6 @@ · 16 unmodified lines | |||
| 17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 19 | * | 19 | * |
| 20 | * Maintained by: Jim Gill <jgill@vmware.com> | ||
| 21 | * | ||
| 22 | */ | 20 | */ |
| 23 | 21 | ||
| 24 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| @@ -17,8 +17,6 @@ · 16 unmodified lines | |||
| 17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 19 | * | 19 | * |
| 20 | * Maintained by: Jim Gill <jgill@vmware.com> | ||
| 21 | * | ||
| 22 | */ | 20 | */ |
| 23 | 21 | ||
| 24 | #ifndef _VMW_PVSCSI_H_ | 22 | #ifndef _VMW_PVSCSI_H_ |
| @@ -30,7 +30,6 @@ · 29 unmodified lines | |||
| 30 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); | 30 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); |
| 31 | MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); | 31 | MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); |
| 32 | MODULE_LICENSE("GPL v2"); | 32 | MODULE_LICENSE("GPL v2"); |
| 33 | MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}"); | ||
| 34 | 33 | ||
| 35 | static void maple_dma_handler(struct work_struct *work); | 34 | static void maple_dma_handler(struct work_struct *work); |
| 36 | static void maple_vblank_handler(struct work_struct *work); | 35 | static void maple_vblank_handler(struct work_struct *work); |
| @@ -1433,6 +1433,7 @@ static int cqspi_probe(struct platform_device *pdev) · 1432 unmodified lines | |||
| 1433 | cqspi = spi_master_get_devdata(master); | 1433 | cqspi = spi_master_get_devdata(master); |
| 1434 | 1434 | ||
| 1435 | cqspi->pdev = pdev; | 1435 | cqspi->pdev = pdev; |
| 1436 | platform_set_drvdata(pdev, cqspi); | ||
| 1436 | 1437 | ||
| 1437 | /* Obtain configuration from OF. */ | 1438 | /* Obtain configuration from OF. */ |
| 1438 | ret = cqspi_of_get_pdata(cqspi); | 1439 | ret = cqspi_of_get_pdata(cqspi); |
| @@ -260,6 +260,7 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) · 259 unmodified lines | |||
| 260 | struct apci1032_private *devpriv = dev->private; | 260 | struct apci1032_private *devpriv = dev->private; |
| 261 | struct comedi_subdevice *s = dev->read_subdev; | 261 | struct comedi_subdevice *s = dev->read_subdev; |
| 262 | unsigned int ctrl; | 262 | unsigned int ctrl; |
| 263 | unsigned short val; | ||
| 263 | 264 | ||
| 264 | /* check interrupt is from this device */ | 265 | /* check interrupt is from this device */ |
| 265 | if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & | 266 | if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & |
| @@ -275,7 +276,8 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) · 9 unmodified lines | |||
| 275 | outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); | 276 | outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); |
| 276 | 277 | ||
| 277 | s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; | 278 | s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; |
| 278 | comedi_buf_write_samples(s, &s->state, 1); | 279 | val = s->state; |
| 280 | comedi_buf_write_samples(s, &val, 1); | ||
| 279 | comedi_handle_events(dev, s); | 281 | comedi_handle_events(dev, s); |
| 280 | 282 | ||
| 281 | /* enable the interrupt */ | 283 | /* enable the interrupt */ |
| @@ -208,7 +208,7 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) · 207 unmodified lines | |||
| 208 | struct comedi_device *dev = d; | 208 | struct comedi_device *dev = d; |
| 209 | struct apci1500_private *devpriv = dev->private; | 209 | struct apci1500_private *devpriv = dev->private; |
| 210 | struct comedi_subdevice *s = dev->read_subdev; | 210 | struct comedi_subdevice *s = dev->read_subdev; |
| 211 | unsigned int status = 0; | 211 | unsigned short status = 0; |
| 212 | unsigned int val; | 212 | unsigned int val; |
| 213 | 213 | ||
| 214 | val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); | 214 | val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); |
| @@ -238,14 +238,14 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) · 23 unmodified lines | |||
| 238 | * | 238 | * |
| 239 | * Mask Meaning | 239 | * Mask Meaning |
| 240 | * ---------- ------------------------------------------ | 240 | * ---------- ------------------------------------------ |
| 241 | * 0x00000001 Event 1 has occurred | 241 | * 0b00000001 Event 1 has occurred |
| 242 | * 0x00000010 Event 2 has occurred | 242 | * 0b00000010 Event 2 has occurred |
| 243 | * 0x00000100 Counter/timer 1 has run down (not implemented) | 243 | * 0b00000100 Counter/timer 1 has run down (not implemented) |
| 244 | * 0x00001000 Counter/timer 2 has run down (not implemented) | 244 | * 0b00001000 Counter/timer 2 has run down (not implemented) |
| 245 | * 0x00010000 Counter 3 has run down (not implemented) | 245 | * 0b00010000 Counter 3 has run down (not implemented) |
| 246 | * 0x00100000 Watchdog has run down (not implemented) | 246 | * 0b00100000 Watchdog has run down (not implemented) |
| 247 | * 0x01000000 Voltage error | 247 | * 0b01000000 Voltage error |
| 248 | * 0x10000000 Short-circuit error | 248 | * 0b10000000 Short-circuit error |
| 249 | */ | 249 | */ |
| 250 | comedi_buf_write_samples(s, &status, 1); | 250 | comedi_buf_write_samples(s, &status, 1); |
| 251 | comedi_handle_events(dev, s); | 251 | comedi_handle_events(dev, s); |
| @@ -300,11 +300,11 @@ static int pci1710_ai_eoc(struct comedi_device *dev, · 299 unmodified lines | |||
| 300 | static int pci1710_ai_read_sample(struct comedi_device *dev, | 300 | static int pci1710_ai_read_sample(struct comedi_device *dev, |
| 301 | struct comedi_subdevice *s, | 301 | struct comedi_subdevice *s, |
| 302 | unsigned int cur_chan, | 302 | unsigned int cur_chan, |
| 303 | unsigned int *val) | 303 | unsigned short *val) |
| 304 | { | 304 | { |
| 305 | const struct boardtype *board = dev->board_ptr; | 305 | const struct boardtype *board = dev->board_ptr; |
| 306 | struct pci1710_private *devpriv = dev->private; | 306 | struct pci1710_private *devpriv = dev->private; |
| 307 | unsigned int sample; | 307 | unsigned short sample; |
| 308 | unsigned int chan; | 308 | unsigned int chan; |
| 309 | 309 | ||
| 310 | sample = inw(dev->iobase + PCI171X_AD_DATA_REG); | 310 | sample = inw(dev->iobase + PCI171X_AD_DATA_REG); |
| @@ -345,7 +345,7 @@ static int pci1710_ai_insn_read(struct comedi_device *dev, · 34 unmodified lines | |||
| 345 | pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); | 345 | pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); |
| 346 | 346 | ||
| 347 | for (i = 0; i < insn->n; i++) { | 347 | for (i = 0; i < insn->n; i++) { |
| 348 | unsigned int val; | 348 | unsigned short val; |
| 349 | 349 | ||
| 350 | /* start conversion */ | 350 | /* start conversion */ |
| 351 | outw(0, dev->iobase + PCI171X_SOFTTRG_REG); | 351 | outw(0, dev->iobase + PCI171X_SOFTTRG_REG); |
| @@ -395,7 +395,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, · 43 unmodified lines | |||
| 395 | { | 395 | { |
| 396 | struct comedi_cmd *cmd = &s->async->cmd; | 396 | struct comedi_cmd *cmd = &s->async->cmd; |
| 397 | unsigned int status; | 397 | unsigned int status; |
| 398 | unsigned int val; | 398 | unsigned short val; |
| 399 | int ret; | 399 | int ret; |
| 400 | 400 | ||
| 401 | status = inw(dev->iobase + PCI171X_STATUS_REG); | 401 | status = inw(dev->iobase + PCI171X_STATUS_REG); |
| @@ -455,7 +455,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev, · 53 unmodified lines | |||
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | for (i = 0; i < devpriv->max_samples; i++) { | 457 | for (i = 0; i < devpriv->max_samples; i++) { |
| 458 | unsigned int val; | 458 | unsigned short val; |
| 459 | int ret; | 459 | int ret; |
| 460 | 460 | ||
| 461 | ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); | 461 | ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); |
| @@ -126,7 +126,9 @@ static irqreturn_t pc236_interrupt(int irq, void *d) · 125 unmodified lines | |||
| 126 | 126 | ||
| 127 | handled = pc236_intr_check(dev); | 127 | handled = pc236_intr_check(dev); |
| 128 | if (dev->attached && handled) { | 128 | if (dev->attached && handled) { |
| 129 | comedi_buf_write_samples(s, &s->state, 1); | 129 | unsigned short val = 0; |
| 130 | |||
| 131 | comedi_buf_write_samples(s, &val, 1); | ||
| 130 | comedi_handle_events(dev, s); | 132 | comedi_handle_events(dev, s); |
| 131 | } | 133 | } |
| 132 | return IRQ_RETVAL(handled); | 134 | return IRQ_RETVAL(handled); |
| @@ -1281,7 +1281,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, · 1280 unmodified lines | |||
| 1281 | devpriv->amcc + AMCC_OP_REG_INTCSR); | 1281 | devpriv->amcc + AMCC_OP_REG_INTCSR); |
| 1282 | 1282 | ||
| 1283 | ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED, | 1283 | ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED, |
| 1284 | dev->board_name, dev); | 1284 | "cb_pcidas", dev); |
| 1285 | if (ret) { | 1285 | if (ret) { |
| 1286 | dev_dbg(dev->class_dev, "unable to allocate irq %d\n", | 1286 | dev_dbg(dev->class_dev, "unable to allocate irq %d\n", |
| 1287 | pcidev->irq); | 1287 | pcidev->irq); |
| @@ -4035,7 +4035,7 @@ static int auto_attach(struct comedi_device *dev, · 4034 unmodified lines | |||
| 4035 | init_stc_registers(dev); | 4035 | init_stc_registers(dev); |
| 4036 | 4036 | ||
| 4037 | retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, | 4037 | retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, |
| 4038 | dev->board_name, dev); | 4038 | "cb_pcidas64", dev); |
| 4039 | if (retval) { | 4039 | if (retval) { |
| 4040 | dev_dbg(dev->class_dev, "unable to allocate irq %u\n", | 4040 | dev_dbg(dev->class_dev, "unable to allocate irq %u\n", |
| 4041 | pcidev->irq); | 4041 | pcidev->irq); |
| @@ -210,12 +210,13 @@ static irqreturn_t parport_interrupt(int irq, void *d) · 209 unmodified lines | |||
| 210 | struct comedi_device *dev = d; | 210 | struct comedi_device *dev = d; |
| 211 | struct comedi_subdevice *s = dev->read_subdev; | 211 | struct comedi_subdevice *s = dev->read_subdev; |
| 212 | unsigned int ctrl; | 212 | unsigned int ctrl; |
| 213 | unsigned short val = 0; | ||
| 213 | 214 | ||
| 214 | ctrl = inb(dev->iobase + PARPORT_CTRL_REG); | 215 | ctrl = inb(dev->iobase + PARPORT_CTRL_REG); |
| 215 | if (!(ctrl & PARPORT_CTRL_IRQ_ENA)) | 216 | if (!(ctrl & PARPORT_CTRL_IRQ_ENA)) |
| 216 | return IRQ_NONE; | 217 | return IRQ_NONE; |
| 217 | 218 | ||
| 218 | comedi_buf_write_samples(s, &s->state, 1); | 219 | comedi_buf_write_samples(s, &val, 1); |
| 219 | comedi_handle_events(dev, s); | 220 | comedi_handle_events(dev, s); |
| 220 | 221 | ||
| 221 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
| @@ -186,7 +186,7 @@ static irqreturn_t das6402_interrupt(int irq, void *d) · 185 unmodified lines | |||
| 186 | if (status & DAS6402_STATUS_FFULL) { | 186 | if (status & DAS6402_STATUS_FFULL) { |
| 187 | async->events |= COMEDI_CB_OVERFLOW; | 187 | async->events |= COMEDI_CB_OVERFLOW; |
| 188 | } else if (status & DAS6402_STATUS_FFNE) { | 188 | } else if (status & DAS6402_STATUS_FFNE) { |
| 189 | unsigned int val; | 189 | unsigned short val; |
| 190 | 190 | ||
| 191 | val = das6402_ai_read_sample(dev, s); | 191 | val = das6402_ai_read_sample(dev, s); |
| 192 | comedi_buf_write_samples(s, &val, 1); | 192 | comedi_buf_write_samples(s, &val, 1); |
| @@ -427,7 +427,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) · 426 unmodified lines | |||
| 427 | struct comedi_cmd *cmd; | 427 | struct comedi_cmd *cmd; |
| 428 | unsigned long irq_flags; | 428 | unsigned long irq_flags; |
| 429 | unsigned int status; | 429 | unsigned int status; |
| 430 | unsigned int val; | 430 | unsigned short val; |
| 431 | bool fifo_empty; | 431 | bool fifo_empty; |
| 432 | bool fifo_overflow; | 432 | bool fifo_overflow; |
| 433 | int i; | 433 | int i; |
| @@ -404,7 +404,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d) · 403 unmodified lines | |||
| 404 | { | 404 | { |
| 405 | struct comedi_device *dev = d; | 405 | struct comedi_device *dev = d; |
| 406 | unsigned char intstat; | 406 | unsigned char intstat; |
| 407 | unsigned int val; | 407 | unsigned short val; |
| 408 | int i; | 408 | int i; |
| 409 | 409 | ||
| 410 | if (!dev->attached) { | 410 | if (!dev->attached) { |
| @@ -924,7 +924,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) · 923 unmodified lines | |||
| 924 | struct comedi_subdevice *s = dev->read_subdev; | 924 | struct comedi_subdevice *s = dev->read_subdev; |
| 925 | int i; | 925 | int i; |
| 926 | int c = 0; | 926 | int c = 0; |
| 927 | unsigned int lval; | 927 | unsigned short lval; |
| 928 | 928 | ||
| 929 | if (!dev->attached) | 929 | if (!dev->attached) |
| 930 | return IRQ_NONE; | 930 | return IRQ_NONE; |
| @@ -195,7 +195,9 @@ static irqreturn_t ni6527_interrupt(int irq, void *d) · 194 unmodified lines | |||
| 195 | return IRQ_NONE; | 195 | return IRQ_NONE; |
| 196 | 196 | ||
| 197 | if (status & NI6527_STATUS_EDGE) { | 197 | if (status & NI6527_STATUS_EDGE) { |
| 198 | comedi_buf_write_samples(s, &s->state, 1); | 198 | unsigned short val = 0; |
| 199 | |||
| 200 | comedi_buf_write_samples(s, &val, 1); | ||
| 199 | comedi_handle_events(dev, s); | 201 | comedi_handle_events(dev, s); |
| 200 | } | 202 | } |
| 201 | 203 | ||
| @@ -472,6 +472,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) · 471 unmodified lines | |||
| 472 | struct comedi_device *dev = d; | 472 | struct comedi_device *dev = d; |
| 473 | struct comedi_subdevice *s = dev->read_subdev; | 473 | struct comedi_subdevice *s = dev->read_subdev; |
| 474 | unsigned int status; | 474 | unsigned int status; |
| 475 | unsigned short val = 0; | ||
| 475 | 476 | ||
| 476 | status = readb(dev->mmio + NI_65XX_STATUS_REG); | 477 | status = readb(dev->mmio + NI_65XX_STATUS_REG); |
| 477 | if ((status & NI_65XX_STATUS_INT) == 0) | 478 | if ((status & NI_65XX_STATUS_INT) == 0) |
| @@ -482,7 +483,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) · 4 unmodified lines | |||
| 482 | writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT, | 483 | writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT, |
| 483 | dev->mmio + NI_65XX_CLR_REG); | 484 | dev->mmio + NI_65XX_CLR_REG); |
| 484 | 485 | ||
| 485 | comedi_buf_write_samples(s, &s->state, 1); | 486 | comedi_buf_write_samples(s, &val, 1); |
| 486 | comedi_handle_events(dev, s); | 487 | comedi_handle_events(dev, s); |
| 487 | 488 | ||
| 488 | return IRQ_HANDLED; | 489 | return IRQ_HANDLED; |
| @@ -184,7 +184,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) · 183 unmodified lines | |||
| 184 | struct comedi_device *dev = d; | 184 | struct comedi_device *dev = d; |
| 185 | struct comedi_subdevice *s = dev->read_subdev; | 185 | struct comedi_subdevice *s = dev->read_subdev; |
| 186 | struct comedi_cmd *cmd = &s->async->cmd; | 186 | struct comedi_cmd *cmd = &s->async->cmd; |
| 187 | unsigned int data; | 187 | unsigned short data; |
| 188 | 188 | ||
| 189 | if (!dev->attached) { | 189 | if (!dev->attached) { |
| 190 | dev_err(dev->class_dev, "spurious interrupt\n"); | 190 | dev_err(dev->class_dev, "spurious interrupt\n"); |
| @@ -220,9 +220,11 @@ static irqreturn_t pcl726_interrupt(int irq, void *d) · 219 unmodified lines | |||
| 220 | struct pcl726_private *devpriv = dev->private; | 220 | struct pcl726_private *devpriv = dev->private; |
| 221 | 221 | ||
| 222 | if (devpriv->cmd_running) { | 222 | if (devpriv->cmd_running) { |
| 223 | unsigned short val = 0; | ||
| 224 | |||
| 223 | pcl726_intr_cancel(dev, s); | 225 | pcl726_intr_cancel(dev, s); |
| 224 | 226 | ||
| 225 | comedi_buf_write_samples(s, &s->state, 1); | 227 | comedi_buf_write_samples(s, &val, 1); |
| 226 | comedi_handle_events(dev, s); | 228 | comedi_handle_events(dev, s); |
| 227 | } | 229 | } |
| 228 | 230 | ||
| @@ -423,7 +423,7 @@ static int pcl818_ai_eoc(struct comedi_device *dev, · 422 unmodified lines | |||
| 423 | 423 | ||
| 424 | static bool pcl818_ai_write_sample(struct comedi_device *dev, | 424 | static bool pcl818_ai_write_sample(struct comedi_device *dev, |
| 425 | struct comedi_subdevice *s, | 425 | struct comedi_subdevice *s, |
| 426 | unsigned int chan, unsigned int val) | 426 | unsigned int chan, unsigned short val) |
| 427 | { | 427 | { |
| 428 | struct pcl818_private *devpriv = dev->private; | 428 | struct pcl818_private *devpriv = dev->private; |
| 429 | struct comedi_cmd *cmd = &s->async->cmd; | 429 | struct comedi_cmd *cmd = &s->async->cmd; |
| @@ -877,5 +877,4 @@ module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver); · 876 unmodified lines | |||
| 877 | 877 | ||
| 878 | MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>"); | 878 | MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>"); |
| 879 | MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver"); | 879 | MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver"); |
| 880 | MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140"); | ||
| 881 | MODULE_LICENSE("GPL"); | 880 | MODULE_LICENSE("GPL"); |
| @@ -1120,6 +1120,7 @@ static int ks_wlan_set_scan(struct net_device *dev, · 1119 unmodified lines | |||
| 1120 | { | 1120 | { |
| 1121 | struct ks_wlan_private *priv = netdev_priv(dev); | 1121 | struct ks_wlan_private *priv = netdev_priv(dev); |
| 1122 | struct iw_scan_req *req = NULL; | 1122 | struct iw_scan_req *req = NULL; |
| 1123 | int len; | ||
| 1123 | 1124 | ||
| 1124 | if (priv->sleep_mode == SLP_SLEEP) | 1125 | if (priv->sleep_mode == SLP_SLEEP) |
| 1125 | return -EPERM; | 1126 | return -EPERM; |
| @@ -1129,8 +1130,9 @@ static int ks_wlan_set_scan(struct net_device *dev, · 3 unmodified lines | |||
| 1129 | if (wrqu->data.length == sizeof(struct iw_scan_req) && | 1130 | if (wrqu->data.length == sizeof(struct iw_scan_req) && |
| 1130 | wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 1131 | wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
| 1131 | req = (struct iw_scan_req *)extra; | 1132 | req = (struct iw_scan_req *)extra; |
| 1132 | priv->scan_ssid_len = req->essid_len; | 1133 | len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); |
| 1133 | memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); | 1134 | priv->scan_ssid_len = len; |
| 1135 | memcpy(priv->scan_ssid, req->essid, len); | ||
| 1134 | } else { | 1136 | } else { |
| 1135 | priv->scan_ssid_len = 0; | 1137 | priv->scan_ssid_len = 0; |
| 1136 | } | 1138 | } |
| @@ -791,6 +791,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) · 790 unmodified lines | |||
| 791 | p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SSID, &ie_len, | 791 | p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SSID, &ie_len, |
| 792 | pbss_network->ie_length - _BEACON_IE_OFFSET_); | 792 | pbss_network->ie_length - _BEACON_IE_OFFSET_); |
| 793 | if (p && ie_len > 0) { | 793 | if (p && ie_len > 0) { |
| 794 | ie_len = min_t(int, ie_len, sizeof(pbss_network->ssid.ssid)); | ||
| 794 | memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid)); | 795 | memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid)); |
| 795 | memcpy(pbss_network->ssid.ssid, p + 2, ie_len); | 796 | memcpy(pbss_network->ssid.ssid, p + 2, ie_len); |
| 796 | pbss_network->ssid.ssid_length = ie_len; | 797 | pbss_network->ssid.ssid_length = ie_len; |
| @@ -811,6 +812,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) · 14 unmodified lines | |||
| 811 | p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES, &ie_len, | 812 | p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES, &ie_len, |
| 812 | pbss_network->ie_length - _BEACON_IE_OFFSET_); | 813 | pbss_network->ie_length - _BEACON_IE_OFFSET_); |
| 813 | if (p) { | 814 | if (p) { |
| 815 | ie_len = min_t(int, ie_len, NDIS_802_11_LENGTH_RATES_EX); | ||
| 814 | memcpy(supportRate, p + 2, ie_len); | 816 | memcpy(supportRate, p + 2, ie_len); |
| 815 | supportRateNum = ie_len; | 817 | supportRateNum = ie_len; |
| 816 | } | 818 | } |
| @@ -819,6 +821,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) · 2 unmodified lines | |||
| 819 | p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES, | 821 | p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES, |
| 820 | &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_); | 822 | &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_); |
| 821 | if (p) { | 823 | if (p) { |
| 824 | ie_len = min_t(int, ie_len, | ||
| 825 | NDIS_802_11_LENGTH_RATES_EX - supportRateNum); | ||
| 822 | memcpy(supportRate + supportRateNum, p + 2, ie_len); | 826 | memcpy(supportRate + supportRateNum, p + 2, ie_len); |
| 823 | supportRateNum += ie_len; | 827 | supportRateNum += ie_len; |
| 824 | } | 828 | } |
| @@ -934,6 +938,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) · 109 unmodified lines | |||
| 934 | 938 | ||
| 935 | pht_cap->mcs.rx_mask[0] = 0xff; | 939 | pht_cap->mcs.rx_mask[0] = 0xff; |
| 936 | pht_cap->mcs.rx_mask[1] = 0x0; | 940 | pht_cap->mcs.rx_mask[1] = 0x0; |
| 941 | ie_len = min_t(int, ie_len, sizeof(pmlmepriv->htpriv.ht_cap)); | ||
| 937 | memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); | 942 | memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); |
| 938 | } | 943 | } |
| 939 | 944 | ||
| @@ -1133,9 +1133,11 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, · 1132 unmodified lines | |||
| 1133 | break; | 1133 | break; |
| 1134 | } | 1134 | } |
| 1135 | sec_len = *(pos++); len -= 1; | 1135 | sec_len = *(pos++); len -= 1; |
| 1136 | if (sec_len > 0 && sec_len <= len) { | 1136 | if (sec_len > 0 && |
| 1137 | sec_len <= len && | ||
| 1138 | sec_len <= 32) { | ||
| 1137 | ssid[ssid_index].ssid_length = sec_len; | 1139 | ssid[ssid_index].ssid_length = sec_len; |
| 1138 | memcpy(ssid[ssid_index].ssid, pos, ssid[ssid_index].ssid_length); | 1140 | memcpy(ssid[ssid_index].ssid, pos, sec_len); |
| 1139 | ssid_index++; | 1141 | ssid_index++; |
| 1140 | } | 1142 | } |
| 1141 | pos += sec_len; | 1143 | pos += sec_len; |
| @@ -27,6 +27,7 @@ config RTLLIB_CRYPTO_CCMP · 26 unmodified lines | |||
| 27 | config RTLLIB_CRYPTO_TKIP | 27 | config RTLLIB_CRYPTO_TKIP |
| 28 | tristate "Support for rtllib TKIP crypto" | 28 | tristate "Support for rtllib TKIP crypto" |
| 29 | depends on RTLLIB | 29 | depends on RTLLIB |
| 30 | select CRYPTO | ||
| 30 | select CRYPTO_LIB_ARC4 | 31 | select CRYPTO_LIB_ARC4 |
| 31 | select CRYPTO_MICHAEL_MIC | 32 | select CRYPTO_MICHAEL_MIC |
| 32 | default y | 33 | default y |
| @@ -406,9 +406,10 @@ static int _rtl92e_wx_set_scan(struct net_device *dev, · 405 unmodified lines | |||
| 406 | struct iw_scan_req *req = (struct iw_scan_req *)b; | 406 | struct iw_scan_req *req = (struct iw_scan_req *)b; |
| 407 | 407 | ||
| 408 | if (req->essid_len) { | 408 | if (req->essid_len) { |
| 409 | ieee->current_network.ssid_len = req->essid_len; | 409 | int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); |
| 410 | memcpy(ieee->current_network.ssid, req->essid, | 410 | |
| 411 | req->essid_len); | 411 | ieee->current_network.ssid_len = len; |
| 412 | memcpy(ieee->current_network.ssid, req->essid, len); | ||
| 412 | } | 413 | } |
| 413 | } | 414 | } |
| 414 | 415 | ||
| @@ -331,8 +331,10 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, · 330 unmodified lines | |||
| 331 | struct iw_scan_req *req = (struct iw_scan_req *)b; | 331 | struct iw_scan_req *req = (struct iw_scan_req *)b; |
| 332 | 332 | ||
| 333 | if (req->essid_len) { | 333 | if (req->essid_len) { |
| 334 | ieee->current_network.ssid_len = req->essid_len; | 334 | int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); |
| 335 | memcpy(ieee->current_network.ssid, req->essid, req->essid_len); | 335 | |
| 336 | ieee->current_network.ssid_len = len; | ||
| 337 | memcpy(ieee->current_network.ssid, req->essid, len); | ||
| 336 | } | 338 | } |
| 337 | } | 339 | } |
| 338 | 340 | ||
| @@ -192,8 +192,10 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, · 191 unmodified lines | |||
| 192 | psurveyPara->ss_ssidlen = 0; | 192 | psurveyPara->ss_ssidlen = 0; |
| 193 | memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); | 193 | memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); |
| 194 | if (pssid && pssid->SsidLength) { | 194 | if (pssid && pssid->SsidLength) { |
| 195 | memcpy(psurveyPara->ss_ssid, pssid->Ssid, pssid->SsidLength); | 195 | int len = min_t(int, pssid->SsidLength, IW_ESSID_MAX_SIZE); |
| 196 | psurveyPara->ss_ssidlen = cpu_to_le32(pssid->SsidLength); | 196 | |
| 197 | memcpy(psurveyPara->ss_ssid, pssid->Ssid, len); | ||
| 198 | psurveyPara->ss_ssidlen = cpu_to_le32(len); | ||
| 197 | } | 199 | } |
| 198 | set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); | 200 | set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); |
| 199 | r8712_enqueue_cmd(pcmdpriv, ph2c); | 201 | r8712_enqueue_cmd(pcmdpriv, ph2c); |
| @@ -924,7 +924,7 @@ static int r871x_wx_set_priv(struct net_device *dev, · 923 unmodified lines | |||
| 924 | struct iw_point *dwrq = (struct iw_point *)awrq; | 924 | struct iw_point *dwrq = (struct iw_point *)awrq; |
| 925 | 925 | ||
| 926 | len = dwrq->length; | 926 | len = dwrq->length; |
| 927 | ext = memdup_user(dwrq->pointer, len); | 927 | ext = strndup_user(dwrq->pointer, len); |
| 928 | if (IS_ERR(ext)) | 928 | if (IS_ERR(ext)) |
| 929 | return PTR_ERR(ext); | 929 | return PTR_ERR(ext); |
| 930 | 930 | ||
| @@ -150,7 +150,7 @@ struct vnt_cts { · 149 unmodified lines | |||
| 150 | u16 reserved; | 150 | u16 reserved; |
| 151 | struct ieee80211_cts data; | 151 | struct ieee80211_cts data; |
| 152 | u16 reserved2; | 152 | u16 reserved2; |
| 153 | } __packed; | 153 | } __packed __aligned(2); |
| 154 | 154 | ||
| 155 | struct vnt_cts_fb { | 155 | struct vnt_cts_fb { |
| 156 | struct vnt_phy_field b; | 156 | struct vnt_phy_field b; |
| @@ -160,7 +160,7 @@ struct vnt_cts_fb { · 3 unmodified lines | |||
| 160 | __le16 cts_duration_ba_f1; | 160 | __le16 cts_duration_ba_f1; |
| 161 | struct ieee80211_cts data; | 161 | struct ieee80211_cts data; |
| 162 | u16 reserved2; | 162 | u16 reserved2; |
| 163 | } __packed; | 163 | } __packed __aligned(2); |
| 164 | 164 | ||
| 165 | struct vnt_tx_fifo_head { | 165 | struct vnt_tx_fifo_head { |
| 166 | u8 tx_key[WLAN_KEY_LEN_CCMP]; | 166 | u8 tx_key[WLAN_KEY_LEN_CCMP]; |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/gpio/consumer.h> | ||
| 8 | #include <net/mac80211.h> | 9 | #include <net/mac80211.h> |
| 9 | 10 | ||
| 10 | #include "bh.h" | 11 | #include "bh.h" |
| @@ -8,6 +8,10 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_BH_H | 8 | #ifndef WFX_BH_H |
| 9 | #define WFX_BH_H | 9 | #define WFX_BH_H |
| 10 | 10 | ||
| 11 | #include <linux/atomic.h> | ||
| 12 | #include <linux/wait.h> | ||
| 13 | #include <linux/workqueue.h> | ||
| 14 | |||
| 11 | struct wfx_dev; | 15 | struct wfx_dev; |
| 12 | 16 | ||
| 13 | struct wfx_hif { | 17 | struct wfx_hif { |
| @@ -8,6 +8,9 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_BUS_H | 8 | #ifndef WFX_BUS_H |
| 9 | #define WFX_BUS_H | 9 | #define WFX_BUS_H |
| 10 | 10 | ||
| 11 | #include <linux/mmc/sdio_func.h> | ||
| 12 | #include <linux/spi/spi.h> | ||
| 13 | |||
| 11 | #define WFX_REG_CONFIG 0x0 | 14 | #define WFX_REG_CONFIG 0x0 |
| 12 | #define WFX_REG_CONTROL 0x1 | 15 | #define WFX_REG_CONTROL 0x1 |
| 13 | #define WFX_REG_IN_OUT_QUEUE 0x2 | 16 | #define WFX_REG_IN_OUT_QUEUE 0x2 |
| @@ -5,13 +5,19 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/module.h> | ||
| 8 | #include <linux/mmc/sdio.h> | 9 | #include <linux/mmc/sdio.h> |
| 9 | #include <linux/mmc/sdio_func.h> | 10 | #include <linux/mmc/sdio_func.h> |
| 10 | #include <linux/mmc/card.h> | 11 | #include <linux/mmc/card.h> |
| 12 | #include <linux/interrupt.h> | ||
| 11 | #include <linux/of_irq.h> | 13 | #include <linux/of_irq.h> |
| 14 | #include <linux/irq.h> | ||
| 12 | 15 | ||
| 13 | #include "bus.h" | 16 | #include "bus.h" |
| 14 | #include "wfx.h" | 17 | #include "wfx.h" |
| 18 | #include "hwio.h" | ||
| 19 | #include "main.h" | ||
| 20 | #include "bh.h" | ||
| 15 | 21 | ||
| 16 | static const struct wfx_platform_data wfx_sdio_pdata = { | 22 | static const struct wfx_platform_data wfx_sdio_pdata = { |
| 17 | .file_fw = "wfm_wf200", | 23 | .file_fw = "wfm_wf200", |
| @@ -6,12 +6,19 @@ · 5 unmodified lines | |||
| 6 | * Copyright (c) 2011, Sagrad Inc. | 6 | * Copyright (c) 2011, Sagrad Inc. |
| 7 | * Copyright (c) 2010, ST-Ericsson | 7 | * Copyright (c) 2010, ST-Ericsson |
| 8 | */ | 8 | */ |
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/delay.h> | ||
| 11 | #include <linux/gpio/consumer.h> | ||
| 9 | #include <linux/spi/spi.h> | 12 | #include <linux/spi/spi.h> |
| 13 | #include <linux/interrupt.h> | ||
| 10 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
| 11 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 12 | 16 | ||
| 13 | #include "bus.h" | 17 | #include "bus.h" |
| 14 | #include "wfx.h" | 18 | #include "wfx.h" |
| 19 | #include "hwio.h" | ||
| 20 | #include "main.h" | ||
| 21 | #include "bh.h" | ||
| 15 | 22 | ||
| 16 | #define SET_WRITE 0x7FFF /* usage: and operation */ | 23 | #define SET_WRITE 0x7FFF /* usage: and operation */ |
| 17 | #define SET_READ 0x8000 /* usage: or operation */ | 24 | #define SET_READ 0x8000 /* usage: or operation */ |
| @@ -5,8 +5,13 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/etherdevice.h> | ||
| 9 | #include <net/mac80211.h> | ||
| 10 | |||
| 8 | #include "data_rx.h" | 11 | #include "data_rx.h" |
| 9 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "bh.h" | ||
| 14 | #include "sta.h" | ||
| 10 | 15 | ||
| 11 | static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt) | 16 | static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt) |
| 12 | { | 17 | { |
| @@ -6,9 +6,14 @@ · 5 unmodified lines | |||
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <net/mac80211.h> | 8 | #include <net/mac80211.h> |
| 9 | #include <linux/etherdevice.h> | ||
| 9 | 10 | ||
| 11 | #include "data_tx.h" | ||
| 10 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "bh.h" | ||
| 11 | #include "sta.h" | 14 | #include "sta.h" |
| 15 | #include "queue.h" | ||
| 16 | #include "debug.h" | ||
| 12 | #include "traces.h" | 17 | #include "traces.h" |
| 13 | #include "hif_tx_mib.h" | 18 | #include "hif_tx_mib.h" |
| 14 | 19 | ||
| @@ -8,6 +8,9 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_DATA_TX_H | 8 | #ifndef WFX_DATA_TX_H |
| 9 | #define WFX_DATA_TX_H | 9 | #define WFX_DATA_TX_H |
| 10 | 10 | ||
| 11 | #include <linux/list.h> | ||
| 12 | #include <net/mac80211.h> | ||
| 13 | |||
| 11 | #include "hif_api_cmd.h" | 14 | #include "hif_api_cmd.h" |
| 12 | #include "hif_api_mib.h" | 15 | #include "hif_api_mib.h" |
| 13 | 16 | ||
| @@ -5,9 +5,15 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/debugfs.h> | ||
| 9 | #include <linux/seq_file.h> | ||
| 10 | #include <linux/crc32.h> | ||
| 11 | |||
| 8 | #include "debug.h" | 12 | #include "debug.h" |
| 9 | #include "wfx.h" | 13 | #include "wfx.h" |
| 10 | #include "sta.h" | 14 | #include "sta.h" |
| 15 | #include "main.h" | ||
| 16 | #include "hif_tx.h" | ||
| 11 | #include "hif_tx_mib.h" | 17 | #include "hif_tx_mib.h" |
| 12 | 18 | ||
| 13 | #define CREATE_TRACE_POINTS | 19 | #define CREATE_TRACE_POINTS |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/firmware.h> | 8 | #include <linux/firmware.h> |
| 9 | #include <linux/slab.h> | ||
| 10 | #include <linux/mm.h> | ||
| 9 | #include <linux/bitfield.h> | 11 | #include <linux/bitfield.h> |
| 10 | 12 | ||
| 11 | #include "fwio.h" | 13 | #include "fwio.h" |
| @@ -8,6 +8,10 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_HIF_API_CMD_H | 8 | #ifndef WFX_HIF_API_CMD_H |
| 9 | #define WFX_HIF_API_CMD_H | 9 | #define WFX_HIF_API_CMD_H |
| 10 | 10 | ||
| 11 | #include <linux/ieee80211.h> | ||
| 12 | |||
| 13 | #include "hif_api_general.h" | ||
| 14 | |||
| 11 | enum hif_requests_ids { | 15 | enum hif_requests_ids { |
| 12 | HIF_REQ_ID_RESET = 0x0a, | 16 | HIF_REQ_ID_RESET = 0x0a, |
| 13 | HIF_REQ_ID_READ_MIB = 0x05, | 17 | HIF_REQ_ID_READ_MIB = 0x05, |
| @@ -8,6 +8,15 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_HIF_API_GENERAL_H | 8 | #ifndef WFX_HIF_API_GENERAL_H |
| 9 | #define WFX_HIF_API_GENERAL_H | 9 | #define WFX_HIF_API_GENERAL_H |
| 10 | 10 | ||
| 11 | #ifdef __KERNEL__ | ||
| 12 | #include <linux/types.h> | ||
| 13 | #include <linux/if_ether.h> | ||
| 14 | #else | ||
| 15 | #include <net/ethernet.h> | ||
| 16 | #include <stdint.h> | ||
| 17 | #define __packed __attribute__((__packed__)) | ||
| 18 | #endif | ||
| 19 | |||
| 11 | #define HIF_ID_IS_INDICATION 0x80 | 20 | #define HIF_ID_IS_INDICATION 0x80 |
| 12 | #define HIF_COUNTER_MAX 7 | 21 | #define HIF_COUNTER_MAX 7 |
| 13 | 22 | ||
| @@ -6,7 +6,11 @@ · 5 unmodified lines | |||
| 6 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 6 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 7 | * Copyright (c) 2010, ST-Ericsson | 7 | * Copyright (c) 2010, ST-Ericsson |
| 8 | */ | 8 | */ |
| 9 | #include <linux/etherdevice.h> | ||
| 10 | |||
| 11 | #include "hif_tx.h" | ||
| 9 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "bh.h" | ||
| 10 | #include "hwio.h" | 14 | #include "hwio.h" |
| 11 | #include "debug.h" | 15 | #include "debug.h" |
| 12 | #include "sta.h" | 16 | #include "sta.h" |
| @@ -6,8 +6,13 @@ · 5 unmodified lines | |||
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | * Copyright (C) 2010, ST-Ericsson SA | 7 | * Copyright (C) 2010, ST-Ericsson SA |
| 8 | */ | 8 | */ |
| 9 | |||
| 10 | #include <linux/etherdevice.h> | ||
| 11 | |||
| 9 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "hif_tx.h" | ||
| 10 | #include "hif_tx_mib.h" | 14 | #include "hif_tx_mib.h" |
| 15 | #include "hif_api_mib.h" | ||
| 11 | 16 | ||
| 12 | int hif_set_output_power(struct wfx_vif *wvif, int val) | 17 | int hif_set_output_power(struct wfx_vif *wvif, int val) |
| 13 | { | 18 | { |
| @@ -5,10 +5,13 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/delay.h> | ||
| 8 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 9 | 11 | ||
| 10 | #include "hwio.h" | 12 | #include "hwio.h" |
| 11 | #include "wfx.h" | 13 | #include "wfx.h" |
| 14 | #include "bus.h" | ||
| 12 | #include "traces.h" | 15 | #include "traces.h" |
| 13 | 16 | ||
| 14 | /* | 17 | /* |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_HWIO_H | 8 | #ifndef WFX_HWIO_H |
| 9 | #define WFX_HWIO_H | 9 | #define WFX_HWIO_H |
| 10 | 10 | ||
| 11 | #include <linux/types.h> | ||
| 12 | |||
| 11 | struct wfx_dev; | 13 | struct wfx_dev; |
| 12 | 14 | ||
| 13 | int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t buf_len); | 15 | int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t buf_len); |
| @@ -5,10 +5,12 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/etherdevice.h> | ||
| 8 | #include <net/mac80211.h> | 9 | #include <net/mac80211.h> |
| 9 | 10 | ||
| 10 | #include "key.h" | 11 | #include "key.h" |
| 11 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "hif_tx_mib.h" | ||
| 12 | 14 | ||
| 13 | static int wfx_alloc_key(struct wfx_dev *wdev) | 15 | static int wfx_alloc_key(struct wfx_dev *wdev) |
| 14 | { | 16 | { |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_KEY_H | 8 | #ifndef WFX_KEY_H |
| 9 | #define WFX_KEY_H | 9 | #define WFX_KEY_H |
| 10 | 10 | ||
| 11 | #include <net/mac80211.h> | ||
| 12 | |||
| 11 | struct wfx_dev; | 13 | struct wfx_dev; |
| 12 | struct wfx_vif; | 14 | struct wfx_vif; |
| 13 | 15 | ||
| @@ -10,21 +10,28 @@ · 9 unmodified lines | |||
| 10 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> | 10 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> |
| 11 | * Copyright (c) 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. | 11 | * Copyright (c) 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. |
| 12 | */ | 12 | */ |
| 13 | #include <linux/module.h> | ||
| 13 | #include <linux/of.h> | 14 | #include <linux/of.h> |
| 14 | #include <linux/of_net.h> | 15 | #include <linux/of_net.h> |
| 16 | #include <linux/gpio/consumer.h> | ||
| 15 | #include <linux/mmc/sdio_func.h> | 17 | #include <linux/mmc/sdio_func.h> |
| 16 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
| 19 | #include <linux/etherdevice.h> | ||
| 17 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
| 18 | 21 | ||
| 22 | #include "main.h" | ||
| 19 | #include "wfx.h" | 23 | #include "wfx.h" |
| 20 | #include "fwio.h" | 24 | #include "fwio.h" |
| 21 | #include "hwio.h" | 25 | #include "hwio.h" |
| 22 | #include "bus.h" | 26 | #include "bus.h" |
| 27 | #include "bh.h" | ||
| 23 | #include "sta.h" | 28 | #include "sta.h" |
| 24 | #include "key.h" | 29 | #include "key.h" |
| 25 | #include "scan.h" | 30 | #include "scan.h" |
| 26 | #include "debug.h" | 31 | #include "debug.h" |
| 32 | #include "data_tx.h" | ||
| 27 | #include "hif_tx_mib.h" | 33 | #include "hif_tx_mib.h" |
| 34 | #include "hif_api_cmd.h" | ||
| 28 | 35 | ||
| 29 | #define WFX_PDS_MAX_SIZE 1500 | 36 | #define WFX_PDS_MAX_SIZE 1500 |
| 30 | 37 | ||
| @@ -10,8 +10,11 @@ · 9 unmodified lines | |||
| 10 | #ifndef WFX_MAIN_H | 10 | #ifndef WFX_MAIN_H |
| 11 | #define WFX_MAIN_H | 11 | #define WFX_MAIN_H |
| 12 | 12 | ||
| 13 | #include <linux/device.h> | ||
| 13 | #include <linux/gpio/consumer.h> | 14 | #include <linux/gpio/consumer.h> |
| 14 | 15 | ||
| 16 | #include "hif_api_general.h" | ||
| 17 | |||
| 15 | struct wfx_dev; | 18 | struct wfx_dev; |
| 16 | struct hwbus_ops; | 19 | struct hwbus_ops; |
| 17 | 20 | ||
| @@ -5,9 +5,13 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/sched.h> | ||
| 8 | #include <net/mac80211.h> | 9 | #include <net/mac80211.h> |
| 9 | 10 | ||
| 11 | #include "queue.h" | ||
| 10 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "sta.h" | ||
| 14 | #include "data_tx.h" | ||
| 11 | #include "traces.h" | 15 | #include "traces.h" |
| 12 | 16 | ||
| 13 | void wfx_tx_lock(struct wfx_dev *wdev) | 17 | void wfx_tx_lock(struct wfx_dev *wdev) |
| @@ -8,6 +8,9 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_QUEUE_H | 8 | #ifndef WFX_QUEUE_H |
| 9 | #define WFX_QUEUE_H | 9 | #define WFX_QUEUE_H |
| 10 | 10 | ||
| 11 | #include <linux/skbuff.h> | ||
| 12 | #include <linux/atomic.h> | ||
| 13 | |||
| 11 | struct wfx_dev; | 14 | struct wfx_dev; |
| 12 | struct wfx_vif; | 15 | struct wfx_vif; |
| 13 | 16 | ||
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_SCAN_H | 8 | #ifndef WFX_SCAN_H |
| 9 | #define WFX_SCAN_H | 9 | #define WFX_SCAN_H |
| 10 | 10 | ||
| 11 | #include <net/mac80211.h> | ||
| 12 | |||
| 11 | struct wfx_dev; | 13 | struct wfx_dev; |
| 12 | struct wfx_vif; | 14 | struct wfx_vif; |
| 13 | 15 | ||
| @@ -5,11 +5,17 @@ · 4 unmodified lines | |||
| 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. | 5 | * Copyright (c) 2017-2020, Silicon Laboratories, Inc. |
| 6 | * Copyright (c) 2010, ST-Ericsson | 6 | * Copyright (c) 2010, ST-Ericsson |
| 7 | */ | 7 | */ |
| 8 | #include <linux/etherdevice.h> | ||
| 8 | #include <net/mac80211.h> | 9 | #include <net/mac80211.h> |
| 9 | 10 | ||
| 10 | #include "sta.h" | 11 | #include "sta.h" |
| 11 | #include "wfx.h" | 12 | #include "wfx.h" |
| 13 | #include "fwio.h" | ||
| 14 | #include "bh.h" | ||
| 15 | #include "key.h" | ||
| 12 | #include "scan.h" | 16 | #include "scan.h" |
| 17 | #include "debug.h" | ||
| 18 | #include "hif_tx.h" | ||
| 13 | #include "hif_tx_mib.h" | 19 | #include "hif_tx_mib.h" |
| 14 | 20 | ||
| 15 | #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2 | 21 | #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2 |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #ifndef WFX_STA_H | 8 | #ifndef WFX_STA_H |
| 9 | #define WFX_STA_H | 9 | #define WFX_STA_H |
| 10 | 10 | ||
| 11 | #include <net/mac80211.h> | ||
| 12 | |||
| 11 | struct wfx_dev; | 13 | struct wfx_dev; |
| 12 | struct wfx_vif; | 14 | struct wfx_vif; |
| 13 | 15 | ||
| @@ -12,8 +12,11 @@ · 11 unmodified lines | |||
| 12 | #define _WFX_TRACE_H | 12 | #define _WFX_TRACE_H |
| 13 | 13 | ||
| 14 | #include <linux/tracepoint.h> | 14 | #include <linux/tracepoint.h> |
| 15 | #include <net/mac80211.h> | ||
| 15 | 16 | ||
| 16 | #include "bus.h" | 17 | #include "bus.h" |
| 18 | #include "hif_api_cmd.h" | ||
| 19 | #include "hif_api_mib.h" | ||
| 17 | 20 | ||
| 18 | /* The hell below need some explanations. For each symbolic number, we need to | 21 | /* The hell below need some explanations. For each symbolic number, we need to |
| 19 | * define it with TRACE_DEFINE_ENUM() and in a list for __print_symbolic. | 22 | * define it with TRACE_DEFINE_ENUM() and in a list for __print_symbolic. |
| @@ -10,6 +10,9 @@ · 9 unmodified lines | |||
| 10 | #ifndef WFX_H | 10 | #ifndef WFX_H |
| 11 | #define WFX_H | 11 | #define WFX_H |
| 12 | 12 | ||
| 13 | #include <linux/completion.h> | ||
| 14 | #include <linux/workqueue.h> | ||
| 15 | #include <linux/mutex.h> | ||
| 13 | #include <linux/nospec.h> | 16 | #include <linux/nospec.h> |
| 14 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
| 15 | 18 | ||
| @@ -747,7 +747,6 @@ module_platform_driver(optee_driver); · 746 unmodified lines | |||
| 747 | 747 | ||
| 748 | MODULE_AUTHOR("Linaro"); | 748 | MODULE_AUTHOR("Linaro"); |
| 749 | MODULE_DESCRIPTION("OP-TEE driver"); | 749 | MODULE_DESCRIPTION("OP-TEE driver"); |
| 750 | MODULE_SUPPORTED_DEVICE(""); | ||
| 751 | MODULE_VERSION("1.0"); | 750 | MODULE_VERSION("1.0"); |
| 752 | MODULE_LICENSE("GPL v2"); | 751 | MODULE_LICENSE("GPL v2"); |
| 753 | MODULE_ALIAS("platform:optee"); | 752 | MODULE_ALIAS("platform:optee"); |
| @@ -674,6 +674,9 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, · 673 unmodified lines | |||
| 674 | { | 674 | { |
| 675 | struct cooling_dev_stats *stats = cdev->stats; | 675 | struct cooling_dev_stats *stats = cdev->stats; |
| 676 | 676 | ||
| 677 | if (!stats) | ||
| 678 | return; | ||
| 679 | |||
| 677 | spin_lock(&stats->lock); | 680 | spin_lock(&stats->lock); |
| 678 | 681 | ||
| 679 | if (stats->state == new_state) | 682 | if (stats->state == new_state) |
| @@ -768,12 +768,6 @@ static int tb_init_port(struct tb_port *port) · 767 unmodified lines | |||
| 768 | 768 | ||
| 769 | tb_dump_port(port->sw->tb, &port->config); | 769 | tb_dump_port(port->sw->tb, &port->config); |
| 770 | 770 | ||
| 771 | /* Control port does not need HopID allocation */ | ||
| 772 | if (port->port) { | ||
| 773 | ida_init(&port->in_hopids); | ||
| 774 | ida_init(&port->out_hopids); | ||
| 775 | } | ||
| 776 | |||
| 777 | INIT_LIST_HEAD(&port->list); | 771 | INIT_LIST_HEAD(&port->list); |
| 778 | return 0; | 772 | return 0; |
| 779 | 773 | ||
| @@ -1842,10 +1836,8 @@ static void tb_switch_release(struct device *dev) · 1062 unmodified lines | |||
| 1842 | dma_port_free(sw->dma_port); | 1836 | dma_port_free(sw->dma_port); |
| 1843 | 1837 | ||
| 1844 | tb_switch_for_each_port(sw, port) { | 1838 | tb_switch_for_each_port(sw, port) { |
| 1845 | if (!port->disabled) { | 1839 | ida_destroy(&port->in_hopids); |
| 1846 | ida_destroy(&port->in_hopids); | 1840 | ida_destroy(&port->out_hopids); |
| 1847 | ida_destroy(&port->out_hopids); | ||
| 1848 | } | ||
| 1849 | } | 1841 | } |
| 1850 | 1842 | ||
| 1851 | kfree(sw->uuid); | 1843 | kfree(sw->uuid); |
| @@ -2025,6 +2017,12 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, · 173 unmodified lines | |||
| 2025 | /* minimum setup for tb_find_cap and tb_drom_read to work */ | 2017 | /* minimum setup for tb_find_cap and tb_drom_read to work */ |
| 2026 | sw->ports[i].sw = sw; | 2018 | sw->ports[i].sw = sw; |
| 2027 | sw->ports[i].port = i; | 2019 | sw->ports[i].port = i; |
| 2020 | |||
| 2021 | /* Control port does not need HopID allocation */ | ||
| 2022 | if (i) { | ||
| 2023 | ida_init(&sw->ports[i].in_hopids); | ||
| 2024 | ida_init(&sw->ports[i].out_hopids); | ||
| 2025 | } | ||
| 2028 | } | 2026 | } |
| 2029 | 2027 | ||
| 2030 | ret = tb_switch_find_vse_cap(sw, TB_VSE_CAP_PLUG_EVENTS); | 2028 | ret = tb_switch_find_vse_cap(sw, TB_VSE_CAP_PLUG_EVENTS); |
| @@ -138,6 +138,10 @@ static void tb_discover_tunnels(struct tb_switch *sw) · 137 unmodified lines | |||
| 138 | parent->boot = true; | 138 | parent->boot = true; |
| 139 | parent = tb_switch_parent(parent); | 139 | parent = tb_switch_parent(parent); |
| 140 | } | 140 | } |
| 141 | } else if (tb_tunnel_is_dp(tunnel)) { | ||
| 142 | /* Keep the domain from powering down */ | ||
| 143 | pm_runtime_get_sync(&tunnel->src_port->sw->dev); | ||
| 144 | pm_runtime_get_sync(&tunnel->dst_port->sw->dev); | ||
| 141 | } | 145 | } |
| 142 | 146 | ||
| 143 | list_add_tail(&tunnel->list, &tcm->tunnel_list); | 147 | list_add_tail(&tunnel->list, &tcm->tunnel_list); |
| @@ -66,8 +66,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) · 65 unmodified lines | |||
| 66 | wake_up_interruptible(&tty->link->read_wait); | 66 | wake_up_interruptible(&tty->link->read_wait); |
| 67 | wake_up_interruptible(&tty->link->write_wait); | 67 | wake_up_interruptible(&tty->link->write_wait); |
| 68 | if (tty->driver->subtype == PTY_TYPE_MASTER) { | 68 | if (tty->driver->subtype == PTY_TYPE_MASTER) { |
| 69 | struct file *f; | 69 | set_bit(TTY_OTHER_CLOSED, &tty->flags); |
| 70 | |||
| 71 | #ifdef CONFIG_UNIX98_PTYS | 70 | #ifdef CONFIG_UNIX98_PTYS |
| 72 | if (tty->driver == ptm_driver) { | 71 | if (tty->driver == ptm_driver) { |
| 73 | mutex_lock(&devpts_mutex); | 72 | mutex_lock(&devpts_mutex); |
| @@ -76,17 +75,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) · 2 unmodified lines | |||
| 76 | mutex_unlock(&devpts_mutex); | 75 | mutex_unlock(&devpts_mutex); |
| 77 | } | 76 | } |
| 78 | #endif | 77 | #endif |
| 79 | 78 | tty_vhangup(tty->link); | |
| 80 | /* | ||
| 81 | * This hack is required because a program can open a | ||
| 82 | * pty and redirect a console to it, but if the pty is | ||
| 83 | * closed and the console is not released, then the | ||
| 84 | * slave side will never close. So release the | ||
| 85 | * redirect when the master closes. | ||
| 86 | */ | ||
| 87 | f = tty_release_redirect(tty->link); | ||
| 88 | if (f) | ||
| 89 | fput(f); | ||
| 90 | } | 79 | } |
| 91 | } | 80 | } |
| 92 | 81 | ||
| @@ -1639,8 +1639,6 @@ module_exit(icom_exit); · 1638 unmodified lines | |||
| 1639 | 1639 | ||
| 1640 | MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>"); | 1640 | MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>"); |
| 1641 | MODULE_DESCRIPTION("IBM iSeries Serial IOA driver"); | 1641 | MODULE_DESCRIPTION("IBM iSeries Serial IOA driver"); |
| 1642 | MODULE_SUPPORTED_DEVICE | ||
| 1643 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); | ||
| 1644 | MODULE_LICENSE("GPL"); | 1642 | MODULE_LICENSE("GPL"); |
| 1645 | MODULE_FIRMWARE("icom_call_setup.bin"); | 1643 | MODULE_FIRMWARE("icom_call_setup.bin"); |
| 1646 | MODULE_FIRMWARE("icom_res_dce.bin"); | 1644 | MODULE_FIRMWARE("icom_res_dce.bin"); |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | |||
| 19 | MODULE_AUTHOR("Digi International, https://www.digi.com"); | 19 | MODULE_AUTHOR("Digi International, https://www.digi.com"); |
| 20 | MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); | 20 | MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); |
| 21 | MODULE_LICENSE("GPL"); | 21 | MODULE_LICENSE("GPL"); |
| 22 | MODULE_SUPPORTED_DEVICE("jsm"); | ||
| 23 | 22 | ||
| 24 | #define JSM_DRIVER_NAME "jsm" | 23 | #define JSM_DRIVER_NAME "jsm" |
| 25 | #define NR_PORTS 32 | 24 | #define NR_PORTS 32 |
| @@ -1056,9 +1056,9 @@ static int max310x_startup(struct uart_port *port) · 1055 unmodified lines | |||
| 1056 | max310x_port_update(port, MAX310X_MODE1_REG, | 1056 | max310x_port_update(port, MAX310X_MODE1_REG, |
| 1057 | MAX310X_MODE1_TRNSCVCTRL_BIT, 0); | 1057 | MAX310X_MODE1_TRNSCVCTRL_BIT, 0); |
| 1058 | 1058 | ||
| 1059 | /* Reset FIFOs */ | 1059 | /* Configure MODE2 register & Reset FIFOs*/ |
| 1060 | max310x_port_write(port, MAX310X_MODE2_REG, | 1060 | val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT; |
| 1061 | MAX310X_MODE2_FIFORST_BIT); | 1061 | max310x_port_write(port, MAX310X_MODE2_REG, val); |
| 1062 | max310x_port_update(port, MAX310X_MODE2_REG, | 1062 | max310x_port_update(port, MAX310X_MODE2_REG, |
| 1063 | MAX310X_MODE2_FIFORST_BIT, 0); | 1063 | MAX310X_MODE2_FIFORST_BIT, 0); |
| 1064 | 1064 | ||
| @@ -1086,27 +1086,8 @@ static int max310x_startup(struct uart_port *port) · 21 unmodified lines | |||
| 1086 | /* Clear IRQ status register */ | 1086 | /* Clear IRQ status register */ |
| 1087 | max310x_port_read(port, MAX310X_IRQSTS_REG); | 1087 | max310x_port_read(port, MAX310X_IRQSTS_REG); |
| 1088 | 1088 | ||
| 1089 | /* | 1089 | /* Enable RX, TX, CTS change interrupts */ |
| 1090 | * Let's ask for an interrupt after a timeout equivalent to | 1090 | val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT; |
| 1091 | * the receiving time of 4 characters after the last character | ||
| 1092 | * has been received. | ||
| 1093 | */ | ||
| 1094 | max310x_port_write(port, MAX310X_RXTO_REG, 4); | ||
| 1095 | |||
| 1096 | /* | ||
| 1097 | * Make sure we also get RX interrupts when the RX FIFO is | ||
| 1098 | * filling up quickly, so get an interrupt when half of the RX | ||
| 1099 | * FIFO has been filled in. | ||
| 1100 | */ | ||
| 1101 | max310x_port_write(port, MAX310X_FIFOTRIGLVL_REG, | ||
| 1102 | MAX310X_FIFOTRIGLVL_RX(MAX310X_FIFO_SIZE / 2)); | ||
| 1103 | |||
| 1104 | /* Enable RX timeout interrupt in LSR */ | ||
| 1105 | max310x_port_write(port, MAX310X_LSR_IRQEN_REG, | ||
| 1106 | MAX310X_LSR_RXTO_BIT); | ||
| 1107 | |||
| 1108 | /* Enable LSR, RX FIFO trigger, CTS change interrupts */ | ||
| 1109 | val = MAX310X_IRQ_LSR_BIT | MAX310X_IRQ_RXFIFO_BIT | MAX310X_IRQ_TXEMPTY_BIT; | ||
| 1110 | max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT); | 1091 | max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT); |
| 1111 | 1092 | ||
| 1112 | return 0; | 1093 | return 0; |
| @@ -544,9 +544,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); · 543 unmodified lines | |||
| 544 | * @tty: tty device | 544 | * @tty: tty device |
| 545 | * | 545 | * |
| 546 | * This is available to the pty code so if the master closes, if the | 546 | * This is available to the pty code so if the master closes, if the |
| 547 | * slave is a redirect it can release the redirect. It returns the | 547 | * slave is a redirect it can release the redirect. |
| 548 | * filp for the redirect, which must be fput when the operations on | ||
| 549 | * the tty are completed. | ||
| 550 | */ | 548 | */ |
| 551 | struct file *tty_release_redirect(struct tty_struct *tty) | 549 | struct file *tty_release_redirect(struct tty_struct *tty) |
| 552 | { | 550 | { |
| @@ -561,6 +559,7 @@ struct file *tty_release_redirect(struct tty_struct *tty) · 8 unmodified lines | |||
| 561 | 559 | ||
| 562 | return f; | 560 | return f; |
| 563 | } | 561 | } |
| 562 | EXPORT_SYMBOL_GPL(tty_release_redirect); | ||
| 564 | 563 | ||
| 565 | /** | 564 | /** |
| 566 | * __tty_hangup - actual handler for hangup events | 565 | * __tty_hangup - actual handler for hangup events |
| @@ -2197,7 +2197,10 @@ static int cdnsp_queue_isoc_tx(struct cdnsp_device *pdev, · 2196 unmodified lines | |||
| 2197 | * inverted in the first TDs isoc TRB. | 2197 | * inverted in the first TDs isoc TRB. |
| 2198 | */ | 2198 | */ |
| 2199 | field = TRB_TYPE(TRB_ISOC) | TRB_TLBPC(last_burst_pkt) | | 2199 | field = TRB_TYPE(TRB_ISOC) | TRB_TLBPC(last_burst_pkt) | |
| 2200 | start_cycle ? 0 : 1 | TRB_SIA | TRB_TBC(burst_count); | 2200 | TRB_SIA | TRB_TBC(burst_count); |
| 2201 | |||
| 2202 | if (!start_cycle) | ||
| 2203 | field |= TRB_CYCLE; | ||
| 2201 | 2204 | ||
| 2202 | /* Fill the rest of the TRB fields, and remaining normal TRBs. */ | 2205 | /* Fill the rest of the TRB fields, and remaining normal TRBs. */ |
| 2203 | for (i = 0; i < trbs_per_td; i++) { | 2206 | for (i = 0; i < trbs_per_td; i++) { |
| @@ -1935,6 +1935,11 @@ static const struct usb_device_id acm_ids[] = { · 1934 unmodified lines | |||
| 1935 | .driver_info = SEND_ZERO_PACKET, | 1935 | .driver_info = SEND_ZERO_PACKET, |
| 1936 | }, | 1936 | }, |
| 1937 | 1937 | ||
| 1938 | /* Exclude Goodix Fingerprint Reader */ | ||
| 1939 | { USB_DEVICE(0x27c6, 0x5395), | ||
| 1940 | .driver_info = IGNORE_DEVICE, | ||
| 1941 | }, | ||
| 1942 | |||
| 1938 | /* control interfaces without any protocol set */ | 1943 | /* control interfaces without any protocol set */ |
| 1939 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1944 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
| 1940 | USB_CDC_PROTO_NONE) }, | 1945 | USB_CDC_PROTO_NONE) }, |
| @@ -494,16 +494,24 @@ static int usblp_release(struct inode *inode, struct file *file) · 493 unmodified lines | |||
| 494 | /* No kernel lock - fine */ | 494 | /* No kernel lock - fine */ |
| 495 | static __poll_t usblp_poll(struct file *file, struct poll_table_struct *wait) | 495 | static __poll_t usblp_poll(struct file *file, struct poll_table_struct *wait) |
| 496 | { | 496 | { |
| 497 | __poll_t ret; | 497 | struct usblp *usblp = file->private_data; |
| 498 | __poll_t ret = 0; | ||
| 498 | unsigned long flags; | 499 | unsigned long flags; |
| 499 | 500 | ||
| 500 | struct usblp *usblp = file->private_data; | ||
| 501 | /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */ | 501 | /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */ |
| 502 | poll_wait(file, &usblp->rwait, wait); | 502 | poll_wait(file, &usblp->rwait, wait); |
| 503 | poll_wait(file, &usblp->wwait, wait); | 503 | poll_wait(file, &usblp->wwait, wait); |
| 504 | |||
| 505 | mutex_lock(&usblp->mut); | ||
| 506 | if (!usblp->present) | ||
| 507 | ret |= EPOLLHUP; | ||
| 508 | mutex_unlock(&usblp->mut); | ||
| 509 | |||
| 504 | spin_lock_irqsave(&usblp->lock, flags); | 510 | spin_lock_irqsave(&usblp->lock, flags); |
| 505 | ret = ((usblp->bidir && usblp->rcomplete) ? EPOLLIN | EPOLLRDNORM : 0) | | 511 | if (usblp->bidir && usblp->rcomplete) |
| 506 | ((usblp->no_paper || usblp->wcomplete) ? EPOLLOUT | EPOLLWRNORM : 0); | 512 | ret |= EPOLLIN | EPOLLRDNORM; |
| 513 | if (usblp->no_paper || usblp->wcomplete) | ||
| 514 | ret |= EPOLLOUT | EPOLLWRNORM; | ||
| 507 | spin_unlock_irqrestore(&usblp->lock, flags); | 515 | spin_unlock_irqrestore(&usblp->lock, flags); |
| 508 | return ret; | 516 | return ret; |
| 509 | } | 517 | } |
| @@ -748,6 +748,38 @@ void usb_put_intf(struct usb_interface *intf) · 747 unmodified lines | |||
| 748 | } | 748 | } |
| 749 | EXPORT_SYMBOL_GPL(usb_put_intf); | 749 | EXPORT_SYMBOL_GPL(usb_put_intf); |
| 750 | 750 | ||
| 751 | /** | ||
| 752 | * usb_intf_get_dma_device - acquire a reference on the usb interface's DMA endpoint | ||
| 753 | * @intf: the usb interface | ||
| 754 | * | ||
| 755 | * While a USB device cannot perform DMA operations by itself, many USB | ||
| 756 | * controllers can. A call to usb_intf_get_dma_device() returns the DMA endpoint | ||
| 757 | * for the given USB interface, if any. The returned device structure must be | ||
| 758 | * released with put_device(). | ||
| 759 | * | ||
| 760 | * See also usb_get_dma_device(). | ||
| 761 | * | ||
| 762 | * Returns: A reference to the usb interface's DMA endpoint; or NULL if none | ||
| 763 | * exists. | ||
| 764 | */ | ||
| 765 | struct device *usb_intf_get_dma_device(struct usb_interface *intf) | ||
| 766 | { | ||
| 767 | struct usb_device *udev = interface_to_usbdev(intf); | ||
| 768 | struct device *dmadev; | ||
| 769 | |||
| 770 | if (!udev->bus) | ||
| 771 | return NULL; | ||
| 772 | |||
| 773 | dmadev = get_device(udev->bus->sysdev); | ||
| 774 | if (!dmadev || !dmadev->dma_mask) { | ||
| 775 | put_device(dmadev); | ||
| 776 | return NULL; | ||
| 777 | } | ||
| 778 | |||
| 779 | return dmadev; | ||
| 780 | } | ||
| 781 | EXPORT_SYMBOL_GPL(usb_intf_get_dma_device); | ||
| 782 | |||
| 751 | /* USB device locking | 783 | /* USB device locking |
| 752 | * | 784 | * |
| 753 | * USB devices and interfaces are locked using the semaphore in their | 785 | * USB devices and interfaces are locked using the semaphore in their |
| @@ -358,8 +358,10 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) · 357 unmodified lines | |||
| 358 | if (ret) | 358 | if (ret) |
| 359 | dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); | 359 | dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); |
| 360 | 360 | ||
| 361 | if (device_may_wakeup(qcom->dev)) | ||
| 362 | dwc3_qcom_enable_interrupts(qcom); | ||
| 363 | |||
| 361 | qcom->is_suspended = true; | 364 | qcom->is_suspended = true; |
| 362 | dwc3_qcom_enable_interrupts(qcom); | ||
| 363 | 365 | ||
| 364 | return 0; | 366 | return 0; |
| 365 | } | 367 | } |
| @@ -372,7 +374,8 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom) · 6 unmodified lines | |||
| 372 | if (!qcom->is_suspended) | 374 | if (!qcom->is_suspended) |
| 373 | return 0; | 375 | return 0; |
| 374 | 376 | ||
| 375 | dwc3_qcom_disable_interrupts(qcom); | 377 | if (device_may_wakeup(qcom->dev)) |
| 378 | dwc3_qcom_disable_interrupts(qcom); | ||
| 376 | 379 | ||
| 377 | for (i = 0; i < qcom->num_clocks; i++) { | 380 | for (i = 0; i < qcom->num_clocks; i++) { |
| 378 | ret = clk_prepare_enable(qcom->clks[i]); | 381 | ret = clk_prepare_enable(qcom->clks[i]); |
| @@ -650,16 +653,19 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) · 271 unmodified lines | |||
| 650 | ret = of_platform_populate(np, NULL, NULL, dev); | 653 | ret = of_platform_populate(np, NULL, NULL, dev); |
| 651 | if (ret) { | 654 | if (ret) { |
| 652 | dev_err(dev, "failed to register dwc3 core - %d\n", ret); | 655 | dev_err(dev, "failed to register dwc3 core - %d\n", ret); |
| 653 | return ret; | 656 | goto node_put; |
| 654 | } | 657 | } |
| 655 | 658 | ||
| 656 | qcom->dwc3 = of_find_device_by_node(dwc3_np); | 659 | qcom->dwc3 = of_find_device_by_node(dwc3_np); |
| 657 | if (!qcom->dwc3) { | 660 | if (!qcom->dwc3) { |
| 661 | ret = -ENODEV; | ||
| 658 | dev_err(dev, "failed to get dwc3 platform device\n"); | 662 | dev_err(dev, "failed to get dwc3 platform device\n"); |
| 659 | return -ENODEV; | ||
| 660 | } | 663 | } |
| 661 | 664 | ||
| 662 | return 0; | 665 | node_put: |
| 666 | of_node_put(dwc3_np); | ||
| 667 | |||
| 668 | return ret; | ||
| 663 | } | 669 | } |
| 664 | 670 | ||
| 665 | static struct platform_device * | 671 | static struct platform_device * |
| @@ -938,6 +944,8 @@ static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = { · 272 unmodified lines | |||
| 938 | static const struct acpi_device_id dwc3_qcom_acpi_match[] = { | 944 | static const struct acpi_device_id dwc3_qcom_acpi_match[] = { |
| 939 | { "QCOM2430", (unsigned long)&sdm845_acpi_pdata }, | 945 | { "QCOM2430", (unsigned long)&sdm845_acpi_pdata }, |
| 940 | { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata }, | 946 | { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata }, |
| 947 | { "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata }, | ||
| 948 | { "QCOM04A6", (unsigned long)&sdm845_acpi_pdata }, | ||
| 941 | { }, | 949 | { }, |
| 942 | }; | 950 | }; |
| 943 | MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match); | 951 | MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match); |
| @@ -783,8 +783,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) · 782 unmodified lines | |||
| 783 | 783 | ||
| 784 | trace_dwc3_gadget_ep_disable(dep); | 784 | trace_dwc3_gadget_ep_disable(dep); |
| 785 | 785 | ||
| 786 | dwc3_remove_requests(dwc, dep); | ||
| 787 | |||
| 788 | /* make sure HW endpoint isn't stalled */ | 786 | /* make sure HW endpoint isn't stalled */ |
| 789 | if (dep->flags & DWC3_EP_STALL) | 787 | if (dep->flags & DWC3_EP_STALL) |
| 790 | __dwc3_gadget_ep_set_halt(dep, 0, false); | 788 | __dwc3_gadget_ep_set_halt(dep, 0, false); |
| @@ -803,6 +801,8 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) · 12 unmodified lines | |||
| 803 | dep->endpoint.desc = NULL; | 801 | dep->endpoint.desc = NULL; |
| 804 | } | 802 | } |
| 805 | 803 | ||
| 804 | dwc3_remove_requests(dwc, dep); | ||
| 805 | |||
| 806 | return 0; | 806 | return 0; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| @@ -1617,7 +1617,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) · 808 unmodified lines | |||
| 1617 | { | 1617 | { |
| 1618 | struct dwc3 *dwc = dep->dwc; | 1618 | struct dwc3 *dwc = dep->dwc; |
| 1619 | 1619 | ||
| 1620 | if (!dep->endpoint.desc || !dwc->pullups_connected) { | 1620 | if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) { |
| 1621 | dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", | 1621 | dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", |
| 1622 | dep->name); | 1622 | dep->name); |
| 1623 | return -ESHUTDOWN; | 1623 | return -ESHUTDOWN; |
| @@ -2247,6 +2247,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) · 623 unmodified lines | |||
| 2247 | if (!is_on) { | 2247 | if (!is_on) { |
| 2248 | u32 count; | 2248 | u32 count; |
| 2249 | 2249 | ||
| 2250 | dwc->connected = false; | ||
| 2250 | /* | 2251 | /* |
| 2251 | * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a | 2252 | * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a |
| 2252 | * Section 4.1.8 Table 4-7, it states that for a device-initiated | 2253 | * Section 4.1.8 Table 4-7, it states that for a device-initiated |
| @@ -2271,7 +2272,6 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) · 18 unmodified lines | |||
| 2271 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % | 2272 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % |
| 2272 | dwc->ev_buf->length; | 2273 | dwc->ev_buf->length; |
| 2273 | } | 2274 | } |
| 2274 | dwc->connected = false; | ||
| 2275 | } else { | 2275 | } else { |
| 2276 | __dwc3_gadget_start(dwc); | 2276 | __dwc3_gadget_start(dwc); |
| 2277 | } | 2277 | } |
| @@ -3321,8 +3321,6 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) · 1043 unmodified lines | |||
| 3321 | { | 3321 | { |
| 3322 | u32 reg; | 3322 | u32 reg; |
| 3323 | 3323 | ||
| 3324 | dwc->connected = true; | ||
| 3325 | |||
| 3326 | /* | 3324 | /* |
| 3327 | * WORKAROUND: DWC3 revisions <1.88a have an issue which | 3325 | * WORKAROUND: DWC3 revisions <1.88a have an issue which |
| 3328 | * would cause a missing Disconnect Event if there's a | 3326 | * would cause a missing Disconnect Event if there's a |
| @@ -3362,6 +3360,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) · 33 unmodified lines | |||
| 3362 | * transfers." | 3360 | * transfers." |
| 3363 | */ | 3361 | */ |
| 3364 | dwc3_stop_active_transfers(dwc); | 3362 | dwc3_stop_active_transfers(dwc); |
| 3363 | dwc->connected = true; | ||
| 3365 | 3364 | ||
| 3366 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 3365 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
| 3367 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | 3366 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; |
| @@ -97,6 +97,8 @@ struct gadget_config_name { · 96 unmodified lines | |||
| 97 | struct list_head list; | 97 | struct list_head list; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | #define USB_MAX_STRING_WITH_NULL_LEN (USB_MAX_STRING_LEN+1) | ||
| 101 | |||
| 100 | static int usb_string_copy(const char *s, char **s_copy) | 102 | static int usb_string_copy(const char *s, char **s_copy) |
| 101 | { | 103 | { |
| 102 | int ret; | 104 | int ret; |
| @@ -106,12 +108,16 @@ static int usb_string_copy(const char *s, char **s_copy) · 3 unmodified lines | |||
| 106 | if (ret > USB_MAX_STRING_LEN) | 108 | if (ret > USB_MAX_STRING_LEN) |
| 107 | return -EOVERFLOW; | 109 | return -EOVERFLOW; |
| 108 | 110 | ||
| 109 | str = kstrdup(s, GFP_KERNEL); | 111 | if (copy) { |
| 110 | if (!str) | 112 | str = copy; |
| 111 | return -ENOMEM; | 113 | } else { |
| 114 | str = kmalloc(USB_MAX_STRING_WITH_NULL_LEN, GFP_KERNEL); | ||
| 115 | if (!str) | ||
| 116 | return -ENOMEM; | ||
| 117 | } | ||
| 118 | strcpy(str, s); | ||
| 112 | if (str[ret - 1] == '\n') | 119 | if (str[ret - 1] == '\n') |
| 113 | str[ret - 1] = '\0'; | 120 | str[ret - 1] = '\0'; |
| 114 | kfree(copy); | ||
| 115 | *s_copy = str; | 121 | *s_copy = str; |
| 116 | return 0; | 122 | return 0; |
| 117 | } | 123 | } |
| @@ -499,6 +499,7 @@ static void f_audio_disable(struct usb_function *f) · 498 unmodified lines | |||
| 499 | uac1->as_out_alt = 0; | 499 | uac1->as_out_alt = 0; |
| 500 | uac1->as_in_alt = 0; | 500 | uac1->as_in_alt = 0; |
| 501 | 501 | ||
| 502 | u_audio_stop_playback(&uac1->g_audio); | ||
| 502 | u_audio_stop_capture(&uac1->g_audio); | 503 | u_audio_stop_capture(&uac1->g_audio); |
| 503 | } | 504 | } |
| 504 | 505 | ||
| @@ -478,7 +478,7 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, · 477 unmodified lines | |||
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | max_size_bw = num_channels(chmask) * ssize * | 480 | max_size_bw = num_channels(chmask) * ssize * |
| 481 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); | 481 | ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1); |
| 482 | ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, | 482 | ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, |
| 483 | max_size_ep)); | 483 | max_size_ep)); |
| 484 | 484 | ||
| @@ -182,12 +182,11 @@ out: \ · 181 unmodified lines | |||
| 182 | size_t len) \ | 182 | size_t len) \ |
| 183 | { \ | 183 | { \ |
| 184 | struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ | 184 | struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| 185 | int ret; \ | 185 | int ret = -EINVAL; \ |
| 186 | u8 val; \ | 186 | u8 val; \ |
| 187 | \ | 187 | \ |
| 188 | mutex_lock(&opts->lock); \ | 188 | mutex_lock(&opts->lock); \ |
| 189 | ret = sscanf(page, "%02hhx", &val); \ | 189 | if (sscanf(page, "%02hhx", &val) > 0) { \ |
| 190 | if (ret > 0) { \ | ||
| 191 | opts->_n_ = val; \ | 190 | opts->_n_ = val; \ |
| 192 | ret = len; \ | 191 | ret = len; \ |
| 193 | } \ | 192 | } \ |
| @@ -1773,8 +1773,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev) · 1772 unmodified lines | |||
| 1773 | udc_info = dev_get_platdata(&pdev->dev); | 1773 | udc_info = dev_get_platdata(&pdev->dev); |
| 1774 | 1774 | ||
| 1775 | base_addr = devm_platform_ioremap_resource(pdev, 0); | 1775 | base_addr = devm_platform_ioremap_resource(pdev, 0); |
| 1776 | if (!base_addr) { | 1776 | if (IS_ERR(base_addr)) { |
| 1777 | retval = -ENOMEM; | 1777 | retval = PTR_ERR(base_addr); |
| 1778 | goto err_mem; | 1778 | goto err_mem; |
| 1779 | } | 1779 | } |
| 1780 | 1780 | ||
| @@ -66,6 +66,7 @@ · 65 unmodified lines | |||
| 66 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 | 66 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 |
| 67 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 | 67 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 |
| 68 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 | 68 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 |
| 69 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 | ||
| 69 | 70 | ||
| 70 | static const char hcd_name[] = "xhci_hcd"; | 71 | static const char hcd_name[] = "xhci_hcd"; |
| 71 | 72 | ||
| @@ -276,11 +277,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 204 unmodified lines | |||
| 276 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) | 277 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) |
| 277 | xhci->quirks |= XHCI_BROKEN_STREAMS; | 278 | xhci->quirks |= XHCI_BROKEN_STREAMS; |
| 278 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | 279 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && |
| 279 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) | 280 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) { |
| 280 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | 281 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
| 282 | xhci->quirks |= XHCI_NO_64BIT_SUPPORT; | ||
| 283 | } | ||
| 281 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | 284 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && |
| 282 | (pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI || | 285 | (pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI || |
| 283 | pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI)) | 286 | pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI || |
| 287 | pdev->device == PCI_DEVICE_ID_ASMEDIA_3242_XHCI)) | ||
| 284 | xhci->quirks |= XHCI_NO_64BIT_SUPPORT; | 288 | xhci->quirks |= XHCI_NO_64BIT_SUPPORT; |
| 285 | 289 | ||
| 286 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | 290 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && |
| @@ -295,6 +299,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 8 unmodified lines | |||
| 295 | pdev->device == 0x9026) | 299 | pdev->device == 0x9026) |
| 296 | xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; | 300 | xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; |
| 297 | 301 | ||
| 302 | if (pdev->vendor == PCI_VENDOR_ID_AMD && | ||
| 303 | (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2 || | ||
| 304 | pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4)) | ||
| 305 | xhci->quirks |= XHCI_NO_SOFT_RETRY; | ||
| 306 | |||
| 298 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 307 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
| 299 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | 308 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
| 300 | "QUIRK: Resetting on resume"); | 309 | "QUIRK: Resetting on resume"); |
| @@ -2484,7 +2484,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, · 2483 unmodified lines | |||
| 2484 | remaining = 0; | 2484 | remaining = 0; |
| 2485 | break; | 2485 | break; |
| 2486 | case COMP_USB_TRANSACTION_ERROR: | 2486 | case COMP_USB_TRANSACTION_ERROR: |
| 2487 | if ((ep_ring->err_count++ > MAX_SOFT_RETRY) || | 2487 | if (xhci->quirks & XHCI_NO_SOFT_RETRY || |
| 2488 | (ep_ring->err_count++ > MAX_SOFT_RETRY) || | ||
| 2488 | le32_to_cpu(slot_ctx->tt_info) & TT_SLOT) | 2489 | le32_to_cpu(slot_ctx->tt_info) & TT_SLOT) |
| 2489 | break; | 2490 | break; |
| 2490 | 2491 | ||
| @@ -883,44 +883,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) · 882 unmodified lines | |||
| 883 | xhci_set_cmd_ring_deq(xhci); | 883 | xhci_set_cmd_ring_deq(xhci); |
| 884 | } | 884 | } |
| 885 | 885 | ||
| 886 | static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci) | 886 | /* |
| 887 | * Disable port wake bits if do_wakeup is not set. | ||
| 888 | * | ||
| 889 | * Also clear a possible internal port wake state left hanging for ports that | ||
| 890 | * detected termination but never successfully enumerated (trained to 0U). | ||
| 891 | * Internal wake causes immediate xHCI wake after suspend. PORT_CSC write done | ||
| 892 | * at enumeration clears this wake, force one here as well for unconnected ports | ||
| 893 | */ | ||
| 894 | |||
| 895 | static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci, | ||
| 896 | struct xhci_hub *rhub, | ||
| 897 | bool do_wakeup) | ||
| 887 | { | 898 | { |
| 888 | struct xhci_port **ports; | ||
| 889 | int port_index; | ||
| 890 | unsigned long flags; | 899 | unsigned long flags; |
| 891 | u32 t1, t2, portsc; | 900 | u32 t1, t2, portsc; |
| 901 | int i; | ||
| 892 | 902 | ||
| 893 | spin_lock_irqsave(&xhci->lock, flags); | 903 | spin_lock_irqsave(&xhci->lock, flags); |
| 894 | 904 | ||
| 895 | /* disable usb3 ports Wake bits */ | 905 | for (i = 0; i < rhub->num_ports; i++) { |
| 896 | port_index = xhci->usb3_rhub.num_ports; | 906 | portsc = readl(rhub->ports[i]->addr); |
| 897 | ports = xhci->usb3_rhub.ports; | 907 | t1 = xhci_port_state_to_neutral(portsc); |
| 898 | while (port_index--) { | 908 | t2 = t1; |
| 899 | t1 = readl(ports[port_index]->addr); | 909 | |
| 900 | portsc = t1; | 910 | /* clear wake bits if do_wake is not set */ |
| 901 | t1 = xhci_port_state_to_neutral(t1); | 911 | if (!do_wakeup) |
| 902 | t2 = t1 & ~PORT_WAKE_BITS; | 912 | t2 &= ~PORT_WAKE_BITS; |
| 903 | if (t1 != t2) { | 913 | |
| 904 | writel(t2, ports[port_index]->addr); | 914 | /* Don't touch csc bit if connected or connect change is set */ |
| 905 | xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n", | 915 | if (!(portsc & (PORT_CSC | PORT_CONNECT))) |
| 906 | xhci->usb3_rhub.hcd->self.busnum, | 916 | t2 |= PORT_CSC; |
| 907 | port_index + 1, portsc, t2); | ||
| 908 | } | ||
| 909 | } | ||
| 910 | 917 | ||
| 911 | /* disable usb2 ports Wake bits */ | ||
| 912 | port_index = xhci->usb2_rhub.num_ports; | ||
| 913 | ports = xhci->usb2_rhub.ports; | ||
| 914 | while (port_index--) { | ||
| 915 | t1 = readl(ports[port_index]->addr); | ||
| 916 | portsc = t1; | ||
| 917 | t1 = xhci_port_state_to_neutral(t1); | ||
| 918 | t2 = t1 & ~PORT_WAKE_BITS; | ||
| 919 | if (t1 != t2) { | 918 | if (t1 != t2) { |
| 920 | writel(t2, ports[port_index]->addr); | 919 | writel(t2, rhub->ports[i]->addr); |
| 921 | xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n", | 920 | xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n", |
| 922 | xhci->usb2_rhub.hcd->self.busnum, | 921 | rhub->hcd->self.busnum, i + 1, portsc, t2); |
| 923 | port_index + 1, portsc, t2); | ||
| 924 | } | 922 | } |
| 925 | } | 923 | } |
| 926 | spin_unlock_irqrestore(&xhci->lock, flags); | 924 | spin_unlock_irqrestore(&xhci->lock, flags); |
| @@ -983,8 +981,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) · 56 unmodified lines | |||
| 983 | return -EINVAL; | 981 | return -EINVAL; |
| 984 | 982 | ||
| 985 | /* Clear root port wake on bits if wakeup not allowed. */ | 983 | /* Clear root port wake on bits if wakeup not allowed. */ |
| 986 | if (!do_wakeup) | 984 | xhci_disable_hub_port_wake(xhci, &xhci->usb3_rhub, do_wakeup); |
| 987 | xhci_disable_port_wake_on_bits(xhci); | 985 | xhci_disable_hub_port_wake(xhci, &xhci->usb2_rhub, do_wakeup); |
| 988 | 986 | ||
| 989 | if (!HCD_HW_ACCESSIBLE(hcd)) | 987 | if (!HCD_HW_ACCESSIBLE(hcd)) |
| 990 | return 0; | 988 | return 0; |
| @@ -1088,6 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) · 97 unmodified lines | |||
| 1088 | struct usb_hcd *secondary_hcd; | 1086 | struct usb_hcd *secondary_hcd; |
| 1089 | int retval = 0; | 1087 | int retval = 0; |
| 1090 | bool comp_timer_running = false; | 1088 | bool comp_timer_running = false; |
| 1089 | bool pending_portevent = false; | ||
| 1091 | 1090 | ||
| 1092 | if (!hcd->state) | 1091 | if (!hcd->state) |
| 1093 | return 0; | 1092 | return 0; |
| @@ -1226,13 +1225,22 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) · 132 unmodified lines | |||
| 1226 | 1225 | ||
| 1227 | done: | 1226 | done: |
| 1228 | if (retval == 0) { | 1227 | if (retval == 0) { |
| 1229 | /* Resume root hubs only when have pending events. */ | 1228 | /* |
| 1230 | if (xhci_pending_portevent(xhci)) { | 1229 | * Resume roothubs only if there are pending events. |
| 1230 | * USB 3 devices resend U3 LFPS wake after a 100ms delay if | ||
| 1231 | * the first wake signalling failed, give it that chance. | ||
| 1232 | */ | ||
| 1233 | pending_portevent = xhci_pending_portevent(xhci); | ||
| 1234 | if (!pending_portevent) { | ||
| 1235 | msleep(120); | ||
| 1236 | pending_portevent = xhci_pending_portevent(xhci); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | if (pending_portevent) { | ||
| 1231 | usb_hcd_resume_root_hub(xhci->shared_hcd); | 1240 | usb_hcd_resume_root_hub(xhci->shared_hcd); |
| 1232 | usb_hcd_resume_root_hub(hcd); | 1241 | usb_hcd_resume_root_hub(hcd); |
| 1233 | } | 1242 | } |
| 1234 | } | 1243 | } |
| 1235 | |||
| 1236 | /* | 1244 | /* |
| 1237 | * If system is subject to the Quirk, Compliance Mode Timer needs to | 1245 | * If system is subject to the Quirk, Compliance Mode Timer needs to |
| 1238 | * be re-initialized Always after a system resume. Ports are subject | 1246 | * be re-initialized Always after a system resume. Ports are subject |
| @@ -1891,6 +1891,7 @@ struct xhci_hcd { · 1890 unmodified lines | |||
| 1891 | #define XHCI_SKIP_PHY_INIT BIT_ULL(37) | 1891 | #define XHCI_SKIP_PHY_INIT BIT_ULL(37) |
| 1892 | #define XHCI_DISABLE_SPARSE BIT_ULL(38) | 1892 | #define XHCI_DISABLE_SPARSE BIT_ULL(38) |
| 1893 | #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) | 1893 | #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) |
| 1894 | #define XHCI_NO_SOFT_RETRY BIT_ULL(40) | ||
| 1894 | 1895 | ||
| 1895 | unsigned int num_active_eps; | 1896 | unsigned int num_active_eps; |
| 1896 | unsigned int limit_active_eps; | 1897 | unsigned int limit_active_eps; |
| @@ -117,7 +117,6 @@ MODULE_DEVICE_TABLE(usb, ld_usb_table); · 116 unmodified lines | |||
| 117 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); | 117 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); |
| 118 | MODULE_DESCRIPTION("LD USB Driver"); | 118 | MODULE_DESCRIPTION("LD USB Driver"); |
| 119 | MODULE_LICENSE("GPL"); | 119 | MODULE_LICENSE("GPL"); |
| 120 | MODULE_SUPPORTED_DEVICE("LD USB Devices"); | ||
| 121 | 120 | ||
| 122 | /* All interrupt in transfers are collected in a ring buffer to | 121 | /* All interrupt in transfers are collected in a ring buffer to |
| 123 | * avoid racing conditions and get better performance of the driver. | 122 | * avoid racing conditions and get better performance of the driver. |
| @@ -746,6 +746,8 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, · 745 unmodified lines | |||
| 746 | 746 | ||
| 747 | void usbhs_pipe_free(struct usbhs_pipe *pipe) | 747 | void usbhs_pipe_free(struct usbhs_pipe *pipe) |
| 748 | { | 748 | { |
| 749 | usbhsp_pipe_select(pipe); | ||
| 750 | usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0); | ||
| 749 | usbhsp_put_pipe(pipe); | 751 | usbhsp_put_pipe(pipe); |
| 750 | } | 752 | } |
| 751 | 753 | ||
| @@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = { · 85 unmodified lines | |||
| 86 | { USB_DEVICE(0x1a86, 0x7522) }, | 86 | { USB_DEVICE(0x1a86, 0x7522) }, |
| 87 | { USB_DEVICE(0x1a86, 0x7523) }, | 87 | { USB_DEVICE(0x1a86, 0x7523) }, |
| 88 | { USB_DEVICE(0x4348, 0x5523) }, | 88 | { USB_DEVICE(0x4348, 0x5523) }, |
| 89 | { USB_DEVICE(0x9986, 0x7523) }, | ||
| 89 | { }, | 90 | { }, |
| 90 | }; | 91 | }; |
| 91 | MODULE_DEVICE_TABLE(usb, id_table); | 92 | MODULE_DEVICE_TABLE(usb, id_table); |
| @@ -145,6 +145,7 @@ static const struct usb_device_id id_table[] = { · 144 unmodified lines | |||
| 145 | { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ | 145 | { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ |
| 146 | { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ | 146 | { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ |
| 147 | { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ | 147 | { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ |
| 148 | { USB_DEVICE(0x10C4, 0x88D8) }, /* Acuity Brands nLight Air Adapter */ | ||
| 148 | { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */ | 149 | { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */ |
| 149 | { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */ | 150 | { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */ |
| 150 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ | 151 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ |
| @@ -201,6 +202,8 @@ static const struct usb_device_id id_table[] = { · 50 unmodified lines | |||
| 201 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ | 202 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ |
| 202 | { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ | 203 | { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ |
| 203 | { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ | 204 | { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ |
| 205 | { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 Display serial interface */ | ||
| 206 | { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */ | ||
| 204 | { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ | 207 | { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ |
| 205 | { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ | 208 | { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ |
| 206 | { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ | 209 | { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ |
| @@ -3003,26 +3003,32 @@ static int edge_startup(struct usb_serial *serial) · 3002 unmodified lines | |||
| 3003 | response = -ENODEV; | 3003 | response = -ENODEV; |
| 3004 | } | 3004 | } |
| 3005 | 3005 | ||
| 3006 | usb_free_urb(edge_serial->interrupt_read_urb); | 3006 | goto error; |
| 3007 | kfree(edge_serial->interrupt_in_buffer); | ||
| 3008 | |||
| 3009 | usb_free_urb(edge_serial->read_urb); | ||
| 3010 | kfree(edge_serial->bulk_in_buffer); | ||
| 3011 | |||
| 3012 | kfree(edge_serial); | ||
| 3013 | |||
| 3014 | return response; | ||
| 3015 | } | 3007 | } |
| 3016 | 3008 | ||
| 3017 | /* start interrupt read for this edgeport this interrupt will | 3009 | /* start interrupt read for this edgeport this interrupt will |
| 3018 | * continue as long as the edgeport is connected */ | 3010 | * continue as long as the edgeport is connected */ |
| 3019 | response = usb_submit_urb(edge_serial->interrupt_read_urb, | 3011 | response = usb_submit_urb(edge_serial->interrupt_read_urb, |
| 3020 | GFP_KERNEL); | 3012 | GFP_KERNEL); |
| 3021 | if (response) | 3013 | if (response) { |
| 3022 | dev_err(ddev, "%s - Error %d submitting control urb\n", | 3014 | dev_err(ddev, "%s - Error %d submitting control urb\n", |
| 3023 | __func__, response); | 3015 | __func__, response); |
| 3016 | |||
| 3017 | goto error; | ||
| 3018 | } | ||
| 3024 | } | 3019 | } |
| 3025 | return response; | 3020 | return response; |
| 3021 | |||
| 3022 | error: | ||
| 3023 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
| 3024 | kfree(edge_serial->interrupt_in_buffer); | ||
| 3025 | |||
| 3026 | usb_free_urb(edge_serial->read_urb); | ||
| 3027 | kfree(edge_serial->bulk_in_buffer); | ||
| 3028 | |||
| 3029 | kfree(edge_serial); | ||
| 3030 | |||
| 3031 | return response; | ||
| 3026 | } | 3032 | } |
| 3027 | 3033 | ||
| 3028 | 3034 | ||
| @@ -545,37 +545,13 @@ static void xr_close(struct usb_serial_port *port) · 544 unmodified lines | |||
| 545 | 545 | ||
| 546 | static int xr_probe(struct usb_serial *serial, const struct usb_device_id *id) | 546 | static int xr_probe(struct usb_serial *serial, const struct usb_device_id *id) |
| 547 | { | 547 | { |
| 548 | struct usb_driver *driver = serial->type->usb_driver; | ||
| 549 | struct usb_interface *control_interface; | ||
| 550 | int ret; | ||
| 551 | |||
| 552 | /* Don't bind to control interface */ | 548 | /* Don't bind to control interface */ |
| 553 | if (serial->interface->cur_altsetting->desc.bInterfaceNumber == 0) | 549 | if (serial->interface->cur_altsetting->desc.bInterfaceNumber == 0) |
| 554 | return -ENODEV; | 550 | return -ENODEV; |
| 555 | 551 | ||
| 556 | /* But claim the control interface during data interface probe */ | ||
| 557 | control_interface = usb_ifnum_to_if(serial->dev, 0); | ||
| 558 | if (!control_interface) | ||
| 559 | return -ENODEV; | ||
| 560 | |||
| 561 | ret = usb_driver_claim_interface(driver, control_interface, NULL); | ||
| 562 | if (ret) { | ||
| 563 | dev_err(&serial->interface->dev, "Failed to claim control interface\n"); | ||
| 564 | return ret; | ||
| 565 | } | ||
| 566 | |||
| 567 | return 0; | 552 | return 0; |
| 568 | } | 553 | } |
| 569 | 554 | ||
| 570 | static void xr_disconnect(struct usb_serial *serial) | ||
| 571 | { | ||
| 572 | struct usb_driver *driver = serial->type->usb_driver; | ||
| 573 | struct usb_interface *control_interface; | ||
| 574 | |||
| 575 | control_interface = usb_ifnum_to_if(serial->dev, 0); | ||
| 576 | usb_driver_release_interface(driver, control_interface); | ||
| 577 | } | ||
| 578 | |||
| 579 | static const struct usb_device_id id_table[] = { | 555 | static const struct usb_device_id id_table[] = { |
| 580 | { USB_DEVICE(0x04e2, 0x1410) }, /* XR21V141X */ | 556 | { USB_DEVICE(0x04e2, 0x1410) }, /* XR21V141X */ |
| 581 | { } | 557 | { } |
| @@ -590,7 +566,6 @@ static struct usb_serial_driver xr_device = { · 8 unmodified lines | |||
| 590 | .id_table = id_table, | 566 | .id_table = id_table, |
| 591 | .num_ports = 1, | 567 | .num_ports = 1, |
| 592 | .probe = xr_probe, | 568 | .probe = xr_probe, |
| 593 | .disconnect = xr_disconnect, | ||
| 594 | .open = xr_open, | 569 | .open = xr_open, |
| 595 | .close = xr_close, | 570 | .close = xr_close, |
| 596 | .break_ctl = xr_break_ctl, | 571 | .break_ctl = xr_break_ctl, |
| @@ -656,6 +656,13 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) · 655 unmodified lines | |||
| 656 | need_auto_sense = 1; | 656 | need_auto_sense = 1; |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | /* Some devices (Kindle) require another command after SYNC CACHE */ | ||
| 660 | if ((us->fflags & US_FL_SENSE_AFTER_SYNC) && | ||
| 661 | srb->cmnd[0] == SYNCHRONIZE_CACHE) { | ||
| 662 | usb_stor_dbg(us, "-- sense after SYNC CACHE\n"); | ||
| 663 | need_auto_sense = 1; | ||
| 664 | } | ||
| 665 | |||
| 659 | /* | 666 | /* |
| 660 | * If we have a failure, we're going to do a REQUEST_SENSE | 667 | * If we have a failure, we're going to do a REQUEST_SENSE |
| 661 | * automatically. Note that we differentiate between a command | 668 | * automatically. Note that we differentiate between a command |
| @@ -2211,6 +2211,18 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, · 2210 unmodified lines | |||
| 2211 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 2211 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 2212 | US_FL_NO_READ_DISC_INFO ), | 2212 | US_FL_NO_READ_DISC_INFO ), |
| 2213 | 2213 | ||
| 2214 | /* | ||
| 2215 | * Reported by Matthias Schwarzott <zzam@gentoo.org> | ||
| 2216 | * The Amazon Kindle treats SYNCHRONIZE CACHE as an indication that | ||
| 2217 | * the host may be finished with it, and automatically ejects its | ||
| 2218 | * emulated media unless it receives another command within one second. | ||
| 2219 | */ | ||
| 2220 | UNUSUAL_DEV( 0x1949, 0x0004, 0x0000, 0x9999, | ||
| 2221 | "Amazon", | ||
| 2222 | "Kindle", | ||
| 2223 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 2224 | US_FL_SENSE_AFTER_SYNC ), | ||
| 2225 | |||
| 2214 | /* | 2226 | /* |
| 2215 | * Reported by Oliver Neukum <oneukum@suse.com> | 2227 | * Reported by Oliver Neukum <oneukum@suse.com> |
| 2216 | * This device morphes spontaneously into another device if the access | 2228 | * This device morphes spontaneously into another device if the access |
| @@ -942,6 +942,7 @@ static int tcpm_set_current_limit(struct tcpm_port *port, u32 max_ma, u32 mv) · 941 unmodified lines | |||
| 942 | 942 | ||
| 943 | port->supply_voltage = mv; | 943 | port->supply_voltage = mv; |
| 944 | port->current_limit = max_ma; | 944 | port->current_limit = max_ma; |
| 945 | power_supply_changed(port->psy); | ||
| 945 | 946 | ||
| 946 | if (port->tcpc->set_current_limit) | 947 | if (port->tcpc->set_current_limit) |
| 947 | ret = port->tcpc->set_current_limit(port->tcpc, max_ma, mv); | 948 | ret = port->tcpc->set_current_limit(port->tcpc, max_ma, mv); |
| @@ -2928,6 +2929,7 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, · 1980 unmodified lines | |||
| 2928 | 2929 | ||
| 2929 | port->pps_data.supported = false; | 2930 | port->pps_data.supported = false; |
| 2930 | port->usb_type = POWER_SUPPLY_USB_TYPE_PD; | 2931 | port->usb_type = POWER_SUPPLY_USB_TYPE_PD; |
| 2932 | power_supply_changed(port->psy); | ||
| 2931 | 2933 | ||
| 2932 | /* | 2934 | /* |
| 2933 | * Select the source PDO providing the most power which has a | 2935 | * Select the source PDO providing the most power which has a |
| @@ -2952,6 +2954,7 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, · 18 unmodified lines | |||
| 2952 | port->pps_data.supported = true; | 2954 | port->pps_data.supported = true; |
| 2953 | port->usb_type = | 2955 | port->usb_type = |
| 2954 | POWER_SUPPLY_USB_TYPE_PD_PPS; | 2956 | POWER_SUPPLY_USB_TYPE_PD_PPS; |
| 2957 | power_supply_changed(port->psy); | ||
| 2955 | } | 2958 | } |
| 2956 | continue; | 2959 | continue; |
| 2957 | default: | 2960 | default: |
| @@ -3109,6 +3112,7 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) · 151 unmodified lines | |||
| 3109 | port->pps_data.out_volt)); | 3112 | port->pps_data.out_volt)); |
| 3110 | port->pps_data.op_curr = min(port->pps_data.max_curr, | 3113 | port->pps_data.op_curr = min(port->pps_data.max_curr, |
| 3111 | port->pps_data.op_curr); | 3114 | port->pps_data.op_curr); |
| 3115 | power_supply_changed(port->psy); | ||
| 3112 | } | 3116 | } |
| 3113 | 3117 | ||
| 3114 | return src_pdo; | 3118 | return src_pdo; |
| @@ -3344,6 +3348,7 @@ static int tcpm_set_charge(struct tcpm_port *port, bool charge) · 229 unmodified lines | |||
| 3344 | return ret; | 3348 | return ret; |
| 3345 | } | 3349 | } |
| 3346 | port->vbus_charge = charge; | 3350 | port->vbus_charge = charge; |
| 3351 | power_supply_changed(port->psy); | ||
| 3347 | return 0; | 3352 | return 0; |
| 3348 | } | 3353 | } |
| 3349 | 3354 | ||
| @@ -3523,6 +3528,7 @@ static void tcpm_reset_port(struct tcpm_port *port) · 173 unmodified lines | |||
| 3523 | port->try_src_count = 0; | 3528 | port->try_src_count = 0; |
| 3524 | port->try_snk_count = 0; | 3529 | port->try_snk_count = 0; |
| 3525 | port->usb_type = POWER_SUPPLY_USB_TYPE_C; | 3530 | port->usb_type = POWER_SUPPLY_USB_TYPE_C; |
| 3531 | power_supply_changed(port->psy); | ||
| 3526 | port->nr_sink_caps = 0; | 3532 | port->nr_sink_caps = 0; |
| 3527 | port->sink_cap_done = false; | 3533 | port->sink_cap_done = false; |
| 3528 | if (port->tcpc->enable_frs) | 3534 | if (port->tcpc->enable_frs) |
| @@ -5167,7 +5173,7 @@ static void tcpm_enable_frs_work(struct kthread_work *work) · 1638 unmodified lines | |||
| 5167 | goto unlock; | 5173 | goto unlock; |
| 5168 | 5174 | ||
| 5169 | /* Send when the state machine is idle */ | 5175 | /* Send when the state machine is idle */ |
| 5170 | if (port->state != SNK_READY || port->vdm_state != VDM_STATE_DONE || port->send_discover) | 5176 | if (port->state != SNK_READY || port->vdm_sm_running || port->send_discover) |
| 5171 | goto resched; | 5177 | goto resched; |
| 5172 | 5178 | ||
| 5173 | port->upcoming_state = GET_SINK_CAP; | 5179 | port->upcoming_state = GET_SINK_CAP; |
| @@ -5905,7 +5911,7 @@ static int tcpm_psy_set_prop(struct power_supply *psy, · 731 unmodified lines | |||
| 5905 | ret = -EINVAL; | 5911 | ret = -EINVAL; |
| 5906 | break; | 5912 | break; |
| 5907 | } | 5913 | } |
| 5908 | 5914 | power_supply_changed(port->psy); | |
| 5909 | return ret; | 5915 | return ret; |
| 5910 | } | 5916 | } |
| 5911 | 5917 | ||
| @@ -6058,6 +6064,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) · 146 unmodified lines | |||
| 6058 | err = devm_tcpm_psy_register(port); | 6064 | err = devm_tcpm_psy_register(port); |
| 6059 | if (err) | 6065 | if (err) |
| 6060 | goto out_role_sw_put; | 6066 | goto out_role_sw_put; |
| 6067 | power_supply_changed(port->psy); | ||
| 6061 | 6068 | ||
| 6062 | port->typec_port = typec_register_port(port->dev, &port->typec_caps); | 6069 | port->typec_port = typec_register_port(port->dev, &port->typec_caps); |
| 6063 | if (IS_ERR(port->typec_port)) { | 6070 | if (IS_ERR(port->typec_port)) { |
| @@ -64,7 +64,6 @@ enum { · 63 unmodified lines | |||
| 64 | struct tps6598x_rx_identity_reg { | 64 | struct tps6598x_rx_identity_reg { |
| 65 | u8 status; | 65 | u8 status; |
| 66 | struct usb_pd_identity identity; | 66 | struct usb_pd_identity identity; |
| 67 | u32 vdo[3]; | ||
| 68 | } __packed; | 67 | } __packed; |
| 69 | 68 | ||
| 70 | /* Standard Task return codes */ | 69 | /* Standard Task return codes */ |
| @@ -46,6 +46,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a · 45 unmodified lines | |||
| 46 | int sockfd = 0; | 46 | int sockfd = 0; |
| 47 | struct socket *socket; | 47 | struct socket *socket; |
| 48 | int rv; | 48 | int rv; |
| 49 | struct task_struct *tcp_rx = NULL; | ||
| 50 | struct task_struct *tcp_tx = NULL; | ||
| 49 | 51 | ||
| 50 | if (!sdev) { | 52 | if (!sdev) { |
| 51 | dev_err(dev, "sdev is null\n"); | 53 | dev_err(dev, "sdev is null\n"); |
| @@ -69,23 +71,47 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a · 17 unmodified lines | |||
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | socket = sockfd_lookup(sockfd, &err); | 73 | socket = sockfd_lookup(sockfd, &err); |
| 72 | if (!socket) | 74 | if (!socket) { |
| 75 | dev_err(dev, "failed to lookup sock"); | ||
| 73 | goto err; | 76 | goto err; |
| 77 | } | ||
| 74 | 78 | ||
| 75 | sdev->ud.tcp_socket = socket; | 79 | if (socket->type != SOCK_STREAM) { |
| 76 | sdev->ud.sockfd = sockfd; | 80 | dev_err(dev, "Expecting SOCK_STREAM - found %d", |
| 81 | socket->type); | ||
| 82 | goto sock_err; | ||
| 83 | } | ||
| 77 | 84 | ||
| 85 | /* unlock and create threads and get tasks */ | ||
| 78 | spin_unlock_irq(&sdev->ud.lock); | 86 | spin_unlock_irq(&sdev->ud.lock); |
| 87 | tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx"); | ||
| 88 | if (IS_ERR(tcp_rx)) { | ||
| 89 | sockfd_put(socket); | ||
| 90 | return -EINVAL; | ||
| 91 | } | ||
| 92 | tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx"); | ||
| 93 | if (IS_ERR(tcp_tx)) { | ||
| 94 | kthread_stop(tcp_rx); | ||
| 95 | sockfd_put(socket); | ||
| 96 | return -EINVAL; | ||
| 97 | } | ||
| 79 | 98 | ||
| 80 | sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, | 99 | /* get task structs now */ |
| 81 | "stub_rx"); | 100 | get_task_struct(tcp_rx); |
| 82 | sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, | 101 | get_task_struct(tcp_tx); |
| 83 | "stub_tx"); | ||
| 84 | 102 | ||
| 103 | /* lock and update sdev->ud state */ | ||
| 85 | spin_lock_irq(&sdev->ud.lock); | 104 | spin_lock_irq(&sdev->ud.lock); |
| 105 | sdev->ud.tcp_socket = socket; | ||
| 106 | sdev->ud.sockfd = sockfd; | ||
| 107 | sdev->ud.tcp_rx = tcp_rx; | ||
| 108 | sdev->ud.tcp_tx = tcp_tx; | ||
| 86 | sdev->ud.status = SDEV_ST_USED; | 109 | sdev->ud.status = SDEV_ST_USED; |
| 87 | spin_unlock_irq(&sdev->ud.lock); | 110 | spin_unlock_irq(&sdev->ud.lock); |
| 88 | 111 | ||
| 112 | wake_up_process(sdev->ud.tcp_rx); | ||
| 113 | wake_up_process(sdev->ud.tcp_tx); | ||
| 114 | |||
| 89 | } else { | 115 | } else { |
| 90 | dev_info(dev, "stub down\n"); | 116 | dev_info(dev, "stub down\n"); |
| 91 | 117 | ||
| @@ -100,6 +126,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a · 8 unmodified lines | |||
| 100 | 126 | ||
| 101 | return count; | 127 | return count; |
| 102 | 128 | ||
| 129 | sock_err: | ||
| 130 | sockfd_put(socket); | ||
| 103 | err: | 131 | err: |
| 104 | spin_unlock_irq(&sdev->ud.lock); | 132 | spin_unlock_irq(&sdev->ud.lock); |
| 105 | return -EINVAL; | 133 | return -EINVAL; |
| @@ -312,6 +312,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, · 311 unmodified lines | |||
| 312 | struct vhci *vhci; | 312 | struct vhci *vhci; |
| 313 | int err; | 313 | int err; |
| 314 | unsigned long flags; | 314 | unsigned long flags; |
| 315 | struct task_struct *tcp_rx = NULL; | ||
| 316 | struct task_struct *tcp_tx = NULL; | ||
| 315 | 317 | ||
| 316 | /* | 318 | /* |
| 317 | * @rhport: port number of vhci_hcd | 319 | * @rhport: port number of vhci_hcd |
| @@ -349,12 +351,35 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, · 31 unmodified lines | |||
| 349 | 351 | ||
| 350 | /* Extract socket from fd. */ | 352 | /* Extract socket from fd. */ |
| 351 | socket = sockfd_lookup(sockfd, &err); | 353 | socket = sockfd_lookup(sockfd, &err); |
| 352 | if (!socket) | 354 | if (!socket) { |
| 355 | dev_err(dev, "failed to lookup sock"); | ||
| 353 | return -EINVAL; | 356 | return -EINVAL; |
| 357 | } | ||
| 358 | if (socket->type != SOCK_STREAM) { | ||
| 359 | dev_err(dev, "Expecting SOCK_STREAM - found %d", | ||
| 360 | socket->type); | ||
| 361 | sockfd_put(socket); | ||
| 362 | return -EINVAL; | ||
| 363 | } | ||
| 364 | |||
| 365 | /* create threads before locking */ | ||
| 366 | tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); | ||
| 367 | if (IS_ERR(tcp_rx)) { | ||
| 368 | sockfd_put(socket); | ||
| 369 | return -EINVAL; | ||
| 370 | } | ||
| 371 | tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); | ||
| 372 | if (IS_ERR(tcp_tx)) { | ||
| 373 | kthread_stop(tcp_rx); | ||
| 374 | sockfd_put(socket); | ||
| 375 | return -EINVAL; | ||
| 376 | } | ||
| 354 | 377 | ||
| 355 | /* now need lock until setting vdev status as used */ | 378 | /* get task structs now */ |
| 379 | get_task_struct(tcp_rx); | ||
| 380 | get_task_struct(tcp_tx); | ||
| 356 | 381 | ||
| 357 | /* begin a lock */ | 382 | /* now begin lock until setting vdev status set */ |
| 358 | spin_lock_irqsave(&vhci->lock, flags); | 383 | spin_lock_irqsave(&vhci->lock, flags); |
| 359 | spin_lock(&vdev->ud.lock); | 384 | spin_lock(&vdev->ud.lock); |
| 360 | 385 | ||
| @@ -364,6 +389,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, · 3 unmodified lines | |||
| 364 | spin_unlock_irqrestore(&vhci->lock, flags); | 389 | spin_unlock_irqrestore(&vhci->lock, flags); |
| 365 | 390 | ||
| 366 | sockfd_put(socket); | 391 | sockfd_put(socket); |
| 392 | kthread_stop_put(tcp_rx); | ||
| 393 | kthread_stop_put(tcp_tx); | ||
| 367 | 394 | ||
| 368 | dev_err(dev, "port %d already used\n", rhport); | 395 | dev_err(dev, "port %d already used\n", rhport); |
| 369 | /* | 396 | /* |
| @@ -382,6 +409,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, · 12 unmodified lines | |||
| 382 | vdev->speed = speed; | 409 | vdev->speed = speed; |
| 383 | vdev->ud.sockfd = sockfd; | 410 | vdev->ud.sockfd = sockfd; |
| 384 | vdev->ud.tcp_socket = socket; | 411 | vdev->ud.tcp_socket = socket; |
| 412 | vdev->ud.tcp_rx = tcp_rx; | ||
| 413 | vdev->ud.tcp_tx = tcp_tx; | ||
| 385 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | 414 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
| 386 | usbip_kcov_handle_init(&vdev->ud); | 415 | usbip_kcov_handle_init(&vdev->ud); |
| 387 | 416 | ||
| @@ -389,8 +418,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, · 1 unmodified line | |||
| 389 | spin_unlock_irqrestore(&vhci->lock, flags); | 418 | spin_unlock_irqrestore(&vhci->lock, flags); |
| 390 | /* end the lock */ | 419 | /* end the lock */ |
| 391 | 420 | ||
| 392 | vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); | 421 | wake_up_process(vdev->ud.tcp_rx); |
| 393 | vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); | 422 | wake_up_process(vdev->ud.tcp_tx); |
| 394 | 423 | ||
| 395 | rh_port_connect(vdev, speed); | 424 | rh_port_connect(vdev, speed); |
| 396 | 425 | ||
| @@ -90,8 +90,9 @@ unlock: · 89 unmodified lines | |||
| 90 | } | 90 | } |
| 91 | static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor)); | 91 | static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor)); |
| 92 | 92 | ||
| 93 | static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *attr, | 93 | static ssize_t usbip_sockfd_store(struct device *dev, |
| 94 | const char *in, size_t count) | 94 | struct device_attribute *attr, |
| 95 | const char *in, size_t count) | ||
| 95 | { | 96 | { |
| 96 | struct vudc *udc = (struct vudc *) dev_get_drvdata(dev); | 97 | struct vudc *udc = (struct vudc *) dev_get_drvdata(dev); |
| 97 | int rv; | 98 | int rv; |
| @@ -100,6 +101,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a · 2 unmodified lines | |||
| 100 | struct socket *socket; | 101 | struct socket *socket; |
| 101 | unsigned long flags; | 102 | unsigned long flags; |
| 102 | int ret; | 103 | int ret; |
| 104 | struct task_struct *tcp_rx = NULL; | ||
| 105 | struct task_struct *tcp_tx = NULL; | ||
| 103 | 106 | ||
| 104 | rv = kstrtoint(in, 0, &sockfd); | 107 | rv = kstrtoint(in, 0, &sockfd); |
| 105 | if (rv != 0) | 108 | if (rv != 0) |
| @@ -138,24 +141,54 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a · 32 unmodified lines | |||
| 138 | goto unlock_ud; | 141 | goto unlock_ud; |
| 139 | } | 142 | } |
| 140 | 143 | ||
| 141 | udc->ud.tcp_socket = socket; | 144 | if (socket->type != SOCK_STREAM) { |
| 145 | dev_err(dev, "Expecting SOCK_STREAM - found %d", | ||
| 146 | socket->type); | ||
| 147 | ret = -EINVAL; | ||
| 148 | goto sock_err; | ||
| 149 | } | ||
| 142 | 150 | ||
| 151 | /* unlock and create threads and get tasks */ | ||
| 143 | spin_unlock_irq(&udc->ud.lock); | 152 | spin_unlock_irq(&udc->ud.lock); |
| 144 | spin_unlock_irqrestore(&udc->lock, flags); | 153 | spin_unlock_irqrestore(&udc->lock, flags); |
| 145 | 154 | ||
| 146 | udc->ud.tcp_rx = kthread_get_run(&v_rx_loop, | 155 | tcp_rx = kthread_create(&v_rx_loop, &udc->ud, "vudc_rx"); |
| 147 | &udc->ud, "vudc_rx"); | 156 | if (IS_ERR(tcp_rx)) { |
| 148 | udc->ud.tcp_tx = kthread_get_run(&v_tx_loop, | 157 | sockfd_put(socket); |
| 149 | &udc->ud, "vudc_tx"); | 158 | return -EINVAL; |
| 159 | } | ||
| 160 | tcp_tx = kthread_create(&v_tx_loop, &udc->ud, "vudc_tx"); | ||
| 161 | if (IS_ERR(tcp_tx)) { | ||
| 162 | kthread_stop(tcp_rx); | ||
| 163 | sockfd_put(socket); | ||
| 164 | return -EINVAL; | ||
| 165 | } | ||
| 166 | |||
| 167 | /* get task structs now */ | ||
| 168 | get_task_struct(tcp_rx); | ||
| 169 | get_task_struct(tcp_tx); | ||
| 150 | 170 | ||
| 171 | /* lock and update udc->ud state */ | ||
| 151 | spin_lock_irqsave(&udc->lock, flags); | 172 | spin_lock_irqsave(&udc->lock, flags); |
| 152 | spin_lock_irq(&udc->ud.lock); | 173 | spin_lock_irq(&udc->ud.lock); |
| 174 | |||
| 175 | udc->ud.tcp_socket = socket; | ||
| 176 | udc->ud.tcp_rx = tcp_rx; | ||
| 177 | udc->ud.tcp_tx = tcp_tx; | ||
| 153 | udc->ud.status = SDEV_ST_USED; | 178 | udc->ud.status = SDEV_ST_USED; |
| 179 | |||
| 154 | spin_unlock_irq(&udc->ud.lock); | 180 | spin_unlock_irq(&udc->ud.lock); |
| 155 | 181 | ||
| 156 | ktime_get_ts64(&udc->start_time); | 182 | ktime_get_ts64(&udc->start_time); |
| 157 | v_start_timer(udc); | 183 | v_start_timer(udc); |
| 158 | udc->connected = 1; | 184 | udc->connected = 1; |
| 185 | |||
| 186 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 187 | |||
| 188 | wake_up_process(udc->ud.tcp_rx); | ||
| 189 | wake_up_process(udc->ud.tcp_tx); | ||
| 190 | return count; | ||
| 191 | |||
| 159 | } else { | 192 | } else { |
| 160 | if (!udc->connected) { | 193 | if (!udc->connected) { |
| 161 | dev_err(dev, "Device not connected"); | 194 | dev_err(dev, "Device not connected"); |
| @@ -177,6 +210,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a · 15 unmodified lines | |||
| 177 | 210 | ||
| 178 | return count; | 211 | return count; |
| 179 | 212 | ||
| 213 | sock_err: | ||
| 214 | sockfd_put(socket); | ||
| 180 | unlock_ud: | 215 | unlock_ud: |
| 181 | spin_unlock_irq(&udc->ud.lock); | 216 | spin_unlock_irq(&udc->ud.lock); |
| 182 | unlock: | 217 | unlock: |
| @@ -431,8 +431,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 430 unmodified lines | |||
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, | 433 | adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, |
| 434 | dev, &ifc_vdpa_ops, | 434 | dev, &ifc_vdpa_ops, NULL); |
| 435 | IFCVF_MAX_QUEUE_PAIRS * 2, NULL); | ||
| 436 | if (adapter == NULL) { | 435 | if (adapter == NULL) { |
| 437 | IFCVF_ERR(pdev, "Failed to allocate vDPA structure"); | 436 | IFCVF_ERR(pdev, "Failed to allocate vDPA structure"); |
| 438 | return -ENOMEM; | 437 | return -ENOMEM; |
| @@ -456,7 +455,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 17 unmodified lines | |||
| 456 | for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) | 455 | for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) |
| 457 | vf->vring[i].irq = -EINVAL; | 456 | vf->vring[i].irq = -EINVAL; |
| 458 | 457 | ||
| 459 | ret = vdpa_register_device(&adapter->vdpa); | 458 | ret = vdpa_register_device(&adapter->vdpa, IFCVF_MAX_QUEUE_PAIRS * 2); |
| 460 | if (ret) { | 459 | if (ret) { |
| 461 | IFCVF_ERR(pdev, "Failed to register ifcvf to vdpa bus"); | 460 | IFCVF_ERR(pdev, "Failed to register ifcvf to vdpa bus"); |
| 462 | goto err; | 461 | goto err; |
| @@ -1982,7 +1982,7 @@ static int mlx5v_probe(struct auxiliary_device *adev, · 1981 unmodified lines | |||
| 1982 | max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); | 1982 | max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); |
| 1983 | 1983 | ||
| 1984 | ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, | 1984 | ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, |
| 1985 | 2 * mlx5_vdpa_max_qps(max_vqs), NULL); | 1985 | NULL); |
| 1986 | if (IS_ERR(ndev)) | 1986 | if (IS_ERR(ndev)) |
| 1987 | return PTR_ERR(ndev); | 1987 | return PTR_ERR(ndev); |
| 1988 | 1988 | ||
| @@ -2009,7 +2009,7 @@ static int mlx5v_probe(struct auxiliary_device *adev, · 20 unmodified lines | |||
| 2009 | if (err) | 2009 | if (err) |
| 2010 | goto err_res; | 2010 | goto err_res; |
| 2011 | 2011 | ||
| 2012 | err = vdpa_register_device(&mvdev->vdev); | 2012 | err = vdpa_register_device(&mvdev->vdev, 2 * mlx5_vdpa_max_qps(max_vqs)); |
| 2013 | if (err) | 2013 | if (err) |
| 2014 | goto err_reg; | 2014 | goto err_reg; |
| 2015 | 2015 | ||
| @@ -69,7 +69,6 @@ static void vdpa_release_dev(struct device *d) · 68 unmodified lines | |||
| 69 | * initialized but before registered. | 69 | * initialized but before registered. |
| 70 | * @parent: the parent device | 70 | * @parent: the parent device |
| 71 | * @config: the bus operations that is supported by this device | 71 | * @config: the bus operations that is supported by this device |
| 72 | * @nvqs: number of virtqueues supported by this device | ||
| 73 | * @size: size of the parent structure that contains private data | 72 | * @size: size of the parent structure that contains private data |
| 74 | * @name: name of the vdpa device; optional. | 73 | * @name: name of the vdpa device; optional. |
| 75 | * | 74 | * |
| @@ -81,7 +80,7 @@ static void vdpa_release_dev(struct device *d) · 5 unmodified lines | |||
| 81 | */ | 80 | */ |
| 82 | struct vdpa_device *__vdpa_alloc_device(struct device *parent, | 81 | struct vdpa_device *__vdpa_alloc_device(struct device *parent, |
| 83 | const struct vdpa_config_ops *config, | 82 | const struct vdpa_config_ops *config, |
| 84 | int nvqs, size_t size, const char *name) | 83 | size_t size, const char *name) |
| 85 | { | 84 | { |
| 86 | struct vdpa_device *vdev; | 85 | struct vdpa_device *vdev; |
| 87 | int err = -EINVAL; | 86 | int err = -EINVAL; |
| @@ -107,7 +106,6 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent, · 19 unmodified lines | |||
| 107 | vdev->index = err; | 106 | vdev->index = err; |
| 108 | vdev->config = config; | 107 | vdev->config = config; |
| 109 | vdev->features_valid = false; | 108 | vdev->features_valid = false; |
| 110 | vdev->nvqs = nvqs; | ||
| 111 | 109 | ||
| 112 | if (name) | 110 | if (name) |
| 113 | err = dev_set_name(&vdev->dev, "%s", name); | 111 | err = dev_set_name(&vdev->dev, "%s", name); |
| @@ -136,10 +134,12 @@ static int vdpa_name_match(struct device *dev, const void *data) · 22 unmodified lines | |||
| 136 | return (strcmp(dev_name(&vdev->dev), data) == 0); | 134 | return (strcmp(dev_name(&vdev->dev), data) == 0); |
| 137 | } | 135 | } |
| 138 | 136 | ||
| 139 | static int __vdpa_register_device(struct vdpa_device *vdev) | 137 | static int __vdpa_register_device(struct vdpa_device *vdev, int nvqs) |
| 140 | { | 138 | { |
| 141 | struct device *dev; | 139 | struct device *dev; |
| 142 | 140 | ||
| 141 | vdev->nvqs = nvqs; | ||
| 142 | |||
| 143 | lockdep_assert_held(&vdpa_dev_mutex); | 143 | lockdep_assert_held(&vdpa_dev_mutex); |
| 144 | dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); | 144 | dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); |
| 145 | if (dev) { | 145 | if (dev) { |
| @@ -155,15 +155,16 @@ static int __vdpa_register_device(struct vdpa_device *vdev) · 9 unmodified lines | |||
| 155 | * Caller must invoke this routine in the management device dev_add() | 155 | * Caller must invoke this routine in the management device dev_add() |
| 156 | * callback after setting up valid mgmtdev for this vdpa device. | 156 | * callback after setting up valid mgmtdev for this vdpa device. |
| 157 | * @vdev: the vdpa device to be registered to vDPA bus | 157 | * @vdev: the vdpa device to be registered to vDPA bus |
| 158 | * @nvqs: number of virtqueues supported by this device | ||
| 158 | * | 159 | * |
| 159 | * Returns an error when fail to add device to vDPA bus | 160 | * Returns an error when fail to add device to vDPA bus |
| 160 | */ | 161 | */ |
| 161 | int _vdpa_register_device(struct vdpa_device *vdev) | 162 | int _vdpa_register_device(struct vdpa_device *vdev, int nvqs) |
| 162 | { | 163 | { |
| 163 | if (!vdev->mdev) | 164 | if (!vdev->mdev) |
| 164 | return -EINVAL; | 165 | return -EINVAL; |
| 165 | 166 | ||
| 166 | return __vdpa_register_device(vdev); | 167 | return __vdpa_register_device(vdev, nvqs); |
| 167 | } | 168 | } |
| 168 | EXPORT_SYMBOL_GPL(_vdpa_register_device); | 169 | EXPORT_SYMBOL_GPL(_vdpa_register_device); |
| 169 | 170 | ||
| @@ -171,15 +172,16 @@ EXPORT_SYMBOL_GPL(_vdpa_register_device); · 1 unmodified line | |||
| 171 | * vdpa_register_device - register a vDPA device | 172 | * vdpa_register_device - register a vDPA device |
| 172 | * Callers must have a succeed call of vdpa_alloc_device() before. | 173 | * Callers must have a succeed call of vdpa_alloc_device() before. |
| 173 | * @vdev: the vdpa device to be registered to vDPA bus | 174 | * @vdev: the vdpa device to be registered to vDPA bus |
| 175 | * @nvqs: number of virtqueues supported by this device | ||
| 174 | * | 176 | * |
| 175 | * Returns an error when fail to add to vDPA bus | 177 | * Returns an error when fail to add to vDPA bus |
| 176 | */ | 178 | */ |
| 177 | int vdpa_register_device(struct vdpa_device *vdev) | 179 | int vdpa_register_device(struct vdpa_device *vdev, int nvqs) |
| 178 | { | 180 | { |
| 179 | int err; | 181 | int err; |
| 180 | 182 | ||
| 181 | mutex_lock(&vdpa_dev_mutex); | 183 | mutex_lock(&vdpa_dev_mutex); |
| 182 | err = __vdpa_register_device(vdev); | 184 | err = __vdpa_register_device(vdev, nvqs); |
| 183 | mutex_unlock(&vdpa_dev_mutex); | 185 | mutex_unlock(&vdpa_dev_mutex); |
| 184 | return err; | 186 | return err; |
| 185 | } | 187 | } |
| @@ -235,7 +235,7 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr) · 234 unmodified lines | |||
| 235 | ops = &vdpasim_config_ops; | 235 | ops = &vdpasim_config_ops; |
| 236 | 236 | ||
| 237 | vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, | 237 | vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, |
| 238 | dev_attr->nvqs, dev_attr->name); | 238 | dev_attr->name); |
| 239 | if (!vdpasim) | 239 | if (!vdpasim) |
| 240 | goto err_alloc; | 240 | goto err_alloc; |
| 241 | 241 | ||
| @@ -110,8 +110,7 @@ out: · 109 unmodified lines | |||
| 110 | 110 | ||
| 111 | static void vdpasim_net_get_config(struct vdpasim *vdpasim, void *config) | 111 | static void vdpasim_net_get_config(struct vdpasim *vdpasim, void *config) |
| 112 | { | 112 | { |
| 113 | struct virtio_net_config *net_config = | 113 | struct virtio_net_config *net_config = config; |
| 114 | (struct virtio_net_config *)config; | ||
| 115 | 114 | ||
| 116 | net_config->mtu = cpu_to_vdpasim16(vdpasim, 1500); | 115 | net_config->mtu = cpu_to_vdpasim16(vdpasim, 1500); |
| 117 | net_config->status = cpu_to_vdpasim16(vdpasim, VIRTIO_NET_S_LINK_UP); | 116 | net_config->status = cpu_to_vdpasim16(vdpasim, VIRTIO_NET_S_LINK_UP); |
| @@ -147,7 +146,7 @@ static int vdpasim_net_dev_add(struct vdpa_mgmt_dev *mdev, const char *name) · 29 unmodified lines | |||
| 147 | if (IS_ERR(simdev)) | 146 | if (IS_ERR(simdev)) |
| 148 | return PTR_ERR(simdev); | 147 | return PTR_ERR(simdev); |
| 149 | 148 | ||
| 150 | ret = _vdpa_register_device(&simdev->vdpa); | 149 | ret = _vdpa_register_device(&simdev->vdpa, VDPASIM_NET_VQ_NUM); |
| 151 | if (ret) | 150 | if (ret) |
| 152 | goto reg_err; | 151 | goto reg_err; |
| 153 | 152 | ||
| @@ -21,8 +21,8 @@ config VFIO_VIRQFD · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | menuconfig VFIO | 22 | menuconfig VFIO |
| 23 | tristate "VFIO Non-Privileged userspace driver framework" | 23 | tristate "VFIO Non-Privileged userspace driver framework" |
| 24 | depends on IOMMU_API | 24 | select IOMMU_API |
| 25 | select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64) | 25 | select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64) |
| 26 | help | 26 | help |
| 27 | VFIO provides a framework for secure userspace device drivers. | 27 | VFIO provides a framework for secure userspace device drivers. |
| 28 | See Documentation/driver-api/vfio.rst for more details. | 28 | See Documentation/driver-api/vfio.rst for more details. |
| @@ -1,7 +1,7 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | config VFIO_PLATFORM | 2 | config VFIO_PLATFORM |
| 3 | tristate "VFIO support for platform devices" | 3 | tristate "VFIO support for platform devices" |
| 4 | depends on VFIO && EVENTFD && (ARM || ARM64) | 4 | depends on VFIO && EVENTFD && (ARM || ARM64 || COMPILE_TEST) |
| 5 | select VFIO_VIRQFD | 5 | select VFIO_VIRQFD |
| 6 | help | 6 | help |
| 7 | Support for platform devices with VFIO. This is required to make | 7 | Support for platform devices with VFIO. This is required to make |
| @@ -12,7 +12,7 @@ config VFIO_PLATFORM · 4 unmodified lines | |||
| 12 | 12 | ||
| 13 | config VFIO_AMBA | 13 | config VFIO_AMBA |
| 14 | tristate "VFIO support for AMBA devices" | 14 | tristate "VFIO support for AMBA devices" |
| 15 | depends on VFIO_PLATFORM && ARM_AMBA | 15 | depends on VFIO_PLATFORM && (ARM_AMBA || COMPILE_TEST) |
| 16 | help | 16 | help |
| 17 | Support for ARM AMBA devices with VFIO. This is required to make | 17 | Support for ARM AMBA devices with VFIO. This is required to make |
| 18 | use of ARM AMBA devices present on the system using the VFIO | 18 | use of ARM AMBA devices present on the system using the VFIO |
| @@ -189,7 +189,7 @@ static struct vfio_dma *vfio_find_dma(struct vfio_iommu *iommu, · 188 unmodified lines | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | static struct rb_node *vfio_find_dma_first_node(struct vfio_iommu *iommu, | 191 | static struct rb_node *vfio_find_dma_first_node(struct vfio_iommu *iommu, |
| 192 | dma_addr_t start, size_t size) | 192 | dma_addr_t start, u64 size) |
| 193 | { | 193 | { |
| 194 | struct rb_node *res = NULL; | 194 | struct rb_node *res = NULL; |
| 195 | struct rb_node *node = iommu->dma_list.rb_node; | 195 | struct rb_node *node = iommu->dma_list.rb_node; |
| @@ -785,7 +785,12 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr, · 589 unmodified lines | |||
| 785 | return -ENODEV; | 785 | return -ENODEV; |
| 786 | 786 | ||
| 787 | ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages); | 787 | ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages); |
| 788 | if (ret == 1 && do_accounting && !is_invalid_reserved_pfn(*pfn_base)) { | 788 | if (ret != 1) |
| 789 | goto out; | ||
| 790 | |||
| 791 | ret = 0; | ||
| 792 | |||
| 793 | if (do_accounting && !is_invalid_reserved_pfn(*pfn_base)) { | ||
| 789 | ret = vfio_lock_acct(dma, 1, true); | 794 | ret = vfio_lock_acct(dma, 1, true); |
| 790 | if (ret) { | 795 | if (ret) { |
| 791 | put_pfn(*pfn_base, dma->prot); | 796 | put_pfn(*pfn_base, dma->prot); |
| @@ -797,6 +802,7 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr, · 5 unmodified lines | |||
| 797 | } | 802 | } |
| 798 | } | 803 | } |
| 799 | 804 | ||
| 805 | out: | ||
| 800 | mmput(mm); | 806 | mmput(mm); |
| 801 | return ret; | 807 | return ret; |
| 802 | } | 808 | } |
| @@ -1288,7 +1294,7 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu, · 485 unmodified lines | |||
| 1288 | int ret = -EINVAL, retries = 0; | 1294 | int ret = -EINVAL, retries = 0; |
| 1289 | unsigned long pgshift; | 1295 | unsigned long pgshift; |
| 1290 | dma_addr_t iova = unmap->iova; | 1296 | dma_addr_t iova = unmap->iova; |
| 1291 | unsigned long size = unmap->size; | 1297 | u64 size = unmap->size; |
| 1292 | bool unmap_all = unmap->flags & VFIO_DMA_UNMAP_FLAG_ALL; | 1298 | bool unmap_all = unmap->flags & VFIO_DMA_UNMAP_FLAG_ALL; |
| 1293 | bool invalidate_vaddr = unmap->flags & VFIO_DMA_UNMAP_FLAG_VADDR; | 1299 | bool invalidate_vaddr = unmap->flags & VFIO_DMA_UNMAP_FLAG_VADDR; |
| 1294 | struct rb_node *n, *first_n; | 1300 | struct rb_node *n, *first_n; |
| @@ -1304,14 +1310,12 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu, · 9 unmodified lines | |||
| 1304 | if (unmap_all) { | 1310 | if (unmap_all) { |
| 1305 | if (iova || size) | 1311 | if (iova || size) |
| 1306 | goto unlock; | 1312 | goto unlock; |
| 1307 | size = SIZE_MAX; | 1313 | size = U64_MAX; |
| 1308 | } else if (!size || size & (pgsize - 1)) { | 1314 | } else if (!size || size & (pgsize - 1) || |
| 1315 | iova + size - 1 < iova || size > SIZE_MAX) { | ||
| 1309 | goto unlock; | 1316 | goto unlock; |
| 1310 | } | 1317 | } |
| 1311 | 1318 | ||
| 1312 | if (iova + size - 1 < iova || size > SIZE_MAX) | ||
| 1313 | goto unlock; | ||
| 1314 | |||
| 1315 | /* When dirty tracking is enabled, allow only min supported pgsize */ | 1319 | /* When dirty tracking is enabled, allow only min supported pgsize */ |
| 1316 | if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) && | 1320 | if ((unmap->flags & VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP) && |
| 1317 | (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) { | 1321 | (!iommu->dirty_page_tracking || (bitmap->pgsize != pgsize))) { |
| @@ -308,8 +308,10 @@ static long vhost_vdpa_get_vring_num(struct vhost_vdpa *v, u16 __user *argp) · 307 unmodified lines | |||
| 308 | 308 | ||
| 309 | static void vhost_vdpa_config_put(struct vhost_vdpa *v) | 309 | static void vhost_vdpa_config_put(struct vhost_vdpa *v) |
| 310 | { | 310 | { |
| 311 | if (v->config_ctx) | 311 | if (v->config_ctx) { |
| 312 | eventfd_ctx_put(v->config_ctx); | 312 | eventfd_ctx_put(v->config_ctx); |
| 313 | v->config_ctx = NULL; | ||
| 314 | } | ||
| 313 | } | 315 | } |
| 314 | 316 | ||
| 315 | static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) | 317 | static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) |
| @@ -329,8 +331,12 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) · 13 unmodified lines | |||
| 329 | if (!IS_ERR_OR_NULL(ctx)) | 331 | if (!IS_ERR_OR_NULL(ctx)) |
| 330 | eventfd_ctx_put(ctx); | 332 | eventfd_ctx_put(ctx); |
| 331 | 333 | ||
| 332 | if (IS_ERR(v->config_ctx)) | 334 | if (IS_ERR(v->config_ctx)) { |
| 333 | return PTR_ERR(v->config_ctx); | 335 | long ret = PTR_ERR(v->config_ctx); |
| 336 | |||
| 337 | v->config_ctx = NULL; | ||
| 338 | return ret; | ||
| 339 | } | ||
| 334 | 340 | ||
| 335 | v->vdpa->config->set_config_cb(v->vdpa, &cb); | 341 | v->vdpa->config->set_config_cb(v->vdpa, &cb); |
| 336 | 342 | ||
| @@ -900,14 +906,10 @@ err: · 563 unmodified lines | |||
| 900 | 906 | ||
| 901 | static void vhost_vdpa_clean_irq(struct vhost_vdpa *v) | 907 | static void vhost_vdpa_clean_irq(struct vhost_vdpa *v) |
| 902 | { | 908 | { |
| 903 | struct vhost_virtqueue *vq; | ||
| 904 | int i; | 909 | int i; |
| 905 | 910 | ||
| 906 | for (i = 0; i < v->nvqs; i++) { | 911 | for (i = 0; i < v->nvqs; i++) |
| 907 | vq = &v->vqs[i]; | 912 | vhost_vdpa_unsetup_vq_irq(v, i); |
| 908 | if (vq->call_ctx.producer.irq) | ||
| 909 | irq_bypass_unregister_producer(&vq->call_ctx.producer); | ||
| 910 | } | ||
| 911 | } | 913 | } |
| 912 | 914 | ||
| 913 | static int vhost_vdpa_release(struct inode *inode, struct file *filep) | 915 | static int vhost_vdpa_release(struct inode *inode, struct file *filep) |
| @@ -332,8 +332,8 @@ static void vhost_vq_reset(struct vhost_dev *dev, · 331 unmodified lines | |||
| 332 | vq->error_ctx = NULL; | 332 | vq->error_ctx = NULL; |
| 333 | vq->kick = NULL; | 333 | vq->kick = NULL; |
| 334 | vq->log_ctx = NULL; | 334 | vq->log_ctx = NULL; |
| 335 | vhost_reset_is_le(vq); | ||
| 336 | vhost_disable_cross_endian(vq); | 335 | vhost_disable_cross_endian(vq); |
| 336 | vhost_reset_is_le(vq); | ||
| 337 | vq->busyloop_timeout = 0; | 337 | vq->busyloop_timeout = 0; |
| 338 | vq->umem = NULL; | 338 | vq->umem = NULL; |
| 339 | vq->iotlb = NULL; | 339 | vq->iotlb = NULL; |
| @@ -287,11 +287,8 @@ static inline void aty_st_8(int regindex, u8 val, const struct atyfb_par *par) · 286 unmodified lines | |||
| 287 | #endif | 287 | #endif |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | #if defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) || \ | ||
| 291 | defined (CONFIG_FB_ATY_BACKLIGHT) | ||
| 292 | extern void aty_st_lcd(int index, u32 val, const struct atyfb_par *par); | 290 | extern void aty_st_lcd(int index, u32 val, const struct atyfb_par *par); |
| 293 | extern u32 aty_ld_lcd(int index, const struct atyfb_par *par); | 291 | extern u32 aty_ld_lcd(int index, const struct atyfb_par *par); |
| 294 | #endif | ||
| 295 | 292 | ||
| 296 | /* | 293 | /* |
| 297 | * DAC operations | 294 | * DAC operations |
| @@ -133,7 +133,7 @@ · 132 unmodified lines | |||
| 133 | #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) | 133 | #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) |
| 134 | 134 | ||
| 135 | #if defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_GENERIC_LCD) || \ | 135 | #if defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_GENERIC_LCD) || \ |
| 136 | defined(CONFIG_FB_ATY_BACKLIGHT) | 136 | defined(CONFIG_FB_ATY_BACKLIGHT) || defined (CONFIG_PPC_PMAC) |
| 137 | static const u32 lt_lcd_regs[] = { | 137 | static const u32 lt_lcd_regs[] = { |
| 138 | CNFG_PANEL_LG, | 138 | CNFG_PANEL_LG, |
| 139 | LCD_GEN_CNTL_LG, | 139 | LCD_GEN_CNTL_LG, |
| @@ -175,8 +175,8 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par) · 35 unmodified lines | |||
| 175 | return aty_ld_le32(LCD_DATA, par); | 175 | return aty_ld_le32(LCD_DATA, par); |
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| 178 | #else /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) \ | 178 | #else /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) || |
| 179 | defined(CONFIG_FB_ATY_GENERIC_LCD) */ | 179 | defined(CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_PPC_PMAC) */ |
| 180 | void aty_st_lcd(int index, u32 val, const struct atyfb_par *par) | 180 | void aty_st_lcd(int index, u32 val, const struct atyfb_par *par) |
| 181 | { } | 181 | { } |
| 182 | 182 | ||
| @@ -184,7 +184,8 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par) · 1 unmodified line | |||
| 184 | { | 184 | { |
| 185 | return 0; | 185 | return 0; |
| 186 | } | 186 | } |
| 187 | #endif /* defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */ | 187 | #endif /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) || |
| 188 | defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_PPC_PMAC) */ | ||
| 188 | 189 | ||
| 189 | #ifdef CONFIG_FB_ATY_GENERIC_LCD | 190 | #ifdef CONFIG_FB_ATY_GENERIC_LCD |
| 190 | /* | 191 | /* |
| @@ -333,7 +333,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, · 332 unmodified lines | |||
| 333 | acrn_ioreq_request_clear(vm); | 333 | acrn_ioreq_request_clear(vm); |
| 334 | break; | 334 | break; |
| 335 | case ACRN_IOCTL_PM_GET_CPU_STATE: | 335 | case ACRN_IOCTL_PM_GET_CPU_STATE: |
| 336 | if (copy_from_user(&cstate_cmd, (void *)ioctl_param, | 336 | if (copy_from_user(&cstate_cmd, (void __user *)ioctl_param, |
| 337 | sizeof(cstate_cmd))) | 337 | sizeof(cstate_cmd))) |
| 338 | return -EFAULT; | 338 | return -EFAULT; |
| 339 | 339 | ||
| @@ -404,6 +404,14 @@ fail_remove: · 64 unmodified lines | |||
| 404 | } | 404 | } |
| 405 | static DEVICE_ATTR_WO(remove_cpu); | 405 | static DEVICE_ATTR_WO(remove_cpu); |
| 406 | 406 | ||
| 407 | static umode_t acrn_attr_visible(struct kobject *kobj, struct attribute *a, int n) | ||
| 408 | { | ||
| 409 | if (a == &dev_attr_remove_cpu.attr) | ||
| 410 | return IS_ENABLED(CONFIG_HOTPLUG_CPU) ? a->mode : 0; | ||
| 411 | |||
| 412 | return a->mode; | ||
| 413 | } | ||
| 414 | |||
| 407 | static struct attribute *acrn_attrs[] = { | 415 | static struct attribute *acrn_attrs[] = { |
| 408 | &dev_attr_remove_cpu.attr, | 416 | &dev_attr_remove_cpu.attr, |
| 409 | NULL | 417 | NULL |
| @@ -411,6 +419,7 @@ static struct attribute *acrn_attrs[] = { · 1 unmodified line | |||
| 411 | 419 | ||
| 412 | static struct attribute_group acrn_attr_group = { | 420 | static struct attribute_group acrn_attr_group = { |
| 413 | .attrs = acrn_attrs, | 421 | .attrs = acrn_attrs, |
| 422 | .is_visible = acrn_attr_visible, | ||
| 414 | }; | 423 | }; |
| 415 | 424 | ||
| 416 | static const struct attribute_group *acrn_attr_groups[] = { | 425 | static const struct attribute_group *acrn_attr_groups[] = { |
| @@ -112,7 +112,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) · 111 unmodified lines | |||
| 112 | { | 112 | { |
| 113 | struct eventfd_ctx *eventfd = NULL; | 113 | struct eventfd_ctx *eventfd = NULL; |
| 114 | struct hsm_irqfd *irqfd, *tmp; | 114 | struct hsm_irqfd *irqfd, *tmp; |
| 115 | unsigned int events; | 115 | __poll_t events; |
| 116 | struct fd f; | 116 | struct fd f; |
| 117 | int ret = 0; | 117 | int ret = 0; |
| 118 | 118 | ||
| @@ -158,9 +158,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) · 39 unmodified lines | |||
| 158 | mutex_unlock(&vm->irqfds_lock); | 158 | mutex_unlock(&vm->irqfds_lock); |
| 159 | 159 | ||
| 160 | /* Check the pending event in this stage */ | 160 | /* Check the pending event in this stage */ |
| 161 | events = f.file->f_op->poll(f.file, &irqfd->pt); | 161 | events = vfs_poll(f.file, &irqfd->pt); |
| 162 | 162 | ||
| 163 | if (events & POLLIN) | 163 | if (events & EPOLLIN) |
| 164 | acrn_irqfd_inject(irqfd); | 164 | acrn_irqfd_inject(irqfd); |
| 165 | 165 | ||
| 166 | fdput(f); | 166 | fdput(f); |
| @@ -141,15 +141,14 @@ void virtio_config_changed(struct virtio_device *dev) · 140 unmodified lines | |||
| 141 | } | 141 | } |
| 142 | EXPORT_SYMBOL_GPL(virtio_config_changed); | 142 | EXPORT_SYMBOL_GPL(virtio_config_changed); |
| 143 | 143 | ||
| 144 | void virtio_config_disable(struct virtio_device *dev) | 144 | static void virtio_config_disable(struct virtio_device *dev) |
| 145 | { | 145 | { |
| 146 | spin_lock_irq(&dev->config_lock); | 146 | spin_lock_irq(&dev->config_lock); |
| 147 | dev->config_enabled = false; | 147 | dev->config_enabled = false; |
| 148 | spin_unlock_irq(&dev->config_lock); | 148 | spin_unlock_irq(&dev->config_lock); |
| 149 | } | 149 | } |
| 150 | EXPORT_SYMBOL_GPL(virtio_config_disable); | ||
| 151 | 150 | ||
| 152 | void virtio_config_enable(struct virtio_device *dev) | 151 | static void virtio_config_enable(struct virtio_device *dev) |
| 153 | { | 152 | { |
| 154 | spin_lock_irq(&dev->config_lock); | 153 | spin_lock_irq(&dev->config_lock); |
| 155 | dev->config_enabled = true; | 154 | dev->config_enabled = true; |
| @@ -158,7 +157,6 @@ void virtio_config_enable(struct virtio_device *dev) · 2 unmodified lines | |||
| 158 | dev->config_change_pending = false; | 157 | dev->config_change_pending = false; |
| 159 | spin_unlock_irq(&dev->config_lock); | 158 | spin_unlock_irq(&dev->config_lock); |
| 160 | } | 159 | } |
| 161 | EXPORT_SYMBOL_GPL(virtio_config_enable); | ||
| 162 | 160 | ||
| 163 | void virtio_add_status(struct virtio_device *dev, unsigned int status) | 161 | void virtio_add_status(struct virtio_device *dev, unsigned int status) |
| 164 | { | 162 | { |
| @@ -548,8 +548,7 @@ static void virtio_mmio_release_dev(struct device *_d) · 547 unmodified lines | |||
| 548 | { | 548 | { |
| 549 | struct virtio_device *vdev = | 549 | struct virtio_device *vdev = |
| 550 | container_of(_d, struct virtio_device, dev); | 550 | container_of(_d, struct virtio_device, dev); |
| 551 | struct virtio_mmio_device *vm_dev = | 551 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); |
| 552 | container_of(vdev, struct virtio_mmio_device, vdev); | ||
| 553 | struct platform_device *pdev = vm_dev->pdev; | 552 | struct platform_device *pdev = vm_dev->pdev; |
| 554 | 553 | ||
| 555 | devm_kfree(&pdev->dev, vm_dev); | 554 | devm_kfree(&pdev->dev, vm_dev); |
| @@ -273,7 +273,6 @@ module_exit(cpu5wdt_exit_module); · 272 unmodified lines | |||
| 273 | 273 | ||
| 274 | MODULE_AUTHOR("Heiko Ronsdorf <hero@ihg.uni-duisburg.de>"); | 274 | MODULE_AUTHOR("Heiko Ronsdorf <hero@ihg.uni-duisburg.de>"); |
| 275 | MODULE_DESCRIPTION("sma cpu5 watchdog driver"); | 275 | MODULE_DESCRIPTION("sma cpu5 watchdog driver"); |
| 276 | MODULE_SUPPORTED_DEVICE("sma cpu5 watchdog"); | ||
| 277 | MODULE_LICENSE("GPL"); | 276 | MODULE_LICENSE("GPL"); |
| 278 | 277 | ||
| 279 | module_param_hw(port, int, ioport, 0); | 278 | module_param_hw(port, int, ioport, 0); |
| @@ -172,7 +172,6 @@ MODULE_PARM_DESC(wd2_timeout, "Default watchdog2 timeout in 1/10secs"); · 171 unmodified lines | |||
| 172 | MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); | 172 | MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); |
| 173 | MODULE_DESCRIPTION("Hardware watchdog driver for Sun Microsystems CP1400/1500"); | 173 | MODULE_DESCRIPTION("Hardware watchdog driver for Sun Microsystems CP1400/1500"); |
| 174 | MODULE_LICENSE("GPL"); | 174 | MODULE_LICENSE("GPL"); |
| 175 | MODULE_SUPPORTED_DEVICE("watchdog"); | ||
| 176 | 175 | ||
| 177 | static void cpwd_writew(u16 val, void __iomem *addr) | 176 | static void cpwd_writew(u16 val, void __iomem *addr) |
| 178 | { | 177 | { |
| @@ -46,7 +46,6 @@ · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); | 47 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); |
| 48 | MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO"); | 48 | MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO"); |
| 49 | MODULE_SUPPORTED_DEVICE("watchdog"); | ||
| 50 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
| 51 | 50 | ||
| 52 | #define DRIVER_NAME "riowd" | 51 | #define DRIVER_NAME "riowd" |
| @@ -47,6 +47,11 @@ static unsigned evtchn_2l_max_channels(void) · 46 unmodified lines | |||
| 47 | return EVTCHN_2L_NR_CHANNELS; | 47 | return EVTCHN_2L_NR_CHANNELS; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static void evtchn_2l_remove(evtchn_port_t evtchn, unsigned int cpu) | ||
| 51 | { | ||
| 52 | clear_bit(evtchn, BM(per_cpu(cpu_evtchn_mask, cpu))); | ||
| 53 | } | ||
| 54 | |||
| 50 | static void evtchn_2l_bind_to_cpu(evtchn_port_t evtchn, unsigned int cpu, | 55 | static void evtchn_2l_bind_to_cpu(evtchn_port_t evtchn, unsigned int cpu, |
| 51 | unsigned int old_cpu) | 56 | unsigned int old_cpu) |
| 52 | { | 57 | { |
| @@ -72,12 +77,6 @@ static bool evtchn_2l_is_pending(evtchn_port_t port) · 19 unmodified lines | |||
| 72 | return sync_test_bit(port, BM(&s->evtchn_pending[0])); | 77 | return sync_test_bit(port, BM(&s->evtchn_pending[0])); |
| 73 | } | 78 | } |
| 74 | 79 | ||
| 75 | static bool evtchn_2l_test_and_set_mask(evtchn_port_t port) | ||
| 76 | { | ||
| 77 | struct shared_info *s = HYPERVISOR_shared_info; | ||
| 78 | return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0])); | ||
| 79 | } | ||
| 80 | |||
| 81 | static void evtchn_2l_mask(evtchn_port_t port) | 80 | static void evtchn_2l_mask(evtchn_port_t port) |
| 82 | { | 81 | { |
| 83 | struct shared_info *s = HYPERVISOR_shared_info; | 82 | struct shared_info *s = HYPERVISOR_shared_info; |
| @@ -355,18 +354,27 @@ static void evtchn_2l_resume(void) · 271 unmodified lines | |||
| 355 | EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); | 354 | EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); |
| 356 | } | 355 | } |
| 357 | 356 | ||
| 357 | static int evtchn_2l_percpu_deinit(unsigned int cpu) | ||
| 358 | { | ||
| 359 | memset(per_cpu(cpu_evtchn_mask, cpu), 0, sizeof(xen_ulong_t) * | ||
| 360 | EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); | ||
| 361 | |||
| 362 | return 0; | ||
| 363 | } | ||
| 364 | |||
| 358 | static const struct evtchn_ops evtchn_ops_2l = { | 365 | static const struct evtchn_ops evtchn_ops_2l = { |
| 359 | .max_channels = evtchn_2l_max_channels, | 366 | .max_channels = evtchn_2l_max_channels, |
| 360 | .nr_channels = evtchn_2l_max_channels, | 367 | .nr_channels = evtchn_2l_max_channels, |
| 368 | .remove = evtchn_2l_remove, | ||
| 361 | .bind_to_cpu = evtchn_2l_bind_to_cpu, | 369 | .bind_to_cpu = evtchn_2l_bind_to_cpu, |
| 362 | .clear_pending = evtchn_2l_clear_pending, | 370 | .clear_pending = evtchn_2l_clear_pending, |
| 363 | .set_pending = evtchn_2l_set_pending, | 371 | .set_pending = evtchn_2l_set_pending, |
| 364 | .is_pending = evtchn_2l_is_pending, | 372 | .is_pending = evtchn_2l_is_pending, |
| 365 | .test_and_set_mask = evtchn_2l_test_and_set_mask, | ||
| 366 | .mask = evtchn_2l_mask, | 373 | .mask = evtchn_2l_mask, |
| 367 | .unmask = evtchn_2l_unmask, | 374 | .unmask = evtchn_2l_unmask, |
| 368 | .handle_events = evtchn_2l_handle_events, | 375 | .handle_events = evtchn_2l_handle_events, |
| 369 | .resume = evtchn_2l_resume, | 376 | .resume = evtchn_2l_resume, |
| 377 | .percpu_deinit = evtchn_2l_percpu_deinit, | ||
| 370 | }; | 378 | }; |
| 371 | 379 | ||
| 372 | void __init xen_evtchn_2l_init(void) | 380 | void __init xen_evtchn_2l_init(void) |
| @@ -98,13 +98,19 @@ struct irq_info { · 97 unmodified lines | |||
| 98 | short refcnt; | 98 | short refcnt; |
| 99 | u8 spurious_cnt; | 99 | u8 spurious_cnt; |
| 100 | u8 is_accounted; | 100 | u8 is_accounted; |
| 101 | enum xen_irq_type type; /* type */ | 101 | short type; /* type: IRQT_* */ |
| 102 | u8 mask_reason; /* Why is event channel masked */ | ||
| 103 | #define EVT_MASK_REASON_EXPLICIT 0x01 | ||
| 104 | #define EVT_MASK_REASON_TEMPORARY 0x02 | ||
| 105 | #define EVT_MASK_REASON_EOI_PENDING 0x04 | ||
| 106 | u8 is_active; /* Is event just being handled? */ | ||
| 102 | unsigned irq; | 107 | unsigned irq; |
| 103 | evtchn_port_t evtchn; /* event channel */ | 108 | evtchn_port_t evtchn; /* event channel */ |
| 104 | unsigned short cpu; /* cpu bound */ | 109 | unsigned short cpu; /* cpu bound */ |
| 105 | unsigned short eoi_cpu; /* EOI must happen on this cpu-1 */ | 110 | unsigned short eoi_cpu; /* EOI must happen on this cpu-1 */ |
| 106 | unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ | 111 | unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ |
| 107 | u64 eoi_time; /* Time in jiffies when to EOI. */ | 112 | u64 eoi_time; /* Time in jiffies when to EOI. */ |
| 113 | spinlock_t lock; | ||
| 108 | 114 | ||
| 109 | union { | 115 | union { |
| 110 | unsigned short virq; | 116 | unsigned short virq; |
| @@ -154,6 +160,7 @@ static DEFINE_RWLOCK(evtchn_rwlock); · 43 unmodified lines | |||
| 154 | * evtchn_rwlock | 160 | * evtchn_rwlock |
| 155 | * IRQ-desc lock | 161 | * IRQ-desc lock |
| 156 | * percpu eoi_list_lock | 162 | * percpu eoi_list_lock |
| 163 | * irq_info->lock | ||
| 157 | */ | 164 | */ |
| 158 | 165 | ||
| 159 | static LIST_HEAD(xen_irq_list_head); | 166 | static LIST_HEAD(xen_irq_list_head); |
| @@ -304,6 +311,8 @@ static int xen_irq_info_common_setup(struct irq_info *info, · 144 unmodified lines | |||
| 304 | info->irq = irq; | 311 | info->irq = irq; |
| 305 | info->evtchn = evtchn; | 312 | info->evtchn = evtchn; |
| 306 | info->cpu = cpu; | 313 | info->cpu = cpu; |
| 314 | info->mask_reason = EVT_MASK_REASON_EXPLICIT; | ||
| 315 | spin_lock_init(&info->lock); | ||
| 307 | 316 | ||
| 308 | ret = set_evtchn_to_irq(evtchn, irq); | 317 | ret = set_evtchn_to_irq(evtchn, irq); |
| 309 | if (ret < 0) | 318 | if (ret < 0) |
| @@ -377,6 +386,7 @@ static int xen_irq_info_pirq_setup(unsigned irq, · 67 unmodified lines | |||
| 377 | static void xen_irq_info_cleanup(struct irq_info *info) | 386 | static void xen_irq_info_cleanup(struct irq_info *info) |
| 378 | { | 387 | { |
| 379 | set_evtchn_to_irq(info->evtchn, -1); | 388 | set_evtchn_to_irq(info->evtchn, -1); |
| 389 | xen_evtchn_port_remove(info->evtchn, info->cpu); | ||
| 380 | info->evtchn = 0; | 390 | info->evtchn = 0; |
| 381 | channels_on_cpu_dec(info); | 391 | channels_on_cpu_dec(info); |
| 382 | } | 392 | } |
| @@ -458,6 +468,34 @@ unsigned int cpu_from_evtchn(evtchn_port_t evtchn) · 75 unmodified lines | |||
| 458 | return ret; | 468 | return ret; |
| 459 | } | 469 | } |
| 460 | 470 | ||
| 471 | static void do_mask(struct irq_info *info, u8 reason) | ||
| 472 | { | ||
| 473 | unsigned long flags; | ||
| 474 | |||
| 475 | spin_lock_irqsave(&info->lock, flags); | ||
| 476 | |||
| 477 | if (!info->mask_reason) | ||
| 478 | mask_evtchn(info->evtchn); | ||
| 479 | |||
| 480 | info->mask_reason |= reason; | ||
| 481 | |||
| 482 | spin_unlock_irqrestore(&info->lock, flags); | ||
| 483 | } | ||
| 484 | |||
| 485 | static void do_unmask(struct irq_info *info, u8 reason) | ||
| 486 | { | ||
| 487 | unsigned long flags; | ||
| 488 | |||
| 489 | spin_lock_irqsave(&info->lock, flags); | ||
| 490 | |||
| 491 | info->mask_reason &= ~reason; | ||
| 492 | |||
| 493 | if (!info->mask_reason) | ||
| 494 | unmask_evtchn(info->evtchn); | ||
| 495 | |||
| 496 | spin_unlock_irqrestore(&info->lock, flags); | ||
| 497 | } | ||
| 498 | |||
| 461 | #ifdef CONFIG_X86 | 499 | #ifdef CONFIG_X86 |
| 462 | static bool pirq_check_eoi_map(unsigned irq) | 500 | static bool pirq_check_eoi_map(unsigned irq) |
| 463 | { | 501 | { |
| @@ -604,7 +642,7 @@ static void xen_irq_lateeoi_locked(struct irq_info *info, bool spurious) · 140 unmodified lines | |||
| 604 | } | 642 | } |
| 605 | 643 | ||
| 606 | info->eoi_time = 0; | 644 | info->eoi_time = 0; |
| 607 | unmask_evtchn(evtchn); | 645 | do_unmask(info, EVT_MASK_REASON_EOI_PENDING); |
| 608 | } | 646 | } |
| 609 | 647 | ||
| 610 | static void xen_irq_lateeoi_worker(struct work_struct *work) | 648 | static void xen_irq_lateeoi_worker(struct work_struct *work) |
| @@ -773,6 +811,12 @@ static void xen_evtchn_close(evtchn_port_t port) · 162 unmodified lines | |||
| 773 | BUG(); | 811 | BUG(); |
| 774 | } | 812 | } |
| 775 | 813 | ||
| 814 | static void event_handler_exit(struct irq_info *info) | ||
| 815 | { | ||
| 816 | smp_store_release(&info->is_active, 0); | ||
| 817 | clear_evtchn(info->evtchn); | ||
| 818 | } | ||
| 819 | |||
| 776 | static void pirq_query_unmask(int irq) | 820 | static void pirq_query_unmask(int irq) |
| 777 | { | 821 | { |
| 778 | struct physdev_irq_status_query irq_status; | 822 | struct physdev_irq_status_query irq_status; |
| @@ -791,14 +835,15 @@ static void pirq_query_unmask(int irq) · 12 unmodified lines | |||
| 791 | 835 | ||
| 792 | static void eoi_pirq(struct irq_data *data) | 836 | static void eoi_pirq(struct irq_data *data) |
| 793 | { | 837 | { |
| 794 | evtchn_port_t evtchn = evtchn_from_irq(data->irq); | 838 | struct irq_info *info = info_for_irq(data->irq); |
| 839 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 795 | struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) }; | 840 | struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) }; |
| 796 | int rc = 0; | 841 | int rc = 0; |
| 797 | 842 | ||
| 798 | if (!VALID_EVTCHN(evtchn)) | 843 | if (!VALID_EVTCHN(evtchn)) |
| 799 | return; | 844 | return; |
| 800 | 845 | ||
| 801 | clear_evtchn(evtchn); | 846 | event_handler_exit(info); |
| 802 | 847 | ||
| 803 | if (pirq_needs_eoi(data->irq)) { | 848 | if (pirq_needs_eoi(data->irq)) { |
| 804 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); | 849 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); |
| @@ -849,7 +894,8 @@ static unsigned int __startup_pirq(unsigned int irq) · 44 unmodified lines | |||
| 849 | goto err; | 894 | goto err; |
| 850 | 895 | ||
| 851 | out: | 896 | out: |
| 852 | unmask_evtchn(evtchn); | 897 | do_unmask(info, EVT_MASK_REASON_EXPLICIT); |
| 898 | |||
| 853 | eoi_pirq(irq_get_irq_data(irq)); | 899 | eoi_pirq(irq_get_irq_data(irq)); |
| 854 | 900 | ||
| 855 | return 0; | 901 | return 0; |
| @@ -876,7 +922,7 @@ static void shutdown_pirq(struct irq_data *data) · 20 unmodified lines | |||
| 876 | if (!VALID_EVTCHN(evtchn)) | 922 | if (!VALID_EVTCHN(evtchn)) |
| 877 | return; | 923 | return; |
| 878 | 924 | ||
| 879 | mask_evtchn(evtchn); | 925 | do_mask(info, EVT_MASK_REASON_EXPLICIT); |
| 880 | xen_evtchn_close(evtchn); | 926 | xen_evtchn_close(evtchn); |
| 881 | xen_irq_info_cleanup(info); | 927 | xen_irq_info_cleanup(info); |
| 882 | } | 928 | } |
| @@ -1628,6 +1674,8 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) · 745 unmodified lines | |||
| 1628 | } | 1674 | } |
| 1629 | 1675 | ||
| 1630 | info = info_for_irq(irq); | 1676 | info = info_for_irq(irq); |
| 1677 | if (xchg_acquire(&info->is_active, 1)) | ||
| 1678 | return; | ||
| 1631 | 1679 | ||
| 1632 | dev = (info->type == IRQT_EVTCHN) ? info->u.interdomain : NULL; | 1680 | dev = (info->type == IRQT_EVTCHN) ? info->u.interdomain : NULL; |
| 1633 | if (dev) | 1681 | if (dev) |
| @@ -1720,10 +1768,10 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq) · 86 unmodified lines | |||
| 1720 | } | 1768 | } |
| 1721 | 1769 | ||
| 1722 | /* Rebind an evtchn so that it gets delivered to a specific cpu */ | 1770 | /* Rebind an evtchn so that it gets delivered to a specific cpu */ |
| 1723 | static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu) | 1771 | static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu) |
| 1724 | { | 1772 | { |
| 1725 | struct evtchn_bind_vcpu bind_vcpu; | 1773 | struct evtchn_bind_vcpu bind_vcpu; |
| 1726 | int masked; | 1774 | evtchn_port_t evtchn = info ? info->evtchn : 0; |
| 1727 | 1775 | ||
| 1728 | if (!VALID_EVTCHN(evtchn)) | 1776 | if (!VALID_EVTCHN(evtchn)) |
| 1729 | return -1; | 1777 | return -1; |
| @@ -1739,7 +1787,7 @@ static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu) · 9 unmodified lines | |||
| 1739 | * Mask the event while changing the VCPU binding to prevent | 1787 | * Mask the event while changing the VCPU binding to prevent |
| 1740 | * it being delivered on an unexpected VCPU. | 1788 | * it being delivered on an unexpected VCPU. |
| 1741 | */ | 1789 | */ |
| 1742 | masked = test_and_set_mask(evtchn); | 1790 | do_mask(info, EVT_MASK_REASON_TEMPORARY); |
| 1743 | 1791 | ||
| 1744 | /* | 1792 | /* |
| 1745 | * If this fails, it usually just indicates that we're dealing with a | 1793 | * If this fails, it usually just indicates that we're dealing with a |
| @@ -1749,8 +1797,7 @@ static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu) · 3 unmodified lines | |||
| 1749 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) | 1797 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) |
| 1750 | bind_evtchn_to_cpu(evtchn, tcpu, false); | 1798 | bind_evtchn_to_cpu(evtchn, tcpu, false); |
| 1751 | 1799 | ||
| 1752 | if (!masked) | 1800 | do_unmask(info, EVT_MASK_REASON_TEMPORARY); |
| 1753 | unmask_evtchn(evtchn); | ||
| 1754 | 1801 | ||
| 1755 | return 0; | 1802 | return 0; |
| 1756 | } | 1803 | } |
| @@ -1789,7 +1836,7 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, · 32 unmodified lines | |||
| 1789 | unsigned int tcpu = select_target_cpu(dest); | 1836 | unsigned int tcpu = select_target_cpu(dest); |
| 1790 | int ret; | 1837 | int ret; |
| 1791 | 1838 | ||
| 1792 | ret = xen_rebind_evtchn_to_cpu(evtchn_from_irq(data->irq), tcpu); | 1839 | ret = xen_rebind_evtchn_to_cpu(info_for_irq(data->irq), tcpu); |
| 1793 | if (!ret) | 1840 | if (!ret) |
| 1794 | irq_data_update_effective_affinity(data, cpumask_of(tcpu)); | 1841 | irq_data_update_effective_affinity(data, cpumask_of(tcpu)); |
| 1795 | 1842 | ||
| @@ -1798,28 +1845,29 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, · 2 unmodified lines | |||
| 1798 | 1845 | ||
| 1799 | static void enable_dynirq(struct irq_data *data) | 1846 | static void enable_dynirq(struct irq_data *data) |
| 1800 | { | 1847 | { |
| 1801 | evtchn_port_t evtchn = evtchn_from_irq(data->irq); | 1848 | struct irq_info *info = info_for_irq(data->irq); |
| 1849 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 1802 | 1850 | ||
| 1803 | if (VALID_EVTCHN(evtchn)) | 1851 | if (VALID_EVTCHN(evtchn)) |
| 1804 | unmask_evtchn(evtchn); | 1852 | do_unmask(info, EVT_MASK_REASON_EXPLICIT); |
| 1805 | } | 1853 | } |
| 1806 | 1854 | ||
| 1807 | static void disable_dynirq(struct irq_data *data) | 1855 | static void disable_dynirq(struct irq_data *data) |
| 1808 | { | 1856 | { |
| 1809 | evtchn_port_t evtchn = evtchn_from_irq(data->irq); | 1857 | struct irq_info *info = info_for_irq(data->irq); |
| 1858 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 1810 | 1859 | ||
| 1811 | if (VALID_EVTCHN(evtchn)) | 1860 | if (VALID_EVTCHN(evtchn)) |
| 1812 | mask_evtchn(evtchn); | 1861 | do_mask(info, EVT_MASK_REASON_EXPLICIT); |
| 1813 | } | 1862 | } |
| 1814 | 1863 | ||
| 1815 | static void ack_dynirq(struct irq_data *data) | 1864 | static void ack_dynirq(struct irq_data *data) |
| 1816 | { | 1865 | { |
| 1817 | evtchn_port_t evtchn = evtchn_from_irq(data->irq); | 1866 | struct irq_info *info = info_for_irq(data->irq); |
| 1867 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 1818 | 1868 | ||
| 1819 | if (!VALID_EVTCHN(evtchn)) | 1869 | if (VALID_EVTCHN(evtchn)) |
| 1820 | return; | 1870 | event_handler_exit(info); |
| 1821 | |||
| 1822 | clear_evtchn(evtchn); | ||
| 1823 | } | 1871 | } |
| 1824 | 1872 | ||
| 1825 | static void mask_ack_dynirq(struct irq_data *data) | 1873 | static void mask_ack_dynirq(struct irq_data *data) |
| @@ -1828,18 +1876,39 @@ static void mask_ack_dynirq(struct irq_data *data) · 2 unmodified lines | |||
| 1828 | ack_dynirq(data); | 1876 | ack_dynirq(data); |
| 1829 | } | 1877 | } |
| 1830 | 1878 | ||
| 1879 | static void lateeoi_ack_dynirq(struct irq_data *data) | ||
| 1880 | { | ||
| 1881 | struct irq_info *info = info_for_irq(data->irq); | ||
| 1882 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 1883 | |||
| 1884 | if (VALID_EVTCHN(evtchn)) { | ||
| 1885 | do_mask(info, EVT_MASK_REASON_EOI_PENDING); | ||
| 1886 | event_handler_exit(info); | ||
| 1887 | } | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | static void lateeoi_mask_ack_dynirq(struct irq_data *data) | ||
| 1891 | { | ||
| 1892 | struct irq_info *info = info_for_irq(data->irq); | ||
| 1893 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 1894 | |||
| 1895 | if (VALID_EVTCHN(evtchn)) { | ||
| 1896 | do_mask(info, EVT_MASK_REASON_EXPLICIT); | ||
| 1897 | event_handler_exit(info); | ||
| 1898 | } | ||
| 1899 | } | ||
| 1900 | |||
| 1831 | static int retrigger_dynirq(struct irq_data *data) | 1901 | static int retrigger_dynirq(struct irq_data *data) |
| 1832 | { | 1902 | { |
| 1833 | evtchn_port_t evtchn = evtchn_from_irq(data->irq); | 1903 | struct irq_info *info = info_for_irq(data->irq); |
| 1834 | int masked; | 1904 | evtchn_port_t evtchn = info ? info->evtchn : 0; |
| 1835 | 1905 | ||
| 1836 | if (!VALID_EVTCHN(evtchn)) | 1906 | if (!VALID_EVTCHN(evtchn)) |
| 1837 | return 0; | 1907 | return 0; |
| 1838 | 1908 | ||
| 1839 | masked = test_and_set_mask(evtchn); | 1909 | do_mask(info, EVT_MASK_REASON_TEMPORARY); |
| 1840 | set_evtchn(evtchn); | 1910 | set_evtchn(evtchn); |
| 1841 | if (!masked) | 1911 | do_unmask(info, EVT_MASK_REASON_TEMPORARY); |
| 1842 | unmask_evtchn(evtchn); | ||
| 1843 | 1912 | ||
| 1844 | return 1; | 1913 | return 1; |
| 1845 | } | 1914 | } |
| @@ -1938,10 +2007,11 @@ static void restore_cpu_ipis(unsigned int cpu) · 92 unmodified lines | |||
| 1938 | /* Clear an irq's pending state, in preparation for polling on it */ | 2007 | /* Clear an irq's pending state, in preparation for polling on it */ |
| 1939 | void xen_clear_irq_pending(int irq) | 2008 | void xen_clear_irq_pending(int irq) |
| 1940 | { | 2009 | { |
| 1941 | evtchn_port_t evtchn = evtchn_from_irq(irq); | 2010 | struct irq_info *info = info_for_irq(irq); |
| 2011 | evtchn_port_t evtchn = info ? info->evtchn : 0; | ||
| 1942 | 2012 | ||
| 1943 | if (VALID_EVTCHN(evtchn)) | 2013 | if (VALID_EVTCHN(evtchn)) |
| 1944 | clear_evtchn(evtchn); | 2014 | event_handler_exit(info); |
| 1945 | } | 2015 | } |
| 1946 | EXPORT_SYMBOL(xen_clear_irq_pending); | 2016 | EXPORT_SYMBOL(xen_clear_irq_pending); |
| 1947 | void xen_set_irq_pending(int irq) | 2017 | void xen_set_irq_pending(int irq) |
| @@ -2053,8 +2123,8 @@ static struct irq_chip xen_lateeoi_chip __read_mostly = { · 105 unmodified lines | |||
| 2053 | .irq_mask = disable_dynirq, | 2123 | .irq_mask = disable_dynirq, |
| 2054 | .irq_unmask = enable_dynirq, | 2124 | .irq_unmask = enable_dynirq, |
| 2055 | 2125 | ||
| 2056 | .irq_ack = mask_ack_dynirq, | 2126 | .irq_ack = lateeoi_ack_dynirq, |
| 2057 | .irq_mask_ack = mask_ack_dynirq, | 2127 | .irq_mask_ack = lateeoi_mask_ack_dynirq, |
| 2058 | 2128 | ||
| 2059 | .irq_set_affinity = set_affinity_irq, | 2129 | .irq_set_affinity = set_affinity_irq, |
| 2060 | .irq_retrigger = retrigger_dynirq, | 2130 | .irq_retrigger = retrigger_dynirq, |
| @@ -209,12 +209,6 @@ static bool evtchn_fifo_is_pending(evtchn_port_t port) · 208 unmodified lines | |||
| 209 | return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); | 209 | return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | static bool evtchn_fifo_test_and_set_mask(evtchn_port_t port) | ||
| 213 | { | ||
| 214 | event_word_t *word = event_word_from_port(port); | ||
| 215 | return sync_test_and_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word)); | ||
| 216 | } | ||
| 217 | |||
| 218 | static void evtchn_fifo_mask(evtchn_port_t port) | 212 | static void evtchn_fifo_mask(evtchn_port_t port) |
| 219 | { | 213 | { |
| 220 | event_word_t *word = event_word_from_port(port); | 214 | event_word_t *word = event_word_from_port(port); |
| @@ -423,7 +417,6 @@ static const struct evtchn_ops evtchn_ops_fifo = { · 202 unmodified lines | |||
| 423 | .clear_pending = evtchn_fifo_clear_pending, | 417 | .clear_pending = evtchn_fifo_clear_pending, |
| 424 | .set_pending = evtchn_fifo_set_pending, | 418 | .set_pending = evtchn_fifo_set_pending, |
| 425 | .is_pending = evtchn_fifo_is_pending, | 419 | .is_pending = evtchn_fifo_is_pending, |
| 426 | .test_and_set_mask = evtchn_fifo_test_and_set_mask, | ||
| 427 | .mask = evtchn_fifo_mask, | 420 | .mask = evtchn_fifo_mask, |
| 428 | .unmask = evtchn_fifo_unmask, | 421 | .unmask = evtchn_fifo_unmask, |
| 429 | .handle_events = evtchn_fifo_handle_events, | 422 | .handle_events = evtchn_fifo_handle_events, |
| @@ -14,13 +14,13 @@ struct evtchn_ops { · 13 unmodified lines | |||
| 14 | unsigned (*nr_channels)(void); | 14 | unsigned (*nr_channels)(void); |
| 15 | 15 | ||
| 16 | int (*setup)(evtchn_port_t port); | 16 | int (*setup)(evtchn_port_t port); |
| 17 | void (*remove)(evtchn_port_t port, unsigned int cpu); | ||
| 17 | void (*bind_to_cpu)(evtchn_port_t evtchn, unsigned int cpu, | 18 | void (*bind_to_cpu)(evtchn_port_t evtchn, unsigned int cpu, |
| 18 | unsigned int old_cpu); | 19 | unsigned int old_cpu); |
| 19 | 20 | ||
| 20 | void (*clear_pending)(evtchn_port_t port); | 21 | void (*clear_pending)(evtchn_port_t port); |
| 21 | void (*set_pending)(evtchn_port_t port); | 22 | void (*set_pending)(evtchn_port_t port); |
| 22 | bool (*is_pending)(evtchn_port_t port); | 23 | bool (*is_pending)(evtchn_port_t port); |
| 23 | bool (*test_and_set_mask)(evtchn_port_t port); | ||
| 24 | void (*mask)(evtchn_port_t port); | 24 | void (*mask)(evtchn_port_t port); |
| 25 | void (*unmask)(evtchn_port_t port); | 25 | void (*unmask)(evtchn_port_t port); |
| 26 | 26 | ||
| @@ -54,6 +54,13 @@ static inline int xen_evtchn_port_setup(evtchn_port_t evtchn) · 27 unmodified lines | |||
| 54 | return 0; | 54 | return 0; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | static inline void xen_evtchn_port_remove(evtchn_port_t evtchn, | ||
| 58 | unsigned int cpu) | ||
| 59 | { | ||
| 60 | if (evtchn_ops->remove) | ||
| 61 | evtchn_ops->remove(evtchn, cpu); | ||
| 62 | } | ||
| 63 | |||
| 57 | static inline void xen_evtchn_port_bind_to_cpu(evtchn_port_t evtchn, | 64 | static inline void xen_evtchn_port_bind_to_cpu(evtchn_port_t evtchn, |
| 58 | unsigned int cpu, | 65 | unsigned int cpu, |
| 59 | unsigned int old_cpu) | 66 | unsigned int old_cpu) |
| @@ -76,11 +83,6 @@ static inline bool test_evtchn(evtchn_port_t port) · 16 unmodified lines | |||
| 76 | return evtchn_ops->is_pending(port); | 83 | return evtchn_ops->is_pending(port); |
| 77 | } | 84 | } |
| 78 | 85 | ||
| 79 | static inline bool test_and_set_mask(evtchn_port_t port) | ||
| 80 | { | ||
| 81 | return evtchn_ops->test_and_set_mask(port); | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline void mask_evtchn(evtchn_port_t port) | 86 | static inline void mask_evtchn(evtchn_port_t port) |
| 85 | { | 87 | { |
| 86 | return evtchn_ops->mask(port); | 88 | return evtchn_ops->mask(port); |
| @@ -133,20 +133,26 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, · 132 unmodified lines | |||
| 133 | if (NULL == add) | 133 | if (NULL == add) |
| 134 | return NULL; | 134 | return NULL; |
| 135 | 135 | ||
| 136 | add->grants = kvcalloc(count, sizeof(add->grants[0]), GFP_KERNEL); | 136 | add->grants = kvmalloc_array(count, sizeof(add->grants[0]), |
| 137 | add->map_ops = kvcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL); | 137 | GFP_KERNEL); |
| 138 | add->unmap_ops = kvcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL); | 138 | add->map_ops = kvmalloc_array(count, sizeof(add->map_ops[0]), |
| 139 | add->kmap_ops = kvcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL); | 139 | GFP_KERNEL); |
| 140 | add->kunmap_ops = kvcalloc(count, | 140 | add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]), |
| 141 | sizeof(add->kunmap_ops[0]), GFP_KERNEL); | 141 | GFP_KERNEL); |
| 142 | add->pages = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); | 142 | add->pages = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); |
| 143 | if (NULL == add->grants || | 143 | if (NULL == add->grants || |
| 144 | NULL == add->map_ops || | 144 | NULL == add->map_ops || |
| 145 | NULL == add->unmap_ops || | 145 | NULL == add->unmap_ops || |
| 146 | NULL == add->kmap_ops || | ||
| 147 | NULL == add->kunmap_ops || | ||
| 148 | NULL == add->pages) | 146 | NULL == add->pages) |
| 149 | goto err; | 147 | goto err; |
| 148 | if (use_ptemod) { | ||
| 149 | add->kmap_ops = kvmalloc_array(count, sizeof(add->kmap_ops[0]), | ||
| 150 | GFP_KERNEL); | ||
| 151 | add->kunmap_ops = kvmalloc_array(count, sizeof(add->kunmap_ops[0]), | ||
| 152 | GFP_KERNEL); | ||
| 153 | if (NULL == add->kmap_ops || NULL == add->kunmap_ops) | ||
| 154 | goto err; | ||
| 155 | } | ||
| 150 | 156 | ||
| 151 | #ifdef CONFIG_XEN_GRANT_DMA_ALLOC | 157 | #ifdef CONFIG_XEN_GRANT_DMA_ALLOC |
| 152 | add->dma_flags = dma_flags; | 158 | add->dma_flags = dma_flags; |
| @@ -183,10 +189,14 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, · 30 unmodified lines | |||
| 183 | goto err; | 189 | goto err; |
| 184 | 190 | ||
| 185 | for (i = 0; i < count; i++) { | 191 | for (i = 0; i < count; i++) { |
| 186 | add->map_ops[i].handle = -1; | 192 | add->grants[i].domid = DOMID_INVALID; |
| 187 | add->unmap_ops[i].handle = -1; | 193 | add->grants[i].ref = INVALID_GRANT_REF; |
| 188 | add->kmap_ops[i].handle = -1; | 194 | add->map_ops[i].handle = INVALID_GRANT_HANDLE; |
| 189 | add->kunmap_ops[i].handle = -1; | 195 | add->unmap_ops[i].handle = INVALID_GRANT_HANDLE; |
| 196 | if (use_ptemod) { | ||
| 197 | add->kmap_ops[i].handle = INVALID_GRANT_HANDLE; | ||
| 198 | add->kunmap_ops[i].handle = INVALID_GRANT_HANDLE; | ||
| 199 | } | ||
| 190 | } | 200 | } |
| 191 | 201 | ||
| 192 | add->index = 0; | 202 | add->index = 0; |
| @@ -274,7 +284,7 @@ static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data) · 81 unmodified lines | |||
| 274 | map->grants[pgnr].ref, | 284 | map->grants[pgnr].ref, |
| 275 | map->grants[pgnr].domid); | 285 | map->grants[pgnr].domid); |
| 276 | gnttab_set_unmap_op(&map->unmap_ops[pgnr], pte_maddr, flags, | 286 | gnttab_set_unmap_op(&map->unmap_ops[pgnr], pte_maddr, flags, |
| 277 | -1 /* handle */); | 287 | INVALID_GRANT_HANDLE); |
| 278 | return 0; | 288 | return 0; |
| 279 | } | 289 | } |
| 280 | 290 | ||
| @@ -292,7 +302,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) · 11 unmodified lines | |||
| 292 | 302 | ||
| 293 | if (!use_ptemod) { | 303 | if (!use_ptemod) { |
| 294 | /* Note: it could already be mapped */ | 304 | /* Note: it could already be mapped */ |
| 295 | if (map->map_ops[0].handle != -1) | 305 | if (map->map_ops[0].handle != INVALID_GRANT_HANDLE) |
| 296 | return 0; | 306 | return 0; |
| 297 | for (i = 0; i < map->count; i++) { | 307 | for (i = 0; i < map->count; i++) { |
| 298 | unsigned long addr = (unsigned long) | 308 | unsigned long addr = (unsigned long) |
| @@ -301,7 +311,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) · 2 unmodified lines | |||
| 301 | map->grants[i].ref, | 311 | map->grants[i].ref, |
| 302 | map->grants[i].domid); | 312 | map->grants[i].domid); |
| 303 | gnttab_set_unmap_op(&map->unmap_ops[i], addr, | 313 | gnttab_set_unmap_op(&map->unmap_ops[i], addr, |
| 304 | map->flags, -1 /* handle */); | 314 | map->flags, INVALID_GRANT_HANDLE); |
| 305 | } | 315 | } |
| 306 | } else { | 316 | } else { |
| 307 | /* | 317 | /* |
| @@ -327,13 +337,13 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) · 19 unmodified lines | |||
| 327 | map->grants[i].ref, | 337 | map->grants[i].ref, |
| 328 | map->grants[i].domid); | 338 | map->grants[i].domid); |
| 329 | gnttab_set_unmap_op(&map->kunmap_ops[i], address, | 339 | gnttab_set_unmap_op(&map->kunmap_ops[i], address, |
| 330 | flags, -1); | 340 | flags, INVALID_GRANT_HANDLE); |
| 331 | } | 341 | } |
| 332 | } | 342 | } |
| 333 | 343 | ||
| 334 | pr_debug("map %d+%d\n", map->index, map->count); | 344 | pr_debug("map %d+%d\n", map->index, map->count); |
| 335 | err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, | 345 | err = gnttab_map_refs(map->map_ops, map->kmap_ops, map->pages, |
| 336 | map->pages, map->count); | 346 | map->count); |
| 337 | 347 | ||
| 338 | for (i = 0; i < map->count; i++) { | 348 | for (i = 0; i < map->count; i++) { |
| 339 | if (map->map_ops[i].status == GNTST_okay) | 349 | if (map->map_ops[i].status == GNTST_okay) |
| @@ -385,7 +395,7 @@ static int __unmap_grant_pages(struct gntdev_grant_map *map, int offset, · 45 unmodified lines | |||
| 385 | pr_debug("unmap handle=%d st=%d\n", | 395 | pr_debug("unmap handle=%d st=%d\n", |
| 386 | map->unmap_ops[offset+i].handle, | 396 | map->unmap_ops[offset+i].handle, |
| 387 | map->unmap_ops[offset+i].status); | 397 | map->unmap_ops[offset+i].status); |
| 388 | map->unmap_ops[offset+i].handle = -1; | 398 | map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; |
| 389 | } | 399 | } |
| 390 | return err; | 400 | return err; |
| 391 | } | 401 | } |
| @@ -401,13 +411,15 @@ static int unmap_grant_pages(struct gntdev_grant_map *map, int offset, · 9 unmodified lines | |||
| 401 | * already unmapped some of the grants. Only unmap valid ranges. | 411 | * already unmapped some of the grants. Only unmap valid ranges. |
| 402 | */ | 412 | */ |
| 403 | while (pages && !err) { | 413 | while (pages && !err) { |
| 404 | while (pages && map->unmap_ops[offset].handle == -1) { | 414 | while (pages && |
| 415 | map->unmap_ops[offset].handle == INVALID_GRANT_HANDLE) { | ||
| 405 | offset++; | 416 | offset++; |
| 406 | pages--; | 417 | pages--; |
| 407 | } | 418 | } |
| 408 | range = 0; | 419 | range = 0; |
| 409 | while (range < pages) { | 420 | while (range < pages) { |
| 410 | if (map->unmap_ops[offset+range].handle == -1) | 421 | if (map->unmap_ops[offset + range].handle == |
| 422 | INVALID_GRANT_HANDLE) | ||
| 411 | break; | 423 | break; |
| 412 | range++; | 424 | range++; |
| 413 | } | 425 | } |
| @@ -203,7 +203,7 @@ config TMPFS_XATTR · 202 unmodified lines | |||
| 203 | 203 | ||
| 204 | config TMPFS_INODE64 | 204 | config TMPFS_INODE64 |
| 205 | bool "Use 64-bit ino_t by default in tmpfs" | 205 | bool "Use 64-bit ino_t by default in tmpfs" |
| 206 | depends on TMPFS && 64BIT && !(S390 || ALPHA) | 206 | depends on TMPFS && 64BIT |
| 207 | default n | 207 | default n |
| 208 | help | 208 | help |
| 209 | tmpfs has historically used only inode numbers as wide as an unsigned | 209 | tmpfs has historically used only inode numbers as wide as an unsigned |
| @@ -70,7 +70,6 @@ const struct inode_operations afs_dir_inode_operations = { · 69 unmodified lines | |||
| 70 | .permission = afs_permission, | 70 | .permission = afs_permission, |
| 71 | .getattr = afs_getattr, | 71 | .getattr = afs_getattr, |
| 72 | .setattr = afs_setattr, | 72 | .setattr = afs_setattr, |
| 73 | .listxattr = afs_listxattr, | ||
| 74 | }; | 73 | }; |
| 75 | 74 | ||
| 76 | const struct address_space_operations afs_dir_aops = { | 75 | const struct address_space_operations afs_dir_aops = { |
| @@ -43,7 +43,6 @@ const struct inode_operations afs_file_inode_operations = { · 42 unmodified lines | |||
| 43 | .getattr = afs_getattr, | 43 | .getattr = afs_getattr, |
| 44 | .setattr = afs_setattr, | 44 | .setattr = afs_setattr, |
| 45 | .permission = afs_permission, | 45 | .permission = afs_permission, |
| 46 | .listxattr = afs_listxattr, | ||
| 47 | }; | 46 | }; |
| 48 | 47 | ||
| 49 | const struct address_space_operations afs_fs_aops = { | 48 | const struct address_space_operations afs_fs_aops = { |
| @@ -181,10 +181,13 @@ void afs_wait_for_operation(struct afs_operation *op) · 180 unmodified lines | |||
| 181 | if (test_bit(AFS_SERVER_FL_IS_YFS, &op->server->flags) && | 181 | if (test_bit(AFS_SERVER_FL_IS_YFS, &op->server->flags) && |
| 182 | op->ops->issue_yfs_rpc) | 182 | op->ops->issue_yfs_rpc) |
| 183 | op->ops->issue_yfs_rpc(op); | 183 | op->ops->issue_yfs_rpc(op); |
| 184 | else | 184 | else if (op->ops->issue_afs_rpc) |
| 185 | op->ops->issue_afs_rpc(op); | 185 | op->ops->issue_afs_rpc(op); |
| 186 | else | ||
| 187 | op->ac.error = -ENOTSUPP; | ||
| 186 | 188 | ||
| 187 | op->error = afs_wait_for_call_to_complete(op->call, &op->ac); | 189 | if (op->call) |
| 190 | op->error = afs_wait_for_call_to_complete(op->call, &op->ac); | ||
| 188 | } | 191 | } |
| 189 | 192 | ||
| 190 | switch (op->error) { | 193 | switch (op->error) { |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | static const struct inode_operations afs_symlink_inode_operations = { | 28 | static const struct inode_operations afs_symlink_inode_operations = { |
| 29 | .get_link = page_get_link, | 29 | .get_link = page_get_link, |
| 30 | .listxattr = afs_listxattr, | ||
| 31 | }; | 30 | }; |
| 32 | 31 | ||
| 33 | static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode) | 32 | static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode) |
| @@ -1509,7 +1509,6 @@ extern int afs_launder_page(struct page *); · 1508 unmodified lines | |||
| 1509 | * xattr.c | 1509 | * xattr.c |
| 1510 | */ | 1510 | */ |
| 1511 | extern const struct xattr_handler *afs_xattr_handlers[]; | 1511 | extern const struct xattr_handler *afs_xattr_handlers[]; |
| 1512 | extern ssize_t afs_listxattr(struct dentry *, char *, size_t); | ||
| 1513 | 1512 | ||
| 1514 | /* | 1513 | /* |
| 1515 | * yfsclient.c | 1514 | * yfsclient.c |
| @@ -32,7 +32,6 @@ const struct inode_operations afs_mntpt_inode_operations = { · 31 unmodified lines | |||
| 32 | .lookup = afs_mntpt_lookup, | 32 | .lookup = afs_mntpt_lookup, |
| 33 | .readlink = page_readlink, | 33 | .readlink = page_readlink, |
| 34 | .getattr = afs_getattr, | 34 | .getattr = afs_getattr, |
| 35 | .listxattr = afs_listxattr, | ||
| 36 | }; | 35 | }; |
| 37 | 36 | ||
| 38 | const struct inode_operations afs_autocell_inode_operations = { | 37 | const struct inode_operations afs_autocell_inode_operations = { |
| @@ -851,8 +851,7 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf) · 850 unmodified lines | |||
| 851 | fscache_wait_on_page_write(vnode->cache, vmf->page); | 851 | fscache_wait_on_page_write(vnode->cache, vmf->page); |
| 852 | #endif | 852 | #endif |
| 853 | 853 | ||
| 854 | if (PageWriteback(vmf->page) && | 854 | if (wait_on_page_writeback_killable(vmf->page)) |
| 855 | wait_on_page_bit_killable(vmf->page, PG_writeback) < 0) | ||
| 856 | return VM_FAULT_RETRY; | 855 | return VM_FAULT_RETRY; |
| 857 | 856 | ||
| 858 | if (lock_page_killable(vmf->page) < 0) | 857 | if (lock_page_killable(vmf->page) < 0) |
| @@ -11,29 +11,6 @@ · 10 unmodified lines | |||
| 11 | #include <linux/xattr.h> | 11 | #include <linux/xattr.h> |
| 12 | #include "internal.h" | 12 | #include "internal.h" |
| 13 | 13 | ||
| 14 | static const char afs_xattr_list[] = | ||
| 15 | "afs.acl\0" | ||
| 16 | "afs.cell\0" | ||
| 17 | "afs.fid\0" | ||
| 18 | "afs.volume\0" | ||
| 19 | "afs.yfs.acl\0" | ||
| 20 | "afs.yfs.acl_inherited\0" | ||
| 21 | "afs.yfs.acl_num_cleaned\0" | ||
| 22 | "afs.yfs.vol_acl"; | ||
| 23 | |||
| 24 | /* | ||
| 25 | * Retrieve a list of the supported xattrs. | ||
| 26 | */ | ||
| 27 | ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size) | ||
| 28 | { | ||
| 29 | if (size == 0) | ||
| 30 | return sizeof(afs_xattr_list); | ||
| 31 | if (size < sizeof(afs_xattr_list)) | ||
| 32 | return -ERANGE; | ||
| 33 | memcpy(buffer, afs_xattr_list, sizeof(afs_xattr_list)); | ||
| 34 | return sizeof(afs_xattr_list); | ||
| 35 | } | ||
| 36 | |||
| 37 | /* | 14 | /* |
| 38 | * Deal with the result of a successful fetch ACL operation. | 15 | * Deal with the result of a successful fetch ACL operation. |
| 39 | */ | 16 | */ |
| @@ -231,6 +208,8 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, · 191 unmodified lines | |||
| 231 | else | 208 | else |
| 232 | ret = -ERANGE; | 209 | ret = -ERANGE; |
| 233 | } | 210 | } |
| 211 | } else if (ret == -ENOTSUPP) { | ||
| 212 | ret = -ENODATA; | ||
| 234 | } | 213 | } |
| 235 | 214 | ||
| 236 | error_yacl: | 215 | error_yacl: |
| @@ -256,6 +235,7 @@ static int afs_xattr_set_yfs(const struct xattr_handler *handler, · 19 unmodified lines | |||
| 256 | { | 235 | { |
| 257 | struct afs_operation *op; | 236 | struct afs_operation *op; |
| 258 | struct afs_vnode *vnode = AFS_FS_I(inode); | 237 | struct afs_vnode *vnode = AFS_FS_I(inode); |
| 238 | int ret; | ||
| 259 | 239 | ||
| 260 | if (flags == XATTR_CREATE || | 240 | if (flags == XATTR_CREATE || |
| 261 | strcmp(name, "acl") != 0) | 241 | strcmp(name, "acl") != 0) |
| @@ -270,7 +250,10 @@ static int afs_xattr_set_yfs(const struct xattr_handler *handler, · 8 unmodified lines | |||
| 270 | return afs_put_operation(op); | 250 | return afs_put_operation(op); |
| 271 | 251 | ||
| 272 | op->ops = &yfs_store_opaque_acl2_operation; | 252 | op->ops = &yfs_store_opaque_acl2_operation; |
| 273 | return afs_do_sync_operation(op); | 253 | ret = afs_do_sync_operation(op); |
| 254 | if (ret == -ENOTSUPP) | ||
| 255 | ret = -ENODATA; | ||
| 256 | return ret; | ||
| 274 | } | 257 | } |
| 275 | 258 | ||
| 276 | static const struct xattr_handler afs_xattr_yfs_handler = { | 259 | static const struct xattr_handler afs_xattr_yfs_handler = { |
| @@ -649,12 +649,24 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, · 648 unmodified lines | |||
| 649 | struct super_block *sb = file_inode(file)->i_sb; | 649 | struct super_block *sb = file_inode(file)->i_sb; |
| 650 | struct dentry *root = sb->s_root, *dentry; | 650 | struct dentry *root = sb->s_root, *dentry; |
| 651 | int err = 0; | 651 | int err = 0; |
| 652 | struct file *f = NULL; | ||
| 652 | 653 | ||
| 653 | e = create_entry(buffer, count); | 654 | e = create_entry(buffer, count); |
| 654 | 655 | ||
| 655 | if (IS_ERR(e)) | 656 | if (IS_ERR(e)) |
| 656 | return PTR_ERR(e); | 657 | return PTR_ERR(e); |
| 657 | 658 | ||
| 659 | if (e->flags & MISC_FMT_OPEN_FILE) { | ||
| 660 | f = open_exec(e->interpreter); | ||
| 661 | if (IS_ERR(f)) { | ||
| 662 | pr_notice("register: failed to install interpreter file %s\n", | ||
| 663 | e->interpreter); | ||
| 664 | kfree(e); | ||
| 665 | return PTR_ERR(f); | ||
| 666 | } | ||
| 667 | e->interp_file = f; | ||
| 668 | } | ||
| 669 | |||
| 658 | inode_lock(d_inode(root)); | 670 | inode_lock(d_inode(root)); |
| 659 | dentry = lookup_one_len(e->name, root, strlen(e->name)); | 671 | dentry = lookup_one_len(e->name, root, strlen(e->name)); |
| 660 | err = PTR_ERR(dentry); | 672 | err = PTR_ERR(dentry); |
| @@ -678,21 +690,6 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, · 17 unmodified lines | |||
| 678 | goto out2; | 690 | goto out2; |
| 679 | } | 691 | } |
| 680 | 692 | ||
| 681 | if (e->flags & MISC_FMT_OPEN_FILE) { | ||
| 682 | struct file *f; | ||
| 683 | |||
| 684 | f = open_exec(e->interpreter); | ||
| 685 | if (IS_ERR(f)) { | ||
| 686 | err = PTR_ERR(f); | ||
| 687 | pr_notice("register: failed to install interpreter file %s\n", e->interpreter); | ||
| 688 | simple_release_fs(&bm_mnt, &entry_count); | ||
| 689 | iput(inode); | ||
| 690 | inode = NULL; | ||
| 691 | goto out2; | ||
| 692 | } | ||
| 693 | e->interp_file = f; | ||
| 694 | } | ||
| 695 | |||
| 696 | e->dentry = dget(dentry); | 693 | e->dentry = dget(dentry); |
| 697 | inode->i_private = e; | 694 | inode->i_private = e; |
| 698 | inode->i_fop = &bm_entry_operations; | 695 | inode->i_fop = &bm_entry_operations; |
| @@ -709,6 +706,8 @@ out: · 10 unmodified lines | |||
| 709 | inode_unlock(d_inode(root)); | 706 | inode_unlock(d_inode(root)); |
| 710 | 707 | ||
| 711 | if (err) { | 708 | if (err) { |
| 709 | if (f) | ||
| 710 | filp_close(f, NULL); | ||
| 712 | kfree(e); | 711 | kfree(e); |
| 713 | return err; | 712 | return err; |
| 714 | } | 713 | } |
| @@ -118,13 +118,22 @@ int truncate_bdev_range(struct block_device *bdev, fmode_t mode, · 117 unmodified lines | |||
| 118 | if (!(mode & FMODE_EXCL)) { | 118 | if (!(mode & FMODE_EXCL)) { |
| 119 | int err = bd_prepare_to_claim(bdev, truncate_bdev_range); | 119 | int err = bd_prepare_to_claim(bdev, truncate_bdev_range); |
| 120 | if (err) | 120 | if (err) |
| 121 | return err; | 121 | goto invalidate; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | truncate_inode_pages_range(bdev->bd_inode->i_mapping, lstart, lend); | 124 | truncate_inode_pages_range(bdev->bd_inode->i_mapping, lstart, lend); |
| 125 | if (!(mode & FMODE_EXCL)) | 125 | if (!(mode & FMODE_EXCL)) |
| 126 | bd_abort_claiming(bdev, truncate_bdev_range); | 126 | bd_abort_claiming(bdev, truncate_bdev_range); |
| 127 | return 0; | 127 | return 0; |
| 128 | |||
| 129 | invalidate: | ||
| 130 | /* | ||
| 131 | * Someone else has handle exclusively open. Try invalidating instead. | ||
| 132 | * The 'end' argument is inclusive so the rounding is safe. | ||
| 133 | */ | ||
| 134 | return invalidate_inode_pages2_range(bdev->bd_inode->i_mapping, | ||
| 135 | lstart >> PAGE_SHIFT, | ||
| 136 | lend >> PAGE_SHIFT); | ||
| 128 | } | 137 | } |
| 129 | 138 | ||
| 130 | static void set_init_blocksize(struct block_device *bdev) | 139 | static void set_init_blocksize(struct block_device *bdev) |
| @@ -423,7 +432,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, · 292 unmodified lines | |||
| 423 | dio->size += bio->bi_iter.bi_size; | 432 | dio->size += bio->bi_iter.bi_size; |
| 424 | pos += bio->bi_iter.bi_size; | 433 | pos += bio->bi_iter.bi_size; |
| 425 | 434 | ||
| 426 | nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_PAGES); | 435 | nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS); |
| 427 | if (!nr_pages) { | 436 | if (!nr_pages) { |
| 428 | bool polled = false; | 437 | bool polled = false; |
| 429 | 438 | ||
| @@ -491,8 +500,8 @@ blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter) · 61 unmodified lines | |||
| 491 | if (!iov_iter_count(iter)) | 500 | if (!iov_iter_count(iter)) |
| 492 | return 0; | 501 | return 0; |
| 493 | 502 | ||
| 494 | nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_PAGES + 1); | 503 | nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1); |
| 495 | if (is_sync_kiocb(iocb) && nr_pages <= BIO_MAX_PAGES) | 504 | if (is_sync_kiocb(iocb) && nr_pages <= BIO_MAX_VECS) |
| 496 | return __blkdev_direct_IO_simple(iocb, iter, nr_pages); | 505 | return __blkdev_direct_IO_simple(iocb, iter, nr_pages); |
| 497 | 506 | ||
| 498 | return __blkdev_direct_IO(iocb, iter, bio_max_segs(nr_pages)); | 507 | return __blkdev_direct_IO(iocb, iter, bio_max_segs(nr_pages)); |
| @@ -1365,7 +1365,9 @@ get_old_root(struct btrfs_root *root, u64 time_seq) · 1364 unmodified lines | |||
| 1365 | "failed to read tree block %llu from get_old_root", | 1365 | "failed to read tree block %llu from get_old_root", |
| 1366 | logical); | 1366 | logical); |
| 1367 | } else { | 1367 | } else { |
| 1368 | btrfs_tree_read_lock(old); | ||
| 1368 | eb = btrfs_clone_extent_buffer(old); | 1369 | eb = btrfs_clone_extent_buffer(old); |
| 1370 | btrfs_tree_read_unlock(old); | ||
| 1369 | free_extent_buffer(old); | 1371 | free_extent_buffer(old); |
| 1370 | } | 1372 | } |
| 1371 | } else if (old_root) { | 1373 | } else if (old_root) { |
| @@ -3323,6 +3323,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, · 3322 unmodified lines | |||
| 3323 | 3323 | ||
| 3324 | if (last_ref && btrfs_header_generation(buf) == trans->transid) { | 3324 | if (last_ref && btrfs_header_generation(buf) == trans->transid) { |
| 3325 | struct btrfs_block_group *cache; | 3325 | struct btrfs_block_group *cache; |
| 3326 | bool must_pin = false; | ||
| 3326 | 3327 | ||
| 3327 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { | 3328 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { |
| 3328 | ret = check_ref_cleanup(trans, buf->start); | 3329 | ret = check_ref_cleanup(trans, buf->start); |
| @@ -3340,7 +3341,27 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, · 11 unmodified lines | |||
| 3340 | goto out; | 3341 | goto out; |
| 3341 | } | 3342 | } |
| 3342 | 3343 | ||
| 3343 | if (btrfs_is_zoned(fs_info)) { | 3344 | /* |
| 3345 | * If this is a leaf and there are tree mod log users, we may | ||
| 3346 | * have recorded mod log operations that point to this leaf. | ||
| 3347 | * So we must make sure no one reuses this leaf's extent before | ||
| 3348 | * mod log operations are applied to a node, otherwise after | ||
| 3349 | * rewinding a node using the mod log operations we get an | ||
| 3350 | * inconsistent btree, as the leaf's extent may now be used as | ||
| 3351 | * a node or leaf for another different btree. | ||
| 3352 | * We are safe from races here because at this point no other | ||
| 3353 | * node or root points to this extent buffer, so if after this | ||
| 3354 | * check a new tree mod log user joins, it will not be able to | ||
| 3355 | * find a node pointing to this leaf and record operations that | ||
| 3356 | * point to this leaf. | ||
| 3357 | */ | ||
| 3358 | if (btrfs_header_level(buf) == 0) { | ||
| 3359 | read_lock(&fs_info->tree_mod_log_lock); | ||
| 3360 | must_pin = !list_empty(&fs_info->tree_mod_seq_list); | ||
| 3361 | read_unlock(&fs_info->tree_mod_log_lock); | ||
| 3362 | } | ||
| 3363 | |||
| 3364 | if (must_pin || btrfs_is_zoned(fs_info)) { | ||
| 3344 | btrfs_redirty_list_add(trans->transaction, buf); | 3365 | btrfs_redirty_list_add(trans->transaction, buf); |
| 3345 | pin_down_extent(trans, cache, buf->start, buf->len, 1); | 3366 | pin_down_extent(trans, cache, buf->start, buf->len, 1); |
| 3346 | btrfs_put_block_group(cache); | 3367 | btrfs_put_block_group(cache); |
| @@ -2885,6 +2885,35 @@ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len) · 2884 unmodified lines | |||
| 2885 | btrfs_subpage_end_reader(fs_info, page, start, len); | 2885 | btrfs_subpage_end_reader(fs_info, page, start, len); |
| 2886 | } | 2886 | } |
| 2887 | 2887 | ||
| 2888 | /* | ||
| 2889 | * Find extent buffer for a givne bytenr. | ||
| 2890 | * | ||
| 2891 | * This is for end_bio_extent_readpage(), thus we can't do any unsafe locking | ||
| 2892 | * in endio context. | ||
| 2893 | */ | ||
| 2894 | static struct extent_buffer *find_extent_buffer_readpage( | ||
| 2895 | struct btrfs_fs_info *fs_info, struct page *page, u64 bytenr) | ||
| 2896 | { | ||
| 2897 | struct extent_buffer *eb; | ||
| 2898 | |||
| 2899 | /* | ||
| 2900 | * For regular sectorsize, we can use page->private to grab extent | ||
| 2901 | * buffer | ||
| 2902 | */ | ||
| 2903 | if (fs_info->sectorsize == PAGE_SIZE) { | ||
| 2904 | ASSERT(PagePrivate(page) && page->private); | ||
| 2905 | return (struct extent_buffer *)page->private; | ||
| 2906 | } | ||
| 2907 | |||
| 2908 | /* For subpage case, we need to lookup buffer radix tree */ | ||
| 2909 | rcu_read_lock(); | ||
| 2910 | eb = radix_tree_lookup(&fs_info->buffer_radix, | ||
| 2911 | bytenr >> fs_info->sectorsize_bits); | ||
| 2912 | rcu_read_unlock(); | ||
| 2913 | ASSERT(eb); | ||
| 2914 | return eb; | ||
| 2915 | } | ||
| 2916 | |||
| 2888 | /* | 2917 | /* |
| 2889 | * after a readpage IO is done, we need to: | 2918 | * after a readpage IO is done, we need to: |
| 2890 | * clear the uptodate bits on error | 2919 | * clear the uptodate bits on error |
| @@ -2996,7 +3025,7 @@ static void end_bio_extent_readpage(struct bio *bio) · 105 unmodified lines | |||
| 2996 | } else { | 3025 | } else { |
| 2997 | struct extent_buffer *eb; | 3026 | struct extent_buffer *eb; |
| 2998 | 3027 | ||
| 2999 | eb = (struct extent_buffer *)page->private; | 3028 | eb = find_extent_buffer_readpage(fs_info, page, start); |
| 3000 | set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags); | 3029 | set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags); |
| 3001 | eb->read_mirror = mirror; | 3030 | eb->read_mirror = mirror; |
| 3002 | atomic_dec(&eb->io_pages); | 3031 | atomic_dec(&eb->io_pages); |
| @@ -3020,7 +3049,7 @@ readpage_ok: · 17 unmodified lines | |||
| 3020 | */ | 3049 | */ |
| 3021 | if (page->index == end_index && i_size <= end) { | 3050 | if (page->index == end_index && i_size <= end) { |
| 3022 | u32 zero_start = max(offset_in_page(i_size), | 3051 | u32 zero_start = max(offset_in_page(i_size), |
| 3023 | offset_in_page(end)); | 3052 | offset_in_page(start)); |
| 3024 | 3053 | ||
| 3025 | zero_user_segment(page, zero_start, | 3054 | zero_user_segment(page, zero_start, |
| 3026 | offset_in_page(end) + 1); | 3055 | offset_in_page(end) + 1); |
| @@ -3059,7 +3088,7 @@ struct bio *btrfs_bio_alloc(u64 first_byte) · 32 unmodified lines | |||
| 3059 | { | 3088 | { |
| 3060 | struct bio *bio; | 3089 | struct bio *bio; |
| 3061 | 3090 | ||
| 3062 | bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, &btrfs_bioset); | 3091 | bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_VECS, &btrfs_bioset); |
| 3063 | bio->bi_iter.bi_sector = first_byte >> 9; | 3092 | bio->bi_iter.bi_sector = first_byte >> 9; |
| 3064 | btrfs_io_bio_init(btrfs_io_bio(bio)); | 3093 | btrfs_io_bio_init(btrfs_io_bio(bio)); |
| 3065 | return bio; | 3094 | return bio; |
| @@ -9008,7 +9008,7 @@ int __init btrfs_init_cachep(void) · 9007 unmodified lines | |||
| 9008 | 9008 | ||
| 9009 | btrfs_free_space_bitmap_cachep = kmem_cache_create("btrfs_free_space_bitmap", | 9009 | btrfs_free_space_bitmap_cachep = kmem_cache_create("btrfs_free_space_bitmap", |
| 9010 | PAGE_SIZE, PAGE_SIZE, | 9010 | PAGE_SIZE, PAGE_SIZE, |
| 9011 | SLAB_RED_ZONE, NULL); | 9011 | SLAB_MEM_SPREAD, NULL); |
| 9012 | if (!btrfs_free_space_bitmap_cachep) | 9012 | if (!btrfs_free_space_bitmap_cachep) |
| 9013 | goto fail; | 9013 | goto fail; |
| 9014 | 9014 | ||
| @@ -9877,6 +9877,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( · 862 unmodified lines | |||
| 9877 | struct btrfs_path *path; | 9877 | struct btrfs_path *path; |
| 9878 | u64 start = ins->objectid; | 9878 | u64 start = ins->objectid; |
| 9879 | u64 len = ins->offset; | 9879 | u64 len = ins->offset; |
| 9880 | int qgroup_released; | ||
| 9880 | int ret; | 9881 | int ret; |
| 9881 | 9882 | ||
| 9882 | memset(&stack_fi, 0, sizeof(stack_fi)); | 9883 | memset(&stack_fi, 0, sizeof(stack_fi)); |
| @@ -9889,16 +9890,16 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( · 6 unmodified lines | |||
| 9889 | btrfs_set_stack_file_extent_compression(&stack_fi, BTRFS_COMPRESS_NONE); | 9890 | btrfs_set_stack_file_extent_compression(&stack_fi, BTRFS_COMPRESS_NONE); |
| 9890 | /* Encryption and other encoding is reserved and all 0 */ | 9891 | /* Encryption and other encoding is reserved and all 0 */ |
| 9891 | 9892 | ||
| 9892 | ret = btrfs_qgroup_release_data(inode, file_offset, len); | 9893 | qgroup_released = btrfs_qgroup_release_data(inode, file_offset, len); |
| 9893 | if (ret < 0) | 9894 | if (qgroup_released < 0) |
| 9894 | return ERR_PTR(ret); | 9895 | return ERR_PTR(qgroup_released); |
| 9895 | 9896 | ||
| 9896 | if (trans) { | 9897 | if (trans) { |
| 9897 | ret = insert_reserved_file_extent(trans, inode, | 9898 | ret = insert_reserved_file_extent(trans, inode, |
| 9898 | file_offset, &stack_fi, | 9899 | file_offset, &stack_fi, |
| 9899 | true, ret); | 9900 | true, qgroup_released); |
| 9900 | if (ret) | 9901 | if (ret) |
| 9901 | return ERR_PTR(ret); | 9902 | goto free_qgroup; |
| 9902 | return trans; | 9903 | return trans; |
| 9903 | } | 9904 | } |
| 9904 | 9905 | ||
| @@ -9909,21 +9910,35 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( · 4 unmodified lines | |||
| 9909 | extent_info.file_offset = file_offset; | 9910 | extent_info.file_offset = file_offset; |
| 9910 | extent_info.extent_buf = (char *)&stack_fi; | 9911 | extent_info.extent_buf = (char *)&stack_fi; |
| 9911 | extent_info.is_new_extent = true; | 9912 | extent_info.is_new_extent = true; |
| 9912 | extent_info.qgroup_reserved = ret; | 9913 | extent_info.qgroup_reserved = qgroup_released; |
| 9913 | extent_info.insertions = 0; | 9914 | extent_info.insertions = 0; |
| 9914 | 9915 | ||
| 9915 | path = btrfs_alloc_path(); | 9916 | path = btrfs_alloc_path(); |
| 9916 | if (!path) | 9917 | if (!path) { |
| 9917 | return ERR_PTR(-ENOMEM); | 9918 | ret = -ENOMEM; |
| 9919 | goto free_qgroup; | ||
| 9920 | } | ||
| 9918 | 9921 | ||
| 9919 | ret = btrfs_replace_file_extents(&inode->vfs_inode, path, file_offset, | 9922 | ret = btrfs_replace_file_extents(&inode->vfs_inode, path, file_offset, |
| 9920 | file_offset + len - 1, &extent_info, | 9923 | file_offset + len - 1, &extent_info, |
| 9921 | &trans); | 9924 | &trans); |
| 9922 | btrfs_free_path(path); | 9925 | btrfs_free_path(path); |
| 9923 | if (ret) | 9926 | if (ret) |
| 9924 | return ERR_PTR(ret); | 9927 | goto free_qgroup; |
| 9925 | |||
| 9926 | return trans; | 9928 | return trans; |
| 9929 | |||
| 9930 | free_qgroup: | ||
| 9931 | /* | ||
| 9932 | * We have released qgroup data range at the beginning of the function, | ||
| 9933 | * and normally qgroup_released bytes will be freed when committing | ||
| 9934 | * transaction. | ||
| 9935 | * But if we error out early, we have to free what we have released | ||
| 9936 | * or we leak qgroup data reservation. | ||
| 9937 | */ | ||
| 9938 | btrfs_qgroup_free_refroot(inode->root->fs_info, | ||
| 9939 | inode->root->root_key.objectid, qgroup_released, | ||
| 9940 | BTRFS_QGROUP_RSV_DATA); | ||
| 9941 | return ERR_PTR(ret); | ||
| 9927 | } | 9942 | } |
| 9928 | 9943 | ||
| 9929 | static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | 9944 | static int __btrfs_prealloc_file_range(struct inode *inode, int mode, |
| @@ -209,7 +209,7 @@ int btree_readahead_hook(struct extent_buffer *eb, int err) · 208 unmodified lines | |||
| 209 | /* find extent */ | 209 | /* find extent */ |
| 210 | spin_lock(&fs_info->reada_lock); | 210 | spin_lock(&fs_info->reada_lock); |
| 211 | re = radix_tree_lookup(&fs_info->reada_tree, | 211 | re = radix_tree_lookup(&fs_info->reada_tree, |
| 212 | eb->start >> PAGE_SHIFT); | 212 | eb->start >> fs_info->sectorsize_bits); |
| 213 | if (re) | 213 | if (re) |
| 214 | re->refcnt++; | 214 | re->refcnt++; |
| 215 | spin_unlock(&fs_info->reada_lock); | 215 | spin_unlock(&fs_info->reada_lock); |
| @@ -240,7 +240,7 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical, · 24 unmodified lines | |||
| 240 | zone = NULL; | 240 | zone = NULL; |
| 241 | spin_lock(&fs_info->reada_lock); | 241 | spin_lock(&fs_info->reada_lock); |
| 242 | ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, | 242 | ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, |
| 243 | logical >> PAGE_SHIFT, 1); | 243 | logical >> fs_info->sectorsize_bits, 1); |
| 244 | if (ret == 1 && logical >= zone->start && logical <= zone->end) { | 244 | if (ret == 1 && logical >= zone->start && logical <= zone->end) { |
| 245 | kref_get(&zone->refcnt); | 245 | kref_get(&zone->refcnt); |
| 246 | spin_unlock(&fs_info->reada_lock); | 246 | spin_unlock(&fs_info->reada_lock); |
| @@ -283,13 +283,13 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical, · 36 unmodified lines | |||
| 283 | 283 | ||
| 284 | spin_lock(&fs_info->reada_lock); | 284 | spin_lock(&fs_info->reada_lock); |
| 285 | ret = radix_tree_insert(&dev->reada_zones, | 285 | ret = radix_tree_insert(&dev->reada_zones, |
| 286 | (unsigned long)(zone->end >> PAGE_SHIFT), | 286 | (unsigned long)(zone->end >> fs_info->sectorsize_bits), |
| 287 | zone); | 287 | zone); |
| 288 | 288 | ||
| 289 | if (ret == -EEXIST) { | 289 | if (ret == -EEXIST) { |
| 290 | kfree(zone); | 290 | kfree(zone); |
| 291 | ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, | 291 | ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, |
| 292 | logical >> PAGE_SHIFT, 1); | 292 | logical >> fs_info->sectorsize_bits, 1); |
| 293 | if (ret == 1 && logical >= zone->start && logical <= zone->end) | 293 | if (ret == 1 && logical >= zone->start && logical <= zone->end) |
| 294 | kref_get(&zone->refcnt); | 294 | kref_get(&zone->refcnt); |
| 295 | else | 295 | else |
| @@ -315,7 +315,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info, · 19 unmodified lines | |||
| 315 | u64 length; | 315 | u64 length; |
| 316 | int real_stripes; | 316 | int real_stripes; |
| 317 | int nzones = 0; | 317 | int nzones = 0; |
| 318 | unsigned long index = logical >> PAGE_SHIFT; | 318 | unsigned long index = logical >> fs_info->sectorsize_bits; |
| 319 | int dev_replace_is_ongoing; | 319 | int dev_replace_is_ongoing; |
| 320 | int have_zone = 0; | 320 | int have_zone = 0; |
| 321 | 321 | ||
| @@ -497,7 +497,7 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info, · 175 unmodified lines | |||
| 497 | struct reada_extent *re) | 497 | struct reada_extent *re) |
| 498 | { | 498 | { |
| 499 | int i; | 499 | int i; |
| 500 | unsigned long index = re->logical >> PAGE_SHIFT; | 500 | unsigned long index = re->logical >> fs_info->sectorsize_bits; |
| 501 | 501 | ||
| 502 | spin_lock(&fs_info->reada_lock); | 502 | spin_lock(&fs_info->reada_lock); |
| 503 | if (--re->refcnt) { | 503 | if (--re->refcnt) { |
| @@ -538,11 +538,12 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info, · 34 unmodified lines | |||
| 538 | static void reada_zone_release(struct kref *kref) | 538 | static void reada_zone_release(struct kref *kref) |
| 539 | { | 539 | { |
| 540 | struct reada_zone *zone = container_of(kref, struct reada_zone, refcnt); | 540 | struct reada_zone *zone = container_of(kref, struct reada_zone, refcnt); |
| 541 | struct btrfs_fs_info *fs_info = zone->device->fs_info; | ||
| 541 | 542 | ||
| 542 | lockdep_assert_held(&zone->device->fs_info->reada_lock); | 543 | lockdep_assert_held(&fs_info->reada_lock); |
| 543 | 544 | ||
| 544 | radix_tree_delete(&zone->device->reada_zones, | 545 | radix_tree_delete(&zone->device->reada_zones, |
| 545 | zone->end >> PAGE_SHIFT); | 546 | zone->end >> fs_info->sectorsize_bits); |
| 546 | 547 | ||
| 547 | kfree(zone); | 548 | kfree(zone); |
| 548 | } | 549 | } |
| @@ -593,7 +594,7 @@ static int reada_add_block(struct reada_control *rc, u64 logical, · 44 unmodified lines | |||
| 593 | static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock) | 594 | static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock) |
| 594 | { | 595 | { |
| 595 | int i; | 596 | int i; |
| 596 | unsigned long index = zone->end >> PAGE_SHIFT; | 597 | unsigned long index = zone->end >> zone->device->fs_info->sectorsize_bits; |
| 597 | 598 | ||
| 598 | for (i = 0; i < zone->ndevs; ++i) { | 599 | for (i = 0; i < zone->ndevs; ++i) { |
| 599 | struct reada_zone *peer; | 600 | struct reada_zone *peer; |
| @@ -628,7 +629,7 @@ static int reada_pick_zone(struct btrfs_device *dev) · 28 unmodified lines | |||
| 628 | (void **)&zone, index, 1); | 629 | (void **)&zone, index, 1); |
| 629 | if (ret == 0) | 630 | if (ret == 0) |
| 630 | break; | 631 | break; |
| 631 | index = (zone->end >> PAGE_SHIFT) + 1; | 632 | index = (zone->end >> dev->fs_info->sectorsize_bits) + 1; |
| 632 | if (zone->locked) { | 633 | if (zone->locked) { |
| 633 | if (zone->elems > top_locked_elems) { | 634 | if (zone->elems > top_locked_elems) { |
| 634 | top_locked_elems = zone->elems; | 635 | top_locked_elems = zone->elems; |
| @@ -709,7 +710,7 @@ static int reada_start_machine_dev(struct btrfs_device *dev) · 74 unmodified lines | |||
| 709 | * plugging to speed things up | 710 | * plugging to speed things up |
| 710 | */ | 711 | */ |
| 711 | ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re, | 712 | ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re, |
| 712 | dev->reada_next >> PAGE_SHIFT, 1); | 713 | dev->reada_next >> fs_info->sectorsize_bits, 1); |
| 713 | if (ret == 0 || re->logical > dev->reada_curr_zone->end) { | 714 | if (ret == 0 || re->logical > dev->reada_curr_zone->end) { |
| 714 | ret = reada_pick_zone(dev); | 715 | ret = reada_pick_zone(dev); |
| 715 | if (!ret) { | 716 | if (!ret) { |
| @@ -718,7 +719,7 @@ static int reada_start_machine_dev(struct btrfs_device *dev) · 2 unmodified lines | |||
| 718 | } | 719 | } |
| 719 | re = NULL; | 720 | re = NULL; |
| 720 | ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re, | 721 | ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re, |
| 721 | dev->reada_next >> PAGE_SHIFT, 1); | 722 | dev->reada_next >> fs_info->sectorsize_bits, 1); |
| 722 | } | 723 | } |
| 723 | if (ret == 0) { | 724 | if (ret == 0) { |
| 724 | spin_unlock(&fs_info->reada_lock); | 725 | spin_unlock(&fs_info->reada_lock); |
| @@ -885,7 +886,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all) · 160 unmodified lines | |||
| 885 | pr_cont(" curr off %llu", | 886 | pr_cont(" curr off %llu", |
| 886 | device->reada_next - zone->start); | 887 | device->reada_next - zone->start); |
| 887 | pr_cont("\n"); | 888 | pr_cont("\n"); |
| 888 | index = (zone->end >> PAGE_SHIFT) + 1; | 889 | index = (zone->end >> fs_info->sectorsize_bits) + 1; |
| 889 | } | 890 | } |
| 890 | cnt = 0; | 891 | cnt = 0; |
| 891 | index = 0; | 892 | index = 0; |
| @@ -910,7 +911,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all) · 18 unmodified lines | |||
| 910 | } | 911 | } |
| 911 | } | 912 | } |
| 912 | pr_cont("\n"); | 913 | pr_cont("\n"); |
| 913 | index = (re->logical >> PAGE_SHIFT) + 1; | 914 | index = (re->logical >> fs_info->sectorsize_bits) + 1; |
| 914 | if (++cnt > 15) | 915 | if (++cnt > 15) |
| 915 | break; | 916 | break; |
| 916 | } | 917 | } |
| @@ -926,7 +927,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all) · 9 unmodified lines | |||
| 926 | if (ret == 0) | 927 | if (ret == 0) |
| 927 | break; | 928 | break; |
| 928 | if (!re->scheduled) { | 929 | if (!re->scheduled) { |
| 929 | index = (re->logical >> PAGE_SHIFT) + 1; | 930 | index = (re->logical >> fs_info->sectorsize_bits) + 1; |
| 930 | continue; | 931 | continue; |
| 931 | } | 932 | } |
| 932 | pr_debug("re: logical %llu size %u list empty %d scheduled %d", | 933 | pr_debug("re: logical %llu size %u list empty %d scheduled %d", |
| @@ -942,7 +943,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all) · 9 unmodified lines | |||
| 942 | } | 943 | } |
| 943 | } | 944 | } |
| 944 | pr_cont("\n"); | 945 | pr_cont("\n"); |
| 945 | index = (re->logical >> PAGE_SHIFT) + 1; | 946 | index = (re->logical >> fs_info->sectorsize_bits) + 1; |
| 946 | } | 947 | } |
| 947 | spin_unlock(&fs_info->reada_lock); | 948 | spin_unlock(&fs_info->reada_lock); |
| 948 | } | 949 | } |
| @@ -1428,7 +1428,7 @@ static void scrub_recheck_block_on_raid56(struct btrfs_fs_info *fs_info, · 1427 unmodified lines | |||
| 1428 | if (!first_page->dev->bdev) | 1428 | if (!first_page->dev->bdev) |
| 1429 | goto out; | 1429 | goto out; |
| 1430 | 1430 | ||
| 1431 | bio = btrfs_io_bio_alloc(BIO_MAX_PAGES); | 1431 | bio = btrfs_io_bio_alloc(BIO_MAX_VECS); |
| 1432 | bio_set_dev(bio, first_page->dev->bdev); | 1432 | bio_set_dev(bio, first_page->dev->bdev); |
| 1433 | 1433 | ||
| 1434 | for (page_num = 0; page_num < sblock->page_count; page_num++) { | 1434 | for (page_num = 0; page_num < sblock->page_count; page_num++) { |
| @@ -3169,10 +3169,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, · 3168 unmodified lines | |||
| 3169 | 3169 | ||
| 3170 | mutex_lock(&log_root_tree->log_mutex); | 3170 | mutex_lock(&log_root_tree->log_mutex); |
| 3171 | 3171 | ||
| 3172 | index2 = log_root_tree->log_transid % 2; | ||
| 3173 | list_add_tail(&root_log_ctx.list, &log_root_tree->log_ctxs[index2]); | ||
| 3174 | root_log_ctx.log_transid = log_root_tree->log_transid; | ||
| 3175 | |||
| 3176 | if (btrfs_is_zoned(fs_info)) { | 3172 | if (btrfs_is_zoned(fs_info)) { |
| 3177 | if (!log_root_tree->node) { | 3173 | if (!log_root_tree->node) { |
| 3178 | ret = btrfs_alloc_log_tree_node(trans, log_root_tree); | 3174 | ret = btrfs_alloc_log_tree_node(trans, log_root_tree); |
| @@ -3183,6 +3179,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, · 4 unmodified lines | |||
| 3183 | } | 3179 | } |
| 3184 | } | 3180 | } |
| 3185 | 3181 | ||
| 3182 | index2 = log_root_tree->log_transid % 2; | ||
| 3183 | list_add_tail(&root_log_ctx.list, &log_root_tree->log_ctxs[index2]); | ||
| 3184 | root_log_ctx.log_transid = log_root_tree->log_transid; | ||
| 3185 | |||
| 3186 | /* | 3186 | /* |
| 3187 | * Now we are safe to update the log_root_tree because we're under the | 3187 | * Now we are safe to update the log_root_tree because we're under the |
| 3188 | * log_mutex, and we're a current writer so we're holding the commit | 3188 | * log_mutex, and we're a current writer so we're holding the commit |
| @@ -118,6 +118,12 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) · 117 unmodified lines | |||
| 118 | cache->mnt = path.mnt; | 118 | cache->mnt = path.mnt; |
| 119 | root = path.dentry; | 119 | root = path.dentry; |
| 120 | 120 | ||
| 121 | ret = -EINVAL; | ||
| 122 | if (mnt_user_ns(path.mnt) != &init_user_ns) { | ||
| 123 | pr_warn("File cache on idmapped mounts not supported"); | ||
| 124 | goto error_unsupported; | ||
| 125 | } | ||
| 126 | |||
| 121 | /* check parameters */ | 127 | /* check parameters */ |
| 122 | ret = -EOPNOTSUPP; | 128 | ret = -EOPNOTSUPP; |
| 123 | if (d_is_negative(root) || | 129 | if (d_is_negative(root) || |
| @@ -24,17 +24,16 @@ static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode, · 23 unmodified lines | |||
| 24 | container_of(wait, struct cachefiles_one_read, monitor); | 24 | container_of(wait, struct cachefiles_one_read, monitor); |
| 25 | struct cachefiles_object *object; | 25 | struct cachefiles_object *object; |
| 26 | struct fscache_retrieval *op = monitor->op; | 26 | struct fscache_retrieval *op = monitor->op; |
| 27 | struct wait_bit_key *key = _key; | 27 | struct wait_page_key *key = _key; |
| 28 | struct page *page = wait->private; | 28 | struct page *page = wait->private; |
| 29 | 29 | ||
| 30 | ASSERT(key); | 30 | ASSERT(key); |
| 31 | 31 | ||
| 32 | _enter("{%lu},%u,%d,{%p,%u}", | 32 | _enter("{%lu},%u,%d,{%p,%u}", |
| 33 | monitor->netfs_page->index, mode, sync, | 33 | monitor->netfs_page->index, mode, sync, |
| 34 | key->flags, key->bit_nr); | 34 | key->page, key->bit_nr); |
| 35 | 35 | ||
| 36 | if (key->flags != &page->flags || | 36 | if (key->page != page || key->bit_nr != PG_locked) |
| 37 | key->bit_nr != PG_locked) | ||
| 38 | return 0; | 37 | return 0; |
| 39 | 38 | ||
| 40 | _debug("--- monitor %p %lx ---", page, page->flags); | 39 | _debug("--- monitor %p %lx ---", page, page->flags); |
| @@ -207,7 +207,7 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v) · 206 unmodified lines | |||
| 207 | from_kuid(&init_user_ns, cfile->uid), | 207 | from_kuid(&init_user_ns, cfile->uid), |
| 208 | cfile->dentry); | 208 | cfile->dentry); |
| 209 | #ifdef CONFIG_CIFS_DEBUG2 | 209 | #ifdef CONFIG_CIFS_DEBUG2 |
| 210 | seq_printf(m, " 0x%llx\n", cfile->fid.mid); | 210 | seq_printf(m, " %llu\n", cfile->fid.mid); |
| 211 | #else | 211 | #else |
| 212 | seq_printf(m, "\n"); | 212 | seq_printf(m, "\n"); |
| 213 | #endif /* CIFS_DEBUG2 */ | 213 | #endif /* CIFS_DEBUG2 */ |
| @@ -248,7 +248,7 @@ nlmsg_fail: · 247 unmodified lines | |||
| 248 | 248 | ||
| 249 | /* | 249 | /* |
| 250 | * Try to find a matching registration for the tcon's server name and share name. | 250 | * Try to find a matching registration for the tcon's server name and share name. |
| 251 | * Calls to this funciton must be protected by cifs_swnreg_idr_mutex. | 251 | * Calls to this function must be protected by cifs_swnreg_idr_mutex. |
| 252 | * TODO Try to avoid memory allocations | 252 | * TODO Try to avoid memory allocations |
| 253 | */ | 253 | */ |
| 254 | static struct cifs_swn_reg *cifs_find_swn_reg(struct cifs_tcon *tcon) | 254 | static struct cifs_swn_reg *cifs_find_swn_reg(struct cifs_tcon *tcon) |
| @@ -1118,7 +1118,6 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, · 1117 unmodified lines | |||
| 1118 | /* Retain old ACEs which we can retain */ | 1118 | /* Retain old ACEs which we can retain */ |
| 1119 | for (i = 0; i < src_num_aces; ++i) { | 1119 | for (i = 0; i < src_num_aces; ++i) { |
| 1120 | pntace = (struct cifs_ace *) (acl_base + size); | 1120 | pntace = (struct cifs_ace *) (acl_base + size); |
| 1121 | pnntace = (struct cifs_ace *) (nacl_base + nsize); | ||
| 1122 | 1121 | ||
| 1123 | if (!new_aces_set && (pntace->flags & INHERITED_ACE)) { | 1122 | if (!new_aces_set && (pntace->flags & INHERITED_ACE)) { |
| 1124 | /* Place the new ACEs in between existing explicit and inherited */ | 1123 | /* Place the new ACEs in between existing explicit and inherited */ |
| @@ -1131,14 +1130,18 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, · 6 unmodified lines | |||
| 1131 | } | 1130 | } |
| 1132 | 1131 | ||
| 1133 | /* If it's any one of the ACE we're replacing, skip! */ | 1132 | /* If it's any one of the ACE we're replacing, skip! */ |
| 1134 | if ((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) || | 1133 | if (!mode_from_sid && |
| 1134 | ((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) || | ||
| 1135 | (compare_sids(&pntace->sid, pownersid) == 0) || | 1135 | (compare_sids(&pntace->sid, pownersid) == 0) || |
| 1136 | (compare_sids(&pntace->sid, pgrpsid) == 0) || | 1136 | (compare_sids(&pntace->sid, pgrpsid) == 0) || |
| 1137 | (compare_sids(&pntace->sid, &sid_everyone) == 0) || | 1137 | (compare_sids(&pntace->sid, &sid_everyone) == 0) || |
| 1138 | (compare_sids(&pntace->sid, &sid_authusers) == 0)) { | 1138 | (compare_sids(&pntace->sid, &sid_authusers) == 0))) { |
| 1139 | goto next_ace; | 1139 | goto next_ace; |
| 1140 | } | 1140 | } |
| 1141 | 1141 | ||
| 1142 | /* update the pointer to the next ACE to populate*/ | ||
| 1143 | pnntace = (struct cifs_ace *) (nacl_base + nsize); | ||
| 1144 | |||
| 1142 | nsize += cifs_copy_ace(pnntace, pntace, NULL); | 1145 | nsize += cifs_copy_ace(pnntace, pntace, NULL); |
| 1143 | num_aces++; | 1146 | num_aces++; |
| 1144 | 1147 | ||
| @@ -290,7 +290,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) · 289 unmodified lines | |||
| 290 | rc = server->ops->queryfs(xid, tcon, cifs_sb, buf); | 290 | rc = server->ops->queryfs(xid, tcon, cifs_sb, buf); |
| 291 | 291 | ||
| 292 | free_xid(xid); | 292 | free_xid(xid); |
| 293 | return 0; | 293 | return rc; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) | 296 | static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) |
| @@ -257,7 +257,7 @@ struct smb_version_operations { · 256 unmodified lines | |||
| 257 | /* verify the message */ | 257 | /* verify the message */ |
| 258 | int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); | 258 | int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); |
| 259 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); | 259 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); |
| 260 | int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); | 260 | int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *); |
| 261 | void (*downgrade_oplock)(struct TCP_Server_Info *server, | 261 | void (*downgrade_oplock)(struct TCP_Server_Info *server, |
| 262 | struct cifsInodeInfo *cinode, __u32 oplock, | 262 | struct cifsInodeInfo *cinode, __u32 oplock, |
| 263 | unsigned int epoch, bool *purge_cache); | 263 | unsigned int epoch, bool *purge_cache); |
| @@ -1705,16 +1705,17 @@ static inline bool is_retryable_error(int error) · 1441 unmodified lines | |||
| 1705 | #define CIFS_NO_RSP_BUF 0x040 /* no response buffer required */ | 1705 | #define CIFS_NO_RSP_BUF 0x040 /* no response buffer required */ |
| 1706 | 1706 | ||
| 1707 | /* Type of request operation */ | 1707 | /* Type of request operation */ |
| 1708 | #define CIFS_ECHO_OP 0x080 /* echo request */ | 1708 | #define CIFS_ECHO_OP 0x080 /* echo request */ |
| 1709 | #define CIFS_OBREAK_OP 0x0100 /* oplock break request */ | 1709 | #define CIFS_OBREAK_OP 0x0100 /* oplock break request */ |
| 1710 | #define CIFS_NEG_OP 0x0200 /* negotiate request */ | 1710 | #define CIFS_NEG_OP 0x0200 /* negotiate request */ |
| 1711 | #define CIFS_CP_CREATE_CLOSE_OP 0x0400 /* compound create+close request */ | ||
| 1711 | /* Lower bitmask values are reserved by others below. */ | 1712 | /* Lower bitmask values are reserved by others below. */ |
| 1712 | #define CIFS_SESS_OP 0x2000 /* session setup request */ | 1713 | #define CIFS_SESS_OP 0x2000 /* session setup request */ |
| 1713 | #define CIFS_OP_MASK 0x2380 /* mask request type */ | 1714 | #define CIFS_OP_MASK 0x2780 /* mask request type */ |
| 1714 | 1715 | ||
| 1715 | #define CIFS_HAS_CREDITS 0x0400 /* already has credits */ | 1716 | #define CIFS_HAS_CREDITS 0x0400 /* already has credits */ |
| 1716 | #define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sending */ | 1717 | #define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sending */ |
| 1717 | #define CIFS_NO_SRV_RSP 0x1000 /* there is no server response */ | 1718 | #define CIFS_NO_SRV_RSP 0x1000 /* there is no server response */ |
| 1718 | 1719 | ||
| 1719 | /* Security Flags: indicate type of session setup needed */ | 1720 | /* Security Flags: indicate type of session setup needed */ |
| 1720 | #define CIFSSEC_MAY_SIGN 0x00001 | 1721 | #define CIFSSEC_MAY_SIGN 0x00001 |
| @@ -741,7 +741,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) · 740 unmodified lines | |||
| 741 | spin_lock(&GlobalMid_Lock); | 741 | spin_lock(&GlobalMid_Lock); |
| 742 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { | 742 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { |
| 743 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 743 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
| 744 | cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid); | 744 | cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid); |
| 745 | kref_get(&mid_entry->refcount); | 745 | kref_get(&mid_entry->refcount); |
| 746 | mid_entry->mid_state = MID_SHUTDOWN; | 746 | mid_entry->mid_state = MID_SHUTDOWN; |
| 747 | list_move(&mid_entry->qhead, &dispose_list); | 747 | list_move(&mid_entry->qhead, &dispose_list); |
| @@ -752,7 +752,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) · 4 unmodified lines | |||
| 752 | /* now walk dispose list and issue callbacks */ | 752 | /* now walk dispose list and issue callbacks */ |
| 753 | list_for_each_safe(tmp, tmp2, &dispose_list) { | 753 | list_for_each_safe(tmp, tmp2, &dispose_list) { |
| 754 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 754 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
| 755 | cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid); | 755 | cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid); |
| 756 | list_del_init(&mid_entry->qhead); | 756 | list_del_init(&mid_entry->qhead); |
| 757 | mid_entry->callback(mid_entry); | 757 | mid_entry->callback(mid_entry); |
| 758 | cifs_mid_q_entry_release(mid_entry); | 758 | cifs_mid_q_entry_release(mid_entry); |
| @@ -1429,6 +1429,11 @@ smbd_connected: · 670 unmodified lines | |||
| 1429 | tcp_ses->min_offload = ctx->min_offload; | 1429 | tcp_ses->min_offload = ctx->min_offload; |
| 1430 | tcp_ses->tcpStatus = CifsNeedNegotiate; | 1430 | tcp_ses->tcpStatus = CifsNeedNegotiate; |
| 1431 | 1431 | ||
| 1432 | if ((ctx->max_credits < 20) || (ctx->max_credits > 60000)) | ||
| 1433 | tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; | ||
| 1434 | else | ||
| 1435 | tcp_ses->max_credits = ctx->max_credits; | ||
| 1436 | |||
| 1432 | tcp_ses->nr_targets = 1; | 1437 | tcp_ses->nr_targets = 1; |
| 1433 | tcp_ses->ignore_signature = ctx->ignore_signature; | 1438 | tcp_ses->ignore_signature = ctx->ignore_signature; |
| 1434 | /* thread spawned, put it on the list */ | 1439 | /* thread spawned, put it on the list */ |
| @@ -2832,11 +2837,6 @@ static int mount_get_conns(struct smb3_fs_context *ctx, struct cifs_sb_info *cif · 1397 unmodified lines | |||
| 2832 | 2837 | ||
| 2833 | *nserver = server; | 2838 | *nserver = server; |
| 2834 | 2839 | ||
| 2835 | if ((ctx->max_credits < 20) || (ctx->max_credits > 60000)) | ||
| 2836 | server->max_credits = SMB2_MAX_CREDITS_AVAILABLE; | ||
| 2837 | else | ||
| 2838 | server->max_credits = ctx->max_credits; | ||
| 2839 | |||
| 2840 | /* get a reference to a SMB session */ | 2840 | /* get a reference to a SMB session */ |
| 2841 | ses = cifs_get_smb_ses(server, ctx); | 2841 | ses = cifs_get_smb_ses(server, ctx); |
| 2842 | if (IS_ERR(ses)) { | 2842 | if (IS_ERR(ses)) { |
| @@ -1196,9 +1196,11 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, · 1195 unmodified lines | |||
| 1196 | pr_warn_once("Witness protocol support is experimental\n"); | 1196 | pr_warn_once("Witness protocol support is experimental\n"); |
| 1197 | break; | 1197 | break; |
| 1198 | case Opt_rootfs: | 1198 | case Opt_rootfs: |
| 1199 | #ifdef CONFIG_CIFS_ROOT | 1199 | #ifndef CONFIG_CIFS_ROOT |
| 1200 | ctx->rootfs = true; | 1200 | cifs_dbg(VFS, "rootfs support requires CONFIG_CIFS_ROOT config option\n"); |
| 1201 | goto cifs_parse_mount_err; | ||
| 1201 | #endif | 1202 | #endif |
| 1203 | ctx->rootfs = true; | ||
| 1202 | break; | 1204 | break; |
| 1203 | case Opt_posixpaths: | 1205 | case Opt_posixpaths: |
| 1204 | if (result.negated) | 1206 | if (result.negated) |
| @@ -2395,7 +2395,7 @@ int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path, · 2394 unmodified lines | |||
| 2395 | * We need to be sure that all dirty pages are written and the server | 2395 | * We need to be sure that all dirty pages are written and the server |
| 2396 | * has actual ctime, mtime and file length. | 2396 | * has actual ctime, mtime and file length. |
| 2397 | */ | 2397 | */ |
| 2398 | if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE)) && | 2398 | if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE | STATX_BLOCKS)) && |
| 2399 | !CIFS_CACHE_READ(CIFS_I(inode)) && | 2399 | !CIFS_CACHE_READ(CIFS_I(inode)) && |
| 2400 | inode->i_mapping && inode->i_mapping->nrpages != 0) { | 2400 | inode->i_mapping && inode->i_mapping->nrpages != 0) { |
| 2401 | rc = filemap_fdatawait(inode->i_mapping); | 2401 | rc = filemap_fdatawait(inode->i_mapping); |
| @@ -2585,6 +2585,14 @@ set_size_out: · 183 unmodified lines | |||
| 2585 | if (rc == 0) { | 2585 | if (rc == 0) { |
| 2586 | cifsInode->server_eof = attrs->ia_size; | 2586 | cifsInode->server_eof = attrs->ia_size; |
| 2587 | cifs_setsize(inode, attrs->ia_size); | 2587 | cifs_setsize(inode, attrs->ia_size); |
| 2588 | /* | ||
| 2589 | * i_blocks is not related to (i_size / i_blksize), but instead | ||
| 2590 | * 512 byte (2**9) size is required for calculating num blocks. | ||
| 2591 | * Until we can query the server for actual allocation size, | ||
| 2592 | * this is best estimate we have for blocks allocated for a file | ||
| 2593 | * Number of blocks must be rounded up so size 1 is not 0 blocks | ||
| 2594 | */ | ||
| 2595 | inode->i_blocks = (512 - 1 + attrs->ia_size) >> 9; | ||
| 2588 | 2596 | ||
| 2589 | /* | 2597 | /* |
| 2590 | * The man page of truncate says if the size changed, | 2598 | * The man page of truncate says if the size changed, |
| @@ -230,6 +230,7 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, · 229 unmodified lines | |||
| 230 | ctx.noautotune = ses->server->noautotune; | 230 | ctx.noautotune = ses->server->noautotune; |
| 231 | ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay; | 231 | ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay; |
| 232 | ctx.echo_interval = ses->server->echo_interval / HZ; | 232 | ctx.echo_interval = ses->server->echo_interval / HZ; |
| 233 | ctx.max_credits = ses->server->max_credits; | ||
| 233 | 234 | ||
| 234 | /* | 235 | /* |
| 235 | * This will be used for encoding/decoding user/domain/pw | 236 | * This will be used for encoding/decoding user/domain/pw |
| @@ -358,6 +358,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 357 unmodified lines | |||
| 358 | if (cfile) | 358 | if (cfile) |
| 359 | goto after_close; | 359 | goto after_close; |
| 360 | /* Close */ | 360 | /* Close */ |
| 361 | flags |= CIFS_CP_CREATE_CLOSE_OP; | ||
| 361 | rqst[num_rqst].rq_iov = &vars->close_iov[0]; | 362 | rqst[num_rqst].rq_iov = &vars->close_iov[0]; |
| 362 | rqst[num_rqst].rq_nvec = 1; | 363 | rqst[num_rqst].rq_nvec = 1; |
| 363 | rc = SMB2_close_init(tcon, server, | 364 | rc = SMB2_close_init(tcon, server, |
| @@ -767,7 +767,7 @@ smb2_cancelled_close_fid(struct work_struct *work) · 766 unmodified lines | |||
| 767 | int rc; | 767 | int rc; |
| 768 | 768 | ||
| 769 | if (cancelled->mid) | 769 | if (cancelled->mid) |
| 770 | cifs_tcon_dbg(VFS, "Close unmatched open for MID:%llx\n", | 770 | cifs_tcon_dbg(VFS, "Close unmatched open for MID:%llu\n", |
| 771 | cancelled->mid); | 771 | cancelled->mid); |
| 772 | else | 772 | else |
| 773 | cifs_tcon_dbg(VFS, "Close interrupted close\n"); | 773 | cifs_tcon_dbg(VFS, "Close interrupted close\n"); |
| @@ -844,14 +844,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, · 70 unmodified lines | |||
| 844 | } | 844 | } |
| 845 | 845 | ||
| 846 | int | 846 | int |
| 847 | smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) | 847 | smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server) |
| 848 | { | 848 | { |
| 849 | struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer; | 849 | struct smb2_sync_hdr *sync_hdr = mid->resp_buf; |
| 850 | struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; | 850 | struct smb2_create_rsp *rsp = mid->resp_buf; |
| 851 | struct cifs_tcon *tcon; | 851 | struct cifs_tcon *tcon; |
| 852 | int rc; | 852 | int rc; |
| 853 | 853 | ||
| 854 | if (sync_hdr->Command != SMB2_CREATE || | 854 | if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE || |
| 855 | sync_hdr->Status != STATUS_SUCCESS) | 855 | sync_hdr->Status != STATUS_SUCCESS) |
| 856 | return 0; | 856 | return 0; |
| 857 | 857 | ||
| @@ -1195,7 +1195,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, · 1194 unmodified lines | |||
| 1195 | struct TCP_Server_Info *server = cifs_pick_channel(ses); | 1195 | struct TCP_Server_Info *server = cifs_pick_channel(ses); |
| 1196 | __le16 *utf16_path = NULL; | 1196 | __le16 *utf16_path = NULL; |
| 1197 | int ea_name_len = strlen(ea_name); | 1197 | int ea_name_len = strlen(ea_name); |
| 1198 | int flags = 0; | 1198 | int flags = CIFS_CP_CREATE_CLOSE_OP; |
| 1199 | int len; | 1199 | int len; |
| 1200 | struct smb_rqst rqst[3]; | 1200 | struct smb_rqst rqst[3]; |
| 1201 | int resp_buftype[3]; | 1201 | int resp_buftype[3]; |
| @@ -1573,7 +1573,7 @@ smb2_ioctl_query_info(const unsigned int xid, · 371 unmodified lines | |||
| 1573 | struct smb_query_info qi; | 1573 | struct smb_query_info qi; |
| 1574 | struct smb_query_info __user *pqi; | 1574 | struct smb_query_info __user *pqi; |
| 1575 | int rc = 0; | 1575 | int rc = 0; |
| 1576 | int flags = 0; | 1576 | int flags = CIFS_CP_CREATE_CLOSE_OP; |
| 1577 | struct smb2_query_info_rsp *qi_rsp = NULL; | 1577 | struct smb2_query_info_rsp *qi_rsp = NULL; |
| 1578 | struct smb2_ioctl_rsp *io_rsp = NULL; | 1578 | struct smb2_ioctl_rsp *io_rsp = NULL; |
| 1579 | void *buffer = NULL; | 1579 | void *buffer = NULL; |
| @@ -2577,7 +2577,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, · 997 unmodified lines | |||
| 2577 | { | 2577 | { |
| 2578 | struct cifs_ses *ses = tcon->ses; | 2578 | struct cifs_ses *ses = tcon->ses; |
| 2579 | struct TCP_Server_Info *server = cifs_pick_channel(ses); | 2579 | struct TCP_Server_Info *server = cifs_pick_channel(ses); |
| 2580 | int flags = 0; | 2580 | int flags = CIFS_CP_CREATE_CLOSE_OP; |
| 2581 | struct smb_rqst rqst[3]; | 2581 | struct smb_rqst rqst[3]; |
| 2582 | int resp_buftype[3]; | 2582 | int resp_buftype[3]; |
| 2583 | struct kvec rsp_iov[3]; | 2583 | struct kvec rsp_iov[3]; |
| @@ -2975,7 +2975,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, · 391 unmodified lines | |||
| 2975 | unsigned int sub_offset; | 2975 | unsigned int sub_offset; |
| 2976 | unsigned int print_len; | 2976 | unsigned int print_len; |
| 2977 | unsigned int print_offset; | 2977 | unsigned int print_offset; |
| 2978 | int flags = 0; | 2978 | int flags = CIFS_CP_CREATE_CLOSE_OP; |
| 2979 | struct smb_rqst rqst[3]; | 2979 | struct smb_rqst rqst[3]; |
| 2980 | int resp_buftype[3]; | 2980 | int resp_buftype[3]; |
| 2981 | struct kvec rsp_iov[3]; | 2981 | struct kvec rsp_iov[3]; |
| @@ -3157,7 +3157,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, · 175 unmodified lines | |||
| 3157 | struct cifs_open_parms oparms; | 3157 | struct cifs_open_parms oparms; |
| 3158 | struct cifs_fid fid; | 3158 | struct cifs_fid fid; |
| 3159 | struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); | 3159 | struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); |
| 3160 | int flags = 0; | 3160 | int flags = CIFS_CP_CREATE_CLOSE_OP; |
| 3161 | struct smb_rqst rqst[3]; | 3161 | struct smb_rqst rqst[3]; |
| 3162 | int resp_buftype[3]; | 3162 | int resp_buftype[3]; |
| 3163 | struct kvec rsp_iov[3]; | 3163 | struct kvec rsp_iov[3]; |
| @@ -4041,8 +4041,7 @@ smb2_async_readv(struct cifs_readdata *rdata) · 4040 unmodified lines | |||
| 4041 | if (rdata->credits.value > 0) { | 4041 | if (rdata->credits.value > 0) { |
| 4042 | shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, | 4042 | shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, |
| 4043 | SMB2_MAX_BUFFER_SIZE)); | 4043 | SMB2_MAX_BUFFER_SIZE)); |
| 4044 | shdr->CreditRequest = | 4044 | shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); |
| 4045 | cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); | ||
| 4046 | 4045 | ||
| 4047 | rc = adjust_credits(server, &rdata->credits, rdata->bytes); | 4046 | rc = adjust_credits(server, &rdata->credits, rdata->bytes); |
| 4048 | if (rc) | 4047 | if (rc) |
| @@ -4348,8 +4347,7 @@ smb2_async_writev(struct cifs_writedata *wdata, · 299 unmodified lines | |||
| 4348 | if (wdata->credits.value > 0) { | 4347 | if (wdata->credits.value > 0) { |
| 4349 | shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, | 4348 | shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, |
| 4350 | SMB2_MAX_BUFFER_SIZE)); | 4349 | SMB2_MAX_BUFFER_SIZE)); |
| 4351 | shdr->CreditRequest = | 4350 | shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); |
| 4352 | cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); | ||
| 4353 | 4351 | ||
| 4354 | rc = adjust_credits(server, &wdata->credits, wdata->bytes); | 4352 | rc = adjust_credits(server, &wdata->credits, wdata->bytes); |
| 4355 | if (rc) | 4353 | if (rc) |
| @@ -246,8 +246,7 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, · 245 unmodified lines | |||
| 246 | extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon, | 246 | extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon, |
| 247 | __u64 persistent_fid, | 247 | __u64 persistent_fid, |
| 248 | __u64 volatile_fid); | 248 | __u64 volatile_fid); |
| 249 | extern int smb2_handle_cancelled_mid(char *buffer, | 249 | extern int smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server); |
| 250 | struct TCP_Server_Info *server); | ||
| 251 | void smb2_cancelled_close_fid(struct work_struct *work); | 250 | void smb2_cancelled_close_fid(struct work_struct *work); |
| 252 | extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, | 251 | extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, |
| 253 | u64 persistent_file_id, u64 volatile_file_id, | 252 | u64 persistent_file_id, u64 volatile_file_id, |
| @@ -101,7 +101,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) · 100 unmodified lines | |||
| 101 | if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && | 101 | if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && |
| 102 | midEntry->mid_state == MID_RESPONSE_RECEIVED && | 102 | midEntry->mid_state == MID_RESPONSE_RECEIVED && |
| 103 | server->ops->handle_cancelled_mid) | 103 | server->ops->handle_cancelled_mid) |
| 104 | server->ops->handle_cancelled_mid(midEntry->resp_buf, server); | 104 | server->ops->handle_cancelled_mid(midEntry, server); |
| 105 | 105 | ||
| 106 | midEntry->mid_state = MID_FREE; | 106 | midEntry->mid_state = MID_FREE; |
| 107 | atomic_dec(&midCount); | 107 | atomic_dec(&midCount); |
| @@ -1196,9 +1196,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 1088 unmodified lines | |||
| 1196 | /* | 1196 | /* |
| 1197 | * Compounding is never used during session establish. | 1197 | * Compounding is never used during session establish. |
| 1198 | */ | 1198 | */ |
| 1199 | if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) | 1199 | if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) { |
| 1200 | mutex_lock(&server->srv_mutex); | ||
| 1200 | smb311_update_preauth_hash(ses, rqst[0].rq_iov, | 1201 | smb311_update_preauth_hash(ses, rqst[0].rq_iov, |
| 1201 | rqst[0].rq_nvec); | 1202 | rqst[0].rq_nvec); |
| 1203 | mutex_unlock(&server->srv_mutex); | ||
| 1204 | } | ||
| 1202 | 1205 | ||
| 1203 | for (i = 0; i < num_rqst; i++) { | 1206 | for (i = 0; i < num_rqst; i++) { |
| 1204 | rc = wait_for_response(server, midQ[i]); | 1207 | rc = wait_for_response(server, midQ[i]); |
| @@ -1207,7 +1210,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 2 unmodified lines | |||
| 1207 | } | 1210 | } |
| 1208 | if (rc != 0) { | 1211 | if (rc != 0) { |
| 1209 | for (; i < num_rqst; i++) { | 1212 | for (; i < num_rqst; i++) { |
| 1210 | cifs_server_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", | 1213 | cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n", |
| 1211 | midQ[i]->mid, le16_to_cpu(midQ[i]->command)); | 1214 | midQ[i]->mid, le16_to_cpu(midQ[i]->command)); |
| 1212 | send_cancel(server, &rqst[i], midQ[i]); | 1215 | send_cancel(server, &rqst[i], midQ[i]); |
| 1213 | spin_lock(&GlobalMid_Lock); | 1216 | spin_lock(&GlobalMid_Lock); |
| @@ -1266,7 +1269,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 52 unmodified lines | |||
| 1266 | .iov_base = resp_iov[0].iov_base, | 1269 | .iov_base = resp_iov[0].iov_base, |
| 1267 | .iov_len = resp_iov[0].iov_len | 1270 | .iov_len = resp_iov[0].iov_len |
| 1268 | }; | 1271 | }; |
| 1272 | mutex_lock(&server->srv_mutex); | ||
| 1269 | smb311_update_preauth_hash(ses, &iov, 1); | 1273 | smb311_update_preauth_hash(ses, &iov, 1); |
| 1274 | mutex_unlock(&server->srv_mutex); | ||
| 1270 | } | 1275 | } |
| 1271 | 1276 | ||
| 1272 | out: | 1277 | out: |
| @@ -378,7 +378,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type · 377 unmodified lines | |||
| 378 | 378 | ||
| 379 | attr = to_attr(dentry); | 379 | attr = to_attr(dentry); |
| 380 | if (!attr) | 380 | if (!attr) |
| 381 | goto out_put_item; | 381 | goto out_free_buffer; |
| 382 | 382 | ||
| 383 | if (type & CONFIGFS_ITEM_BIN_ATTR) { | 383 | if (type & CONFIGFS_ITEM_BIN_ATTR) { |
| 384 | buffer->bin_attr = to_bin_attr(dentry); | 384 | buffer->bin_attr = to_bin_attr(dentry); |
| @@ -391,7 +391,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type · 6 unmodified lines | |||
| 391 | /* Grab the module reference for this attribute if we have one */ | 391 | /* Grab the module reference for this attribute if we have one */ |
| 392 | error = -ENODEV; | 392 | error = -ENODEV; |
| 393 | if (!try_module_get(buffer->owner)) | 393 | if (!try_module_get(buffer->owner)) |
| 394 | goto out_put_item; | 394 | goto out_free_buffer; |
| 395 | 395 | ||
| 396 | error = -EACCES; | 396 | error = -EACCES; |
| 397 | if (!buffer->item->ci_type) | 397 | if (!buffer->item->ci_type) |
| @@ -435,8 +435,6 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type · 37 unmodified lines | |||
| 435 | 435 | ||
| 436 | out_put_module: | 436 | out_put_module: |
| 437 | module_put(buffer->owner); | 437 | module_put(buffer->owner); |
| 438 | out_put_item: | ||
| 439 | config_item_put(buffer->item); | ||
| 440 | out_free_buffer: | 438 | out_free_buffer: |
| 441 | up_read(&frag->frag_sem); | 439 | up_read(&frag->frag_sem); |
| 442 | kfree(buffer); | 440 | kfree(buffer); |
| @@ -52,7 +52,7 @@ static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode, · 51 unmodified lines | |||
| 52 | int num_pages = 0; | 52 | int num_pages = 0; |
| 53 | 53 | ||
| 54 | /* This always succeeds since __GFP_DIRECT_RECLAIM is set. */ | 54 | /* This always succeeds since __GFP_DIRECT_RECLAIM is set. */ |
| 55 | bio = bio_alloc(GFP_NOFS, BIO_MAX_PAGES); | 55 | bio = bio_alloc(GFP_NOFS, BIO_MAX_VECS); |
| 56 | 56 | ||
| 57 | while (len) { | 57 | while (len) { |
| 58 | unsigned int blocks_this_page = min(len, blocks_per_page); | 58 | unsigned int blocks_this_page = min(len, blocks_per_page); |
| @@ -74,7 +74,7 @@ static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode, · 15 unmodified lines | |||
| 74 | len -= blocks_this_page; | 74 | len -= blocks_this_page; |
| 75 | lblk += blocks_this_page; | 75 | lblk += blocks_this_page; |
| 76 | pblk += blocks_this_page; | 76 | pblk += blocks_this_page; |
| 77 | if (num_pages == BIO_MAX_PAGES || !len || | 77 | if (num_pages == BIO_MAX_VECS || !len || |
| 78 | !fscrypt_mergeable_bio(bio, inode, lblk)) { | 78 | !fscrypt_mergeable_bio(bio, inode, lblk)) { |
| 79 | err = submit_bio_wait(bio); | 79 | err = submit_bio_wait(bio); |
| 80 | if (err) | 80 | if (err) |
| @@ -126,7 +126,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, · 45 unmodified lines | |||
| 126 | return fscrypt_zeroout_range_inline_crypt(inode, lblk, pblk, | 126 | return fscrypt_zeroout_range_inline_crypt(inode, lblk, pblk, |
| 127 | len); | 127 | len); |
| 128 | 128 | ||
| 129 | BUILD_BUG_ON(ARRAY_SIZE(pages) > BIO_MAX_PAGES); | 129 | BUILD_BUG_ON(ARRAY_SIZE(pages) > BIO_MAX_VECS); |
| 130 | nr_pages = min_t(unsigned int, ARRAY_SIZE(pages), | 130 | nr_pages = min_t(unsigned int, ARRAY_SIZE(pages), |
| 131 | (len + blocks_per_page - 1) >> blocks_per_page_bits); | 131 | (len + blocks_per_page - 1) >> blocks_per_page_bits); |
| 132 | 132 | ||
| @@ -129,6 +129,7 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio, · 128 unmodified lines | |||
| 129 | struct page *page, | 129 | struct page *page, |
| 130 | erofs_off_t *last_block, | 130 | erofs_off_t *last_block, |
| 131 | unsigned int nblocks, | 131 | unsigned int nblocks, |
| 132 | unsigned int *eblks, | ||
| 132 | bool ra) | 133 | bool ra) |
| 133 | { | 134 | { |
| 134 | struct inode *const inode = mapping->host; | 135 | struct inode *const inode = mapping->host; |
| @@ -145,8 +146,7 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio, · 10 unmodified lines | |||
| 145 | 146 | ||
| 146 | /* note that for readpage case, bio also equals to NULL */ | 147 | /* note that for readpage case, bio also equals to NULL */ |
| 147 | if (bio && | 148 | if (bio && |
| 148 | /* not continuous */ | 149 | (*last_block + 1 != current_block || !*eblks)) { |
| 149 | *last_block + 1 != current_block) { | ||
| 150 | submit_bio_retry: | 150 | submit_bio_retry: |
| 151 | submit_bio(bio); | 151 | submit_bio(bio); |
| 152 | bio = NULL; | 152 | bio = NULL; |
| @@ -216,7 +216,8 @@ submit_bio_retry: · 63 unmodified lines | |||
| 216 | if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) | 216 | if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) |
| 217 | nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE); | 217 | nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE); |
| 218 | 218 | ||
| 219 | bio = bio_alloc(GFP_NOIO, bio_max_segs(nblocks)); | 219 | *eblks = bio_max_segs(nblocks); |
| 220 | bio = bio_alloc(GFP_NOIO, *eblks); | ||
| 220 | 221 | ||
| 221 | bio->bi_end_io = erofs_readendio; | 222 | bio->bi_end_io = erofs_readendio; |
| 222 | bio_set_dev(bio, sb->s_bdev); | 223 | bio_set_dev(bio, sb->s_bdev); |
| @@ -229,16 +230,8 @@ submit_bio_retry: · 6 unmodified lines | |||
| 229 | /* out of the extent or bio is full */ | 230 | /* out of the extent or bio is full */ |
| 230 | if (err < PAGE_SIZE) | 231 | if (err < PAGE_SIZE) |
| 231 | goto submit_bio_retry; | 232 | goto submit_bio_retry; |
| 232 | 233 | --*eblks; | |
| 233 | *last_block = current_block; | 234 | *last_block = current_block; |
| 234 | |||
| 235 | /* shift in advance in case of it followed by too many gaps */ | ||
| 236 | if (bio->bi_iter.bi_size >= bio->bi_max_vecs * PAGE_SIZE) { | ||
| 237 | /* err should reassign to 0 after submitting */ | ||
| 238 | err = 0; | ||
| 239 | goto submit_bio_out; | ||
| 240 | } | ||
| 241 | |||
| 242 | return bio; | 235 | return bio; |
| 243 | 236 | ||
| 244 | err_out: | 237 | err_out: |
| @@ -252,7 +245,6 @@ has_updated: · 7 unmodified lines | |||
| 252 | 245 | ||
| 253 | /* if updated manually, continuous pages has a gap */ | 246 | /* if updated manually, continuous pages has a gap */ |
| 254 | if (bio) | 247 | if (bio) |
| 255 | submit_bio_out: | ||
| 256 | submit_bio(bio); | 248 | submit_bio(bio); |
| 257 | return err ? ERR_PTR(err) : NULL; | 249 | return err ? ERR_PTR(err) : NULL; |
| 258 | } | 250 | } |
| @@ -264,23 +256,26 @@ submit_bio_out: · 5 unmodified lines | |||
| 264 | static int erofs_raw_access_readpage(struct file *file, struct page *page) | 256 | static int erofs_raw_access_readpage(struct file *file, struct page *page) |
| 265 | { | 257 | { |
| 266 | erofs_off_t last_block; | 258 | erofs_off_t last_block; |
| 259 | unsigned int eblks; | ||
| 267 | struct bio *bio; | 260 | struct bio *bio; |
| 268 | 261 | ||
| 269 | trace_erofs_readpage(page, true); | 262 | trace_erofs_readpage(page, true); |
| 270 | 263 | ||
| 271 | bio = erofs_read_raw_page(NULL, page->mapping, | 264 | bio = erofs_read_raw_page(NULL, page->mapping, |
| 272 | page, &last_block, 1, false); | 265 | page, &last_block, 1, &eblks, false); |
| 273 | 266 | ||
| 274 | if (IS_ERR(bio)) | 267 | if (IS_ERR(bio)) |
| 275 | return PTR_ERR(bio); | 268 | return PTR_ERR(bio); |
| 276 | 269 | ||
| 277 | DBG_BUGON(bio); /* since we have only one bio -- must be NULL */ | 270 | if (bio) |
| 271 | submit_bio(bio); | ||
| 278 | return 0; | 272 | return 0; |
| 279 | } | 273 | } |
| 280 | 274 | ||
| 281 | static void erofs_raw_access_readahead(struct readahead_control *rac) | 275 | static void erofs_raw_access_readahead(struct readahead_control *rac) |
| 282 | { | 276 | { |
| 283 | erofs_off_t last_block; | 277 | erofs_off_t last_block; |
| 278 | unsigned int eblks; | ||
| 284 | struct bio *bio = NULL; | 279 | struct bio *bio = NULL; |
| 285 | struct page *page; | 280 | struct page *page; |
| 286 | 281 | ||
| @@ -291,7 +286,7 @@ static void erofs_raw_access_readahead(struct readahead_control *rac) · 4 unmodified lines | |||
| 291 | prefetchw(&page->flags); | 286 | prefetchw(&page->flags); |
| 292 | 287 | ||
| 293 | bio = erofs_read_raw_page(bio, rac->mapping, page, &last_block, | 288 | bio = erofs_read_raw_page(bio, rac->mapping, page, &last_block, |
| 294 | readahead_count(rac), true); | 289 | readahead_count(rac), &eblks, true); |
| 295 | 290 | ||
| 296 | /* all the page errors are ignored when readahead */ | 291 | /* all the page errors are ignored when readahead */ |
| 297 | if (IS_ERR(bio)) { | 292 | if (IS_ERR(bio)) { |
| @@ -305,7 +300,6 @@ static void erofs_raw_access_readahead(struct readahead_control *rac) · 7 unmodified lines | |||
| 305 | put_page(page); | 300 | put_page(page); |
| 306 | } | 301 | } |
| 307 | 302 | ||
| 308 | /* the rare case (end in gaps) */ | ||
| 309 | if (bio) | 303 | if (bio) |
| 310 | submit_bio(bio); | 304 | submit_bio(bio); |
| 311 | } | 305 | } |
| @@ -1235,7 +1235,7 @@ submit_bio_retry: · 1234 unmodified lines | |||
| 1235 | } | 1235 | } |
| 1236 | 1236 | ||
| 1237 | if (!bio) { | 1237 | if (!bio) { |
| 1238 | bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES); | 1238 | bio = bio_alloc(GFP_NOIO, BIO_MAX_VECS); |
| 1239 | 1239 | ||
| 1240 | bio->bi_end_io = z_erofs_decompressqueue_endio; | 1240 | bio->bi_end_io = z_erofs_decompressqueue_endio; |
| 1241 | bio_set_dev(bio, sb->s_bdev); | 1241 | bio_set_dev(bio, sb->s_bdev); |
| @@ -626,27 +626,41 @@ int ext4_claim_free_clusters(struct ext4_sb_info *sbi, · 625 unmodified lines | |||
| 626 | 626 | ||
| 627 | /** | 627 | /** |
| 628 | * ext4_should_retry_alloc() - check if a block allocation should be retried | 628 | * ext4_should_retry_alloc() - check if a block allocation should be retried |
| 629 | * @sb: super block | 629 | * @sb: superblock |
| 630 | * @retries: number of attemps has been made | 630 | * @retries: number of retry attempts made so far |
| 631 | * | 631 | * |
| 632 | * ext4_should_retry_alloc() is called when ENOSPC is returned, and if | 632 | * ext4_should_retry_alloc() is called when ENOSPC is returned while |
| 633 | * it is profitable to retry the operation, this function will wait | 633 | * attempting to allocate blocks. If there's an indication that a pending |
| 634 | * for the current or committing transaction to complete, and then | 634 | * journal transaction might free some space and allow another attempt to |
| 635 | * return TRUE. We will only retry once. | 635 | * succeed, this function will wait for the current or committing transaction |
| 636 | * to complete and then return TRUE. | ||
| 636 | */ | 637 | */ |
| 637 | int ext4_should_retry_alloc(struct super_block *sb, int *retries) | 638 | int ext4_should_retry_alloc(struct super_block *sb, int *retries) |
| 638 | { | 639 | { |
| 639 | if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) || | 640 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 640 | (*retries)++ > 1 || | 641 | |
| 641 | !EXT4_SB(sb)->s_journal) | 642 | if (!sbi->s_journal) |
| 642 | return 0; | 643 | return 0; |
| 643 | 644 | ||
| 644 | smp_mb(); | 645 | if (++(*retries) > 3) { |
| 645 | if (EXT4_SB(sb)->s_mb_free_pending == 0) | 646 | percpu_counter_inc(&sbi->s_sra_exceeded_retry_limit); |
| 646 | return 0; | 647 | return 0; |
| 648 | } | ||
| 647 | 649 | ||
| 650 | /* | ||
| 651 | * if there's no indication that blocks are about to be freed it's | ||
| 652 | * possible we just missed a transaction commit that did so | ||
| 653 | */ | ||
| 654 | smp_mb(); | ||
| 655 | if (sbi->s_mb_free_pending == 0) | ||
| 656 | return ext4_has_free_clusters(sbi, 1, 0); | ||
| 657 | |||
| 658 | /* | ||
| 659 | * it's possible we've just missed a transaction commit here, | ||
| 660 | * so ignore the returned status | ||
| 661 | */ | ||
| 648 | jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); | 662 | jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); |
| 649 | jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); | 663 | (void) jbd2_journal_force_commit_nested(sbi->s_journal); |
| 650 | return 1; | 664 | return 1; |
| 651 | } | 665 | } |
| 652 | 666 | ||
| @@ -1484,6 +1484,7 @@ struct ext4_sb_info { · 1483 unmodified lines | |||
| 1484 | struct percpu_counter s_freeinodes_counter; | 1484 | struct percpu_counter s_freeinodes_counter; |
| 1485 | struct percpu_counter s_dirs_counter; | 1485 | struct percpu_counter s_dirs_counter; |
| 1486 | struct percpu_counter s_dirtyclusters_counter; | 1486 | struct percpu_counter s_dirtyclusters_counter; |
| 1487 | struct percpu_counter s_sra_exceeded_retry_limit; | ||
| 1487 | struct blockgroup_lock *s_blockgroup_lock; | 1488 | struct blockgroup_lock *s_blockgroup_lock; |
| 1488 | struct proc_dir_entry *s_proc; | 1489 | struct proc_dir_entry *s_proc; |
| 1489 | struct kobject s_kobj; | 1490 | struct kobject s_kobj; |
| @@ -2793,6 +2794,8 @@ void __ext4_fc_track_link(handle_t *handle, struct inode *inode, · 1303 unmodified lines | |||
| 2793 | struct dentry *dentry); | 2794 | struct dentry *dentry); |
| 2794 | void ext4_fc_track_unlink(handle_t *handle, struct dentry *dentry); | 2795 | void ext4_fc_track_unlink(handle_t *handle, struct dentry *dentry); |
| 2795 | void ext4_fc_track_link(handle_t *handle, struct dentry *dentry); | 2796 | void ext4_fc_track_link(handle_t *handle, struct dentry *dentry); |
| 2797 | void __ext4_fc_track_create(handle_t *handle, struct inode *inode, | ||
| 2798 | struct dentry *dentry); | ||
| 2796 | void ext4_fc_track_create(handle_t *handle, struct dentry *dentry); | 2799 | void ext4_fc_track_create(handle_t *handle, struct dentry *dentry); |
| 2797 | void ext4_fc_track_inode(handle_t *handle, struct inode *inode); | 2800 | void ext4_fc_track_inode(handle_t *handle, struct inode *inode); |
| 2798 | void ext4_fc_mark_ineligible(struct super_block *sb, int reason); | 2801 | void ext4_fc_mark_ineligible(struct super_block *sb, int reason); |
| @@ -4382,7 +4382,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, · 4381 unmodified lines | |||
| 4382 | { | 4382 | { |
| 4383 | struct inode *inode = file_inode(file); | 4383 | struct inode *inode = file_inode(file); |
| 4384 | handle_t *handle; | 4384 | handle_t *handle; |
| 4385 | int ret, ret2 = 0, ret3 = 0; | 4385 | int ret = 0, ret2 = 0, ret3 = 0; |
| 4386 | int retries = 0; | 4386 | int retries = 0; |
| 4387 | int depth = 0; | 4387 | int depth = 0; |
| 4388 | struct ext4_map_blocks map; | 4388 | struct ext4_map_blocks map; |
| @@ -513,10 +513,10 @@ void ext4_fc_track_link(handle_t *handle, struct dentry *dentry) · 512 unmodified lines | |||
| 513 | __ext4_fc_track_link(handle, d_inode(dentry), dentry); | 513 | __ext4_fc_track_link(handle, d_inode(dentry), dentry); |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) | 516 | void __ext4_fc_track_create(handle_t *handle, struct inode *inode, |
| 517 | struct dentry *dentry) | ||
| 517 | { | 518 | { |
| 518 | struct __track_dentry_update_args args; | 519 | struct __track_dentry_update_args args; |
| 519 | struct inode *inode = d_inode(dentry); | ||
| 520 | int ret; | 520 | int ret; |
| 521 | 521 | ||
| 522 | args.dentry = dentry; | 522 | args.dentry = dentry; |
| @@ -527,6 +527,11 @@ void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) · 4 unmodified lines | |||
| 527 | trace_ext4_fc_track_create(inode, dentry, ret); | 527 | trace_ext4_fc_track_create(inode, dentry, ret); |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) | ||
| 531 | { | ||
| 532 | __ext4_fc_track_create(handle, d_inode(dentry), dentry); | ||
| 533 | } | ||
| 534 | |||
| 530 | /* __track_fn for inode tracking */ | 535 | /* __track_fn for inode tracking */ |
| 531 | static int __track_inode(struct inode *inode, void *arg, bool update) | 536 | static int __track_inode(struct inode *inode, void *arg, bool update) |
| 532 | { | 537 | { |
| @@ -1938,13 +1938,13 @@ static int __ext4_journalled_writepage(struct page *page, · 1937 unmodified lines | |||
| 1938 | if (!ret) | 1938 | if (!ret) |
| 1939 | ret = err; | 1939 | ret = err; |
| 1940 | 1940 | ||
| 1941 | if (!ext4_has_inline_data(inode)) | ||
| 1942 | ext4_walk_page_buffers(NULL, page_bufs, 0, len, | ||
| 1943 | NULL, bput_one); | ||
| 1944 | ext4_set_inode_state(inode, EXT4_STATE_JDATA); | 1941 | ext4_set_inode_state(inode, EXT4_STATE_JDATA); |
| 1945 | out: | 1942 | out: |
| 1946 | unlock_page(page); | 1943 | unlock_page(page); |
| 1947 | out_no_pagelock: | 1944 | out_no_pagelock: |
| 1945 | if (!inline_data && page_bufs) | ||
| 1946 | ext4_walk_page_buffers(NULL, page_bufs, 0, len, | ||
| 1947 | NULL, bput_one); | ||
| 1948 | brelse(inode_bh); | 1948 | brelse(inode_bh); |
| 1949 | return ret; | 1949 | return ret; |
| 1950 | } | 1950 | } |
| @@ -5026,7 +5026,7 @@ static int ext4_do_update_inode(handle_t *handle, · 3075 unmodified lines | |||
| 5026 | struct ext4_inode_info *ei = EXT4_I(inode); | 5026 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 5027 | struct buffer_head *bh = iloc->bh; | 5027 | struct buffer_head *bh = iloc->bh; |
| 5028 | struct super_block *sb = inode->i_sb; | 5028 | struct super_block *sb = inode->i_sb; |
| 5029 | int err = 0, rc, block; | 5029 | int err = 0, block; |
| 5030 | int need_datasync = 0, set_large_file = 0; | 5030 | int need_datasync = 0, set_large_file = 0; |
| 5031 | uid_t i_uid; | 5031 | uid_t i_uid; |
| 5032 | gid_t i_gid; | 5032 | gid_t i_gid; |
| @@ -5138,9 +5138,9 @@ static int ext4_do_update_inode(handle_t *handle, · 105 unmodified lines | |||
| 5138 | bh->b_data); | 5138 | bh->b_data); |
| 5139 | 5139 | ||
| 5140 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); | 5140 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
| 5141 | rc = ext4_handle_dirty_metadata(handle, NULL, bh); | 5141 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
| 5142 | if (!err) | 5142 | if (err) |
| 5143 | err = rc; | 5143 | goto out_brelse; |
| 5144 | ext4_clear_inode_state(inode, EXT4_STATE_NEW); | 5144 | ext4_clear_inode_state(inode, EXT4_STATE_NEW); |
| 5145 | if (set_large_file) { | 5145 | if (set_large_file) { |
| 5146 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access"); | 5146 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access"); |
| @@ -5387,8 +5387,10 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, · 240 unmodified lines | |||
| 5387 | inode->i_gid = attr->ia_gid; | 5387 | inode->i_gid = attr->ia_gid; |
| 5388 | error = ext4_mark_inode_dirty(handle, inode); | 5388 | error = ext4_mark_inode_dirty(handle, inode); |
| 5389 | ext4_journal_stop(handle); | 5389 | ext4_journal_stop(handle); |
| 5390 | if (unlikely(error)) | 5390 | if (unlikely(error)) { |
| 5391 | ext4_fc_stop_update(inode); | ||
| 5391 | return error; | 5392 | return error; |
| 5393 | } | ||
| 5392 | } | 5394 | } |
| 5393 | 5395 | ||
| 5394 | if (attr->ia_valid & ATTR_SIZE) { | 5396 | if (attr->ia_valid & ATTR_SIZE) { |
| @@ -2709,8 +2709,15 @@ static int ext4_mb_init_backend(struct super_block *sb) · 2708 unmodified lines | |||
| 2709 | } | 2709 | } |
| 2710 | 2710 | ||
| 2711 | if (ext4_has_feature_flex_bg(sb)) { | 2711 | if (ext4_has_feature_flex_bg(sb)) { |
| 2712 | /* a single flex group is supposed to be read by a single IO */ | 2712 | /* a single flex group is supposed to be read by a single IO. |
| 2713 | sbi->s_mb_prefetch = min(1 << sbi->s_es->s_log_groups_per_flex, | 2713 | * 2 ^ s_log_groups_per_flex != UINT_MAX as s_mb_prefetch is |
| 2714 | * unsigned integer, so the maximum shift is 32. | ||
| 2715 | */ | ||
| 2716 | if (sbi->s_es->s_log_groups_per_flex >= 32) { | ||
| 2717 | ext4_msg(sb, KERN_ERR, "too many log groups per flexible block group"); | ||
| 2718 | goto err_freesgi; | ||
| 2719 | } | ||
| 2720 | sbi->s_mb_prefetch = min_t(uint, 1 << sbi->s_es->s_log_groups_per_flex, | ||
| 2714 | BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9)); | 2721 | BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9)); |
| 2715 | sbi->s_mb_prefetch *= 8; /* 8 prefetch IOs in flight at most */ | 2722 | sbi->s_mb_prefetch *= 8; /* 8 prefetch IOs in flight at most */ |
| 2716 | } else { | 2723 | } else { |
| @@ -3613,6 +3613,31 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, · 3612 unmodified lines | |||
| 3613 | return retval; | 3613 | return retval; |
| 3614 | } | 3614 | } |
| 3615 | 3615 | ||
| 3616 | static void ext4_resetent(handle_t *handle, struct ext4_renament *ent, | ||
| 3617 | unsigned ino, unsigned file_type) | ||
| 3618 | { | ||
| 3619 | struct ext4_renament old = *ent; | ||
| 3620 | int retval = 0; | ||
| 3621 | |||
| 3622 | /* | ||
| 3623 | * old->de could have moved from under us during make indexed dir, | ||
| 3624 | * so the old->de may no longer valid and need to find it again | ||
| 3625 | * before reset old inode info. | ||
| 3626 | */ | ||
| 3627 | old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); | ||
| 3628 | if (IS_ERR(old.bh)) | ||
| 3629 | retval = PTR_ERR(old.bh); | ||
| 3630 | if (!old.bh) | ||
| 3631 | retval = -ENOENT; | ||
| 3632 | if (retval) { | ||
| 3633 | ext4_std_error(old.dir->i_sb, retval); | ||
| 3634 | return; | ||
| 3635 | } | ||
| 3636 | |||
| 3637 | ext4_setent(handle, &old, ino, file_type); | ||
| 3638 | brelse(old.bh); | ||
| 3639 | } | ||
| 3640 | |||
| 3616 | static int ext4_find_delete_entry(handle_t *handle, struct inode *dir, | 3641 | static int ext4_find_delete_entry(handle_t *handle, struct inode *dir, |
| 3617 | const struct qstr *d_name) | 3642 | const struct qstr *d_name) |
| 3618 | { | 3643 | { |
| @@ -3774,14 +3799,14 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 155 unmodified lines | |||
| 3774 | */ | 3799 | */ |
| 3775 | retval = -ENOENT; | 3800 | retval = -ENOENT; |
| 3776 | if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino) | 3801 | if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino) |
| 3777 | goto end_rename; | 3802 | goto release_bh; |
| 3778 | 3803 | ||
| 3779 | new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, | 3804 | new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, |
| 3780 | &new.de, &new.inlined); | 3805 | &new.de, &new.inlined); |
| 3781 | if (IS_ERR(new.bh)) { | 3806 | if (IS_ERR(new.bh)) { |
| 3782 | retval = PTR_ERR(new.bh); | 3807 | retval = PTR_ERR(new.bh); |
| 3783 | new.bh = NULL; | 3808 | new.bh = NULL; |
| 3784 | goto end_rename; | 3809 | goto release_bh; |
| 3785 | } | 3810 | } |
| 3786 | if (new.bh) { | 3811 | if (new.bh) { |
| 3787 | if (!new.inode) { | 3812 | if (!new.inode) { |
| @@ -3798,15 +3823,13 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 10 unmodified lines | |||
| 3798 | handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits); | 3823 | handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits); |
| 3799 | if (IS_ERR(handle)) { | 3824 | if (IS_ERR(handle)) { |
| 3800 | retval = PTR_ERR(handle); | 3825 | retval = PTR_ERR(handle); |
| 3801 | handle = NULL; | 3826 | goto release_bh; |
| 3802 | goto end_rename; | ||
| 3803 | } | 3827 | } |
| 3804 | } else { | 3828 | } else { |
| 3805 | whiteout = ext4_whiteout_for_rename(mnt_userns, &old, credits, &handle); | 3829 | whiteout = ext4_whiteout_for_rename(mnt_userns, &old, credits, &handle); |
| 3806 | if (IS_ERR(whiteout)) { | 3830 | if (IS_ERR(whiteout)) { |
| 3807 | retval = PTR_ERR(whiteout); | 3831 | retval = PTR_ERR(whiteout); |
| 3808 | whiteout = NULL; | 3832 | goto release_bh; |
| 3809 | goto end_rename; | ||
| 3810 | } | 3833 | } |
| 3811 | } | 3834 | } |
| 3812 | 3835 | ||
| @@ -3850,6 +3873,7 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 37 unmodified lines | |||
| 3850 | retval = ext4_mark_inode_dirty(handle, whiteout); | 3873 | retval = ext4_mark_inode_dirty(handle, whiteout); |
| 3851 | if (unlikely(retval)) | 3874 | if (unlikely(retval)) |
| 3852 | goto end_rename; | 3875 | goto end_rename; |
| 3876 | |||
| 3853 | } | 3877 | } |
| 3854 | if (!new.bh) { | 3878 | if (!new.bh) { |
| 3855 | retval = ext4_add_entry(handle, new.dentry, old.inode); | 3879 | retval = ext4_add_entry(handle, new.dentry, old.inode); |
| @@ -3923,6 +3947,8 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 67 unmodified lines | |||
| 3923 | ext4_fc_track_unlink(handle, new.dentry); | 3947 | ext4_fc_track_unlink(handle, new.dentry); |
| 3924 | __ext4_fc_track_link(handle, old.inode, new.dentry); | 3948 | __ext4_fc_track_link(handle, old.inode, new.dentry); |
| 3925 | __ext4_fc_track_unlink(handle, old.inode, old.dentry); | 3949 | __ext4_fc_track_unlink(handle, old.inode, old.dentry); |
| 3950 | if (whiteout) | ||
| 3951 | __ext4_fc_track_create(handle, whiteout, old.dentry); | ||
| 3926 | } | 3952 | } |
| 3927 | 3953 | ||
| 3928 | if (new.inode) { | 3954 | if (new.inode) { |
| @@ -3937,19 +3963,21 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 8 unmodified lines | |||
| 3937 | end_rename: | 3963 | end_rename: |
| 3938 | if (whiteout) { | 3964 | if (whiteout) { |
| 3939 | if (retval) { | 3965 | if (retval) { |
| 3940 | ext4_setent(handle, &old, | 3966 | ext4_resetent(handle, &old, |
| 3941 | old.inode->i_ino, old_file_type); | 3967 | old.inode->i_ino, old_file_type); |
| 3942 | drop_nlink(whiteout); | 3968 | drop_nlink(whiteout); |
| 3969 | ext4_orphan_add(handle, whiteout); | ||
| 3943 | } | 3970 | } |
| 3944 | unlock_new_inode(whiteout); | 3971 | unlock_new_inode(whiteout); |
| 3972 | ext4_journal_stop(handle); | ||
| 3945 | iput(whiteout); | 3973 | iput(whiteout); |
| 3946 | 3974 | } else { | |
| 3975 | ext4_journal_stop(handle); | ||
| 3947 | } | 3976 | } |
| 3977 | release_bh: | ||
| 3948 | brelse(old.dir_bh); | 3978 | brelse(old.dir_bh); |
| 3949 | brelse(old.bh); | 3979 | brelse(old.bh); |
| 3950 | brelse(new.bh); | 3980 | brelse(new.bh); |
| 3951 | if (handle) | ||
| 3952 | ext4_journal_stop(handle); | ||
| 3953 | return retval; | 3981 | return retval; |
| 3954 | } | 3982 | } |
| 3955 | 3983 | ||
| @@ -398,7 +398,7 @@ static void io_submit_init_bio(struct ext4_io_submit *io, · 397 unmodified lines | |||
| 398 | * bio_alloc will _always_ be able to allocate a bio if | 398 | * bio_alloc will _always_ be able to allocate a bio if |
| 399 | * __GFP_DIRECT_RECLAIM is set, see comments for bio_alloc_bioset(). | 399 | * __GFP_DIRECT_RECLAIM is set, see comments for bio_alloc_bioset(). |
| 400 | */ | 400 | */ |
| 401 | bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES); | 401 | bio = bio_alloc(GFP_NOIO, BIO_MAX_VECS); |
| 402 | fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO); | 402 | fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO); |
| 403 | bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); | 403 | bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); |
| 404 | bio_set_dev(bio, bh->b_bdev); | 404 | bio_set_dev(bio, bh->b_bdev); |
| @@ -1210,6 +1210,7 @@ static void ext4_put_super(struct super_block *sb) · 1209 unmodified lines | |||
| 1210 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 1210 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
| 1211 | percpu_counter_destroy(&sbi->s_dirs_counter); | 1211 | percpu_counter_destroy(&sbi->s_dirs_counter); |
| 1212 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); | 1212 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); |
| 1213 | percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit); | ||
| 1213 | percpu_free_rwsem(&sbi->s_writepages_rwsem); | 1214 | percpu_free_rwsem(&sbi->s_writepages_rwsem); |
| 1214 | #ifdef CONFIG_QUOTA | 1215 | #ifdef CONFIG_QUOTA |
| 1215 | for (i = 0; i < EXT4_MAXQUOTAS; i++) | 1216 | for (i = 0; i < EXT4_MAXQUOTAS; i++) |
| @@ -5011,6 +5012,9 @@ no_journal: · 3795 unmodified lines | |||
| 5011 | if (!err) | 5012 | if (!err) |
| 5012 | err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0, | 5013 | err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0, |
| 5013 | GFP_KERNEL); | 5014 | GFP_KERNEL); |
| 5015 | if (!err) | ||
| 5016 | err = percpu_counter_init(&sbi->s_sra_exceeded_retry_limit, 0, | ||
| 5017 | GFP_KERNEL); | ||
| 5014 | if (!err) | 5018 | if (!err) |
| 5015 | err = percpu_init_rwsem(&sbi->s_writepages_rwsem); | 5019 | err = percpu_init_rwsem(&sbi->s_writepages_rwsem); |
| 5016 | 5020 | ||
| @@ -5124,6 +5128,7 @@ failed_mount6: · 107 unmodified lines | |||
| 5124 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 5128 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
| 5125 | percpu_counter_destroy(&sbi->s_dirs_counter); | 5129 | percpu_counter_destroy(&sbi->s_dirs_counter); |
| 5126 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); | 5130 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); |
| 5131 | percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit); | ||
| 5127 | percpu_free_rwsem(&sbi->s_writepages_rwsem); | 5132 | percpu_free_rwsem(&sbi->s_writepages_rwsem); |
| 5128 | failed_mount5: | 5133 | failed_mount5: |
| 5129 | ext4_ext_release(sb); | 5134 | ext4_ext_release(sb); |
| @@ -5149,8 +5154,8 @@ failed_mount_wq: · 19 unmodified lines | |||
| 5149 | failed_mount3a: | 5154 | failed_mount3a: |
| 5150 | ext4_es_unregister_shrinker(sbi); | 5155 | ext4_es_unregister_shrinker(sbi); |
| 5151 | failed_mount3: | 5156 | failed_mount3: |
| 5152 | del_timer_sync(&sbi->s_err_report); | ||
| 5153 | flush_work(&sbi->s_error_work); | 5157 | flush_work(&sbi->s_error_work); |
| 5158 | del_timer_sync(&sbi->s_err_report); | ||
| 5154 | if (sbi->s_mmp_tsk) | 5159 | if (sbi->s_mmp_tsk) |
| 5155 | kthread_stop(sbi->s_mmp_tsk); | 5160 | kthread_stop(sbi->s_mmp_tsk); |
| 5156 | failed_mount2: | 5161 | failed_mount2: |
| @@ -24,6 +24,7 @@ typedef enum { · 23 unmodified lines | |||
| 24 | attr_session_write_kbytes, | 24 | attr_session_write_kbytes, |
| 25 | attr_lifetime_write_kbytes, | 25 | attr_lifetime_write_kbytes, |
| 26 | attr_reserved_clusters, | 26 | attr_reserved_clusters, |
| 27 | attr_sra_exceeded_retry_limit, | ||
| 27 | attr_inode_readahead, | 28 | attr_inode_readahead, |
| 28 | attr_trigger_test_error, | 29 | attr_trigger_test_error, |
| 29 | attr_first_error_time, | 30 | attr_first_error_time, |
| @@ -202,6 +203,7 @@ EXT4_ATTR_FUNC(delayed_allocation_blocks, 0444); · 172 unmodified lines | |||
| 202 | EXT4_ATTR_FUNC(session_write_kbytes, 0444); | 203 | EXT4_ATTR_FUNC(session_write_kbytes, 0444); |
| 203 | EXT4_ATTR_FUNC(lifetime_write_kbytes, 0444); | 204 | EXT4_ATTR_FUNC(lifetime_write_kbytes, 0444); |
| 204 | EXT4_ATTR_FUNC(reserved_clusters, 0644); | 205 | EXT4_ATTR_FUNC(reserved_clusters, 0644); |
| 206 | EXT4_ATTR_FUNC(sra_exceeded_retry_limit, 0444); | ||
| 205 | 207 | ||
| 206 | EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, | 208 | EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, |
| 207 | ext4_sb_info, s_inode_readahead_blks); | 209 | ext4_sb_info, s_inode_readahead_blks); |
| @@ -251,6 +253,7 @@ static struct attribute *ext4_attrs[] = { · 43 unmodified lines | |||
| 251 | ATTR_LIST(session_write_kbytes), | 253 | ATTR_LIST(session_write_kbytes), |
| 252 | ATTR_LIST(lifetime_write_kbytes), | 254 | ATTR_LIST(lifetime_write_kbytes), |
| 253 | ATTR_LIST(reserved_clusters), | 255 | ATTR_LIST(reserved_clusters), |
| 256 | ATTR_LIST(sra_exceeded_retry_limit), | ||
| 254 | ATTR_LIST(inode_readahead_blks), | 257 | ATTR_LIST(inode_readahead_blks), |
| 255 | ATTR_LIST(inode_goal), | 258 | ATTR_LIST(inode_goal), |
| 256 | ATTR_LIST(mb_stats), | 259 | ATTR_LIST(mb_stats), |
| @@ -374,6 +377,10 @@ static ssize_t ext4_attr_show(struct kobject *kobj, · 117 unmodified lines | |||
| 374 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 377 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
| 375 | (unsigned long long) | 378 | (unsigned long long) |
| 376 | atomic64_read(&sbi->s_resv_clusters)); | 379 | atomic64_read(&sbi->s_resv_clusters)); |
| 380 | case attr_sra_exceeded_retry_limit: | ||
| 381 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
| 382 | (unsigned long long) | ||
| 383 | percpu_counter_sum(&sbi->s_sra_exceeded_retry_limit)); | ||
| 377 | case attr_inode_readahead: | 384 | case attr_inode_readahead: |
| 378 | case attr_pointer_ui: | 385 | case attr_pointer_ui: |
| 379 | if (!ptr) | 386 | if (!ptr) |
| @@ -201,55 +201,76 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc, · 200 unmodified lines | |||
| 201 | struct inode *inode = file_inode(filp); | 201 | struct inode *inode = file_inode(filp); |
| 202 | const int credits = 2; /* superblock and inode for ext4_orphan_del() */ | 202 | const int credits = 2; /* superblock and inode for ext4_orphan_del() */ |
| 203 | handle_t *handle; | 203 | handle_t *handle; |
| 204 | struct ext4_iloc iloc; | ||
| 204 | int err = 0; | 205 | int err = 0; |
| 205 | int err2; | ||
| 206 | 206 | ||
| 207 | if (desc != NULL) { | 207 | /* |
| 208 | /* Succeeded; write the verity descriptor. */ | 208 | * If an error already occurred (which fs/verity/ signals by passing |
| 209 | err = ext4_write_verity_descriptor(inode, desc, desc_size, | 209 | * desc == NULL), then only clean-up is needed. |
| 210 | merkle_tree_size); | 210 | */ |
| 211 | 211 | if (desc == NULL) | |
| 212 | /* Write all pages before clearing VERITY_IN_PROGRESS. */ | 212 | goto cleanup; |
| 213 | if (!err) | ||
| 214 | err = filemap_write_and_wait(inode->i_mapping); | ||
| 215 | } | ||
| 216 | 213 | ||
| 217 | /* If we failed, truncate anything we wrote past i_size. */ | 214 | /* Append the verity descriptor. */ |
| 218 | if (desc == NULL || err) | 215 | err = ext4_write_verity_descriptor(inode, desc, desc_size, |
| 219 | ext4_truncate(inode); | 216 | merkle_tree_size); |
| 217 | if (err) | ||
| 218 | goto cleanup; | ||
| 220 | 219 | ||
| 221 | /* | 220 | /* |
| 222 | * We must always clean up by clearing EXT4_STATE_VERITY_IN_PROGRESS and | 221 | * Write all pages (both data and verity metadata). Note that this must |
| 223 | * deleting the inode from the orphan list, even if something failed. | 222 | * happen before clearing EXT4_STATE_VERITY_IN_PROGRESS; otherwise pages |
| 224 | * If everything succeeded, we'll also set the verity bit in the same | 223 | * beyond i_size won't be written properly. For crash consistency, this |
| 225 | * transaction. | 224 | * also must happen before the verity inode flag gets persisted. |
| 226 | */ | 225 | */ |
| 226 | err = filemap_write_and_wait(inode->i_mapping); | ||
| 227 | if (err) | ||
| 228 | goto cleanup; | ||
| 227 | 229 | ||
| 228 | ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); | 230 | /* |
| 231 | * Finally, set the verity inode flag and remove the inode from the | ||
| 232 | * orphan list (in a single transaction). | ||
| 233 | */ | ||
| 229 | 234 | ||
| 230 | handle = ext4_journal_start(inode, EXT4_HT_INODE, credits); | 235 | handle = ext4_journal_start(inode, EXT4_HT_INODE, credits); |
| 231 | if (IS_ERR(handle)) { | 236 | if (IS_ERR(handle)) { |
| 232 | ext4_orphan_del(NULL, inode); | 237 | err = PTR_ERR(handle); |
| 233 | return PTR_ERR(handle); | 238 | goto cleanup; |
| 234 | } | 239 | } |
| 235 | 240 | ||
| 236 | err2 = ext4_orphan_del(handle, inode); | 241 | err = ext4_orphan_del(handle, inode); |
| 237 | if (err2) | 242 | if (err) |
| 238 | goto out_stop; | 243 | goto stop_and_cleanup; |
| 239 | 244 | ||
| 240 | if (desc != NULL && !err) { | 245 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
| 241 | struct ext4_iloc iloc; | 246 | if (err) |
| 247 | goto stop_and_cleanup; | ||
| 242 | 248 | ||
| 243 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 249 | ext4_set_inode_flag(inode, EXT4_INODE_VERITY); |
| 244 | if (err) | 250 | ext4_set_inode_flags(inode, false); |
| 245 | goto out_stop; | 251 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
| 246 | ext4_set_inode_flag(inode, EXT4_INODE_VERITY); | 252 | if (err) |
| 247 | ext4_set_inode_flags(inode, false); | 253 | goto stop_and_cleanup; |
| 248 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 254 | |
| 249 | } | 255 | ext4_journal_stop(handle); |
| 250 | out_stop: | 256 | |
| 257 | ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); | ||
| 258 | return 0; | ||
| 259 | |||
| 260 | stop_and_cleanup: | ||
| 251 | ext4_journal_stop(handle); | 261 | ext4_journal_stop(handle); |
| 252 | return err ?: err2; | 262 | cleanup: |
| 263 | /* | ||
| 264 | * Verity failed to be enabled, so clean up by truncating any verity | ||
| 265 | * metadata that was written beyond i_size (both from cache and from | ||
| 266 | * disk), removing the inode from the orphan list (if it wasn't done | ||
| 267 | * already), and clearing EXT4_STATE_VERITY_IN_PROGRESS. | ||
| 268 | */ | ||
| 269 | truncate_inode_pages(inode->i_mapping, inode->i_size); | ||
| 270 | ext4_truncate(inode); | ||
| 271 | ext4_orphan_del(NULL, inode); | ||
| 272 | ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); | ||
| 273 | return err; | ||
| 253 | } | 274 | } |
| 254 | 275 | ||
| 255 | static int ext4_get_verity_descriptor_location(struct inode *inode, | 276 | static int ext4_get_verity_descriptor_location(struct inode *inode, |
| @@ -1462,6 +1462,9 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, · 1461 unmodified lines | |||
| 1462 | if (!ce) | 1462 | if (!ce) |
| 1463 | return NULL; | 1463 | return NULL; |
| 1464 | 1464 | ||
| 1465 | WARN_ON_ONCE(ext4_handle_valid(journal_current_handle()) && | ||
| 1466 | !(current->flags & PF_MEMALLOC_NOFS)); | ||
| 1467 | |||
| 1465 | ea_data = kvmalloc(value_len, GFP_KERNEL); | 1468 | ea_data = kvmalloc(value_len, GFP_KERNEL); |
| 1466 | if (!ea_data) { | 1469 | if (!ea_data) { |
| 1467 | mb_cache_entry_put(ea_inode_cache, ce); | 1470 | mb_cache_entry_put(ea_inode_cache, ce); |
| @@ -2327,6 +2330,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, · 859 unmodified lines | |||
| 2327 | error = -ENOSPC; | 2330 | error = -ENOSPC; |
| 2328 | goto cleanup; | 2331 | goto cleanup; |
| 2329 | } | 2332 | } |
| 2333 | WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS)); | ||
| 2330 | } | 2334 | } |
| 2331 | 2335 | ||
| 2332 | error = ext4_reserve_inode_write(handle, inode, &is.iloc); | 2336 | error = ext4_reserve_inode_write(handle, inode, &is.iloc); |
| @@ -2400,7 +2404,7 @@ retry_inode: · 67 unmodified lines | |||
| 2400 | * external inode if possible. | 2404 | * external inode if possible. |
| 2401 | */ | 2405 | */ |
| 2402 | if (ext4_has_feature_ea_inode(inode->i_sb) && | 2406 | if (ext4_has_feature_ea_inode(inode->i_sb) && |
| 2403 | !i.in_inode) { | 2407 | i.value_len && !i.in_inode) { |
| 2404 | i.in_inode = 1; | 2408 | i.in_inode = 1; |
| 2405 | goto retry_inode; | 2409 | goto retry_inode; |
| 2406 | } | 2410 | } |
| @@ -292,7 +292,7 @@ void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index) · 291 unmodified lines | |||
| 292 | f2fs_put_page(page, 0); | 292 | f2fs_put_page(page, 0); |
| 293 | 293 | ||
| 294 | if (readahead) | 294 | if (readahead) |
| 295 | f2fs_ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true); | 295 | f2fs_ra_meta_pages(sbi, index, BIO_MAX_VECS, META_POR, true); |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | static int __f2fs_write_meta_page(struct page *page, | 298 | static int __f2fs_write_meta_page(struct page *page, |
| @@ -857,7 +857,7 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio) · 856 unmodified lines | |||
| 857 | f2fs_submit_merged_ipu_write(fio->sbi, &bio, NULL); | 857 | f2fs_submit_merged_ipu_write(fio->sbi, &bio, NULL); |
| 858 | alloc_new: | 858 | alloc_new: |
| 859 | if (!bio) { | 859 | if (!bio) { |
| 860 | bio = __bio_alloc(fio, BIO_MAX_PAGES); | 860 | bio = __bio_alloc(fio, BIO_MAX_VECS); |
| 861 | __attach_io_flag(fio); | 861 | __attach_io_flag(fio); |
| 862 | f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host, | 862 | f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host, |
| 863 | fio->page->index, fio, GFP_NOIO); | 863 | fio->page->index, fio, GFP_NOIO); |
| @@ -932,7 +932,7 @@ alloc_new: · 68 unmodified lines | |||
| 932 | fio->retry = true; | 932 | fio->retry = true; |
| 933 | goto skip; | 933 | goto skip; |
| 934 | } | 934 | } |
| 935 | io->bio = __bio_alloc(fio, BIO_MAX_PAGES); | 935 | io->bio = __bio_alloc(fio, BIO_MAX_VECS); |
| 936 | f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host, | 936 | f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host, |
| 937 | bio_page->index, fio, GFP_NOIO); | 937 | bio_page->index, fio, GFP_NOIO); |
| 938 | io->fio = *fio; | 938 | io->fio = *fio; |
| @@ -4381,7 +4381,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) · 4380 unmodified lines | |||
| 4381 | block_t total_node_blocks = 0; | 4381 | block_t total_node_blocks = 0; |
| 4382 | 4382 | ||
| 4383 | do { | 4383 | do { |
| 4384 | readed = f2fs_ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES, | 4384 | readed = f2fs_ra_meta_pages(sbi, start_blk, BIO_MAX_VECS, |
| 4385 | META_SIT, true); | 4385 | META_SIT, true); |
| 4386 | 4386 | ||
| 4387 | start = start_blk * sit_i->sents_per_block; | 4387 | start = start_blk * sit_i->sents_per_block; |
| @@ -851,7 +851,7 @@ static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type) · 850 unmodified lines | |||
| 851 | else if (type == NODE) | 851 | else if (type == NODE) |
| 852 | return 8 * sbi->blocks_per_seg; | 852 | return 8 * sbi->blocks_per_seg; |
| 853 | else if (type == META) | 853 | else if (type == META) |
| 854 | return 8 * BIO_MAX_PAGES; | 854 | return 8 * BIO_MAX_VECS; |
| 855 | else | 855 | else |
| 856 | return 0; | 856 | return 0; |
| 857 | } | 857 | } |
| @@ -868,7 +868,7 @@ static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type, · 10 unmodified lines | |||
| 868 | return 0; | 868 | return 0; |
| 869 | 869 | ||
| 870 | nr_to_write = wbc->nr_to_write; | 870 | nr_to_write = wbc->nr_to_write; |
| 871 | desired = BIO_MAX_PAGES; | 871 | desired = BIO_MAX_VECS; |
| 872 | if (type == NODE) | 872 | if (type == NODE) |
| 873 | desired <<= 1; | 873 | desired <<= 1; |
| 874 | 874 | ||
| @@ -753,9 +753,9 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) · 752 unmodified lines | |||
| 753 | case Opt_io_size_bits: | 753 | case Opt_io_size_bits: |
| 754 | if (args->from && match_int(args, &arg)) | 754 | if (args->from && match_int(args, &arg)) |
| 755 | return -EINVAL; | 755 | return -EINVAL; |
| 756 | if (arg <= 0 || arg > __ilog2_u32(BIO_MAX_PAGES)) { | 756 | if (arg <= 0 || arg > __ilog2_u32(BIO_MAX_VECS)) { |
| 757 | f2fs_warn(sbi, "Not support %d, larger than %d", | 757 | f2fs_warn(sbi, "Not support %d, larger than %d", |
| 758 | 1 << arg, BIO_MAX_PAGES); | 758 | 1 << arg, BIO_MAX_VECS); |
| 759 | return -EINVAL; | 759 | return -EINVAL; |
| 760 | } | 760 | } |
| 761 | F2FS_OPTION(sbi).write_io_size_bits = arg; | 761 | F2FS_OPTION(sbi).write_io_size_bits = arg; |
| @@ -2229,19 +2229,21 @@ static int fuse_device_clone(struct fuse_conn *fc, struct file *new) · 2228 unmodified lines | |||
| 2229 | static long fuse_dev_ioctl(struct file *file, unsigned int cmd, | 2229 | static long fuse_dev_ioctl(struct file *file, unsigned int cmd, |
| 2230 | unsigned long arg) | 2230 | unsigned long arg) |
| 2231 | { | 2231 | { |
| 2232 | int err = -ENOTTY; | 2232 | int res; |
| 2233 | int oldfd; | ||
| 2234 | struct fuse_dev *fud = NULL; | ||
| 2233 | 2235 | ||
| 2234 | if (cmd == FUSE_DEV_IOC_CLONE) { | 2236 | if (_IOC_TYPE(cmd) != FUSE_DEV_IOC_MAGIC) |
| 2235 | int oldfd; | 2237 | return -ENOTTY; |
| 2236 | 2238 | ||
| 2237 | err = -EFAULT; | 2239 | switch (_IOC_NR(cmd)) { |
| 2238 | if (!get_user(oldfd, (__u32 __user *) arg)) { | 2240 | case _IOC_NR(FUSE_DEV_IOC_CLONE): |
| 2241 | res = -EFAULT; | ||
| 2242 | if (!get_user(oldfd, (__u32 __user *)arg)) { | ||
| 2239 | struct file *old = fget(oldfd); | 2243 | struct file *old = fget(oldfd); |
| 2240 | 2244 | ||
| 2241 | err = -EINVAL; | 2245 | res = -EINVAL; |
| 2242 | if (old) { | 2246 | if (old) { |
| 2243 | struct fuse_dev *fud = NULL; | ||
| 2244 | |||
| 2245 | /* | 2247 | /* |
| 2246 | * Check against file->f_op because CUSE | 2248 | * Check against file->f_op because CUSE |
| 2247 | * uses the same ioctl handler. | 2249 | * uses the same ioctl handler. |
| @@ -2252,14 +2254,18 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd, · 4 unmodified lines | |||
| 2252 | 2254 | ||
| 2253 | if (fud) { | 2255 | if (fud) { |
| 2254 | mutex_lock(&fuse_mutex); | 2256 | mutex_lock(&fuse_mutex); |
| 2255 | err = fuse_device_clone(fud->fc, file); | 2257 | res = fuse_device_clone(fud->fc, file); |
| 2256 | mutex_unlock(&fuse_mutex); | 2258 | mutex_unlock(&fuse_mutex); |
| 2257 | } | 2259 | } |
| 2258 | fput(old); | 2260 | fput(old); |
| 2259 | } | 2261 | } |
| 2260 | } | 2262 | } |
| 2263 | break; | ||
| 2264 | default: | ||
| 2265 | res = -ENOTTY; | ||
| 2266 | break; | ||
| 2261 | } | 2267 | } |
| 2262 | return err; | 2268 | return res; |
| 2263 | } | 2269 | } |
| 2264 | 2270 | ||
| 2265 | const struct file_operations fuse_dev_operations = { | 2271 | const struct file_operations fuse_dev_operations = { |
| @@ -863,6 +863,7 @@ static inline u64 fuse_get_attr_version(struct fuse_conn *fc) · 862 unmodified lines | |||
| 863 | 863 | ||
| 864 | static inline void fuse_make_bad(struct inode *inode) | 864 | static inline void fuse_make_bad(struct inode *inode) |
| 865 | { | 865 | { |
| 866 | remove_inode_hash(inode); | ||
| 866 | set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state); | 867 | set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state); |
| 867 | } | 868 | } |
| 868 | 869 | ||
| @@ -1324,8 +1324,15 @@ static int virtio_fs_fill_super(struct super_block *sb, struct fs_context *fsc) · 1323 unmodified lines | |||
| 1324 | 1324 | ||
| 1325 | /* virtiofs allocates and installs its own fuse devices */ | 1325 | /* virtiofs allocates and installs its own fuse devices */ |
| 1326 | ctx->fudptr = NULL; | 1326 | ctx->fudptr = NULL; |
| 1327 | if (ctx->dax) | 1327 | if (ctx->dax) { |
| 1328 | if (!fs->dax_dev) { | ||
| 1329 | err = -EINVAL; | ||
| 1330 | pr_err("virtio-fs: dax can't be enabled as filesystem" | ||
| 1331 | " device does not support it.\n"); | ||
| 1332 | goto err_free_fuse_devs; | ||
| 1333 | } | ||
| 1328 | ctx->dax_dev = fs->dax_dev; | 1334 | ctx->dax_dev = fs->dax_dev; |
| 1335 | } | ||
| 1329 | err = fuse_fill_super_common(sb, ctx); | 1336 | err = fuse_fill_super_common(sb, ctx); |
| 1330 | if (err < 0) | 1337 | if (err < 0) |
| 1331 | goto err_free_fuse_devs; | 1338 | goto err_free_fuse_devs; |
| @@ -998,12 +998,16 @@ static void trans_drain(struct gfs2_trans *tr) · 997 unmodified lines | |||
| 998 | while (!list_empty(head)) { | 998 | while (!list_empty(head)) { |
| 999 | bd = list_first_entry(head, struct gfs2_bufdata, bd_list); | 999 | bd = list_first_entry(head, struct gfs2_bufdata, bd_list); |
| 1000 | list_del_init(&bd->bd_list); | 1000 | list_del_init(&bd->bd_list); |
| 1001 | if (!list_empty(&bd->bd_ail_st_list)) | ||
| 1002 | gfs2_remove_from_ail(bd); | ||
| 1001 | kmem_cache_free(gfs2_bufdata_cachep, bd); | 1003 | kmem_cache_free(gfs2_bufdata_cachep, bd); |
| 1002 | } | 1004 | } |
| 1003 | head = &tr->tr_databuf; | 1005 | head = &tr->tr_databuf; |
| 1004 | while (!list_empty(head)) { | 1006 | while (!list_empty(head)) { |
| 1005 | bd = list_first_entry(head, struct gfs2_bufdata, bd_list); | 1007 | bd = list_first_entry(head, struct gfs2_bufdata, bd_list); |
| 1006 | list_del_init(&bd->bd_list); | 1008 | list_del_init(&bd->bd_list); |
| 1009 | if (!list_empty(&bd->bd_ail_st_list)) | ||
| 1010 | gfs2_remove_from_ail(bd); | ||
| 1007 | kmem_cache_free(gfs2_bufdata_cachep, bd); | 1011 | kmem_cache_free(gfs2_bufdata_cachep, bd); |
| 1008 | } | 1012 | } |
| 1009 | } | 1013 | } |
| @@ -1032,7 +1036,7 @@ repeat: · 22 unmodified lines | |||
| 1032 | * Do this check while holding the log_flush_lock to prevent new | 1036 | * Do this check while holding the log_flush_lock to prevent new |
| 1033 | * buffers from being added to the ail via gfs2_pin() | 1037 | * buffers from being added to the ail via gfs2_pin() |
| 1034 | */ | 1038 | */ |
| 1035 | if (gfs2_withdrawn(sdp)) | 1039 | if (gfs2_withdrawn(sdp) || !test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) |
| 1036 | goto out; | 1040 | goto out; |
| 1037 | 1041 | ||
| 1038 | /* Log might have been flushed while we waited for the flush lock */ | 1042 | /* Log might have been flushed while we waited for the flush lock */ |
| @@ -267,7 +267,7 @@ static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno, · 266 unmodified lines | |||
| 267 | bio_end_io_t *end_io) | 267 | bio_end_io_t *end_io) |
| 268 | { | 268 | { |
| 269 | struct super_block *sb = sdp->sd_vfs; | 269 | struct super_block *sb = sdp->sd_vfs; |
| 270 | struct bio *bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES); | 270 | struct bio *bio = bio_alloc(GFP_NOIO, BIO_MAX_VECS); |
| 271 | 271 | ||
| 272 | bio->bi_iter.bi_sector = blkno << sdp->sd_fsb2bb_shift; | 272 | bio->bi_iter.bi_sector = blkno << sdp->sd_fsb2bb_shift; |
| 273 | bio_set_dev(bio, sb->s_bdev); | 273 | bio_set_dev(bio, sb->s_bdev); |
| @@ -1539,9 +1539,7 @@ static int gfs2_reconfigure(struct fs_context *fc) · 1538 unmodified lines | |||
| 1539 | return -EINVAL; | 1539 | return -EINVAL; |
| 1540 | 1540 | ||
| 1541 | if (fc->sb_flags & SB_RDONLY) { | 1541 | if (fc->sb_flags & SB_RDONLY) { |
| 1542 | error = gfs2_make_fs_ro(sdp); | 1542 | gfs2_make_fs_ro(sdp); |
| 1543 | if (error) | ||
| 1544 | errorfc(fc, "unable to remount read-only"); | ||
| 1545 | } else { | 1543 | } else { |
| 1546 | error = gfs2_make_fs_rw(sdp); | 1544 | error = gfs2_make_fs_rw(sdp); |
| 1547 | if (error) | 1545 | if (error) |
| @@ -587,9 +587,8 @@ out: · 586 unmodified lines | |||
| 587 | * Returns: errno | 587 | * Returns: errno |
| 588 | */ | 588 | */ |
| 589 | 589 | ||
| 590 | int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | 590 | void gfs2_make_fs_ro(struct gfs2_sbd *sdp) |
| 591 | { | 591 | { |
| 592 | int error = 0; | ||
| 593 | int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | 592 | int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); |
| 594 | 593 | ||
| 595 | gfs2_flush_delete_work(sdp); | 594 | gfs2_flush_delete_work(sdp); |
| @@ -624,8 +623,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) · 28 unmodified lines | |||
| 624 | 623 | ||
| 625 | if (!log_write_allowed) | 624 | if (!log_write_allowed) |
| 626 | sdp->sd_vfs->s_flags |= SB_RDONLY; | 625 | sdp->sd_vfs->s_flags |= SB_RDONLY; |
| 627 | |||
| 628 | return error; | ||
| 629 | } | 626 | } |
| 630 | 627 | ||
| 631 | /** | 628 | /** |
| @@ -637,7 +634,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) · 5 unmodified lines | |||
| 637 | static void gfs2_put_super(struct super_block *sb) | 634 | static void gfs2_put_super(struct super_block *sb) |
| 638 | { | 635 | { |
| 639 | struct gfs2_sbd *sdp = sb->s_fs_info; | 636 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 640 | int error; | ||
| 641 | struct gfs2_jdesc *jd; | 637 | struct gfs2_jdesc *jd; |
| 642 | 638 | ||
| 643 | /* No more recovery requests */ | 639 | /* No more recovery requests */ |
| @@ -658,9 +654,7 @@ restart: · 14 unmodified lines | |||
| 658 | spin_unlock(&sdp->sd_jindex_spin); | 654 | spin_unlock(&sdp->sd_jindex_spin); |
| 659 | 655 | ||
| 660 | if (!sb_rdonly(sb)) { | 656 | if (!sb_rdonly(sb)) { |
| 661 | error = gfs2_make_fs_ro(sdp); | 657 | gfs2_make_fs_ro(sdp); |
| 662 | if (error) | ||
| 663 | gfs2_io_error(sdp); | ||
| 664 | } | 658 | } |
| 665 | WARN_ON(gfs2_withdrawing(sdp)); | 659 | WARN_ON(gfs2_withdrawing(sdp)); |
| 666 | 660 | ||
| @@ -34,7 +34,7 @@ extern int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, · 33 unmodified lines | |||
| 34 | struct gfs2_inode **ipp); | 34 | struct gfs2_inode **ipp); |
| 35 | 35 | ||
| 36 | extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp); | 36 | extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp); |
| 37 | extern int gfs2_make_fs_ro(struct gfs2_sbd *sdp); | 37 | extern void gfs2_make_fs_ro(struct gfs2_sbd *sdp); |
| 38 | extern void gfs2_online_uevent(struct gfs2_sbd *sdp); | 38 | extern void gfs2_online_uevent(struct gfs2_sbd *sdp); |
| 39 | extern int gfs2_statfs_init(struct gfs2_sbd *sdp); | 39 | extern int gfs2_statfs_init(struct gfs2_sbd *sdp); |
| 40 | extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | 40 | extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, |
| @@ -169,6 +169,8 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl, · 168 unmodified lines | |||
| 169 | bd->bd_bh = bh; | 169 | bd->bd_bh = bh; |
| 170 | bd->bd_gl = gl; | 170 | bd->bd_gl = gl; |
| 171 | INIT_LIST_HEAD(&bd->bd_list); | 171 | INIT_LIST_HEAD(&bd->bd_list); |
| 172 | INIT_LIST_HEAD(&bd->bd_ail_st_list); | ||
| 173 | INIT_LIST_HEAD(&bd->bd_ail_gl_list); | ||
| 172 | bh->b_private = bd; | 174 | bh->b_private = bd; |
| 173 | return bd; | 175 | return bd; |
| 174 | } | 176 | } |
| @@ -119,17 +119,22 @@ void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh) · 118 unmodified lines | |||
| 119 | static void signal_our_withdraw(struct gfs2_sbd *sdp) | 119 | static void signal_our_withdraw(struct gfs2_sbd *sdp) |
| 120 | { | 120 | { |
| 121 | struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl; | 121 | struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl; |
| 122 | struct inode *inode = sdp->sd_jdesc->jd_inode; | 122 | struct inode *inode; |
| 123 | struct gfs2_inode *ip = GFS2_I(inode); | 123 | struct gfs2_inode *ip; |
| 124 | struct gfs2_glock *i_gl = ip->i_gl; | 124 | struct gfs2_glock *i_gl; |
| 125 | u64 no_formal_ino = ip->i_no_formal_ino; | 125 | u64 no_formal_ino; |
| 126 | int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | 126 | int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); |
| 127 | int ret = 0; | 127 | int ret = 0; |
| 128 | int tries; | 128 | int tries; |
| 129 | 129 | ||
| 130 | if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) | 130 | if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc) |
| 131 | return; | 131 | return; |
| 132 | 132 | ||
| 133 | inode = sdp->sd_jdesc->jd_inode; | ||
| 134 | ip = GFS2_I(inode); | ||
| 135 | i_gl = ip->i_gl; | ||
| 136 | no_formal_ino = ip->i_no_formal_ino; | ||
| 137 | |||
| 133 | /* Prevent any glock dq until withdraw recovery is complete */ | 138 | /* Prevent any glock dq until withdraw recovery is complete */ |
| 134 | set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); | 139 | set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); |
| 135 | /* | 140 | /* |
| @@ -156,7 +161,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) · 20 unmodified lines | |||
| 156 | ret = 0; | 161 | ret = 0; |
| 157 | } | 162 | } |
| 158 | if (!ret) | 163 | if (!ret) |
| 159 | ret = gfs2_make_fs_ro(sdp); | 164 | gfs2_make_fs_ro(sdp); |
| 160 | gfs2_freeze_unlock(&freeze_gh); | 165 | gfs2_freeze_unlock(&freeze_gh); |
| 161 | } | 166 | } |
| 162 | 167 | ||
| @@ -110,7 +110,6 @@ struct io_wq { · 109 unmodified lines | |||
| 110 | io_wq_work_fn *do_work; | 110 | io_wq_work_fn *do_work; |
| 111 | 111 | ||
| 112 | struct task_struct *manager; | 112 | struct task_struct *manager; |
| 113 | struct user_struct *user; | ||
| 114 | 113 | ||
| 115 | struct io_wq_hash *hash; | 114 | struct io_wq_hash *hash; |
| 116 | 115 | ||
| @@ -387,13 +386,16 @@ static struct io_wq_work *io_get_next_work(struct io_wqe *wqe) · 270 unmodified lines | |||
| 387 | return NULL; | 386 | return NULL; |
| 388 | } | 387 | } |
| 389 | 388 | ||
| 390 | static void io_flush_signals(void) | 389 | static bool io_flush_signals(void) |
| 391 | { | 390 | { |
| 392 | if (unlikely(test_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL))) { | 391 | if (unlikely(test_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL))) { |
| 392 | __set_current_state(TASK_RUNNING); | ||
| 393 | if (current->task_works) | 393 | if (current->task_works) |
| 394 | task_work_run(); | 394 | task_work_run(); |
| 395 | clear_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL); | 395 | clear_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL); |
| 396 | return true; | ||
| 396 | } | 397 | } |
| 398 | return false; | ||
| 397 | } | 399 | } |
| 398 | 400 | ||
| 399 | static void io_assign_current_work(struct io_worker *worker, | 401 | static void io_assign_current_work(struct io_worker *worker, |
| @@ -489,6 +491,8 @@ static int io_wqe_worker(void *data) · 89 unmodified lines | |||
| 489 | set_task_comm(current, buf); | 491 | set_task_comm(current, buf); |
| 490 | 492 | ||
| 491 | while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) { | 493 | while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) { |
| 494 | long ret; | ||
| 495 | |||
| 492 | set_current_state(TASK_INTERRUPTIBLE); | 496 | set_current_state(TASK_INTERRUPTIBLE); |
| 493 | loop: | 497 | loop: |
| 494 | raw_spin_lock_irq(&wqe->lock); | 498 | raw_spin_lock_irq(&wqe->lock); |
| @@ -498,8 +502,10 @@ loop: · 3 unmodified lines | |||
| 498 | } | 502 | } |
| 499 | __io_worker_idle(wqe, worker); | 503 | __io_worker_idle(wqe, worker); |
| 500 | raw_spin_unlock_irq(&wqe->lock); | 504 | raw_spin_unlock_irq(&wqe->lock); |
| 501 | io_flush_signals(); | 505 | if (io_flush_signals()) |
| 502 | if (schedule_timeout(WORKER_IDLE_TIMEOUT)) | 506 | continue; |
| 507 | ret = schedule_timeout(WORKER_IDLE_TIMEOUT); | ||
| 508 | if (try_to_freeze() || ret) | ||
| 503 | continue; | 509 | continue; |
| 504 | if (fatal_signal_pending(current)) | 510 | if (fatal_signal_pending(current)) |
| 505 | break; | 511 | break; |
| @@ -592,7 +598,7 @@ static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index) · 86 unmodified lines | |||
| 592 | tsk->pf_io_worker = worker; | 598 | tsk->pf_io_worker = worker; |
| 593 | worker->task = tsk; | 599 | worker->task = tsk; |
| 594 | set_cpus_allowed_ptr(tsk, cpumask_of_node(wqe->node)); | 600 | set_cpus_allowed_ptr(tsk, cpumask_of_node(wqe->node)); |
| 595 | tsk->flags |= PF_NOFREEZE | PF_NO_SETAFFINITY; | 601 | tsk->flags |= PF_NO_SETAFFINITY; |
| 596 | 602 | ||
| 597 | raw_spin_lock_irq(&wqe->lock); | 603 | raw_spin_lock_irq(&wqe->lock); |
| 598 | hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list); | 604 | hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list); |
| @@ -722,9 +728,9 @@ static int io_wq_manager(void *data) · 123 unmodified lines | |||
| 722 | io_wq_for_each_worker(wq->wqes[node], io_wq_worker_wake, NULL); | 728 | io_wq_for_each_worker(wq->wqes[node], io_wq_worker_wake, NULL); |
| 723 | rcu_read_unlock(); | 729 | rcu_read_unlock(); |
| 724 | 730 | ||
| 725 | /* we might not ever have created any workers */ | 731 | if (atomic_dec_and_test(&wq->worker_refs)) |
| 726 | if (atomic_read(&wq->worker_refs)) | 732 | complete(&wq->worker_done); |
| 727 | wait_for_completion(&wq->worker_done); | 733 | wait_for_completion(&wq->worker_done); |
| 728 | 734 | ||
| 729 | spin_lock_irq(&wq->hash->wait.lock); | 735 | spin_lock_irq(&wq->hash->wait.lock); |
| 730 | for_each_node(node) | 736 | for_each_node(node) |
| @@ -774,7 +780,10 @@ static int io_wq_fork_manager(struct io_wq *wq) · 43 unmodified lines | |||
| 774 | if (wq->manager) | 780 | if (wq->manager) |
| 775 | return 0; | 781 | return 0; |
| 776 | 782 | ||
| 777 | reinit_completion(&wq->worker_done); | 783 | WARN_ON_ONCE(test_bit(IO_WQ_BIT_EXIT, &wq->state)); |
| 784 | |||
| 785 | init_completion(&wq->worker_done); | ||
| 786 | atomic_set(&wq->worker_refs, 1); | ||
| 778 | tsk = create_io_thread(io_wq_manager, wq, NUMA_NO_NODE); | 787 | tsk = create_io_thread(io_wq_manager, wq, NUMA_NO_NODE); |
| 779 | if (!IS_ERR(tsk)) { | 788 | if (!IS_ERR(tsk)) { |
| 780 | wq->manager = get_task_struct(tsk); | 789 | wq->manager = get_task_struct(tsk); |
| @@ -782,6 +791,9 @@ static int io_wq_fork_manager(struct io_wq *wq) · 1 unmodified line | |||
| 782 | return 0; | 791 | return 0; |
| 783 | } | 792 | } |
| 784 | 793 | ||
| 794 | if (atomic_dec_and_test(&wq->worker_refs)) | ||
| 795 | complete(&wq->worker_done); | ||
| 796 | |||
| 785 | return PTR_ERR(tsk); | 797 | return PTR_ERR(tsk); |
| 786 | } | 798 | } |
| 787 | 799 | ||
| @@ -794,8 +806,7 @@ static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work) · 6 unmodified lines | |||
| 794 | /* Can only happen if manager creation fails after exec */ | 806 | /* Can only happen if manager creation fails after exec */ |
| 795 | if (io_wq_fork_manager(wqe->wq) || | 807 | if (io_wq_fork_manager(wqe->wq) || |
| 796 | test_bit(IO_WQ_BIT_EXIT, &wqe->wq->state)) { | 808 | test_bit(IO_WQ_BIT_EXIT, &wqe->wq->state)) { |
| 797 | work->flags |= IO_WQ_WORK_CANCEL; | 809 | io_run_cancel(work, wqe); |
| 798 | wqe->wq->do_work(work); | ||
| 799 | return; | 810 | return; |
| 800 | } | 811 | } |
| 801 | 812 | ||
| @@ -1018,13 +1029,9 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) · 216 unmodified lines | |||
| 1018 | init_completion(&wq->exited); | 1029 | init_completion(&wq->exited); |
| 1019 | refcount_set(&wq->refs, 1); | 1030 | refcount_set(&wq->refs, 1); |
| 1020 | 1031 | ||
| 1021 | init_completion(&wq->worker_done); | ||
| 1022 | atomic_set(&wq->worker_refs, 0); | ||
| 1023 | |||
| 1024 | ret = io_wq_fork_manager(wq); | 1032 | ret = io_wq_fork_manager(wq); |
| 1025 | if (!ret) | 1033 | if (!ret) |
| 1026 | return wq; | 1034 | return wq; |
| 1027 | |||
| 1028 | err: | 1035 | err: |
| 1029 | io_wq_put_hash(data->hash); | 1036 | io_wq_put_hash(data->hash); |
| 1030 | cpuhp_state_remove_instance_nocalls(io_wq_online, &wq->cpuhp_node); | 1037 | cpuhp_state_remove_instance_nocalls(io_wq_online, &wq->cpuhp_node); |
| @@ -2,7 +2,6 @@ · 1 unmodified line | |||
| 2 | #define INTERNAL_IO_WQ_H | 2 | #define INTERNAL_IO_WQ_H |
| 3 | 3 | ||
| 4 | #include <linux/refcount.h> | 4 | #include <linux/refcount.h> |
| 5 | #include <linux/io_uring.h> | ||
| 6 | 5 | ||
| 7 | struct io_wq; | 6 | struct io_wq; |
| 8 | 7 | ||
| @@ -21,6 +20,15 @@ enum io_wq_cancel { · 12 unmodified lines | |||
| 21 | IO_WQ_CANCEL_NOTFOUND, /* work not found */ | 20 | IO_WQ_CANCEL_NOTFOUND, /* work not found */ |
| 22 | }; | 21 | }; |
| 23 | 22 | ||
| 23 | struct io_wq_work_node { | ||
| 24 | struct io_wq_work_node *next; | ||
| 25 | }; | ||
| 26 | |||
| 27 | struct io_wq_work_list { | ||
| 28 | struct io_wq_work_node *first; | ||
| 29 | struct io_wq_work_node *last; | ||
| 30 | }; | ||
| 31 | |||
| 24 | static inline void wq_list_add_after(struct io_wq_work_node *node, | 32 | static inline void wq_list_add_after(struct io_wq_work_node *node, |
| 25 | struct io_wq_work_node *pos, | 33 | struct io_wq_work_node *pos, |
| 26 | struct io_wq_work_list *list) | 34 | struct io_wq_work_list *list) |
| @@ -79,8 +87,8 @@ static inline void wq_list_del(struct io_wq_work_list *list, · 52 unmodified lines | |||
| 79 | 87 | ||
| 80 | struct io_wq_work { | 88 | struct io_wq_work { |
| 81 | struct io_wq_work_node list; | 89 | struct io_wq_work_node list; |
| 90 | const struct cred *creds; | ||
| 82 | unsigned flags; | 91 | unsigned flags; |
| 83 | unsigned short personality; | ||
| 84 | }; | 92 | }; |
| 85 | 93 | ||
| 86 | static inline struct io_wq_work *wq_next_work(struct io_wq_work *work) | 94 | static inline struct io_wq_work *wq_next_work(struct io_wq_work *work) |
| @@ -258,12 +258,11 @@ enum { · 257 unmodified lines | |||
| 258 | 258 | ||
| 259 | struct io_sq_data { | 259 | struct io_sq_data { |
| 260 | refcount_t refs; | 260 | refcount_t refs; |
| 261 | atomic_t park_pending; | ||
| 261 | struct mutex lock; | 262 | struct mutex lock; |
| 262 | 263 | ||
| 263 | /* ctx's that are using this sqd */ | 264 | /* ctx's that are using this sqd */ |
| 264 | struct list_head ctx_list; | 265 | struct list_head ctx_list; |
| 265 | struct list_head ctx_new_list; | ||
| 266 | struct mutex ctx_lock; | ||
| 267 | 266 | ||
| 268 | struct task_struct *thread; | 267 | struct task_struct *thread; |
| 269 | struct wait_queue_head wait; | 268 | struct wait_queue_head wait; |
| @@ -271,11 +270,11 @@ struct io_sq_data { · 1 unmodified line | |||
| 271 | unsigned sq_thread_idle; | 270 | unsigned sq_thread_idle; |
| 272 | int sq_cpu; | 271 | int sq_cpu; |
| 273 | pid_t task_pid; | 272 | pid_t task_pid; |
| 273 | pid_t task_tgid; | ||
| 274 | 274 | ||
| 275 | unsigned long state; | 275 | unsigned long state; |
| 276 | struct completion startup; | ||
| 277 | struct completion parked; | ||
| 278 | struct completion exited; | 276 | struct completion exited; |
| 277 | struct callback_head *park_task_work; | ||
| 279 | }; | 278 | }; |
| 280 | 279 | ||
| 281 | #define IO_IOPOLL_BATCH 8 | 280 | #define IO_IOPOLL_BATCH 8 |
| @@ -336,7 +335,6 @@ struct io_ring_ctx { · 54 unmodified lines | |||
| 336 | unsigned int drain_next: 1; | 335 | unsigned int drain_next: 1; |
| 337 | unsigned int eventfd_async: 1; | 336 | unsigned int eventfd_async: 1; |
| 338 | unsigned int restricted: 1; | 337 | unsigned int restricted: 1; |
| 339 | unsigned int sqo_exec: 1; | ||
| 340 | 338 | ||
| 341 | /* | 339 | /* |
| 342 | * Ring buffer of indices into array of io_uring_sqe, which is | 340 | * Ring buffer of indices into array of io_uring_sqe, which is |
| @@ -380,6 +378,7 @@ struct io_ring_ctx { · 37 unmodified lines | |||
| 380 | /* Only used for accounting purposes */ | 378 | /* Only used for accounting purposes */ |
| 381 | struct mm_struct *mm_account; | 379 | struct mm_struct *mm_account; |
| 382 | 380 | ||
| 381 | const struct cred *sq_creds; /* cred used for __io_sq_thread() */ | ||
| 383 | struct io_sq_data *sq_data; /* if using sq thread polling */ | 382 | struct io_sq_data *sq_data; /* if using sq thread polling */ |
| 384 | 383 | ||
| 385 | struct wait_queue_head sqo_sq_wait; | 384 | struct wait_queue_head sqo_sq_wait; |
| @@ -400,15 +399,15 @@ struct io_ring_ctx { · 14 unmodified lines | |||
| 400 | struct user_struct *user; | 399 | struct user_struct *user; |
| 401 | 400 | ||
| 402 | struct completion ref_comp; | 401 | struct completion ref_comp; |
| 403 | struct completion sq_thread_comp; | ||
| 404 | 402 | ||
| 405 | #if defined(CONFIG_UNIX) | 403 | #if defined(CONFIG_UNIX) |
| 406 | struct socket *ring_sock; | 404 | struct socket *ring_sock; |
| 407 | #endif | 405 | #endif |
| 408 | 406 | ||
| 409 | struct idr io_buffer_idr; | 407 | struct xarray io_buffers; |
| 410 | 408 | ||
| 411 | struct idr personality_idr; | 409 | struct xarray personalities; |
| 410 | u32 pers_next; | ||
| 412 | 411 | ||
| 413 | struct { | 412 | struct { |
| 414 | unsigned cached_cq_tail; | 413 | unsigned cached_cq_tail; |
| @@ -454,6 +453,23 @@ struct io_ring_ctx { · 39 unmodified lines | |||
| 454 | 453 | ||
| 455 | /* Keep this last, we don't need it for the fast path */ | 454 | /* Keep this last, we don't need it for the fast path */ |
| 456 | struct work_struct exit_work; | 455 | struct work_struct exit_work; |
| 456 | struct list_head tctx_list; | ||
| 457 | }; | ||
| 458 | |||
| 459 | struct io_uring_task { | ||
| 460 | /* submission side */ | ||
| 461 | struct xarray xa; | ||
| 462 | struct wait_queue_head wait; | ||
| 463 | const struct io_ring_ctx *last; | ||
| 464 | struct io_wq *io_wq; | ||
| 465 | struct percpu_counter inflight; | ||
| 466 | atomic_t in_idle; | ||
| 467 | bool sqpoll; | ||
| 468 | |||
| 469 | spinlock_t task_lock; | ||
| 470 | struct io_wq_work_list task_list; | ||
| 471 | unsigned long task_state; | ||
| 472 | struct callback_head task_work; | ||
| 457 | }; | 473 | }; |
| 458 | 474 | ||
| 459 | /* | 475 | /* |
| @@ -805,6 +821,12 @@ struct io_kiocb { · 345 unmodified lines | |||
| 805 | struct io_wq_work work; | 821 | struct io_wq_work work; |
| 806 | }; | 822 | }; |
| 807 | 823 | ||
| 824 | struct io_tctx_node { | ||
| 825 | struct list_head ctx_node; | ||
| 826 | struct task_struct *task; | ||
| 827 | struct io_ring_ctx *ctx; | ||
| 828 | }; | ||
| 829 | |||
| 808 | struct io_defer_entry { | 830 | struct io_defer_entry { |
| 809 | struct list_head list; | 831 | struct list_head list; |
| 810 | struct io_kiocb *req; | 832 | struct io_kiocb *req; |
| @@ -979,6 +1001,8 @@ static const struct io_op_def io_op_defs[] = { · 168 unmodified lines | |||
| 979 | [IORING_OP_UNLINKAT] = {}, | 1001 | [IORING_OP_UNLINKAT] = {}, |
| 980 | }; | 1002 | }; |
| 981 | 1003 | ||
| 1004 | static bool io_disarm_next(struct io_kiocb *req); | ||
| 1005 | static void io_uring_del_task_file(unsigned long index); | ||
| 982 | static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, | 1006 | static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, |
| 983 | struct task_struct *task, | 1007 | struct task_struct *task, |
| 984 | struct files_struct *files); | 1008 | struct files_struct *files); |
| @@ -1129,9 +1153,8 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) · 144 unmodified lines | |||
| 1129 | init_waitqueue_head(&ctx->cq_wait); | 1153 | init_waitqueue_head(&ctx->cq_wait); |
| 1130 | INIT_LIST_HEAD(&ctx->cq_overflow_list); | 1154 | INIT_LIST_HEAD(&ctx->cq_overflow_list); |
| 1131 | init_completion(&ctx->ref_comp); | 1155 | init_completion(&ctx->ref_comp); |
| 1132 | init_completion(&ctx->sq_thread_comp); | 1156 | xa_init_flags(&ctx->io_buffers, XA_FLAGS_ALLOC1); |
| 1133 | idr_init(&ctx->io_buffer_idr); | 1157 | xa_init_flags(&ctx->personalities, XA_FLAGS_ALLOC1); |
| 1134 | idr_init(&ctx->personality_idr); | ||
| 1135 | mutex_init(&ctx->uring_lock); | 1158 | mutex_init(&ctx->uring_lock); |
| 1136 | init_waitqueue_head(&ctx->wait); | 1159 | init_waitqueue_head(&ctx->wait); |
| 1137 | spin_lock_init(&ctx->completion_lock); | 1160 | spin_lock_init(&ctx->completion_lock); |
| @@ -1144,6 +1167,7 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) · 6 unmodified lines | |||
| 1144 | INIT_LIST_HEAD(&ctx->rsrc_ref_list); | 1167 | INIT_LIST_HEAD(&ctx->rsrc_ref_list); |
| 1145 | INIT_DELAYED_WORK(&ctx->rsrc_put_work, io_rsrc_put_work); | 1168 | INIT_DELAYED_WORK(&ctx->rsrc_put_work, io_rsrc_put_work); |
| 1146 | init_llist_head(&ctx->rsrc_put_llist); | 1169 | init_llist_head(&ctx->rsrc_put_llist); |
| 1170 | INIT_LIST_HEAD(&ctx->tctx_list); | ||
| 1147 | INIT_LIST_HEAD(&ctx->submit_state.comp.free_list); | 1171 | INIT_LIST_HEAD(&ctx->submit_state.comp.free_list); |
| 1148 | INIT_LIST_HEAD(&ctx->submit_state.comp.locked_free_list); | 1172 | INIT_LIST_HEAD(&ctx->submit_state.comp.locked_free_list); |
| 1149 | return ctx; | 1173 | return ctx; |
| @@ -1183,6 +1207,9 @@ static void io_prep_async_work(struct io_kiocb *req) · 33 unmodified lines | |||
| 1183 | const struct io_op_def *def = &io_op_defs[req->opcode]; | 1207 | const struct io_op_def *def = &io_op_defs[req->opcode]; |
| 1184 | struct io_ring_ctx *ctx = req->ctx; | 1208 | struct io_ring_ctx *ctx = req->ctx; |
| 1185 | 1209 | ||
| 1210 | if (!req->work.creds) | ||
| 1211 | req->work.creds = get_current_cred(); | ||
| 1212 | |||
| 1186 | if (req->flags & REQ_F_FORCE_ASYNC) | 1213 | if (req->flags & REQ_F_FORCE_ASYNC) |
| 1187 | req->work.flags |= IO_WQ_WORK_CONCURRENT; | 1214 | req->work.flags |= IO_WQ_WORK_CONCURRENT; |
| 1188 | 1215 | ||
| @@ -1514,15 +1541,14 @@ static void io_cqring_fill_event(struct io_kiocb *req, long res) · 325 unmodified lines | |||
| 1514 | __io_cqring_fill_event(req, res, 0); | 1541 | __io_cqring_fill_event(req, res, 0); |
| 1515 | } | 1542 | } |
| 1516 | 1543 | ||
| 1517 | static inline void io_req_complete_post(struct io_kiocb *req, long res, | 1544 | static void io_req_complete_post(struct io_kiocb *req, long res, |
| 1518 | unsigned int cflags) | 1545 | unsigned int cflags) |
| 1519 | { | 1546 | { |
| 1520 | struct io_ring_ctx *ctx = req->ctx; | 1547 | struct io_ring_ctx *ctx = req->ctx; |
| 1521 | unsigned long flags; | 1548 | unsigned long flags; |
| 1522 | 1549 | ||
| 1523 | spin_lock_irqsave(&ctx->completion_lock, flags); | 1550 | spin_lock_irqsave(&ctx->completion_lock, flags); |
| 1524 | __io_cqring_fill_event(req, res, cflags); | 1551 | __io_cqring_fill_event(req, res, cflags); |
| 1525 | io_commit_cqring(ctx); | ||
| 1526 | /* | 1552 | /* |
| 1527 | * If we're the last reference to this request, add to our locked | 1553 | * If we're the last reference to this request, add to our locked |
| 1528 | * free_list cache. | 1554 | * free_list cache. |
| @@ -1530,17 +1556,27 @@ static inline void io_req_complete_post(struct io_kiocb *req, long res, · 1 unmodified line | |||
| 1530 | if (refcount_dec_and_test(&req->refs)) { | 1556 | if (refcount_dec_and_test(&req->refs)) { |
| 1531 | struct io_comp_state *cs = &ctx->submit_state.comp; | 1557 | struct io_comp_state *cs = &ctx->submit_state.comp; |
| 1532 | 1558 | ||
| 1559 | if (req->flags & (REQ_F_LINK | REQ_F_HARDLINK)) { | ||
| 1560 | if (req->flags & (REQ_F_LINK_TIMEOUT | REQ_F_FAIL_LINK)) | ||
| 1561 | io_disarm_next(req); | ||
| 1562 | if (req->link) { | ||
| 1563 | io_req_task_queue(req->link); | ||
| 1564 | req->link = NULL; | ||
| 1565 | } | ||
| 1566 | } | ||
| 1533 | io_dismantle_req(req); | 1567 | io_dismantle_req(req); |
| 1534 | io_put_task(req->task, 1); | 1568 | io_put_task(req->task, 1); |
| 1535 | list_add(&req->compl.list, &cs->locked_free_list); | 1569 | list_add(&req->compl.list, &cs->locked_free_list); |
| 1536 | cs->locked_free_nr++; | 1570 | cs->locked_free_nr++; |
| 1537 | } else | 1571 | } else { |
| 1538 | req = NULL; | 1572 | if (!percpu_ref_tryget(&ctx->refs)) |
| 1573 | req = NULL; | ||
| 1574 | } | ||
| 1575 | io_commit_cqring(ctx); | ||
| 1539 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | 1576 | spin_unlock_irqrestore(&ctx->completion_lock, flags); |
| 1540 | 1577 | ||
| 1541 | io_cqring_ev_posted(ctx); | ||
| 1542 | if (req) { | 1578 | if (req) { |
| 1543 | io_queue_next(req); | 1579 | io_cqring_ev_posted(ctx); |
| 1544 | percpu_ref_put(&ctx->refs); | 1580 | percpu_ref_put(&ctx->refs); |
| 1545 | } | 1581 | } |
| 1546 | } | 1582 | } |
| @@ -1648,6 +1684,10 @@ static void io_dismantle_req(struct io_kiocb *req) · 101 unmodified lines | |||
| 1648 | io_put_file(req, req->file, (req->flags & REQ_F_FIXED_FILE)); | 1684 | io_put_file(req, req->file, (req->flags & REQ_F_FIXED_FILE)); |
| 1649 | if (req->fixed_rsrc_refs) | 1685 | if (req->fixed_rsrc_refs) |
| 1650 | percpu_ref_put(req->fixed_rsrc_refs); | 1686 | percpu_ref_put(req->fixed_rsrc_refs); |
| 1687 | if (req->work.creds) { | ||
| 1688 | put_cred(req->work.creds); | ||
| 1689 | req->work.creds = NULL; | ||
| 1690 | } | ||
| 1651 | 1691 | ||
| 1652 | if (req->flags & REQ_F_INFLIGHT) { | 1692 | if (req->flags & REQ_F_INFLIGHT) { |
| 1653 | struct io_ring_ctx *ctx = req->ctx; | 1693 | struct io_ring_ctx *ctx = req->ctx; |
| @@ -1690,15 +1730,11 @@ static inline void io_remove_next_linked(struct io_kiocb *req) · 36 unmodified lines | |||
| 1690 | nxt->link = NULL; | 1730 | nxt->link = NULL; |
| 1691 | } | 1731 | } |
| 1692 | 1732 | ||
| 1693 | static void io_kill_linked_timeout(struct io_kiocb *req) | 1733 | static bool io_kill_linked_timeout(struct io_kiocb *req) |
| 1734 | __must_hold(&req->ctx->completion_lock) | ||
| 1694 | { | 1735 | { |
| 1695 | struct io_ring_ctx *ctx = req->ctx; | 1736 | struct io_kiocb *link = req->link; |
| 1696 | struct io_kiocb *link; | ||
| 1697 | bool cancelled = false; | 1737 | bool cancelled = false; |
| 1698 | unsigned long flags; | ||
| 1699 | |||
| 1700 | spin_lock_irqsave(&ctx->completion_lock, flags); | ||
| 1701 | link = req->link; | ||
| 1702 | 1738 | ||
| 1703 | /* | 1739 | /* |
| 1704 | * Can happen if a linked timeout fired and link had been like | 1740 | * Can happen if a linked timeout fired and link had been like |
| @@ -1713,50 +1749,48 @@ static void io_kill_linked_timeout(struct io_kiocb *req) · 8 unmodified lines | |||
| 1713 | ret = hrtimer_try_to_cancel(&io->timer); | 1749 | ret = hrtimer_try_to_cancel(&io->timer); |
| 1714 | if (ret != -1) { | 1750 | if (ret != -1) { |
| 1715 | io_cqring_fill_event(link, -ECANCELED); | 1751 | io_cqring_fill_event(link, -ECANCELED); |
| 1716 | io_commit_cqring(ctx); | 1752 | io_put_req_deferred(link, 1); |
| 1717 | cancelled = true; | 1753 | cancelled = true; |
| 1718 | } | 1754 | } |
| 1719 | } | 1755 | } |
| 1720 | req->flags &= ~REQ_F_LINK_TIMEOUT; | 1756 | req->flags &= ~REQ_F_LINK_TIMEOUT; |
| 1721 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | 1757 | return cancelled; |
| 1722 | |||
| 1723 | if (cancelled) { | ||
| 1724 | io_cqring_ev_posted(ctx); | ||
| 1725 | io_put_req(link); | ||
| 1726 | } | ||
| 1727 | } | 1758 | } |
| 1728 | 1759 | ||
| 1729 | |||
| 1730 | static void io_fail_links(struct io_kiocb *req) | 1760 | static void io_fail_links(struct io_kiocb *req) |
| 1761 | __must_hold(&req->ctx->completion_lock) | ||
| 1731 | { | 1762 | { |
| 1732 | struct io_kiocb *link, *nxt; | 1763 | struct io_kiocb *nxt, *link = req->link; |
| 1733 | struct io_ring_ctx *ctx = req->ctx; | ||
| 1734 | unsigned long flags; | ||
| 1735 | 1764 | ||
| 1736 | spin_lock_irqsave(&ctx->completion_lock, flags); | ||
| 1737 | link = req->link; | ||
| 1738 | req->link = NULL; | 1765 | req->link = NULL; |
| 1739 | |||
| 1740 | while (link) { | 1766 | while (link) { |
| 1741 | nxt = link->link; | 1767 | nxt = link->link; |
| 1742 | link->link = NULL; | 1768 | link->link = NULL; |
| 1743 | 1769 | ||
| 1744 | trace_io_uring_fail_link(req, link); | 1770 | trace_io_uring_fail_link(req, link); |
| 1745 | io_cqring_fill_event(link, -ECANCELED); | 1771 | io_cqring_fill_event(link, -ECANCELED); |
| 1746 | |||
| 1747 | io_put_req_deferred(link, 2); | 1772 | io_put_req_deferred(link, 2); |
| 1748 | link = nxt; | 1773 | link = nxt; |
| 1749 | } | 1774 | } |
| 1750 | io_commit_cqring(ctx); | 1775 | } |
| 1751 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | ||
| 1752 | 1776 | ||
| 1753 | io_cqring_ev_posted(ctx); | 1777 | static bool io_disarm_next(struct io_kiocb *req) |
| 1778 | __must_hold(&req->ctx->completion_lock) | ||
| 1779 | { | ||
| 1780 | bool posted = false; | ||
| 1781 | |||
| 1782 | if (likely(req->flags & REQ_F_LINK_TIMEOUT)) | ||
| 1783 | posted = io_kill_linked_timeout(req); | ||
| 1784 | if (unlikely(req->flags & REQ_F_FAIL_LINK)) { | ||
| 1785 | posted |= (req->link != NULL); | ||
| 1786 | io_fail_links(req); | ||
| 1787 | } | ||
| 1788 | return posted; | ||
| 1754 | } | 1789 | } |
| 1755 | 1790 | ||
| 1756 | static struct io_kiocb *__io_req_find_next(struct io_kiocb *req) | 1791 | static struct io_kiocb *__io_req_find_next(struct io_kiocb *req) |
| 1757 | { | 1792 | { |
| 1758 | if (req->flags & REQ_F_LINK_TIMEOUT) | 1793 | struct io_kiocb *nxt; |
| 1759 | io_kill_linked_timeout(req); | ||
| 1760 | 1794 | ||
| 1761 | /* | 1795 | /* |
| 1762 | * If LINK is set, we have dependent requests in this chain. If we | 1796 | * If LINK is set, we have dependent requests in this chain. If we |
| @@ -1764,14 +1798,22 @@ static struct io_kiocb *__io_req_find_next(struct io_kiocb *req) · 1 unmodified line | |||
| 1764 | * dependencies to the next request. In case of failure, fail the rest | 1798 | * dependencies to the next request. In case of failure, fail the rest |
| 1765 | * of the chain. | 1799 | * of the chain. |
| 1766 | */ | 1800 | */ |
| 1767 | if (likely(!(req->flags & REQ_F_FAIL_LINK))) { | 1801 | if (req->flags & (REQ_F_LINK_TIMEOUT | REQ_F_FAIL_LINK)) { |
| 1768 | struct io_kiocb *nxt = req->link; | 1802 | struct io_ring_ctx *ctx = req->ctx; |
| 1803 | unsigned long flags; | ||
| 1804 | bool posted; | ||
| 1769 | 1805 | ||
| 1770 | req->link = NULL; | 1806 | spin_lock_irqsave(&ctx->completion_lock, flags); |
| 1771 | return nxt; | 1807 | posted = io_disarm_next(req); |
| 1808 | if (posted) | ||
| 1809 | io_commit_cqring(req->ctx); | ||
| 1810 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | ||
| 1811 | if (posted) | ||
| 1812 | io_cqring_ev_posted(ctx); | ||
| 1772 | } | 1813 | } |
| 1773 | io_fail_links(req); | 1814 | nxt = req->link; |
| 1774 | return NULL; | 1815 | req->link = NULL; |
| 1816 | return nxt; | ||
| 1775 | } | 1817 | } |
| 1776 | 1818 | ||
| 1777 | static inline struct io_kiocb *io_req_find_next(struct io_kiocb *req) | 1819 | static inline struct io_kiocb *io_req_find_next(struct io_kiocb *req) |
| @@ -1904,17 +1946,44 @@ static int io_req_task_work_add(struct io_kiocb *req) · 126 unmodified lines | |||
| 1904 | return ret; | 1946 | return ret; |
| 1905 | } | 1947 | } |
| 1906 | 1948 | ||
| 1907 | static void io_req_task_work_add_fallback(struct io_kiocb *req, | 1949 | static bool io_run_task_work_head(struct callback_head **work_head) |
| 1908 | task_work_func_t cb) | 1950 | { |
| 1951 | struct callback_head *work, *next; | ||
| 1952 | bool executed = false; | ||
| 1953 | |||
| 1954 | do { | ||
| 1955 | work = xchg(work_head, NULL); | ||
| 1956 | if (!work) | ||
| 1957 | break; | ||
| 1958 | |||
| 1959 | do { | ||
| 1960 | next = work->next; | ||
| 1961 | work->func(work); | ||
| 1962 | work = next; | ||
| 1963 | cond_resched(); | ||
| 1964 | } while (work); | ||
| 1965 | executed = true; | ||
| 1966 | } while (1); | ||
| 1967 | |||
| 1968 | return executed; | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | static void io_task_work_add_head(struct callback_head **work_head, | ||
| 1972 | struct callback_head *task_work) | ||
| 1909 | { | 1973 | { |
| 1910 | struct io_ring_ctx *ctx = req->ctx; | ||
| 1911 | struct callback_head *head; | 1974 | struct callback_head *head; |
| 1912 | 1975 | ||
| 1913 | init_task_work(&req->task_work, cb); | ||
| 1914 | do { | 1976 | do { |
| 1915 | head = READ_ONCE(ctx->exit_task_work); | 1977 | head = READ_ONCE(*work_head); |
| 1916 | req->task_work.next = head; | 1978 | task_work->next = head; |
| 1917 | } while (cmpxchg(&ctx->exit_task_work, head, &req->task_work) != head); | 1979 | } while (cmpxchg(work_head, head, task_work) != head); |
| 1980 | } | ||
| 1981 | |||
| 1982 | static void io_req_task_work_add_fallback(struct io_kiocb *req, | ||
| 1983 | task_work_func_t cb) | ||
| 1984 | { | ||
| 1985 | init_task_work(&req->task_work, cb); | ||
| 1986 | io_task_work_add_head(&req->ctx->exit_task_work, &req->task_work); | ||
| 1918 | } | 1987 | } |
| 1919 | 1988 | ||
| 1920 | static void __io_req_task_cancel(struct io_kiocb *req, int error) | 1989 | static void __io_req_task_cancel(struct io_kiocb *req, int error) |
| @@ -2822,7 +2891,7 @@ static struct io_buffer *io_buffer_select(struct io_kiocb *req, size_t *len, · 901 unmodified lines | |||
| 2822 | 2891 | ||
| 2823 | lockdep_assert_held(&req->ctx->uring_lock); | 2892 | lockdep_assert_held(&req->ctx->uring_lock); |
| 2824 | 2893 | ||
| 2825 | head = idr_find(&req->ctx->io_buffer_idr, bgid); | 2894 | head = xa_load(&req->ctx->io_buffers, bgid); |
| 2826 | if (head) { | 2895 | if (head) { |
| 2827 | if (!list_empty(&head->list)) { | 2896 | if (!list_empty(&head->list)) { |
| 2828 | kbuf = list_last_entry(&head->list, struct io_buffer, | 2897 | kbuf = list_last_entry(&head->list, struct io_buffer, |
| @@ -2830,7 +2899,7 @@ static struct io_buffer *io_buffer_select(struct io_kiocb *req, size_t *len, · 1 unmodified line | |||
| 2830 | list_del(&kbuf->list); | 2899 | list_del(&kbuf->list); |
| 2831 | } else { | 2900 | } else { |
| 2832 | kbuf = head; | 2901 | kbuf = head; |
| 2833 | idr_remove(&req->ctx->io_buffer_idr, bgid); | 2902 | xa_erase(&req->ctx->io_buffers, bgid); |
| 2834 | } | 2903 | } |
| 2835 | if (*len > kbuf->len) | 2904 | if (*len > kbuf->len) |
| 2836 | *len = kbuf->len; | 2905 | *len = kbuf->len; |
| @@ -3871,7 +3940,7 @@ static int __io_remove_buffers(struct io_ring_ctx *ctx, struct io_buffer *buf, · 1034 unmodified lines | |||
| 3871 | } | 3940 | } |
| 3872 | i++; | 3941 | i++; |
| 3873 | kfree(buf); | 3942 | kfree(buf); |
| 3874 | idr_remove(&ctx->io_buffer_idr, bgid); | 3943 | xa_erase(&ctx->io_buffers, bgid); |
| 3875 | 3944 | ||
| 3876 | return i; | 3945 | return i; |
| 3877 | } | 3946 | } |
| @@ -3889,7 +3958,7 @@ static int io_remove_buffers(struct io_kiocb *req, unsigned int issue_flags) · 11 unmodified lines | |||
| 3889 | lockdep_assert_held(&ctx->uring_lock); | 3958 | lockdep_assert_held(&ctx->uring_lock); |
| 3890 | 3959 | ||
| 3891 | ret = -ENOENT; | 3960 | ret = -ENOENT; |
| 3892 | head = idr_find(&ctx->io_buffer_idr, p->bgid); | 3961 | head = xa_load(&ctx->io_buffers, p->bgid); |
| 3893 | if (head) | 3962 | if (head) |
| 3894 | ret = __io_remove_buffers(ctx, head, p->bgid, p->nbufs); | 3963 | ret = __io_remove_buffers(ctx, head, p->bgid, p->nbufs); |
| 3895 | if (ret < 0) | 3964 | if (ret < 0) |
| @@ -3972,21 +4041,14 @@ static int io_provide_buffers(struct io_kiocb *req, unsigned int issue_flags) · 76 unmodified lines | |||
| 3972 | 4041 | ||
| 3973 | lockdep_assert_held(&ctx->uring_lock); | 4042 | lockdep_assert_held(&ctx->uring_lock); |
| 3974 | 4043 | ||
| 3975 | list = head = idr_find(&ctx->io_buffer_idr, p->bgid); | 4044 | list = head = xa_load(&ctx->io_buffers, p->bgid); |
| 3976 | 4045 | ||
| 3977 | ret = io_add_buffers(p, &head); | 4046 | ret = io_add_buffers(p, &head); |
| 3978 | if (ret < 0) | 4047 | if (ret >= 0 && !list) { |
| 3979 | goto out; | 4048 | ret = xa_insert(&ctx->io_buffers, p->bgid, head, GFP_KERNEL); |
| 3980 | 4049 | if (ret < 0) | |
| 3981 | if (!list) { | ||
| 3982 | ret = idr_alloc(&ctx->io_buffer_idr, head, p->bgid, p->bgid + 1, | ||
| 3983 | GFP_KERNEL); | ||
| 3984 | if (ret < 0) { | ||
| 3985 | __io_remove_buffers(ctx, head, p->bgid, -1U); | 4050 | __io_remove_buffers(ctx, head, p->bgid, -1U); |
| 3986 | goto out; | ||
| 3987 | } | ||
| 3988 | } | 4051 | } |
| 3989 | out: | ||
| 3990 | if (ret < 0) | 4052 | if (ret < 0) |
| 3991 | req_set_fail_links(req); | 4053 | req_set_fail_links(req); |
| 3992 | 4054 | ||
| @@ -4324,6 +4386,7 @@ static int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags) · 331 unmodified lines | |||
| 4324 | struct io_async_msghdr iomsg, *kmsg; | 4386 | struct io_async_msghdr iomsg, *kmsg; |
| 4325 | struct socket *sock; | 4387 | struct socket *sock; |
| 4326 | unsigned flags; | 4388 | unsigned flags; |
| 4389 | int min_ret = 0; | ||
| 4327 | int ret; | 4390 | int ret; |
| 4328 | 4391 | ||
| 4329 | sock = sock_from_file(req->file); | 4392 | sock = sock_from_file(req->file); |
| @@ -4338,12 +4401,15 @@ static int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags) · 8 unmodified lines | |||
| 4338 | kmsg = &iomsg; | 4401 | kmsg = &iomsg; |
| 4339 | } | 4402 | } |
| 4340 | 4403 | ||
| 4341 | flags = req->sr_msg.msg_flags; | 4404 | flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; |
| 4342 | if (flags & MSG_DONTWAIT) | 4405 | if (flags & MSG_DONTWAIT) |
| 4343 | req->flags |= REQ_F_NOWAIT; | 4406 | req->flags |= REQ_F_NOWAIT; |
| 4344 | else if (issue_flags & IO_URING_F_NONBLOCK) | 4407 | else if (issue_flags & IO_URING_F_NONBLOCK) |
| 4345 | flags |= MSG_DONTWAIT; | 4408 | flags |= MSG_DONTWAIT; |
| 4346 | 4409 | ||
| 4410 | if (flags & MSG_WAITALL) | ||
| 4411 | min_ret = iov_iter_count(&kmsg->msg.msg_iter); | ||
| 4412 | |||
| 4347 | ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); | 4413 | ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); |
| 4348 | if ((issue_flags & IO_URING_F_NONBLOCK) && ret == -EAGAIN) | 4414 | if ((issue_flags & IO_URING_F_NONBLOCK) && ret == -EAGAIN) |
| 4349 | return io_setup_async_msg(req, kmsg); | 4415 | return io_setup_async_msg(req, kmsg); |
| @@ -4354,7 +4420,7 @@ static int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags) · 4 unmodified lines | |||
| 4354 | if (kmsg->free_iov) | 4420 | if (kmsg->free_iov) |
| 4355 | kfree(kmsg->free_iov); | 4421 | kfree(kmsg->free_iov); |
| 4356 | req->flags &= ~REQ_F_NEED_CLEANUP; | 4422 | req->flags &= ~REQ_F_NEED_CLEANUP; |
| 4357 | if (ret < 0) | 4423 | if (ret < min_ret) |
| 4358 | req_set_fail_links(req); | 4424 | req_set_fail_links(req); |
| 4359 | __io_req_complete(req, issue_flags, ret, 0); | 4425 | __io_req_complete(req, issue_flags, ret, 0); |
| 4360 | return 0; | 4426 | return 0; |
| @@ -4367,6 +4433,7 @@ static int io_send(struct io_kiocb *req, unsigned int issue_flags) · 6 unmodified lines | |||
| 4367 | struct iovec iov; | 4433 | struct iovec iov; |
| 4368 | struct socket *sock; | 4434 | struct socket *sock; |
| 4369 | unsigned flags; | 4435 | unsigned flags; |
| 4436 | int min_ret = 0; | ||
| 4370 | int ret; | 4437 | int ret; |
| 4371 | 4438 | ||
| 4372 | sock = sock_from_file(req->file); | 4439 | sock = sock_from_file(req->file); |
| @@ -4382,12 +4449,15 @@ static int io_send(struct io_kiocb *req, unsigned int issue_flags) · 9 unmodified lines | |||
| 4382 | msg.msg_controllen = 0; | 4449 | msg.msg_controllen = 0; |
| 4383 | msg.msg_namelen = 0; | 4450 | msg.msg_namelen = 0; |
| 4384 | 4451 | ||
| 4385 | flags = req->sr_msg.msg_flags; | 4452 | flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; |
| 4386 | if (flags & MSG_DONTWAIT) | 4453 | if (flags & MSG_DONTWAIT) |
| 4387 | req->flags |= REQ_F_NOWAIT; | 4454 | req->flags |= REQ_F_NOWAIT; |
| 4388 | else if (issue_flags & IO_URING_F_NONBLOCK) | 4455 | else if (issue_flags & IO_URING_F_NONBLOCK) |
| 4389 | flags |= MSG_DONTWAIT; | 4456 | flags |= MSG_DONTWAIT; |
| 4390 | 4457 | ||
| 4458 | if (flags & MSG_WAITALL) | ||
| 4459 | min_ret = iov_iter_count(&msg.msg_iter); | ||
| 4460 | |||
| 4391 | msg.msg_flags = flags; | 4461 | msg.msg_flags = flags; |
| 4392 | ret = sock_sendmsg(sock, &msg); | 4462 | ret = sock_sendmsg(sock, &msg); |
| 4393 | if ((issue_flags & IO_URING_F_NONBLOCK) && ret == -EAGAIN) | 4463 | if ((issue_flags & IO_URING_F_NONBLOCK) && ret == -EAGAIN) |
| @@ -4395,7 +4465,7 @@ static int io_send(struct io_kiocb *req, unsigned int issue_flags) · 1 unmodified line | |||
| 4395 | if (ret == -ERESTARTSYS) | 4465 | if (ret == -ERESTARTSYS) |
| 4396 | ret = -EINTR; | 4466 | ret = -EINTR; |
| 4397 | 4467 | ||
| 4398 | if (ret < 0) | 4468 | if (ret < min_ret) |
| 4399 | req_set_fail_links(req); | 4469 | req_set_fail_links(req); |
| 4400 | __io_req_complete(req, issue_flags, ret, 0); | 4470 | __io_req_complete(req, issue_flags, ret, 0); |
| 4401 | return 0; | 4471 | return 0; |
| @@ -4547,6 +4617,7 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags) · 145 unmodified lines | |||
| 4547 | struct socket *sock; | 4617 | struct socket *sock; |
| 4548 | struct io_buffer *kbuf; | 4618 | struct io_buffer *kbuf; |
| 4549 | unsigned flags; | 4619 | unsigned flags; |
| 4620 | int min_ret = 0; | ||
| 4550 | int ret, cflags = 0; | 4621 | int ret, cflags = 0; |
| 4551 | bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; | 4622 | bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; |
| 4552 | 4623 | ||
| @@ -4572,12 +4643,15 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags) · 19 unmodified lines | |||
| 4572 | 1, req->sr_msg.len); | 4643 | 1, req->sr_msg.len); |
| 4573 | } | 4644 | } |
| 4574 | 4645 | ||
| 4575 | flags = req->sr_msg.msg_flags; | 4646 | flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; |
| 4576 | if (flags & MSG_DONTWAIT) | 4647 | if (flags & MSG_DONTWAIT) |
| 4577 | req->flags |= REQ_F_NOWAIT; | 4648 | req->flags |= REQ_F_NOWAIT; |
| 4578 | else if (force_nonblock) | 4649 | else if (force_nonblock) |
| 4579 | flags |= MSG_DONTWAIT; | 4650 | flags |= MSG_DONTWAIT; |
| 4580 | 4651 | ||
| 4652 | if (flags & MSG_WAITALL) | ||
| 4653 | min_ret = iov_iter_count(&kmsg->msg.msg_iter); | ||
| 4654 | |||
| 4581 | ret = __sys_recvmsg_sock(sock, &kmsg->msg, req->sr_msg.umsg, | 4655 | ret = __sys_recvmsg_sock(sock, &kmsg->msg, req->sr_msg.umsg, |
| 4582 | kmsg->uaddr, flags); | 4656 | kmsg->uaddr, flags); |
| 4583 | if (force_nonblock && ret == -EAGAIN) | 4657 | if (force_nonblock && ret == -EAGAIN) |
| @@ -4591,7 +4665,7 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags) · 7 unmodified lines | |||
| 4591 | if (kmsg->free_iov) | 4665 | if (kmsg->free_iov) |
| 4592 | kfree(kmsg->free_iov); | 4666 | kfree(kmsg->free_iov); |
| 4593 | req->flags &= ~REQ_F_NEED_CLEANUP; | 4667 | req->flags &= ~REQ_F_NEED_CLEANUP; |
| 4594 | if (ret < 0) | 4668 | if (ret < min_ret || ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))) |
| 4595 | req_set_fail_links(req); | 4669 | req_set_fail_links(req); |
| 4596 | __io_req_complete(req, issue_flags, ret, cflags); | 4670 | __io_req_complete(req, issue_flags, ret, cflags); |
| 4597 | return 0; | 4671 | return 0; |
| @@ -4606,6 +4680,7 @@ static int io_recv(struct io_kiocb *req, unsigned int issue_flags) · 8 unmodified lines | |||
| 4606 | struct socket *sock; | 4680 | struct socket *sock; |
| 4607 | struct iovec iov; | 4681 | struct iovec iov; |
| 4608 | unsigned flags; | 4682 | unsigned flags; |
| 4683 | int min_ret = 0; | ||
| 4609 | int ret, cflags = 0; | 4684 | int ret, cflags = 0; |
| 4610 | bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; | 4685 | bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; |
| 4611 | 4686 | ||
| @@ -4631,12 +4706,15 @@ static int io_recv(struct io_kiocb *req, unsigned int issue_flags) · 19 unmodified lines | |||
| 4631 | msg.msg_iocb = NULL; | 4706 | msg.msg_iocb = NULL; |
| 4632 | msg.msg_flags = 0; | 4707 | msg.msg_flags = 0; |
| 4633 | 4708 | ||
| 4634 | flags = req->sr_msg.msg_flags; | 4709 | flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; |
| 4635 | if (flags & MSG_DONTWAIT) | 4710 | if (flags & MSG_DONTWAIT) |
| 4636 | req->flags |= REQ_F_NOWAIT; | 4711 | req->flags |= REQ_F_NOWAIT; |
| 4637 | else if (force_nonblock) | 4712 | else if (force_nonblock) |
| 4638 | flags |= MSG_DONTWAIT; | 4713 | flags |= MSG_DONTWAIT; |
| 4639 | 4714 | ||
| 4715 | if (flags & MSG_WAITALL) | ||
| 4716 | min_ret = iov_iter_count(&msg.msg_iter); | ||
| 4717 | |||
| 4640 | ret = sock_recvmsg(sock, &msg, flags); | 4718 | ret = sock_recvmsg(sock, &msg, flags); |
| 4641 | if (force_nonblock && ret == -EAGAIN) | 4719 | if (force_nonblock && ret == -EAGAIN) |
| 4642 | return -EAGAIN; | 4720 | return -EAGAIN; |
| @@ -4645,7 +4723,7 @@ static int io_recv(struct io_kiocb *req, unsigned int issue_flags) · 2 unmodified lines | |||
| 4645 | out_free: | 4723 | out_free: |
| 4646 | if (req->flags & REQ_F_BUFFER_SELECTED) | 4724 | if (req->flags & REQ_F_BUFFER_SELECTED) |
| 4647 | cflags = io_put_recv_kbuf(req); | 4725 | cflags = io_put_recv_kbuf(req); |
| 4648 | if (ret < 0) | 4726 | if (ret < min_ret || ((flags & MSG_WAITALL) && (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))) |
| 4649 | req_set_fail_links(req); | 4727 | req_set_fail_links(req); |
| 4650 | __io_req_complete(req, issue_flags, ret, cflags); | 4728 | __io_req_complete(req, issue_flags, ret, cflags); |
| 4651 | return 0; | 4729 | return 0; |
| @@ -5559,22 +5637,30 @@ add: · 907 unmodified lines | |||
| 5559 | return 0; | 5637 | return 0; |
| 5560 | } | 5638 | } |
| 5561 | 5639 | ||
| 5640 | struct io_cancel_data { | ||
| 5641 | struct io_ring_ctx *ctx; | ||
| 5642 | u64 user_data; | ||
| 5643 | }; | ||
| 5644 | |||
| 5562 | static bool io_cancel_cb(struct io_wq_work *work, void *data) | 5645 | static bool io_cancel_cb(struct io_wq_work *work, void *data) |
| 5563 | { | 5646 | { |
| 5564 | struct io_kiocb *req = container_of(work, struct io_kiocb, work); | 5647 | struct io_kiocb *req = container_of(work, struct io_kiocb, work); |
| 5648 | struct io_cancel_data *cd = data; | ||
| 5565 | 5649 | ||
| 5566 | return req->user_data == (unsigned long) data; | 5650 | return req->ctx == cd->ctx && req->user_data == cd->user_data; |
| 5567 | } | 5651 | } |
| 5568 | 5652 | ||
| 5569 | static int io_async_cancel_one(struct io_uring_task *tctx, void *sqe_addr) | 5653 | static int io_async_cancel_one(struct io_uring_task *tctx, u64 user_data, |
| 5654 | struct io_ring_ctx *ctx) | ||
| 5570 | { | 5655 | { |
| 5656 | struct io_cancel_data data = { .ctx = ctx, .user_data = user_data, }; | ||
| 5571 | enum io_wq_cancel cancel_ret; | 5657 | enum io_wq_cancel cancel_ret; |
| 5572 | int ret = 0; | 5658 | int ret = 0; |
| 5573 | 5659 | ||
| 5574 | if (!tctx->io_wq) | 5660 | if (!tctx || !tctx->io_wq) |
| 5575 | return -ENOENT; | 5661 | return -ENOENT; |
| 5576 | 5662 | ||
| 5577 | cancel_ret = io_wq_cancel_cb(tctx->io_wq, io_cancel_cb, sqe_addr, false); | 5663 | cancel_ret = io_wq_cancel_cb(tctx->io_wq, io_cancel_cb, &data, false); |
| 5578 | switch (cancel_ret) { | 5664 | switch (cancel_ret) { |
| 5579 | case IO_WQ_CANCEL_OK: | 5665 | case IO_WQ_CANCEL_OK: |
| 5580 | ret = 0; | 5666 | ret = 0; |
| @@ -5597,8 +5683,7 @@ static void io_async_find_and_cancel(struct io_ring_ctx *ctx, · 16 unmodified lines | |||
| 5597 | unsigned long flags; | 5683 | unsigned long flags; |
| 5598 | int ret; | 5684 | int ret; |
| 5599 | 5685 | ||
| 5600 | ret = io_async_cancel_one(req->task->io_uring, | 5686 | ret = io_async_cancel_one(req->task->io_uring, sqe_addr, ctx); |
| 5601 | (void *) (unsigned long) sqe_addr); | ||
| 5602 | if (ret != -ENOENT) { | 5687 | if (ret != -ENOENT) { |
| 5603 | spin_lock_irqsave(&ctx->completion_lock, flags); | 5688 | spin_lock_irqsave(&ctx->completion_lock, flags); |
| 5604 | goto done; | 5689 | goto done; |
| @@ -5639,8 +5724,47 @@ static int io_async_cancel_prep(struct io_kiocb *req, · 34 unmodified lines | |||
| 5639 | static int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags) | 5724 | static int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags) |
| 5640 | { | 5725 | { |
| 5641 | struct io_ring_ctx *ctx = req->ctx; | 5726 | struct io_ring_ctx *ctx = req->ctx; |
| 5727 | u64 sqe_addr = req->cancel.addr; | ||
| 5728 | struct io_tctx_node *node; | ||
| 5729 | int ret; | ||
| 5642 | 5730 | ||
| 5643 | io_async_find_and_cancel(ctx, req, req->cancel.addr, 0); | 5731 | /* tasks should wait for their io-wq threads, so safe w/o sync */ |
| 5732 | ret = io_async_cancel_one(req->task->io_uring, sqe_addr, ctx); | ||
| 5733 | spin_lock_irq(&ctx->completion_lock); | ||
| 5734 | if (ret != -ENOENT) | ||
| 5735 | goto done; | ||
| 5736 | ret = io_timeout_cancel(ctx, sqe_addr); | ||
| 5737 | if (ret != -ENOENT) | ||
| 5738 | goto done; | ||
| 5739 | ret = io_poll_cancel(ctx, sqe_addr); | ||
| 5740 | if (ret != -ENOENT) | ||
| 5741 | goto done; | ||
| 5742 | spin_unlock_irq(&ctx->completion_lock); | ||
| 5743 | |||
| 5744 | /* slow path, try all io-wq's */ | ||
| 5745 | io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK)); | ||
| 5746 | ret = -ENOENT; | ||
| 5747 | list_for_each_entry(node, &ctx->tctx_list, ctx_node) { | ||
| 5748 | struct io_uring_task *tctx = node->task->io_uring; | ||
| 5749 | |||
| 5750 | if (!tctx || !tctx->io_wq) | ||
| 5751 | continue; | ||
| 5752 | ret = io_async_cancel_one(tctx, req->cancel.addr, ctx); | ||
| 5753 | if (ret != -ENOENT) | ||
| 5754 | break; | ||
| 5755 | } | ||
| 5756 | io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK)); | ||
| 5757 | |||
| 5758 | spin_lock_irq(&ctx->completion_lock); | ||
| 5759 | done: | ||
| 5760 | io_cqring_fill_event(req, ret); | ||
| 5761 | io_commit_cqring(ctx); | ||
| 5762 | spin_unlock_irq(&ctx->completion_lock); | ||
| 5763 | io_cqring_ev_posted(ctx); | ||
| 5764 | |||
| 5765 | if (ret < 0) | ||
| 5766 | req_set_fail_links(req); | ||
| 5767 | io_put_req(req); | ||
| 5644 | return 0; | 5768 | return 0; |
| 5645 | } | 5769 | } |
| 5646 | 5770 | ||
| @@ -5916,18 +6040,8 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags) · 269 unmodified lines | |||
| 5916 | const struct cred *creds = NULL; | 6040 | const struct cred *creds = NULL; |
| 5917 | int ret; | 6041 | int ret; |
| 5918 | 6042 | ||
| 5919 | if (req->work.personality) { | 6043 | if (req->work.creds && req->work.creds != current_cred()) |
| 5920 | const struct cred *new_creds; | 6044 | creds = override_creds(req->work.creds); |
| 5921 | |||
| 5922 | if (!(issue_flags & IO_URING_F_NONBLOCK)) | ||
| 5923 | mutex_lock(&ctx->uring_lock); | ||
| 5924 | new_creds = idr_find(&ctx->personality_idr, req->work.personality); | ||
| 5925 | if (!(issue_flags & IO_URING_F_NONBLOCK)) | ||
| 5926 | mutex_unlock(&ctx->uring_lock); | ||
| 5927 | if (!new_creds) | ||
| 5928 | return -EINVAL; | ||
| 5929 | creds = override_creds(new_creds); | ||
| 5930 | } | ||
| 5931 | 6045 | ||
| 5932 | switch (req->opcode) { | 6046 | switch (req->opcode) { |
| 5933 | case IORING_OP_NOP: | 6047 | case IORING_OP_NOP: |
| @@ -6147,7 +6261,6 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer) · 213 unmodified lines | |||
| 6147 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | 6261 | spin_unlock_irqrestore(&ctx->completion_lock, flags); |
| 6148 | 6262 | ||
| 6149 | if (prev) { | 6263 | if (prev) { |
| 6150 | req_set_fail_links(prev); | ||
| 6151 | io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME); | 6264 | io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME); |
| 6152 | io_put_req_deferred(prev, 1); | 6265 | io_put_req_deferred(prev, 1); |
| 6153 | } else { | 6266 | } else { |
| @@ -6291,7 +6404,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, · 137 unmodified lines | |||
| 6291 | { | 6404 | { |
| 6292 | struct io_submit_state *state; | 6405 | struct io_submit_state *state; |
| 6293 | unsigned int sqe_flags; | 6406 | unsigned int sqe_flags; |
| 6294 | int ret = 0; | 6407 | int personality, ret = 0; |
| 6295 | 6408 | ||
| 6296 | req->opcode = READ_ONCE(sqe->opcode); | 6409 | req->opcode = READ_ONCE(sqe->opcode); |
| 6297 | /* same numerical values with corresponding REQ_F_*, safe to copy */ | 6410 | /* same numerical values with corresponding REQ_F_*, safe to copy */ |
| @@ -6306,6 +6419,9 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, · 8 unmodified lines | |||
| 6306 | refcount_set(&req->refs, 2); | 6419 | refcount_set(&req->refs, 2); |
| 6307 | req->task = current; | 6420 | req->task = current; |
| 6308 | req->result = 0; | 6421 | req->result = 0; |
| 6422 | req->work.list.next = NULL; | ||
| 6423 | req->work.creds = NULL; | ||
| 6424 | req->work.flags = 0; | ||
| 6309 | 6425 | ||
| 6310 | /* enforce forwards compatibility on users */ | 6426 | /* enforce forwards compatibility on users */ |
| 6311 | if (unlikely(sqe_flags & ~SQE_VALID_FLAGS)) { | 6427 | if (unlikely(sqe_flags & ~SQE_VALID_FLAGS)) { |
| @@ -6323,9 +6439,13 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, · 11 unmodified lines | |||
| 6323 | !io_op_defs[req->opcode].buffer_select) | 6439 | !io_op_defs[req->opcode].buffer_select) |
| 6324 | return -EOPNOTSUPP; | 6440 | return -EOPNOTSUPP; |
| 6325 | 6441 | ||
| 6326 | req->work.list.next = NULL; | 6442 | personality = READ_ONCE(sqe->personality); |
| 6327 | req->work.flags = 0; | 6443 | if (personality) { |
| 6328 | req->work.personality = READ_ONCE(sqe->personality); | 6444 | req->work.creds = xa_load(&ctx->personalities, personality); |
| 6445 | if (!req->work.creds) | ||
| 6446 | return -EINVAL; | ||
| 6447 | get_cred(req->work.creds); | ||
| 6448 | } | ||
| 6329 | state = &ctx->submit_state; | 6449 | state = &ctx->submit_state; |
| 6330 | 6450 | ||
| 6331 | /* | 6451 | /* |
| @@ -6587,7 +6707,8 @@ static int __io_sq_thread(struct io_ring_ctx *ctx, bool cap_entries) · 255 unmodified lines | |||
| 6587 | if (!list_empty(&ctx->iopoll_list)) | 6707 | if (!list_empty(&ctx->iopoll_list)) |
| 6588 | io_do_iopoll(ctx, &nr_events, 0); | 6708 | io_do_iopoll(ctx, &nr_events, 0); |
| 6589 | 6709 | ||
| 6590 | if (to_submit && likely(!percpu_ref_is_dying(&ctx->refs))) | 6710 | if (to_submit && likely(!percpu_ref_is_dying(&ctx->refs)) && |
| 6711 | !(ctx->flags & IORING_SETUP_R_DISABLED)) | ||
| 6591 | ret = io_submit_sqes(ctx, to_submit); | 6712 | ret = io_submit_sqes(ctx, to_submit); |
| 6592 | mutex_unlock(&ctx->uring_lock); | 6713 | mutex_unlock(&ctx->uring_lock); |
| 6593 | } | 6714 | } |
| @@ -6611,58 +6732,6 @@ static void io_sqd_update_thread_idle(struct io_sq_data *sqd) · 17 unmodified lines | |||
| 6611 | sqd->sq_thread_idle = sq_thread_idle; | 6732 | sqd->sq_thread_idle = sq_thread_idle; |
| 6612 | } | 6733 | } |
| 6613 | 6734 | ||
| 6614 | static void io_sqd_init_new(struct io_sq_data *sqd) | ||
| 6615 | { | ||
| 6616 | struct io_ring_ctx *ctx; | ||
| 6617 | |||
| 6618 | while (!list_empty(&sqd->ctx_new_list)) { | ||
| 6619 | ctx = list_first_entry(&sqd->ctx_new_list, struct io_ring_ctx, sqd_list); | ||
| 6620 | list_move_tail(&ctx->sqd_list, &sqd->ctx_list); | ||
| 6621 | complete(&ctx->sq_thread_comp); | ||
| 6622 | } | ||
| 6623 | |||
| 6624 | io_sqd_update_thread_idle(sqd); | ||
| 6625 | } | ||
| 6626 | |||
| 6627 | static bool io_sq_thread_should_stop(struct io_sq_data *sqd) | ||
| 6628 | { | ||
| 6629 | return test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); | ||
| 6630 | } | ||
| 6631 | |||
| 6632 | static bool io_sq_thread_should_park(struct io_sq_data *sqd) | ||
| 6633 | { | ||
| 6634 | return test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state); | ||
| 6635 | } | ||
| 6636 | |||
| 6637 | static void io_sq_thread_parkme(struct io_sq_data *sqd) | ||
| 6638 | { | ||
| 6639 | for (;;) { | ||
| 6640 | /* | ||
| 6641 | * TASK_PARKED is a special state; we must serialize against | ||
| 6642 | * possible pending wakeups to avoid store-store collisions on | ||
| 6643 | * task->state. | ||
| 6644 | * | ||
| 6645 | * Such a collision might possibly result in the task state | ||
| 6646 | * changin from TASK_PARKED and us failing the | ||
| 6647 | * wait_task_inactive() in kthread_park(). | ||
| 6648 | */ | ||
| 6649 | set_special_state(TASK_PARKED); | ||
| 6650 | if (!test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state)) | ||
| 6651 | break; | ||
| 6652 | |||
| 6653 | /* | ||
| 6654 | * Thread is going to call schedule(), do not preempt it, | ||
| 6655 | * or the caller of kthread_park() may spend more time in | ||
| 6656 | * wait_task_inactive(). | ||
| 6657 | */ | ||
| 6658 | preempt_disable(); | ||
| 6659 | complete(&sqd->parked); | ||
| 6660 | schedule_preempt_disabled(); | ||
| 6661 | preempt_enable(); | ||
| 6662 | } | ||
| 6663 | __set_current_state(TASK_RUNNING); | ||
| 6664 | } | ||
| 6665 | |||
| 6666 | static int io_sq_thread(void *data) | 6735 | static int io_sq_thread(void *data) |
| 6667 | { | 6736 | { |
| 6668 | struct io_sq_data *sqd = data; | 6737 | struct io_sq_data *sqd = data; |
| @@ -6681,31 +6750,32 @@ static int io_sq_thread(void *data) · 12 unmodified lines | |||
| 6681 | set_cpus_allowed_ptr(current, cpu_online_mask); | 6750 | set_cpus_allowed_ptr(current, cpu_online_mask); |
| 6682 | current->flags |= PF_NO_SETAFFINITY; | 6751 | current->flags |= PF_NO_SETAFFINITY; |
| 6683 | 6752 | ||
| 6684 | wait_for_completion(&sqd->startup); | 6753 | mutex_lock(&sqd->lock); |
| 6685 | 6754 | while (!test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state)) { | |
| 6686 | while (!io_sq_thread_should_stop(sqd)) { | ||
| 6687 | int ret; | 6755 | int ret; |
| 6688 | bool cap_entries, sqt_spin, needs_sched; | 6756 | bool cap_entries, sqt_spin, needs_sched; |
| 6689 | 6757 | ||
| 6690 | /* | 6758 | if (test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state)) { |
| 6691 | * Any changes to the sqd lists are synchronized through the | 6759 | mutex_unlock(&sqd->lock); |
| 6692 | * thread parking. This synchronizes the thread vs users, | 6760 | cond_resched(); |
| 6693 | * the users are synchronized on the sqd->ctx_lock. | 6761 | mutex_lock(&sqd->lock); |
| 6694 | */ | 6762 | io_run_task_work(); |
| 6695 | if (io_sq_thread_should_park(sqd)) { | 6763 | io_run_task_work_head(&sqd->park_task_work); |
| 6696 | io_sq_thread_parkme(sqd); | ||
| 6697 | continue; | ||
| 6698 | } | ||
| 6699 | if (unlikely(!list_empty(&sqd->ctx_new_list))) { | ||
| 6700 | io_sqd_init_new(sqd); | ||
| 6701 | timeout = jiffies + sqd->sq_thread_idle; | 6764 | timeout = jiffies + sqd->sq_thread_idle; |
| 6765 | continue; | ||
| 6702 | } | 6766 | } |
| 6703 | if (fatal_signal_pending(current)) | 6767 | if (fatal_signal_pending(current)) |
| 6704 | break; | 6768 | break; |
| 6705 | sqt_spin = false; | 6769 | sqt_spin = false; |
| 6706 | cap_entries = !list_is_singular(&sqd->ctx_list); | 6770 | cap_entries = !list_is_singular(&sqd->ctx_list); |
| 6707 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { | 6771 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { |
| 6772 | const struct cred *creds = NULL; | ||
| 6773 | |||
| 6774 | if (ctx->sq_creds != current_cred()) | ||
| 6775 | creds = override_creds(ctx->sq_creds); | ||
| 6708 | ret = __io_sq_thread(ctx, cap_entries); | 6776 | ret = __io_sq_thread(ctx, cap_entries); |
| 6777 | if (creds) | ||
| 6778 | revert_creds(creds); | ||
| 6709 | if (!sqt_spin && (ret > 0 || !list_empty(&ctx->iopoll_list))) | 6779 | if (!sqt_spin && (ret > 0 || !list_empty(&ctx->iopoll_list))) |
| 6710 | sqt_spin = true; | 6780 | sqt_spin = true; |
| 6711 | } | 6781 | } |
| @@ -6732,45 +6802,33 @@ static int io_sq_thread(void *data) · 20 unmodified lines | |||
| 6732 | } | 6802 | } |
| 6733 | } | 6803 | } |
| 6734 | 6804 | ||
| 6735 | if (needs_sched && !io_sq_thread_should_park(sqd)) { | 6805 | if (needs_sched && !test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state)) { |
| 6736 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) | 6806 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) |
| 6737 | io_ring_set_wakeup_flag(ctx); | 6807 | io_ring_set_wakeup_flag(ctx); |
| 6738 | 6808 | ||
| 6809 | mutex_unlock(&sqd->lock); | ||
| 6739 | schedule(); | 6810 | schedule(); |
| 6740 | try_to_freeze(); | 6811 | try_to_freeze(); |
| 6812 | mutex_lock(&sqd->lock); | ||
| 6741 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) | 6813 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) |
| 6742 | io_ring_clear_wakeup_flag(ctx); | 6814 | io_ring_clear_wakeup_flag(ctx); |
| 6743 | } | 6815 | } |
| 6744 | 6816 | ||
| 6745 | finish_wait(&sqd->wait, &wait); | 6817 | finish_wait(&sqd->wait, &wait); |
| 6818 | io_run_task_work_head(&sqd->park_task_work); | ||
| 6746 | timeout = jiffies + sqd->sq_thread_idle; | 6819 | timeout = jiffies + sqd->sq_thread_idle; |
| 6747 | } | 6820 | } |
| 6748 | 6821 | ||
| 6749 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) | 6822 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) |
| 6750 | io_uring_cancel_sqpoll(ctx); | 6823 | io_uring_cancel_sqpoll(ctx); |
| 6751 | |||
| 6752 | io_run_task_work(); | ||
| 6753 | |||
| 6754 | /* | ||
| 6755 | * Ensure that we park properly if racing with someone trying to park | ||
| 6756 | * while we're exiting. If we fail to grab the lock, check park and | ||
| 6757 | * park if necessary. The ordering with the park bit and the lock | ||
| 6758 | * ensures that we catch this reliably. | ||
| 6759 | */ | ||
| 6760 | if (!mutex_trylock(&sqd->lock)) { | ||
| 6761 | if (io_sq_thread_should_park(sqd)) | ||
| 6762 | io_sq_thread_parkme(sqd); | ||
| 6763 | mutex_lock(&sqd->lock); | ||
| 6764 | } | ||
| 6765 | |||
| 6766 | sqd->thread = NULL; | 6824 | sqd->thread = NULL; |
| 6767 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { | 6825 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) |
| 6768 | ctx->sqo_exec = 1; | ||
| 6769 | io_ring_set_wakeup_flag(ctx); | 6826 | io_ring_set_wakeup_flag(ctx); |
| 6770 | } | 6827 | mutex_unlock(&sqd->lock); |
| 6771 | 6828 | ||
| 6829 | io_run_task_work(); | ||
| 6830 | io_run_task_work_head(&sqd->park_task_work); | ||
| 6772 | complete(&sqd->exited); | 6831 | complete(&sqd->exited); |
| 6773 | mutex_unlock(&sqd->lock); | ||
| 6774 | do_exit(0); | 6832 | do_exit(0); |
| 6775 | } | 6833 | } |
| 6776 | 6834 | ||
| @@ -7071,47 +7129,47 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx) · 294 unmodified lines | |||
| 7071 | static void io_sq_thread_unpark(struct io_sq_data *sqd) | 7129 | static void io_sq_thread_unpark(struct io_sq_data *sqd) |
| 7072 | __releases(&sqd->lock) | 7130 | __releases(&sqd->lock) |
| 7073 | { | 7131 | { |
| 7074 | if (sqd->thread == current) | 7132 | WARN_ON_ONCE(sqd->thread == current); |
| 7075 | return; | 7133 | |
| 7134 | /* | ||
| 7135 | * Do the dance but not conditional clear_bit() because it'd race with | ||
| 7136 | * other threads incrementing park_pending and setting the bit. | ||
| 7137 | */ | ||
| 7076 | clear_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state); | 7138 | clear_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state); |
| 7077 | if (sqd->thread) | 7139 | if (atomic_dec_return(&sqd->park_pending)) |
| 7078 | wake_up_state(sqd->thread, TASK_PARKED); | 7140 | set_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state); |
| 7079 | mutex_unlock(&sqd->lock); | 7141 | mutex_unlock(&sqd->lock); |
| 7080 | } | 7142 | } |
| 7081 | 7143 | ||
| 7082 | static void io_sq_thread_park(struct io_sq_data *sqd) | 7144 | static void io_sq_thread_park(struct io_sq_data *sqd) |
| 7083 | __acquires(&sqd->lock) | 7145 | __acquires(&sqd->lock) |
| 7084 | { | 7146 | { |
| 7085 | if (sqd->thread == current) | 7147 | WARN_ON_ONCE(sqd->thread == current); |
| 7086 | return; | 7148 | |
| 7149 | atomic_inc(&sqd->park_pending); | ||
| 7087 | set_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state); | 7150 | set_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state); |
| 7088 | mutex_lock(&sqd->lock); | 7151 | mutex_lock(&sqd->lock); |
| 7089 | if (sqd->thread) { | 7152 | if (sqd->thread) |
| 7090 | wake_up_process(sqd->thread); | 7153 | wake_up_process(sqd->thread); |
| 7091 | wait_for_completion(&sqd->parked); | ||
| 7092 | } | ||
| 7093 | } | 7154 | } |
| 7094 | 7155 | ||
| 7095 | static void io_sq_thread_stop(struct io_sq_data *sqd) | 7156 | static void io_sq_thread_stop(struct io_sq_data *sqd) |
| 7096 | { | 7157 | { |
| 7097 | if (test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state)) | 7158 | WARN_ON_ONCE(sqd->thread == current); |
| 7098 | return; | 7159 | |
| 7099 | mutex_lock(&sqd->lock); | 7160 | mutex_lock(&sqd->lock); |
| 7100 | if (sqd->thread) { | 7161 | set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); |
| 7101 | set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); | 7162 | if (sqd->thread) |
| 7102 | WARN_ON_ONCE(test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state)); | ||
| 7103 | wake_up_process(sqd->thread); | 7163 | wake_up_process(sqd->thread); |
| 7104 | mutex_unlock(&sqd->lock); | 7164 | mutex_unlock(&sqd->lock); |
| 7105 | wait_for_completion(&sqd->exited); | 7165 | wait_for_completion(&sqd->exited); |
| 7106 | WARN_ON_ONCE(sqd->thread); | ||
| 7107 | } else { | ||
| 7108 | mutex_unlock(&sqd->lock); | ||
| 7109 | } | ||
| 7110 | } | 7166 | } |
| 7111 | 7167 | ||
| 7112 | static void io_put_sq_data(struct io_sq_data *sqd) | 7168 | static void io_put_sq_data(struct io_sq_data *sqd) |
| 7113 | { | 7169 | { |
| 7114 | if (refcount_dec_and_test(&sqd->refs)) { | 7170 | if (refcount_dec_and_test(&sqd->refs)) { |
| 7171 | WARN_ON_ONCE(atomic_read(&sqd->park_pending)); | ||
| 7172 | |||
| 7115 | io_sq_thread_stop(sqd); | 7173 | io_sq_thread_stop(sqd); |
| 7116 | kfree(sqd); | 7174 | kfree(sqd); |
| 7117 | } | 7175 | } |
| @@ -7122,22 +7180,15 @@ static void io_sq_thread_finish(struct io_ring_ctx *ctx) · 4 unmodified lines | |||
| 7122 | struct io_sq_data *sqd = ctx->sq_data; | 7180 | struct io_sq_data *sqd = ctx->sq_data; |
| 7123 | 7181 | ||
| 7124 | if (sqd) { | 7182 | if (sqd) { |
| 7125 | complete(&sqd->startup); | 7183 | io_sq_thread_park(sqd); |
| 7126 | if (sqd->thread) { | 7184 | list_del_init(&ctx->sqd_list); |
| 7127 | wait_for_completion(&ctx->sq_thread_comp); | ||
| 7128 | io_sq_thread_park(sqd); | ||
| 7129 | } | ||
| 7130 | |||
| 7131 | mutex_lock(&sqd->ctx_lock); | ||
| 7132 | list_del(&ctx->sqd_list); | ||
| 7133 | io_sqd_update_thread_idle(sqd); | 7185 | io_sqd_update_thread_idle(sqd); |
| 7134 | mutex_unlock(&sqd->ctx_lock); | 7186 | io_sq_thread_unpark(sqd); |
| 7135 | |||
| 7136 | if (sqd->thread) | ||
| 7137 | io_sq_thread_unpark(sqd); | ||
| 7138 | 7187 | ||
| 7139 | io_put_sq_data(sqd); | 7188 | io_put_sq_data(sqd); |
| 7140 | ctx->sq_data = NULL; | 7189 | ctx->sq_data = NULL; |
| 7190 | if (ctx->sq_creds) | ||
| 7191 | put_cred(ctx->sq_creds); | ||
| 7141 | } | 7192 | } |
| 7142 | } | 7193 | } |
| 7143 | 7194 | ||
| @@ -7161,31 +7212,42 @@ static struct io_sq_data *io_attach_sq_data(struct io_uring_params *p) · 17 unmodified lines | |||
| 7161 | fdput(f); | 7212 | fdput(f); |
| 7162 | return ERR_PTR(-EINVAL); | 7213 | return ERR_PTR(-EINVAL); |
| 7163 | } | 7214 | } |
| 7215 | if (sqd->task_tgid != current->tgid) { | ||
| 7216 | fdput(f); | ||
| 7217 | return ERR_PTR(-EPERM); | ||
| 7218 | } | ||
| 7164 | 7219 | ||
| 7165 | refcount_inc(&sqd->refs); | 7220 | refcount_inc(&sqd->refs); |
| 7166 | fdput(f); | 7221 | fdput(f); |
| 7167 | return sqd; | 7222 | return sqd; |
| 7168 | } | 7223 | } |
| 7169 | 7224 | ||
| 7170 | static struct io_sq_data *io_get_sq_data(struct io_uring_params *p) | 7225 | static struct io_sq_data *io_get_sq_data(struct io_uring_params *p, |
| 7226 | bool *attached) | ||
| 7171 | { | 7227 | { |
| 7172 | struct io_sq_data *sqd; | 7228 | struct io_sq_data *sqd; |
| 7173 | 7229 | ||
| 7174 | if (p->flags & IORING_SETUP_ATTACH_WQ) | 7230 | *attached = false; |
| 7175 | return io_attach_sq_data(p); | 7231 | if (p->flags & IORING_SETUP_ATTACH_WQ) { |
| 7232 | sqd = io_attach_sq_data(p); | ||
| 7233 | if (!IS_ERR(sqd)) { | ||
| 7234 | *attached = true; | ||
| 7235 | return sqd; | ||
| 7236 | } | ||
| 7237 | /* fall through for EPERM case, setup new sqd/task */ | ||
| 7238 | if (PTR_ERR(sqd) != -EPERM) | ||
| 7239 | return sqd; | ||
| 7240 | } | ||
| 7176 | 7241 | ||
| 7177 | sqd = kzalloc(sizeof(*sqd), GFP_KERNEL); | 7242 | sqd = kzalloc(sizeof(*sqd), GFP_KERNEL); |
| 7178 | if (!sqd) | 7243 | if (!sqd) |
| 7179 | return ERR_PTR(-ENOMEM); | 7244 | return ERR_PTR(-ENOMEM); |
| 7180 | 7245 | ||
| 7246 | atomic_set(&sqd->park_pending, 0); | ||
| 7181 | refcount_set(&sqd->refs, 1); | 7247 | refcount_set(&sqd->refs, 1); |
| 7182 | INIT_LIST_HEAD(&sqd->ctx_list); | 7248 | INIT_LIST_HEAD(&sqd->ctx_list); |
| 7183 | INIT_LIST_HEAD(&sqd->ctx_new_list); | ||
| 7184 | mutex_init(&sqd->ctx_lock); | ||
| 7185 | mutex_init(&sqd->lock); | 7249 | mutex_init(&sqd->lock); |
| 7186 | init_waitqueue_head(&sqd->wait); | 7250 | init_waitqueue_head(&sqd->wait); |
| 7187 | init_completion(&sqd->startup); | ||
| 7188 | init_completion(&sqd->parked); | ||
| 7189 | init_completion(&sqd->exited); | 7251 | init_completion(&sqd->exited); |
| 7190 | return sqd; | 7252 | return sqd; |
| 7191 | } | 7253 | } |
| @@ -7802,7 +7864,6 @@ static int io_uring_alloc_task_context(struct task_struct *task, · 610 unmodified lines | |||
| 7802 | init_waitqueue_head(&tctx->wait); | 7864 | init_waitqueue_head(&tctx->wait); |
| 7803 | tctx->last = NULL; | 7865 | tctx->last = NULL; |
| 7804 | atomic_set(&tctx->in_idle, 0); | 7866 | atomic_set(&tctx->in_idle, 0); |
| 7805 | tctx->sqpoll = false; | ||
| 7806 | task->io_uring = tctx; | 7867 | task->io_uring = tctx; |
| 7807 | spin_lock_init(&tctx->task_lock); | 7868 | spin_lock_init(&tctx->task_lock); |
| 7808 | INIT_WQ_LIST(&tctx->task_list); | 7869 | INIT_WQ_LIST(&tctx->task_list); |
| @@ -7823,26 +7884,6 @@ void __io_uring_free(struct task_struct *tsk) · 14 unmodified lines | |||
| 7823 | tsk->io_uring = NULL; | 7884 | tsk->io_uring = NULL; |
| 7824 | } | 7885 | } |
| 7825 | 7886 | ||
| 7826 | static int io_sq_thread_fork(struct io_sq_data *sqd, struct io_ring_ctx *ctx) | ||
| 7827 | { | ||
| 7828 | struct task_struct *tsk; | ||
| 7829 | int ret; | ||
| 7830 | |||
| 7831 | clear_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); | ||
| 7832 | reinit_completion(&sqd->parked); | ||
| 7833 | ctx->sqo_exec = 0; | ||
| 7834 | sqd->task_pid = current->pid; | ||
| 7835 | tsk = create_io_thread(io_sq_thread, sqd, NUMA_NO_NODE); | ||
| 7836 | if (IS_ERR(tsk)) | ||
| 7837 | return PTR_ERR(tsk); | ||
| 7838 | ret = io_uring_alloc_task_context(tsk, ctx); | ||
| 7839 | if (ret) | ||
| 7840 | set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); | ||
| 7841 | sqd->thread = tsk; | ||
| 7842 | wake_up_new_task(tsk); | ||
| 7843 | return ret; | ||
| 7844 | } | ||
| 7845 | |||
| 7846 | static int io_sq_offload_create(struct io_ring_ctx *ctx, | 7887 | static int io_sq_offload_create(struct io_ring_ctx *ctx, |
| 7847 | struct io_uring_params *p) | 7888 | struct io_uring_params *p) |
| 7848 | { | 7889 | { |
| @@ -7865,29 +7906,36 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, · 16 unmodified lines | |||
| 7865 | if (ctx->flags & IORING_SETUP_SQPOLL) { | 7906 | if (ctx->flags & IORING_SETUP_SQPOLL) { |
| 7866 | struct task_struct *tsk; | 7907 | struct task_struct *tsk; |
| 7867 | struct io_sq_data *sqd; | 7908 | struct io_sq_data *sqd; |
| 7909 | bool attached; | ||
| 7868 | 7910 | ||
| 7869 | ret = -EPERM; | 7911 | ret = -EPERM; |
| 7870 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) | 7912 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) |
| 7871 | goto err; | 7913 | goto err; |
| 7872 | 7914 | ||
| 7873 | sqd = io_get_sq_data(p); | 7915 | sqd = io_get_sq_data(p, &attached); |
| 7874 | if (IS_ERR(sqd)) { | 7916 | if (IS_ERR(sqd)) { |
| 7875 | ret = PTR_ERR(sqd); | 7917 | ret = PTR_ERR(sqd); |
| 7876 | goto err; | 7918 | goto err; |
| 7877 | } | 7919 | } |
| 7878 | 7920 | ||
| 7921 | ctx->sq_creds = get_current_cred(); | ||
| 7879 | ctx->sq_data = sqd; | 7922 | ctx->sq_data = sqd; |
| 7880 | io_sq_thread_park(sqd); | ||
| 7881 | mutex_lock(&sqd->ctx_lock); | ||
| 7882 | list_add(&ctx->sqd_list, &sqd->ctx_new_list); | ||
| 7883 | mutex_unlock(&sqd->ctx_lock); | ||
| 7884 | io_sq_thread_unpark(sqd); | ||
| 7885 | |||
| 7886 | ctx->sq_thread_idle = msecs_to_jiffies(p->sq_thread_idle); | 7923 | ctx->sq_thread_idle = msecs_to_jiffies(p->sq_thread_idle); |
| 7887 | if (!ctx->sq_thread_idle) | 7924 | if (!ctx->sq_thread_idle) |
| 7888 | ctx->sq_thread_idle = HZ; | 7925 | ctx->sq_thread_idle = HZ; |
| 7889 | 7926 | ||
| 7890 | if (sqd->thread) | 7927 | ret = 0; |
| 7928 | io_sq_thread_park(sqd); | ||
| 7929 | list_add(&ctx->sqd_list, &sqd->ctx_list); | ||
| 7930 | io_sqd_update_thread_idle(sqd); | ||
| 7931 | /* don't attach to a dying SQPOLL thread, would be racy */ | ||
| 7932 | if (attached && !sqd->thread) | ||
| 7933 | ret = -ENXIO; | ||
| 7934 | io_sq_thread_unpark(sqd); | ||
| 7935 | |||
| 7936 | if (ret < 0) | ||
| 7937 | goto err; | ||
| 7938 | if (attached) | ||
| 7891 | return 0; | 7939 | return 0; |
| 7892 | 7940 | ||
| 7893 | if (p->flags & IORING_SETUP_SQ_AFF) { | 7941 | if (p->flags & IORING_SETUP_SQ_AFF) { |
| @@ -7895,9 +7943,9 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, · 1 unmodified line | |||
| 7895 | 7943 | ||
| 7896 | ret = -EINVAL; | 7944 | ret = -EINVAL; |
| 7897 | if (cpu >= nr_cpu_ids) | 7945 | if (cpu >= nr_cpu_ids) |
| 7898 | goto err; | 7946 | goto err_sqpoll; |
| 7899 | if (!cpu_online(cpu)) | 7947 | if (!cpu_online(cpu)) |
| 7900 | goto err; | 7948 | goto err_sqpoll; |
| 7901 | 7949 | ||
| 7902 | sqd->sq_cpu = cpu; | 7950 | sqd->sq_cpu = cpu; |
| 7903 | } else { | 7951 | } else { |
| @@ -7905,15 +7953,15 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, · 1 unmodified line | |||
| 7905 | } | 7953 | } |
| 7906 | 7954 | ||
| 7907 | sqd->task_pid = current->pid; | 7955 | sqd->task_pid = current->pid; |
| 7956 | sqd->task_tgid = current->tgid; | ||
| 7908 | tsk = create_io_thread(io_sq_thread, sqd, NUMA_NO_NODE); | 7957 | tsk = create_io_thread(io_sq_thread, sqd, NUMA_NO_NODE); |
| 7909 | if (IS_ERR(tsk)) { | 7958 | if (IS_ERR(tsk)) { |
| 7910 | ret = PTR_ERR(tsk); | 7959 | ret = PTR_ERR(tsk); |
| 7911 | goto err; | 7960 | goto err_sqpoll; |
| 7912 | } | 7961 | } |
| 7913 | ret = io_uring_alloc_task_context(tsk, ctx); | 7962 | |
| 7914 | if (ret) | ||
| 7915 | set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); | ||
| 7916 | sqd->thread = tsk; | 7963 | sqd->thread = tsk; |
| 7964 | ret = io_uring_alloc_task_context(tsk, ctx); | ||
| 7917 | wake_up_new_task(tsk); | 7965 | wake_up_new_task(tsk); |
| 7918 | if (ret) | 7966 | if (ret) |
| 7919 | goto err; | 7967 | goto err; |
| @@ -7927,15 +7975,9 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, · 7 unmodified lines | |||
| 7927 | err: | 7975 | err: |
| 7928 | io_sq_thread_finish(ctx); | 7976 | io_sq_thread_finish(ctx); |
| 7929 | return ret; | 7977 | return ret; |
| 7930 | } | 7978 | err_sqpoll: |
| 7931 | 7979 | complete(&ctx->sq_data->exited); | |
| 7932 | static void io_sq_offload_start(struct io_ring_ctx *ctx) | 7980 | goto err; |
| 7933 | { | ||
| 7934 | struct io_sq_data *sqd = ctx->sq_data; | ||
| 7935 | |||
| 7936 | ctx->flags &= ~IORING_SETUP_R_DISABLED; | ||
| 7937 | if (ctx->flags & IORING_SETUP_SQPOLL) | ||
| 7938 | complete(&sqd->startup); | ||
| 7939 | } | 7981 | } |
| 7940 | 7982 | ||
| 7941 | static inline void __io_unaccount_mem(struct user_struct *user, | 7983 | static inline void __io_unaccount_mem(struct user_struct *user, |
| @@ -8345,19 +8387,13 @@ static int io_eventfd_unregister(struct io_ring_ctx *ctx) · 403 unmodified lines | |||
| 8345 | return -ENXIO; | 8387 | return -ENXIO; |
| 8346 | } | 8388 | } |
| 8347 | 8389 | ||
| 8348 | static int __io_destroy_buffers(int id, void *p, void *data) | ||
| 8349 | { | ||
| 8350 | struct io_ring_ctx *ctx = data; | ||
| 8351 | struct io_buffer *buf = p; | ||
| 8352 | |||
| 8353 | __io_remove_buffers(ctx, buf, id, -1U); | ||
| 8354 | return 0; | ||
| 8355 | } | ||
| 8356 | |||
| 8357 | static void io_destroy_buffers(struct io_ring_ctx *ctx) | 8390 | static void io_destroy_buffers(struct io_ring_ctx *ctx) |
| 8358 | { | 8391 | { |
| 8359 | idr_for_each(&ctx->io_buffer_idr, __io_destroy_buffers, ctx); | 8392 | struct io_buffer *buf; |
| 8360 | idr_destroy(&ctx->io_buffer_idr); | 8393 | unsigned long index; |
| 8394 | |||
| 8395 | xa_for_each(&ctx->io_buffers, index, buf) | ||
| 8396 | __io_remove_buffers(ctx, buf, index, -1U); | ||
| 8361 | } | 8397 | } |
| 8362 | 8398 | ||
| 8363 | static void io_req_cache_free(struct list_head *list, struct task_struct *tsk) | 8399 | static void io_req_cache_free(struct list_head *list, struct task_struct *tsk) |
| @@ -8399,11 +8435,13 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx) · 35 unmodified lines | |||
| 8399 | { | 8435 | { |
| 8400 | /* | 8436 | /* |
| 8401 | * Some may use context even when all refs and requests have been put, | 8437 | * Some may use context even when all refs and requests have been put, |
| 8402 | * and they are free to do so while still holding uring_lock, see | 8438 | * and they are free to do so while still holding uring_lock or |
| 8403 | * __io_req_task_submit(). Wait for them to finish. | 8439 | * completion_lock, see __io_req_task_submit(). Wait for them to finish. |
| 8404 | */ | 8440 | */ |
| 8405 | mutex_lock(&ctx->uring_lock); | 8441 | mutex_lock(&ctx->uring_lock); |
| 8406 | mutex_unlock(&ctx->uring_lock); | 8442 | mutex_unlock(&ctx->uring_lock); |
| 8443 | spin_lock_irq(&ctx->completion_lock); | ||
| 8444 | spin_unlock_irq(&ctx->completion_lock); | ||
| 8407 | 8445 | ||
| 8408 | io_sq_thread_finish(ctx); | 8446 | io_sq_thread_finish(ctx); |
| 8409 | io_sqe_buffers_unregister(ctx); | 8447 | io_sqe_buffers_unregister(ctx); |
| @@ -8418,7 +8456,6 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx) · 8 unmodified lines | |||
| 8418 | mutex_unlock(&ctx->uring_lock); | 8456 | mutex_unlock(&ctx->uring_lock); |
| 8419 | io_eventfd_unregister(ctx); | 8457 | io_eventfd_unregister(ctx); |
| 8420 | io_destroy_buffers(ctx); | 8458 | io_destroy_buffers(ctx); |
| 8421 | idr_destroy(&ctx->personality_idr); | ||
| 8422 | 8459 | ||
| 8423 | #if defined(CONFIG_UNIX) | 8460 | #if defined(CONFIG_UNIX) |
| 8424 | if (ctx->ring_sock) { | 8461 | if (ctx->ring_sock) { |
| @@ -8483,7 +8520,7 @@ static int io_unregister_personality(struct io_ring_ctx *ctx, unsigned id) · 58 unmodified lines | |||
| 8483 | { | 8520 | { |
| 8484 | const struct cred *creds; | 8521 | const struct cred *creds; |
| 8485 | 8522 | ||
| 8486 | creds = idr_remove(&ctx->personality_idr, id); | 8523 | creds = xa_erase(&ctx->personalities, id); |
| 8487 | if (creds) { | 8524 | if (creds) { |
| 8488 | put_cred(creds); | 8525 | put_cred(creds); |
| 8489 | return 0; | 8526 | return 0; |
| @@ -8492,40 +8529,39 @@ static int io_unregister_personality(struct io_ring_ctx *ctx, unsigned id) · 2 unmodified lines | |||
| 8492 | return -EINVAL; | 8529 | return -EINVAL; |
| 8493 | } | 8530 | } |
| 8494 | 8531 | ||
| 8495 | static int io_remove_personalities(int id, void *p, void *data) | 8532 | static inline bool io_run_ctx_fallback(struct io_ring_ctx *ctx) |
| 8496 | { | 8533 | { |
| 8497 | struct io_ring_ctx *ctx = data; | 8534 | return io_run_task_work_head(&ctx->exit_task_work); |
| 8498 | |||
| 8499 | io_unregister_personality(ctx, id); | ||
| 8500 | return 0; | ||
| 8501 | } | 8535 | } |
| 8502 | 8536 | ||
| 8503 | static bool io_run_ctx_fallback(struct io_ring_ctx *ctx) | 8537 | struct io_tctx_exit { |
| 8504 | { | 8538 | struct callback_head task_work; |
| 8505 | struct callback_head *work, *next; | 8539 | struct completion completion; |
| 8506 | bool executed = false; | 8540 | struct io_ring_ctx *ctx; |
| 8507 | 8541 | }; | |
| 8508 | do { | ||
| 8509 | work = xchg(&ctx->exit_task_work, NULL); | ||
| 8510 | if (!work) | ||
| 8511 | break; | ||
| 8512 | 8542 | ||
| 8513 | do { | 8543 | static void io_tctx_exit_cb(struct callback_head *cb) |
| 8514 | next = work->next; | 8544 | { |
| 8515 | work->func(work); | 8545 | struct io_uring_task *tctx = current->io_uring; |
| 8516 | work = next; | 8546 | struct io_tctx_exit *work; |
| 8517 | cond_resched(); | ||
| 8518 | } while (work); | ||
| 8519 | executed = true; | ||
| 8520 | } while (1); | ||
| 8521 | 8547 | ||
| 8522 | return executed; | 8548 | work = container_of(cb, struct io_tctx_exit, task_work); |
| 8549 | /* | ||
| 8550 | * When @in_idle, we're in cancellation and it's racy to remove the | ||
| 8551 | * node. It'll be removed by the end of cancellation, just ignore it. | ||
| 8552 | */ | ||
| 8553 | if (!atomic_read(&tctx->in_idle)) | ||
| 8554 | io_uring_del_task_file((unsigned long)work->ctx); | ||
| 8555 | complete(&work->completion); | ||
| 8523 | } | 8556 | } |
| 8524 | 8557 | ||
| 8525 | static void io_ring_exit_work(struct work_struct *work) | 8558 | static void io_ring_exit_work(struct work_struct *work) |
| 8526 | { | 8559 | { |
| 8527 | struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx, | 8560 | struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx, exit_work); |
| 8528 | exit_work); | 8561 | unsigned long timeout = jiffies + HZ * 60 * 5; |
| 8562 | struct io_tctx_exit exit; | ||
| 8563 | struct io_tctx_node *node; | ||
| 8564 | int ret; | ||
| 8529 | 8565 | ||
| 8530 | /* | 8566 | /* |
| 8531 | * If we're doing polled IO and end up having requests being | 8567 | * If we're doing polled IO and end up having requests being |
| @@ -8535,21 +8571,57 @@ static void io_ring_exit_work(struct work_struct *work) · 3 unmodified lines | |||
| 8535 | */ | 8571 | */ |
| 8536 | do { | 8572 | do { |
| 8537 | io_uring_try_cancel_requests(ctx, NULL, NULL); | 8573 | io_uring_try_cancel_requests(ctx, NULL, NULL); |
| 8574 | |||
| 8575 | WARN_ON_ONCE(time_after(jiffies, timeout)); | ||
| 8538 | } while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20)); | 8576 | } while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20)); |
| 8577 | |||
| 8578 | mutex_lock(&ctx->uring_lock); | ||
| 8579 | while (!list_empty(&ctx->tctx_list)) { | ||
| 8580 | WARN_ON_ONCE(time_after(jiffies, timeout)); | ||
| 8581 | |||
| 8582 | node = list_first_entry(&ctx->tctx_list, struct io_tctx_node, | ||
| 8583 | ctx_node); | ||
| 8584 | exit.ctx = ctx; | ||
| 8585 | init_completion(&exit.completion); | ||
| 8586 | init_task_work(&exit.task_work, io_tctx_exit_cb); | ||
| 8587 | ret = task_work_add(node->task, &exit.task_work, TWA_SIGNAL); | ||
| 8588 | if (WARN_ON_ONCE(ret)) | ||
| 8589 | continue; | ||
| 8590 | wake_up_process(node->task); | ||
| 8591 | |||
| 8592 | mutex_unlock(&ctx->uring_lock); | ||
| 8593 | wait_for_completion(&exit.completion); | ||
| 8594 | cond_resched(); | ||
| 8595 | mutex_lock(&ctx->uring_lock); | ||
| 8596 | } | ||
| 8597 | mutex_unlock(&ctx->uring_lock); | ||
| 8598 | |||
| 8539 | io_ring_ctx_free(ctx); | 8599 | io_ring_ctx_free(ctx); |
| 8540 | } | 8600 | } |
| 8541 | 8601 | ||
| 8542 | static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) | 8602 | static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) |
| 8543 | { | 8603 | { |
| 8604 | unsigned long index; | ||
| 8605 | struct creds *creds; | ||
| 8606 | |||
| 8544 | mutex_lock(&ctx->uring_lock); | 8607 | mutex_lock(&ctx->uring_lock); |
| 8545 | percpu_ref_kill(&ctx->refs); | 8608 | percpu_ref_kill(&ctx->refs); |
| 8546 | /* if force is set, the ring is going away. always drop after that */ | 8609 | /* if force is set, the ring is going away. always drop after that */ |
| 8547 | ctx->cq_overflow_flushed = 1; | 8610 | ctx->cq_overflow_flushed = 1; |
| 8548 | if (ctx->rings) | 8611 | if (ctx->rings) |
| 8549 | __io_cqring_overflow_flush(ctx, true, NULL, NULL); | 8612 | __io_cqring_overflow_flush(ctx, true, NULL, NULL); |
| 8550 | idr_for_each(&ctx->personality_idr, io_remove_personalities, ctx); | 8613 | xa_for_each(&ctx->personalities, index, creds) |
| 8614 | io_unregister_personality(ctx, index); | ||
| 8551 | mutex_unlock(&ctx->uring_lock); | 8615 | mutex_unlock(&ctx->uring_lock); |
| 8552 | 8616 | ||
| 8617 | /* prevent SQPOLL from submitting new requests */ | ||
| 8618 | if (ctx->sq_data) { | ||
| 8619 | io_sq_thread_park(ctx->sq_data); | ||
| 8620 | list_del_init(&ctx->sqd_list); | ||
| 8621 | io_sqd_update_thread_idle(ctx->sq_data); | ||
| 8622 | io_sq_thread_unpark(ctx->sq_data); | ||
| 8623 | } | ||
| 8624 | |||
| 8553 | io_kill_timeouts(ctx, NULL, NULL); | 8625 | io_kill_timeouts(ctx, NULL, NULL); |
| 8554 | io_poll_remove_all(ctx, NULL, NULL); | 8626 | io_poll_remove_all(ctx, NULL, NULL); |
| 8555 | 8627 | ||
| @@ -8600,11 +8672,11 @@ static bool io_cancel_task_cb(struct io_wq_work *work, void *data) · 44 unmodified lines | |||
| 8600 | return ret; | 8672 | return ret; |
| 8601 | } | 8673 | } |
| 8602 | 8674 | ||
| 8603 | static void io_cancel_defer_files(struct io_ring_ctx *ctx, | 8675 | static bool io_cancel_defer_files(struct io_ring_ctx *ctx, |
| 8604 | struct task_struct *task, | 8676 | struct task_struct *task, |
| 8605 | struct files_struct *files) | 8677 | struct files_struct *files) |
| 8606 | { | 8678 | { |
| 8607 | struct io_defer_entry *de = NULL; | 8679 | struct io_defer_entry *de; |
| 8608 | LIST_HEAD(list); | 8680 | LIST_HEAD(list); |
| 8609 | 8681 | ||
| 8610 | spin_lock_irq(&ctx->completion_lock); | 8682 | spin_lock_irq(&ctx->completion_lock); |
| @@ -8615,6 +8687,8 @@ static void io_cancel_defer_files(struct io_ring_ctx *ctx, · 4 unmodified lines | |||
| 8615 | } | 8687 | } |
| 8616 | } | 8688 | } |
| 8617 | spin_unlock_irq(&ctx->completion_lock); | 8689 | spin_unlock_irq(&ctx->completion_lock); |
| 8690 | if (list_empty(&list)) | ||
| 8691 | return false; | ||
| 8618 | 8692 | ||
| 8619 | while (!list_empty(&list)) { | 8693 | while (!list_empty(&list)) { |
| 8620 | de = list_first_entry(&list, struct io_defer_entry, list); | 8694 | de = list_first_entry(&list, struct io_defer_entry, list); |
| @@ -8624,6 +8698,38 @@ static void io_cancel_defer_files(struct io_ring_ctx *ctx, · 3 unmodified lines | |||
| 8624 | io_req_complete(de->req, -ECANCELED); | 8698 | io_req_complete(de->req, -ECANCELED); |
| 8625 | kfree(de); | 8699 | kfree(de); |
| 8626 | } | 8700 | } |
| 8701 | return true; | ||
| 8702 | } | ||
| 8703 | |||
| 8704 | static bool io_cancel_ctx_cb(struct io_wq_work *work, void *data) | ||
| 8705 | { | ||
| 8706 | struct io_kiocb *req = container_of(work, struct io_kiocb, work); | ||
| 8707 | |||
| 8708 | return req->ctx == data; | ||
| 8709 | } | ||
| 8710 | |||
| 8711 | static bool io_uring_try_cancel_iowq(struct io_ring_ctx *ctx) | ||
| 8712 | { | ||
| 8713 | struct io_tctx_node *node; | ||
| 8714 | enum io_wq_cancel cret; | ||
| 8715 | bool ret = false; | ||
| 8716 | |||
| 8717 | mutex_lock(&ctx->uring_lock); | ||
| 8718 | list_for_each_entry(node, &ctx->tctx_list, ctx_node) { | ||
| 8719 | struct io_uring_task *tctx = node->task->io_uring; | ||
| 8720 | |||
| 8721 | /* | ||
| 8722 | * io_wq will stay alive while we hold uring_lock, because it's | ||
| 8723 | * killed after ctx nodes, which requires to take the lock. | ||
| 8724 | */ | ||
| 8725 | if (!tctx || !tctx->io_wq) | ||
| 8726 | continue; | ||
| 8727 | cret = io_wq_cancel_cb(tctx->io_wq, io_cancel_ctx_cb, ctx, true); | ||
| 8728 | ret |= (cret != IO_WQ_CANCEL_NOTFOUND); | ||
| 8729 | } | ||
| 8730 | mutex_unlock(&ctx->uring_lock); | ||
| 8731 | |||
| 8732 | return ret; | ||
| 8627 | } | 8733 | } |
| 8628 | 8734 | ||
| 8629 | static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, | 8735 | static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, |
| @@ -8631,27 +8737,34 @@ static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, · 1 unmodified line | |||
| 8631 | struct files_struct *files) | 8737 | struct files_struct *files) |
| 8632 | { | 8738 | { |
| 8633 | struct io_task_cancel cancel = { .task = task, .files = files, }; | 8739 | struct io_task_cancel cancel = { .task = task, .files = files, }; |
| 8634 | struct task_struct *tctx_task = task ?: current; | 8740 | struct io_uring_task *tctx = task ? task->io_uring : NULL; |
| 8635 | struct io_uring_task *tctx = tctx_task->io_uring; | ||
| 8636 | 8741 | ||
| 8637 | while (1) { | 8742 | while (1) { |
| 8638 | enum io_wq_cancel cret; | 8743 | enum io_wq_cancel cret; |
| 8639 | bool ret = false; | 8744 | bool ret = false; |
| 8640 | 8745 | ||
| 8641 | if (tctx && tctx->io_wq) { | 8746 | if (!task) { |
| 8747 | ret |= io_uring_try_cancel_iowq(ctx); | ||
| 8748 | } else if (tctx && tctx->io_wq) { | ||
| 8749 | /* | ||
| 8750 | * Cancels requests of all rings, not only @ctx, but | ||
| 8751 | * it's fine as the task is in exit/exec. | ||
| 8752 | */ | ||
| 8642 | cret = io_wq_cancel_cb(tctx->io_wq, io_cancel_task_cb, | 8753 | cret = io_wq_cancel_cb(tctx->io_wq, io_cancel_task_cb, |
| 8643 | &cancel, true); | 8754 | &cancel, true); |
| 8644 | ret |= (cret != IO_WQ_CANCEL_NOTFOUND); | 8755 | ret |= (cret != IO_WQ_CANCEL_NOTFOUND); |
| 8645 | } | 8756 | } |
| 8646 | 8757 | ||
| 8647 | /* SQPOLL thread does its own polling */ | 8758 | /* SQPOLL thread does its own polling */ |
| 8648 | if (!(ctx->flags & IORING_SETUP_SQPOLL) && !files) { | 8759 | if ((!(ctx->flags & IORING_SETUP_SQPOLL) && !files) || |
| 8760 | (ctx->sq_data && ctx->sq_data->thread == current)) { | ||
| 8649 | while (!list_empty_careful(&ctx->iopoll_list)) { | 8761 | while (!list_empty_careful(&ctx->iopoll_list)) { |
| 8650 | io_iopoll_try_reap_events(ctx); | 8762 | io_iopoll_try_reap_events(ctx); |
| 8651 | ret = true; | 8763 | ret = true; |
| 8652 | } | 8764 | } |
| 8653 | } | 8765 | } |
| 8654 | 8766 | ||
| 8767 | ret |= io_cancel_defer_files(ctx, task, files); | ||
| 8655 | ret |= io_poll_remove_all(ctx, task, files); | 8768 | ret |= io_poll_remove_all(ctx, task, files); |
| 8656 | ret |= io_kill_timeouts(ctx, task, files); | 8769 | ret |= io_kill_timeouts(ctx, task, files); |
| 8657 | ret |= io_run_task_work(); | 8770 | ret |= io_run_task_work(); |
| @@ -8691,58 +8804,21 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, · 33 unmodified lines | |||
| 8691 | 8804 | ||
| 8692 | io_uring_try_cancel_requests(ctx, task, files); | 8805 | io_uring_try_cancel_requests(ctx, task, files); |
| 8693 | 8806 | ||
| 8694 | if (ctx->sq_data) | ||
| 8695 | io_sq_thread_unpark(ctx->sq_data); | ||
| 8696 | prepare_to_wait(&task->io_uring->wait, &wait, | 8807 | prepare_to_wait(&task->io_uring->wait, &wait, |
| 8697 | TASK_UNINTERRUPTIBLE); | 8808 | TASK_UNINTERRUPTIBLE); |
| 8698 | if (inflight == io_uring_count_inflight(ctx, task, files)) | 8809 | if (inflight == io_uring_count_inflight(ctx, task, files)) |
| 8699 | schedule(); | 8810 | schedule(); |
| 8700 | finish_wait(&task->io_uring->wait, &wait); | 8811 | finish_wait(&task->io_uring->wait, &wait); |
| 8701 | if (ctx->sq_data) | ||
| 8702 | io_sq_thread_park(ctx->sq_data); | ||
| 8703 | } | ||
| 8704 | } | ||
| 8705 | |||
| 8706 | /* | ||
| 8707 | * We need to iteratively cancel requests, in case a request has dependent | ||
| 8708 | * hard links. These persist even for failure of cancelations, hence keep | ||
| 8709 | * looping until none are found. | ||
| 8710 | */ | ||
| 8711 | static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, | ||
| 8712 | struct files_struct *files) | ||
| 8713 | { | ||
| 8714 | struct task_struct *task = current; | ||
| 8715 | |||
| 8716 | if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { | ||
| 8717 | /* never started, nothing to cancel */ | ||
| 8718 | if (ctx->flags & IORING_SETUP_R_DISABLED) { | ||
| 8719 | io_sq_offload_start(ctx); | ||
| 8720 | return; | ||
| 8721 | } | ||
| 8722 | io_sq_thread_park(ctx->sq_data); | ||
| 8723 | task = ctx->sq_data->thread; | ||
| 8724 | if (task) | ||
| 8725 | atomic_inc(&task->io_uring->in_idle); | ||
| 8726 | } | 8812 | } |
| 8727 | |||
| 8728 | io_cancel_defer_files(ctx, task, files); | ||
| 8729 | |||
| 8730 | io_uring_cancel_files(ctx, task, files); | ||
| 8731 | if (!files) | ||
| 8732 | io_uring_try_cancel_requests(ctx, task, NULL); | ||
| 8733 | |||
| 8734 | if (task) | ||
| 8735 | atomic_dec(&task->io_uring->in_idle); | ||
| 8736 | if (ctx->sq_data) | ||
| 8737 | io_sq_thread_unpark(ctx->sq_data); | ||
| 8738 | } | 8813 | } |
| 8739 | 8814 | ||
| 8740 | /* | 8815 | /* |
| 8741 | * Note that this task has used io_uring. We use it for cancelation purposes. | 8816 | * Note that this task has used io_uring. We use it for cancelation purposes. |
| 8742 | */ | 8817 | */ |
| 8743 | static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file) | 8818 | static int io_uring_add_task_file(struct io_ring_ctx *ctx) |
| 8744 | { | 8819 | { |
| 8745 | struct io_uring_task *tctx = current->io_uring; | 8820 | struct io_uring_task *tctx = current->io_uring; |
| 8821 | struct io_tctx_node *node; | ||
| 8746 | int ret; | 8822 | int ret; |
| 8747 | 8823 | ||
| 8748 | if (unlikely(!tctx)) { | 8824 | if (unlikely(!tctx)) { |
| @@ -8751,102 +8827,151 @@ static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file) · 2 unmodified lines | |||
| 8751 | return ret; | 8827 | return ret; |
| 8752 | tctx = current->io_uring; | 8828 | tctx = current->io_uring; |
| 8753 | } | 8829 | } |
| 8754 | if (tctx->last != file) { | 8830 | if (tctx->last != ctx) { |
| 8755 | void *old = xa_load(&tctx->xa, (unsigned long)file); | 8831 | void *old = xa_load(&tctx->xa, (unsigned long)ctx); |
| 8756 | 8832 | ||
| 8757 | if (!old) { | 8833 | if (!old) { |
| 8758 | get_file(file); | 8834 | node = kmalloc(sizeof(*node), GFP_KERNEL); |
| 8759 | ret = xa_err(xa_store(&tctx->xa, (unsigned long)file, | 8835 | if (!node) |
| 8760 | file, GFP_KERNEL)); | 8836 | return -ENOMEM; |
| 8837 | node->ctx = ctx; | ||
| 8838 | node->task = current; | ||
| 8839 | |||
| 8840 | ret = xa_err(xa_store(&tctx->xa, (unsigned long)ctx, | ||
| 8841 | node, GFP_KERNEL)); | ||
| 8761 | if (ret) { | 8842 | if (ret) { |
| 8762 | fput(file); | 8843 | kfree(node); |
| 8763 | return ret; | 8844 | return ret; |
| 8764 | } | 8845 | } |
| 8846 | |||
| 8847 | mutex_lock(&ctx->uring_lock); | ||
| 8848 | list_add(&node->ctx_node, &ctx->tctx_list); | ||
| 8849 | mutex_unlock(&ctx->uring_lock); | ||
| 8765 | } | 8850 | } |
| 8766 | tctx->last = file; | 8851 | tctx->last = ctx; |
| 8767 | } | 8852 | } |
| 8768 | |||
| 8769 | /* | ||
| 8770 | * This is race safe in that the task itself is doing this, hence it | ||
| 8771 | * cannot be going through the exit/cancel paths at the same time. | ||
| 8772 | * This cannot be modified while exit/cancel is running. | ||
| 8773 | */ | ||
| 8774 | if (!tctx->sqpoll && (ctx->flags & IORING_SETUP_SQPOLL)) | ||
| 8775 | tctx->sqpoll = true; | ||
| 8776 | |||
| 8777 | return 0; | 8853 | return 0; |
| 8778 | } | 8854 | } |
| 8779 | 8855 | ||
| 8780 | /* | 8856 | /* |
| 8781 | * Remove this io_uring_file -> task mapping. | 8857 | * Remove this io_uring_file -> task mapping. |
| 8782 | */ | 8858 | */ |
| 8783 | static void io_uring_del_task_file(struct file *file) | 8859 | static void io_uring_del_task_file(unsigned long index) |
| 8784 | { | 8860 | { |
| 8785 | struct io_uring_task *tctx = current->io_uring; | 8861 | struct io_uring_task *tctx = current->io_uring; |
| 8862 | struct io_tctx_node *node; | ||
| 8863 | |||
| 8864 | if (!tctx) | ||
| 8865 | return; | ||
| 8866 | node = xa_erase(&tctx->xa, index); | ||
| 8867 | if (!node) | ||
| 8868 | return; | ||
| 8869 | |||
| 8870 | WARN_ON_ONCE(current != node->task); | ||
| 8871 | WARN_ON_ONCE(list_empty(&node->ctx_node)); | ||
| 8872 | |||
| 8873 | mutex_lock(&node->ctx->uring_lock); | ||
| 8874 | list_del(&node->ctx_node); | ||
| 8875 | mutex_unlock(&node->ctx->uring_lock); | ||
| 8786 | 8876 | ||
| 8787 | if (tctx->last == file) | 8877 | if (tctx->last == node->ctx) |
| 8788 | tctx->last = NULL; | 8878 | tctx->last = NULL; |
| 8789 | file = xa_erase(&tctx->xa, (unsigned long)file); | 8879 | kfree(node); |
| 8790 | if (file) | ||
| 8791 | fput(file); | ||
| 8792 | } | 8880 | } |
| 8793 | 8881 | ||
| 8794 | static void io_uring_clean_tctx(struct io_uring_task *tctx) | 8882 | static void io_uring_clean_tctx(struct io_uring_task *tctx) |
| 8795 | { | 8883 | { |
| 8796 | struct file *file; | 8884 | struct io_tctx_node *node; |
| 8797 | unsigned long index; | 8885 | unsigned long index; |
| 8798 | 8886 | ||
| 8799 | xa_for_each(&tctx->xa, index, file) | 8887 | xa_for_each(&tctx->xa, index, node) |
| 8800 | io_uring_del_task_file(file); | 8888 | io_uring_del_task_file(index); |
| 8801 | if (tctx->io_wq) { | 8889 | if (tctx->io_wq) { |
| 8802 | io_wq_put_and_exit(tctx->io_wq); | 8890 | io_wq_put_and_exit(tctx->io_wq); |
| 8803 | tctx->io_wq = NULL; | 8891 | tctx->io_wq = NULL; |
| 8804 | } | 8892 | } |
| 8805 | } | 8893 | } |
| 8806 | 8894 | ||
| 8895 | static s64 tctx_inflight(struct io_uring_task *tctx) | ||
| 8896 | { | ||
| 8897 | return percpu_counter_sum(&tctx->inflight); | ||
| 8898 | } | ||
| 8899 | |||
| 8900 | static void io_sqpoll_cancel_cb(struct callback_head *cb) | ||
| 8901 | { | ||
| 8902 | struct io_tctx_exit *work = container_of(cb, struct io_tctx_exit, task_work); | ||
| 8903 | struct io_ring_ctx *ctx = work->ctx; | ||
| 8904 | struct io_sq_data *sqd = ctx->sq_data; | ||
| 8905 | |||
| 8906 | if (sqd->thread) | ||
| 8907 | io_uring_cancel_sqpoll(ctx); | ||
| 8908 | complete(&work->completion); | ||
| 8909 | } | ||
| 8910 | |||
| 8911 | static void io_sqpoll_cancel_sync(struct io_ring_ctx *ctx) | ||
| 8912 | { | ||
| 8913 | struct io_sq_data *sqd = ctx->sq_data; | ||
| 8914 | struct io_tctx_exit work = { .ctx = ctx, }; | ||
| 8915 | struct task_struct *task; | ||
| 8916 | |||
| 8917 | io_sq_thread_park(sqd); | ||
| 8918 | list_del_init(&ctx->sqd_list); | ||
| 8919 | io_sqd_update_thread_idle(sqd); | ||
| 8920 | task = sqd->thread; | ||
| 8921 | if (task) { | ||
| 8922 | init_completion(&work.completion); | ||
| 8923 | init_task_work(&work.task_work, io_sqpoll_cancel_cb); | ||
| 8924 | io_task_work_add_head(&sqd->park_task_work, &work.task_work); | ||
| 8925 | wake_up_process(task); | ||
| 8926 | } | ||
| 8927 | io_sq_thread_unpark(sqd); | ||
| 8928 | |||
| 8929 | if (task) | ||
| 8930 | wait_for_completion(&work.completion); | ||
| 8931 | } | ||
| 8932 | |||
| 8807 | void __io_uring_files_cancel(struct files_struct *files) | 8933 | void __io_uring_files_cancel(struct files_struct *files) |
| 8808 | { | 8934 | { |
| 8809 | struct io_uring_task *tctx = current->io_uring; | 8935 | struct io_uring_task *tctx = current->io_uring; |
| 8810 | struct file *file; | 8936 | struct io_tctx_node *node; |
| 8811 | unsigned long index; | 8937 | unsigned long index; |
| 8812 | 8938 | ||
| 8813 | /* make sure overflow events are dropped */ | 8939 | /* make sure overflow events are dropped */ |
| 8814 | atomic_inc(&tctx->in_idle); | 8940 | atomic_inc(&tctx->in_idle); |
| 8815 | xa_for_each(&tctx->xa, index, file) | 8941 | xa_for_each(&tctx->xa, index, node) { |
| 8816 | io_uring_cancel_task_requests(file->private_data, files); | 8942 | struct io_ring_ctx *ctx = node->ctx; |
| 8943 | |||
| 8944 | if (ctx->sq_data) { | ||
| 8945 | io_sqpoll_cancel_sync(ctx); | ||
| 8946 | continue; | ||
| 8947 | } | ||
| 8948 | io_uring_cancel_files(ctx, current, files); | ||
| 8949 | if (!files) | ||
| 8950 | io_uring_try_cancel_requests(ctx, current, NULL); | ||
| 8951 | } | ||
| 8817 | atomic_dec(&tctx->in_idle); | 8952 | atomic_dec(&tctx->in_idle); |
| 8818 | 8953 | ||
| 8819 | if (files) | 8954 | if (files) |
| 8820 | io_uring_clean_tctx(tctx); | 8955 | io_uring_clean_tctx(tctx); |
| 8821 | } | 8956 | } |
| 8822 | 8957 | ||
| 8823 | static s64 tctx_inflight(struct io_uring_task *tctx) | 8958 | /* should only be called by SQPOLL task */ |
| 8824 | { | ||
| 8825 | return percpu_counter_sum(&tctx->inflight); | ||
| 8826 | } | ||
| 8827 | |||
| 8828 | static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx) | 8959 | static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx) |
| 8829 | { | 8960 | { |
| 8830 | struct io_sq_data *sqd = ctx->sq_data; | 8961 | struct io_sq_data *sqd = ctx->sq_data; |
| 8831 | struct io_uring_task *tctx; | 8962 | struct io_uring_task *tctx = current->io_uring; |
| 8832 | s64 inflight; | 8963 | s64 inflight; |
| 8833 | DEFINE_WAIT(wait); | 8964 | DEFINE_WAIT(wait); |
| 8834 | 8965 | ||
| 8835 | if (!sqd) | 8966 | WARN_ON_ONCE(!sqd || ctx->sq_data->thread != current); |
| 8836 | return; | 8967 | |
| 8837 | io_sq_thread_park(sqd); | ||
| 8838 | if (!sqd->thread || !sqd->thread->io_uring) { | ||
| 8839 | io_sq_thread_unpark(sqd); | ||
| 8840 | return; | ||
| 8841 | } | ||
| 8842 | tctx = ctx->sq_data->thread->io_uring; | ||
| 8843 | atomic_inc(&tctx->in_idle); | 8968 | atomic_inc(&tctx->in_idle); |
| 8844 | do { | 8969 | do { |
| 8845 | /* read completions before cancelations */ | 8970 | /* read completions before cancelations */ |
| 8846 | inflight = tctx_inflight(tctx); | 8971 | inflight = tctx_inflight(tctx); |
| 8847 | if (!inflight) | 8972 | if (!inflight) |
| 8848 | break; | 8973 | break; |
| 8849 | io_uring_cancel_task_requests(ctx, NULL); | 8974 | io_uring_try_cancel_requests(ctx, current, NULL); |
| 8850 | 8975 | ||
| 8851 | prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE); | 8976 | prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE); |
| 8852 | /* | 8977 | /* |
| @@ -8859,7 +8984,6 @@ static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx) · 6 unmodified lines | |||
| 8859 | finish_wait(&tctx->wait, &wait); | 8984 | finish_wait(&tctx->wait, &wait); |
| 8860 | } while (1); | 8985 | } while (1); |
| 8861 | atomic_dec(&tctx->in_idle); | 8986 | atomic_dec(&tctx->in_idle); |
| 8862 | io_sq_thread_unpark(sqd); | ||
| 8863 | } | 8987 | } |
| 8864 | 8988 | ||
| 8865 | /* | 8989 | /* |
| @@ -8874,15 +8998,6 @@ void __io_uring_task_cancel(void) · 8 unmodified lines | |||
| 8874 | 8998 | ||
| 8875 | /* make sure overflow events are dropped */ | 8999 | /* make sure overflow events are dropped */ |
| 8876 | atomic_inc(&tctx->in_idle); | 9000 | atomic_inc(&tctx->in_idle); |
| 8877 | |||
| 8878 | if (tctx->sqpoll) { | ||
| 8879 | struct file *file; | ||
| 8880 | unsigned long index; | ||
| 8881 | |||
| 8882 | xa_for_each(&tctx->xa, index, file) | ||
| 8883 | io_uring_cancel_sqpoll(file->private_data); | ||
| 8884 | } | ||
| 8885 | |||
| 8886 | do { | 9001 | do { |
| 8887 | /* read completions before cancelations */ | 9002 | /* read completions before cancelations */ |
| 8888 | inflight = tctx_inflight(tctx); | 9003 | inflight = tctx_inflight(tctx); |
| @@ -8981,7 +9096,6 @@ static unsigned long io_uring_nommu_get_unmapped_area(struct file *file, · 92 unmodified lines | |||
| 8981 | 9096 | ||
| 8982 | static int io_sqpoll_wait_sq(struct io_ring_ctx *ctx) | 9097 | static int io_sqpoll_wait_sq(struct io_ring_ctx *ctx) |
| 8983 | { | 9098 | { |
| 8984 | int ret = 0; | ||
| 8985 | DEFINE_WAIT(wait); | 9099 | DEFINE_WAIT(wait); |
| 8986 | 9100 | ||
| 8987 | do { | 9101 | do { |
| @@ -8995,7 +9109,7 @@ static int io_sqpoll_wait_sq(struct io_ring_ctx *ctx) · 7 unmodified lines | |||
| 8995 | } while (!signal_pending(current)); | 9109 | } while (!signal_pending(current)); |
| 8996 | 9110 | ||
| 8997 | finish_wait(&ctx->sqo_sq_wait, &wait); | 9111 | finish_wait(&ctx->sqo_sq_wait, &wait); |
| 8998 | return ret; | 9112 | return 0; |
| 8999 | } | 9113 | } |
| 9000 | 9114 | ||
| 9001 | static int io_get_ext_arg(unsigned flags, const void __user *argp, size_t *argsz, | 9115 | static int io_get_ext_arg(unsigned flags, const void __user *argp, size_t *argsz, |
| @@ -9069,13 +9183,10 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, · 67 unmodified lines | |||
| 9069 | if (ctx->flags & IORING_SETUP_SQPOLL) { | 9183 | if (ctx->flags & IORING_SETUP_SQPOLL) { |
| 9070 | io_cqring_overflow_flush(ctx, false, NULL, NULL); | 9184 | io_cqring_overflow_flush(ctx, false, NULL, NULL); |
| 9071 | 9185 | ||
| 9072 | if (unlikely(ctx->sqo_exec)) { | ||
| 9073 | ret = io_sq_thread_fork(ctx->sq_data, ctx); | ||
| 9074 | if (ret) | ||
| 9075 | goto out; | ||
| 9076 | ctx->sqo_exec = 0; | ||
| 9077 | } | ||
| 9078 | ret = -EOWNERDEAD; | 9186 | ret = -EOWNERDEAD; |
| 9187 | if (unlikely(ctx->sq_data->thread == NULL)) { | ||
| 9188 | goto out; | ||
| 9189 | } | ||
| 9079 | if (flags & IORING_ENTER_SQ_WAKEUP) | 9190 | if (flags & IORING_ENTER_SQ_WAKEUP) |
| 9080 | wake_up(&ctx->sq_data->wait); | 9191 | wake_up(&ctx->sq_data->wait); |
| 9081 | if (flags & IORING_ENTER_SQ_WAIT) { | 9192 | if (flags & IORING_ENTER_SQ_WAIT) { |
| @@ -9085,7 +9196,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, · 3 unmodified lines | |||
| 9085 | } | 9196 | } |
| 9086 | submitted = to_submit; | 9197 | submitted = to_submit; |
| 9087 | } else if (to_submit) { | 9198 | } else if (to_submit) { |
| 9088 | ret = io_uring_add_task_file(ctx, f.file); | 9199 | ret = io_uring_add_task_file(ctx); |
| 9089 | if (unlikely(ret)) | 9200 | if (unlikely(ret)) |
| 9090 | goto out; | 9201 | goto out; |
| 9091 | mutex_lock(&ctx->uring_lock); | 9202 | mutex_lock(&ctx->uring_lock); |
| @@ -9127,10 +9238,9 @@ out_fput: · 35 unmodified lines | |||
| 9127 | } | 9238 | } |
| 9128 | 9239 | ||
| 9129 | #ifdef CONFIG_PROC_FS | 9240 | #ifdef CONFIG_PROC_FS |
| 9130 | static int io_uring_show_cred(int id, void *p, void *data) | 9241 | static int io_uring_show_cred(struct seq_file *m, unsigned int id, |
| 9242 | const struct cred *cred) | ||
| 9131 | { | 9243 | { |
| 9132 | const struct cred *cred = p; | ||
| 9133 | struct seq_file *m = data; | ||
| 9134 | struct user_namespace *uns = seq_user_ns(m); | 9244 | struct user_namespace *uns = seq_user_ns(m); |
| 9135 | struct group_info *gi; | 9245 | struct group_info *gi; |
| 9136 | kernel_cap_t cap; | 9246 | kernel_cap_t cap; |
| @@ -9198,9 +9308,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) · 61 unmodified lines | |||
| 9198 | seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf, | 9308 | seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf, |
| 9199 | (unsigned int) buf->len); | 9309 | (unsigned int) buf->len); |
| 9200 | } | 9310 | } |
| 9201 | if (has_lock && !idr_is_empty(&ctx->personality_idr)) { | 9311 | if (has_lock && !xa_empty(&ctx->personalities)) { |
| 9312 | unsigned long index; | ||
| 9313 | const struct cred *cred; | ||
| 9314 | |||
| 9202 | seq_printf(m, "Personalities:\n"); | 9315 | seq_printf(m, "Personalities:\n"); |
| 9203 | idr_for_each(&ctx->personality_idr, io_uring_show_cred, m); | 9316 | xa_for_each(&ctx->personalities, index, cred) |
| 9317 | io_uring_show_cred(m, index, cred); | ||
| 9204 | } | 9318 | } |
| 9205 | seq_printf(m, "PollList:\n"); | 9319 | seq_printf(m, "PollList:\n"); |
| 9206 | spin_lock_irq(&ctx->completion_lock); | 9320 | spin_lock_irq(&ctx->completion_lock); |
| @@ -9294,7 +9408,7 @@ static int io_uring_install_fd(struct io_ring_ctx *ctx, struct file *file) · 87 unmodified lines | |||
| 9294 | if (fd < 0) | 9408 | if (fd < 0) |
| 9295 | return fd; | 9409 | return fd; |
| 9296 | 9410 | ||
| 9297 | ret = io_uring_add_task_file(ctx, file); | 9411 | ret = io_uring_add_task_file(ctx); |
| 9298 | if (ret) { | 9412 | if (ret) { |
| 9299 | put_unused_fd(fd); | 9413 | put_unused_fd(fd); |
| 9300 | return ret; | 9414 | return ret; |
| @@ -9402,9 +9516,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p, · 101 unmodified lines | |||
| 9402 | if (ret) | 9516 | if (ret) |
| 9403 | goto err; | 9517 | goto err; |
| 9404 | 9518 | ||
| 9405 | if (!(p->flags & IORING_SETUP_R_DISABLED)) | ||
| 9406 | io_sq_offload_start(ctx); | ||
| 9407 | |||
| 9408 | memset(&p->sq_off, 0, sizeof(p->sq_off)); | 9519 | memset(&p->sq_off, 0, sizeof(p->sq_off)); |
| 9409 | p->sq_off.head = offsetof(struct io_rings, sq.head); | 9520 | p->sq_off.head = offsetof(struct io_rings, sq.head); |
| 9410 | p->sq_off.tail = offsetof(struct io_rings, sq.tail); | 9521 | p->sq_off.tail = offsetof(struct io_rings, sq.tail); |
| @@ -9532,14 +9643,16 @@ out: · 121 unmodified lines | |||
| 9532 | static int io_register_personality(struct io_ring_ctx *ctx) | 9643 | static int io_register_personality(struct io_ring_ctx *ctx) |
| 9533 | { | 9644 | { |
| 9534 | const struct cred *creds; | 9645 | const struct cred *creds; |
| 9646 | u32 id; | ||
| 9535 | int ret; | 9647 | int ret; |
| 9536 | 9648 | ||
| 9537 | creds = get_current_cred(); | 9649 | creds = get_current_cred(); |
| 9538 | 9650 | ||
| 9539 | ret = idr_alloc_cyclic(&ctx->personality_idr, (void *) creds, 1, | 9651 | ret = xa_alloc_cyclic(&ctx->personalities, &id, (void *)creds, |
| 9540 | USHRT_MAX, GFP_KERNEL); | 9652 | XA_LIMIT(0, USHRT_MAX), &ctx->pers_next, GFP_KERNEL); |
| 9541 | if (ret < 0) | 9653 | if (!ret) |
| 9542 | put_cred(creds); | 9654 | return id; |
| 9655 | put_cred(creds); | ||
| 9543 | return ret; | 9656 | return ret; |
| 9544 | } | 9657 | } |
| 9545 | 9658 | ||
| @@ -9621,7 +9734,9 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx) · 75 unmodified lines | |||
| 9621 | if (ctx->restrictions.registered) | 9734 | if (ctx->restrictions.registered) |
| 9622 | ctx->restricted = 1; | 9735 | ctx->restricted = 1; |
| 9623 | 9736 | ||
| 9624 | io_sq_offload_start(ctx); | 9737 | ctx->flags &= ~IORING_SETUP_R_DISABLED; |
| 9738 | if (ctx->sq_data && wq_has_sleeper(&ctx->sq_data->wait)) | ||
| 9739 | wake_up(&ctx->sq_data->wait); | ||
| 9625 | return 0; | 9740 | return 0; |
| 9626 | } | 9741 | } |
| 9627 | 9742 | ||
| @@ -1221,7 +1221,7 @@ iomap_alloc_ioend(struct inode *inode, struct iomap_writepage_ctx *wpc, · 1220 unmodified lines | |||
| 1221 | struct iomap_ioend *ioend; | 1221 | struct iomap_ioend *ioend; |
| 1222 | struct bio *bio; | 1222 | struct bio *bio; |
| 1223 | 1223 | ||
| 1224 | bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, &iomap_ioend_bioset); | 1224 | bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_VECS, &iomap_ioend_bioset); |
| 1225 | bio_set_dev(bio, wpc->iomap.bdev); | 1225 | bio_set_dev(bio, wpc->iomap.bdev); |
| 1226 | bio->bi_iter.bi_sector = sector; | 1226 | bio->bi_iter.bi_sector = sector; |
| 1227 | bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc); | 1227 | bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc); |
| @@ -1252,7 +1252,7 @@ iomap_chain_bio(struct bio *prev) · 24 unmodified lines | |||
| 1252 | { | 1252 | { |
| 1253 | struct bio *new; | 1253 | struct bio *new; |
| 1254 | 1254 | ||
| 1255 | new = bio_alloc(GFP_NOFS, BIO_MAX_PAGES); | 1255 | new = bio_alloc(GFP_NOFS, BIO_MAX_VECS); |
| 1256 | bio_copy_dev(new, prev);/* also copies over blkcg information */ | 1256 | bio_copy_dev(new, prev);/* also copies over blkcg information */ |
| 1257 | new->bi_iter.bi_sector = bio_end_sector(prev); | 1257 | new->bi_iter.bi_sector = bio_end_sector(prev); |
| 1258 | new->bi_opf = prev->bi_opf; | 1258 | new->bi_opf = prev->bi_opf; |
| @@ -296,7 +296,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, · 295 unmodified lines | |||
| 296 | */ | 296 | */ |
| 297 | bio_opf = iomap_dio_bio_opflags(dio, iomap, use_fua); | 297 | bio_opf = iomap_dio_bio_opflags(dio, iomap, use_fua); |
| 298 | 298 | ||
| 299 | nr_pages = bio_iov_vecs_to_alloc(dio->submit.iter, BIO_MAX_PAGES); | 299 | nr_pages = bio_iov_vecs_to_alloc(dio->submit.iter, BIO_MAX_VECS); |
| 300 | do { | 300 | do { |
| 301 | size_t n; | 301 | size_t n; |
| 302 | if (dio->error) { | 302 | if (dio->error) { |
| @@ -338,7 +338,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, · 35 unmodified lines | |||
| 338 | copied += n; | 338 | copied += n; |
| 339 | 339 | ||
| 340 | nr_pages = bio_iov_vecs_to_alloc(dio->submit.iter, | 340 | nr_pages = bio_iov_vecs_to_alloc(dio->submit.iter, |
| 341 | BIO_MAX_PAGES); | 341 | BIO_MAX_VECS); |
| 342 | iomap_dio_submit_bio(dio, iomap, bio, pos); | 342 | iomap_dio_submit_bio(dio, iomap, bio, pos); |
| 343 | pos += n; | 343 | pos += n; |
| 344 | } while (nr_pages); | 344 | } while (nr_pages); |
| @@ -170,6 +170,16 @@ int iomap_swapfile_activate(struct swap_info_struct *sis, · 169 unmodified lines | |||
| 170 | return ret; | 170 | return ret; |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /* | ||
| 174 | * If this swapfile doesn't contain even a single page-aligned | ||
| 175 | * contiguous range of blocks, reject this useless swapfile to | ||
| 176 | * prevent confusion later on. | ||
| 177 | */ | ||
| 178 | if (isi.nr_pages == 0) { | ||
| 179 | pr_warn("swapon: Cannot find a single usable page in file.\n"); | ||
| 180 | return -EINVAL; | ||
| 181 | } | ||
| 182 | |||
| 173 | *pagespan = 1 + isi.highest_ppage - isi.lowest_ppage; | 183 | *pagespan = 1 + isi.highest_ppage - isi.lowest_ppage; |
| 174 | sis->max = isi.nr_pages; | 184 | sis->max = isi.nr_pages; |
| 175 | sis->pages = isi.nr_pages - 1; | 185 | sis->pages = isi.nr_pages - 1; |
| @@ -1808,9 +1808,6 @@ check_conflicting_open(struct file *filp, const long arg, int flags) · 1807 unmodified lines | |||
| 1808 | 1808 | ||
| 1809 | if (flags & FL_LAYOUT) | 1809 | if (flags & FL_LAYOUT) |
| 1810 | return 0; | 1810 | return 0; |
| 1811 | if (flags & FL_DELEG) | ||
| 1812 | /* We leave these checks to the caller. */ | ||
| 1813 | return 0; | ||
| 1814 | 1811 | ||
| 1815 | if (arg == F_RDLCK) | 1812 | if (arg == F_RDLCK) |
| 1816 | return inode_is_open_for_write(inode) ? -EAGAIN : 0; | 1813 | return inode_is_open_for_write(inode) ? -EAGAIN : 0; |
| @@ -616,7 +616,7 @@ alloc_new: · 615 unmodified lines | |||
| 616 | goto out; | 616 | goto out; |
| 617 | } | 617 | } |
| 618 | bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9), | 618 | bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9), |
| 619 | BIO_MAX_PAGES, GFP_NOFS|__GFP_HIGH); | 619 | BIO_MAX_VECS, GFP_NOFS|__GFP_HIGH); |
| 620 | if (bio == NULL) | 620 | if (bio == NULL) |
| 621 | goto confused; | 621 | goto confused; |
| 622 | 622 | ||
| @@ -127,7 +127,7 @@ config PNFS_BLOCK · 126 unmodified lines | |||
| 127 | config PNFS_FLEXFILE_LAYOUT | 127 | config PNFS_FLEXFILE_LAYOUT |
| 128 | tristate | 128 | tristate |
| 129 | depends on NFS_V4_1 && NFS_V3 | 129 | depends on NFS_V4_1 && NFS_V3 |
| 130 | default m | 130 | default NFS_V4 |
| 131 | 131 | ||
| 132 | config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN | 132 | config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN |
| 133 | string "NFSv4.1 Implementation ID Domain" | 133 | string "NFSv4.1 Implementation ID Domain" |
| @@ -81,8 +81,9 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir · 80 unmodified lines | |||
| 81 | spin_lock(&dir->i_lock); | 81 | spin_lock(&dir->i_lock); |
| 82 | if (list_empty(&nfsi->open_files) && | 82 | if (list_empty(&nfsi->open_files) && |
| 83 | (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) | 83 | (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) |
| 84 | nfsi->cache_validity |= NFS_INO_INVALID_DATA | | 84 | nfs_set_cache_invalid(dir, |
| 85 | NFS_INO_REVAL_FORCED; | 85 | NFS_INO_INVALID_DATA | |
| 86 | NFS_INO_REVAL_FORCED); | ||
| 86 | list_add(&ctx->list, &nfsi->open_files); | 87 | list_add(&ctx->list, &nfsi->open_files); |
| 87 | spin_unlock(&dir->i_lock); | 88 | spin_unlock(&dir->i_lock); |
| 88 | return ctx; | 89 | return ctx; |
| @@ -1401,6 +1402,13 @@ out_force: · 1312 unmodified lines | |||
| 1401 | goto out; | 1402 | goto out; |
| 1402 | } | 1403 | } |
| 1403 | 1404 | ||
| 1405 | static void nfs_mark_dir_for_revalidate(struct inode *inode) | ||
| 1406 | { | ||
| 1407 | spin_lock(&inode->i_lock); | ||
| 1408 | nfs_set_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE); | ||
| 1409 | spin_unlock(&inode->i_lock); | ||
| 1410 | } | ||
| 1411 | |||
| 1404 | /* | 1412 | /* |
| 1405 | * We judge how long we want to trust negative | 1413 | * We judge how long we want to trust negative |
| 1406 | * dentries by looking at the parent inode mtime. | 1414 | * dentries by looking at the parent inode mtime. |
| @@ -1435,19 +1443,14 @@ nfs_lookup_revalidate_done(struct inode *dir, struct dentry *dentry, · 28 unmodified lines | |||
| 1435 | __func__, dentry); | 1443 | __func__, dentry); |
| 1436 | return 1; | 1444 | return 1; |
| 1437 | case 0: | 1445 | case 0: |
| 1438 | nfs_mark_for_revalidate(dir); | 1446 | /* |
| 1439 | if (inode && S_ISDIR(inode->i_mode)) { | 1447 | * We can't d_drop the root of a disconnected tree: |
| 1440 | /* Purge readdir caches. */ | 1448 | * its d_hash is on the s_anon list and d_drop() would hide |
| 1441 | nfs_zap_caches(inode); | 1449 | * it from shrink_dcache_for_unmount(), leading to busy |
| 1442 | /* | 1450 | * inodes on unmount and further oopses. |
| 1443 | * We can't d_drop the root of a disconnected tree: | 1451 | */ |
| 1444 | * its d_hash is on the s_anon list and d_drop() would hide | 1452 | if (inode && IS_ROOT(dentry)) |
| 1445 | * it from shrink_dcache_for_unmount(), leading to busy | 1453 | return 1; |
| 1446 | * inodes on unmount and further oopses. | ||
| 1447 | */ | ||
| 1448 | if (IS_ROOT(dentry)) | ||
| 1449 | return 1; | ||
| 1450 | } | ||
| 1451 | dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", | 1454 | dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", |
| 1452 | __func__, dentry); | 1455 | __func__, dentry); |
| 1453 | return 0; | 1456 | return 0; |
| @@ -1525,6 +1528,13 @@ out: · 71 unmodified lines | |||
| 1525 | nfs_free_fattr(fattr); | 1528 | nfs_free_fattr(fattr); |
| 1526 | nfs_free_fhandle(fhandle); | 1529 | nfs_free_fhandle(fhandle); |
| 1527 | nfs4_label_free(label); | 1530 | nfs4_label_free(label); |
| 1531 | |||
| 1532 | /* | ||
| 1533 | * If the lookup failed despite the dentry change attribute being | ||
| 1534 | * a match, then we should revalidate the directory cache. | ||
| 1535 | */ | ||
| 1536 | if (!ret && nfs_verify_change_attribute(dir, dentry->d_time)) | ||
| 1537 | nfs_mark_dir_for_revalidate(dir); | ||
| 1528 | return nfs_lookup_revalidate_done(dir, dentry, inode, ret); | 1538 | return nfs_lookup_revalidate_done(dir, dentry, inode, ret); |
| 1529 | } | 1539 | } |
| 1530 | 1540 | ||
| @@ -1567,7 +1577,7 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, · 36 unmodified lines | |||
| 1567 | error = nfs_lookup_verify_inode(inode, flags); | 1577 | error = nfs_lookup_verify_inode(inode, flags); |
| 1568 | if (error) { | 1578 | if (error) { |
| 1569 | if (error == -ESTALE) | 1579 | if (error == -ESTALE) |
| 1570 | nfs_zap_caches(dir); | 1580 | nfs_mark_dir_for_revalidate(dir); |
| 1571 | goto out_bad; | 1581 | goto out_bad; |
| 1572 | } | 1582 | } |
| 1573 | nfs_advise_use_readdirplus(dir); | 1583 | nfs_advise_use_readdirplus(dir); |
| @@ -1691,10 +1701,9 @@ static void nfs_drop_nlink(struct inode *inode) · 117 unmodified lines | |||
| 1691 | if (inode->i_nlink > 0) | 1701 | if (inode->i_nlink > 0) |
| 1692 | drop_nlink(inode); | 1702 | drop_nlink(inode); |
| 1693 | NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); | 1703 | NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); |
| 1694 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE | 1704 | nfs_set_cache_invalid( |
| 1695 | | NFS_INO_INVALID_CTIME | 1705 | inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | |
| 1696 | | NFS_INO_INVALID_OTHER | 1706 | NFS_INO_INVALID_OTHER | NFS_INO_REVAL_FORCED); |
| 1697 | | NFS_INO_REVAL_FORCED; | ||
| 1698 | spin_unlock(&inode->i_lock); | 1707 | spin_unlock(&inode->i_lock); |
| 1699 | } | 1708 | } |
| 1700 | 1709 | ||
| @@ -1706,7 +1715,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) · 5 unmodified lines | |||
| 1706 | { | 1715 | { |
| 1707 | if (S_ISDIR(inode->i_mode)) | 1716 | if (S_ISDIR(inode->i_mode)) |
| 1708 | /* drop any readdir cache as it could easily be old */ | 1717 | /* drop any readdir cache as it could easily be old */ |
| 1709 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | 1718 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
| 1710 | 1719 | ||
| 1711 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | 1720 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
| 1712 | nfs_complete_unlink(dentry, inode); | 1721 | nfs_complete_unlink(dentry, inode); |
| @@ -2064,7 +2073,6 @@ out: · 351 unmodified lines | |||
| 2064 | dput(parent); | 2073 | dput(parent); |
| 2065 | return d; | 2074 | return d; |
| 2066 | out_error: | 2075 | out_error: |
| 2067 | nfs_mark_for_revalidate(dir); | ||
| 2068 | d = ERR_PTR(error); | 2076 | d = ERR_PTR(error); |
| 2069 | goto out; | 2077 | goto out; |
| 2070 | } | 2078 | } |
| @@ -2473,9 +2481,9 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 402 unmodified lines | |||
| 2473 | if (error == 0) { | 2481 | if (error == 0) { |
| 2474 | spin_lock(&old_inode->i_lock); | 2482 | spin_lock(&old_inode->i_lock); |
| 2475 | NFS_I(old_inode)->attr_gencount = nfs_inc_attr_generation_counter(); | 2483 | NFS_I(old_inode)->attr_gencount = nfs_inc_attr_generation_counter(); |
| 2476 | NFS_I(old_inode)->cache_validity |= NFS_INO_INVALID_CHANGE | 2484 | nfs_set_cache_invalid(old_inode, NFS_INO_INVALID_CHANGE | |
| 2477 | | NFS_INO_INVALID_CTIME | 2485 | NFS_INO_INVALID_CTIME | |
| 2478 | | NFS_INO_REVAL_FORCED; | 2486 | NFS_INO_REVAL_FORCED); |
| 2479 | spin_unlock(&old_inode->i_lock); | 2487 | spin_unlock(&old_inode->i_lock); |
| 2480 | } | 2488 | } |
| 2481 | out: | 2489 | out: |
| @@ -207,7 +207,7 @@ static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi) · 206 unmodified lines | |||
| 207 | } | 207 | } |
| 208 | #endif | 208 | #endif |
| 209 | 209 | ||
| 210 | static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) | 210 | void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) |
| 211 | { | 211 | { |
| 212 | struct nfs_inode *nfsi = NFS_I(inode); | 212 | struct nfs_inode *nfsi = NFS_I(inode); |
| 213 | bool have_delegation = NFS_PROTO(inode)->have_delegation(inode, FMODE_READ); | 213 | bool have_delegation = NFS_PROTO(inode)->have_delegation(inode, FMODE_READ); |
| @@ -229,6 +229,7 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) · 15 unmodified lines | |||
| 229 | if (flags & NFS_INO_INVALID_DATA) | 229 | if (flags & NFS_INO_INVALID_DATA) |
| 230 | nfs_fscache_invalidate(inode); | 230 | nfs_fscache_invalidate(inode); |
| 231 | } | 231 | } |
| 232 | EXPORT_SYMBOL_GPL(nfs_set_cache_invalid); | ||
| 232 | 233 | ||
| 233 | /* | 234 | /* |
| 234 | * Invalidate the local caches | 235 | * Invalidate the local caches |
| @@ -1067,8 +1068,8 @@ void nfs_inode_attach_open_context(struct nfs_open_context *ctx) · 832 unmodified lines | |||
| 1067 | spin_lock(&inode->i_lock); | 1068 | spin_lock(&inode->i_lock); |
| 1068 | if (list_empty(&nfsi->open_files) && | 1069 | if (list_empty(&nfsi->open_files) && |
| 1069 | (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) | 1070 | (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) |
| 1070 | nfsi->cache_validity |= NFS_INO_INVALID_DATA | | 1071 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA | |
| 1071 | NFS_INO_REVAL_FORCED; | 1072 | NFS_INO_REVAL_FORCED); |
| 1072 | list_add_tail_rcu(&ctx->list, &nfsi->open_files); | 1073 | list_add_tail_rcu(&ctx->list, &nfsi->open_files); |
| 1073 | spin_unlock(&inode->i_lock); | 1074 | spin_unlock(&inode->i_lock); |
| 1074 | } | 1075 | } |
| @@ -411,7 +411,8 @@ extern int nfs_write_inode(struct inode *, struct writeback_control *); · 410 unmodified lines | |||
| 411 | extern int nfs_drop_inode(struct inode *); | 411 | extern int nfs_drop_inode(struct inode *); |
| 412 | extern void nfs_clear_inode(struct inode *); | 412 | extern void nfs_clear_inode(struct inode *); |
| 413 | extern void nfs_evict_inode(struct inode *); | 413 | extern void nfs_evict_inode(struct inode *); |
| 414 | void nfs_zap_acl_cache(struct inode *inode); | 414 | extern void nfs_zap_acl_cache(struct inode *inode); |
| 415 | extern void nfs_set_cache_invalid(struct inode *inode, unsigned long flags); | ||
| 415 | extern bool nfs_check_cache_invalid(struct inode *, unsigned long); | 416 | extern bool nfs_check_cache_invalid(struct inode *, unsigned long); |
| 416 | extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); | 417 | extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); |
| 417 | extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode); | 418 | extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode); |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | |||
| 36 | #define NFS3_pagepad_sz (1) /* Page padding */ | 36 | #define NFS3_pagepad_sz (1) /* Page padding */ |
| 37 | #define NFS3_fhandle_sz (1+16) | 37 | #define NFS3_fhandle_sz (1+16) |
| 38 | #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */ | 38 | #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */ |
| 39 | #define NFS3_post_op_fh_sz (1+NFS3_fh_sz) | ||
| 39 | #define NFS3_sattr_sz (15) | 40 | #define NFS3_sattr_sz (15) |
| 40 | #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) | 41 | #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) |
| 41 | #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) | 42 | #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) |
| @@ -73,7 +74,7 @@ · 31 unmodified lines | |||
| 73 | #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1+NFS3_pagepad_sz) | 74 | #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1+NFS3_pagepad_sz) |
| 74 | #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3+NFS3_pagepad_sz) | 75 | #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3+NFS3_pagepad_sz) |
| 75 | #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4) | 76 | #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4) |
| 76 | #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) | 77 | #define NFS3_createres_sz (1+NFS3_post_op_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) |
| 77 | #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz)) | 78 | #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz)) |
| 78 | #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) | 79 | #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) |
| 79 | #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2+NFS3_pagepad_sz) | 80 | #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2+NFS3_pagepad_sz) |
| @@ -357,13 +357,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, · 356 unmodified lines | |||
| 357 | truncate_pagecache_range(dst_inode, pos_dst, | 357 | truncate_pagecache_range(dst_inode, pos_dst, |
| 358 | pos_dst + res->write_res.count); | 358 | pos_dst + res->write_res.count); |
| 359 | spin_lock(&dst_inode->i_lock); | 359 | spin_lock(&dst_inode->i_lock); |
| 360 | NFS_I(dst_inode)->cache_validity |= (NFS_INO_REVAL_PAGECACHE | | 360 | nfs_set_cache_invalid( |
| 361 | NFS_INO_REVAL_FORCED | NFS_INO_INVALID_SIZE | | 361 | dst_inode, NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED | |
| 362 | NFS_INO_INVALID_ATTR | NFS_INO_INVALID_DATA); | 362 | NFS_INO_INVALID_SIZE | NFS_INO_INVALID_ATTR | |
| 363 | NFS_INO_INVALID_DATA); | ||
| 363 | spin_unlock(&dst_inode->i_lock); | 364 | spin_unlock(&dst_inode->i_lock); |
| 364 | spin_lock(&src_inode->i_lock); | 365 | spin_lock(&src_inode->i_lock); |
| 365 | NFS_I(src_inode)->cache_validity |= (NFS_INO_REVAL_PAGECACHE | | 366 | nfs_set_cache_invalid(src_inode, NFS_INO_REVAL_PAGECACHE | |
| 366 | NFS_INO_REVAL_FORCED | NFS_INO_INVALID_ATIME); | 367 | NFS_INO_REVAL_FORCED | |
| 368 | NFS_INO_INVALID_ATIME); | ||
| 367 | spin_unlock(&src_inode->i_lock); | 369 | spin_unlock(&src_inode->i_lock); |
| 368 | status = res->write_res.count; | 370 | status = res->write_res.count; |
| 369 | out: | 371 | out: |
| @@ -1169,14 +1169,14 @@ int nfs4_call_sync(struct rpc_clnt *clnt, · 1168 unmodified lines | |||
| 1169 | static void | 1169 | static void |
| 1170 | nfs4_inc_nlink_locked(struct inode *inode) | 1170 | nfs4_inc_nlink_locked(struct inode *inode) |
| 1171 | { | 1171 | { |
| 1172 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER; | 1172 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER); |
| 1173 | inc_nlink(inode); | 1173 | inc_nlink(inode); |
| 1174 | } | 1174 | } |
| 1175 | 1175 | ||
| 1176 | static void | 1176 | static void |
| 1177 | nfs4_dec_nlink_locked(struct inode *inode) | 1177 | nfs4_dec_nlink_locked(struct inode *inode) |
| 1178 | { | 1178 | { |
| 1179 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER; | 1179 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER); |
| 1180 | drop_nlink(inode); | 1180 | drop_nlink(inode); |
| 1181 | } | 1181 | } |
| 1182 | 1182 | ||
| @@ -1187,35 +1187,31 @@ nfs4_update_changeattr_locked(struct inode *inode, · 4 unmodified lines | |||
| 1187 | { | 1187 | { |
| 1188 | struct nfs_inode *nfsi = NFS_I(inode); | 1188 | struct nfs_inode *nfsi = NFS_I(inode); |
| 1189 | 1189 | ||
| 1190 | nfsi->cache_validity |= NFS_INO_INVALID_CTIME | 1190 | cache_validity |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; |
| 1191 | | NFS_INO_INVALID_MTIME | ||
| 1192 | | cache_validity; | ||
| 1193 | 1191 | ||
| 1194 | if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) { | 1192 | if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) { |
| 1195 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | 1193 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; |
| 1196 | nfsi->attrtimeo_timestamp = jiffies; | 1194 | nfsi->attrtimeo_timestamp = jiffies; |
| 1197 | } else { | 1195 | } else { |
| 1198 | if (S_ISDIR(inode->i_mode)) { | 1196 | if (S_ISDIR(inode->i_mode)) { |
| 1199 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1197 | cache_validity |= NFS_INO_INVALID_DATA; |
| 1200 | nfs_force_lookup_revalidate(inode); | 1198 | nfs_force_lookup_revalidate(inode); |
| 1201 | } else { | 1199 | } else { |
| 1202 | if (!NFS_PROTO(inode)->have_delegation(inode, | 1200 | if (!NFS_PROTO(inode)->have_delegation(inode, |
| 1203 | FMODE_READ)) | 1201 | FMODE_READ)) |
| 1204 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; | 1202 | cache_validity |= NFS_INO_REVAL_PAGECACHE; |
| 1205 | } | 1203 | } |
| 1206 | 1204 | ||
| 1207 | if (cinfo->before != inode_peek_iversion_raw(inode)) | 1205 | if (cinfo->before != inode_peek_iversion_raw(inode)) |
| 1208 | nfsi->cache_validity |= NFS_INO_INVALID_ACCESS | | 1206 | cache_validity |= NFS_INO_INVALID_ACCESS | |
| 1209 | NFS_INO_INVALID_ACL | | 1207 | NFS_INO_INVALID_ACL | |
| 1210 | NFS_INO_INVALID_XATTR; | 1208 | NFS_INO_INVALID_XATTR; |
| 1211 | } | 1209 | } |
| 1212 | inode_set_iversion_raw(inode, cinfo->after); | 1210 | inode_set_iversion_raw(inode, cinfo->after); |
| 1213 | nfsi->read_cache_jiffies = timestamp; | 1211 | nfsi->read_cache_jiffies = timestamp; |
| 1214 | nfsi->attr_gencount = nfs_inc_attr_generation_counter(); | 1212 | nfsi->attr_gencount = nfs_inc_attr_generation_counter(); |
| 1213 | nfs_set_cache_invalid(inode, cache_validity); | ||
| 1215 | nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE; | 1214 | nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE; |
| 1216 | |||
| 1217 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) | ||
| 1218 | nfs_fscache_invalidate(inode); | ||
| 1219 | } | 1215 | } |
| 1220 | 1216 | ||
| 1221 | void | 1217 | void |
| @@ -5893,6 +5889,9 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl · 4671 unmodified lines | |||
| 5893 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); | 5889 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); |
| 5894 | int ret, i; | 5890 | int ret, i; |
| 5895 | 5891 | ||
| 5892 | /* You can't remove system.nfs4_acl: */ | ||
| 5893 | if (buflen == 0) | ||
| 5894 | return -EINVAL; | ||
| 5896 | if (!nfs4_server_supports_acls(server)) | 5895 | if (!nfs4_server_supports_acls(server)) |
| 5897 | return -EOPNOTSUPP; | 5896 | return -EOPNOTSUPP; |
| 5898 | if (npages > ARRAY_SIZE(pages)) | 5897 | if (npages > ARRAY_SIZE(pages)) |
| @@ -5915,9 +5914,9 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl · 16 unmodified lines | |||
| 5915 | * so mark the attribute cache invalid. | 5914 | * so mark the attribute cache invalid. |
| 5916 | */ | 5915 | */ |
| 5917 | spin_lock(&inode->i_lock); | 5916 | spin_lock(&inode->i_lock); |
| 5918 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE | 5917 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE | |
| 5919 | | NFS_INO_INVALID_CTIME | 5918 | NFS_INO_INVALID_CTIME | |
| 5920 | | NFS_INO_REVAL_FORCED; | 5919 | NFS_INO_REVAL_FORCED); |
| 5921 | spin_unlock(&inode->i_lock); | 5920 | spin_unlock(&inode->i_lock); |
| 5922 | nfs_access_zap_cache(inode); | 5921 | nfs_access_zap_cache(inode); |
| 5923 | nfs_zap_acl_cache(inode); | 5922 | nfs_zap_acl_cache(inode); |
| @@ -5969,7 +5968,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf, · 45 unmodified lines | |||
| 5969 | return ret; | 5968 | return ret; |
| 5970 | if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) | 5969 | if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) |
| 5971 | return -ENOENT; | 5970 | return -ENOENT; |
| 5972 | return 0; | 5971 | return label.len; |
| 5973 | } | 5972 | } |
| 5974 | 5973 | ||
| 5975 | static int nfs4_get_security_label(struct inode *inode, void *buf, | 5974 | static int nfs4_get_security_label(struct inode *inode, void *buf, |
| @@ -500,9 +500,9 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry) · 499 unmodified lines | |||
| 500 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 500 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
| 501 | spin_lock(&inode->i_lock); | 501 | spin_lock(&inode->i_lock); |
| 502 | NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); | 502 | NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); |
| 503 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE | 503 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE | |
| 504 | | NFS_INO_INVALID_CTIME | 504 | NFS_INO_INVALID_CTIME | |
| 505 | | NFS_INO_REVAL_FORCED; | 505 | NFS_INO_REVAL_FORCED); |
| 506 | spin_unlock(&inode->i_lock); | 506 | spin_unlock(&inode->i_lock); |
| 507 | d_move(dentry, sdentry); | 507 | d_move(dentry, sdentry); |
| 508 | break; | 508 | break; |
| @@ -303,9 +303,9 @@ static void nfs_set_pageerror(struct address_space *mapping) · 302 unmodified lines | |||
| 303 | nfs_zap_mapping(mapping->host, mapping); | 303 | nfs_zap_mapping(mapping->host, mapping); |
| 304 | /* Force file size revalidation */ | 304 | /* Force file size revalidation */ |
| 305 | spin_lock(&inode->i_lock); | 305 | spin_lock(&inode->i_lock); |
| 306 | NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED | | 306 | nfs_set_cache_invalid(inode, NFS_INO_REVAL_FORCED | |
| 307 | NFS_INO_REVAL_PAGECACHE | | 307 | NFS_INO_REVAL_PAGECACHE | |
| 308 | NFS_INO_INVALID_SIZE; | 308 | NFS_INO_INVALID_SIZE); |
| 309 | spin_unlock(&inode->i_lock); | 309 | spin_unlock(&inode->i_lock); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| @@ -1604,7 +1604,7 @@ static int nfs_writeback_done(struct rpc_task *task, · 1292 unmodified lines | |||
| 1604 | /* Deal with the suid/sgid bit corner case */ | 1604 | /* Deal with the suid/sgid bit corner case */ |
| 1605 | if (nfs_should_remove_suid(inode)) { | 1605 | if (nfs_should_remove_suid(inode)) { |
| 1606 | spin_lock(&inode->i_lock); | 1606 | spin_lock(&inode->i_lock); |
| 1607 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER; | 1607 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER); |
| 1608 | spin_unlock(&inode->i_lock); | 1608 | spin_unlock(&inode->i_lock); |
| 1609 | } | 1609 | } |
| 1610 | return 0; | 1610 | return 0; |
| @@ -73,6 +73,7 @@ config NFSD_V4 · 72 unmodified lines | |||
| 73 | select NFSD_V3 | 73 | select NFSD_V3 |
| 74 | select FS_POSIX_ACL | 74 | select FS_POSIX_ACL |
| 75 | select SUNRPC_GSS | 75 | select SUNRPC_GSS |
| 76 | select CRYPTO | ||
| 76 | select CRYPTO_MD5 | 77 | select CRYPTO_MD5 |
| 77 | select CRYPTO_SHA256 | 78 | select CRYPTO_SHA256 |
| 78 | select GRACE_PERIOD | 79 | select GRACE_PERIOD |
| @@ -898,6 +898,8 @@ nfsd_file_find_locked(struct inode *inode, unsigned int may_flags, · 897 unmodified lines | |||
| 898 | continue; | 898 | continue; |
| 899 | if (!nfsd_match_cred(nf->nf_cred, current_cred())) | 899 | if (!nfsd_match_cred(nf->nf_cred, current_cred())) |
| 900 | continue; | 900 | continue; |
| 901 | if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) | ||
| 902 | continue; | ||
| 901 | if (nfsd_file_get(nf) != NULL) | 903 | if (nfsd_file_get(nf) != NULL) |
| 902 | return nf; | 904 | return nf; |
| 903 | } | 905 | } |
| @@ -1189,6 +1189,7 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata) · 1188 unmodified lines | |||
| 1189 | switch (task->tk_status) { | 1189 | switch (task->tk_status) { |
| 1190 | case -EIO: | 1190 | case -EIO: |
| 1191 | case -ETIMEDOUT: | 1191 | case -ETIMEDOUT: |
| 1192 | case -EACCES: | ||
| 1192 | nfsd4_mark_cb_down(clp, task->tk_status); | 1193 | nfsd4_mark_cb_down(clp, task->tk_status); |
| 1193 | } | 1194 | } |
| 1194 | break; | 1195 | break; |
| @@ -1302,7 +1302,7 @@ nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src, · 1301 unmodified lines | |||
| 1302 | struct nfsd_file *dst) | 1302 | struct nfsd_file *dst) |
| 1303 | { | 1303 | { |
| 1304 | nfs42_ssc_close(src->nf_file); | 1304 | nfs42_ssc_close(src->nf_file); |
| 1305 | /* 'src' is freed by nfsd4_do_async_copy */ | 1305 | fput(src->nf_file); |
| 1306 | nfsd_file_put(dst); | 1306 | nfsd_file_put(dst); |
| 1307 | mntput(ss_mnt); | 1307 | mntput(ss_mnt); |
| 1308 | } | 1308 | } |
| @@ -4940,31 +4940,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, · 4939 unmodified lines | |||
| 4940 | return fl; | 4940 | return fl; |
| 4941 | } | 4941 | } |
| 4942 | 4942 | ||
| 4943 | static int nfsd4_check_conflicting_opens(struct nfs4_client *clp, | ||
| 4944 | struct nfs4_file *fp) | ||
| 4945 | { | ||
| 4946 | struct nfs4_clnt_odstate *co; | ||
| 4947 | struct file *f = fp->fi_deleg_file->nf_file; | ||
| 4948 | struct inode *ino = locks_inode(f); | ||
| 4949 | int writes = atomic_read(&ino->i_writecount); | ||
| 4950 | |||
| 4951 | if (fp->fi_fds[O_WRONLY]) | ||
| 4952 | writes--; | ||
| 4953 | if (fp->fi_fds[O_RDWR]) | ||
| 4954 | writes--; | ||
| 4955 | if (writes > 0) | ||
| 4956 | return -EAGAIN; | ||
| 4957 | spin_lock(&fp->fi_lock); | ||
| 4958 | list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) { | ||
| 4959 | if (co->co_client != clp) { | ||
| 4960 | spin_unlock(&fp->fi_lock); | ||
| 4961 | return -EAGAIN; | ||
| 4962 | } | ||
| 4963 | } | ||
| 4964 | spin_unlock(&fp->fi_lock); | ||
| 4965 | return 0; | ||
| 4966 | } | ||
| 4967 | |||
| 4968 | static struct nfs4_delegation * | 4943 | static struct nfs4_delegation * |
| 4969 | nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, | 4944 | nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, |
| 4970 | struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate) | 4945 | struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate) |
| @@ -4984,12 +4959,9 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, · 13 unmodified lines | |||
| 4984 | 4959 | ||
| 4985 | nf = find_readable_file(fp); | 4960 | nf = find_readable_file(fp); |
| 4986 | if (!nf) { | 4961 | if (!nf) { |
| 4987 | /* | 4962 | /* We should always have a readable file here */ |
| 4988 | * We probably could attempt another open and get a read | 4963 | WARN_ON_ONCE(1); |
| 4989 | * delegation, but for now, don't bother until the | 4964 | return ERR_PTR(-EBADF); |
| 4990 | * client actually sends us one. | ||
| 4991 | */ | ||
| 4992 | return ERR_PTR(-EAGAIN); | ||
| 4993 | } | 4965 | } |
| 4994 | spin_lock(&state_lock); | 4966 | spin_lock(&state_lock); |
| 4995 | spin_lock(&fp->fi_lock); | 4967 | spin_lock(&fp->fi_lock); |
| @@ -5019,19 +4991,11 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, · 23 unmodified lines | |||
| 5019 | if (!fl) | 4991 | if (!fl) |
| 5020 | goto out_clnt_odstate; | 4992 | goto out_clnt_odstate; |
| 5021 | 4993 | ||
| 5022 | status = nfsd4_check_conflicting_opens(clp, fp); | ||
| 5023 | if (status) { | ||
| 5024 | locks_free_lock(fl); | ||
| 5025 | goto out_clnt_odstate; | ||
| 5026 | } | ||
| 5027 | status = vfs_setlease(fp->fi_deleg_file->nf_file, fl->fl_type, &fl, NULL); | 4994 | status = vfs_setlease(fp->fi_deleg_file->nf_file, fl->fl_type, &fl, NULL); |
| 5028 | if (fl) | 4995 | if (fl) |
| 5029 | locks_free_lock(fl); | 4996 | locks_free_lock(fl); |
| 5030 | if (status) | 4997 | if (status) |
| 5031 | goto out_clnt_odstate; | 4998 | goto out_clnt_odstate; |
| 5032 | status = nfsd4_check_conflicting_opens(clp, fp); | ||
| 5033 | if (status) | ||
| 5034 | goto out_clnt_odstate; | ||
| 5035 | 4999 | ||
| 5036 | spin_lock(&state_lock); | 5000 | spin_lock(&state_lock); |
| 5037 | spin_lock(&fp->fi_lock); | 5001 | spin_lock(&fp->fi_lock); |
| @@ -5113,6 +5077,17 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, · 75 unmodified lines | |||
| 5113 | goto out_no_deleg; | 5077 | goto out_no_deleg; |
| 5114 | if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) | 5078 | if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) |
| 5115 | goto out_no_deleg; | 5079 | goto out_no_deleg; |
| 5080 | /* | ||
| 5081 | * Also, if the file was opened for write or | ||
| 5082 | * create, there's a good chance the client's | ||
| 5083 | * about to write to it, resulting in an | ||
| 5084 | * immediate recall (since we don't support | ||
| 5085 | * write delegations): | ||
| 5086 | */ | ||
| 5087 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) | ||
| 5088 | goto out_no_deleg; | ||
| 5089 | if (open->op_create == NFS4_OPEN_CREATE) | ||
| 5090 | goto out_no_deleg; | ||
| 5116 | break; | 5091 | break; |
| 5117 | default: | 5092 | default: |
| 5118 | goto out_no_deleg; | 5093 | goto out_no_deleg; |
| @@ -5389,7 +5364,7 @@ nfs4_laundromat(struct nfsd_net *nn) · 270 unmodified lines | |||
| 5389 | idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) { | 5364 | idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) { |
| 5390 | cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid); | 5365 | cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid); |
| 5391 | if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID && | 5366 | if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID && |
| 5392 | cps->cpntf_time > cutoff) | 5367 | cps->cpntf_time < cutoff) |
| 5393 | _free_cpntf_state_locked(nn, cps); | 5368 | _free_cpntf_state_locked(nn, cps); |
| 5394 | } | 5369 | } |
| 5395 | spin_unlock(&nn->s2s_cp_lock); | 5370 | spin_unlock(&nn->s2s_cp_lock); |
| @@ -399,7 +399,7 @@ static void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf, · 398 unmodified lines | |||
| 399 | { | 399 | { |
| 400 | wi->bio = NULL; | 400 | wi->bio = NULL; |
| 401 | wi->rest_blocks = segbuf->sb_sum.nblocks; | 401 | wi->rest_blocks = segbuf->sb_sum.nblocks; |
| 402 | wi->max_pages = BIO_MAX_PAGES; | 402 | wi->max_pages = BIO_MAX_VECS; |
| 403 | wi->nr_vecs = min(wi->max_pages, wi->rest_blocks); | 403 | wi->nr_vecs = min(wi->max_pages, wi->rest_blocks); |
| 404 | wi->start = wi->end = 0; | 404 | wi->start = wi->end = 0; |
| 405 | wi->blocknr = segbuf->sb_pseg_start; | 405 | wi->blocknr = segbuf->sb_pseg_start; |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED) | 13 | #define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED) |
| 14 | #define IS_MNT_SLAVE(m) ((m)->mnt_master) | 14 | #define IS_MNT_SLAVE(m) ((m)->mnt_master) |
| 15 | #define IS_MNT_NEW(m) (!(m)->mnt_ns) | 15 | #define IS_MNT_NEW(m) (!(m)->mnt_ns || is_anon_ns((m)->mnt_ns)) |
| 16 | #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) | 16 | #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) |
| 17 | #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) | 17 | #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) |
| 18 | #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED) | 18 | #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED) |
| @@ -1036,8 +1036,6 @@ struct clear_refs_private { · 1035 unmodified lines | |||
| 1036 | 1036 | ||
| 1037 | #ifdef CONFIG_MEM_SOFT_DIRTY | 1037 | #ifdef CONFIG_MEM_SOFT_DIRTY |
| 1038 | 1038 | ||
| 1039 | #define is_cow_mapping(flags) (((flags) & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE) | ||
| 1040 | |||
| 1041 | static inline bool pte_is_pinned(struct vm_area_struct *vma, unsigned long addr, pte_t pte) | 1039 | static inline bool pte_is_pinned(struct vm_area_struct *vma, unsigned long addr, pte_t pte) |
| 1042 | { | 1040 | { |
| 1043 | struct page *page; | 1041 | struct page *page; |
| @@ -1055,10 +1055,9 @@ static long do_restart_poll(struct restart_block *restart_block) · 1054 unmodified lines | |||
| 1055 | 1055 | ||
| 1056 | ret = do_sys_poll(ufds, nfds, to); | 1056 | ret = do_sys_poll(ufds, nfds, to); |
| 1057 | 1057 | ||
| 1058 | if (ret == -ERESTARTNOHAND) { | 1058 | if (ret == -ERESTARTNOHAND) |
| 1059 | restart_block->fn = do_restart_poll; | 1059 | ret = set_restart_fn(restart_block, do_restart_poll); |
| 1060 | ret = -ERESTART_RESTARTBLOCK; | 1060 | |
| 1061 | } | ||
| 1062 | return ret; | 1061 | return ret; |
| 1063 | } | 1062 | } |
| 1064 | 1063 | ||
| @@ -1080,7 +1079,6 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, · 15 unmodified lines | |||
| 1080 | struct restart_block *restart_block; | 1079 | struct restart_block *restart_block; |
| 1081 | 1080 | ||
| 1082 | restart_block = ¤t->restart_block; | 1081 | restart_block = ¤t->restart_block; |
| 1083 | restart_block->fn = do_restart_poll; | ||
| 1084 | restart_block->poll.ufds = ufds; | 1082 | restart_block->poll.ufds = ufds; |
| 1085 | restart_block->poll.nfds = nfds; | 1083 | restart_block->poll.nfds = nfds; |
| 1086 | 1084 | ||
| @@ -1091,7 +1089,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, · 4 unmodified lines | |||
| 1091 | } else | 1089 | } else |
| 1092 | restart_block->poll.has_timeout = 0; | 1090 | restart_block->poll.has_timeout = 0; |
| 1093 | 1091 | ||
| 1094 | ret = -ERESTART_RESTARTBLOCK; | 1092 | ret = set_restart_fn(restart_block, do_restart_poll); |
| 1095 | } | 1093 | } |
| 1096 | return ret; | 1094 | return ret; |
| 1097 | } | 1095 | } |
| @@ -87,7 +87,7 @@ static int squashfs_bio_read(struct super_block *sb, u64 index, int length, · 86 unmodified lines | |||
| 87 | int error, i; | 87 | int error, i; |
| 88 | struct bio *bio; | 88 | struct bio *bio; |
| 89 | 89 | ||
| 90 | if (page_count <= BIO_MAX_PAGES) | 90 | if (page_count <= BIO_MAX_VECS) |
| 91 | bio = bio_alloc(GFP_NOIO, page_count); | 91 | bio = bio_alloc(GFP_NOIO, page_count); |
| 92 | else | 92 | else |
| 93 | bio = bio_kmalloc(GFP_NOIO, page_count); | 93 | bio = bio_kmalloc(GFP_NOIO, page_count); |
| @@ -152,14 +152,18 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, · 151 unmodified lines | |||
| 152 | start = le64_to_cpu(table[n]); | 152 | start = le64_to_cpu(table[n]); |
| 153 | end = le64_to_cpu(table[n + 1]); | 153 | end = le64_to_cpu(table[n + 1]); |
| 154 | 154 | ||
| 155 | if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { | 155 | if (start >= end |
| 156 | || (end - start) > | ||
| 157 | (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { | ||
| 156 | kfree(table); | 158 | kfree(table); |
| 157 | return ERR_PTR(-EINVAL); | 159 | return ERR_PTR(-EINVAL); |
| 158 | } | 160 | } |
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | start = le64_to_cpu(table[indexes - 1]); | 163 | start = le64_to_cpu(table[indexes - 1]); |
| 162 | if (start >= lookup_table_start || (lookup_table_start - start) > SQUASHFS_METADATA_SIZE) { | 164 | if (start >= lookup_table_start || |
| 165 | (lookup_table_start - start) > | ||
| 166 | (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { | ||
| 163 | kfree(table); | 167 | kfree(table); |
| 164 | return ERR_PTR(-EINVAL); | 168 | return ERR_PTR(-EINVAL); |
| 165 | } | 169 | } |
| @@ -97,14 +97,16 @@ __le64 *squashfs_read_id_index_table(struct super_block *sb, · 96 unmodified lines | |||
| 97 | start = le64_to_cpu(table[n]); | 97 | start = le64_to_cpu(table[n]); |
| 98 | end = le64_to_cpu(table[n + 1]); | 98 | end = le64_to_cpu(table[n + 1]); |
| 99 | 99 | ||
| 100 | if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { | 100 | if (start >= end || (end - start) > |
| 101 | (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { | ||
| 101 | kfree(table); | 102 | kfree(table); |
| 102 | return ERR_PTR(-EINVAL); | 103 | return ERR_PTR(-EINVAL); |
| 103 | } | 104 | } |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | start = le64_to_cpu(table[indexes - 1]); | 107 | start = le64_to_cpu(table[indexes - 1]); |
| 107 | if (start >= id_table_start || (id_table_start - start) > SQUASHFS_METADATA_SIZE) { | 108 | if (start >= id_table_start || (id_table_start - start) > |
| 109 | (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { | ||
| 108 | kfree(table); | 110 | kfree(table); |
| 109 | return ERR_PTR(-EINVAL); | 111 | return ERR_PTR(-EINVAL); |
| 110 | } | 112 | } |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | /* size of metadata (inode and directory) blocks */ | 18 | /* size of metadata (inode and directory) blocks */ |
| 19 | #define SQUASHFS_METADATA_SIZE 8192 | 19 | #define SQUASHFS_METADATA_SIZE 8192 |
| 20 | #define SQUASHFS_BLOCK_OFFSET 2 | ||
| 20 | 21 | ||
| 21 | /* default size of block device I/O */ | 22 | /* default size of block device I/O */ |
| 22 | #ifdef CONFIG_SQUASHFS_4K_DEVBLK_SIZE | 23 | #ifdef CONFIG_SQUASHFS_4K_DEVBLK_SIZE |
| @@ -109,14 +109,16 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start, · 108 unmodified lines | |||
| 109 | start = le64_to_cpu(table[n]); | 109 | start = le64_to_cpu(table[n]); |
| 110 | end = le64_to_cpu(table[n + 1]); | 110 | end = le64_to_cpu(table[n + 1]); |
| 111 | 111 | ||
| 112 | if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { | 112 | if (start >= end || (end - start) > |
| 113 | (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { | ||
| 113 | kfree(table); | 114 | kfree(table); |
| 114 | return ERR_PTR(-EINVAL); | 115 | return ERR_PTR(-EINVAL); |
| 115 | } | 116 | } |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | start = le64_to_cpu(table[indexes - 1]); | 119 | start = le64_to_cpu(table[indexes - 1]); |
| 119 | if (start >= table_start || (table_start - start) > SQUASHFS_METADATA_SIZE) { | 120 | if (start >= table_start || (table_start - start) > |
| 121 | (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { | ||
| 120 | kfree(table); | 122 | kfree(table); |
| 121 | return ERR_PTR(-EINVAL); | 123 | return ERR_PTR(-EINVAL); |
| 122 | } | 124 | } |
| @@ -1007,9 +1007,10 @@ xfs_create( · 1006 unmodified lines | |||
| 1007 | /* | 1007 | /* |
| 1008 | * Make sure that we have allocated dquot(s) on disk. | 1008 | * Make sure that we have allocated dquot(s) on disk. |
| 1009 | */ | 1009 | */ |
| 1010 | error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, | 1010 | error = xfs_qm_vop_dqalloc(dp, fsuid_into_mnt(mnt_userns), |
| 1011 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, | 1011 | fsgid_into_mnt(mnt_userns), prid, |
| 1012 | &udqp, &gdqp, &pdqp); | 1012 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, |
| 1013 | &udqp, &gdqp, &pdqp); | ||
| 1013 | if (error) | 1014 | if (error) |
| 1014 | return error; | 1015 | return error; |
| 1015 | 1016 | ||
| @@ -1157,9 +1158,10 @@ xfs_create_tmpfile( · 141 unmodified lines | |||
| 1157 | /* | 1158 | /* |
| 1158 | * Make sure that we have allocated dquot(s) on disk. | 1159 | * Make sure that we have allocated dquot(s) on disk. |
| 1159 | */ | 1160 | */ |
| 1160 | error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, | 1161 | error = xfs_qm_vop_dqalloc(dp, fsuid_into_mnt(mnt_userns), |
| 1161 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, | 1162 | fsgid_into_mnt(mnt_userns), prid, |
| 1162 | &udqp, &gdqp, &pdqp); | 1163 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, |
| 1164 | &udqp, &gdqp, &pdqp); | ||
| 1163 | if (error) | 1165 | if (error) |
| 1164 | return error; | 1166 | return error; |
| 1165 | 1167 | ||
| @@ -168,6 +168,12 @@ xfs_bulkstat_one( · 167 unmodified lines | |||
| 168 | }; | 168 | }; |
| 169 | int error; | 169 | int error; |
| 170 | 170 | ||
| 171 | if (breq->mnt_userns != &init_user_ns) { | ||
| 172 | xfs_warn_ratelimited(breq->mp, | ||
| 173 | "bulkstat not supported inside of idmapped mounts."); | ||
| 174 | return -EINVAL; | ||
| 175 | } | ||
| 176 | |||
| 171 | ASSERT(breq->icount == 1); | 177 | ASSERT(breq->icount == 1); |
| 172 | 178 | ||
| 173 | bc.buf = kmem_zalloc(sizeof(struct xfs_bulkstat), | 179 | bc.buf = kmem_zalloc(sizeof(struct xfs_bulkstat), |
| @@ -634,6 +634,47 @@ xfs_check_summary_counts( · 633 unmodified lines | |||
| 634 | return xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount); | 634 | return xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount); |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | /* | ||
| 638 | * Flush and reclaim dirty inodes in preparation for unmount. Inodes and | ||
| 639 | * internal inode structures can be sitting in the CIL and AIL at this point, | ||
| 640 | * so we need to unpin them, write them back and/or reclaim them before unmount | ||
| 641 | * can proceed. | ||
| 642 | * | ||
| 643 | * An inode cluster that has been freed can have its buffer still pinned in | ||
| 644 | * memory because the transaction is still sitting in a iclog. The stale inodes | ||
| 645 | * on that buffer will be pinned to the buffer until the transaction hits the | ||
| 646 | * disk and the callbacks run. Pushing the AIL will skip the stale inodes and | ||
| 647 | * may never see the pinned buffer, so nothing will push out the iclog and | ||
| 648 | * unpin the buffer. | ||
| 649 | * | ||
| 650 | * Hence we need to force the log to unpin everything first. However, log | ||
| 651 | * forces don't wait for the discards they issue to complete, so we have to | ||
| 652 | * explicitly wait for them to complete here as well. | ||
| 653 | * | ||
| 654 | * Then we can tell the world we are unmounting so that error handling knows | ||
| 655 | * that the filesystem is going away and we should error out anything that we | ||
| 656 | * have been retrying in the background. This will prevent never-ending | ||
| 657 | * retries in AIL pushing from hanging the unmount. | ||
| 658 | * | ||
| 659 | * Finally, we can push the AIL to clean all the remaining dirty objects, then | ||
| 660 | * reclaim the remaining inodes that are still in memory at this point in time. | ||
| 661 | */ | ||
| 662 | static void | ||
| 663 | xfs_unmount_flush_inodes( | ||
| 664 | struct xfs_mount *mp) | ||
| 665 | { | ||
| 666 | xfs_log_force(mp, XFS_LOG_SYNC); | ||
| 667 | xfs_extent_busy_wait_all(mp); | ||
| 668 | flush_workqueue(xfs_discard_wq); | ||
| 669 | |||
| 670 | mp->m_flags |= XFS_MOUNT_UNMOUNTING; | ||
| 671 | |||
| 672 | xfs_ail_push_all_sync(mp->m_ail); | ||
| 673 | cancel_delayed_work_sync(&mp->m_reclaim_work); | ||
| 674 | xfs_reclaim_inodes(mp); | ||
| 675 | xfs_health_unmount(mp); | ||
| 676 | } | ||
| 677 | |||
| 637 | /* | 678 | /* |
| 638 | * This function does the following on an initial mount of a file system: | 679 | * This function does the following on an initial mount of a file system: |
| 639 | * - reads the superblock from disk and init the mount struct | 680 | * - reads the superblock from disk and init the mount struct |
| @@ -1008,7 +1049,7 @@ xfs_mountfs( · 368 unmodified lines | |||
| 1008 | /* Clean out dquots that might be in memory after quotacheck. */ | 1049 | /* Clean out dquots that might be in memory after quotacheck. */ |
| 1009 | xfs_qm_unmount(mp); | 1050 | xfs_qm_unmount(mp); |
| 1010 | /* | 1051 | /* |
| 1011 | * Cancel all delayed reclaim work and reclaim the inodes directly. | 1052 | * Flush all inode reclamation work and flush the log. |
65 more lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 16 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 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 17 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 7 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 13 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 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 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 25 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 36 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 293 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 109 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 16 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 112 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 99 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 304 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 17 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 39 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 23 lines aren’t shown here.
This diff is large: its 223 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 24 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 67 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 80 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 58 lines aren’t shown here.
This diff is large: its 12 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 33 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 21 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 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 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 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 23 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 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 136 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 47 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 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 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 12 lines aren’t shown here.
This diff is large: its 14 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 12 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 41 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 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 15 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 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 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 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 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 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 11 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 5 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 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 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 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 12 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 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 19 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 13 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 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 19 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 195 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 49 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 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 25 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 125 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 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 22 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 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 8 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 24 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 32 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 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 37 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 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 135 lines aren’t shown here.
This diff is large: its 261 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.