We want the USB fixes in here as well and it resolves a merge issue with xhci-mtk.c
Unified · Split
| @@ -36,6 +36,7 @@ Andrew Morton <akpm@linux-foundation.org> · 35 unmodified lines | ||
| 36 | 36 | Andrew Murray <amurray@thegoodpenguin.co.uk> <amurray@embedded-bits.co.uk> |
| 37 | 37 | Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com> |
| 38 | 38 | Andrew Vasquez <andrew.vasquez@qlogic.com> |
| 39 | +Andrey Konovalov <andreyknvl@gmail.com> <andreyknvl@google.com> | |
| 39 | 40 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> |
| 40 | 41 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> |
| 41 | 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 | 66 | Changbin Du <changbin.du@intel.com> <changbin.du@intel.com> |
| 66 | 67 | Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> |
| 67 | 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 | 71 | Christophe Ricard <christophe.ricard@gmail.com> |
| 69 | 72 | Christoph Hellwig <hch@lst.de> |
| 70 | 73 | Corey Minyard <minyard@acm.org> |
| @@ -17,12 +17,12 @@ For ACPI on arm64, tables also fall into the following categories: · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | - Recommended: BERT, EINJ, ERST, HEST, PCCT, SSDT |
| 19 | 19 | |
| 20 | − - Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, IORT, | |
| 21 | − MCHI, MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, STAO, | |
| 22 | − TCPA, TPM2, UEFI, XENV | |
| 20 | + - Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, IBFT, | |
| 21 | + IORT, MCHI, MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, | |
| 22 | + STAO, TCPA, TPM2, UEFI, XENV | |
| 23 | 23 | |
| 24 | − - Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, LPIT, | |
| 25 | − MSDM, OEMx, PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT | |
| 24 | + - Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IVRS, LPIT, MSDM, OEMx, | |
| 25 | + PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT | |
| 26 | 26 | |
| 27 | 27 | ====== ======================================================================== |
| 28 | 28 | Table Usage for ARMv8 Linux |
| @@ -130,6 +130,9 @@ stable kernels. · 129 unmodified lines | ||
| 130 | 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 | 136 | | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | |
| 134 | 137 | +----------------+-----------------+-----------------+-----------------------------+ |
| 135 | 138 | +----------------+-----------------+-----------------+-----------------------------+ |
| @@ -267,7 +267,7 @@ DATA PATH · 266 unmodified lines | ||
| 267 | 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 | 272 | - Maps data buffers (skb->data and frags). |
| 273 | 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 | 52 | ``devlink-dpipe`` should change according to the changes done by the |
| 53 | 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 | 56 | using Ternary Content Addressable Memory (TCAM). The TCAM memory can be |
| 57 | 57 | divided into TCAM regions. Complex TC filters can have multiple rules with |
| 58 | 58 | different priorities and different lookup keys. On the other hand hardware |
| @@ -151,7 +151,7 @@ representor netdevice. · 150 unmodified lines | ||
| 151 | 151 | ------------- |
| 152 | 152 | A subfunction devlink port is created but it is not active yet. That means the |
| 153 | 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 | 155 | representor to do settings, putting it into bridge, adding TC rules, etc. A user |
| 156 | 156 | might as well configure the hardware address (such as MAC address) of the |
| 157 | 157 | subfunction while subfunction is inactive. |
| @@ -173,7 +173,7 @@ Terms and Definitions · 15 unmodified lines | ||
| 173 | 173 | * - Term |
| 174 | 174 | - Definitions |
| 175 | 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 | 177 | more PCI controllers. |
| 178 | 178 | * - ``PCI controller`` |
| 179 | 179 | - A controller consists of potentially multiple physical functions, |
| @@ -50,7 +50,7 @@ Callbacks to implement · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | The NIC driver offering ipsec offload will need to implement these |
| 52 | 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 | 54 | NETIF_F_HW_ESP_TX_CSUM will signal the availability of the offload. |
| 55 | 55 | |
| 56 | 56 | |
| @@ -2489,7 +2489,7 @@ N: sc27xx · 2488 unmodified lines | ||
| 2489 | 2489 | N: sc2731 |
| 2490 | 2490 | |
| 2491 | 2491 | ARM/STI ARCHITECTURE |
| 2492 | −M: Patrice Chotard <patrice.chotard@st.com> | |
| 2492 | +M: Patrice Chotard <patrice.chotard@foss.st.com> | |
| 2493 | 2493 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2494 | 2494 | S: Maintained |
| 2495 | 2495 | W: http://www.stlinux.com |
| @@ -2522,7 +2522,7 @@ F: include/linux/remoteproc/st_slim_rproc.h · 26 unmodified lines | ||
| 2522 | 2522 | |
| 2523 | 2523 | ARM/STM32 ARCHITECTURE |
| 2524 | 2524 | M: Maxime Coquelin <mcoquelin.stm32@gmail.com> |
| 2525 | −M: Alexandre Torgue <alexandre.torgue@st.com> | |
| 2525 | +M: Alexandre Torgue <alexandre.torgue@foss.st.com> | |
| 2526 | 2526 | L: linux-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) |
| 2527 | 2527 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2528 | 2528 | S: Maintained |
| @@ -3115,7 +3115,7 @@ C: irc://irc.oftc.net/bcache · 586 unmodified lines | ||
| 3115 | 3115 | F: drivers/md/bcache/ |
| 3116 | 3116 | |
| 3117 | 3117 | BDISP ST MEDIA DRIVER |
| 3118 | −M: Fabien Dessenne <fabien.dessenne@st.com> | |
| 3118 | +M: Fabien Dessenne <fabien.dessenne@foss.st.com> | |
| 3119 | 3119 | L: linux-media@vger.kernel.org |
| 3120 | 3120 | S: Supported |
| 3121 | 3121 | W: https://linuxtv.org |
| @@ -3675,7 +3675,7 @@ M: bcm-kernel-feedback-list@broadcom.com · 553 unmodified lines | ||
| 3675 | 3675 | L: linux-pm@vger.kernel.org |
| 3676 | 3676 | S: Maintained |
| 3677 | 3677 | T: git git://github.com/broadcom/stblinux.git |
| 3678 | −F: drivers/soc/bcm/bcm-pmb.c | |
| 3678 | +F: drivers/soc/bcm/bcm63xx/bcm-pmb.c | |
| 3679 | 3679 | F: include/dt-bindings/soc/bcm-pmb.h |
| 3680 | 3680 | |
| 3681 | 3681 | BROADCOM SPECIFIC AMBA DRIVER (BCMA) |
| @@ -5080,7 +5080,7 @@ S: Maintained · 1398 unmodified lines | ||
| 5080 | 5080 | F: drivers/platform/x86/dell/dell-wmi.c |
| 5081 | 5081 | |
| 5082 | 5082 | DELTA ST MEDIA DRIVER |
| 5083 | −M: Hugues Fruchet <hugues.fruchet@st.com> | |
| 5083 | +M: Hugues Fruchet <hugues.fruchet@foss.st.com> | |
| 5084 | 5084 | L: linux-media@vger.kernel.org |
| 5085 | 5085 | S: Supported |
| 5086 | 5086 | W: https://linuxtv.org |
| @@ -6006,7 +6006,6 @@ F: drivers/gpu/drm/rockchip/ · 919 unmodified lines | ||
| 6006 | 6006 | |
| 6007 | 6007 | DRM DRIVERS FOR STI |
| 6008 | 6008 | M: Benjamin Gaignard <benjamin.gaignard@linaro.org> |
| 6009 | −M: Vincent Abriou <vincent.abriou@st.com> | |
| 6010 | 6009 | L: dri-devel@lists.freedesktop.org |
| 6011 | 6010 | S: Maintained |
| 6012 | 6011 | T: git git://anongit.freedesktop.org/drm/drm-misc |
| @@ -6014,10 +6013,9 @@ F: Documentation/devicetree/bindings/display/st,stih4xx.txt · 1 unmodified line | ||
| 6014 | 6013 | F: drivers/gpu/drm/sti |
| 6015 | 6014 | |
| 6016 | 6015 | DRM DRIVERS FOR STM |
| 6017 | −M: Yannick Fertre <yannick.fertre@st.com> | |
| 6018 | −M: Philippe Cornu <philippe.cornu@st.com> | |
| 6016 | +M: Yannick Fertre <yannick.fertre@foss.st.com> | |
| 6017 | +M: Philippe Cornu <philippe.cornu@foss.st.com> | |
| 6019 | 6018 | M: Benjamin Gaignard <benjamin.gaignard@linaro.org> |
| 6020 | −M: Vincent Abriou <vincent.abriou@st.com> | |
| 6021 | 6019 | L: dri-devel@lists.freedesktop.org |
| 6022 | 6020 | S: Maintained |
| 6023 | 6021 | T: git git://anongit.freedesktop.org/drm/drm-misc |
| @@ -7476,8 +7474,9 @@ F: include/uapi/asm-generic/ · 1452 unmodified lines | ||
| 7476 | 7474 | GENERIC PHY FRAMEWORK |
| 7477 | 7475 | M: Kishon Vijay Abraham I <kishon@ti.com> |
| 7478 | 7476 | M: Vinod Koul <vkoul@kernel.org> |
| 7479 | −L: linux-kernel@vger.kernel.org | |
| 7477 | +L: linux-phy@lists.infradead.org | |
| 7480 | 7478 | S: Supported |
| 7479 | +Q: https://patchwork.kernel.org/project/linux-phy/list/ | |
| 7481 | 7480 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git |
| 7482 | 7481 | F: Documentation/devicetree/bindings/phy/ |
| 7483 | 7482 | F: drivers/phy/ |
| @@ -8230,7 +8229,7 @@ F: include/linux/hugetlb.h · 746 unmodified lines | ||
| 8230 | 8229 | F: mm/hugetlb.c |
| 8231 | 8230 | |
| 8232 | 8231 | HVA ST MEDIA DRIVER |
| 8233 | −M: Jean-Christophe Trotin <jean-christophe.trotin@st.com> | |
| 8232 | +M: Jean-Christophe Trotin <jean-christophe.trotin@foss.st.com> | |
| 8234 | 8233 | L: linux-media@vger.kernel.org |
| 8235 | 8234 | S: Supported |
| 8236 | 8235 | W: https://linuxtv.org |
| @@ -8520,6 +8519,7 @@ IBM Power SRIOV Virtual NIC Device Driver · 283 unmodified lines | ||
| 8520 | 8519 | M: Dany Madden <drt@linux.ibm.com> |
| 8521 | 8520 | M: Lijun Pan <ljp@linux.ibm.com> |
| 8522 | 8521 | M: Sukadev Bhattiprolu <sukadev@linux.ibm.com> |
| 8522 | +R: Thomas Falcon <tlfalcon@linux.ibm.com> | |
| 8523 | 8523 | L: netdev@vger.kernel.org |
| 8524 | 8524 | S: Supported |
| 8525 | 8525 | F: drivers/net/ethernet/ibm/ibmvnic.* |
| @@ -10029,7 +10029,6 @@ F: scripts/leaking_addresses.pl · 1503 unmodified lines | ||
| 10029 | 10029 | |
| 10030 | 10030 | LED SUBSYSTEM |
| 10031 | 10031 | M: Pavel Machek <pavel@ucw.cz> |
| 10032 | −R: Dan Murphy <dmurphy@ti.com> | |
| 10033 | 10032 | L: linux-leds@vger.kernel.org |
| 10034 | 10033 | S: Maintained |
| 10035 | 10034 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git |
| @@ -10905,7 +10904,6 @@ T: git git://linuxtv.org/media_tree.git · 869 unmodified lines | ||
| 10905 | 10904 | F: drivers/media/radio/radio-maxiradio* |
| 10906 | 10905 | |
| 10907 | 10906 | MCAN MMIO DEVICE DRIVER |
| 10908 | −M: Dan Murphy <dmurphy@ti.com> | |
| 10909 | 10907 | M: Pankaj Sharma <pankj.sharma@samsung.com> |
| 10910 | 10908 | L: linux-can@vger.kernel.org |
| 10911 | 10909 | S: Maintained |
| @@ -11166,7 +11164,7 @@ T: git git://linuxtv.org/media_tree.git · 254 unmodified lines | ||
| 11166 | 11164 | F: drivers/media/dvb-frontends/stv6111* |
| 11167 | 11165 | |
| 11168 | 11166 | MEDIA DRIVERS FOR STM32 - DCMI |
| 11169 | −M: Hugues Fruchet <hugues.fruchet@st.com> | |
| 11167 | +M: Hugues Fruchet <hugues.fruchet@foss.st.com> | |
| 11170 | 11168 | L: linux-media@vger.kernel.org |
| 11171 | 11169 | S: Supported |
| 11172 | 11170 | T: git git://linuxtv.org/media_tree.git |
| @@ -12537,7 +12535,7 @@ NETWORKING [MPTCP] · 1364 unmodified lines | ||
| 12537 | 12535 | M: Mat Martineau <mathew.j.martineau@linux.intel.com> |
| 12538 | 12536 | M: Matthieu Baerts <matthieu.baerts@tessares.net> |
| 12539 | 12537 | L: netdev@vger.kernel.org |
| 12540 | −L: mptcp@lists.01.org | |
| 12538 | +L: mptcp@lists.linux.dev | |
| 12541 | 12539 | S: Maintained |
| 12542 | 12540 | W: https://github.com/multipath-tcp/mptcp_net-next/wiki |
| 12543 | 12541 | B: https://github.com/multipath-tcp/mptcp_net-next/issues |
| @@ -14708,15 +14706,11 @@ F: drivers/net/ethernet/qlogic/qlcnic/ · 2164 unmodified lines | ||
| 14708 | 14706 | QLOGIC QLGE 10Gb ETHERNET DRIVER |
| 14709 | 14707 | M: Manish Chopra <manishc@marvell.com> |
| 14710 | 14708 | M: GR-Linux-NIC-Dev@marvell.com |
| 14711 | −L: netdev@vger.kernel.org | |
| 14712 | −S: Supported | |
| 14713 | −F: drivers/staging/qlge/ | |
| 14714 | − | |
| 14715 | −QLOGIC QLGE 10Gb ETHERNET DRIVER | |
| 14716 | 14709 | M: Coiby Xu <coiby.xu@gmail.com> |
| 14717 | 14710 | L: netdev@vger.kernel.org |
| 14718 | −S: Maintained | |
| 14711 | +S: Supported | |
| 14719 | 14712 | F: Documentation/networking/device_drivers/qlogic/qlge.rst |
| 14713 | +F: drivers/staging/qlge/ | |
| 14720 | 14714 | |
| 14721 | 14715 | QM1D1B0004 MEDIA DRIVER |
| 14722 | 14716 | M: Akihiro Tsukada <tskd08@gmail.com> |
| @@ -15634,8 +15628,8 @@ F: Documentation/s390/pci.rst · 911 unmodified lines | ||
| 15634 | 15628 | |
| 15635 | 15629 | S390 VFIO AP DRIVER |
| 15636 | 15630 | M: Tony Krowiak <akrowiak@linux.ibm.com> |
| 15637 | −M: Pierre Morel <pmorel@linux.ibm.com> | |
| 15638 | 15631 | M: Halil Pasic <pasic@linux.ibm.com> |
| 15632 | +M: Jason Herne <jjherne@linux.ibm.com> | |
| 15639 | 15633 | L: linux-s390@vger.kernel.org |
| 15640 | 15634 | S: Supported |
| 15641 | 15635 | W: http://www.ibm.com/developerworks/linux/linux390/ |
| @@ -15647,6 +15641,7 @@ F: drivers/s390/crypto/vfio_ap_private.h · 5 unmodified lines | ||
| 15647 | 15641 | S390 VFIO-CCW DRIVER |
| 15648 | 15642 | M: Cornelia Huck <cohuck@redhat.com> |
| 15649 | 15643 | M: Eric Farman <farman@linux.ibm.com> |
| 15644 | +M: Matthew Rosato <mjrosato@linux.ibm.com> | |
| 15650 | 15645 | R: Halil Pasic <pasic@linux.ibm.com> |
| 15651 | 15646 | L: linux-s390@vger.kernel.org |
| 15652 | 15647 | L: kvm@vger.kernel.org |
| @@ -15657,6 +15652,7 @@ F: include/uapi/linux/vfio_ccw.h · 4 unmodified lines | ||
| 15657 | 15652 | |
| 15658 | 15653 | S390 VFIO-PCI DRIVER |
| 15659 | 15654 | M: Matthew Rosato <mjrosato@linux.ibm.com> |
| 15655 | +M: Eric Farman <farman@linux.ibm.com> | |
| 15660 | 15656 | L: linux-s390@vger.kernel.org |
| 15661 | 15657 | L: kvm@vger.kernel.org |
| 15662 | 15658 | S: Supported |
| @@ -16886,8 +16882,10 @@ F: tools/spi/ · 1223 unmodified lines | ||
| 16886 | 16882 | |
| 16887 | 16883 | SPIDERNET NETWORK DRIVER for CELL |
| 16888 | 16884 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> |
| 16885 | +M: Geoff Levand <geoff@infradead.org> | |
| 16889 | 16886 | L: netdev@vger.kernel.org |
| 16890 | −S: Supported | |
| 16887 | +L: linuxppc-dev@lists.ozlabs.org | |
| 16888 | +S: Maintained | |
| 16891 | 16889 | F: Documentation/networking/device_drivers/ethernet/toshiba/spider_net.rst |
| 16892 | 16890 | F: drivers/net/ethernet/toshiba/spider_net* |
| 16893 | 16891 | |
| @@ -16941,7 +16939,8 @@ F: Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt · 47 unmodified lines | ||
| 16941 | 16939 | F: drivers/media/i2c/st-mipid02.c |
| 16942 | 16940 | |
| 16943 | 16941 | ST STM32 I2C/SMBUS DRIVER |
| 16944 | −M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> | |
| 16942 | +M: Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com> | |
| 16943 | +M: Alain Volmat <alain.volmat@foss.st.com> | |
| 16945 | 16944 | L: linux-i2c@vger.kernel.org |
| 16946 | 16945 | S: Maintained |
| 16947 | 16946 | F: drivers/i2c/busses/i2c-stm32* |
| @@ -17066,7 +17065,7 @@ F: kernel/jump_label.c · 118 unmodified lines | ||
| 17066 | 17065 | F: kernel/static_call.c |
| 17067 | 17066 | |
| 17068 | 17067 | STI AUDIO (ASoC) DRIVERS |
| 17069 | −M: Arnaud Pouliquen <arnaud.pouliquen@st.com> | |
| 17068 | +M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | |
| 17070 | 17069 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17071 | 17070 | S: Maintained |
| 17072 | 17071 | F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt |
| @@ -17086,15 +17085,15 @@ T: git git://linuxtv.org/media_tree.git · 13 unmodified lines | ||
| 17086 | 17085 | F: drivers/media/usb/stk1160/ |
| 17087 | 17086 | |
| 17088 | 17087 | STM32 AUDIO (ASoC) DRIVERS |
| 17089 | −M: Olivier Moysan <olivier.moysan@st.com> | |
| 17090 | −M: Arnaud Pouliquen <arnaud.pouliquen@st.com> | |
| 17088 | +M: Olivier Moysan <olivier.moysan@foss.st.com> | |
| 17089 | +M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | |
| 17091 | 17090 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17092 | 17091 | S: Maintained |
| 17093 | 17092 | F: Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml |
| 17094 | 17093 | F: sound/soc/stm/ |
| 17095 | 17094 | |
| 17096 | 17095 | STM32 TIMER/LPTIMER DRIVERS |
| 17097 | −M: Fabrice Gasnier <fabrice.gasnier@st.com> | |
| 17096 | +M: Fabrice Gasnier <fabrice.gasnier@foss.st.com> | |
| 17098 | 17097 | S: Maintained |
| 17099 | 17098 | F: Documentation/ABI/testing/*timer-stm32 |
| 17100 | 17099 | F: Documentation/devicetree/bindings/*/*stm32-*timer* |
| @@ -17104,7 +17103,7 @@ F: include/linux/*/stm32-*tim* · 3 unmodified lines | ||
| 17104 | 17103 | |
| 17105 | 17104 | STMMAC ETHERNET DRIVER |
| 17106 | 17105 | M: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
| 17107 | −M: Alexandre Torgue <alexandre.torgue@st.com> | |
| 17106 | +M: Alexandre Torgue <alexandre.torgue@foss.st.com> | |
| 17108 | 17107 | M: Jose Abreu <joabreu@synopsys.com> |
| 17109 | 17108 | L: netdev@vger.kernel.org |
| 17110 | 17109 | S: Supported |
| @@ -17846,7 +17845,6 @@ S: Maintained · 735 unmodified lines | ||
| 17846 | 17845 | F: drivers/thermal/ti-soc-thermal/ |
| 17847 | 17846 | |
| 17848 | 17847 | TI BQ27XXX POWER SUPPLY DRIVER |
| 17849 | −R: Dan Murphy <dmurphy@ti.com> | |
| 17850 | 17848 | F: drivers/power/supply/bq27xxx_battery.c |
| 17851 | 17849 | F: drivers/power/supply/bq27xxx_battery_i2c.c |
| 17852 | 17850 | F: include/linux/power/bq27xxx_battery.h |
| @@ -17981,7 +17979,6 @@ S: Odd Fixes · 128 unmodified lines | ||
| 17981 | 17979 | F: sound/soc/codecs/tas571x* |
| 17982 | 17980 | |
| 17983 | 17981 | TI TCAN4X5X DEVICE DRIVER |
| 17984 | −M: Dan Murphy <dmurphy@ti.com> | |
| 17985 | 17982 | L: linux-can@vger.kernel.org |
| 17986 | 17983 | S: Maintained |
| 17987 | 17984 | F: Documentation/devicetree/bindings/net/can/tcan4x5x.txt |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 12 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc4 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Frozen Wasteland |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -40,6 +40,9 @@ · 39 unmodified lines | ||
| 40 | 40 | ethernet1 = &cpsw_emac1; |
| 41 | 41 | spi0 = &spi0; |
| 42 | 42 | spi1 = &spi1; |
| 43 | + mmc0 = &mmc1; | |
| 44 | + mmc1 = &mmc2; | |
| 45 | + mmc2 = &mmc3; | |
| 43 | 46 | }; |
| 44 | 47 | |
| 45 | 48 | cpus { |
| @@ -334,14 +334,6 @@ · 333 unmodified lines | ||
| 334 | 334 | }; |
| 335 | 335 | |
| 336 | 336 | &pinctrl { |
| 337 | − atmel,mux-mask = < | |
| 338 | − /* A B C */ | |
| 339 | − 0xFFFFFE7F 0xC0E0397F 0xEF00019D /* pioA */ | |
| 340 | − 0x03FFFFFF 0x02FC7E68 0x00780000 /* pioB */ | |
| 341 | − 0xffffffff 0xF83FFFFF 0xB800F3FC /* pioC */ | |
| 342 | − 0x003FFFFF 0x003F8000 0x00000000 /* pioD */ | |
| 343 | − >; | |
| 344 | − | |
| 345 | 337 | adc { |
| 346 | 338 | pinctrl_adc_default: adc_default { |
| 347 | 339 | atmel,pins = <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; |
| @@ -84,8 +84,8 @@ · 83 unmodified lines | ||
| 84 | 84 | pinctrl-0 = <&pinctrl_macb0_default>; |
| 85 | 85 | phy-mode = "rmii"; |
| 86 | 86 | |
| 87 | − ethernet-phy@0 { | |
| 88 | − reg = <0x0>; | |
| 87 | + ethernet-phy@7 { | |
| 88 | + reg = <0x7>; | |
| 89 | 89 | interrupt-parent = <&pioA>; |
| 90 | 90 | interrupts = <PIN_PD31 IRQ_TYPE_LEVEL_LOW>; |
| 91 | 91 | pinctrl-names = "default"; |
| @@ -210,9 +210,6 @@ · 209 unmodified lines | ||
| 210 | 210 | micrel,led-mode = <1>; |
| 211 | 211 | clocks = <&clks IMX6UL_CLK_ENET_REF>; |
| 212 | 212 | clock-names = "rmii-ref"; |
| 213 | − reset-gpios = <&gpio_spi 1 GPIO_ACTIVE_LOW>; | |
| 214 | − reset-assert-us = <10000>; | |
| 215 | − reset-deassert-us = <100>; | |
| 216 | 213 | |
| 217 | 214 | }; |
| 218 | 215 | |
| @@ -222,9 +219,6 @@ · 3 unmodified lines | ||
| 222 | 219 | micrel,led-mode = <1>; |
| 223 | 220 | clocks = <&clks IMX6UL_CLK_ENET2_REF>; |
| 224 | 221 | clock-names = "rmii-ref"; |
| 225 | − reset-gpios = <&gpio_spi 2 GPIO_ACTIVE_LOW>; | |
| 226 | − reset-assert-us = <10000>; | |
| 227 | − reset-deassert-us = <100>; | |
| 228 | 222 | }; |
| 229 | 223 | }; |
| 230 | 224 | }; |
| @@ -243,6 +237,22 @@ · 12 unmodified lines | ||
| 243 | 237 | status = "okay"; |
| 244 | 238 | }; |
| 245 | 239 | |
| 240 | +&gpio_spi { | |
| 241 | + eth0-phy-hog { | |
| 242 | + gpio-hog; | |
| 243 | + gpios = <1 GPIO_ACTIVE_HIGH>; | |
| 244 | + output-high; | |
| 245 | + line-name = "eth0-phy"; | |
| 246 | + }; | |
| 247 | + | |
| 248 | + eth1-phy-hog { | |
| 249 | + gpio-hog; | |
| 250 | + gpios = <2 GPIO_ACTIVE_HIGH>; | |
| 251 | + output-high; | |
| 252 | + line-name = "eth1-phy"; | |
| 253 | + }; | |
| 254 | +}; | |
| 255 | + | |
| 246 | 256 | &i2c1 { |
| 247 | 257 | clock-frequency = <100000>; |
| 248 | 258 | pinctrl-names = "default"; |
| @@ -14,5 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | 16 | &gpmi { |
| 17 | + fsl,use-minimum-ecc; | |
| 17 | 18 | status = "okay"; |
| 18 | 19 | }; |
| @@ -606,6 +606,15 @@ · 605 unmodified lines | ||
| 606 | 606 | compatible = "microchip,sam9x60-pinctrl", "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; |
| 607 | 607 | ranges = <0xfffff400 0xfffff400 0x800>; |
| 608 | 608 | |
| 609 | + /* mux-mask corresponding to sam9x60 SoC in TFBGA228L package */ | |
| 610 | + atmel,mux-mask = < | |
| 611 | + /* A B C */ | |
| 612 | + 0xffffffff 0xffe03fff 0xef00019d /* pioA */ | |
| 613 | + 0x03ffffff 0x02fc7e7f 0x00780000 /* pioB */ | |
| 614 | + 0xffffffff 0xffffffff 0xf83fffff /* pioC */ | |
| 615 | + 0x003fffff 0x003f8000 0x00000000 /* pioD */ | |
| 616 | + >; | |
| 617 | + | |
| 609 | 618 | pioA: gpio@fffff400 { |
| 610 | 619 | compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
| 611 | 620 | reg = <0xfffff400 0x200>; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | #include <linux/irq.h> |
| 9 | 9 | #include <linux/irqdomain.h> |
| 10 | +#include <linux/irqchip.h> | |
| 10 | 11 | #include <linux/io.h> |
| 11 | 12 | #include <linux/of.h> |
| 12 | 13 | #include <linux/of_address.h> |
| @@ -162,7 +163,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) · 149 unmodified lines | ||
| 162 | 163 | * interrupts. It registers the interrupt enable and disable functions |
| 163 | 164 | * to the kernel for each interrupt source. |
| 164 | 165 | */ |
| 165 | −void __init mxc_init_irq(void __iomem *irqbase) | |
| 166 | +static void __init mxc_init_irq(void __iomem *irqbase) | |
| 166 | 167 | { |
| 167 | 168 | struct device_node *np; |
| 168 | 169 | int irq_base; |
| @@ -220,3 +221,16 @@ void __init mxc_init_irq(void __iomem *irqbase) · 51 unmodified lines | ||
| 220 | 221 | |
| 221 | 222 | printk(KERN_INFO "MXC IRQ initialized\n"); |
| 222 | 223 | } |
| 224 | + | |
| 225 | +static int __init imx_avic_init(struct device_node *node, | |
| 226 | + struct device_node *parent) | |
| 227 | +{ | |
| 228 | + void __iomem *avic_base; | |
| 229 | + | |
| 230 | + avic_base = of_iomap(node, 0); | |
| 231 | + BUG_ON(!avic_base); | |
| 232 | + mxc_init_irq(avic_base); | |
| 233 | + return 0; | |
| 234 | +} | |
| 235 | + | |
| 236 | +IRQCHIP_DECLARE(imx_avic, "fsl,avic", imx_avic_init); | |
| @@ -22,7 +22,6 @@ void mx35_map_io(void); · 21 unmodified lines | ||
| 22 | 22 | void imx21_init_early(void); |
| 23 | 23 | void imx31_init_early(void); |
| 24 | 24 | void imx35_init_early(void); |
| 25 | −void mxc_init_irq(void __iomem *); | |
| 26 | 25 | void mx31_init_irq(void); |
| 27 | 26 | void mx35_init_irq(void); |
| 28 | 27 | void mxc_set_cpu_type(unsigned int type); |
| @@ -17,16 +17,6 @@ static void __init imx1_init_early(void) · 16 unmodified lines | ||
| 17 | 17 | mxc_set_cpu_type(MXC_CPU_MX1); |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | −static void __init imx1_init_irq(void) | |
| 21 | −{ | |
| 22 | − void __iomem *avic_addr; | |
| 23 | − | |
| 24 | − avic_addr = ioremap(MX1_AVIC_ADDR, SZ_4K); | |
| 25 | − WARN_ON(!avic_addr); | |
| 26 | − | |
| 27 | − mxc_init_irq(avic_addr); | |
| 28 | −} | |
| 29 | − | |
| 30 | 20 | static const char * const imx1_dt_board_compat[] __initconst = { |
| 31 | 21 | "fsl,imx1", |
| 32 | 22 | NULL |
| @@ -34,7 +24,6 @@ static const char * const imx1_dt_board_compat[] __initconst = { · 1 unmodified line | ||
| 34 | 24 | |
| 35 | 25 | DT_MACHINE_START(IMX1_DT, "Freescale i.MX1 (Device Tree Support)") |
| 36 | 26 | .init_early = imx1_init_early, |
| 37 | − .init_irq = imx1_init_irq, | |
| 38 | 27 | .dt_compat = imx1_dt_board_compat, |
| 39 | 28 | .restart = mxc_restart, |
| 40 | 29 | MACHINE_END |
| @@ -22,17 +22,6 @@ static void __init imx25_dt_init(void) · 21 unmodified lines | ||
| 22 | 22 | imx_aips_allow_unprivileged_access("fsl,imx25-aips"); |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | −static void __init mx25_init_irq(void) | |
| 26 | −{ | |
| 27 | − struct device_node *np; | |
| 28 | − void __iomem *avic_base; | |
| 29 | − | |
| 30 | − np = of_find_compatible_node(NULL, NULL, "fsl,avic"); | |
| 31 | − avic_base = of_iomap(np, 0); | |
| 32 | − BUG_ON(!avic_base); | |
| 33 | − mxc_init_irq(avic_base); | |
| 34 | −} | |
| 35 | − | |
| 36 | 25 | static const char * const imx25_dt_board_compat[] __initconst = { |
| 37 | 26 | "fsl,imx25", |
| 38 | 27 | NULL |
| @@ -42,6 +31,5 @@ DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") · 3 unmodified lines | ||
| 42 | 31 | .init_early = imx25_init_early, |
| 43 | 32 | .init_machine = imx25_dt_init, |
| 44 | 33 | .init_late = imx25_pm_init, |
| 45 | − .init_irq = mx25_init_irq, | |
| 46 | 34 | .dt_compat = imx25_dt_board_compat, |
| 47 | 35 | MACHINE_END |
| @@ -56,17 +56,6 @@ static void __init imx27_init_early(void) · 55 unmodified lines | ||
| 56 | 56 | mxc_set_cpu_type(MXC_CPU_MX27); |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | −static void __init mx27_init_irq(void) | |
| 60 | −{ | |
| 61 | − void __iomem *avic_base; | |
| 62 | − struct device_node *np; | |
| 63 | − | |
| 64 | − np = of_find_compatible_node(NULL, NULL, "fsl,avic"); | |
| 65 | − avic_base = of_iomap(np, 0); | |
| 66 | − BUG_ON(!avic_base); | |
| 67 | − mxc_init_irq(avic_base); | |
| 68 | −} | |
| 69 | − | |
| 70 | 59 | static const char * const imx27_dt_board_compat[] __initconst = { |
| 71 | 60 | "fsl,imx27", |
| 72 | 61 | NULL |
| @@ -75,7 +64,6 @@ static const char * const imx27_dt_board_compat[] __initconst = { · 2 unmodified lines | ||
| 75 | 64 | DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)") |
| 76 | 65 | .map_io = mx27_map_io, |
| 77 | 66 | .init_early = imx27_init_early, |
| 78 | − .init_irq = mx27_init_irq, | |
| 79 | 67 | .init_late = imx27_pm_init, |
| 80 | 68 | .dt_compat = imx27_dt_board_compat, |
| 81 | 69 | MACHINE_END |
| @@ -14,6 +14,5 @@ static const char * const imx31_dt_board_compat[] __initconst = { · 13 unmodified lines | ||
| 14 | 14 | DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)") |
| 15 | 15 | .map_io = mx31_map_io, |
| 16 | 16 | .init_early = imx31_init_early, |
| 17 | − .init_irq = mx31_init_irq, | |
| 18 | 17 | .dt_compat = imx31_dt_board_compat, |
| 19 | 18 | MACHINE_END |
| @@ -27,6 +27,5 @@ DT_MACHINE_START(IMX35_DT, "Freescale i.MX35 (Device Tree Support)") · 26 unmodified lines | ||
| 27 | 27 | .l2c_aux_mask = ~0, |
| 28 | 28 | .map_io = mx35_map_io, |
| 29 | 29 | .init_early = imx35_init_early, |
| 30 | − .init_irq = mx35_init_irq, | |
| 31 | 30 | .dt_compat = imx35_dt_board_compat, |
| 32 | 31 | MACHINE_END |
| @@ -109,18 +109,6 @@ void __init imx31_init_early(void) · 108 unmodified lines | ||
| 109 | 109 | mx3_ccm_base = of_iomap(np, 0); |
| 110 | 110 | BUG_ON(!mx3_ccm_base); |
| 111 | 111 | } |
| 112 | − | |
| 113 | −void __init mx31_init_irq(void) | |
| 114 | −{ | |
| 115 | − void __iomem *avic_base; | |
| 116 | − struct device_node *np; | |
| 117 | − | |
| 118 | − np = of_find_compatible_node(NULL, NULL, "fsl,imx31-avic"); | |
| 119 | − avic_base = of_iomap(np, 0); | |
| 120 | − BUG_ON(!avic_base); | |
| 121 | − | |
| 122 | − mxc_init_irq(avic_base); | |
| 123 | −} | |
| 124 | 112 | #endif /* ifdef CONFIG_SOC_IMX31 */ |
| 125 | 113 | |
| 126 | 114 | #ifdef CONFIG_SOC_IMX35 |
| @@ -158,16 +146,4 @@ void __init imx35_init_early(void) · 31 unmodified lines | ||
| 158 | 146 | mx3_ccm_base = of_iomap(np, 0); |
| 159 | 147 | BUG_ON(!mx3_ccm_base); |
| 160 | 148 | } |
| 161 | − | |
| 162 | −void __init mx35_init_irq(void) | |
| 163 | −{ | |
| 164 | − void __iomem *avic_base; | |
| 165 | − struct device_node *np; | |
| 166 | − | |
| 167 | − np = of_find_compatible_node(NULL, NULL, "fsl,imx35-avic"); | |
| 168 | − avic_base = of_iomap(np, 0); | |
| 169 | − BUG_ON(!avic_base); | |
| 170 | − | |
| 171 | − mxc_init_irq(avic_base); | |
| 172 | −} | |
| 173 | 149 | #endif /* ifdef CONFIG_SOC_IMX35 */ |
| @@ -88,34 +88,26 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | extern struct omap_sr_data omap_sr_pdata[]; |
| 90 | 90 | |
| 91 | −static int __init sr_dev_init(struct omap_hwmod *oh, void *user) | |
| 91 | +static int __init sr_init_by_name(const char *name, const char *voltdm) | |
| 92 | 92 | { |
| 93 | 93 | struct omap_sr_data *sr_data = NULL; |
| 94 | 94 | struct omap_volt_data *volt_data; |
| 95 | − struct omap_smartreflex_dev_attr *sr_dev_attr; | |
| 96 | 95 | static int i; |
| 97 | 96 | |
| 98 | − if (!strncmp(oh->name, "smartreflex_mpu_iva", 20) || | |
| 99 | − !strncmp(oh->name, "smartreflex_mpu", 16)) | |
| 97 | + if (!strncmp(name, "smartreflex_mpu_iva", 20) || | |
| 98 | + !strncmp(name, "smartreflex_mpu", 16)) | |
| 100 | 99 | sr_data = &omap_sr_pdata[OMAP_SR_MPU]; |
| 101 | − else if (!strncmp(oh->name, "smartreflex_core", 17)) | |
| 100 | + else if (!strncmp(name, "smartreflex_core", 17)) | |
| 102 | 101 | sr_data = &omap_sr_pdata[OMAP_SR_CORE]; |
| 103 | − else if (!strncmp(oh->name, "smartreflex_iva", 16)) | |
| 102 | + else if (!strncmp(name, "smartreflex_iva", 16)) | |
| 104 | 103 | sr_data = &omap_sr_pdata[OMAP_SR_IVA]; |
| 105 | 104 | |
| 106 | 105 | if (!sr_data) { |
| 107 | − pr_err("%s: Unknown instance %s\n", __func__, oh->name); | |
| 106 | + pr_err("%s: Unknown instance %s\n", __func__, name); | |
| 108 | 107 | return -EINVAL; |
| 109 | 108 | } |
| 110 | 109 | |
| 111 | − sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; | |
| 112 | − if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { | |
| 113 | − pr_err("%s: No voltage domain specified for %s. Cannot initialize\n", | |
| 114 | − __func__, oh->name); | |
| 115 | − goto exit; | |
| 116 | − } | |
| 117 | − | |
| 118 | − sr_data->name = oh->name; | |
| 110 | + sr_data->name = name; | |
| 119 | 111 | if (cpu_is_omap343x()) |
| 120 | 112 | sr_data->ip_type = 1; |
| 121 | 113 | else |
| @@ -136,10 +128,10 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) · 14 unmodified lines | ||
| 136 | 128 | } |
| 137 | 129 | } |
| 138 | 130 | |
| 139 | − sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name); | |
| 131 | + sr_data->voltdm = voltdm_lookup(voltdm); | |
| 140 | 132 | if (!sr_data->voltdm) { |
| 141 | 133 | pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", |
| 142 | − __func__, sr_dev_attr->sensor_voltdm_name); | |
| 134 | + __func__, voltdm); | |
| 143 | 135 | goto exit; |
| 144 | 136 | } |
| 145 | 137 | |
| @@ -160,6 +152,20 @@ exit: · 14 unmodified lines | ||
| 160 | 152 | return 0; |
| 161 | 153 | } |
| 162 | 154 | |
| 155 | +static int __init sr_dev_init(struct omap_hwmod *oh, void *user) | |
| 156 | +{ | |
| 157 | + struct omap_smartreflex_dev_attr *sr_dev_attr; | |
| 158 | + | |
| 159 | + sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; | |
| 160 | + if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { | |
| 161 | + pr_err("%s: No voltage domain specified for %s. Cannot initialize\n", | |
| 162 | + __func__, oh->name); | |
| 163 | + return 0; | |
| 164 | + } | |
| 165 | + | |
| 166 | + return sr_init_by_name(oh->name, sr_dev_attr->sensor_voltdm_name); | |
| 167 | +} | |
| 168 | + | |
| 163 | 169 | /* |
| 164 | 170 | * API to be called from board files to enable smartreflex |
| 165 | 171 | * autocompensation at init. |
| @@ -169,7 +175,42 @@ void __init omap_enable_smartreflex_on_init(void) · 3 unmodified lines | ||
| 169 | 175 | sr_enable_on_init = true; |
| 170 | 176 | } |
| 171 | 177 | |
| 178 | +static const char * const omap4_sr_instances[] = { | |
| 179 | + "mpu", | |
| 180 | + "iva", | |
| 181 | + "core", | |
| 182 | +}; | |
| 183 | + | |
| 184 | +static const char * const dra7_sr_instances[] = { | |
| 185 | + "mpu", | |
| 186 | + "core", | |
| 187 | +}; | |
| 188 | + | |
| 172 | 189 | int __init omap_devinit_smartreflex(void) |
| 173 | 190 | { |
| 191 | + const char * const *sr_inst; | |
| 192 | + int i, nr_sr = 0; | |
| 193 | + | |
| 194 | + if (soc_is_omap44xx()) { | |
| 195 | + sr_inst = omap4_sr_instances; | |
| 196 | + nr_sr = ARRAY_SIZE(omap4_sr_instances); | |
| 197 | + | |
| 198 | + } else if (soc_is_dra7xx()) { | |
| 199 | + sr_inst = dra7_sr_instances; | |
| 200 | + nr_sr = ARRAY_SIZE(dra7_sr_instances); | |
| 201 | + } | |
| 202 | + | |
| 203 | + if (nr_sr) { | |
| 204 | + const char *name, *voltdm; | |
| 205 | + | |
| 206 | + for (i = 0; i < nr_sr; i++) { | |
| 207 | + name = kasprintf(GFP_KERNEL, "smartreflex_%s", sr_inst[i]); | |
| 208 | + voltdm = sr_inst[i]; | |
| 209 | + sr_init_by_name(name, voltdm); | |
| 210 | + } | |
| 211 | + | |
| 212 | + return 0; | |
| 213 | + } | |
| 214 | + | |
| 174 | 215 | return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL); |
| 175 | 216 | } |
| @@ -810,6 +810,16 @@ config QCOM_FALKOR_ERRATUM_E1041 · 809 unmodified lines | ||
| 810 | 810 | |
| 811 | 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 | 823 | config SOCIONEXT_SYNQUACER_PREITS |
| 814 | 824 | bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" |
| 815 | 825 | default y |
| @@ -198,6 +198,7 @@ · 197 unmodified lines | ||
| 198 | 198 | ranges = <0x0 0x00 0x1700000 0x100000>; |
| 199 | 199 | reg = <0x00 0x1700000 0x0 0x100000>; |
| 200 | 200 | interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; |
| 201 | + dma-coherent; | |
| 201 | 202 | |
| 202 | 203 | sec_jr0: jr@10000 { |
| 203 | 204 | compatible = "fsl,sec-v5.4-job-ring", |
| @@ -348,6 +348,7 @@ · 347 unmodified lines | ||
| 348 | 348 | ranges = <0x0 0x00 0x1700000 0x100000>; |
| 349 | 349 | reg = <0x00 0x1700000 0x0 0x100000>; |
| 350 | 350 | interrupts = <0 75 0x4>; |
| 351 | + dma-coherent; | |
| 351 | 352 | |
| 352 | 353 | sec_jr0: jr@10000 { |
| 353 | 354 | compatible = "fsl,sec-v5.4-job-ring", |
| @@ -354,6 +354,7 @@ · 353 unmodified lines | ||
| 354 | 354 | ranges = <0x0 0x00 0x1700000 0x100000>; |
| 355 | 355 | reg = <0x00 0x1700000 0x0 0x100000>; |
| 356 | 356 | interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; |
| 357 | + dma-coherent; | |
| 357 | 358 | |
| 358 | 359 | sec_jr0: jr@10000 { |
| 359 | 360 | compatible = "fsl,sec-v5.4-job-ring", |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | &i2c2 { |
| 37 | 37 | clock-frequency = <400000>; |
| 38 | − pinctrl-names = "default"; | |
| 38 | + pinctrl-names = "default", "gpio"; | |
| 39 | 39 | pinctrl-0 = <&pinctrl_i2c2>; |
| 40 | 40 | pinctrl-1 = <&pinctrl_i2c2_gpio>; |
| 41 | 41 | sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; |
| @@ -67,7 +67,7 @@ · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | &i2c1 { |
| 69 | 69 | clock-frequency = <400000>; |
| 70 | − pinctrl-names = "default"; | |
| 70 | + pinctrl-names = "default", "gpio"; | |
| 71 | 71 | pinctrl-0 = <&pinctrl_i2c1>; |
| 72 | 72 | pinctrl-1 = <&pinctrl_i2c1_gpio>; |
| 73 | 73 | sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; |
| @@ -37,7 +37,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) · 36 unmodified lines | ||
| 37 | 37 | } while (--n > 0); |
| 38 | 38 | |
| 39 | 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 | 42 | #define ip_fast_csum ip_fast_csum |
| 43 | 43 | |
| @@ -66,7 +66,8 @@ · 65 unmodified lines | ||
| 66 | 66 | #define ARM64_WORKAROUND_1508412 58 |
| 67 | 67 | #define ARM64_HAS_LDAPR 59 |
| 68 | 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 | 73 | #endif /* __ASM_CPUCAPS_H */ |
| @@ -278,6 +278,7 @@ · 277 unmodified lines | ||
| 278 | 278 | #define CPTR_EL2_DEFAULT CPTR_EL2_RES1 |
| 279 | 279 | |
| 280 | 280 | /* Hyp Debug Configuration Register bits */ |
| 281 | +#define MDCR_EL2_TTRF (1 << 19) | |
| 281 | 282 | #define MDCR_EL2_TPMS (1 << 14) |
| 282 | 283 | #define MDCR_EL2_E2PB_MASK (UL(0x3)) |
| 283 | 284 | #define MDCR_EL2_E2PB_SHIFT (UL(12)) |
| @@ -251,6 +251,8 @@ unsigned long get_wchan(struct task_struct *p); · 250 unmodified lines | ||
| 251 | 251 | extern struct task_struct *cpu_switch_to(struct task_struct *prev, |
| 252 | 252 | struct task_struct *next); |
| 253 | 253 | |
| 254 | +asmlinkage void arm64_preempt_schedule_irq(void); | |
| 255 | + | |
| 254 | 256 | #define task_pt_regs(p) \ |
| 255 | 257 | ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) |
| 256 | 258 | |
| @@ -55,6 +55,8 @@ void arch_setup_new_exec(void); · 54 unmodified lines | ||
| 55 | 55 | #define arch_setup_new_exec arch_setup_new_exec |
| 56 | 56 | |
| 57 | 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 | 61 | #endif |
| 60 | 62 | |
| @@ -525,6 +525,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { · 524 unmodified lines | ||
| 525 | 525 | 0, 0, |
| 526 | 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 | 536 | #endif |
| 529 | 537 | { |
| 530 | 538 | } |
| @@ -383,7 +383,6 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { · 382 unmodified lines | ||
| 383 | 383 | * of support. |
| 384 | 384 | */ |
| 385 | 385 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0), |
| 386 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0), | |
| 387 | 386 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6), |
| 388 | 387 | ARM64_FTR_END, |
| 389 | 388 | }; |
| @@ -1321,7 +1320,10 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) · 931 unmodified lines | ||
| 1321 | 1320 | * may share TLB entries with a CPU stuck in the crashed |
| 1322 | 1321 | * kernel. |
| 1323 | 1322 | */ |
| 1324 | − if (is_kdump_kernel()) | |
| 1323 | + if (is_kdump_kernel()) | |
| 1324 | + return false; | |
| 1325 | + | |
| 1326 | + if (cpus_have_const_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP)) | |
| 1325 | 1327 | return false; |
| 1326 | 1328 | |
| 1327 | 1329 | return has_cpuid_feature(entry, scope); |
| @@ -353,7 +353,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) · 352 unmodified lines | ||
| 353 | 353 | * with the CLIDR_EL1 fields to avoid triggering false warnings |
| 354 | 354 | * when there is a mismatch across the CPUs. Keep track of the |
| 355 | 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 | 358 | info->reg_ctr = read_cpuid_effective_cachetype(); |
| 359 | 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 | 64 | ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) |
| 65 | 65 | { |
| 66 | 66 | memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count); |
| 67 | + *ppos += count; | |
| 68 | + | |
| 67 | 69 | return count; |
| 68 | 70 | } |
| @@ -57,6 +57,8 @@ · 56 unmodified lines | ||
| 57 | 57 | #include <asm/processor.h> |
| 58 | 58 | #include <asm/pointer_auth.h> |
| 59 | 59 | #include <asm/stacktrace.h> |
| 60 | +#include <asm/switch_to.h> | |
| 61 | +#include <asm/system_misc.h> | |
| 60 | 62 | |
| 61 | 63 | #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) |
| 62 | 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 | 195 | #ifdef CONFIG_STACKTRACE |
| 196 | 196 | |
| 197 | −void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, | |
| 198 | − struct task_struct *task, struct pt_regs *regs) | |
| 197 | +noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, | |
| 198 | + void *cookie, struct task_struct *task, | |
| 199 | + struct pt_regs *regs) | |
| 199 | 200 | { |
| 200 | 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 | 204 | start_backtrace(&frame, regs->regs[29], regs->pc); |
| 204 | 205 | else if (task == current) |
| 205 | 206 | start_backtrace(&frame, |
| 206 | − (unsigned long)__builtin_frame_address(0), | |
| 207 | − (unsigned long)arch_stack_walk); | |
| 207 | + (unsigned long)__builtin_frame_address(1), | |
| 208 | + (unsigned long)__builtin_return_address(0)); | |
| 208 | 209 | else |
| 209 | 210 | start_backtrace(&frame, thread_saved_fp(task), |
| 210 | 211 | thread_saved_pc(task)); |
| @@ -89,6 +89,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) · 88 unmodified lines | ||
| 89 | 89 | * - Debug ROM Address (MDCR_EL2_TDRA) |
| 90 | 90 | * - OS related registers (MDCR_EL2_TDOSA) |
| 91 | 91 | * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) |
| 92 | + * - Self-hosted Trace Filter controls (MDCR_EL2_TTRF) | |
| 92 | 93 | * |
| 93 | 94 | * Additionally, KVM only traps guest accesses to the debug registers if |
| 94 | 95 | * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY |
| @@ -112,6 +113,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) · 17 unmodified lines | ||
| 112 | 113 | vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; |
| 113 | 114 | vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | |
| 114 | 115 | MDCR_EL2_TPMS | |
| 116 | + MDCR_EL2_TTRF | | |
| 115 | 117 | MDCR_EL2_TPMCR | |
| 116 | 118 | MDCR_EL2_TDRA | |
| 117 | 119 | MDCR_EL2_TDOSA); |
| @@ -429,6 +429,13 @@ u64 __vgic_v3_get_gic_config(void) · 428 unmodified lines | ||
| 429 | 429 | if (has_vhe()) |
| 430 | 430 | flags = local_daif_save(); |
| 431 | 431 | |
| 432 | + /* | |
| 433 | + * Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates | |
| 434 | + * that to be able to set ICC_SRE_EL1.SRE to 0, all the | |
| 435 | + * interrupt overrides must be set. You've got to love this. | |
| 436 | + */ | |
| 437 | + sysreg_clear_set(hcr_el2, 0, HCR_AMO | HCR_FMO | HCR_IMO); | |
| 438 | + isb(); | |
| 432 | 439 | write_gicreg(0, ICC_SRE_EL1); |
| 433 | 440 | isb(); |
| 434 | 441 | |
| @@ -436,6 +443,8 @@ u64 __vgic_v3_get_gic_config(void) · 1 unmodified line | ||
| 436 | 443 | |
| 437 | 444 | write_gicreg(sre, ICC_SRE_EL1); |
| 438 | 445 | isb(); |
| 446 | + sysreg_clear_set(hcr_el2, HCR_AMO | HCR_FMO | HCR_IMO, 0); | |
| 447 | + isb(); | |
| 439 | 448 | |
| 440 | 449 | if (has_vhe()) |
| 441 | 450 | local_daif_restore(flags); |
| @@ -1448,6 +1448,22 @@ static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size) · 1447 unmodified lines | ||
| 1448 | 1448 | struct range arch_get_mappable_range(void) |
| 1449 | 1449 | { |
| 1450 | 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); | |
| 1451 | 1467 | |
| 1452 | 1468 | /* |
| 1453 | 1469 | * Linear mapping region is the range [PAGE_OFFSET..(PAGE_END - 1)] |
| @@ -1455,8 +1471,9 @@ struct range arch_get_mappable_range(void) · 1 unmodified line | ||
| 1455 | 1471 | * range which can be mapped inside this linear mapping range, must |
| 1456 | 1472 | * also be derived from its end points. |
| 1457 | 1473 | */ |
| 1458 | − mhp_range.start = __pa(_PAGE_OFFSET(vabits_actual)); | |
| 1459 | − mhp_range.end = __pa(PAGE_END - 1); | |
| 1474 | + mhp_range.start = start_linear_pa; | |
| 1475 | + mhp_range.end = end_linear_pa; | |
| 1476 | + | |
| 1460 | 1477 | return mhp_range; |
| 1461 | 1478 | } |
| 1462 | 1479 | |
| @@ -59,7 +59,7 @@ show_##name(struct device *dev, struct device_attribute *attr, \ · 58 unmodified lines | ||
| 59 | 59 | char *buf) \ |
| 60 | 60 | { \ |
| 61 | 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 | 65 | #define store(name) \ |
| @@ -86,9 +86,9 @@ store_call_start(struct device *dev, struct device_attribute *attr, · 20 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | #ifdef ERR_INJ_DEBUG |
| 88 | 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]); | |
| 90 | − printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]); | |
| 91 | − printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n", | |
| 89 | + printk(KERN_DEBUG "err_type_info=%llx,\n", err_type_info[cpu]); | |
| 90 | + printk(KERN_DEBUG "err_struct_info=%llx,\n", err_struct_info[cpu]); | |
| 91 | + printk(KERN_DEBUG "err_data_buffer=%llx, %llx, %llx.\n", | |
| 92 | 92 | err_data_buffer[cpu].data1, |
| 93 | 93 | err_data_buffer[cpu].data2, |
| 94 | 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 | 118 | #ifdef ERR_INJ_DEBUG |
| 119 | 119 | printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); |
| 120 | − printk(KERN_DEBUG "capabilities=%lx,\n", capabilities[cpu]); | |
| 121 | − printk(KERN_DEBUG "resources=%lx\n", resources[cpu]); | |
| 120 | + printk(KERN_DEBUG "capabilities=%llx,\n", capabilities[cpu]); | |
| 121 | + printk(KERN_DEBUG "resources=%llx\n", resources[cpu]); | |
| 122 | 122 | #endif |
| 123 | 123 | return size; |
| 124 | 124 | } |
| @@ -131,7 +131,7 @@ show_virtual_to_phys(struct device *dev, struct device_attribute *attr, · 6 unmodified lines | ||
| 131 | 131 | char *buf) |
| 132 | 132 | { |
| 133 | 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 | 137 | static ssize_t |
| @@ -145,7 +145,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr, · 7 unmodified lines | ||
| 145 | 145 | ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL); |
| 146 | 146 | if (ret<=0) { |
| 147 | 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 | 149 | #endif |
| 150 | 150 | return -EINVAL; |
| 151 | 151 | } |
| @@ -163,7 +163,7 @@ show_err_data_buffer(struct device *dev, · 11 unmodified lines | ||
| 163 | 163 | { |
| 164 | 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 | 167 | err_data_buffer[cpu].data1, |
| 168 | 168 | err_data_buffer[cpu].data2, |
| 169 | 169 | err_data_buffer[cpu].data3); |
| @@ -178,13 +178,13 @@ store_err_data_buffer(struct device *dev, · 8 unmodified lines | ||
| 178 | 178 | int ret; |
| 179 | 179 | |
| 180 | 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 | 182 | err_data_buffer[cpu].data1, |
| 183 | 183 | err_data_buffer[cpu].data2, |
| 184 | 184 | err_data_buffer[cpu].data3, |
| 185 | 185 | cpu); |
| 186 | 186 | #endif |
| 187 | − ret=sscanf(buf, "%lx, %lx, %lx", | |
| 187 | + ret = sscanf(buf, "%llx, %llx, %llx", | |
| 188 | 188 | &err_data_buffer[cpu].data1, |
| 189 | 189 | &err_data_buffer[cpu].data2, |
| 190 | 190 | &err_data_buffer[cpu].data3); |
| @@ -1824,7 +1824,7 @@ ia64_mca_cpu_init(void *cpu_data) · 1823 unmodified lines | ||
| 1824 | 1824 | data = mca_bootmem(); |
| 1825 | 1825 | first_time = 0; |
| 1826 | 1826 | } else |
| 1827 | − data = (void *)__get_free_pages(GFP_KERNEL, | |
| 1827 | + data = (void *)__get_free_pages(GFP_ATOMIC, | |
| 1828 | 1828 | get_order(sz)); |
| 1829 | 1829 | if (!data) |
| 1830 | 1830 | panic("Could not allocate MCA memory for cpu %d\n", |
| @@ -43,7 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | #include <asm/prom.h> |
| 44 | 44 | |
| 45 | 45 | #ifdef CONFIG_MIPS_ELF_APPENDED_DTB |
| 46 | −const char __section(".appended_dtb") __appended_dtb[0x100000]; | |
| 46 | +char __section(".appended_dtb") __appended_dtb[0x100000]; | |
| 47 | 47 | #endif /* CONFIG_MIPS_ELF_APPENDED_DTB */ |
| 48 | 48 | |
| 49 | 49 | struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; |
| @@ -887,7 +887,8 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot, · 886 unmodified lines | ||
| 887 | 887 | |
| 888 | 888 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
| 889 | 889 | |
| 890 | − flags = (newpp & 7) | H_AVPN; | |
| 890 | + flags = (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO)) | H_AVPN; | |
| 891 | + flags |= (newpp & HPTE_R_KEY_HI) >> 48; | |
| 891 | 892 | if (mmu_has_feature(MMU_FTR_KERNEL_RO)) |
| 892 | 893 | /* Move pp0 into bit 8 (IBM 55) */ |
| 893 | 894 | flags |= (newpp & HPTE_R_PP0) >> 55; |
| @@ -452,12 +452,28 @@ static int do_suspend(void) · 451 unmodified lines | ||
| 452 | 452 | return ret; |
| 453 | 453 | } |
| 454 | 454 | |
| 455 | +/** | |
| 456 | + * struct pseries_suspend_info - State shared between CPUs for join/suspend. | |
| 457 | + * @counter: Threads are to increment this upon resuming from suspend | |
| 458 | + * or if an error is received from H_JOIN. The thread which performs | |
| 459 | + * the first increment (i.e. sets it to 1) is responsible for | |
| 460 | + * waking the other threads. | |
| 461 | + * @done: False if join/suspend is in progress. True if the operation is | |
| 462 | + * complete (successful or not). | |
| 463 | + */ | |
| 464 | +struct pseries_suspend_info { | |
| 465 | + atomic_t counter; | |
| 466 | + bool done; | |
| 467 | +}; | |
| 468 | + | |
| 455 | 469 | static int do_join(void *arg) |
| 456 | 470 | { |
| 457 | − atomic_t *counter = arg; | |
| 471 | + struct pseries_suspend_info *info = arg; | |
| 472 | + atomic_t *counter = &info->counter; | |
| 458 | 473 | long hvrc; |
| 459 | 474 | int ret; |
| 460 | 475 | |
| 476 | +retry: | |
| 461 | 477 | /* Must ensure MSR.EE off for H_JOIN. */ |
| 462 | 478 | hard_irq_disable(); |
| 463 | 479 | hvrc = plpar_hcall_norets(H_JOIN); |
| @@ -473,8 +489,20 @@ static int do_join(void *arg) · 9 unmodified lines | ||
| 473 | 489 | case H_SUCCESS: |
| 474 | 490 | /* |
| 475 | 491 | * The suspend is complete and this cpu has received a |
| 476 | − * prod. | |
| 492 | + * prod, or we've received a stray prod from unrelated | |
| 493 | + * code (e.g. paravirt spinlocks) and we need to join | |
| 494 | + * again. | |
| 495 | + * | |
| 496 | + * This barrier orders the return from H_JOIN above vs | |
| 497 | + * the load of info->done. It pairs with the barrier | |
| 498 | + * in the wakeup/prod path below. | |
| 477 | 499 | */ |
| 500 | + smp_mb(); | |
| 501 | + if (READ_ONCE(info->done) == false) { | |
| 502 | + pr_info_ratelimited("premature return from H_JOIN on CPU %i, retrying", | |
| 503 | + smp_processor_id()); | |
| 504 | + goto retry; | |
| 505 | + } | |
| 478 | 506 | ret = 0; |
| 479 | 507 | break; |
| 480 | 508 | case H_BAD_MODE: |
| @@ -488,6 +516,13 @@ static int do_join(void *arg) · 7 unmodified lines | ||
| 488 | 516 | |
| 489 | 517 | if (atomic_inc_return(counter) == 1) { |
| 490 | 518 | pr_info("CPU %u waking all threads\n", smp_processor_id()); |
| 519 | + WRITE_ONCE(info->done, true); | |
| 520 | + /* | |
| 521 | + * This barrier orders the store to info->done vs subsequent | |
| 522 | + * H_PRODs to wake the other CPUs. It pairs with the barrier | |
| 523 | + * in the H_SUCCESS case above. | |
| 524 | + */ | |
| 525 | + smp_mb(); | |
| 491 | 526 | prod_others(); |
| 492 | 527 | } |
| 493 | 528 | /* |
| @@ -535,11 +570,16 @@ static int pseries_suspend(u64 handle) · 41 unmodified lines | ||
| 535 | 570 | int ret; |
| 536 | 571 | |
| 537 | 572 | while (true) { |
| 538 | − atomic_t counter = ATOMIC_INIT(0); | |
| 573 | + struct pseries_suspend_info info; | |
| 539 | 574 | unsigned long vasi_state; |
| 540 | 575 | int vasi_err; |
| 541 | 576 | |
| 542 | − ret = stop_machine(do_join, &counter, cpu_online_mask); | |
| 577 | + info = (struct pseries_suspend_info) { | |
| 578 | + .counter = ATOMIC_INIT(0), | |
| 579 | + .done = false, | |
| 580 | + }; | |
| 581 | + | |
| 582 | + ret = stop_machine(do_join, &info, cpu_online_mask); | |
| 543 | 583 | if (ret == 0) |
| 544 | 584 | break; |
| 545 | 585 | /* |
| @@ -314,7 +314,7 @@ endchoice · 313 unmodified lines | ||
| 314 | 314 | # Common NUMA Features |
| 315 | 315 | config NUMA |
| 316 | 316 | bool "NUMA Memory Allocation and Scheduler Support" |
| 317 | − depends on SMP | |
| 317 | + depends on SMP && MMU | |
| 318 | 318 | select GENERIC_ARCH_NUMA |
| 319 | 319 | select OF_NUMA |
| 320 | 320 | select ARCH_SUPPORTS_NUMA_BALANCING |
| @@ -306,7 +306,9 @@ do { \ · 305 unmodified lines | ||
| 306 | 306 | * data types like structures or arrays. |
| 307 | 307 | * |
| 308 | 308 | * @ptr must have pointer-to-simple-variable type, and @x must be assignable |
| 309 | − * to the result of dereferencing @ptr. | |
| 309 | + * to the result of dereferencing @ptr. The value of @x is copied to avoid | |
| 310 | + * re-ordering where @x is evaluated inside the block that enables user-space | |
| 311 | + * access (thus bypassing user space protection if @x is a function). | |
| 310 | 312 | * |
| 311 | 313 | * Caller must check the pointer with access_ok() before calling this |
| 312 | 314 | * function. |
| @@ -316,12 +318,13 @@ do { \ · 3 unmodified lines | ||
| 316 | 318 | #define __put_user(x, ptr) \ |
| 317 | 319 | ({ \ |
| 318 | 320 | __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ |
| 321 | + __typeof__(*__gu_ptr) __val = (x); \ | |
| 319 | 322 | long __pu_err = 0; \ |
| 320 | 323 | \ |
| 321 | 324 | __chk_user_ptr(__gu_ptr); \ |
| 322 | 325 | \ |
| 323 | 326 | __enable_user_access(); \ |
| 324 | − __put_user_nocheck(x, __gu_ptr, __pu_err); \ | |
| 327 | + __put_user_nocheck(__val, __gu_ptr, __pu_err); \ | |
| 325 | 328 | __disable_user_access(); \ |
| 326 | 329 | \ |
| 327 | 330 | __pu_err; \ |
| @@ -447,6 +447,7 @@ ENDPROC(__switch_to) · 446 unmodified lines | ||
| 447 | 447 | #endif |
| 448 | 448 | |
| 449 | 449 | .section ".rodata" |
| 450 | + .align LGREG | |
| 450 | 451 | /* Exception vector table */ |
| 451 | 452 | ENTRY(excp_vect_table) |
| 452 | 453 | RISCV_PTR do_trap_insn_misaligned |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include <asm/stacktrace.h> |
| 16 | 16 | |
| 17 | −register const unsigned long sp_in_global __asm__("sp"); | |
| 17 | +register unsigned long sp_in_global __asm__("sp"); | |
| 18 | 18 | |
| 19 | 19 | #ifdef CONFIG_FRAME_POINTER |
| 20 | 20 | |
| @@ -216,7 +216,7 @@ void __init kasan_init(void) · 215 unmodified lines | ||
| 216 | 216 | break; |
| 217 | 217 | |
| 218 | 218 | kasan_populate(kasan_mem_to_shadow(start), kasan_mem_to_shadow(end)); |
| 219 | − }; | |
| 219 | + } | |
| 220 | 220 | |
| 221 | 221 | for (i = 0; i < PTRS_PER_PTE; i++) |
| 222 | 222 | set_pte(&kasan_early_shadow_pte[i], |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <vdso/datapage.h> |
| 7 | 7 | |
| 8 | 8 | struct arch_vdso_data { |
| 9 | − __u64 tod_steering_delta; | |
| 9 | + __s64 tod_steering_delta; | |
| 10 | 10 | __u64 tod_steering_end; |
| 11 | 11 | }; |
| 12 | 12 | |
| @@ -80,10 +80,12 @@ void __init time_early_init(void) · 79 unmodified lines | ||
| 80 | 80 | { |
| 81 | 81 | struct ptff_qto qto; |
| 82 | 82 | struct ptff_qui qui; |
| 83 | + int cs; | |
| 83 | 84 | |
| 84 | 85 | /* Initialize TOD steering parameters */ |
| 85 | 86 | tod_steering_end = tod_clock_base.tod; |
| 86 | − vdso_data->arch_data.tod_steering_end = tod_steering_end; | |
| 87 | + for (cs = 0; cs < CS_BASES; cs++) | |
| 88 | + vdso_data[cs].arch_data.tod_steering_end = tod_steering_end; | |
| 87 | 89 | |
| 88 | 90 | if (!test_facility(28)) |
| 89 | 91 | return; |
| @@ -366,6 +368,7 @@ static void clock_sync_global(unsigned long delta) · 276 unmodified lines | ||
| 366 | 368 | { |
| 367 | 369 | unsigned long now, adj; |
| 368 | 370 | struct ptff_qto qto; |
| 371 | + int cs; | |
| 369 | 372 | |
| 370 | 373 | /* Fixup the monotonic sched clock. */ |
| 371 | 374 | tod_clock_base.eitod += delta; |
| @@ -381,7 +384,10 @@ static void clock_sync_global(unsigned long delta) · 9 unmodified lines | ||
| 381 | 384 | panic("TOD clock sync offset %li is too large to drift\n", |
| 382 | 385 | tod_steering_delta); |
| 383 | 386 | tod_steering_end = now + (abs(tod_steering_delta) << 15); |
| 384 | − vdso_data->arch_data.tod_steering_end = tod_steering_end; | |
| 387 | + for (cs = 0; cs < CS_BASES; cs++) { | |
| 388 | + vdso_data[cs].arch_data.tod_steering_end = tod_steering_end; | |
| 389 | + vdso_data[cs].arch_data.tod_steering_delta = tod_steering_delta; | |
| 390 | + } | |
| 385 | 391 | |
| 386 | 392 | /* Update LPAR offset. */ |
| 387 | 393 | if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0) |
| @@ -27,7 +27,7 @@ endif · 26 unmodified lines | ||
| 27 | 27 | REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING \ |
| 28 | 28 | -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ |
| 29 | 29 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ |
| 30 | − -mno-mmx -mno-sse | |
| 30 | + -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) | |
| 31 | 31 | |
| 32 | 32 | REALMODE_CFLAGS += -ffreestanding |
| 33 | 33 | REALMODE_CFLAGS += -fno-stack-protector |
| @@ -132,6 +132,7 @@ void native_play_dead(void); · 131 unmodified lines | ||
| 132 | 132 | void play_dead_common(void); |
| 133 | 133 | void wbinvd_on_cpu(int cpu); |
| 134 | 134 | int wbinvd_on_all_cpus(void); |
| 135 | +bool wakeup_cpu0(void); | |
| 135 | 136 | |
| 136 | 137 | void native_smp_send_reschedule(int cpu); |
| 137 | 138 | void native_send_call_func_ipi(const struct cpumask *mask); |
| @@ -86,18 +86,6 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, · 85 unmodified lines | ||
| 86 | 86 | } |
| 87 | 87 | #endif |
| 88 | 88 | |
| 89 | −/* | |
| 90 | − * The maximum amount of extra memory compared to the base size. The | |
| 91 | − * main scaling factor is the size of struct page. At extreme ratios | |
| 92 | − * of base:extra, all the base memory can be filled with page | |
| 93 | − * structures for the extra memory, leaving no space for anything | |
| 94 | − * else. | |
| 95 | − * | |
| 96 | − * 10x seems like a reasonable balance between scaling flexibility and | |
| 97 | − * leaving a practically usable system. | |
| 98 | − */ | |
| 99 | −#define XEN_EXTRA_MEM_RATIO (10) | |
| 100 | − | |
| 101 | 89 | /* |
| 102 | 90 | * Helper functions to write or read unsigned long values to/from |
| 103 | 91 | * memory, when the access may fault. |
| @@ -1554,10 +1554,18 @@ void __init acpi_boot_table_init(void) · 1553 unmodified lines | ||
| 1554 | 1554 | /* |
| 1555 | 1555 | * Initialize the ACPI boot-time table parser. |
| 1556 | 1556 | */ |
| 1557 | − if (acpi_table_init()) { | |
| 1557 | + if (acpi_locate_initial_tables()) | |
| 1558 | 1558 | disable_acpi(); |
| 1559 | − return; | |
| 1560 | − } | |
| 1559 | + else | |
| 1560 | + acpi_reserve_initial_tables(); | |
| 1561 | +} | |
| 1562 | + | |
| 1563 | +int __init early_acpi_boot_init(void) | |
| 1564 | +{ | |
| 1565 | + if (acpi_disabled) | |
| 1566 | + return 1; | |
| 1567 | + | |
| 1568 | + acpi_table_init_complete(); | |
| 1561 | 1569 | |
| 1562 | 1570 | acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); |
| 1563 | 1571 | |
| @@ -1570,18 +1578,9 @@ void __init acpi_boot_table_init(void) · 6 unmodified lines | ||
| 1570 | 1578 | } else { |
| 1571 | 1579 | printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); |
| 1572 | 1580 | disable_acpi(); |
| 1573 | − return; | |
| 1581 | + return 1; | |
| 1574 | 1582 | } |
| 1575 | 1583 | } |
| 1576 | −} | |
| 1577 | − | |
| 1578 | −int __init early_acpi_boot_init(void) | |
| 1579 | −{ | |
| 1580 | − /* | |
| 1581 | − * If acpi_disabled, bail out | |
| 1582 | − */ | |
| 1583 | − if (acpi_disabled) | |
| 1584 | − return 1; | |
| 1585 | 1584 | |
| 1586 | 1585 | /* |
| 1587 | 1586 | * Process the Multiple APIC Description Table (MADT), if present |
| @@ -1045,6 +1045,9 @@ void __init setup_arch(char **cmdline_p) · 1044 unmodified lines | ||
| 1045 | 1045 | |
| 1046 | 1046 | cleanup_highmap(); |
| 1047 | 1047 | |
| 1048 | + /* Look for ACPI tables and reserve memory occupied by them. */ | |
| 1049 | + acpi_boot_table_init(); | |
| 1050 | + | |
| 1048 | 1051 | memblock_set_current_limit(ISA_END_ADDRESS); |
| 1049 | 1052 | e820__memblock_setup(); |
| 1050 | 1053 | |
| @@ -1136,11 +1139,6 @@ void __init setup_arch(char **cmdline_p) · 85 unmodified lines | ||
| 1136 | 1139 | |
| 1137 | 1140 | early_platform_quirks(); |
| 1138 | 1141 | |
| 1139 | − /* | |
| 1140 | − * Parse the ACPI tables for possible boot-time SMP configuration. | |
| 1141 | − */ | |
| 1142 | − acpi_boot_table_init(); | |
| 1143 | − | |
| 1144 | 1142 | early_acpi_boot_init(); |
| 1145 | 1143 | |
| 1146 | 1144 | initmem_init(); |
| @@ -1659,7 +1659,7 @@ void play_dead_common(void) · 1658 unmodified lines | ||
| 1659 | 1659 | local_irq_disable(); |
| 1660 | 1660 | } |
| 1661 | 1661 | |
| 1662 | −static bool wakeup_cpu0(void) | |
| 1662 | +bool wakeup_cpu0(void) | |
| 1663 | 1663 | { |
| 1664 | 1664 | if (smp_processor_id() == 0 && enable_start_cpu0) |
| 1665 | 1665 | return true; |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | −ccflags-y += -Iarch/x86/kvm | |
| 3 | +ccflags-y += -I $(srctree)/arch/x86/kvm | |
| 4 | 4 | ccflags-$(CONFIG_KVM_WERROR) += -Werror |
| 5 | 5 | |
| 6 | 6 | ifeq ($(CONFIG_FRAME_POINTER),y) |
| @@ -5884,6 +5884,7 @@ static void kvm_recover_nx_lpages(struct kvm *kvm) · 5883 unmodified lines | ||
| 5884 | 5884 | struct kvm_mmu_page *sp; |
| 5885 | 5885 | unsigned int ratio; |
| 5886 | 5886 | LIST_HEAD(invalid_list); |
| 5887 | + bool flush = false; | |
| 5887 | 5888 | ulong to_zap; |
| 5888 | 5889 | |
| 5889 | 5890 | rcu_idx = srcu_read_lock(&kvm->srcu); |
| @@ -5905,19 +5906,19 @@ static void kvm_recover_nx_lpages(struct kvm *kvm) · 15 unmodified lines | ||
| 5905 | 5906 | lpage_disallowed_link); |
| 5906 | 5907 | WARN_ON_ONCE(!sp->lpage_disallowed); |
| 5907 | 5908 | if (is_tdp_mmu_page(sp)) { |
| 5908 | − kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn, | |
| 5909 | − sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level)); | |
| 5909 | + flush = kvm_tdp_mmu_zap_sp(kvm, sp); | |
| 5910 | 5910 | } else { |
| 5911 | 5911 | kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); |
| 5912 | 5912 | WARN_ON_ONCE(sp->lpage_disallowed); |
| 5913 | 5913 | } |
| 5914 | 5914 | |
| 5915 | 5915 | if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { |
| 5916 | − kvm_mmu_commit_zap_page(kvm, &invalid_list); | |
| 5916 | + kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); | |
| 5917 | 5917 | cond_resched_rwlock_write(&kvm->mmu_lock); |
| 5918 | + flush = false; | |
| 5918 | 5919 | } |
| 5919 | 5920 | } |
| 5920 | − kvm_mmu_commit_zap_page(kvm, &invalid_list); | |
| 5921 | + kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); | |
| 5921 | 5922 | |
| 5922 | 5923 | write_unlock(&kvm->mmu_lock); |
| 5923 | 5924 | srcu_read_unlock(&kvm->srcu, rcu_idx); |
| @@ -86,7 +86,7 @@ static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, · 85 unmodified lines | ||
| 86 | 86 | list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) |
| 87 | 87 | |
| 88 | 88 | static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, |
| 89 | − gfn_t start, gfn_t end, bool can_yield); | |
| 89 | + gfn_t start, gfn_t end, bool can_yield, bool flush); | |
| 90 | 90 | |
| 91 | 91 | void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root) |
| 92 | 92 | { |
| @@ -99,7 +99,7 @@ void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root) · 6 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | list_del(&root->link); |
| 101 | 101 | |
| 102 | − zap_gfn_range(kvm, root, 0, max_gfn, false); | |
| 102 | + zap_gfn_range(kvm, root, 0, max_gfn, false, false); | |
| 103 | 103 | |
| 104 | 104 | free_page((unsigned long)root->spt); |
| 105 | 105 | kmem_cache_free(mmu_page_header_cache, root); |
| @@ -668,20 +668,21 @@ static inline bool tdp_mmu_iter_cond_resched(struct kvm *kvm, · 562 unmodified lines | ||
| 668 | 668 | * scheduler needs the CPU or there is contention on the MMU lock. If this |
| 669 | 669 | * function cannot yield, it will not release the MMU lock or reschedule and |
| 670 | 670 | * the caller must ensure it does not supply too large a GFN range, or the |
| 671 | − * operation can cause a soft lockup. | |
| 671 | + * operation can cause a soft lockup. Note, in some use cases a flush may be | |
| 672 | + * required by prior actions. Ensure the pending flush is performed prior to | |
| 673 | + * yielding. | |
| 672 | 674 | */ |
| 673 | 675 | static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, |
| 674 | − gfn_t start, gfn_t end, bool can_yield) | |
| 676 | + gfn_t start, gfn_t end, bool can_yield, bool flush) | |
| 675 | 677 | { |
| 676 | 678 | struct tdp_iter iter; |
| 677 | − bool flush_needed = false; | |
| 678 | 679 | |
| 679 | 680 | rcu_read_lock(); |
| 680 | 681 | |
| 681 | 682 | tdp_root_for_each_pte(iter, root, start, end) { |
| 682 | 683 | if (can_yield && |
| 683 | − tdp_mmu_iter_cond_resched(kvm, &iter, flush_needed)) { | |
| 684 | − flush_needed = false; | |
| 684 | + tdp_mmu_iter_cond_resched(kvm, &iter, flush)) { | |
| 685 | + flush = false; | |
| 685 | 686 | continue; |
| 686 | 687 | } |
| 687 | 688 | |
| @@ -699,11 +700,11 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, · 11 unmodified lines | ||
| 699 | 700 | continue; |
| 700 | 701 | |
| 701 | 702 | tdp_mmu_set_spte(kvm, &iter, 0); |
| 702 | − flush_needed = true; | |
| 703 | + flush = true; | |
| 703 | 704 | } |
| 704 | 705 | |
| 705 | 706 | rcu_read_unlock(); |
| 706 | − return flush_needed; | |
| 707 | + return flush; | |
| 707 | 708 | } |
| 708 | 709 | |
| 709 | 710 | /* |
| @@ -712,13 +713,14 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, · 2 unmodified lines | ||
| 712 | 713 | * SPTEs have been cleared and a TLB flush is needed before releasing the |
| 713 | 714 | * MMU lock. |
| 714 | 715 | */ |
| 715 | −bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end) | |
| 716 | +bool __kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end, | |
| 717 | + bool can_yield) | |
| 716 | 718 | { |
| 717 | 719 | struct kvm_mmu_page *root; |
| 718 | 720 | bool flush = false; |
| 719 | 721 | |
| 720 | 722 | for_each_tdp_mmu_root_yield_safe(kvm, root) |
| 721 | − flush |= zap_gfn_range(kvm, root, start, end, true); | |
| 723 | + flush = zap_gfn_range(kvm, root, start, end, can_yield, flush); | |
| 722 | 724 | |
| 723 | 725 | return flush; |
| 724 | 726 | } |
| @@ -930,7 +932,7 @@ static int zap_gfn_range_hva_wrapper(struct kvm *kvm, · 205 unmodified lines | ||
| 930 | 932 | struct kvm_mmu_page *root, gfn_t start, |
| 931 | 933 | gfn_t end, unsigned long unused) |
| 932 | 934 | { |
| 933 | − return zap_gfn_range(kvm, root, start, end, false); | |
| 935 | + return zap_gfn_range(kvm, root, start, end, false, false); | |
| 934 | 936 | } |
| 935 | 937 | |
| 936 | 938 | int kvm_tdp_mmu_zap_hva_range(struct kvm *kvm, unsigned long start, |
| @@ -8,7 +8,29 @@ · 7 unmodified lines | ||
| 8 | 8 | hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); |
| 9 | 9 | void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root); |
| 10 | 10 | |
| 11 | −bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end); | |
| 11 | +bool __kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end, | |
| 12 | + bool can_yield); | |
| 13 | +static inline bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, | |
| 14 | + gfn_t end) | |
| 15 | +{ | |
| 16 | + return __kvm_tdp_mmu_zap_gfn_range(kvm, start, end, true); | |
| 17 | +} | |
| 18 | +static inline bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp) | |
| 19 | +{ | |
| 20 | + gfn_t end = sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level); | |
| 21 | + | |
| 22 | + /* | |
| 23 | + * Don't allow yielding, as the caller may have a flush pending. Note, | |
| 24 | + * if mmu_lock is held for write, zapping will never yield in this case, | |
| 25 | + * but explicitly disallow it for safety. The TDP MMU does not yield | |
| 26 | + * until it has made forward progress (steps sideways), and when zapping | |
| 27 | + * a single shadow page that it's guaranteed to see (thus the mmu_lock | |
| 28 | + * requirement), its "step sideways" will always step beyond the bounds | |
| 29 | + * of the shadow page's gfn range and stop iterating before yielding. | |
| 30 | + */ | |
| 31 | + lockdep_assert_held_write(&kvm->mmu_lock); | |
| 32 | + return __kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn, end, false); | |
| 33 | +} | |
| 12 | 34 | void kvm_tdp_mmu_zap_all(struct kvm *kvm); |
| 13 | 35 | |
| 14 | 36 | int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, |
| @@ -246,11 +246,18 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control) · 245 unmodified lines | ||
| 246 | 246 | return true; |
| 247 | 247 | } |
| 248 | 248 | |
| 249 | −static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) | |
| 249 | +static bool nested_vmcb_check_save(struct vcpu_svm *svm, struct vmcb *vmcb12) | |
| 250 | 250 | { |
| 251 | 251 | struct kvm_vcpu *vcpu = &svm->vcpu; |
| 252 | 252 | bool vmcb12_lma; |
| 253 | 253 | |
| 254 | + /* | |
| 255 | + * FIXME: these should be done after copying the fields, | |
| 256 | + * to avoid TOC/TOU races. For these save area checks | |
| 257 | + * the possible damage is limited since kvm_set_cr0 and | |
| 258 | + * kvm_set_cr4 handle failure; EFER_SVME is an exception | |
| 259 | + * so it is force-set later in nested_prepare_vmcb_save. | |
| 260 | + */ | |
| 254 | 261 | if ((vmcb12->save.efer & EFER_SVME) == 0) |
| 255 | 262 | return false; |
| 256 | 263 | |
| @@ -271,7 +278,7 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) · 14 unmodified lines | ||
| 271 | 278 | if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) |
| 272 | 279 | return false; |
| 273 | 280 | |
| 274 | − return nested_vmcb_check_controls(&vmcb12->control); | |
| 281 | + return true; | |
| 275 | 282 | } |
| 276 | 283 | |
| 277 | 284 | static void load_nested_vmcb_control(struct vcpu_svm *svm, |
| @@ -396,7 +403,14 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12) · 118 unmodified lines | ||
| 396 | 403 | svm->vmcb->save.gdtr = vmcb12->save.gdtr; |
| 397 | 404 | svm->vmcb->save.idtr = vmcb12->save.idtr; |
| 398 | 405 | kvm_set_rflags(&svm->vcpu, vmcb12->save.rflags | X86_EFLAGS_FIXED); |
| 399 | − svm_set_efer(&svm->vcpu, vmcb12->save.efer); | |
| 406 | + | |
| 407 | + /* | |
| 408 | + * Force-set EFER_SVME even though it is checked earlier on the | |
| 409 | + * VMCB12, because the guest can flip the bit between the check | |
| 410 | + * and now. Clearing EFER_SVME would call svm_free_nested. | |
| 411 | + */ | |
| 412 | + svm_set_efer(&svm->vcpu, vmcb12->save.efer | EFER_SVME); | |
| 413 | + | |
| 400 | 414 | svm_set_cr0(&svm->vcpu, vmcb12->save.cr0); |
| 401 | 415 | svm_set_cr4(&svm->vcpu, vmcb12->save.cr4); |
| 402 | 416 | svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = vmcb12->save.cr2; |
| @@ -468,7 +482,6 @@ int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb12_gpa, · 65 unmodified lines | ||
| 468 | 482 | |
| 469 | 483 | |
| 470 | 484 | svm->nested.vmcb12_gpa = vmcb12_gpa; |
| 471 | − load_nested_vmcb_control(svm, &vmcb12->control); | |
| 472 | 485 | nested_prepare_vmcb_control(svm); |
| 473 | 486 | nested_prepare_vmcb_save(svm, vmcb12); |
| 474 | 487 | |
| @@ -515,7 +528,10 @@ int nested_svm_vmrun(struct vcpu_svm *svm) · 40 unmodified lines | ||
| 515 | 528 | if (WARN_ON_ONCE(!svm->nested.initialized)) |
| 516 | 529 | return -EINVAL; |
| 517 | 530 | |
| 518 | − if (!nested_vmcb_checks(svm, vmcb12)) { | |
| 531 | + load_nested_vmcb_control(svm, &vmcb12->control); | |
| 532 | + | |
| 533 | + if (!nested_vmcb_check_save(svm, vmcb12) || | |
| 534 | + !nested_vmcb_check_controls(&svm->nested.ctl)) { | |
| 519 | 535 | vmcb12->control.exit_code = SVM_EXIT_ERR; |
| 520 | 536 | vmcb12->control.exit_code_hi = 0; |
| 521 | 537 | vmcb12->control.exit_info_1 = 0; |
| @@ -1209,6 +1225,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, · 687 unmodified lines | ||
| 1209 | 1225 | */ |
| 1210 | 1226 | if (!(save->cr0 & X86_CR0_PG)) |
| 1211 | 1227 | goto out_free; |
| 1228 | + if (!(save->efer & EFER_SVME)) | |
| 1229 | + goto out_free; | |
| 1212 | 1230 | |
| 1213 | 1231 | /* |
| 1214 | 1232 | * All checks done, we can enter guest mode. L1 control fields |
| @@ -98,6 +98,8 @@ static enum index msr_to_index(u32 msr) · 97 unmodified lines | ||
| 98 | 98 | static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, |
| 99 | 99 | enum pmu_type type) |
| 100 | 100 | { |
| 101 | + struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu); | |
| 102 | + | |
| 101 | 103 | switch (msr) { |
| 102 | 104 | case MSR_F15H_PERF_CTL0: |
| 103 | 105 | case MSR_F15H_PERF_CTL1: |
| @@ -105,6 +107,9 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, · 1 unmodified line | ||
| 105 | 107 | case MSR_F15H_PERF_CTL3: |
| 106 | 108 | case MSR_F15H_PERF_CTL4: |
| 107 | 109 | case MSR_F15H_PERF_CTL5: |
| 110 | + if (!guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE)) | |
| 111 | + return NULL; | |
| 112 | + fallthrough; | |
| 108 | 113 | case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3: |
| 109 | 114 | if (type != PMU_TYPE_EVNTSEL) |
| 110 | 115 | return NULL; |
| @@ -115,6 +120,9 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, · 4 unmodified lines | ||
| 115 | 120 | case MSR_F15H_PERF_CTR3: |
| 116 | 121 | case MSR_F15H_PERF_CTR4: |
| 117 | 122 | case MSR_F15H_PERF_CTR5: |
| 123 | + if (!guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE)) | |
| 124 | + return NULL; | |
| 125 | + fallthrough; | |
| 118 | 126 | case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3: |
| 119 | 127 | if (type != PMU_TYPE_COUNTER) |
| 120 | 128 | return NULL; |
| @@ -271,8 +271,7 @@ static struct kmem_cache *x86_emulator_cache; · 270 unmodified lines | ||
| 271 | 271 | * When called, it means the previous get/set msr reached an invalid msr. |
| 272 | 272 | * Return true if we want to ignore/silent this failed msr access. |
| 273 | 273 | */ |
| 274 | −static bool kvm_msr_ignored_check(struct kvm_vcpu *vcpu, u32 msr, | |
| 275 | − u64 data, bool write) | |
| 274 | +static bool kvm_msr_ignored_check(u32 msr, u64 data, bool write) | |
| 276 | 275 | { |
| 277 | 276 | const char *op = write ? "wrmsr" : "rdmsr"; |
| 278 | 277 | |
| @@ -1445,7 +1444,7 @@ static int do_get_msr_feature(struct kvm_vcpu *vcpu, unsigned index, u64 *data) · 1166 unmodified lines | ||
| 1445 | 1444 | if (r == KVM_MSR_RET_INVALID) { |
| 1446 | 1445 | /* Unconditionally clear the output for simplicity */ |
| 1447 | 1446 | *data = 0; |
| 1448 | − if (kvm_msr_ignored_check(vcpu, index, 0, false)) | |
| 1447 | + if (kvm_msr_ignored_check(index, 0, false)) | |
| 1449 | 1448 | r = 0; |
| 1450 | 1449 | } |
| 1451 | 1450 | |
| @@ -1620,7 +1619,7 @@ static int kvm_set_msr_ignored_check(struct kvm_vcpu *vcpu, · 168 unmodified lines | ||
| 1620 | 1619 | int ret = __kvm_set_msr(vcpu, index, data, host_initiated); |
| 1621 | 1620 | |
| 1622 | 1621 | if (ret == KVM_MSR_RET_INVALID) |
| 1623 | − if (kvm_msr_ignored_check(vcpu, index, data, true)) | |
| 1622 | + if (kvm_msr_ignored_check(index, data, true)) | |
| 1624 | 1623 | ret = 0; |
| 1625 | 1624 | |
| 1626 | 1625 | return ret; |
| @@ -1658,7 +1657,7 @@ static int kvm_get_msr_ignored_check(struct kvm_vcpu *vcpu, · 31 unmodified lines | ||
| 1658 | 1657 | if (ret == KVM_MSR_RET_INVALID) { |
| 1659 | 1658 | /* Unconditionally clear *data for simplicity */ |
| 1660 | 1659 | *data = 0; |
| 1661 | − if (kvm_msr_ignored_check(vcpu, index, 0, false)) | |
| 1660 | + if (kvm_msr_ignored_check(index, 0, false)) | |
| 1662 | 1661 | ret = 0; |
| 1663 | 1662 | } |
| 1664 | 1663 | |
| @@ -2329,7 +2328,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) · 664 unmodified lines | ||
| 2329 | 2328 | kvm_vcpu_write_tsc_offset(vcpu, offset); |
| 2330 | 2329 | raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); |
| 2331 | 2330 | |
| 2332 | − spin_lock(&kvm->arch.pvclock_gtod_sync_lock); | |
| 2331 | + spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags); | |
| 2333 | 2332 | if (!matched) { |
| 2334 | 2333 | kvm->arch.nr_vcpus_matched_tsc = 0; |
| 2335 | 2334 | } else if (!already_matched) { |
| @@ -2337,7 +2336,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) · 1 unmodified line | ||
| 2337 | 2336 | } |
| 2338 | 2337 | |
| 2339 | 2338 | kvm_track_tsc_matching(vcpu); |
| 2340 | − spin_unlock(&kvm->arch.pvclock_gtod_sync_lock); | |
| 2339 | + spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags); | |
| 2341 | 2340 | } |
| 2342 | 2341 | |
| 2343 | 2342 | static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, |
| @@ -2559,13 +2558,16 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) · 215 unmodified lines | ||
| 2559 | 2558 | int i; |
| 2560 | 2559 | struct kvm_vcpu *vcpu; |
| 2561 | 2560 | struct kvm_arch *ka = &kvm->arch; |
| 2561 | + unsigned long flags; | |
| 2562 | 2562 | |
| 2563 | 2563 | kvm_hv_invalidate_tsc_page(kvm); |
| 2564 | 2564 | |
| 2565 | − spin_lock(&ka->pvclock_gtod_sync_lock); | |
| 2566 | 2565 | kvm_make_mclock_inprogress_request(kvm); |
| 2566 | + | |
| 2567 | 2567 | /* no guest entries from this point */ |
| 2568 | + spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags); | |
| 2568 | 2569 | pvclock_update_vm_gtod_copy(kvm); |
| 2570 | + spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); | |
| 2569 | 2571 | |
| 2570 | 2572 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 2571 | 2573 | kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); |
| @@ -2573,8 +2575,6 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) · 1 unmodified line | ||
| 2573 | 2575 | /* guest entries allowed */ |
| 2574 | 2576 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 2575 | 2577 | kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu); |
| 2576 | − | |
| 2577 | − spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 2578 | 2578 | #endif |
| 2579 | 2579 | } |
| 2580 | 2580 | |
| @@ -2582,17 +2582,18 @@ u64 get_kvmclock_ns(struct kvm *kvm) · 1 unmodified line | ||
| 2582 | 2582 | { |
| 2583 | 2583 | struct kvm_arch *ka = &kvm->arch; |
| 2584 | 2584 | struct pvclock_vcpu_time_info hv_clock; |
| 2585 | + unsigned long flags; | |
| 2585 | 2586 | u64 ret; |
| 2586 | 2587 | |
| 2587 | − spin_lock(&ka->pvclock_gtod_sync_lock); | |
| 2588 | + spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags); | |
| 2588 | 2589 | if (!ka->use_master_clock) { |
| 2589 | − spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 2590 | + spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); | |
| 2590 | 2591 | return get_kvmclock_base_ns() + ka->kvmclock_offset; |
| 2591 | 2592 | } |
| 2592 | 2593 | |
| 2593 | 2594 | hv_clock.tsc_timestamp = ka->master_cycle_now; |
| 2594 | 2595 | hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset; |
| 2595 | − spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 2596 | + spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); | |
| 2596 | 2597 | |
| 2597 | 2598 | /* both __this_cpu_read() and rdtsc() should be on the same cpu */ |
| 2598 | 2599 | get_cpu(); |
| @@ -2686,13 +2687,13 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 87 unmodified lines | ||
| 2686 | 2687 | * If the host uses TSC clock, then passthrough TSC as stable |
| 2687 | 2688 | * to the guest. |
| 2688 | 2689 | */ |
| 2689 | − spin_lock(&ka->pvclock_gtod_sync_lock); | |
| 2690 | + spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags); | |
| 2690 | 2691 | use_master_clock = ka->use_master_clock; |
| 2691 | 2692 | if (use_master_clock) { |
| 2692 | 2693 | host_tsc = ka->master_cycle_now; |
| 2693 | 2694 | kernel_ns = ka->master_kernel_ns; |
| 2694 | 2695 | } |
| 2695 | − spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 2696 | + spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); | |
| 2696 | 2697 | |
| 2697 | 2698 | /* Keep irq disabled to prevent changes to the clock */ |
| 2698 | 2699 | local_irq_save(flags); |
| @@ -5726,6 +5727,7 @@ set_pit2_out: · 3027 unmodified lines | ||
| 5726 | 5727 | } |
| 5727 | 5728 | #endif |
| 5728 | 5729 | case KVM_SET_CLOCK: { |
| 5730 | + struct kvm_arch *ka = &kvm->arch; | |
| 5729 | 5731 | struct kvm_clock_data user_ns; |
| 5730 | 5732 | u64 now_ns; |
| 5731 | 5733 | |
| @@ -5744,8 +5746,22 @@ set_pit2_out: · 12 unmodified lines | ||
| 5744 | 5746 | * pvclock_update_vm_gtod_copy(). |
| 5745 | 5747 | */ |
| 5746 | 5748 | kvm_gen_update_masterclock(kvm); |
| 5747 | − now_ns = get_kvmclock_ns(kvm); | |
| 5748 | − kvm->arch.kvmclock_offset += user_ns.clock - now_ns; | |
| 5749 | + | |
| 5750 | + /* | |
| 5751 | + * This pairs with kvm_guest_time_update(): when masterclock is | |
| 5752 | + * in use, we use master_kernel_ns + kvmclock_offset to set | |
| 5753 | + * unsigned 'system_time' so if we use get_kvmclock_ns() (which | |
| 5754 | + * is slightly ahead) here we risk going negative on unsigned | |
| 5755 | + * 'system_time' when 'user_ns.clock' is very small. | |
| 5756 | + */ | |
| 5757 | + spin_lock_irq(&ka->pvclock_gtod_sync_lock); | |
| 5758 | + if (kvm->arch.use_master_clock) | |
| 5759 | + now_ns = ka->master_kernel_ns; | |
| 5760 | + else | |
| 5761 | + now_ns = get_kvmclock_base_ns(); | |
| 5762 | + ka->kvmclock_offset = user_ns.clock - now_ns; | |
| 5763 | + spin_unlock_irq(&ka->pvclock_gtod_sync_lock); | |
| 5764 | + | |
| 5749 | 5765 | kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE); |
| 5750 | 5766 | break; |
| 5751 | 5767 | } |
| @@ -7724,6 +7740,7 @@ static void kvm_hyperv_tsc_notifier(void) · 1972 unmodified lines | ||
| 7724 | 7740 | struct kvm *kvm; |
| 7725 | 7741 | struct kvm_vcpu *vcpu; |
| 7726 | 7742 | int cpu; |
| 7743 | + unsigned long flags; | |
| 7727 | 7744 | |
| 7728 | 7745 | mutex_lock(&kvm_lock); |
| 7729 | 7746 | list_for_each_entry(kvm, &vm_list, vm_list) |
| @@ -7739,17 +7756,15 @@ static void kvm_hyperv_tsc_notifier(void) · 9 unmodified lines | ||
| 7739 | 7756 | list_for_each_entry(kvm, &vm_list, vm_list) { |
| 7740 | 7757 | struct kvm_arch *ka = &kvm->arch; |
| 7741 | 7758 | |
| 7742 | − spin_lock(&ka->pvclock_gtod_sync_lock); | |
| 7743 | − | |
| 7759 | + spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags); | |
| 7744 | 7760 | pvclock_update_vm_gtod_copy(kvm); |
| 7761 | + spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); | |
| 7745 | 7762 | |
| 7746 | 7763 | kvm_for_each_vcpu(cpu, vcpu, kvm) |
| 7747 | 7764 | kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); |
| 7748 | 7765 | |
| 7749 | 7766 | kvm_for_each_vcpu(cpu, vcpu, kvm) |
| 7750 | 7767 | kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu); |
| 7751 | − | |
| 7752 | − spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 7753 | 7768 | } |
| 7754 | 7769 | mutex_unlock(&kvm_lock); |
| 7755 | 7770 | } |
| @@ -250,7 +250,6 @@ static inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu) · 249 unmodified lines | ||
| 250 | 250 | void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock, int sec_hi_ofs); |
| 251 | 251 | void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); |
| 252 | 252 | |
| 253 | −void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); | |
| 254 | 253 | u64 get_kvmclock_ns(struct kvm *kvm); |
| 255 | 254 | |
| 256 | 255 | int kvm_read_guest_virt(struct kvm_vcpu *vcpu, |
| @@ -262,7 +262,7 @@ static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc) · 261 unmodified lines | ||
| 262 | 262 | if (pgprot_val(old_prot) == pgprot_val(new_prot)) |
| 263 | 263 | return; |
| 264 | 264 | |
| 265 | − pa = pfn << page_level_shift(level); | |
| 265 | + pa = pfn << PAGE_SHIFT; | |
| 266 | 266 | size = page_level_size(level); |
| 267 | 267 | |
| 268 | 268 | /* |
| @@ -1936,7 +1936,7 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog, · 1935 unmodified lines | ||
| 1936 | 1936 | * add rsp, 8 // skip eth_type_trans's frame |
| 1937 | 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 | 1940 | const struct btf_func_model *m, u32 flags, |
| 1941 | 1941 | struct bpf_tramp_progs *tprogs, |
| 1942 | 1942 | void *orig_call) |
| @@ -1975,6 +1975,15 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, · 32 unmodified lines | ||
| 1975 | 1975 | |
| 1976 | 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 | 1987 | if (fentry->nr_progs) |
| 1979 | 1988 | if (invoke_bpf(m, &prog, fentry, stack_size)) |
| 1980 | 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 | 2004 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 1996 | − if (fentry->nr_progs || fmod_ret->nr_progs) | |
| 1997 | − restore_regs(m, &prog, nr_args, stack_size); | |
| 2005 | + restore_regs(m, &prog, nr_args, stack_size); | |
| 1998 | 2006 | |
| 1999 | 2007 | /* call original function */ |
| 2000 | 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 | 2012 | /* remember return value in a stack for bpf prog to access */ |
| 2005 | 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 | 2019 | if (fmod_ret->nr_progs) { |
| @@ -2033,9 +2044,17 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, · 24 unmodified lines | ||
| 2033 | 2044 | * the return value is only updated on the stack and still needs to be |
| 2034 | 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 | 2055 | /* restore original return value back into RAX */ |
| 2038 | 2056 | emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); |
| 2057 | + } | |
| 2039 | 2058 | |
| 2040 | 2059 | EMIT1(0x5B); /* pop rbx */ |
| 2041 | 2060 | EMIT1(0xC9); /* leave */ |
| @@ -2225,7 +2244,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 183 unmodified lines | ||
| 2225 | 2244 | padding = true; |
| 2226 | 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 | 2248 | if (!addrs) { |
| 2230 | 2249 | prog = orig_prog; |
| 2231 | 2250 | goto out_addrs; |
| @@ -2317,7 +2336,7 @@ out_image: · 85 unmodified lines | ||
| 2317 | 2336 | if (image) |
| 2318 | 2337 | bpf_prog_fill_jited_linfo(prog, addrs + 1); |
| 2319 | 2338 | out_addrs: |
| 2320 | − kfree(addrs); | |
| 2339 | + kvfree(addrs); | |
| 2321 | 2340 | kfree(jit_data); |
| 2322 | 2341 | prog->aux->jit_data = NULL; |
| 2323 | 2342 | } |
| @@ -98,8 +98,8 @@ EXPORT_SYMBOL_GPL(xen_p2m_size); · 97 unmodified lines | ||
| 98 | 98 | unsigned long xen_max_p2m_pfn __read_mostly; |
| 99 | 99 | EXPORT_SYMBOL_GPL(xen_max_p2m_pfn); |
| 100 | 100 | |
| 101 | −#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT | |
| 102 | −#define P2M_LIMIT CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT | |
| 101 | +#ifdef CONFIG_XEN_MEMORY_HOTPLUG_LIMIT | |
| 102 | +#define P2M_LIMIT CONFIG_XEN_MEMORY_HOTPLUG_LIMIT | |
| 103 | 103 | #else |
| 104 | 104 | #define P2M_LIMIT 0 |
| 105 | 105 | #endif |
| @@ -416,9 +416,6 @@ void __init xen_vmalloc_p2m_tree(void) · 310 unmodified lines | ||
| 416 | 416 | xen_p2m_last_pfn = xen_max_p2m_pfn; |
| 417 | 417 | |
| 418 | 418 | p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE; |
| 419 | − if (!p2m_limit && IS_ENABLED(CONFIG_XEN_UNPOPULATED_ALLOC)) | |
| 420 | − p2m_limit = xen_start_info->nr_pages * XEN_EXTRA_MEM_RATIO; | |
| 421 | − | |
| 422 | 419 | vm.flags = VM_ALLOC; |
| 423 | 420 | vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit), |
| 424 | 421 | PMD_SIZE * PMDS_PER_MID_PAGE); |
| @@ -59,6 +59,18 @@ static struct { · 58 unmodified lines | ||
| 59 | 59 | } xen_remap_buf __initdata __aligned(PAGE_SIZE); |
| 60 | 60 | static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY; |
| 61 | 61 | |
| 62 | +/* | |
| 63 | + * The maximum amount of extra memory compared to the base size. The | |
| 64 | + * main scaling factor is the size of struct page. At extreme ratios | |
| 65 | + * of base:extra, all the base memory can be filled with page | |
| 66 | + * structures for the extra memory, leaving no space for anything | |
| 67 | + * else. | |
| 68 | + * | |
| 69 | + * 10x seems like a reasonable balance between scaling flexibility and | |
| 70 | + * leaving a practically usable system. | |
| 71 | + */ | |
| 72 | +#define EXTRA_MEM_RATIO (10) | |
| 73 | + | |
| 62 | 74 | static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB); |
| 63 | 75 | |
| 64 | 76 | static void __init xen_parse_512gb(void) |
| @@ -778,13 +790,13 @@ char * __init xen_memory_setup(void) · 713 unmodified lines | ||
| 778 | 790 | extra_pages += max_pages - max_pfn; |
| 779 | 791 | |
| 780 | 792 | /* |
| 781 | − * Clamp the amount of extra memory to a XEN_EXTRA_MEM_RATIO | |
| 793 | + * Clamp the amount of extra memory to a EXTRA_MEM_RATIO | |
| 782 | 794 | * factor the base size. |
| 783 | 795 | * |
| 784 | 796 | * Make sure we have no memory above max_pages, as this area |
| 785 | 797 | * isn't handled by the p2m management. |
| 786 | 798 | */ |
| 787 | − extra_pages = min3(XEN_EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), | |
| 799 | + extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), | |
| 788 | 800 | extra_pages, max_pages - max_pfn); |
| 789 | 801 | i = 0; |
| 790 | 802 | addr = xen_e820_table.entries[0].addr; |
| @@ -99,37 +99,6 @@ · 98 unmodified lines | ||
| 99 | 99 | LOAD_CP_REGS_TAB(6) |
| 100 | 100 | LOAD_CP_REGS_TAB(7) |
| 101 | 101 | |
| 102 | −/* | |
| 103 | − * coprocessor_flush(struct thread_info*, index) | |
| 104 | − * a2 a3 | |
| 105 | − * | |
| 106 | − * Save coprocessor registers for coprocessor 'index'. | |
| 107 | − * The register values are saved to or loaded from the coprocessor area | |
| 108 | − * inside the task_info structure. | |
| 109 | − * | |
| 110 | − * Note that this function doesn't update the coprocessor_owner information! | |
| 111 | − * | |
| 112 | − */ | |
| 113 | − | |
| 114 | −ENTRY(coprocessor_flush) | |
| 115 | − | |
| 116 | − /* reserve 4 bytes on stack to save a0 */ | |
| 117 | − abi_entry(4) | |
| 118 | − | |
| 119 | − s32i a0, a1, 0 | |
| 120 | − movi a0, .Lsave_cp_regs_jump_table | |
| 121 | − addx8 a3, a3, a0 | |
| 122 | − l32i a4, a3, 4 | |
| 123 | − l32i a3, a3, 0 | |
| 124 | − add a2, a2, a4 | |
| 125 | − beqz a3, 1f | |
| 126 | − callx0 a3 | |
| 127 | −1: l32i a0, a1, 0 | |
| 128 | − | |
| 129 | − abi_ret(4) | |
| 130 | − | |
| 131 | −ENDPROC(coprocessor_flush) | |
| 132 | − | |
| 133 | 102 | /* |
| 134 | 103 | * Entry condition: |
| 135 | 104 | * |
| @@ -245,6 +214,39 @@ ENTRY(fast_coprocessor) · 109 unmodified lines | ||
| 245 | 214 | |
| 246 | 215 | ENDPROC(fast_coprocessor) |
| 247 | 216 | |
| 217 | + .text | |
| 218 | + | |
| 219 | +/* | |
| 220 | + * coprocessor_flush(struct thread_info*, index) | |
| 221 | + * a2 a3 | |
| 222 | + * | |
| 223 | + * Save coprocessor registers for coprocessor 'index'. | |
| 224 | + * The register values are saved to or loaded from the coprocessor area | |
| 225 | + * inside the task_info structure. | |
| 226 | + * | |
| 227 | + * Note that this function doesn't update the coprocessor_owner information! | |
| 228 | + * | |
| 229 | + */ | |
| 230 | + | |
| 231 | +ENTRY(coprocessor_flush) | |
| 232 | + | |
| 233 | + /* reserve 4 bytes on stack to save a0 */ | |
| 234 | + abi_entry(4) | |
| 235 | + | |
| 236 | + s32i a0, a1, 0 | |
| 237 | + movi a0, .Lsave_cp_regs_jump_table | |
| 238 | + addx8 a3, a3, a0 | |
| 239 | + l32i a4, a3, 4 | |
| 240 | + l32i a3, a3, 0 | |
| 241 | + add a2, a2, a4 | |
| 242 | + beqz a3, 1f | |
| 243 | + callx0 a3 | |
| 244 | +1: l32i a0, a1, 0 | |
| 245 | + | |
| 246 | + abi_ret(4) | |
| 247 | + | |
| 248 | +ENDPROC(coprocessor_flush) | |
| 249 | + | |
| 248 | 250 | .data |
| 249 | 251 | |
| 250 | 252 | ENTRY(coprocessor_owner) |
| @@ -112,8 +112,11 @@ good_area: · 111 unmodified lines | ||
| 112 | 112 | */ |
| 113 | 113 | fault = handle_mm_fault(vma, address, flags, regs); |
| 114 | 114 | |
| 115 | − if (fault_signal_pending(fault, regs)) | |
| 115 | + if (fault_signal_pending(fault, regs)) { | |
| 116 | + if (!user_mode(regs)) | |
| 117 | + goto bad_page_fault; | |
| 116 | 118 | return; |
| 119 | + } | |
| 117 | 120 | |
| 118 | 121 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 119 | 122 | if (fault & VM_FAULT_OOM) |
| @@ -277,7 +277,7 @@ static struct bio *__bio_chain_endio(struct bio *bio) · 276 unmodified lines | ||
| 277 | 277 | { |
| 278 | 278 | struct bio *parent = bio->bi_private; |
| 279 | 279 | |
| 280 | − if (!parent->bi_status) | |
| 280 | + if (bio->bi_status && !parent->bi_status) | |
| 281 | 281 | parent->bi_status = bio->bi_status; |
| 282 | 282 | bio_put(bio); |
| 283 | 283 | return parent; |
| @@ -949,7 +949,7 @@ void bio_release_pages(struct bio *bio, bool mark_dirty) · 665 unmodified lines | ||
| 949 | 949 | } |
| 950 | 950 | EXPORT_SYMBOL_GPL(bio_release_pages); |
| 951 | 951 | |
| 952 | −static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) | |
| 952 | +static void __bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) | |
| 953 | 953 | { |
| 954 | 954 | WARN_ON_ONCE(bio->bi_max_vecs); |
| 955 | 955 | |
| @@ -959,11 +959,26 @@ static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) · 3 unmodified lines | ||
| 959 | 959 | bio->bi_iter.bi_size = iter->count; |
| 960 | 960 | bio_set_flag(bio, BIO_NO_PAGE_REF); |
| 961 | 961 | bio_set_flag(bio, BIO_CLONED); |
| 962 | +} | |
| 962 | 963 | |
| 964 | +static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) | |
| 965 | +{ | |
| 966 | + __bio_iov_bvec_set(bio, iter); | |
| 963 | 967 | iov_iter_advance(iter, iter->count); |
| 964 | 968 | return 0; |
| 965 | 969 | } |
| 966 | 970 | |
| 971 | +static int bio_iov_bvec_set_append(struct bio *bio, struct iov_iter *iter) | |
| 972 | +{ | |
| 973 | + struct request_queue *q = bio->bi_bdev->bd_disk->queue; | |
| 974 | + struct iov_iter i = *iter; | |
| 975 | + | |
| 976 | + iov_iter_truncate(&i, queue_max_zone_append_sectors(q) << 9); | |
| 977 | + __bio_iov_bvec_set(bio, &i); | |
| 978 | + iov_iter_advance(iter, i.count); | |
| 979 | + return 0; | |
| 980 | +} | |
| 981 | + | |
| 967 | 982 | #define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *)) |
| 968 | 983 | |
| 969 | 984 | /** |
| @@ -1094,8 +1109,8 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) · 124 unmodified lines | ||
| 1094 | 1109 | int ret = 0; |
| 1095 | 1110 | |
| 1096 | 1111 | if (iov_iter_is_bvec(iter)) { |
| 1097 | − if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND)) | |
| 1098 | − return -EINVAL; | |
| 1112 | + if (bio_op(bio) == REQ_OP_ZONE_APPEND) | |
| 1113 | + return bio_iov_bvec_set_append(bio, iter); | |
| 1099 | 1114 | return bio_iov_bvec_set(bio, iter); |
| 1100 | 1115 | } |
| 1101 | 1116 | |
| @@ -382,6 +382,14 @@ unsigned int blk_recalc_rq_segments(struct request *rq) · 381 unmodified lines | ||
| 382 | 382 | switch (bio_op(rq->bio)) { |
| 383 | 383 | case REQ_OP_DISCARD: |
| 384 | 384 | case REQ_OP_SECURE_ERASE: |
| 385 | + if (queue_max_discard_segments(rq->q) > 1) { | |
| 386 | + struct bio *bio = rq->bio; | |
| 387 | + | |
| 388 | + for_each_bio(bio) | |
| 389 | + nr_phys_segs++; | |
| 390 | + return nr_phys_segs; | |
| 391 | + } | |
| 392 | + return 1; | |
| 385 | 393 | case REQ_OP_WRITE_ZEROES: |
| 386 | 394 | return 0; |
| 387 | 395 | case REQ_OP_WRITE_SAME: |
| @@ -302,7 +302,6 @@ static const char *const rqf_name[] = { · 301 unmodified lines | ||
| 302 | 302 | RQF_NAME(QUIET), |
| 303 | 303 | RQF_NAME(ELVPRIV), |
| 304 | 304 | RQF_NAME(IO_STAT), |
| 305 | − RQF_NAME(ALLOCED), | |
| 306 | 305 | RQF_NAME(PM), |
| 307 | 306 | RQF_NAME(HASHED), |
| 308 | 307 | RQF_NAME(STATS), |
| @@ -322,6 +322,13 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, · 321 unmodified lines | ||
| 322 | 322 | const char *dname; |
| 323 | 323 | int err; |
| 324 | 324 | |
| 325 | + /* | |
| 326 | + * disk_max_parts() won't be zero, either GENHD_FL_EXT_DEVT is set | |
| 327 | + * or 'minors' is passed to alloc_disk(). | |
| 328 | + */ | |
| 329 | + if (partno >= disk_max_parts(disk)) | |
| 330 | + return ERR_PTR(-EINVAL); | |
| 331 | + | |
| 325 | 332 | /* |
| 326 | 333 | * Partitions are not supported on zoned block devices that are used as |
| 327 | 334 | * such. |
| @@ -99,13 +99,12 @@ acpi_status acpi_ns_root_initialize(void) · 98 unmodified lines | ||
| 99 | 99 | * just create and link the new node(s) here. |
| 100 | 100 | */ |
| 101 | 101 | new_node = |
| 102 | − ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node)); | |
| 102 | + acpi_ns_create_node(*ACPI_CAST_PTR(u32, init_val->name)); | |
| 103 | 103 | if (!new_node) { |
| 104 | 104 | status = AE_NO_MEMORY; |
| 105 | 105 | goto unlock_and_exit; |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | − ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name); | |
| 109 | 108 | new_node->descriptor_type = ACPI_DESC_TYPE_NAMED; |
| 110 | 109 | new_node->type = init_val->type; |
| 111 | 110 | |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | #ifndef _ACPI_INTERNAL_H_ |
| 10 | 10 | #define _ACPI_INTERNAL_H_ |
| 11 | 11 | |
| 12 | +#include <linux/idr.h> | |
| 13 | + | |
| 12 | 14 | #define PREFIX "ACPI: " |
| 13 | 15 | |
| 14 | 16 | int early_acpi_osi_init(void); |
| @@ -96,9 +98,11 @@ void acpi_scan_table_handler(u32 event, void *table, void *context); · 81 unmodified lines | ||
| 96 | 98 | |
| 97 | 99 | extern struct list_head acpi_bus_id_list; |
| 98 | 100 | |
| 101 | +#define ACPI_MAX_DEVICE_INSTANCES 4096 | |
| 102 | + | |
| 99 | 103 | struct acpi_device_bus_id { |
| 100 | 104 | const char *bus_id; |
| 101 | − unsigned int instance_no; | |
| 105 | + struct ida instance_ida; | |
| 102 | 106 | struct list_head node; |
| 103 | 107 | }; |
| 104 | 108 | |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | */ |
| 30 | 30 | #ifdef CONFIG_X86 |
| 31 | 31 | #include <asm/apic.h> |
| 32 | +#include <asm/cpu.h> | |
| 32 | 33 | #endif |
| 33 | 34 | |
| 34 | 35 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
| @@ -541,6 +542,12 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) · 506 unmodified lines | ||
| 541 | 542 | wait_for_freeze(); |
| 542 | 543 | } else |
| 543 | 544 | return -ENODEV; |
| 545 | + | |
| 546 | +#if defined(CONFIG_X86) && defined(CONFIG_HOTPLUG_CPU) | |
| 547 | + /* If NMI wants to wake up CPU0, start CPU0. */ | |
| 548 | + if (wakeup_cpu0()) | |
| 549 | + start_cpu0(); | |
| 550 | +#endif | |
| 544 | 551 | } |
| 545 | 552 | |
| 546 | 553 | /* Never reached */ |
| @@ -479,9 +479,8 @@ static void acpi_device_del(struct acpi_device *device) · 478 unmodified lines | ||
| 479 | 479 | list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) |
| 480 | 480 | if (!strcmp(acpi_device_bus_id->bus_id, |
| 481 | 481 | acpi_device_hid(device))) { |
| 482 | − if (acpi_device_bus_id->instance_no > 0) | |
| 483 | − acpi_device_bus_id->instance_no--; | |
| 484 | − else { | |
| 482 | + ida_simple_remove(&acpi_device_bus_id->instance_ida, device->pnp.instance_no); | |
| 483 | + if (ida_is_empty(&acpi_device_bus_id->instance_ida)) { | |
| 485 | 484 | list_del(&acpi_device_bus_id->node); |
| 486 | 485 | kfree_const(acpi_device_bus_id->bus_id); |
| 487 | 486 | kfree(acpi_device_bus_id); |
| @@ -631,6 +630,21 @@ static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id) · 143 unmodified lines | ||
| 631 | 630 | return NULL; |
| 632 | 631 | } |
| 633 | 632 | |
| 633 | +static int acpi_device_set_name(struct acpi_device *device, | |
| 634 | + struct acpi_device_bus_id *acpi_device_bus_id) | |
| 635 | +{ | |
| 636 | + struct ida *instance_ida = &acpi_device_bus_id->instance_ida; | |
| 637 | + int result; | |
| 638 | + | |
| 639 | + result = ida_simple_get(instance_ida, 0, ACPI_MAX_DEVICE_INSTANCES, GFP_KERNEL); | |
| 640 | + if (result < 0) | |
| 641 | + return result; | |
| 642 | + | |
| 643 | + device->pnp.instance_no = result; | |
| 644 | + dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, result); | |
| 645 | + return 0; | |
| 646 | +} | |
| 647 | + | |
| 634 | 648 | int acpi_device_add(struct acpi_device *device, |
| 635 | 649 | void (*release)(struct device *)) |
| 636 | 650 | { |
| @@ -665,7 +679,9 @@ int acpi_device_add(struct acpi_device *device, · 28 unmodified lines | ||
| 665 | 679 | |
| 666 | 680 | acpi_device_bus_id = acpi_device_bus_id_match(acpi_device_hid(device)); |
| 667 | 681 | if (acpi_device_bus_id) { |
| 668 | − acpi_device_bus_id->instance_no++; | |
| 682 | + result = acpi_device_set_name(device, acpi_device_bus_id); | |
| 683 | + if (result) | |
| 684 | + goto err_unlock; | |
| 669 | 685 | } else { |
| 670 | 686 | acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id), |
| 671 | 687 | GFP_KERNEL); |
| @@ -681,9 +697,16 @@ int acpi_device_add(struct acpi_device *device, · 9 unmodified lines | ||
| 681 | 697 | goto err_unlock; |
| 682 | 698 | } |
| 683 | 699 | |
| 700 | + ida_init(&acpi_device_bus_id->instance_ida); | |
| 701 | + | |
| 702 | + result = acpi_device_set_name(device, acpi_device_bus_id); | |
| 703 | + if (result) { | |
| 704 | + kfree(acpi_device_bus_id); | |
| 705 | + goto err_unlock; | |
| 706 | + } | |
| 707 | + | |
| 684 | 708 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
| 685 | 709 | } |
| 686 | − dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); | |
| 687 | 710 | |
| 688 | 711 | if (device->parent) |
| 689 | 712 | list_add_tail(&device->node, &device->parent->children); |
| @@ -1647,6 +1670,8 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, · 957 unmodified lines | ||
| 1647 | 1670 | device_initialize(&device->dev); |
| 1648 | 1671 | dev_set_uevent_suppress(&device->dev, true); |
| 1649 | 1672 | acpi_init_coherency(device); |
| 1673 | + /* Assume there are unmet deps to start with. */ | |
| 1674 | + device->dep_unmet = 1; | |
| 1650 | 1675 | } |
| 1651 | 1676 | |
| 1652 | 1677 | void acpi_device_add_finalize(struct acpi_device *device) |
| @@ -1910,6 +1935,8 @@ static void acpi_scan_dep_init(struct acpi_device *adev) · 257 unmodified lines | ||
| 1910 | 1935 | { |
| 1911 | 1936 | struct acpi_dep_data *dep; |
| 1912 | 1937 | |
| 1938 | + adev->dep_unmet = 0; | |
| 1939 | + | |
| 1913 | 1940 | mutex_lock(&acpi_dep_list_lock); |
| 1914 | 1941 | |
| 1915 | 1942 | list_for_each_entry(dep, &acpi_dep_list, node) { |
| @@ -1957,7 +1984,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep, · 41 unmodified lines | ||
| 1957 | 1984 | return AE_CTRL_DEPTH; |
| 1958 | 1985 | |
| 1959 | 1986 | acpi_scan_init_hotplug(device); |
| 1960 | − if (!check_dep) | |
| 1987 | + /* | |
| 1988 | + * If check_dep is true at this point, the device has no dependencies, | |
| 1989 | + * or the creation of the device object would have been postponed above. | |
| 1990 | + */ | |
| 1991 | + if (check_dep) | |
| 1992 | + device->dep_unmet = 0; | |
| 1993 | + else | |
| 1961 | 1994 | acpi_scan_dep_init(device); |
| 1962 | 1995 | |
| 1963 | 1996 | out: |
| @@ -780,7 +780,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table, · 779 unmodified lines | ||
| 780 | 780 | } |
| 781 | 781 | |
| 782 | 782 | /* |
| 783 | − * acpi_table_init() | |
| 783 | + * acpi_locate_initial_tables() | |
| 784 | 784 | * |
| 785 | 785 | * find RSDP, find and checksum SDT/XSDT. |
| 786 | 786 | * checksum all tables, print SDT/XSDT |
| @@ -788,7 +788,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table, · 1 unmodified line | ||
| 788 | 788 | * result: sdt_entry[] is initialized |
| 789 | 789 | */ |
| 790 | 790 | |
| 791 | −int __init acpi_table_init(void) | |
| 791 | +int __init acpi_locate_initial_tables(void) | |
| 792 | 792 | { |
| 793 | 793 | acpi_status status; |
| 794 | 794 | |
| @@ -803,9 +803,45 @@ int __init acpi_table_init(void) · 8 unmodified lines | ||
| 803 | 803 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); |
| 804 | 804 | if (ACPI_FAILURE(status)) |
| 805 | 805 | return -EINVAL; |
| 806 | − acpi_table_initrd_scan(); | |
| 807 | 806 | |
| 807 | + return 0; | |
| 808 | +} | |
| 809 | + | |
| 810 | +void __init acpi_reserve_initial_tables(void) | |
| 811 | +{ | |
| 812 | + int i; | |
| 813 | + | |
| 814 | + for (i = 0; i < ACPI_MAX_TABLES; i++) { | |
| 815 | + struct acpi_table_desc *table_desc = &initial_tables[i]; | |
| 816 | + u64 start = table_desc->address; | |
| 817 | + u64 size = table_desc->length; | |
| 818 | + | |
| 819 | + if (!start || !size) | |
| 820 | + break; | |
| 821 | + | |
| 822 | + pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n", | |
| 823 | + table_desc->signature.ascii, start, start + size - 1); | |
| 824 | + | |
| 825 | + memblock_reserve(start, size); | |
| 826 | + } | |
| 827 | +} | |
| 828 | + | |
| 829 | +void __init acpi_table_init_complete(void) | |
| 830 | +{ | |
| 831 | + acpi_table_initrd_scan(); | |
| 808 | 832 | check_multiple_madt(); |
| 833 | +} | |
| 834 | + | |
| 835 | +int __init acpi_table_init(void) | |
| 836 | +{ | |
| 837 | + int ret; | |
| 838 | + | |
| 839 | + ret = acpi_locate_initial_tables(); | |
| 840 | + if (ret) | |
| 841 | + return ret; | |
| 842 | + | |
| 843 | + acpi_table_init_complete(); | |
| 844 | + | |
| 809 | 845 | return 0; |
| 810 | 846 | } |
| 811 | 847 | |
| @@ -147,6 +147,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { · 146 unmodified lines | ||
| 147 | 147 | }, |
| 148 | 148 | }, |
| 149 | 149 | { |
| 150 | + .callback = video_detect_force_vendor, | |
| 150 | 151 | .ident = "Sony VPCEH3U1E", |
| 151 | 152 | .matches = { |
| 152 | 153 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
| @@ -470,12 +470,14 @@ static ssize_t charlcd_write(struct file *file, const char __user *buf, · 469 unmodified lines | ||
| 470 | 470 | char c; |
| 471 | 471 | |
| 472 | 472 | for (; count-- > 0; (*ppos)++, tmp++) { |
| 473 | − if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) | |
| 473 | + if (((count + 1) & 0x1f) == 0) { | |
| 474 | 474 | /* |
| 475 | − * let's be a little nice with other processes | |
| 476 | − * that need some CPU | |
| 475 | + * charlcd_write() is invoked as a VFS->write() callback | |
| 476 | + * and as such it is always invoked from preemptible | |
| 477 | + * context and may sleep. | |
| 477 | 478 | */ |
| 478 | − schedule(); | |
| 479 | + cond_resched(); | |
| 480 | + } | |
| 479 | 481 | |
| 480 | 482 | if (get_user(c, tmp)) |
| 481 | 483 | return -EFAULT; |
| @@ -537,12 +539,8 @@ static void charlcd_puts(struct charlcd *lcd, const char *s) · 55 unmodified lines | ||
| 537 | 539 | int count = strlen(s); |
| 538 | 540 | |
| 539 | 541 | for (; count-- > 0; tmp++) { |
| 540 | − if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) | |
| 541 | − /* | |
| 542 | − * let's be a little nice with other processes | |
| 543 | − * that need some CPU | |
| 544 | − */ | |
| 545 | − schedule(); | |
| 542 | + if (((count + 1) & 0x1f) == 0) | |
| 543 | + cond_resched(); | |
| 546 | 544 | |
| 547 | 545 | charlcd_write_char(lcd, *tmp); |
| 548 | 546 | } |
| @@ -97,6 +97,9 @@ static void deferred_probe_work_func(struct work_struct *work) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | get_device(dev); |
| 99 | 99 | |
| 100 | + kfree(dev->p->deferred_probe_reason); | |
| 101 | + dev->p->deferred_probe_reason = NULL; | |
| 102 | + | |
| 100 | 103 | /* |
| 101 | 104 | * Drop the mutex while probing each device; the probe path may |
| 102 | 105 | * manipulate the deferred list |
| @@ -305,7 +305,7 @@ static int rpm_get_suppliers(struct device *dev) · 304 unmodified lines | ||
| 305 | 305 | return 0; |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | −static void rpm_put_suppliers(struct device *dev) | |
| 308 | +static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend) | |
| 309 | 309 | { |
| 310 | 310 | struct device_link *link; |
| 311 | 311 | |
| @@ -313,10 +313,30 @@ static void rpm_put_suppliers(struct device *dev) · 1 unmodified line | ||
| 313 | 313 | device_links_read_lock_held()) { |
| 314 | 314 | |
| 315 | 315 | while (refcount_dec_not_one(&link->rpm_active)) |
| 316 | − pm_runtime_put(link->supplier); | |
| 316 | + pm_runtime_put_noidle(link->supplier); | |
| 317 | + | |
| 318 | + if (try_to_suspend) | |
| 319 | + pm_request_idle(link->supplier); | |
| 317 | 320 | } |
| 318 | 321 | } |
| 319 | 322 | |
| 323 | +static void rpm_put_suppliers(struct device *dev) | |
| 324 | +{ | |
| 325 | + __rpm_put_suppliers(dev, true); | |
| 326 | +} | |
| 327 | + | |
| 328 | +static void rpm_suspend_suppliers(struct device *dev) | |
| 329 | +{ | |
| 330 | + struct device_link *link; | |
| 331 | + int idx = device_links_read_lock(); | |
| 332 | + | |
| 333 | + list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, | |
| 334 | + device_links_read_lock_held()) | |
| 335 | + pm_request_idle(link->supplier); | |
| 336 | + | |
| 337 | + device_links_read_unlock(idx); | |
| 338 | +} | |
| 339 | + | |
| 320 | 340 | /** |
| 321 | 341 | * __rpm_callback - Run a given runtime PM callback for a given device. |
| 322 | 342 | * @cb: Runtime PM callback to run. |
| @@ -344,8 +364,10 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) · 21 unmodified lines | ||
| 344 | 364 | idx = device_links_read_lock(); |
| 345 | 365 | |
| 346 | 366 | retval = rpm_get_suppliers(dev); |
| 347 | − if (retval) | |
| 367 | + if (retval) { | |
| 368 | + rpm_put_suppliers(dev); | |
| 348 | 369 | goto fail; |
| 370 | + } | |
| 349 | 371 | |
| 350 | 372 | device_links_read_unlock(idx); |
| 351 | 373 | } |
| @@ -368,9 +390,9 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) · 16 unmodified lines | ||
| 368 | 390 | || (dev->power.runtime_status == RPM_RESUMING && retval))) { |
| 369 | 391 | idx = device_links_read_lock(); |
| 370 | 392 | |
| 371 | − fail: | |
| 372 | − rpm_put_suppliers(dev); | |
| 393 | + __rpm_put_suppliers(dev, false); | |
| 373 | 394 | |
| 395 | +fail: | |
| 374 | 396 | device_links_read_unlock(idx); |
| 375 | 397 | } |
| 376 | 398 | |
| @@ -642,8 +664,11 @@ static int rpm_suspend(struct device *dev, int rpmflags) · 265 unmodified lines | ||
| 642 | 664 | goto out; |
| 643 | 665 | } |
| 644 | 666 | |
| 667 | + if (dev->power.irq_safe) | |
| 668 | + goto out; | |
| 669 | + | |
| 645 | 670 | /* Maybe the parent is now able to suspend. */ |
| 646 | − if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { | |
| 671 | + if (parent && !parent->power.ignore_children) { | |
| 647 | 672 | spin_unlock(&dev->power.lock); |
| 648 | 673 | |
| 649 | 674 | spin_lock(&parent->power.lock); |
| @@ -652,6 +677,14 @@ static int rpm_suspend(struct device *dev, int rpmflags) · 2 unmodified lines | ||
| 652 | 677 | |
| 653 | 678 | spin_lock(&dev->power.lock); |
| 654 | 679 | } |
| 680 | + /* Maybe the suppliers are now able to suspend. */ | |
| 681 | + if (dev->power.links_count > 0) { | |
| 682 | + spin_unlock_irq(&dev->power.lock); | |
| 683 | + | |
| 684 | + rpm_suspend_suppliers(dev); | |
| 685 | + | |
| 686 | + spin_lock_irq(&dev->power.lock); | |
| 687 | + } | |
| 655 | 688 | |
| 656 | 689 | out: |
| 657 | 690 | trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); |
| @@ -1657,8 +1690,8 @@ void pm_runtime_get_suppliers(struct device *dev) · 999 unmodified lines | ||
| 1657 | 1690 | device_links_read_lock_held()) |
| 1658 | 1691 | if (link->flags & DL_FLAG_PM_RUNTIME) { |
| 1659 | 1692 | link->supplier_preactivated = true; |
| 1660 | − refcount_inc(&link->rpm_active); | |
| 1661 | 1693 | pm_runtime_get_sync(link->supplier); |
| 1694 | + refcount_inc(&link->rpm_active); | |
| 1662 | 1695 | } |
| 1663 | 1696 | |
| 1664 | 1697 | device_links_read_unlock(idx); |
| @@ -1671,6 +1704,8 @@ void pm_runtime_get_suppliers(struct device *dev) · 6 unmodified lines | ||
| 1671 | 1704 | void pm_runtime_put_suppliers(struct device *dev) |
| 1672 | 1705 | { |
| 1673 | 1706 | struct device_link *link; |
| 1707 | + unsigned long flags; | |
| 1708 | + bool put; | |
| 1674 | 1709 | int idx; |
| 1675 | 1710 | |
| 1676 | 1711 | idx = device_links_read_lock(); |
| @@ -1679,7 +1714,11 @@ void pm_runtime_put_suppliers(struct device *dev) · 2 unmodified lines | ||
| 1679 | 1714 | device_links_read_lock_held()) |
| 1680 | 1715 | if (link->supplier_preactivated) { |
| 1681 | 1716 | link->supplier_preactivated = false; |
| 1682 | − if (refcount_dec_not_one(&link->rpm_active)) | |
| 1717 | + spin_lock_irqsave(&dev->power.lock, flags); | |
| 1718 | + put = pm_runtime_status_suspended(dev) && | |
| 1719 | + refcount_dec_not_one(&link->rpm_active); | |
| 1720 | + spin_unlock_irqrestore(&dev->power.lock, flags); | |
| 1721 | + if (put) | |
| 1683 | 1722 | pm_runtime_put(link->supplier); |
| 1684 | 1723 | } |
| 1685 | 1724 | |
| @@ -1369,10 +1369,13 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector, · 1368 unmodified lines | ||
| 1369 | 1369 | } |
| 1370 | 1370 | |
| 1371 | 1371 | if (dev->zoned) |
| 1372 | − cmd->error = null_process_zoned_cmd(cmd, op, | |
| 1373 | − sector, nr_sectors); | |
| 1372 | + sts = null_process_zoned_cmd(cmd, op, sector, nr_sectors); | |
| 1374 | 1373 | else |
| 1375 | − cmd->error = null_process_cmd(cmd, op, sector, nr_sectors); | |
| 1374 | + sts = null_process_cmd(cmd, op, sector, nr_sectors); | |
| 1375 | + | |
| 1376 | + /* Do not overwrite errors (e.g. timeout errors) */ | |
| 1377 | + if (cmd->error == BLK_STS_OK) | |
| 1378 | + cmd->error = sts; | |
| 1376 | 1379 | |
| 1377 | 1380 | out: |
| 1378 | 1381 | nullb_complete_cmd(cmd); |
| @@ -1451,8 +1454,20 @@ static bool should_requeue_request(struct request *rq) · 72 unmodified lines | ||
| 1451 | 1454 | |
| 1452 | 1455 | static enum blk_eh_timer_return null_timeout_rq(struct request *rq, bool res) |
| 1453 | 1456 | { |
| 1457 | + struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); | |
| 1458 | + | |
| 1454 | 1459 | pr_info("rq %p timed out\n", rq); |
| 1455 | − blk_mq_complete_request(rq); | |
| 1460 | + | |
| 1461 | + /* | |
| 1462 | + * If the device is marked as blocking (i.e. memory backed or zoned | |
| 1463 | + * device), the submission path may be blocked waiting for resources | |
| 1464 | + * and cause real timeouts. For these real timeouts, the submission | |
| 1465 | + * path will complete the request using blk_mq_complete_request(). | |
| 1466 | + * Only fake timeouts need to execute blk_mq_complete_request() here. | |
| 1467 | + */ | |
| 1468 | + cmd->error = BLK_STS_TIMEOUT; | |
| 1469 | + if (cmd->fake_timeout) | |
| 1470 | + blk_mq_complete_request(rq); | |
| 1456 | 1471 | return BLK_EH_DONE; |
| 1457 | 1472 | } |
| 1458 | 1473 | |
| @@ -1473,6 +1488,7 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 14 unmodified lines | ||
| 1473 | 1488 | cmd->rq = bd->rq; |
| 1474 | 1489 | cmd->error = BLK_STS_OK; |
| 1475 | 1490 | cmd->nq = nq; |
| 1491 | + cmd->fake_timeout = should_timeout_request(bd->rq); | |
| 1476 | 1492 | |
| 1477 | 1493 | blk_mq_start_request(bd->rq); |
| 1478 | 1494 | |
| @@ -1489,7 +1505,7 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 10 unmodified lines | ||
| 1489 | 1505 | return BLK_STS_OK; |
| 1490 | 1506 | } |
| 1491 | 1507 | } |
| 1492 | − if (should_timeout_request(bd->rq)) | |
| 1508 | + if (cmd->fake_timeout) | |
| 1493 | 1509 | return BLK_STS_OK; |
| 1494 | 1510 | |
| 1495 | 1511 | return null_handle_cmd(cmd, sector, nr_sectors, req_op(bd->rq)); |
| @@ -22,6 +22,7 @@ struct nullb_cmd { · 21 unmodified lines | ||
| 22 | 22 | blk_status_t error; |
| 23 | 23 | struct nullb_queue *nq; |
| 24 | 24 | struct hrtimer timer; |
| 25 | + bool fake_timeout; | |
| 25 | 26 | }; |
| 26 | 27 | |
| 27 | 28 | struct nullb_queue { |
| @@ -891,7 +891,7 @@ next: · 890 unmodified lines | ||
| 891 | 891 | out: |
| 892 | 892 | for (i = last_map; i < num; i++) { |
| 893 | 893 | /* Don't zap current batch's valid persistent grants. */ |
| 894 | − if(i >= last_map + segs_to_map) | |
| 894 | + if(i >= map_until) | |
| 895 | 895 | pages[i]->persistent_gnt = NULL; |
| 896 | 896 | pages[i]->handle = BLKBACK_INVALID_HANDLE; |
| 897 | 897 | } |
| @@ -285,7 +285,7 @@ static int omap_l3_probe(struct platform_device *pdev) · 284 unmodified lines | ||
| 285 | 285 | */ |
| 286 | 286 | l3->debug_irq = platform_get_irq(pdev, 0); |
| 287 | 287 | ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler, |
| 288 | − 0x0, "l3-dbg-irq", l3); | |
| 288 | + IRQF_NO_THREAD, "l3-dbg-irq", l3); | |
| 289 | 289 | if (ret) { |
| 290 | 290 | dev_err(l3->dev, "request_irq failed for %d\n", |
| 291 | 291 | l3->debug_irq); |
| @@ -294,7 +294,7 @@ static int omap_l3_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 294 | 294 | |
| 295 | 295 | l3->app_irq = platform_get_irq(pdev, 1); |
| 296 | 296 | ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler, |
| 297 | − 0x0, "l3-app-irq", l3); | |
| 297 | + IRQF_NO_THREAD, "l3-app-irq", l3); | |
| 298 | 298 | if (ret) |
| 299 | 299 | dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq); |
| 300 | 300 | |
| @@ -3053,7 +3053,9 @@ static int sysc_remove(struct platform_device *pdev) · 3052 unmodified lines | ||
| 3053 | 3053 | |
| 3054 | 3054 | pm_runtime_put_sync(&pdev->dev); |
| 3055 | 3055 | pm_runtime_disable(&pdev->dev); |
| 3056 | − reset_control_assert(ddata->rsts); | |
| 3056 | + | |
| 3057 | + if (!reset_control_status(ddata->rsts)) | |
| 3058 | + reset_control_assert(ddata->rsts); | |
| 3057 | 3059 | |
| 3058 | 3060 | unprepare: |
| 3059 | 3061 | sysc_unprepare(ddata); |
| @@ -730,7 +730,8 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 729 unmodified lines | ||
| 730 | 730 | struct clk_rate_request parent_req = { }; |
| 731 | 731 | struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw); |
| 732 | 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 | 735 | int ret; |
| 735 | 736 | |
| 736 | 737 | p0 = cgfx->hws[0]; |
| @@ -750,14 +751,15 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 13 unmodified lines | ||
| 750 | 751 | return 0; |
| 751 | 752 | } |
| 752 | 753 | |
| 753 | − request = req->rate; | |
| 754 | − if (cgfx->div > 1) | |
| 755 | − parent_req.rate = request = request * cgfx->div; | |
| 754 | + if (mux_div == 0) | |
| 755 | + mux_div = 1; | |
| 756 | + | |
| 757 | + parent_req.rate = req->rate * mux_div; | |
| 756 | 758 | |
| 757 | 759 | /* This has to be a fixed rate PLL */ |
| 758 | 760 | p0_rate = clk_hw_get_rate(p0); |
| 759 | 761 | |
| 760 | − if (request == p0_rate) { | |
| 762 | + if (parent_req.rate == p0_rate) { | |
| 761 | 763 | req->rate = req->best_parent_rate = p0_rate; |
| 762 | 764 | req->best_parent_hw = p0; |
| 763 | 765 | return 0; |
| @@ -765,7 +767,7 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 1 unmodified line | ||
| 765 | 767 | |
| 766 | 768 | if (req->best_parent_hw == p0) { |
| 767 | 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 | 771 | req->best_parent_hw = p2; |
| 770 | 772 | else |
| 771 | 773 | req->best_parent_hw = p1; |
| @@ -780,8 +782,7 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, · 8 unmodified lines | ||
| 780 | 782 | return ret; |
| 781 | 783 | |
| 782 | 784 | req->rate = req->best_parent_rate = parent_req.rate; |
| 783 | − if (cgfx->div > 1) | |
| 784 | − req->rate /= cgfx->div; | |
| 785 | + req->rate /= mux_div; | |
| 785 | 786 | |
| 786 | 787 | return 0; |
| 787 | 788 | } |
| @@ -510,9 +510,12 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = { · 509 unmodified lines | ||
| 510 | 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 | 516 | static struct clk_hw *sc7280_rpmh_clocks[] = { |
| 514 | − [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, | |
| 515 | − [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, | |
| 517 | + [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw, | |
| 518 | + [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw, | |
| 516 | 519 | [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, |
| 517 | 520 | [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, |
| 518 | 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 | 620 | .name = "gcc_sdcc1_apps_clk_src", |
| 621 | 621 | .parent_data = gcc_parent_data_1, |
| 622 | 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 | 642 | .name = "gcc_sdcc1_ice_core_clk_src", |
| 643 | 643 | .parent_data = gcc_parent_data_0, |
| 644 | 644 | .num_parents = 4, |
| 645 | − .ops = &clk_rcg2_floor_ops, | |
| 645 | + .ops = &clk_rcg2_ops, | |
| 646 | 646 | }, |
| 647 | 647 | }; |
| 648 | 648 | |
| @@ -267,7 +267,7 @@ struct freq_attr cpufreq_freq_attr_##_name##_freqs = \ · 266 unmodified lines | ||
| 267 | 267 | __ATTR_RO(_name##_frequencies) |
| 268 | 268 | |
| 269 | 269 | /* |
| 270 | − * show_scaling_available_frequencies - show available normal frequencies for | |
| 270 | + * scaling_available_frequencies_show - show available normal frequencies for | |
| 271 | 271 | * the specified CPU |
| 272 | 272 | */ |
| 273 | 273 | static ssize_t scaling_available_frequencies_show(struct cpufreq_policy *policy, |
| @@ -279,7 +279,7 @@ cpufreq_attr_available_freq(scaling_available); · 5 unmodified lines | ||
| 279 | 279 | EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); |
| 280 | 280 | |
| 281 | 281 | /* |
| 282 | − * show_available_boost_freqs - show available boost frequencies for | |
| 282 | + * scaling_boost_frequencies_show - show available boost frequencies for | |
| 283 | 283 | * the specified CPU |
| 284 | 284 | */ |
| 285 | 285 | static ssize_t scaling_boost_frequencies_show(struct cpufreq_policy *policy, |
| @@ -1241,6 +1241,7 @@ int extcon_dev_register(struct extcon_dev *edev) · 1240 unmodified lines | ||
| 1241 | 1241 | sizeof(*edev->nh), GFP_KERNEL); |
| 1242 | 1242 | if (!edev->nh) { |
| 1243 | 1243 | ret = -ENOMEM; |
| 1244 | + device_unregister(&edev->dev); | |
| 1244 | 1245 | goto err_dev; |
| 1245 | 1246 | } |
| 1246 | 1247 | |
| @@ -346,6 +346,7 @@ nosy_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 345 unmodified lines | ||
| 346 | 346 | struct client *client = file->private_data; |
| 347 | 347 | spinlock_t *client_list_lock = &client->lynx->client_list_lock; |
| 348 | 348 | struct nosy_stats stats; |
| 349 | + int ret; | |
| 349 | 350 | |
| 350 | 351 | switch (cmd) { |
| 351 | 352 | case NOSY_IOC_GET_STATS: |
| @@ -360,11 +361,15 @@ nosy_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 8 unmodified lines | ||
| 360 | 361 | return 0; |
| 361 | 362 | |
| 362 | 363 | case NOSY_IOC_START: |
| 364 | + ret = -EBUSY; | |
| 363 | 365 | spin_lock_irq(client_list_lock); |
| 364 | − list_add_tail(&client->link, &client->lynx->client_list); | |
| 366 | + if (list_empty(&client->link)) { | |
| 367 | + list_add_tail(&client->link, &client->lynx->client_list); | |
| 368 | + ret = 0; | |
| 369 | + } | |
| 365 | 370 | spin_unlock_irq(client_list_lock); |
| 366 | 371 | |
| 367 | − return 0; | |
| 372 | + return ret; | |
| 368 | 373 | |
| 369 | 374 | case NOSY_IOC_STOP: |
| 370 | 375 | spin_lock_irq(client_list_lock); |
| @@ -1007,13 +1007,9 @@ struct amdgpu_device { · 1006 unmodified lines | ||
| 1007 | 1007 | |
| 1008 | 1008 | /* s3/s4 mask */ |
| 1009 | 1009 | bool in_suspend; |
| 1010 | − bool in_hibernate; | |
| 1011 | − | |
| 1012 | − /* | |
| 1013 | − * The combination flag in_poweroff_reboot_com used to identify the poweroff | |
| 1014 | − * and reboot opt in the s0i3 system-wide suspend. | |
| 1015 | − */ | |
| 1016 | − bool in_poweroff_reboot_com; | |
| 1010 | + bool in_s3; | |
| 1011 | + bool in_s4; | |
| 1012 | + bool in_s0ix; | |
| 1017 | 1013 | |
| 1018 | 1014 | atomic_t in_gpu_reset; |
| 1019 | 1015 | enum pp_mp1_state mp1_state; |
| @@ -2371,6 +2371,10 @@ static int amdgpu_device_set_cg_state(struct amdgpu_device *adev, · 2370 unmodified lines | ||
| 2371 | 2371 | i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; |
| 2372 | 2372 | if (!adev->ip_blocks[i].status.late_initialized) |
| 2373 | 2373 | continue; |
| 2374 | + /* skip CG for GFX on S0ix */ | |
| 2375 | + if (adev->in_s0ix && | |
| 2376 | + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX) | |
| 2377 | + continue; | |
| 2374 | 2378 | /* skip CG for VCE/UVD, it's handled specially */ |
| 2375 | 2379 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && |
| 2376 | 2380 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && |
| @@ -2402,6 +2406,10 @@ static int amdgpu_device_set_pg_state(struct amdgpu_device *adev, enum amd_power · 25 unmodified lines | ||
| 2402 | 2406 | i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; |
| 2403 | 2407 | if (!adev->ip_blocks[i].status.late_initialized) |
| 2404 | 2408 | continue; |
| 2409 | + /* skip PG for GFX on S0ix */ | |
| 2410 | + if (adev->in_s0ix && | |
| 2411 | + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX) | |
| 2412 | + continue; | |
| 2405 | 2413 | /* skip CG for VCE/UVD, it's handled specially */ |
| 2406 | 2414 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && |
| 2407 | 2415 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && |
| @@ -2678,11 +2686,8 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev) · 270 unmodified lines | ||
| 2678 | 2686 | { |
| 2679 | 2687 | int i, r; |
| 2680 | 2688 | |
| 2681 | − if (adev->in_poweroff_reboot_com || | |
| 2682 | − !amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) { | |
| 2683 | − amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); | |
| 2684 | − amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); | |
| 2685 | − } | |
| 2689 | + amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); | |
| 2690 | + amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); | |
| 2686 | 2691 | |
| 2687 | 2692 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 2688 | 2693 | if (!adev->ip_blocks[i].status.valid) |
| @@ -2722,6 +2727,9 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) · 33 unmodified lines | ||
| 2722 | 2727 | { |
| 2723 | 2728 | int i, r; |
| 2724 | 2729 | |
| 2730 | + if (adev->in_s0ix) | |
| 2731 | + amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry); | |
| 2732 | + | |
| 2725 | 2733 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 2726 | 2734 | if (!adev->ip_blocks[i].status.valid) |
| 2727 | 2735 | continue; |
| @@ -2734,6 +2742,17 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) · 6 unmodified lines | ||
| 2734 | 2742 | adev->ip_blocks[i].status.hw = false; |
| 2735 | 2743 | continue; |
| 2736 | 2744 | } |
| 2745 | + | |
| 2746 | + /* skip suspend of gfx and psp for S0ix | |
| 2747 | + * gfx is in gfxoff state, so on resume it will exit gfxoff just | |
| 2748 | + * like at runtime. PSP is also part of the always on hardware | |
| 2749 | + * so no need to suspend it. | |
| 2750 | + */ | |
| 2751 | + if (adev->in_s0ix && | |
| 2752 | + (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP || | |
| 2753 | + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX)) | |
| 2754 | + continue; | |
| 2755 | + | |
| 2737 | 2756 | /* XXX handle errors */ |
| 2738 | 2757 | r = adev->ip_blocks[i].version->funcs->suspend(adev); |
| 2739 | 2758 | /* XXX handle errors */ |
| @@ -3673,14 +3692,9 @@ void amdgpu_device_fini(struct amdgpu_device *adev) · 933 unmodified lines | ||
| 3673 | 3692 | */ |
| 3674 | 3693 | int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) |
| 3675 | 3694 | { |
| 3676 | − struct amdgpu_device *adev; | |
| 3677 | − struct drm_crtc *crtc; | |
| 3678 | − struct drm_connector *connector; | |
| 3679 | − struct drm_connector_list_iter iter; | |
| 3695 | + struct amdgpu_device *adev = drm_to_adev(dev); | |
| 3680 | 3696 | int r; |
| 3681 | 3697 | |
| 3682 | − adev = drm_to_adev(dev); | |
| 3683 | − | |
| 3684 | 3698 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 3685 | 3699 | return 0; |
| 3686 | 3700 | |
| @@ -3692,61 +3706,19 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) · 5 unmodified lines | ||
| 3692 | 3706 | |
| 3693 | 3707 | cancel_delayed_work_sync(&adev->delayed_init_work); |
| 3694 | 3708 | |
| 3695 | − if (!amdgpu_device_has_dc_support(adev)) { | |
| 3696 | − /* turn off display hw */ | |
| 3697 | − drm_modeset_lock_all(dev); | |
| 3698 | − drm_connector_list_iter_begin(dev, &iter); | |
| 3699 | − drm_for_each_connector_iter(connector, &iter) | |
| 3700 | − drm_helper_connector_dpms(connector, | |
| 3701 | − DRM_MODE_DPMS_OFF); | |
| 3702 | − drm_connector_list_iter_end(&iter); | |
| 3703 | − drm_modeset_unlock_all(dev); | |
| 3704 | − /* unpin the front buffers and cursors */ | |
| 3705 | − list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 3706 | − struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | |
| 3707 | − struct drm_framebuffer *fb = crtc->primary->fb; | |
| 3708 | − struct amdgpu_bo *robj; | |
| 3709 | − | |
| 3710 | − if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { | |
| 3711 | − struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | |
| 3712 | − r = amdgpu_bo_reserve(aobj, true); | |
| 3713 | − if (r == 0) { | |
| 3714 | − amdgpu_bo_unpin(aobj); | |
| 3715 | − amdgpu_bo_unreserve(aobj); | |
| 3716 | − } | |
| 3717 | − } | |
| 3718 | − | |
| 3719 | − if (fb == NULL || fb->obj[0] == NULL) { | |
| 3720 | − continue; | |
| 3721 | − } | |
| 3722 | − robj = gem_to_amdgpu_bo(fb->obj[0]); | |
| 3723 | − /* don't unpin kernel fb objects */ | |
| 3724 | − if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { | |
| 3725 | − r = amdgpu_bo_reserve(robj, true); | |
| 3726 | − if (r == 0) { | |
| 3727 | − amdgpu_bo_unpin(robj); | |
| 3728 | − amdgpu_bo_unreserve(robj); | |
| 3729 | − } | |
| 3730 | − } | |
| 3731 | − } | |
| 3732 | − } | |
| 3733 | − | |
| 3734 | 3709 | amdgpu_ras_suspend(adev); |
| 3735 | 3710 | |
| 3736 | 3711 | r = amdgpu_device_ip_suspend_phase1(adev); |
| 3737 | 3712 | |
| 3738 | − amdgpu_amdkfd_suspend(adev, adev->in_runpm); | |
| 3713 | + if (!adev->in_s0ix) | |
| 3714 | + amdgpu_amdkfd_suspend(adev, adev->in_runpm); | |
| 3739 | 3715 | |
| 3740 | 3716 | /* evict vram memory */ |
| 3741 | 3717 | amdgpu_bo_evict_vram(adev); |
| 3742 | 3718 | |
| 3743 | 3719 | amdgpu_fence_driver_suspend(adev); |
| 3744 | 3720 | |
| 3745 | − if (adev->in_poweroff_reboot_com || | |
| 3746 | − !amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) | |
| 3747 | − r = amdgpu_device_ip_suspend_phase2(adev); | |
| 3748 | − else | |
| 3749 | − amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry); | |
| 3721 | + r = amdgpu_device_ip_suspend_phase2(adev); | |
| 3750 | 3722 | /* evict remaining vram memory |
| 3751 | 3723 | * This second call to evict vram is to evict the gart page table |
| 3752 | 3724 | * using the CPU. |
| @@ -3768,16 +3740,13 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) · 15 unmodified lines | ||
| 3768 | 3740 | */ |
| 3769 | 3741 | int amdgpu_device_resume(struct drm_device *dev, bool fbcon) |
| 3770 | 3742 | { |
| 3771 | − struct drm_connector *connector; | |
| 3772 | − struct drm_connector_list_iter iter; | |
| 3773 | 3743 | struct amdgpu_device *adev = drm_to_adev(dev); |
| 3774 | − struct drm_crtc *crtc; | |
| 3775 | 3744 | int r = 0; |
| 3776 | 3745 | |
| 3777 | 3746 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 3778 | 3747 | return 0; |
| 3779 | 3748 | |
| 3780 | − if (amdgpu_acpi_is_s0ix_supported(adev)) | |
| 3749 | + if (adev->in_s0ix) | |
| 3781 | 3750 | amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry); |
| 3782 | 3751 | |
| 3783 | 3752 | /* post card */ |
| @@ -3802,50 +3771,17 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) · 18 unmodified lines | ||
| 3802 | 3771 | queue_delayed_work(system_wq, &adev->delayed_init_work, |
| 3803 | 3772 | msecs_to_jiffies(AMDGPU_RESUME_MS)); |
| 3804 | 3773 | |
| 3805 | − if (!amdgpu_device_has_dc_support(adev)) { | |
| 3806 | − /* pin cursors */ | |
| 3807 | − list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 3808 | − struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | |
| 3809 | − | |
| 3810 | − if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { | |
| 3811 | − struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | |
| 3812 | − r = amdgpu_bo_reserve(aobj, true); | |
| 3813 | − if (r == 0) { | |
| 3814 | − r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); | |
| 3815 | − if (r != 0) | |
| 3816 | − dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r); | |
| 3817 | − amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); | |
| 3818 | − amdgpu_bo_unreserve(aobj); | |
| 3819 | − } | |
| 3820 | − } | |
| 3821 | − } | |
| 3774 | + if (!adev->in_s0ix) { | |
| 3775 | + r = amdgpu_amdkfd_resume(adev, adev->in_runpm); | |
| 3776 | + if (r) | |
| 3777 | + return r; | |
| 3822 | 3778 | } |
| 3823 | − r = amdgpu_amdkfd_resume(adev, adev->in_runpm); | |
| 3824 | − if (r) | |
| 3825 | − return r; | |
| 3826 | 3779 | |
| 3827 | 3780 | /* Make sure IB tests flushed */ |
| 3828 | 3781 | flush_delayed_work(&adev->delayed_init_work); |
| 3829 | 3782 | |
| 3830 | − /* blat the mode back in */ | |
| 3831 | − if (fbcon) { | |
| 3832 | − if (!amdgpu_device_has_dc_support(adev)) { | |
| 3833 | − /* pre DCE11 */ | |
| 3834 | − drm_helper_resume_force_mode(dev); | |
| 3835 | − | |
| 3836 | − /* turn on display hw */ | |
| 3837 | − drm_modeset_lock_all(dev); | |
| 3838 | − | |
| 3839 | − drm_connector_list_iter_begin(dev, &iter); | |
| 3840 | − drm_for_each_connector_iter(connector, &iter) | |
| 3841 | − drm_helper_connector_dpms(connector, | |
| 3842 | − DRM_MODE_DPMS_ON); | |
| 3843 | − drm_connector_list_iter_end(&iter); | |
| 3844 | − | |
| 3845 | − drm_modeset_unlock_all(dev); | |
| 3846 | − } | |
| 3783 | + if (fbcon) | |
| 3847 | 3784 | amdgpu_fbdev_set_suspend(adev, 0); |
| 3848 | − } | |
| 3849 | 3785 | |
| 3850 | 3786 | drm_kms_helper_poll_enable(dev); |
| 3851 | 3787 | |
| @@ -1310,3 +1310,92 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc, · 1309 unmodified lines | ||
| 1310 | 1310 | return amdgpu_display_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, |
| 1311 | 1311 | stime, etime, mode); |
| 1312 | 1312 | } |
| 1313 | + | |
| 1314 | +int amdgpu_display_suspend_helper(struct amdgpu_device *adev) | |
| 1315 | +{ | |
| 1316 | + struct drm_device *dev = adev_to_drm(adev); | |
| 1317 | + struct drm_crtc *crtc; | |
| 1318 | + struct drm_connector *connector; | |
| 1319 | + struct drm_connector_list_iter iter; | |
| 1320 | + int r; | |
| 1321 | + | |
| 1322 | + /* turn off display hw */ | |
| 1323 | + drm_modeset_lock_all(dev); | |
| 1324 | + drm_connector_list_iter_begin(dev, &iter); | |
| 1325 | + drm_for_each_connector_iter(connector, &iter) | |
| 1326 | + drm_helper_connector_dpms(connector, | |
| 1327 | + DRM_MODE_DPMS_OFF); | |
| 1328 | + drm_connector_list_iter_end(&iter); | |
| 1329 | + drm_modeset_unlock_all(dev); | |
| 1330 | + /* unpin the front buffers and cursors */ | |
| 1331 | + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 1332 | + struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | |
| 1333 | + struct drm_framebuffer *fb = crtc->primary->fb; | |
| 1334 | + struct amdgpu_bo *robj; | |
| 1335 | + | |
| 1336 | + if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { | |
| 1337 | + struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | |
| 1338 | + r = amdgpu_bo_reserve(aobj, true); | |
| 1339 | + if (r == 0) { | |
| 1340 | + amdgpu_bo_unpin(aobj); | |
| 1341 | + amdgpu_bo_unreserve(aobj); | |
| 1342 | + } | |
| 1343 | + } | |
| 1344 | + | |
| 1345 | + if (fb == NULL || fb->obj[0] == NULL) { | |
| 1346 | + continue; | |
| 1347 | + } | |
| 1348 | + robj = gem_to_amdgpu_bo(fb->obj[0]); | |
| 1349 | + /* don't unpin kernel fb objects */ | |
| 1350 | + if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { | |
| 1351 | + r = amdgpu_bo_reserve(robj, true); | |
| 1352 | + if (r == 0) { | |
| 1353 | + amdgpu_bo_unpin(robj); | |
| 1354 | + amdgpu_bo_unreserve(robj); | |
| 1355 | + } | |
| 1356 | + } | |
| 1357 | + } | |
| 1358 | + return r; | |
| 1359 | +} | |
| 1360 | + | |
| 1361 | +int amdgpu_display_resume_helper(struct amdgpu_device *adev) | |
| 1362 | +{ | |
| 1363 | + struct drm_device *dev = adev_to_drm(adev); | |
| 1364 | + struct drm_connector *connector; | |
| 1365 | + struct drm_connector_list_iter iter; | |
| 1366 | + struct drm_crtc *crtc; | |
| 1367 | + int r; | |
| 1368 | + | |
| 1369 | + /* pin cursors */ | |
| 1370 | + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 1371 | + struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | |
| 1372 | + | |
| 1373 | + if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { | |
| 1374 | + struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | |
| 1375 | + r = amdgpu_bo_reserve(aobj, true); | |
| 1376 | + if (r == 0) { | |
| 1377 | + r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); | |
| 1378 | + if (r != 0) | |
| 1379 | + dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r); | |
| 1380 | + amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); | |
| 1381 | + amdgpu_bo_unreserve(aobj); | |
| 1382 | + } | |
| 1383 | + } | |
| 1384 | + } | |
| 1385 | + | |
| 1386 | + drm_helper_resume_force_mode(dev); | |
| 1387 | + | |
| 1388 | + /* turn on display hw */ | |
| 1389 | + drm_modeset_lock_all(dev); | |
| 1390 | + | |
| 1391 | + drm_connector_list_iter_begin(dev, &iter); | |
| 1392 | + drm_for_each_connector_iter(connector, &iter) | |
| 1393 | + drm_helper_connector_dpms(connector, | |
| 1394 | + DRM_MODE_DPMS_ON); | |
| 1395 | + drm_connector_list_iter_end(&iter); | |
| 1396 | + | |
| 1397 | + drm_modeset_unlock_all(dev); | |
| 1398 | + | |
| 1399 | + return 0; | |
| 1400 | +} | |
| 1401 | + | |
| @@ -47,4 +47,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, · 46 unmodified lines | ||
| 47 | 47 | const struct drm_format_info * |
| 48 | 48 | amdgpu_lookup_format_info(u32 format, uint64_t modifier); |
| 49 | 49 | |
| 50 | +int amdgpu_display_suspend_helper(struct amdgpu_device *adev); | |
| 51 | +int amdgpu_display_resume_helper(struct amdgpu_device *adev); | |
| 52 | + | |
| 50 | 53 | #endif |
| @@ -1107,6 +1107,7 @@ static const struct pci_device_id pciidlist[] = { · 1106 unmodified lines | ||
| 1107 | 1107 | {0x1002, 0x73A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1108 | 1108 | {0x1002, 0x73AB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1109 | 1109 | {0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1110 | + {0x1002, 0x73AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, | |
| 1110 | 1111 | {0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1111 | 1112 | |
| 1112 | 1113 | /* Van Gogh */ |
| @@ -1274,24 +1275,35 @@ amdgpu_pci_shutdown(struct pci_dev *pdev) · 161 unmodified lines | ||
| 1274 | 1275 | */ |
| 1275 | 1276 | if (!amdgpu_passthrough(adev)) |
| 1276 | 1277 | adev->mp1_state = PP_MP1_STATE_UNLOAD; |
| 1277 | − adev->in_poweroff_reboot_com = true; | |
| 1278 | 1278 | amdgpu_device_ip_suspend(adev); |
| 1279 | − adev->in_poweroff_reboot_com = false; | |
| 1280 | 1279 | adev->mp1_state = PP_MP1_STATE_NONE; |
| 1281 | 1280 | } |
| 1282 | 1281 | |
| 1283 | 1282 | static int amdgpu_pmops_suspend(struct device *dev) |
| 1284 | 1283 | { |
| 1285 | 1284 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 1285 | + struct amdgpu_device *adev = drm_to_adev(drm_dev); | |
| 1286 | + int r; | |
| 1286 | 1287 | |
| 1287 | − return amdgpu_device_suspend(drm_dev, true); | |
| 1288 | + if (amdgpu_acpi_is_s0ix_supported(adev)) | |
| 1289 | + adev->in_s0ix = true; | |
| 1290 | + adev->in_s3 = true; | |
| 1291 | + r = amdgpu_device_suspend(drm_dev, true); | |
| 1292 | + adev->in_s3 = false; | |
| 1293 | + | |
| 1294 | + return r; | |
| 1288 | 1295 | } |
| 1289 | 1296 | |
| 1290 | 1297 | static int amdgpu_pmops_resume(struct device *dev) |
| 1291 | 1298 | { |
| 1292 | 1299 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 1300 | + struct amdgpu_device *adev = drm_to_adev(drm_dev); | |
| 1301 | + int r; | |
| 1293 | 1302 | |
| 1294 | − return amdgpu_device_resume(drm_dev, true); | |
| 1303 | + r = amdgpu_device_resume(drm_dev, true); | |
| 1304 | + if (amdgpu_acpi_is_s0ix_supported(adev)) | |
| 1305 | + adev->in_s0ix = false; | |
| 1306 | + return r; | |
| 1295 | 1307 | } |
| 1296 | 1308 | |
| 1297 | 1309 | static int amdgpu_pmops_freeze(struct device *dev) |
| @@ -1300,9 +1312,9 @@ static int amdgpu_pmops_freeze(struct device *dev) · 2 unmodified lines | ||
| 1300 | 1312 | struct amdgpu_device *adev = drm_to_adev(drm_dev); |
| 1301 | 1313 | int r; |
| 1302 | 1314 | |
| 1303 | − adev->in_hibernate = true; | |
| 1315 | + adev->in_s4 = true; | |
| 1304 | 1316 | r = amdgpu_device_suspend(drm_dev, true); |
| 1305 | − adev->in_hibernate = false; | |
| 1317 | + adev->in_s4 = false; | |
| 1306 | 1318 | if (r) |
| 1307 | 1319 | return r; |
| 1308 | 1320 | return amdgpu_asic_reset(adev); |
| @@ -1318,13 +1330,8 @@ static int amdgpu_pmops_thaw(struct device *dev) · 9 unmodified lines | ||
| 1318 | 1330 | static int amdgpu_pmops_poweroff(struct device *dev) |
| 1319 | 1331 | { |
| 1320 | 1332 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 1321 | − struct amdgpu_device *adev = drm_to_adev(drm_dev); | |
| 1322 | − int r; | |
| 1323 | 1333 | |
| 1324 | − adev->in_poweroff_reboot_com = true; | |
| 1325 | − r = amdgpu_device_suspend(drm_dev, true); | |
| 1326 | − adev->in_poweroff_reboot_com = false; | |
| 1327 | − return r; | |
| 1334 | + return amdgpu_device_suspend(drm_dev, true); | |
| 1328 | 1335 | } |
| 1329 | 1336 | |
| 1330 | 1337 | static int amdgpu_pmops_restore(struct device *dev) |
| @@ -778,9 +778,9 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 777 unmodified lines | ||
| 778 | 778 | dev_info->high_va_offset = AMDGPU_GMC_HOLE_END; |
| 779 | 779 | dev_info->high_va_max = AMDGPU_GMC_HOLE_END | vm_size; |
| 780 | 780 | } |
| 781 | − dev_info->virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); | |
| 781 | + dev_info->virtual_address_alignment = max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); | |
| 782 | 782 | dev_info->pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE; |
| 783 | − dev_info->gart_page_size = AMDGPU_GPU_PAGE_SIZE; | |
| 783 | + dev_info->gart_page_size = max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); | |
| 784 | 784 | dev_info->cu_active_number = adev->gfx.cu_info.number; |
| 785 | 785 | dev_info->cu_ao_mask = adev->gfx.cu_info.ao_cu_mask; |
| 786 | 786 | dev_info->ce_ram_size = adev->gfx.ce_ram_size; |
| @@ -1028,13 +1028,10 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev) · 1027 unmodified lines | ||
| 1028 | 1028 | { |
| 1029 | 1029 | struct ttm_resource_manager *man; |
| 1030 | 1030 | |
| 1031 | − /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ | |
| 1032 | −#ifndef CONFIG_HIBERNATION | |
| 1033 | − if (adev->flags & AMD_IS_APU) { | |
| 1034 | − /* Useless to evict on IGP chips */ | |
| 1031 | + if (adev->in_s3 && (adev->flags & AMD_IS_APU)) { | |
| 1032 | + /* No need to evict vram on APUs for suspend to ram */ | |
| 1035 | 1033 | return 0; |
| 1036 | 1034 | } |
| 1037 | −#endif | |
| 1038 | 1035 | |
| 1039 | 1036 | man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); |
| 1040 | 1037 | return ttm_resource_manager_evict_all(&adev->mman.bdev, man); |
| @@ -2197,8 +2197,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, · 2196 unmodified lines | ||
| 2197 | 2197 | uint64_t eaddr; |
| 2198 | 2198 | |
| 2199 | 2199 | /* validate the parameters */ |
| 2200 | − if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || | |
| 2201 | − size == 0 || size & AMDGPU_GPU_PAGE_MASK) | |
| 2200 | + if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || | |
| 2201 | + size == 0 || size & ~PAGE_MASK) | |
| 2202 | 2202 | return -EINVAL; |
| 2203 | 2203 | |
| 2204 | 2204 | /* make sure object fit at this offset */ |
| @@ -2263,8 +2263,8 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, · 58 unmodified lines | ||
| 2263 | 2263 | int r; |
| 2264 | 2264 | |
| 2265 | 2265 | /* validate the parameters */ |
| 2266 | − if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || | |
| 2267 | − size == 0 || size & AMDGPU_GPU_PAGE_MASK) | |
| 2266 | + if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || | |
| 2267 | + size == 0 || size & ~PAGE_MASK) | |
| 2268 | 2268 | return -EINVAL; |
| 2269 | 2269 | |
| 2270 | 2270 | /* make sure object fit at this offset */ |
| @@ -2409,7 +2409,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, · 138 unmodified lines | ||
| 2409 | 2409 | after->start = eaddr + 1; |
| 2410 | 2410 | after->last = tmp->last; |
| 2411 | 2411 | after->offset = tmp->offset; |
| 2412 | − after->offset += after->start - tmp->start; | |
| 2412 | + after->offset += (after->start - tmp->start) << PAGE_SHIFT; | |
| 2413 | 2413 | after->flags = tmp->flags; |
| 2414 | 2414 | after->bo_va = tmp->bo_va; |
| 2415 | 2415 | list_add(&after->list, &tmp->bo_va->invalids); |
| @@ -2897,6 +2897,11 @@ static int dce_v10_0_hw_fini(void *handle) · 2896 unmodified lines | ||
| 2897 | 2897 | static int dce_v10_0_suspend(void *handle) |
| 2898 | 2898 | { |
| 2899 | 2899 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 2900 | + int r; | |
| 2901 | + | |
| 2902 | + r = amdgpu_display_suspend_helper(adev); | |
| 2903 | + if (r) | |
| 2904 | + return r; | |
| 2900 | 2905 | |
| 2901 | 2906 | adev->mode_info.bl_level = |
| 2902 | 2907 | amdgpu_atombios_encoder_get_backlight_level_from_reg(adev); |
| @@ -2921,8 +2926,10 @@ static int dce_v10_0_resume(void *handle) · 18 unmodified lines | ||
| 2921 | 2926 | amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder, |
| 2922 | 2927 | bl_level); |
| 2923 | 2928 | } |
| 2929 | + if (ret) | |
| 2930 | + return ret; | |
| 2924 | 2931 | |
| 2925 | − return ret; | |
| 2932 | + return amdgpu_display_resume_helper(adev); | |
| 2926 | 2933 | } |
| 2927 | 2934 | |
| 2928 | 2935 | static bool dce_v10_0_is_idle(void *handle) |
| @@ -3027,6 +3027,11 @@ static int dce_v11_0_hw_fini(void *handle) · 3026 unmodified lines | ||
| 3027 | 3027 | static int dce_v11_0_suspend(void *handle) |
| 3028 | 3028 | { |
| 3029 | 3029 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 3030 | + int r; | |
| 3031 | + | |
| 3032 | + r = amdgpu_display_suspend_helper(adev); | |
| 3033 | + if (r) | |
| 3034 | + return r; | |
| 3030 | 3035 | |
| 3031 | 3036 | adev->mode_info.bl_level = |
| 3032 | 3037 | amdgpu_atombios_encoder_get_backlight_level_from_reg(adev); |
| @@ -3051,8 +3056,10 @@ static int dce_v11_0_resume(void *handle) · 18 unmodified lines | ||
| 3051 | 3056 | amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder, |
| 3052 | 3057 | bl_level); |
| 3053 | 3058 | } |
| 3059 | + if (ret) | |
| 3060 | + return ret; | |
| 3054 | 3061 | |
| 3055 | − return ret; | |
| 3062 | + return amdgpu_display_resume_helper(adev); | |
| 3056 | 3063 | } |
| 3057 | 3064 | |
| 3058 | 3065 | static bool dce_v11_0_is_idle(void *handle) |
| @@ -2770,7 +2770,11 @@ static int dce_v6_0_hw_fini(void *handle) · 2769 unmodified lines | ||
| 2770 | 2770 | static int dce_v6_0_suspend(void *handle) |
| 2771 | 2771 | { |
| 2772 | 2772 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 2773 | + int r; | |
| 2773 | 2774 | |
| 2775 | + r = amdgpu_display_suspend_helper(adev); | |
| 2776 | + if (r) | |
| 2777 | + return r; | |
| 2774 | 2778 | adev->mode_info.bl_level = |
| 2775 | 2779 | amdgpu_atombios_encoder_get_backlight_level_from_reg(adev); |
| 2776 | 2780 | |
| @@ -2794,8 +2798,10 @@ static int dce_v6_0_resume(void *handle) · 17 unmodified lines | ||
| 2794 | 2798 | amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder, |
| 2795 | 2799 | bl_level); |
| 2796 | 2800 | } |
| 2801 | + if (ret) | |
| 2802 | + return ret; | |
| 2797 | 2803 | |
| 2798 | − return ret; | |
| 2804 | + return amdgpu_display_resume_helper(adev); | |
| 2799 | 2805 | } |
| 2800 | 2806 | |
| 2801 | 2807 | static bool dce_v6_0_is_idle(void *handle) |
| @@ -2796,6 +2796,11 @@ static int dce_v8_0_hw_fini(void *handle) · 2795 unmodified lines | ||
| 2796 | 2796 | static int dce_v8_0_suspend(void *handle) |
| 2797 | 2797 | { |
| 2798 | 2798 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 2799 | + int r; | |
| 2800 | + | |
| 2801 | + r = amdgpu_display_suspend_helper(adev); | |
| 2802 | + if (r) | |
| 2803 | + return r; | |
| 2799 | 2804 | |
| 2800 | 2805 | adev->mode_info.bl_level = |
| 2801 | 2806 | amdgpu_atombios_encoder_get_backlight_level_from_reg(adev); |
| @@ -2820,8 +2825,10 @@ static int dce_v8_0_resume(void *handle) · 18 unmodified lines | ||
| 2820 | 2825 | amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder, |
| 2821 | 2826 | bl_level); |
| 2822 | 2827 | } |
| 2828 | + if (ret) | |
| 2829 | + return ret; | |
| 2823 | 2830 | |
| 2824 | − return ret; | |
| 2831 | + return amdgpu_display_resume_helper(adev); | |
| 2825 | 2832 | } |
| 2826 | 2833 | |
| 2827 | 2834 | static bool dce_v8_0_is_idle(void *handle) |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #include "dce_v11_0.h" |
| 40 | 40 | #include "dce_virtual.h" |
| 41 | 41 | #include "ivsrcid/ivsrcid_vislands30.h" |
| 42 | +#include "amdgpu_display.h" | |
| 42 | 43 | |
| 43 | 44 | #define DCE_VIRTUAL_VBLANK_PERIOD 16666666 |
| 44 | 45 | |
| @@ -491,12 +492,24 @@ static int dce_virtual_hw_fini(void *handle) · 446 unmodified lines | ||
| 491 | 492 | |
| 492 | 493 | static int dce_virtual_suspend(void *handle) |
| 493 | 494 | { |
| 495 | + struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
| 496 | + int r; | |
| 497 | + | |
| 498 | + r = amdgpu_display_suspend_helper(adev); | |
| 499 | + if (r) | |
| 500 | + return r; | |
| 494 | 501 | return dce_virtual_hw_fini(handle); |
| 495 | 502 | } |
| 496 | 503 | |
| 497 | 504 | static int dce_virtual_resume(void *handle) |
| 498 | 505 | { |
| 499 | − return dce_virtual_hw_init(handle); | |
| 506 | + struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
| 507 | + int r; | |
| 508 | + | |
| 509 | + r = dce_virtual_hw_init(handle); | |
| 510 | + if (r) | |
| 511 | + return r; | |
| 512 | + return amdgpu_display_resume_helper(adev); | |
| 500 | 513 | } |
| 501 | 514 | |
| 502 | 515 | static bool dce_virtual_is_idle(void *handle) |
| @@ -155,7 +155,7 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev, · 154 unmodified lines | ||
| 155 | 155 | |
| 156 | 156 | /* Wait till CP writes sync code: */ |
| 157 | 157 | status = amdkfd_fence_wait_timeout( |
| 158 | − (unsigned int *) rm_state, | |
| 158 | + rm_state, | |
| 159 | 159 | QUEUESTATE__ACTIVE, 1500); |
| 160 | 160 | |
| 161 | 161 | kfd_gtt_sa_free(dbgdev->dev, mem_obj); |
| @@ -1167,7 +1167,7 @@ static int start_cpsch(struct device_queue_manager *dqm) · 1166 unmodified lines | ||
| 1167 | 1167 | if (retval) |
| 1168 | 1168 | goto fail_allocate_vidmem; |
| 1169 | 1169 | |
| 1170 | − dqm->fence_addr = dqm->fence_mem->cpu_ptr; | |
| 1170 | + dqm->fence_addr = (uint64_t *)dqm->fence_mem->cpu_ptr; | |
| 1171 | 1171 | dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr; |
| 1172 | 1172 | |
| 1173 | 1173 | init_interrupts(dqm); |
| @@ -1340,8 +1340,8 @@ out: · 166 unmodified lines | ||
| 1340 | 1340 | return retval; |
| 1341 | 1341 | } |
| 1342 | 1342 | |
| 1343 | −int amdkfd_fence_wait_timeout(unsigned int *fence_addr, | |
| 1344 | − unsigned int fence_value, | |
| 1343 | +int amdkfd_fence_wait_timeout(uint64_t *fence_addr, | |
| 1344 | + uint64_t fence_value, | |
| 1345 | 1345 | unsigned int timeout_ms) |
| 1346 | 1346 | { |
| 1347 | 1347 | unsigned long end_jiffies = msecs_to_jiffies(timeout_ms) + jiffies; |
| @@ -192,7 +192,7 @@ struct device_queue_manager { · 191 unmodified lines | ||
| 192 | 192 | uint16_t vmid_pasid[VMID_NUM]; |
| 193 | 193 | uint64_t pipelines_addr; |
| 194 | 194 | uint64_t fence_gpu_addr; |
| 195 | − unsigned int *fence_addr; | |
| 195 | + uint64_t *fence_addr; | |
| 196 | 196 | struct kfd_mem_obj *fence_mem; |
| 197 | 197 | bool active_runlist; |
| 198 | 198 | int sched_policy; |
| @@ -347,7 +347,7 @@ fail_create_runlist_ib: · 346 unmodified lines | ||
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, |
| 350 | − uint32_t fence_value) | |
| 350 | + uint64_t fence_value) | |
| 351 | 351 | { |
| 352 | 352 | uint32_t *buffer, size; |
| 353 | 353 | int retval = 0; |
| @@ -283,7 +283,7 @@ static int pm_unmap_queues_v9(struct packet_manager *pm, uint32_t *buffer, · 282 unmodified lines | ||
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | static int pm_query_status_v9(struct packet_manager *pm, uint32_t *buffer, |
| 286 | − uint64_t fence_address, uint32_t fence_value) | |
| 286 | + uint64_t fence_address, uint64_t fence_value) | |
| 287 | 287 | { |
| 288 | 288 | struct pm4_mes_query_status *packet; |
| 289 | 289 | |
| @@ -263,7 +263,7 @@ static int pm_unmap_queues_vi(struct packet_manager *pm, uint32_t *buffer, · 262 unmodified lines | ||
| 263 | 263 | } |
| 264 | 264 | |
| 265 | 265 | static int pm_query_status_vi(struct packet_manager *pm, uint32_t *buffer, |
| 266 | − uint64_t fence_address, uint32_t fence_value) | |
| 266 | + uint64_t fence_address, uint64_t fence_value) | |
| 267 | 267 | { |
| 268 | 268 | struct pm4_mes_query_status *packet; |
| 269 | 269 | |
| @@ -1003,8 +1003,8 @@ int pqm_get_wave_state(struct process_queue_manager *pqm, · 1002 unmodified lines | ||
| 1003 | 1003 | u32 *ctl_stack_used_size, |
| 1004 | 1004 | u32 *save_area_used_size); |
| 1005 | 1005 | |
| 1006 | −int amdkfd_fence_wait_timeout(unsigned int *fence_addr, | |
| 1007 | − unsigned int fence_value, | |
| 1006 | +int amdkfd_fence_wait_timeout(uint64_t *fence_addr, | |
| 1007 | + uint64_t fence_value, | |
| 1008 | 1008 | unsigned int timeout_ms); |
| 1009 | 1009 | |
| 1010 | 1010 | /* Packet Manager */ |
| @@ -1040,7 +1040,7 @@ struct packet_manager_funcs { · 29 unmodified lines | ||
| 1040 | 1040 | uint32_t filter_param, bool reset, |
| 1041 | 1041 | unsigned int sdma_engine); |
| 1042 | 1042 | int (*query_status)(struct packet_manager *pm, uint32_t *buffer, |
| 1043 | − uint64_t fence_address, uint32_t fence_value); | |
| 1043 | + uint64_t fence_address, uint64_t fence_value); | |
| 1044 | 1044 | int (*release_mem)(uint64_t gpu_addr, uint32_t *buffer); |
| 1045 | 1045 | |
| 1046 | 1046 | /* Packet sizes */ |
| @@ -1062,7 +1062,7 @@ int pm_send_set_resources(struct packet_manager *pm, · 15 unmodified lines | ||
| 1062 | 1062 | struct scheduling_resources *res); |
| 1063 | 1063 | int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues); |
| 1064 | 1064 | int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, |
| 1065 | − uint32_t fence_value); | |
| 1065 | + uint64_t fence_value); | |
| 1066 | 1066 | |
| 1067 | 1067 | int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, |
| 1068 | 1068 | enum kfd_unmap_queues_filter mode, |
| @@ -341,8 +341,7 @@ void enc2_hw_init(struct link_encoder *enc) · 340 unmodified lines | ||
| 341 | 341 | } else { |
| 342 | 342 | AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); |
| 343 | 343 | |
| 344 | − AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c4d); | |
| 345 | − | |
| 344 | + AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a); | |
| 346 | 345 | } |
| 347 | 346 | |
| 348 | 347 | //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; |
| @@ -587,6 +587,48 @@ static int smu7_force_switch_to_arbf0(struct pp_hwmgr *hwmgr) · 586 unmodified lines | ||
| 587 | 587 | tmp, MC_CG_ARB_FREQ_F0); |
| 588 | 588 | } |
| 589 | 589 | |
| 590 | +static uint16_t smu7_override_pcie_speed(struct pp_hwmgr *hwmgr) | |
| 591 | +{ | |
| 592 | + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | |
| 593 | + uint16_t pcie_gen = 0; | |
| 594 | + | |
| 595 | + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4 && | |
| 596 | + adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN4) | |
| 597 | + pcie_gen = 3; | |
| 598 | + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 && | |
| 599 | + adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3) | |
| 600 | + pcie_gen = 2; | |
| 601 | + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 && | |
| 602 | + adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2) | |
| 603 | + pcie_gen = 1; | |
| 604 | + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 && | |
| 605 | + adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1) | |
| 606 | + pcie_gen = 0; | |
| 607 | + | |
| 608 | + return pcie_gen; | |
| 609 | +} | |
| 610 | + | |
| 611 | +static uint16_t smu7_override_pcie_width(struct pp_hwmgr *hwmgr) | |
| 612 | +{ | |
| 613 | + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | |
| 614 | + uint16_t pcie_width = 0; | |
| 615 | + | |
| 616 | + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) | |
| 617 | + pcie_width = 16; | |
| 618 | + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) | |
| 619 | + pcie_width = 12; | |
| 620 | + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) | |
| 621 | + pcie_width = 8; | |
| 622 | + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) | |
| 623 | + pcie_width = 4; | |
| 624 | + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) | |
| 625 | + pcie_width = 2; | |
| 626 | + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) | |
| 627 | + pcie_width = 1; | |
| 628 | + | |
| 629 | + return pcie_width; | |
| 630 | +} | |
| 631 | + | |
| 590 | 632 | static int smu7_setup_default_pcie_table(struct pp_hwmgr *hwmgr) |
| 591 | 633 | { |
| 592 | 634 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); |
| @@ -683,6 +725,11 @@ static int smu7_setup_default_pcie_table(struct pp_hwmgr *hwmgr) · 90 unmodified lines | ||
| 683 | 725 | PP_Min_PCIEGen), |
| 684 | 726 | get_pcie_lane_support(data->pcie_lane_cap, |
| 685 | 727 | PP_Max_PCIELane)); |
| 728 | + | |
| 729 | + if (data->pcie_dpm_key_disabled) | |
| 730 | + phm_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, | |
| 731 | + data->dpm_table.pcie_speed_table.count, | |
| 732 | + smu7_override_pcie_speed(hwmgr), smu7_override_pcie_width(hwmgr)); | |
| 686 | 733 | } |
| 687 | 734 | return 0; |
| 688 | 735 | } |
| @@ -1248,6 +1295,13 @@ static int smu7_start_dpm(struct pp_hwmgr *hwmgr) · 559 unmodified lines | ||
| 1248 | 1295 | NULL)), |
| 1249 | 1296 | "Failed to enable pcie DPM during DPM Start Function!", |
| 1250 | 1297 | return -EINVAL); |
| 1298 | + } else { | |
| 1299 | + PP_ASSERT_WITH_CODE( | |
| 1300 | + (0 == smum_send_msg_to_smc(hwmgr, | |
| 1301 | + PPSMC_MSG_PCIeDPM_Disable, | |
| 1302 | + NULL)), | |
| 1303 | + "Failed to disble pcie DPM during DPM Start Function!", | |
| 1304 | + return -EINVAL); | |
| 1251 | 1305 | } |
| 1252 | 1306 | |
| 1253 | 1307 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
| @@ -3276,7 +3330,8 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, · 2022 unmodified lines | ||
| 3276 | 3330 | |
| 3277 | 3331 | disable_mclk_switching_for_display = ((1 < hwmgr->display_config->num_display) && |
| 3278 | 3332 | !hwmgr->display_config->multi_monitor_in_sync) || |
| 3279 | − smu7_vblank_too_short(hwmgr, hwmgr->display_config->min_vblank_time); | |
| 3333 | + (hwmgr->display_config->num_display && | |
| 3334 | + smu7_vblank_too_short(hwmgr, hwmgr->display_config->min_vblank_time)); | |
| 3280 | 3335 | |
| 3281 | 3336 | disable_mclk_switching = disable_mclk_switching_for_frame_lock || |
| 3282 | 3337 | disable_mclk_switching_for_display; |
| @@ -54,6 +54,9 @@ · 53 unmodified lines | ||
| 54 | 54 | #include "smuio/smuio_9_0_offset.h" |
| 55 | 55 | #include "smuio/smuio_9_0_sh_mask.h" |
| 56 | 56 | |
| 57 | +#define smnPCIE_LC_SPEED_CNTL 0x11140290 | |
| 58 | +#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 | |
| 59 | + | |
| 57 | 60 | #define HBM_MEMORY_CHANNEL_WIDTH 128 |
| 58 | 61 | |
| 59 | 62 | static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; |
| @@ -443,8 +446,7 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) · 383 unmodified lines | ||
| 443 | 446 | if (PP_CAP(PHM_PlatformCaps_VCEDPM)) |
| 444 | 447 | data->smu_features[GNLD_DPM_VCE].supported = true; |
| 445 | 448 | |
| 446 | − if (!data->registry_data.pcie_dpm_key_disabled) | |
| 447 | − data->smu_features[GNLD_DPM_LINK].supported = true; | |
| 449 | + data->smu_features[GNLD_DPM_LINK].supported = true; | |
| 448 | 450 | |
| 449 | 451 | if (!data->registry_data.dcefclk_dpm_key_disabled) |
| 450 | 452 | data->smu_features[GNLD_DPM_DCEFCLK].supported = true; |
| @@ -1544,6 +1546,13 @@ static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) · 1093 unmodified lines | ||
| 1544 | 1546 | pp_table->PcieLaneCount[i] = pcie_width; |
| 1545 | 1547 | } |
| 1546 | 1548 | |
| 1549 | + if (data->registry_data.pcie_dpm_key_disabled) { | |
| 1550 | + for (i = 0; i < NUM_LINK_LEVELS; i++) { | |
| 1551 | + pp_table->PcieGenSpeed[i] = pcie_gen; | |
| 1552 | + pp_table->PcieLaneCount[i] = pcie_width; | |
| 1553 | + } | |
| 1554 | + } | |
| 1555 | + | |
| 1547 | 1556 | return 0; |
| 1548 | 1557 | } |
| 1549 | 1558 | |
| @@ -2966,6 +2975,14 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap) · 1416 unmodified lines | ||
| 2966 | 2975 | } |
| 2967 | 2976 | } |
| 2968 | 2977 | |
| 2978 | + if (data->registry_data.pcie_dpm_key_disabled) { | |
| 2979 | + PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, | |
| 2980 | + false, data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap), | |
| 2981 | + "Attempt to Disable Link DPM feature Failed!", return -EINVAL); | |
| 2982 | + data->smu_features[GNLD_DPM_LINK].enabled = false; | |
| 2983 | + data->smu_features[GNLD_DPM_LINK].supported = false; | |
| 2984 | + } | |
| 2985 | + | |
| 2969 | 2986 | return 0; |
| 2970 | 2987 | } |
| 2971 | 2988 | |
| @@ -4584,6 +4601,24 @@ static int vega10_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe · 1612 unmodified lines | ||
| 4584 | 4601 | return 0; |
| 4585 | 4602 | } |
| 4586 | 4603 | |
| 4604 | +static int vega10_get_current_pcie_link_width_level(struct pp_hwmgr *hwmgr) | |
| 4605 | +{ | |
| 4606 | + struct amdgpu_device *adev = hwmgr->adev; | |
| 4607 | + | |
| 4608 | + return (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & | |
| 4609 | + PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) | |
| 4610 | + >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; | |
| 4611 | +} | |
| 4612 | + | |
| 4613 | +static int vega10_get_current_pcie_link_speed_level(struct pp_hwmgr *hwmgr) | |
| 4614 | +{ | |
| 4615 | + struct amdgpu_device *adev = hwmgr->adev; | |
| 4616 | + | |
| 4617 | + return (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & | |
| 4618 | + PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) | |
| 4619 | + >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; | |
| 4620 | +} | |
| 4621 | + | |
| 4587 | 4622 | static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, |
| 4588 | 4623 | enum pp_clock_type type, char *buf) |
| 4589 | 4624 | { |
| @@ -4592,8 +4627,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 2 unmodified lines | ||
| 4592 | 4627 | struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); |
| 4593 | 4628 | struct vega10_single_dpm_table *soc_table = &(data->dpm_table.soc_table); |
| 4594 | 4629 | struct vega10_single_dpm_table *dcef_table = &(data->dpm_table.dcef_table); |
| 4595 | − struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table); | |
| 4596 | 4630 | struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL; |
| 4631 | + uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width; | |
| 4632 | + PPTable_t *pptable = &(data->smc_state_table.pp_table); | |
| 4597 | 4633 | |
| 4598 | 4634 | int i, now, size = 0, count = 0; |
| 4599 | 4635 | |
| @@ -4650,15 +4686,31 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 50 unmodified lines | ||
| 4650 | 4686 | "*" : ""); |
| 4651 | 4687 | break; |
| 4652 | 4688 | case PP_PCIE: |
| 4653 | − smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex, &now); | |
| 4654 | − | |
| 4655 | − for (i = 0; i < pcie_table->count; i++) | |
| 4656 | − size += sprintf(buf + size, "%d: %s %s\n", i, | |
| 4657 | − (pcie_table->pcie_gen[i] == 0) ? "2.5GT/s, x1" : | |
| 4658 | − (pcie_table->pcie_gen[i] == 1) ? "5.0GT/s, x16" : | |
| 4659 | − (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "", | |
| 4660 | − (i == now) ? "*" : ""); | |
| 4689 | + current_gen_speed = | |
| 4690 | + vega10_get_current_pcie_link_speed_level(hwmgr); | |
| 4691 | + current_lane_width = | |
| 4692 | + vega10_get_current_pcie_link_width_level(hwmgr); | |
| 4693 | + for (i = 0; i < NUM_LINK_LEVELS; i++) { | |
| 4694 | + gen_speed = pptable->PcieGenSpeed[i]; | |
| 4695 | + lane_width = pptable->PcieLaneCount[i]; | |
| 4696 | + | |
| 4697 | + size += sprintf(buf + size, "%d: %s %s %s\n", i, | |
| 4698 | + (gen_speed == 0) ? "2.5GT/s," : | |
| 4699 | + (gen_speed == 1) ? "5.0GT/s," : | |
| 4700 | + (gen_speed == 2) ? "8.0GT/s," : | |
| 4701 | + (gen_speed == 3) ? "16.0GT/s," : "", | |
| 4702 | + (lane_width == 1) ? "x1" : | |
| 4703 | + (lane_width == 2) ? "x2" : | |
| 4704 | + (lane_width == 3) ? "x4" : | |
| 4705 | + (lane_width == 4) ? "x8" : | |
| 4706 | + (lane_width == 5) ? "x12" : | |
| 4707 | + (lane_width == 6) ? "x16" : "", | |
| 4708 | + (current_gen_speed == gen_speed) && | |
| 4709 | + (current_lane_width == lane_width) ? | |
| 4710 | + "*" : ""); | |
| 4711 | + } | |
| 4661 | 4712 | break; |
| 4713 | + | |
| 4662 | 4714 | case OD_SCLK: |
| 4663 | 4715 | if (hwmgr->od_enabled) { |
| 4664 | 4716 | size = sprintf(buf, "%s:\n", "OD_SCLK"); |
| @@ -133,6 +133,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr) · 132 unmodified lines | ||
| 133 | 133 | data->registry_data.auto_wattman_debug = 0; |
| 134 | 134 | data->registry_data.auto_wattman_sample_period = 100; |
| 135 | 135 | data->registry_data.auto_wattman_threshold = 50; |
| 136 | + data->registry_data.pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); | |
| 136 | 137 | } |
| 137 | 138 | |
| 138 | 139 | static int vega12_set_features_platform_caps(struct pp_hwmgr *hwmgr) |
| @@ -539,6 +540,29 @@ static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) · 400 unmodified lines | ||
| 539 | 540 | pp_table->PcieLaneCount[i] = pcie_width_arg; |
| 540 | 541 | } |
| 541 | 542 | |
| 543 | + /* override to the highest if it's disabled from ppfeaturmask */ | |
| 544 | + if (data->registry_data.pcie_dpm_key_disabled) { | |
| 545 | + for (i = 0; i < NUM_LINK_LEVELS; i++) { | |
| 546 | + smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width; | |
| 547 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 548 | + PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, | |
| 549 | + NULL); | |
| 550 | + PP_ASSERT_WITH_CODE(!ret, | |
| 551 | + "[OverridePcieParameters] Attempt to override pcie params failed!", | |
| 552 | + return ret); | |
| 553 | + | |
| 554 | + pp_table->PcieGenSpeed[i] = pcie_gen; | |
| 555 | + pp_table->PcieLaneCount[i] = pcie_width; | |
| 556 | + } | |
| 557 | + ret = vega12_enable_smc_features(hwmgr, | |
| 558 | + false, | |
| 559 | + data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap); | |
| 560 | + PP_ASSERT_WITH_CODE(!ret, | |
| 561 | + "Attempt to Disable DPM LINK Failed!", | |
| 562 | + return ret); | |
| 563 | + data->smu_features[GNLD_DPM_LINK].enabled = false; | |
| 564 | + data->smu_features[GNLD_DPM_LINK].supported = false; | |
| 565 | + } | |
| 542 | 566 | return 0; |
| 543 | 567 | } |
| 544 | 568 | |
| @@ -171,6 +171,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) · 170 unmodified lines | ||
| 171 | 171 | data->registry_data.gfxoff_controlled_by_driver = 1; |
| 172 | 172 | data->gfxoff_allowed = false; |
| 173 | 173 | data->counter_gfxoff = 0; |
| 174 | + data->registry_data.pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); | |
| 174 | 175 | } |
| 175 | 176 | |
| 176 | 177 | static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) |
| @@ -884,6 +885,30 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) · 707 unmodified lines | ||
| 884 | 885 | pp_table->PcieLaneCount[i] = pcie_width_arg; |
| 885 | 886 | } |
| 886 | 887 | |
| 888 | + /* override to the highest if it's disabled from ppfeaturmask */ | |
| 889 | + if (data->registry_data.pcie_dpm_key_disabled) { | |
| 890 | + for (i = 0; i < NUM_LINK_LEVELS; i++) { | |
| 891 | + smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width; | |
| 892 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 893 | + PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, | |
| 894 | + NULL); | |
| 895 | + PP_ASSERT_WITH_CODE(!ret, | |
| 896 | + "[OverridePcieParameters] Attempt to override pcie params failed!", | |
| 897 | + return ret); | |
| 898 | + | |
| 899 | + pp_table->PcieGenSpeed[i] = pcie_gen; | |
| 900 | + pp_table->PcieLaneCount[i] = pcie_width; | |
| 901 | + } | |
| 902 | + ret = vega20_enable_smc_features(hwmgr, | |
| 903 | + false, | |
| 904 | + data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap); | |
| 905 | + PP_ASSERT_WITH_CODE(!ret, | |
| 906 | + "Attempt to Disable DPM LINK Failed!", | |
| 907 | + return ret); | |
| 908 | + data->smu_features[GNLD_DPM_LINK].enabled = false; | |
| 909 | + data->smu_features[GNLD_DPM_LINK].supported = false; | |
| 910 | + } | |
| 911 | + | |
| 887 | 912 | return 0; |
| 888 | 913 | } |
| 889 | 914 | |
| @@ -1294,7 +1294,7 @@ static int smu_disable_dpms(struct smu_context *smu) · 1293 unmodified lines | ||
| 1294 | 1294 | bool use_baco = !smu->is_apu && |
| 1295 | 1295 | ((amdgpu_in_reset(adev) && |
| 1296 | 1296 | (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || |
| 1297 | − ((adev->in_runpm || adev->in_hibernate) && amdgpu_asic_supports_baco(adev))); | |
| 1297 | + ((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev))); | |
| 1298 | 1298 | |
| 1299 | 1299 | /* |
| 1300 | 1300 | * For custom pptable uploading, skip the DPM features |
| @@ -1431,7 +1431,8 @@ static int smu_suspend(void *handle) · 130 unmodified lines | ||
| 1431 | 1431 | |
| 1432 | 1432 | smu->watermarks_bitmap &= ~(WATERMARKS_LOADED); |
| 1433 | 1433 | |
| 1434 | − if (smu->is_apu) | |
| 1434 | + /* skip CGPG when in S0ix */ | |
| 1435 | + if (smu->is_apu && !adev->in_s0ix) | |
| 1435 | 1436 | smu_set_gfx_cgpg(&adev->smu, false); |
| 1436 | 1437 | |
| 1437 | 1438 | return 0; |
| @@ -384,10 +384,15 @@ static int vangogh_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) · 383 unmodified lines | ||
| 384 | 384 | |
| 385 | 385 | static bool vangogh_is_dpm_running(struct smu_context *smu) |
| 386 | 386 | { |
| 387 | + struct amdgpu_device *adev = smu->adev; | |
| 387 | 388 | int ret = 0; |
| 388 | 389 | uint32_t feature_mask[2]; |
| 389 | 390 | uint64_t feature_enabled; |
| 390 | 391 | |
| 392 | + /* we need to re-init after suspend so return false */ | |
| 393 | + if (adev->in_suspend) | |
| 394 | + return false; | |
| 395 | + | |
| 391 | 396 | ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2); |
| 392 | 397 | |
| 393 | 398 | if (ret) |
| @@ -689,7 +689,8 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj) · 688 unmodified lines | ||
| 689 | 689 | struct page **pages = pvec + pinned; |
| 690 | 690 | |
| 691 | 691 | ret = pin_user_pages_fast(ptr, num_pages, |
| 692 | − !userptr->ro ? FOLL_WRITE : 0, pages); | |
| 692 | + FOLL_WRITE | FOLL_FORCE | FOLL_LONGTERM, | |
| 693 | + pages); | |
| 693 | 694 | if (ret < 0) { |
| 694 | 695 | unpin_user_pages(pvec, pinned); |
| 695 | 696 | kvfree(pvec); |
| @@ -13,7 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/irq.h> |
| 14 | 14 | #include <linux/mfd/syscon.h> |
| 15 | 15 | #include <linux/of_device.h> |
| 16 | −#include <linux/of_gpio.h> | |
| 17 | 16 | #include <linux/platform_device.h> |
| 18 | 17 | #include <linux/pm_runtime.h> |
| 19 | 18 | #include <linux/regmap.h> |
| @@ -317,12 +317,13 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ · 316 unmodified lines | ||
| 317 | 317 | if (!new_plane_state->hw.crtc && !old_plane_state->hw.crtc) |
| 318 | 318 | return 0; |
| 319 | 319 | |
| 320 | − new_crtc_state->enabled_planes |= BIT(plane->id); | |
| 321 | − | |
| 322 | 320 | ret = plane->check_plane(new_crtc_state, new_plane_state); |
| 323 | 321 | if (ret) |
| 324 | 322 | return ret; |
| 325 | 323 | |
| 324 | + if (fb) | |
| 325 | + new_crtc_state->enabled_planes |= BIT(plane->id); | |
| 326 | + | |
| 326 | 327 | /* FIXME pre-g4x don't work like this */ |
| 327 | 328 | if (new_plane_state->uapi.visible) |
| 328 | 329 | new_crtc_state->active_planes |= BIT(plane->id); |
| @@ -3619,9 +3619,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) · 3618 unmodified lines | ||
| 3619 | 3619 | { |
| 3620 | 3620 | int ret; |
| 3621 | 3621 | |
| 3622 | − intel_dp_lttpr_init(intel_dp); | |
| 3623 | − | |
| 3624 | − if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) | |
| 3622 | + if (intel_dp_init_lttpr_and_dprx_caps(intel_dp) < 0) | |
| 3625 | 3623 | return false; |
| 3626 | 3624 | |
| 3627 | 3625 | /* |
| @@ -133,6 +133,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, · 132 unmodified lines | ||
| 133 | 133 | else |
| 134 | 134 | precharge = 5; |
| 135 | 135 | |
| 136 | + /* Max timeout value on G4x-BDW: 1.6ms */ | |
| 136 | 137 | if (IS_BROADWELL(dev_priv)) |
| 137 | 138 | timeout = DP_AUX_CH_CTL_TIME_OUT_600us; |
| 138 | 139 | else |
| @@ -159,6 +160,12 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp, · 20 unmodified lines | ||
| 159 | 160 | enum phy phy = intel_port_to_phy(i915, dig_port->base.port); |
| 160 | 161 | u32 ret; |
| 161 | 162 | |
| 163 | + /* | |
| 164 | + * Max timeout values: | |
| 165 | + * SKL-GLK: 1.6ms | |
| 166 | + * CNL: 3.2ms | |
| 167 | + * ICL+: 4ms | |
| 168 | + */ | |
| 162 | 169 | ret = DP_AUX_CH_CTL_SEND_BUSY | |
| 163 | 170 | DP_AUX_CH_CTL_DONE | |
| 164 | 171 | DP_AUX_CH_CTL_INTERRUPT | |
| @@ -34,6 +34,11 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE]) · 33 unmodified lines | ||
| 34 | 34 | link_status[3], link_status[4], link_status[5]); |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | +static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp) | |
| 38 | +{ | |
| 39 | + memset(&intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps)); | |
| 40 | +} | |
| 41 | + | |
| 37 | 42 | static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp) |
| 38 | 43 | { |
| 39 | 44 | intel_dp->lttpr_common_caps[DP_PHY_REPEATER_CNT - |
| @@ -81,19 +86,36 @@ static void intel_dp_read_lttpr_phy_caps(struct intel_dp *intel_dp, · 41 unmodified lines | ||
| 81 | 86 | |
| 82 | 87 | static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp) |
| 83 | 88 | { |
| 84 | − if (drm_dp_read_lttpr_common_caps(&intel_dp->aux, | |
| 85 | − intel_dp->lttpr_common_caps) < 0) { | |
| 86 | − memset(intel_dp->lttpr_common_caps, 0, | |
| 87 | − sizeof(intel_dp->lttpr_common_caps)); | |
| 89 | + struct drm_i915_private *i915 = dp_to_i915(intel_dp); | |
| 90 | + | |
| 91 | + if (intel_dp_is_edp(intel_dp)) | |
| 88 | 92 | return false; |
| 89 | − } | |
| 93 | + | |
| 94 | + /* | |
| 95 | + * Detecting LTTPRs must be avoided on platforms with an AUX timeout | |
| 96 | + * period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1). | |
| 97 | + */ | |
| 98 | + if (INTEL_GEN(i915) < 10) | |
| 99 | + return false; | |
| 100 | + | |
| 101 | + if (drm_dp_read_lttpr_common_caps(&intel_dp->aux, | |
| 102 | + intel_dp->lttpr_common_caps) < 0) | |
| 103 | + goto reset_caps; | |
| 90 | 104 | |
| 91 | 105 | drm_dbg_kms(&dp_to_i915(intel_dp)->drm, |
| 92 | 106 | "LTTPR common capabilities: %*ph\n", |
| 93 | 107 | (int)sizeof(intel_dp->lttpr_common_caps), |
| 94 | 108 | intel_dp->lttpr_common_caps); |
| 95 | 109 | |
| 110 | + /* The minimum value of LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV is 1.4 */ | |
| 111 | + if (intel_dp->lttpr_common_caps[0] < 0x14) | |
| 112 | + goto reset_caps; | |
| 113 | + | |
| 96 | 114 | return true; |
| 115 | + | |
| 116 | +reset_caps: | |
| 117 | + intel_dp_reset_lttpr_common_caps(intel_dp); | |
| 118 | + return false; | |
| 97 | 119 | } |
| 98 | 120 | |
| 99 | 121 | static bool |
| @@ -106,33 +128,49 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable) · 6 unmodified lines | ||
| 106 | 128 | } |
| 107 | 129 | |
| 108 | 130 | /** |
| 109 | − * intel_dp_lttpr_init - detect LTTPRs and init the LTTPR link training mode | |
| 131 | + * intel_dp_init_lttpr_and_dprx_caps - detect LTTPR and DPRX caps, init the LTTPR link training mode | |
| 110 | 132 | * @intel_dp: Intel DP struct |
| 111 | 133 | * |
| 112 | − * Read the LTTPR common capabilities, switch to non-transparent link training | |
| 113 | − * mode if any is detected and read the PHY capabilities for all detected | |
| 114 | − * LTTPRs. In case of an LTTPR detection error or if the number of | |
| 134 | + * Read the LTTPR common and DPRX capabilities and switch to non-transparent | |
| 135 | + * link training mode if any is detected and read the PHY capabilities for all | |
| 136 | + * detected LTTPRs. In case of an LTTPR detection error or if the number of | |
| 115 | 137 | * LTTPRs is more than is supported (8), fall back to the no-LTTPR, |
| 116 | 138 | * transparent mode link training mode. |
| 117 | 139 | * |
| 118 | 140 | * Returns: |
| 119 | − * >0 if LTTPRs were detected and the non-transparent LT mode was set | |
| 141 | + * >0 if LTTPRs were detected and the non-transparent LT mode was set. The | |
| 142 | + * DPRX capabilities are read out. | |
| 120 | 143 | * 0 if no LTTPRs or more than 8 LTTPRs were detected or in case of a |
| 121 | − * detection failure and the transparent LT mode was set | |
| 144 | + * detection failure and the transparent LT mode was set. The DPRX | |
| 145 | + * capabilities are read out. | |
| 146 | + * <0 Reading out the DPRX capabilities failed. | |
| 122 | 147 | */ |
| 123 | −int intel_dp_lttpr_init(struct intel_dp *intel_dp) | |
| 148 | +int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp) | |
| 124 | 149 | { |
| 125 | 150 | int lttpr_count; |
| 126 | 151 | bool ret; |
| 127 | 152 | int i; |
| 128 | 153 | |
| 129 | − if (intel_dp_is_edp(intel_dp)) | |
| 130 | − return 0; | |
| 131 | − | |
| 132 | 154 | ret = intel_dp_read_lttpr_common_caps(intel_dp); |
| 155 | + | |
| 156 | + /* The DPTX shall read the DPRX caps after LTTPR detection. */ | |
| 157 | + if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) { | |
| 158 | + intel_dp_reset_lttpr_common_caps(intel_dp); | |
| 159 | + return -EIO; | |
| 160 | + } | |
| 161 | + | |
| 133 | 162 | if (!ret) |
| 134 | 163 | return 0; |
| 135 | 164 | |
| 165 | + /* | |
| 166 | + * The 0xF0000-0xF02FF range is only valid if the DPCD revision is | |
| 167 | + * at least 1.4. | |
| 168 | + */ | |
| 169 | + if (intel_dp->dpcd[DP_DPCD_REV] < 0x14) { | |
| 170 | + intel_dp_reset_lttpr_common_caps(intel_dp); | |
| 171 | + return 0; | |
| 172 | + } | |
| 173 | + | |
| 136 | 174 | lttpr_count = drm_dp_lttpr_count(intel_dp->lttpr_common_caps); |
| 137 | 175 | /* |
| 138 | 176 | * Prevent setting LTTPR transparent mode explicitly if no LTTPRs are |
| @@ -172,7 +210,7 @@ int intel_dp_lttpr_init(struct intel_dp *intel_dp) · 33 unmodified lines | ||
| 172 | 210 | |
| 173 | 211 | return lttpr_count; |
| 174 | 212 | } |
| 175 | −EXPORT_SYMBOL(intel_dp_lttpr_init); | |
| 213 | +EXPORT_SYMBOL(intel_dp_init_lttpr_and_dprx_caps); | |
| 176 | 214 | |
| 177 | 215 | static u8 dp_voltage_max(u8 preemph) |
| 178 | 216 | { |
| @@ -807,7 +845,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp, · 628 unmodified lines | ||
| 807 | 845 | * TODO: Reiniting LTTPRs here won't be needed once proper connector |
| 808 | 846 | * HW state readout is added. |
| 809 | 847 | */ |
| 810 | − int lttpr_count = intel_dp_lttpr_init(intel_dp); | |
| 848 | + int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); | |
| 849 | + | |
| 850 | + if (lttpr_count < 0) | |
| 851 | + return; | |
| 811 | 852 | |
| 812 | 853 | if (!intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count)) |
| 813 | 854 | intel_dp_schedule_fallback_link_training(intel_dp, crtc_state); |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | struct intel_crtc_state; |
| 12 | 12 | struct intel_dp; |
| 13 | 13 | |
| 14 | −int intel_dp_lttpr_init(struct intel_dp *intel_dp); | |
| 14 | +int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp); | |
| 15 | 15 | |
| 16 | 16 | void intel_dp_get_adjust_train(struct intel_dp *intel_dp, |
| 17 | 17 | const struct intel_crtc_state *crtc_state, |
| @@ -1014,20 +1014,14 @@ static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state) · 1013 unmodified lines | ||
| 1014 | 1014 | { |
| 1015 | 1015 | enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; |
| 1016 | 1016 | |
| 1017 | − if (crtc_state->cpu_transcoder == TRANSCODER_EDP) | |
| 1018 | − return DSS_CTL1; | |
| 1019 | − | |
| 1020 | − return ICL_PIPE_DSS_CTL1(pipe); | |
| 1017 | + return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL1(pipe) : DSS_CTL1; | |
| 1021 | 1018 | } |
| 1022 | 1019 | |
| 1023 | 1020 | static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state) |
| 1024 | 1021 | { |
| 1025 | 1022 | enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; |
| 1026 | 1023 | |
| 1027 | − if (crtc_state->cpu_transcoder == TRANSCODER_EDP) | |
| 1028 | − return DSS_CTL2; | |
| 1029 | − | |
| 1030 | − return ICL_PIPE_DSS_CTL2(pipe); | |
| 1024 | + return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL2(pipe) : DSS_CTL2; | |
| 1031 | 1025 | } |
| 1032 | 1026 | |
| 1033 | 1027 | void intel_dsc_enable(struct intel_encoder *encoder, |
| @@ -316,7 +316,18 @@ void i915_vma_revoke_fence(struct i915_vma *vma) · 315 unmodified lines | ||
| 316 | 316 | WRITE_ONCE(fence->vma, NULL); |
| 317 | 317 | vma->fence = NULL; |
| 318 | 318 | |
| 319 | − with_intel_runtime_pm_if_in_use(fence_to_uncore(fence)->rpm, wakeref) | |
| 319 | + /* | |
| 320 | + * Skip the write to HW if and only if the device is currently | |
| 321 | + * suspended. | |
| 322 | + * | |
| 323 | + * If the driver does not currently hold a wakeref (if_in_use == 0), | |
| 324 | + * the device may currently be runtime suspended, or it may be woken | |
| 325 | + * up before the suspend takes place. If the device is not suspended | |
| 326 | + * (powered down) and we skip clearing the fence register, the HW is | |
| 327 | + * left in an undefined state where we may end up with multiple | |
| 328 | + * registers overlapping. | |
| 329 | + */ | |
| 330 | + with_intel_runtime_pm_if_active(fence_to_uncore(fence)->rpm, wakeref) | |
| 320 | 331 | fence_write(fence); |
| 321 | 332 | } |
| 322 | 333 | |
| @@ -412,12 +412,20 @@ intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm) · 411 unmodified lines | ||
| 412 | 412 | } |
| 413 | 413 | |
| 414 | 414 | /** |
| 415 | − * intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use | |
| 415 | + * __intel_runtime_pm_get_if_active - grab a runtime pm reference if device is active | |
| 416 | 416 | * @rpm: the intel_runtime_pm structure |
| 417 | + * @ignore_usecount: get a ref even if dev->power.usage_count is 0 | |
| 417 | 418 | * |
| 418 | 419 | * This function grabs a device-level runtime pm reference if the device is |
| 419 | − * already in use and ensures that it is powered up. It is illegal to try | |
| 420 | − * and access the HW should intel_runtime_pm_get_if_in_use() report failure. | |
| 420 | + * already active and ensures that it is powered up. It is illegal to try | |
| 421 | + * and access the HW should intel_runtime_pm_get_if_active() report failure. | |
| 422 | + * | |
| 423 | + * If @ignore_usecount=true, a reference will be acquired even if there is no | |
| 424 | + * user requiring the device to be powered up (dev->power.usage_count == 0). | |
| 425 | + * If the function returns false in this case then it's guaranteed that the | |
| 426 | + * device's runtime suspend hook has been called already or that it will be | |
| 427 | + * called (and hence it's also guaranteed that the device's runtime resume | |
| 428 | + * hook will be called eventually). | |
| 421 | 429 | * |
| 422 | 430 | * Any runtime pm reference obtained by this function must have a symmetric |
| 423 | 431 | * call to intel_runtime_pm_put() to release the reference again. |
| @@ -425,7 +433,8 @@ intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm) · 1 unmodified line | ||
| 425 | 433 | * Returns: the wakeref cookie to pass to intel_runtime_pm_put(), evaluates |
| 426 | 434 | * as True if the wakeref was acquired, or False otherwise. |
| 427 | 435 | */ |
| 428 | −intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) | |
| 436 | +static intel_wakeref_t __intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm, | |
| 437 | + bool ignore_usecount) | |
| 429 | 438 | { |
| 430 | 439 | if (IS_ENABLED(CONFIG_PM)) { |
| 431 | 440 | /* |
| @@ -434,7 +443,7 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) · 2 unmodified lines | ||
| 434 | 443 | * function, since the power state is undefined. This applies |
| 435 | 444 | * atm to the late/early system suspend/resume handlers. |
| 436 | 445 | */ |
| 437 | − if (pm_runtime_get_if_in_use(rpm->kdev) <= 0) | |
| 446 | + if (pm_runtime_get_if_active(rpm->kdev, ignore_usecount) <= 0) | |
| 438 | 447 | return 0; |
| 439 | 448 | } |
| 440 | 449 | |
| @@ -443,6 +452,16 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) · 2 unmodified lines | ||
| 443 | 452 | return track_intel_runtime_pm_wakeref(rpm); |
| 444 | 453 | } |
| 445 | 454 | |
| 455 | +intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) | |
| 456 | +{ | |
| 457 | + return __intel_runtime_pm_get_if_active(rpm, false); | |
| 458 | +} | |
| 459 | + | |
| 460 | +intel_wakeref_t intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm) | |
| 461 | +{ | |
| 462 | + return __intel_runtime_pm_get_if_active(rpm, true); | |
| 463 | +} | |
| 464 | + | |
| 446 | 465 | /** |
| 447 | 466 | * intel_runtime_pm_get_noresume - grab a runtime pm reference |
| 448 | 467 | * @rpm: the intel_runtime_pm structure |
| @@ -177,6 +177,7 @@ void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm); · 176 unmodified lines | ||
| 177 | 177 | |
| 178 | 178 | intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm); |
| 179 | 179 | intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm); |
| 180 | +intel_wakeref_t intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm); | |
| 180 | 181 | intel_wakeref_t intel_runtime_pm_get_noresume(struct intel_runtime_pm *rpm); |
| 181 | 182 | intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); |
| 182 | 183 | |
| @@ -188,6 +189,10 @@ intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); · 5 unmodified lines | ||
| 188 | 189 | for ((wf) = intel_runtime_pm_get_if_in_use(rpm); (wf); \ |
| 189 | 190 | intel_runtime_pm_put((rpm), (wf)), (wf) = 0) |
| 190 | 191 | |
| 192 | +#define with_intel_runtime_pm_if_active(rpm, wf) \ | |
| 193 | + for ((wf) = intel_runtime_pm_get_if_active(rpm); (wf); \ | |
| 194 | + intel_runtime_pm_put((rpm), (wf)), (wf) = 0) | |
| 195 | + | |
| 191 | 196 | void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm); |
| 192 | 197 | #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) |
| 193 | 198 | void intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref); |
| @@ -215,7 +215,7 @@ static int imx_drm_bind(struct device *dev) · 214 unmodified lines | ||
| 215 | 215 | |
| 216 | 216 | ret = drmm_mode_config_init(drm); |
| 217 | 217 | if (ret) |
| 218 | − return ret; | |
| 218 | + goto err_kms; | |
| 219 | 219 | |
| 220 | 220 | ret = drm_vblank_init(drm, MAX_CRTC); |
| 221 | 221 | if (ret) |
| @@ -197,6 +197,11 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder) · 196 unmodified lines | ||
| 197 | 197 | int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; |
| 198 | 198 | int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); |
| 199 | 199 | |
| 200 | + if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { | |
| 201 | + dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); | |
| 202 | + return; | |
| 203 | + } | |
| 204 | + | |
| 200 | 205 | drm_panel_prepare(imx_ldb_ch->panel); |
| 201 | 206 | |
| 202 | 207 | if (dual) { |
| @@ -255,6 +260,11 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder, · 52 unmodified lines | ||
| 255 | 260 | int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); |
| 256 | 261 | u32 bus_format = imx_ldb_ch->bus_format; |
| 257 | 262 | |
| 263 | + if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { | |
| 264 | + dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); | |
| 265 | + return; | |
| 266 | + } | |
| 267 | + | |
| 258 | 268 | if (mode->clock > 170000) { |
| 259 | 269 | dev_warn(ldb->dev, |
| 260 | 270 | "%s: mode exceeds 170 MHz pixel clock\n", __func__); |
| @@ -583,7 +593,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) · 322 unmodified lines | ||
| 583 | 593 | struct imx_ldb_channel *channel = &imx_ldb->channel[i]; |
| 584 | 594 | |
| 585 | 595 | if (!channel->ldb) |
| 586 | − break; | |
| 596 | + continue; | |
| 587 | 597 | |
| 588 | 598 | ret = imx_ldb_register(drm, channel); |
| 589 | 599 | if (ret) |
| @@ -304,7 +304,7 @@ int a5xx_power_init(struct msm_gpu *gpu) · 303 unmodified lines | ||
| 304 | 304 | /* Set up the limits management */ |
| 305 | 305 | if (adreno_is_a530(adreno_gpu)) |
| 306 | 306 | a530_lm_setup(gpu); |
| 307 | − else | |
| 307 | + else if (adreno_is_a540(adreno_gpu)) | |
| 308 | 308 | a540_lm_setup(gpu); |
| 309 | 309 | |
| 310 | 310 | /* Set up SP/TP power collpase */ |
| @@ -339,7 +339,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) · 338 unmodified lines | ||
| 339 | 339 | else |
| 340 | 340 | bit = a6xx_gmu_oob_bits[state].ack_new; |
| 341 | 341 | |
| 342 | − gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, bit); | |
| 342 | + gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit); | |
| 343 | 343 | } |
| 344 | 344 | |
| 345 | 345 | /* Enable CPU control of SPTP power power collapse */ |
| @@ -522,28 +522,73 @@ static int a6xx_cp_init(struct msm_gpu *gpu) · 521 unmodified lines | ||
| 522 | 522 | return a6xx_idle(gpu, ring) ? 0 : -EINVAL; |
| 523 | 523 | } |
| 524 | 524 | |
| 525 | −static void a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, | |
| 525 | +/* | |
| 526 | + * Check that the microcode version is new enough to include several key | |
| 527 | + * security fixes. Return true if the ucode is safe. | |
| 528 | + */ | |
| 529 | +static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, | |
| 526 | 530 | struct drm_gem_object *obj) |
| 527 | 531 | { |
| 532 | + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; | |
| 533 | + struct msm_gpu *gpu = &adreno_gpu->base; | |
| 528 | 534 | u32 *buf = msm_gem_get_vaddr(obj); |
| 535 | + bool ret = false; | |
| 529 | 536 | |
| 530 | 537 | if (IS_ERR(buf)) |
| 531 | − return; | |
| 538 | + return false; | |
| 532 | 539 | |
| 533 | 540 | /* |
| 534 | − * If the lowest nibble is 0xa that is an indication that this microcode | |
| 535 | − * has been patched. The actual version is in dword [3] but we only care | |
| 536 | − * about the patchlevel which is the lowest nibble of dword [3] | |
| 537 | − * | |
| 538 | − * Otherwise check that the firmware is greater than or equal to 1.90 | |
| 539 | − * which was the first version that had this fix built in | |
| 541 | + * Targets up to a640 (a618, a630 and a640) need to check for a | |
| 542 | + * microcode version that is patched to support the whereami opcode or | |
| 543 | + * one that is new enough to include it by default. | |
| 540 | 544 | */ |
| 541 | − if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) | |
| 542 | − a6xx_gpu->has_whereami = true; | |
| 543 | − else if ((buf[0] & 0xfff) > 0x190) | |
| 544 | − a6xx_gpu->has_whereami = true; | |
| 545 | + if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) || | |
| 546 | + adreno_is_a640(adreno_gpu)) { | |
| 547 | + /* | |
| 548 | + * If the lowest nibble is 0xa that is an indication that this | |
| 549 | + * microcode has been patched. The actual version is in dword | |
| 550 | + * [3] but we only care about the patchlevel which is the lowest | |
| 551 | + * nibble of dword [3] | |
| 552 | + * | |
| 553 | + * Otherwise check that the firmware is greater than or equal | |
| 554 | + * to 1.90 which was the first version that had this fix built | |
| 555 | + * in | |
| 556 | + */ | |
| 557 | + if ((((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) || | |
| 558 | + (buf[0] & 0xfff) >= 0x190) { | |
| 559 | + a6xx_gpu->has_whereami = true; | |
| 560 | + ret = true; | |
| 561 | + goto out; | |
| 562 | + } | |
| 563 | + | |
| 564 | + DRM_DEV_ERROR(&gpu->pdev->dev, | |
| 565 | + "a630 SQE ucode is too old. Have version %x need at least %x\n", | |
| 566 | + buf[0] & 0xfff, 0x190); | |
| 567 | + } else { | |
| 568 | + /* | |
| 569 | + * a650 tier targets don't need whereami but still need to be | |
| 570 | + * equal to or newer than 1.95 for other security fixes | |
| 571 | + */ | |
| 572 | + if (adreno_is_a650(adreno_gpu)) { | |
| 573 | + if ((buf[0] & 0xfff) >= 0x195) { | |
| 574 | + ret = true; | |
| 575 | + goto out; | |
| 576 | + } | |
| 577 | + | |
| 578 | + DRM_DEV_ERROR(&gpu->pdev->dev, | |
| 579 | + "a650 SQE ucode is too old. Have version %x need at least %x\n", | |
| 580 | + buf[0] & 0xfff, 0x195); | |
| 581 | + } | |
| 545 | 582 | |
| 583 | + /* | |
| 584 | + * When a660 is added those targets should return true here | |
| 585 | + * since those have all the critical security fixes built in | |
| 586 | + * from the start | |
| 587 | + */ | |
| 588 | + } | |
| 589 | +out: | |
| 546 | 590 | msm_gem_put_vaddr(obj); |
| 591 | + return ret; | |
| 547 | 592 | } |
| 548 | 593 | |
| 549 | 594 | static int a6xx_ucode_init(struct msm_gpu *gpu) |
| @@ -566,7 +611,13 @@ static int a6xx_ucode_init(struct msm_gpu *gpu) · 16 unmodified lines | ||
| 566 | 611 | } |
| 567 | 612 | |
| 568 | 613 | msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw"); |
| 569 | − a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo); | |
| 614 | + if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) { | |
| 615 | + msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace); | |
| 616 | + drm_gem_object_put(a6xx_gpu->sqe_bo); | |
| 617 | + | |
| 618 | + a6xx_gpu->sqe_bo = NULL; | |
| 619 | + return -EPERM; | |
| 620 | + } | |
| 570 | 621 | } |
| 571 | 622 | |
| 572 | 623 | gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE_LO, |
| @@ -1350,35 +1401,20 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, · 777 unmodified lines | ||
| 1350 | 1401 | u32 revn) |
| 1351 | 1402 | { |
| 1352 | 1403 | struct opp_table *opp_table; |
| 1353 | − struct nvmem_cell *cell; | |
| 1354 | 1404 | u32 supp_hw = UINT_MAX; |
| 1355 | − void *buf; | |
| 1356 | − | |
| 1357 | − cell = nvmem_cell_get(dev, "speed_bin"); | |
| 1358 | − /* | |
| 1359 | − * -ENOENT means that the platform doesn't support speedbin which is | |
| 1360 | − * fine | |
| 1361 | − */ | |
| 1362 | − if (PTR_ERR(cell) == -ENOENT) | |
| 1363 | − return 0; | |
| 1364 | − else if (IS_ERR(cell)) { | |
| 1365 | − DRM_DEV_ERROR(dev, | |
| 1366 | − "failed to read speed-bin. Some OPPs may not be supported by hardware"); | |
| 1367 | − goto done; | |
| 1368 | − } | |
| 1405 | + u16 speedbin; | |
| 1406 | + int ret; | |
| 1369 | 1407 | |
| 1370 | − buf = nvmem_cell_read(cell, NULL); | |
| 1371 | − if (IS_ERR(buf)) { | |
| 1372 | − nvmem_cell_put(cell); | |
| 1408 | + ret = nvmem_cell_read_u16(dev, "speed_bin", &speedbin); | |
| 1409 | + if (ret) { | |
| 1373 | 1410 | DRM_DEV_ERROR(dev, |
| 1374 | − "failed to read speed-bin. Some OPPs may not be supported by hardware"); | |
| 1411 | + "failed to read speed-bin (%d). Some OPPs may not be supported by hardware", | |
| 1412 | + ret); | |
| 1375 | 1413 | goto done; |
| 1376 | 1414 | } |
| 1415 | + speedbin = le16_to_cpu(speedbin); | |
| 1377 | 1416 | |
| 1378 | − supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf)); | |
| 1379 | − | |
| 1380 | − kfree(buf); | |
| 1381 | − nvmem_cell_put(cell); | |
| 1417 | + supp_hw = fuse_to_supp_hw(dev, revn, speedbin); | |
| 1382 | 1418 | |
| 1383 | 1419 | done: |
| 1384 | 1420 | opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1); |
| @@ -43,6 +43,8 @@ · 42 unmodified lines | ||
| 43 | 43 | #define DPU_DEBUGFS_DIR "msm_dpu" |
| 44 | 44 | #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" |
| 45 | 45 | |
| 46 | +#define MIN_IB_BW 400000000ULL /* Min ib vote 400MB */ | |
| 47 | + | |
| 46 | 48 | static int dpu_kms_hw_init(struct msm_kms *kms); |
| 47 | 49 | static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); |
| 48 | 50 | |
| @@ -931,6 +933,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 882 unmodified lines | ||
| 931 | 933 | DPU_DEBUG("REG_DMA is not defined"); |
| 932 | 934 | } |
| 933 | 935 | |
| 936 | + if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) | |
| 937 | + dpu_kms_parse_data_bus_icc_path(dpu_kms); | |
| 938 | + | |
| 934 | 939 | pm_runtime_get_sync(&dpu_kms->pdev->dev); |
| 935 | 940 | |
| 936 | 941 | dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0); |
| @@ -1032,9 +1037,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 95 unmodified lines | ||
| 1032 | 1037 | |
| 1033 | 1038 | dpu_vbif_init_memtypes(dpu_kms); |
| 1034 | 1039 | |
| 1035 | − if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) | |
| 1036 | − dpu_kms_parse_data_bus_icc_path(dpu_kms); | |
| 1037 | − | |
| 1038 | 1040 | pm_runtime_put_sync(&dpu_kms->pdev->dev); |
| 1039 | 1041 | |
| 1040 | 1042 | return 0; |
| @@ -1191,10 +1193,10 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) · 150 unmodified lines | ||
| 1191 | 1193 | |
| 1192 | 1194 | ddev = dpu_kms->dev; |
| 1193 | 1195 | |
| 1196 | + WARN_ON(!(dpu_kms->num_paths)); | |
| 1194 | 1197 | /* Min vote of BW is required before turning on AXI clk */ |
| 1195 | 1198 | for (i = 0; i < dpu_kms->num_paths; i++) |
| 1196 | − icc_set_bw(dpu_kms->path[i], 0, | |
| 1197 | − dpu_kms->catalog->perf.min_dram_ib); | |
| 1199 | + icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW)); | |
| 1198 | 1200 | |
| 1199 | 1201 | rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); |
| 1200 | 1202 | if (rc) { |
| @@ -32,6 +32,8 @@ struct dp_aux_private { · 31 unmodified lines | ||
| 32 | 32 | struct drm_dp_aux dp_aux; |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | +#define MAX_AUX_RETRIES 5 | |
| 36 | + | |
| 35 | 37 | static const char *dp_aux_get_error(u32 aux_error) |
| 36 | 38 | { |
| 37 | 39 | switch (aux_error) { |
| @@ -377,6 +379,11 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 339 unmodified lines | ||
| 377 | 379 | ret = dp_aux_cmd_fifo_tx(aux, msg); |
| 378 | 380 | |
| 379 | 381 | if (ret < 0) { |
| 382 | + if (aux->native) { | |
| 383 | + aux->retry_cnt++; | |
| 384 | + if (!(aux->retry_cnt % MAX_AUX_RETRIES)) | |
| 385 | + dp_catalog_aux_update_cfg(aux->catalog); | |
| 386 | + } | |
| 380 | 387 | usleep_range(400, 500); /* at least 400us to next try */ |
| 381 | 388 | goto unlock_exit; |
| 382 | 389 | } |
| @@ -163,7 +163,7 @@ struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev, · 162 unmodified lines | ||
| 163 | 163 | break; |
| 164 | 164 | case MSM_DSI_PHY_7NM: |
| 165 | 165 | case MSM_DSI_PHY_7NM_V4_1: |
| 166 | − pll = msm_dsi_pll_7nm_init(pdev, id); | |
| 166 | + pll = msm_dsi_pll_7nm_init(pdev, type, id); | |
| 167 | 167 | break; |
| 168 | 168 | default: |
| 169 | 169 | pll = ERR_PTR(-ENXIO); |
| @@ -117,10 +117,12 @@ msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) · 116 unmodified lines | ||
| 117 | 117 | } |
| 118 | 118 | #endif |
| 119 | 119 | #ifdef CONFIG_DRM_MSM_DSI_7NM_PHY |
| 120 | −struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id); | |
| 120 | +struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, | |
| 121 | + enum msm_dsi_phy_type type, int id); | |
| 121 | 122 | #else |
| 122 | 123 | static inline struct msm_dsi_pll * |
| 123 | −msm_dsi_pll_7nm_init(struct platform_device *pdev, int id) | |
| 124 | +msm_dsi_pll_7nm_init(struct platform_device *pdev, | |
| 125 | + enum msm_dsi_phy_type type, int id) | |
| 124 | 126 | { |
| 125 | 127 | return ERR_PTR(-ENODEV); |
| 126 | 128 | } |
| @@ -325,7 +325,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll) · 324 unmodified lines | ||
| 325 | 325 | pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); |
| 326 | 326 | pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); |
| 327 | 327 | pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); |
| 328 | − pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40); | |
| 328 | + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate); | |
| 329 | 329 | pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); |
| 330 | 330 | pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ |
| 331 | 331 | pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); |
| @@ -509,6 +509,7 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, · 177 unmodified lines | ||
| 509 | 509 | { |
| 510 | 510 | struct msm_dsi_pll *pll = hw_clk_to_pll(hw); |
| 511 | 511 | struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); |
| 512 | + struct dsi_pll_config *config = &pll_7nm->pll_configuration; | |
| 512 | 513 | void __iomem *base = pll_7nm->mmio; |
| 513 | 514 | u64 ref_clk = pll_7nm->vco_ref_clk_rate; |
| 514 | 515 | u64 vco_rate = 0x0; |
| @@ -529,9 +530,8 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, · 14 unmodified lines | ||
| 529 | 530 | /* |
| 530 | 531 | * TODO: |
| 531 | 532 | * 1. Assumes prescaler is disabled |
| 532 | − * 2. Multiplier is 2^18. it should be 2^(num_of_frac_bits) | |
| 533 | 533 | */ |
| 534 | − multiplier = 1 << 18; | |
| 534 | + multiplier = 1 << config->frac_bits; | |
| 535 | 535 | pll_freq = dec * (ref_clk * 2); |
| 536 | 536 | tmp64 = (ref_clk * 2 * frac); |
| 537 | 537 | pll_freq += div_u64(tmp64, multiplier); |
| @@ -852,7 +852,8 @@ err_base_clk_hw: · 314 unmodified lines | ||
| 852 | 852 | return ret; |
| 853 | 853 | } |
| 854 | 854 | |
| 855 | −struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id) | |
| 855 | +struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, | |
| 856 | + enum msm_dsi_phy_type type, int id) | |
| 856 | 857 | { |
| 857 | 858 | struct dsi_pll_7nm *pll_7nm; |
| 858 | 859 | struct msm_dsi_pll *pll; |
| @@ -885,7 +886,7 @@ struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id) · 26 unmodified lines | ||
| 885 | 886 | pll = &pll_7nm->base; |
| 886 | 887 | pll->min_rate = 1000000000UL; |
| 887 | 888 | pll->max_rate = 3500000000UL; |
| 888 | − if (pll->type == MSM_DSI_PHY_7NM_V4_1) { | |
| 889 | + if (type == MSM_DSI_PHY_7NM_V4_1) { | |
| 889 | 890 | pll->min_rate = 600000000UL; |
| 890 | 891 | pll->max_rate = (unsigned long)5000000000ULL; |
| 891 | 892 | /* workaround for max rate overflowing on 32-bit builds: */ |
| @@ -57,10 +57,13 @@ static void vblank_put(struct msm_kms *kms, unsigned crtc_mask) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | static void lock_crtcs(struct msm_kms *kms, unsigned int crtc_mask) |
| 59 | 59 | { |
| 60 | + int crtc_index; | |
| 60 | 61 | struct drm_crtc *crtc; |
| 61 | 62 | |
| 62 | − for_each_crtc_mask(kms->dev, crtc, crtc_mask) | |
| 63 | − mutex_lock(&kms->commit_lock[drm_crtc_index(crtc)]); | |
| 63 | + for_each_crtc_mask(kms->dev, crtc, crtc_mask) { | |
| 64 | + crtc_index = drm_crtc_index(crtc); | |
| 65 | + mutex_lock_nested(&kms->commit_lock[crtc_index], crtc_index); | |
| 66 | + } | |
| 64 | 67 | } |
| 65 | 68 | |
| 66 | 69 | static void unlock_crtcs(struct msm_kms *kms, unsigned int crtc_mask) |
| @@ -1072,6 +1072,10 @@ static int __maybe_unused msm_pm_resume(struct device *dev) · 1071 unmodified lines | ||
| 1072 | 1072 | static int __maybe_unused msm_pm_prepare(struct device *dev) |
| 1073 | 1073 | { |
| 1074 | 1074 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 1075 | + struct msm_drm_private *priv = ddev ? ddev->dev_private : NULL; | |
| 1076 | + | |
| 1077 | + if (!priv || !priv->kms) | |
| 1078 | + return 0; | |
| 1075 | 1079 | |
| 1076 | 1080 | return drm_mode_config_helper_suspend(ddev); |
| 1077 | 1081 | } |
| @@ -1079,6 +1083,10 @@ static int __maybe_unused msm_pm_prepare(struct device *dev) · 1 unmodified line | ||
| 1079 | 1083 | static void __maybe_unused msm_pm_complete(struct device *dev) |
| 1080 | 1084 | { |
| 1081 | 1085 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 1086 | + struct msm_drm_private *priv = ddev ? ddev->dev_private : NULL; | |
| 1087 | + | |
| 1088 | + if (!priv || !priv->kms) | |
| 1089 | + return; | |
| 1082 | 1090 | |
| 1083 | 1091 | drm_mode_config_helper_resume(ddev); |
| 1084 | 1092 | } |
| @@ -1311,6 +1319,10 @@ static int msm_pdev_remove(struct platform_device *pdev) · 226 unmodified lines | ||
| 1311 | 1319 | static void msm_pdev_shutdown(struct platform_device *pdev) |
| 1312 | 1320 | { |
| 1313 | 1321 | struct drm_device *drm = platform_get_drvdata(pdev); |
| 1322 | + struct msm_drm_private *priv = drm ? drm->dev_private : NULL; | |
| 1323 | + | |
| 1324 | + if (!priv || !priv->kms) | |
| 1325 | + return; | |
| 1314 | 1326 | |
| 1315 | 1327 | drm_atomic_helper_shutdown(drm); |
| 1316 | 1328 | } |
| @@ -45,7 +45,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, · 44 unmodified lines | ||
| 45 | 45 | int ret; |
| 46 | 46 | |
| 47 | 47 | if (fence > fctx->last_fence) { |
| 48 | − DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", | |
| 48 | + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", | |
| 49 | 49 | fctx->name, fence, fctx->last_fence); |
| 50 | 50 | return -EINVAL; |
| 51 | 51 | } |
| @@ -157,7 +157,6 @@ struct msm_kms { · 156 unmodified lines | ||
| 157 | 157 | * from the crtc's pending_timer close to end of the frame: |
| 158 | 158 | */ |
| 159 | 159 | struct mutex commit_lock[MAX_CRTCS]; |
| 160 | − struct lock_class_key commit_lock_keys[MAX_CRTCS]; | |
| 161 | 160 | unsigned pending_crtc_mask; |
| 162 | 161 | struct msm_pending_timer pending_timers[MAX_CRTCS]; |
| 163 | 162 | }; |
| @@ -167,11 +166,8 @@ static inline int msm_kms_init(struct msm_kms *kms, · 3 unmodified lines | ||
| 167 | 166 | { |
| 168 | 167 | unsigned i, ret; |
| 169 | 168 | |
| 170 | − for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++) { | |
| 171 | − lockdep_register_key(&kms->commit_lock_keys[i]); | |
| 172 | − __mutex_init(&kms->commit_lock[i], "&kms->commit_lock[i]", | |
| 173 | − &kms->commit_lock_keys[i]); | |
| 174 | − } | |
| 169 | + for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++) | |
| 170 | + mutex_init(&kms->commit_lock[i]); | |
| 175 | 171 | |
| 176 | 172 | kms->funcs = funcs; |
| 177 | 173 | |
| @@ -2693,9 +2693,20 @@ nv50_display_create(struct drm_device *dev) · 2692 unmodified lines | ||
| 2693 | 2693 | else |
| 2694 | 2694 | nouveau_display(dev)->format_modifiers = disp50xx_modifiers; |
| 2695 | 2695 | |
| 2696 | − if (disp->disp->object.oclass >= GK104_DISP) { | |
| 2696 | + /* FIXME: 256x256 cursors are supported on Kepler, however unlike Maxwell and later | |
| 2697 | + * generations Kepler requires that we use small pages (4K) for cursor scanout surfaces. The | |
| 2698 | + * proper fix for this is to teach nouveau to migrate fbs being used for the cursor plane to | |
| 2699 | + * small page allocations in prepare_fb(). When this is implemented, we should also force | |
| 2700 | + * large pages (128K) for ovly fbs in order to fix Kepler ovlys. | |
| 2701 | + * But until then, just limit cursors to 128x128 - which is small enough to avoid ever using | |
| 2702 | + * large pages. | |
| 2703 | + */ | |
| 2704 | + if (disp->disp->object.oclass >= GM107_DISP) { | |
| 2697 | 2705 | dev->mode_config.cursor_width = 256; |
| 2698 | 2706 | dev->mode_config.cursor_height = 256; |
| 2707 | + } else if (disp->disp->object.oclass >= GK104_DISP) { | |
| 2708 | + dev->mode_config.cursor_width = 128; | |
| 2709 | + dev->mode_config.cursor_height = 128; | |
| 2699 | 2710 | } else { |
| 2700 | 2711 | dev->mode_config.cursor_width = 64; |
| 2701 | 2712 | dev->mode_config.cursor_height = 64; |
| @@ -48,21 +48,12 @@ static unsigned int rcar_du_encoder_count_ports(struct device_node *node) · 47 unmodified lines | ||
| 48 | 48 | static const struct drm_encoder_funcs rcar_du_encoder_funcs = { |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | −static void rcar_du_encoder_release(struct drm_device *dev, void *res) | |
| 52 | −{ | |
| 53 | − struct rcar_du_encoder *renc = res; | |
| 54 | − | |
| 55 | − drm_encoder_cleanup(&renc->base); | |
| 56 | − kfree(renc); | |
| 57 | −} | |
| 58 | − | |
| 59 | 51 | int rcar_du_encoder_init(struct rcar_du_device *rcdu, |
| 60 | 52 | enum rcar_du_output output, |
| 61 | 53 | struct device_node *enc_node) |
| 62 | 54 | { |
| 63 | 55 | struct rcar_du_encoder *renc; |
| 64 | 56 | struct drm_bridge *bridge; |
| 65 | − int ret; | |
| 66 | 57 | |
| 67 | 58 | /* |
| 68 | 59 | * Locate the DRM bridge from the DT node. For the DPAD outputs, if the |
| @@ -101,26 +92,16 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, · 32 unmodified lines | ||
| 101 | 92 | return -ENOLINK; |
| 102 | 93 | } |
| 103 | 94 | |
| 104 | − renc = kzalloc(sizeof(*renc), GFP_KERNEL); | |
| 105 | − if (renc == NULL) | |
| 106 | − return -ENOMEM; | |
| 107 | − | |
| 108 | − renc->output = output; | |
| 109 | − | |
| 110 | 95 | dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n", |
| 111 | 96 | enc_node, output); |
| 112 | 97 | |
| 113 | − ret = drm_encoder_init(&rcdu->ddev, &renc->base, &rcar_du_encoder_funcs, | |
| 114 | − DRM_MODE_ENCODER_NONE, NULL); | |
| 115 | − if (ret < 0) { | |
| 116 | − kfree(renc); | |
| 117 | − return ret; | |
| 118 | − } | |
| 98 | + renc = drmm_encoder_alloc(&rcdu->ddev, struct rcar_du_encoder, base, | |
| 99 | + &rcar_du_encoder_funcs, DRM_MODE_ENCODER_NONE, | |
| 100 | + NULL); | |
| 101 | + if (!renc) | |
| 102 | + return -ENOMEM; | |
| 119 | 103 | |
| 120 | − ret = drmm_add_action_or_reset(&rcdu->ddev, rcar_du_encoder_release, | |
| 121 | − renc); | |
| 122 | − if (ret) | |
| 123 | − return ret; | |
| 104 | + renc->output = output; | |
| 124 | 105 | |
| 125 | 106 | /* |
| 126 | 107 | * Attach the bridge to the encoder. The bridge will create the |
| @@ -1688,6 +1688,11 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, · 1687 unmodified lines | ||
| 1688 | 1688 | dev_err(dc->dev, |
| 1689 | 1689 | "failed to set clock rate to %lu Hz\n", |
| 1690 | 1690 | state->pclk); |
| 1691 | + | |
| 1692 | + err = clk_set_rate(dc->clk, state->pclk); | |
| 1693 | + if (err < 0) | |
| 1694 | + dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", | |
| 1695 | + dc->clk, state->pclk, err); | |
| 1691 | 1696 | } |
| 1692 | 1697 | |
| 1693 | 1698 | DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), |
| @@ -1698,11 +1703,6 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, · 4 unmodified lines | ||
| 1698 | 1703 | value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1; |
| 1699 | 1704 | tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); |
| 1700 | 1705 | } |
| 1701 | − | |
| 1702 | − err = clk_set_rate(dc->clk, state->pclk); | |
| 1703 | − if (err < 0) | |
| 1704 | − dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", | |
| 1705 | − dc->clk, state->pclk, err); | |
| 1706 | 1706 | } |
| 1707 | 1707 | |
| 1708 | 1708 | static void tegra_dc_stop(struct tegra_dc *dc) |
| @@ -2501,22 +2501,18 @@ static int tegra_dc_couple(struct tegra_dc *dc) · 792 unmodified lines | ||
| 2501 | 2501 | * POWER_CONTROL registers during CRTC enabling. |
| 2502 | 2502 | */ |
| 2503 | 2503 | if (dc->soc->coupled_pm && dc->pipe == 1) { |
| 2504 | − u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER; | |
| 2505 | − struct device_link *link; | |
| 2506 | − struct device *partner; | |
| 2504 | + struct device *companion; | |
| 2505 | + struct tegra_dc *parent; | |
| 2507 | 2506 | |
| 2508 | − partner = driver_find_device(dc->dev->driver, NULL, NULL, | |
| 2509 | − tegra_dc_match_by_pipe); | |
| 2510 | − if (!partner) | |
| 2507 | + companion = driver_find_device(dc->dev->driver, NULL, (const void *)0, | |
| 2508 | + tegra_dc_match_by_pipe); | |
| 2509 | + if (!companion) | |
| 2511 | 2510 | return -EPROBE_DEFER; |
| 2512 | 2511 | |
| 2513 | − link = device_link_add(dc->dev, partner, flags); | |
| 2514 | − if (!link) { | |
| 2515 | − dev_err(dc->dev, "failed to link controllers\n"); | |
| 2516 | − return -EINVAL; | |
| 2517 | − } | |
| 2512 | + parent = dev_get_drvdata(companion); | |
| 2513 | + dc->client.parent = &parent->client; | |
| 2518 | 2514 | |
| 2519 | − dev_dbg(dc->dev, "coupled to %s\n", dev_name(partner)); | |
| 2515 | + dev_dbg(dc->dev, "coupled to %s\n", dev_name(companion)); | |
| 2520 | 2516 | } |
| 2521 | 2517 | |
| 2522 | 2518 | return 0; |
| @@ -3115,6 +3115,12 @@ static int tegra_sor_init(struct host1x_client *client) · 3114 unmodified lines | ||
| 3115 | 3115 | * kernel is possible. |
| 3116 | 3116 | */ |
| 3117 | 3117 | if (sor->rst) { |
| 3118 | + err = pm_runtime_resume_and_get(sor->dev); | |
| 3119 | + if (err < 0) { | |
| 3120 | + dev_err(sor->dev, "failed to get runtime PM: %d\n", err); | |
| 3121 | + return err; | |
| 3122 | + } | |
| 3123 | + | |
| 3118 | 3124 | err = reset_control_acquire(sor->rst); |
| 3119 | 3125 | if (err < 0) { |
| 3120 | 3126 | dev_err(sor->dev, "failed to acquire SOR reset: %d\n", |
| @@ -3148,6 +3154,7 @@ static int tegra_sor_init(struct host1x_client *client) · 27 unmodified lines | ||
| 3148 | 3154 | } |
| 3149 | 3155 | |
| 3150 | 3156 | reset_control_release(sor->rst); |
| 3157 | + pm_runtime_put(sor->dev); | |
| 3151 | 3158 | } |
| 3152 | 3159 | |
| 3153 | 3160 | err = clk_prepare_enable(sor->clk_safe); |
| @@ -705,8 +705,9 @@ void host1x_driver_unregister(struct host1x_driver *driver) · 704 unmodified lines | ||
| 705 | 705 | EXPORT_SYMBOL(host1x_driver_unregister); |
| 706 | 706 | |
| 707 | 707 | /** |
| 708 | − * host1x_client_register() - register a host1x client | |
| 708 | + * __host1x_client_register() - register a host1x client | |
| 709 | 709 | * @client: host1x client |
| 710 | + * @key: lock class key for the client-specific mutex | |
| 710 | 711 | * |
| 711 | 712 | * Registers a host1x client with each host1x controller instance. Note that |
| 712 | 713 | * each client will only match their parent host1x controller and will only be |
| @@ -715,13 +716,14 @@ EXPORT_SYMBOL(host1x_driver_unregister); · 2 unmodified lines | ||
| 715 | 716 | * device and call host1x_device_init(), which will in turn call each client's |
| 716 | 717 | * &host1x_client_ops.init implementation. |
| 717 | 718 | */ |
| 718 | −int host1x_client_register(struct host1x_client *client) | |
| 719 | +int __host1x_client_register(struct host1x_client *client, | |
| 720 | + struct lock_class_key *key) | |
| 719 | 721 | { |
| 720 | 722 | struct host1x *host1x; |
| 721 | 723 | int err; |
| 722 | 724 | |
| 723 | 725 | INIT_LIST_HEAD(&client->list); |
| 724 | − mutex_init(&client->lock); | |
| 726 | + __mutex_init(&client->lock, "host1x client lock", key); | |
| 725 | 727 | client->usecount = 0; |
| 726 | 728 | |
| 727 | 729 | mutex_lock(&devices_lock); |
| @@ -742,7 +744,7 @@ int host1x_client_register(struct host1x_client *client) · 14 unmodified lines | ||
| 742 | 744 | |
| 743 | 745 | return 0; |
| 744 | 746 | } |
| 745 | −EXPORT_SYMBOL(host1x_client_register); | |
| 747 | +EXPORT_SYMBOL(__host1x_client_register); | |
| 746 | 748 | |
| 747 | 749 | /** |
| 748 | 750 | * host1x_client_unregister() - unregister a host1x client |
| @@ -3610,13 +3610,13 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) · 3609 unmodified lines | ||
| 3610 | 3610 | ep->com.local_addr.ss_family == AF_INET) { |
| 3611 | 3611 | err = cxgb4_remove_server_filter( |
| 3612 | 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 | 3614 | } else { |
| 3615 | 3615 | struct sockaddr_in6 *sin6; |
| 3616 | 3616 | c4iw_init_wr_wait(ep->com.wr_waitp); |
| 3617 | 3617 | err = cxgb4_remove_server( |
| 3618 | 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 | 3620 | if (err) |
| 3621 | 3621 | goto done; |
| 3622 | 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 | 1194 | upper_32_bits(dma)); |
| 1195 | 1195 | roce_write(hr_dev, ROCEE_TX_CMQ_DEPTH_REG, |
| 1196 | 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 | 1199 | roce_write(hr_dev, ROCEE_TX_CMQ_TAIL_REG, 0); |
| 1200 | + roce_write(hr_dev, ROCEE_TX_CMQ_HEAD_REG, 0); | |
| 1199 | 1201 | } else { |
| 1200 | 1202 | roce_write(hr_dev, ROCEE_RX_CMQ_BASEADDR_L_REG, (u32)dma); |
| 1201 | 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 | 1116 | case MLX5_CMD_OP_CREATE_MKEY: |
| 1117 | 1117 | MLX5_SET(destroy_mkey_in, din, opcode, |
| 1118 | 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 | 1120 | break; |
| 1121 | 1121 | case MLX5_CMD_OP_CREATE_CQ: |
| 1122 | 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 | 1079 | qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc); |
| 1080 | 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 | 1082 | MLX5_SET(qpc, qpc, log_page_size, qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT); |
| 1083 | 1083 | |
| 1084 | 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 | 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 | 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 | 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 | 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 | 1219 | MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING || |
| 1218 | 1220 | MLX5_CAP_ROCE(dev->mdev, qp_ts_format) == |
| 1219 | 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 | 1225 | if (recv_cq && |
| 1223 | 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 | 1933 | if (qp->flags & IB_QP_CREATE_MANAGED_RECV) |
| 1931 | 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 | 1937 | MLX5_SET(qpc, qpc, rq_type, MLX5_SRQ_RQ); |
| 1934 | 1938 | MLX5_SET(qpc, qpc, no_sq, 1); |
| 1935 | 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 | 4877 | struct mlx5_ib_dev *dev; |
| 4874 | 4878 | int has_net_offloads; |
| 4875 | 4879 | __be64 *rq_pas0; |
| 4880 | + int ts_format; | |
| 4876 | 4881 | void *in; |
| 4877 | 4882 | void *rqc; |
| 4878 | 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 | 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 | 4893 | inlen = MLX5_ST_SZ_BYTES(create_rq_in) + sizeof(u64) * rwq->rq_num_pas; |
| 4885 | 4894 | in = kvzalloc(inlen, GFP_KERNEL); |
| 4886 | 4895 | if (!in) |
| @@ -4890,6 +4899,7 @@ static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd, · 3 unmodified lines | ||
| 4890 | 4899 | rqc = MLX5_ADDR_OF(create_rq_in, in, ctx); |
| 4891 | 4900 | MLX5_SET(rqc, rqc, mem_rq_type, |
| 4892 | 4901 | MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE); |
| 4902 | + MLX5_SET(rqc, rqc, ts_format, ts_format); | |
| 4893 | 4903 | MLX5_SET(rqc, rqc, user_index, rwq->user_index); |
| 4894 | 4904 | MLX5_SET(rqc, rqc, cqn, to_mcq(init_attr->cq)->mcq.cqn); |
| 4895 | 4905 | MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST); |
| @@ -53,7 +53,7 @@ void icc_bulk_put(int num_paths, struct icc_bulk_data *paths) · 52 unmodified lines | ||
| 53 | 53 | EXPORT_SYMBOL_GPL(icc_bulk_put); |
| 54 | 54 | |
| 55 | 55 | /** |
| 56 | − * icc_bulk_set() - set bandwidth to a set of paths | |
| 56 | + * icc_bulk_set_bw() - set bandwidth to a set of paths | |
| 57 | 57 | * @num_paths: the number of icc_bulk_data |
| 58 | 58 | * @paths: the icc_bulk_data table containing the paths and bandwidth |
| 59 | 59 | * |
| @@ -942,6 +942,8 @@ int icc_link_destroy(struct icc_node *src, struct icc_node *dst) · 941 unmodified lines | ||
| 942 | 942 | GFP_KERNEL); |
| 943 | 943 | if (new) |
| 944 | 944 | src->links = new; |
| 945 | + else | |
| 946 | + ret = -ENOMEM; | |
| 945 | 947 | |
| 946 | 948 | out: |
| 947 | 949 | mutex_unlock(&icc_lock); |
| @@ -131,7 +131,7 @@ DEFINE_QNODE(mas_pcnoc_sdcc_1, MSM8939_MASTER_SDCC_1, 8, -1, -1, MSM8939_PNOC_IN · 130 unmodified lines | ||
| 131 | 131 | DEFINE_QNODE(mas_pcnoc_sdcc_2, MSM8939_MASTER_SDCC_2, 8, -1, -1, MSM8939_PNOC_INT_1); |
| 132 | 132 | DEFINE_QNODE(mas_qdss_bam, MSM8939_MASTER_QDSS_BAM, 8, -1, -1, MSM8939_SNOC_QDSS_INT); |
| 133 | 133 | DEFINE_QNODE(mas_qdss_etr, MSM8939_MASTER_QDSS_ETR, 8, -1, -1, MSM8939_SNOC_QDSS_INT); |
| 134 | −DEFINE_QNODE(mas_snoc_cfg, MSM8939_MASTER_SNOC_CFG, 4, 20, -1, MSM8939_SLAVE_SRVC_SNOC); | |
| 134 | +DEFINE_QNODE(mas_snoc_cfg, MSM8939_MASTER_SNOC_CFG, 4, -1, -1, MSM8939_SLAVE_SRVC_SNOC); | |
| 135 | 135 | DEFINE_QNODE(mas_spdm, MSM8939_MASTER_SPDM, 4, -1, -1, MSM8939_PNOC_MAS_0); |
| 136 | 136 | DEFINE_QNODE(mas_tcu0, MSM8939_MASTER_TCU0, 16, -1, -1, MSM8939_SLAVE_EBI_CH0, MSM8939_BIMC_SNOC_MAS, MSM8939_SLAVE_AMPSS_L2); |
| 137 | 137 | DEFINE_QNODE(mas_usb_hs1, MSM8939_MASTER_USB_HS1, 4, -1, -1, MSM8939_PNOC_MAS_1); |
| @@ -156,14 +156,14 @@ DEFINE_QNODE(pcnoc_snoc_mas, MSM8939_PNOC_SNOC_MAS, 8, 29, -1, MSM8939_PNOC_SNOC · 18 unmodified lines | ||
| 156 | 156 | DEFINE_QNODE(pcnoc_snoc_slv, MSM8939_PNOC_SNOC_SLV, 8, -1, 45, MSM8939_SNOC_INT_0, MSM8939_SNOC_INT_BIMC, MSM8939_SNOC_INT_1); |
| 157 | 157 | DEFINE_QNODE(qdss_int, MSM8939_SNOC_QDSS_INT, 8, -1, -1, MSM8939_SNOC_INT_0, MSM8939_SNOC_INT_BIMC); |
| 158 | 158 | DEFINE_QNODE(slv_apps_l2, MSM8939_SLAVE_AMPSS_L2, 16, -1, -1, 0); |
| 159 | −DEFINE_QNODE(slv_apss, MSM8939_SLAVE_APSS, 4, -1, 20, 0); | |
| 159 | +DEFINE_QNODE(slv_apss, MSM8939_SLAVE_APSS, 4, -1, -1, 0); | |
| 160 | 160 | DEFINE_QNODE(slv_audio, MSM8939_SLAVE_LPASS, 4, -1, -1, 0); |
| 161 | 161 | DEFINE_QNODE(slv_bimc_cfg, MSM8939_SLAVE_BIMC_CFG, 4, -1, -1, 0); |
| 162 | 162 | DEFINE_QNODE(slv_blsp_1, MSM8939_SLAVE_BLSP_1, 4, -1, -1, 0); |
| 163 | 163 | DEFINE_QNODE(slv_boot_rom, MSM8939_SLAVE_BOOT_ROM, 4, -1, -1, 0); |
| 164 | 164 | DEFINE_QNODE(slv_camera_cfg, MSM8939_SLAVE_CAMERA_CFG, 4, -1, -1, 0); |
| 165 | −DEFINE_QNODE(slv_cats_0, MSM8939_SLAVE_CATS_128, 16, -1, 106, 0); | |
| 166 | −DEFINE_QNODE(slv_cats_1, MSM8939_SLAVE_OCMEM_64, 8, -1, 107, 0); | |
| 165 | +DEFINE_QNODE(slv_cats_0, MSM8939_SLAVE_CATS_128, 16, -1, -1, 0); | |
| 166 | +DEFINE_QNODE(slv_cats_1, MSM8939_SLAVE_OCMEM_64, 8, -1, -1, 0); | |
| 167 | 167 | DEFINE_QNODE(slv_clk_ctl, MSM8939_SLAVE_CLK_CTL, 4, -1, -1, 0); |
| 168 | 168 | DEFINE_QNODE(slv_crypto_0_cfg, MSM8939_SLAVE_CRYPTO_0_CFG, 4, -1, -1, 0); |
| 169 | 169 | DEFINE_QNODE(slv_dehr_cfg, MSM8939_SLAVE_DEHR_CFG, 4, -1, -1, 0); |
| @@ -187,20 +187,20 @@ DEFINE_QNODE(slv_sdcc_2, MSM8939_SLAVE_SDCC_2, 4, -1, -1, 0); · 17 unmodified lines | ||
| 187 | 187 | DEFINE_QNODE(slv_security, MSM8939_SLAVE_SECURITY, 4, -1, -1, 0); |
| 188 | 188 | DEFINE_QNODE(slv_snoc_cfg, MSM8939_SLAVE_SNOC_CFG, 4, -1, -1, 0); |
| 189 | 189 | DEFINE_QNODE(slv_spdm, MSM8939_SLAVE_SPDM, 4, -1, -1, 0); |
| 190 | −DEFINE_QNODE(slv_srvc_snoc, MSM8939_SLAVE_SRVC_SNOC, 8, -1, 29, 0); | |
| 190 | +DEFINE_QNODE(slv_srvc_snoc, MSM8939_SLAVE_SRVC_SNOC, 8, -1, -1, 0); | |
| 191 | 191 | DEFINE_QNODE(slv_tcsr, MSM8939_SLAVE_TCSR, 4, -1, -1, 0); |
| 192 | 192 | DEFINE_QNODE(slv_tlmm, MSM8939_SLAVE_TLMM, 4, -1, -1, 0); |
| 193 | 193 | DEFINE_QNODE(slv_usb_hs1, MSM8939_SLAVE_USB_HS1, 4, -1, -1, 0); |
| 194 | 194 | DEFINE_QNODE(slv_usb_hs2, MSM8939_SLAVE_USB_HS2, 4, -1, -1, 0); |
| 195 | 195 | DEFINE_QNODE(slv_venus_cfg, MSM8939_SLAVE_VENUS_CFG, 4, -1, -1, 0); |
| 196 | −DEFINE_QNODE(snoc_bimc_0_mas, MSM8939_SNOC_BIMC_0_MAS, 16, 3, -1, MSM8939_SNOC_BIMC_0_SLV); | |
| 197 | −DEFINE_QNODE(snoc_bimc_0_slv, MSM8939_SNOC_BIMC_0_SLV, 16, -1, 24, MSM8939_SLAVE_EBI_CH0); | |
| 196 | +DEFINE_QNODE(snoc_bimc_0_mas, MSM8939_SNOC_BIMC_0_MAS, 16, -1, -1, MSM8939_SNOC_BIMC_0_SLV); | |
| 197 | +DEFINE_QNODE(snoc_bimc_0_slv, MSM8939_SNOC_BIMC_0_SLV, 16, -1, -1, MSM8939_SLAVE_EBI_CH0); | |
| 198 | 198 | DEFINE_QNODE(snoc_bimc_1_mas, MSM8939_SNOC_BIMC_1_MAS, 16, 76, -1, MSM8939_SNOC_BIMC_1_SLV); |
| 199 | 199 | DEFINE_QNODE(snoc_bimc_1_slv, MSM8939_SNOC_BIMC_1_SLV, 16, -1, 104, MSM8939_SLAVE_EBI_CH0); |
| 200 | 200 | DEFINE_QNODE(snoc_bimc_2_mas, MSM8939_SNOC_BIMC_2_MAS, 16, -1, -1, MSM8939_SNOC_BIMC_2_SLV); |
| 201 | 201 | DEFINE_QNODE(snoc_bimc_2_slv, MSM8939_SNOC_BIMC_2_SLV, 16, -1, -1, MSM8939_SLAVE_EBI_CH0); |
| 202 | 202 | DEFINE_QNODE(snoc_int_0, MSM8939_SNOC_INT_0, 8, 99, 130, MSM8939_SLAVE_QDSS_STM, MSM8939_SLAVE_IMEM, MSM8939_SNOC_PNOC_MAS); |
| 203 | −DEFINE_QNODE(snoc_int_1, MSM8939_SNOC_INT_1, 8, 100, 131, MSM8939_SLAVE_APSS, MSM8939_SLAVE_CATS_128, MSM8939_SLAVE_OCMEM_64); | |
| 203 | +DEFINE_QNODE(snoc_int_1, MSM8939_SNOC_INT_1, 8, -1, -1, MSM8939_SLAVE_APSS, MSM8939_SLAVE_CATS_128, MSM8939_SLAVE_OCMEM_64); | |
| 204 | 204 | DEFINE_QNODE(snoc_int_bimc, MSM8939_SNOC_INT_BIMC, 8, 101, 132, MSM8939_SNOC_BIMC_1_MAS); |
| 205 | 205 | DEFINE_QNODE(snoc_pcnoc_mas, MSM8939_SNOC_PNOC_MAS, 8, -1, -1, MSM8939_SNOC_PNOC_SLV); |
| 206 | 206 | DEFINE_QNODE(snoc_pcnoc_slv, MSM8939_SNOC_PNOC_SLV, 8, -1, -1, MSM8939_PNOC_INT_0); |
| @@ -721,7 +721,7 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) · 720 unmodified lines | ||
| 721 | 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 | 726 | struct capi_ctr *ctr; |
| 727 | 727 | u16 ret; |
| @@ -787,7 +787,7 @@ u16 capi20_get_version(u32 contr, struct capi_version *verp) · 59 unmodified lines | ||
| 787 | 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 | 792 | struct capi_ctr *ctr; |
| 793 | 793 | u16 ret; |
| @@ -694,7 +694,7 @@ isac_release(struct isac_hw *isac) · 693 unmodified lines | ||
| 694 | 694 | { |
| 695 | 695 | if (isac->type & IPAC_TYPE_ISACX) |
| 696 | 696 | WriteISAC(isac, ISACX_MASK, 0xff); |
| 697 | − else | |
| 697 | + else if (isac->type != 0) | |
| 698 | 698 | WriteISAC(isac, ISAC_MASK, 0xff); |
| 699 | 699 | if (isac->dch.timer.function != NULL) { |
| 700 | 700 | del_timer(&isac->dch.timer); |
| @@ -529,7 +529,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ · 528 unmodified lines | ||
| 529 | 529 | * Grab our output buffer. |
| 530 | 530 | */ |
| 531 | 531 | nl = orig_nl = get_result_buffer(param, param_size, &len); |
| 532 | − if (len < needed) { | |
| 532 | + if (len < needed || len < sizeof(nl->dev)) { | |
| 533 | 533 | param->flags |= DM_BUFFER_FULL_FLAG; |
| 534 | 534 | goto out; |
| 535 | 535 | } |
| @@ -1594,6 +1594,13 @@ static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev, · 1593 unmodified lines | ||
| 1594 | 1594 | return blk_queue_zoned_model(q) != *zoned_model; |
| 1595 | 1595 | } |
| 1596 | 1596 | |
| 1597 | +/* | |
| 1598 | + * Check the device zoned model based on the target feature flag. If the target | |
| 1599 | + * has the DM_TARGET_ZONED_HM feature flag set, host-managed zoned devices are | |
| 1600 | + * also accepted but all devices must have the same zoned model. If the target | |
| 1601 | + * has the DM_TARGET_MIXED_ZONED_MODEL feature set, the devices can have any | |
| 1602 | + * zoned model with all zoned devices having the same zone size. | |
| 1603 | + */ | |
| 1597 | 1604 | static bool dm_table_supports_zoned_model(struct dm_table *t, |
| 1598 | 1605 | enum blk_zoned_model zoned_model) |
| 1599 | 1606 | { |
| @@ -1603,13 +1610,15 @@ static bool dm_table_supports_zoned_model(struct dm_table *t, · 3 unmodified lines | ||
| 1603 | 1610 | for (i = 0; i < dm_table_get_num_targets(t); i++) { |
| 1604 | 1611 | ti = dm_table_get_target(t, i); |
| 1605 | 1612 | |
| 1606 | − if (zoned_model == BLK_ZONED_HM && | |
| 1607 | − !dm_target_supports_zoned_hm(ti->type)) | |
| 1608 | − return false; | |
| 1609 | − | |
| 1610 | − if (!ti->type->iterate_devices || | |
| 1611 | − ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model)) | |
| 1612 | − return false; | |
| 1613 | + if (dm_target_supports_zoned_hm(ti->type)) { | |
| 1614 | + if (!ti->type->iterate_devices || | |
| 1615 | + ti->type->iterate_devices(ti, device_not_zoned_model, | |
| 1616 | + &zoned_model)) | |
| 1617 | + return false; | |
| 1618 | + } else if (!dm_target_supports_mixed_zoned_model(ti->type)) { | |
| 1619 | + if (zoned_model == BLK_ZONED_HM) | |
| 1620 | + return false; | |
| 1621 | + } | |
| 1613 | 1622 | } |
| 1614 | 1623 | |
| 1615 | 1624 | return true; |
| @@ -1621,9 +1630,17 @@ static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev * · 5 unmodified lines | ||
| 1621 | 1630 | struct request_queue *q = bdev_get_queue(dev->bdev); |
| 1622 | 1631 | unsigned int *zone_sectors = data; |
| 1623 | 1632 | |
| 1633 | + if (!blk_queue_is_zoned(q)) | |
| 1634 | + return 0; | |
| 1635 | + | |
| 1624 | 1636 | return blk_queue_zone_sectors(q) != *zone_sectors; |
| 1625 | 1637 | } |
| 1626 | 1638 | |
| 1639 | +/* | |
| 1640 | + * Check consistency of zoned model and zone sectors across all targets. For | |
| 1641 | + * zone sectors, if the destination device is a zoned block device, it shall | |
| 1642 | + * have the specified zone_sectors. | |
| 1643 | + */ | |
| 1627 | 1644 | static int validate_hardware_zoned_model(struct dm_table *table, |
| 1628 | 1645 | enum blk_zoned_model zoned_model, |
| 1629 | 1646 | unsigned int zone_sectors) |
| @@ -1642,7 +1659,7 @@ static int validate_hardware_zoned_model(struct dm_table *table, · 12 unmodified lines | ||
| 1642 | 1659 | return -EINVAL; |
| 1643 | 1660 | |
| 1644 | 1661 | if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) { |
| 1645 | − DMERR("%s: zone sectors is not consistent across all devices", | |
| 1662 | + DMERR("%s: zone sectors is not consistent across all zoned devices", | |
| 1646 | 1663 | dm_device_name(table->md)); |
| 1647 | 1664 | return -EINVAL; |
| 1648 | 1665 | } |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" |
| 35 | 35 | #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" |
| 36 | 36 | |
| 37 | −#define DM_VERITY_OPTS_MAX (2 + DM_VERITY_OPTS_FEC + \ | |
| 37 | +#define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \ | |
| 38 | 38 | DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) |
| 39 | 39 | |
| 40 | 40 | static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; |
| @@ -1143,7 +1143,7 @@ static int dmz_message(struct dm_target *ti, unsigned int argc, char **argv, · 1142 unmodified lines | ||
| 1143 | 1143 | static struct target_type dmz_type = { |
| 1144 | 1144 | .name = "zoned", |
| 1145 | 1145 | .version = {2, 0, 0}, |
| 1146 | − .features = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM, | |
| 1146 | + .features = DM_TARGET_SINGLETON | DM_TARGET_MIXED_ZONED_MODEL, | |
| 1147 | 1147 | .module = THIS_MODULE, |
| 1148 | 1148 | .ctr = dmz_ctr, |
| 1149 | 1149 | .dtr = dmz_dtr, |
| @@ -2036,7 +2036,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, · 2035 unmodified lines | ||
| 2036 | 2036 | if (size != dm_get_size(md)) |
| 2037 | 2037 | memset(&md->geometry, 0, sizeof(md->geometry)); |
| 2038 | 2038 | |
| 2039 | − set_capacity_and_notify(md->disk, size); | |
| 2039 | + if (!get_capacity(md->disk)) | |
| 2040 | + set_capacity(md->disk, size); | |
| 2041 | + else | |
| 2042 | + set_capacity_and_notify(md->disk, size); | |
| 2040 | 2043 | |
| 2041 | 2044 | dm_table_event_callback(t, event_callback, md); |
| 2042 | 2045 | |
| @@ -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 | 77 | [INTEL_QUARK_IORES_MEM] = { |
| 77 | 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 | 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 | 91 | [INTEL_QUARK_IORES_MEM] = { |
| 90 | 92 | .flags = IORESOURCE_MEM, |
| 91 | 93 | }, |
| @@ -2286,8 +2286,8 @@ int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp, · 2285 unmodified lines | ||
| 2286 | 2286 | if (buffer_id == 0) |
| 2287 | 2287 | return -EINVAL; |
| 2288 | 2288 | |
| 2289 | − if (!mei_cl_is_connected(cl)) | |
| 2290 | − return -ENODEV; | |
| 2289 | + if (mei_cl_is_connected(cl)) | |
| 2290 | + return -EPROTO; | |
| 2291 | 2291 | |
| 2292 | 2292 | if (cl->dma_mapped) |
| 2293 | 2293 | return -EPROTO; |
| @@ -2327,9 +2327,7 @@ int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp, · 33 unmodified lines | ||
| 2327 | 2327 | |
| 2328 | 2328 | mutex_unlock(&dev->device_lock); |
| 2329 | 2329 | wait_event_timeout(cl->wait, |
| 2330 | − cl->dma_mapped || | |
| 2331 | − cl->status || | |
| 2332 | − !mei_cl_is_connected(cl), | |
| 2330 | + cl->dma_mapped || cl->status, | |
| 2333 | 2331 | mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); |
| 2334 | 2332 | mutex_lock(&dev->device_lock); |
| 2335 | 2333 | |
| @@ -2376,8 +2374,9 @@ int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp) · 40 unmodified lines | ||
| 2376 | 2374 | return -EOPNOTSUPP; |
| 2377 | 2375 | } |
| 2378 | 2376 | |
| 2379 | − if (!mei_cl_is_connected(cl)) | |
| 2380 | − return -ENODEV; | |
| 2377 | + /* do not allow unmap for connected client */ | |
| 2378 | + if (mei_cl_is_connected(cl)) | |
| 2379 | + return -EPROTO; | |
| 2381 | 2380 | |
| 2382 | 2381 | if (!cl->dma_mapped) |
| 2383 | 2382 | return -EPROTO; |
| @@ -2405,9 +2404,7 @@ int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp) · 21 unmodified lines | ||
| 2405 | 2404 | |
| 2406 | 2405 | mutex_unlock(&dev->device_lock); |
| 2407 | 2406 | wait_event_timeout(cl->wait, |
| 2408 | − !cl->dma_mapped || | |
| 2409 | − cl->status || | |
| 2410 | − !mei_cl_is_connected(cl), | |
| 2407 | + !cl->dma_mapped || cl->status, | |
| 2411 | 2408 | mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); |
| 2412 | 2409 | mutex_lock(&dev->device_lock); |
| 2413 | 2410 | |
| @@ -127,6 +127,8 @@ static int com20020pci_probe(struct pci_dev *pdev, · 126 unmodified lines | ||
| 127 | 127 | int i, ioaddr, ret; |
| 128 | 128 | struct resource *r; |
| 129 | 129 | |
| 130 | + ret = 0; | |
| 131 | + | |
| 130 | 132 | if (pci_enable_device(pdev)) |
| 131 | 133 | return -EIO; |
| 132 | 134 | |
| @@ -139,6 +141,8 @@ static int com20020pci_probe(struct pci_dev *pdev, · 6 unmodified lines | ||
| 139 | 141 | priv->ci = ci; |
| 140 | 142 | mm = &ci->misc_map; |
| 141 | 143 | |
| 144 | + pci_set_drvdata(pdev, priv); | |
| 145 | + | |
| 142 | 146 | INIT_LIST_HEAD(&priv->list_dev); |
| 143 | 147 | |
| 144 | 148 | if (mm->size) { |
| @@ -161,7 +165,7 @@ static int com20020pci_probe(struct pci_dev *pdev, · 16 unmodified lines | ||
| 161 | 165 | dev = alloc_arcdev(device); |
| 162 | 166 | if (!dev) { |
| 163 | 167 | ret = -ENOMEM; |
| 164 | − goto out_port; | |
| 168 | + break; | |
| 165 | 169 | } |
| 166 | 170 | dev->dev_port = i; |
| 167 | 171 | |
| @@ -178,7 +182,7 @@ static int com20020pci_probe(struct pci_dev *pdev, · 10 unmodified lines | ||
| 178 | 182 | pr_err("IO region %xh-%xh already allocated\n", |
| 179 | 183 | ioaddr, ioaddr + cm->size - 1); |
| 180 | 184 | ret = -EBUSY; |
| 181 | − goto out_port; | |
| 185 | + goto err_free_arcdev; | |
| 182 | 186 | } |
| 183 | 187 | |
| 184 | 188 | /* Dummy access after Reset |
| @@ -216,18 +220,18 @@ static int com20020pci_probe(struct pci_dev *pdev, · 31 unmodified lines | ||
| 216 | 220 | if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { |
| 217 | 221 | pr_err("IO address %Xh is empty!\n", ioaddr); |
| 218 | 222 | ret = -EIO; |
| 219 | − goto out_port; | |
| 223 | + goto err_free_arcdev; | |
| 220 | 224 | } |
| 221 | 225 | if (com20020_check(dev)) { |
| 222 | 226 | ret = -EIO; |
| 223 | − goto out_port; | |
| 227 | + goto err_free_arcdev; | |
| 224 | 228 | } |
| 225 | 229 | |
| 226 | 230 | card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), |
| 227 | 231 | GFP_KERNEL); |
| 228 | 232 | if (!card) { |
| 229 | 233 | ret = -ENOMEM; |
| 230 | − goto out_port; | |
| 234 | + goto err_free_arcdev; | |
| 231 | 235 | } |
| 232 | 236 | |
| 233 | 237 | card->index = i; |
| @@ -253,29 +257,29 @@ static int com20020pci_probe(struct pci_dev *pdev, · 19 unmodified lines | ||
| 253 | 257 | |
| 254 | 258 | ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); |
| 255 | 259 | if (ret) |
| 256 | − goto out_port; | |
| 260 | + goto err_free_arcdev; | |
| 257 | 261 | |
| 258 | 262 | ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); |
| 259 | 263 | if (ret) |
| 260 | − goto out_port; | |
| 264 | + goto err_free_arcdev; | |
| 261 | 265 | |
| 262 | 266 | dev_set_drvdata(&dev->dev, card); |
| 263 | 267 | |
| 264 | 268 | ret = com20020_found(dev, IRQF_SHARED); |
| 265 | 269 | if (ret) |
| 266 | − goto out_port; | |
| 270 | + goto err_free_arcdev; | |
| 267 | 271 | |
| 268 | 272 | devm_arcnet_led_init(dev, dev->dev_id, i); |
| 269 | 273 | |
| 270 | 274 | list_add(&card->list, &priv->list_dev); |
| 271 | − } | |
| 275 | + continue; | |
| 272 | 276 | |
| 273 | − pci_set_drvdata(pdev, priv); | |
| 274 | − | |
| 275 | − return 0; | |
| 276 | − | |
| 277 | −out_port: | |
| 278 | − com20020pci_remove(pdev); | |
| 277 | +err_free_arcdev: | |
| 278 | + free_arcdev(dev); | |
| 279 | + break; | |
| 280 | + } | |
| 281 | + if (ret) | |
| 282 | + com20020pci_remove(pdev); | |
| 279 | 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 | 3979 | rcu_read_lock(); |
| 3980 | 3980 | slave = bond_first_slave_rcu(bond); |
| 3981 | − if (!slave) { | |
| 3982 | − ret = -EINVAL; | |
| 3981 | + if (!slave) | |
| 3983 | 3982 | goto out; |
| 3984 | − } | |
| 3985 | 3983 | slave_ops = slave->dev->netdev_ops; |
| 3986 | − if (!slave_ops->ndo_neigh_setup) { | |
| 3987 | − ret = -EINVAL; | |
| 3984 | + if (!slave_ops->ndo_neigh_setup) | |
| 3988 | 3985 | goto out; |
| 3989 | − } | |
| 3990 | 3986 | |
| 3991 | 3987 | /* TODO: find another way [1] to implement this. |
| 3992 | 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 | 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 | 215 | static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv) |
| 228 | 216 | { |
| 229 | 217 | if (priv->device) |
| @@ -1335,7 +1323,6 @@ static const struct net_device_ops c_can_netdev_ops = { · 1105 unmodified lines | ||
| 1335 | 1323 | |
| 1336 | 1324 | int register_c_can_dev(struct net_device *dev) |
| 1337 | 1325 | { |
| 1338 | − struct c_can_priv *priv = netdev_priv(dev); | |
| 1339 | 1326 | int err; |
| 1340 | 1327 | |
| 1341 | 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 | 1333 | pinctrl_pm_select_sleep_state(dev->dev.parent); |
| 1347 | 1334 | |
| 1348 | − c_can_pm_runtime_enable(priv); | |
| 1349 | − | |
| 1350 | 1335 | dev->flags |= IFF_ECHO; /* we support local echo */ |
| 1351 | 1336 | dev->netdev_ops = &c_can_netdev_ops; |
| 1352 | 1337 | |
| 1353 | 1338 | err = register_candev(dev); |
| 1354 | − if (err) | |
| 1355 | − c_can_pm_runtime_disable(priv); | |
| 1356 | − else | |
| 1339 | + if (!err) | |
| 1357 | 1340 | devm_can_led_init(dev); |
| 1358 | − | |
| 1359 | 1341 | return err; |
| 1360 | 1342 | } |
| 1361 | 1343 | EXPORT_SYMBOL_GPL(register_c_can_dev); |
| 1362 | 1344 | |
| 1363 | 1345 | void unregister_c_can_dev(struct net_device *dev) |
| 1364 | 1346 | { |
| 1365 | − struct c_can_priv *priv = netdev_priv(dev); | |
| 1366 | − | |
| 1367 | 1347 | unregister_candev(dev); |
| 1368 | − | |
| 1369 | − c_can_pm_runtime_disable(priv); | |
| 1370 | 1348 | } |
| 1371 | 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 | 240 | struct net_device *dev = pci_get_drvdata(pdev); |
| 241 | 241 | struct c_can_priv *priv = netdev_priv(dev); |
| 242 | + void __iomem *addr = priv->base; | |
| 242 | 243 | |
| 243 | 244 | unregister_c_can_dev(dev); |
| 244 | 245 | |
| 245 | 246 | free_c_can_dev(dev); |
| 246 | 247 | |
| 247 | − pci_iounmap(pdev, priv->base); | |
| 248 | + pci_iounmap(pdev, addr); | |
| 248 | 249 | pci_disable_msi(pdev); |
| 249 | 250 | pci_clear_master(pdev); |
| 250 | 251 | pci_release_regions(pdev); |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/list.h> |
| 30 | 30 | #include <linux/io.h> |
| 31 | 31 | #include <linux/platform_device.h> |
| 32 | +#include <linux/pm_runtime.h> | |
| 32 | 33 | #include <linux/clk.h> |
| 33 | 34 | #include <linux/of.h> |
| 34 | 35 | #include <linux/of_device.h> |
| @@ -386,6 +387,7 @@ static int c_can_plat_probe(struct platform_device *pdev) · 351 unmodified lines | ||
| 386 | 387 | platform_set_drvdata(pdev, dev); |
| 387 | 388 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 388 | 389 | |
| 390 | + pm_runtime_enable(priv->device); | |
| 389 | 391 | ret = register_c_can_dev(dev); |
| 390 | 392 | if (ret) { |
| 391 | 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 | 400 | return 0; |
| 399 | 401 | |
| 400 | 402 | exit_free_device: |
| 403 | + pm_runtime_disable(priv->device); | |
| 401 | 404 | free_c_can_dev(dev); |
| 402 | 405 | exit: |
| 403 | 406 | dev_err(&pdev->dev, "probe failed\n"); |
| @@ -408,9 +411,10 @@ exit: · 4 unmodified lines | ||
| 408 | 411 | static int c_can_plat_remove(struct platform_device *pdev) |
| 409 | 412 | { |
| 410 | 413 | struct net_device *dev = platform_get_drvdata(pdev); |
| 414 | + struct c_can_priv *priv = netdev_priv(dev); | |
| 411 | 415 | |
| 412 | 416 | unregister_c_can_dev(dev); |
| 413 | − | |
| 417 | + pm_runtime_disable(priv->device); | |
| 414 | 418 | free_c_can_dev(dev); |
| 415 | 419 | |
| 416 | 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 | 356 | struct rtnl_link_ops can_link_ops __read_mostly = { |
| 357 | 357 | .kind = "can", |
| 358 | + .netns_refund = true, | |
| 358 | 359 | .maxtype = IFLA_CAN_MAX, |
| 359 | 360 | .policy = can_policy, |
| 360 | 361 | .setup = can_setup, |
| @@ -697,9 +697,15 @@ static int flexcan_chip_disable(struct flexcan_priv *priv) · 696 unmodified lines | ||
| 697 | 697 | static int flexcan_chip_freeze(struct flexcan_priv *priv) |
| 698 | 698 | { |
| 699 | 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 | 702 | u32 reg; |
| 702 | 703 | |
| 704 | + if (bitrate) | |
| 705 | + timeout = 1000 * 1000 * 10 / bitrate; | |
| 706 | + else | |
| 707 | + timeout = FLEXCAN_TIMEOUT_US / 10; | |
| 708 | + | |
| 703 | 709 | reg = priv->read(®s->mcr); |
| 704 | 710 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; |
| 705 | 711 | priv->write(reg, ®s->mcr); |
| @@ -57,6 +57,7 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices"); · 56 unmodified lines | ||
| 57 | 57 | #define KVASER_PCIEFD_KCAN_STAT_REG 0x418 |
| 58 | 58 | #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c |
| 59 | 59 | #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420 |
| 60 | +#define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424 | |
| 60 | 61 | #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428 |
| 61 | 62 | #define KVASER_PCIEFD_KCAN_PWM_REG 0x430 |
| 62 | 63 | /* Loopback control register */ |
| @@ -949,6 +950,9 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) · 886 unmodified lines | ||
| 949 | 950 | timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, |
| 950 | 951 | 0); |
| 951 | 952 | |
| 953 | + /* Disable Bus load reporting */ | |
| 954 | + iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG); | |
| 955 | + | |
| 952 | 956 | tx_npackets = ioread32(can->reg_base + |
| 953 | 957 | KVASER_PCIEFD_KCAN_TX_NPACKETS_REG); |
| 954 | 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 | 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 | 504 | m_can_read_fifo(dev, rxfs); |
| 508 | 505 | |
| 509 | 506 | quota--; |
| @@ -876,7 +873,7 @@ static int m_can_rx_peripheral(struct net_device *dev) · 366 unmodified lines | ||
| 876 | 873 | { |
| 877 | 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 | 878 | m_can_enable_all_interrupts(cdev); |
| 882 | 879 | |
| @@ -73,6 +73,7 @@ config CAN_KVASER_USB · 72 unmodified lines | ||
| 73 | 73 | - Kvaser Memorator Pro 5xHS |
| 74 | 74 | - Kvaser USBcan Light 4xHS |
| 75 | 75 | - Kvaser USBcan Pro 2xHS v2 |
| 76 | + - Kvaser USBcan Pro 4xHS | |
| 76 | 77 | - Kvaser USBcan Pro 5xHS |
| 77 | 78 | - Kvaser U100 |
| 78 | 79 | - Kvaser U100P |
| @@ -86,8 +86,9 @@ · 85 unmodified lines | ||
| 86 | 86 | #define USB_U100_PRODUCT_ID 273 |
| 87 | 87 | #define USB_U100P_PRODUCT_ID 274 |
| 88 | 88 | #define USB_U100S_PRODUCT_ID 275 |
| 89 | +#define USB_USBCAN_PRO_4HS_PRODUCT_ID 276 | |
| 89 | 90 | #define USB_HYDRA_PRODUCT_ID_END \ |
| 90 | − USB_U100S_PRODUCT_ID | |
| 91 | + USB_USBCAN_PRO_4HS_PRODUCT_ID | |
| 91 | 92 | |
| 92 | 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 | 194 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) }, |
| 194 | 195 | { USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) }, |
| 195 | 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 | 200 | MODULE_DEVICE_TABLE(usb, kvaser_usb_table); |
| @@ -1105,13 +1105,6 @@ static int b53_setup(struct dsa_switch *ds) · 1104 unmodified lines | ||
| 1105 | 1105 | b53_disable_port(ds, port); |
| 1106 | 1106 | } |
| 1107 | 1107 | |
| 1108 | − /* Let DSA handle the case were multiple bridges span the same switch | |
| 1109 | − * device and different VLAN awareness settings are requested, which | |
| 1110 | − * would be breaking filtering semantics for any of the other bridge | |
| 1111 | − * devices. (not hardware supported) | |
| 1112 | − */ | |
| 1113 | − ds->vlan_filtering_is_global = true; | |
| 1114 | − | |
| 1115 | 1108 | return b53_setup_devlink_resources(ds); |
| 1116 | 1109 | } |
| 1117 | 1110 | |
| @@ -2664,6 +2657,13 @@ struct b53_device *b53_switch_alloc(struct device *base, · 1546 unmodified lines | ||
| 2664 | 2657 | ds->ops = &b53_switch_ops; |
| 2665 | 2658 | ds->untag_bridge_pvid = true; |
| 2666 | 2659 | dev->vlan_enabled = true; |
| 2660 | + /* Let DSA handle the case were multiple bridges span the same switch | |
| 2661 | + * device and different VLAN awareness settings are requested, which | |
| 2662 | + * would be breaking filtering semantics for any of the other bridge | |
| 2663 | + * devices. (not hardware supported) | |
| 2664 | + */ | |
| 2665 | + ds->vlan_filtering_is_global = true; | |
| 2666 | + | |
| 2667 | 2667 | mutex_init(&dev->reg_mutex); |
| 2668 | 2668 | mutex_init(&dev->stats_mutex); |
| 2669 | 2669 | |
| @@ -114,7 +114,10 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) · 113 unmodified lines | ||
| 114 | 114 | /* Force link status for IMP port */ |
| 115 | 115 | reg = core_readl(priv, offset); |
| 116 | 116 | reg |= (MII_SW_OR | LINK_STS); |
| 117 | − reg &= ~GMII_SPEED_UP_2G; | |
| 117 | + if (priv->type == BCM4908_DEVICE_ID) | |
| 118 | + reg |= GMII_SPEED_UP_2G; | |
| 119 | + else | |
| 120 | + reg &= ~GMII_SPEED_UP_2G; | |
| 118 | 121 | core_writel(priv, reg, offset); |
| 119 | 122 | |
| 120 | 123 | /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ |
| @@ -585,8 +588,10 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port) · 464 unmodified lines | ||
| 585 | 588 | * in bits 15:8 and the patch level in bits 7:0 which is exactly what |
| 586 | 589 | * the REG_PHY_REVISION register layout is. |
| 587 | 590 | */ |
| 588 | − | |
| 589 | − return priv->hw_params.gphy_rev; | |
| 591 | + if (priv->int_phy_mask & BIT(port)) | |
| 592 | + return priv->hw_params.gphy_rev; | |
| 593 | + else | |
| 594 | + return 0; | |
| 590 | 595 | } |
| 591 | 596 | |
| 592 | 597 | 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 | 436 | TD_DM_DRVP(8) | TD_DM_DRVN(8)); |
| 437 | 437 | |
| 438 | 438 | /* Setup core clock for MT7530 */ |
| 439 | − if (!trgint) { | |
| 440 | − /* Disable MT7530 core clock */ | |
| 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)); | |
| 439 | + /* Disable MT7530 core clock */ | |
| 440 | + core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); | |
| 457 | 441 | |
| 458 | − /* Enable PLL */ | |
| 459 | − core_write(priv, CORE_GSWPLL_GRP1, | |
| 460 | − RG_GSWPLL_EN_PRE | | |
| 461 | − RG_GSWPLL_POSDIV_200M(2) | | |
| 462 | − RG_GSWPLL_FBKDIV_200M(32)); | |
| 463 | − | |
| 464 | − /* Enable MT7530 core clock */ | |
| 465 | − core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); | |
| 466 | − } | |
| 442 | + /* Disable PLL, since phy_device has not yet been created | |
| 443 | + * provided for phy_[read,write]_mmd_indirect is called, we | |
| 444 | + * provide our own core_write_mmd_indirect to complete this | |
| 445 | + * function. | |
| 446 | + */ | |
| 447 | + core_write_mmd_indirect(priv, | |
| 448 | + CORE_GSWPLL_GRP1, | |
| 449 | + MDIO_MMD_VEND2, | |
| 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 | 466 | /* Setup the MT7530 TRGMII Tx Clock */ |
| 469 | 467 | core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); |
| @@ -54,7 +54,7 @@ config B44_PCI · 53 unmodified lines | ||
| 54 | 54 | config BCM4908_ENET |
| 55 | 55 | tristate "Broadcom BCM4908 internal mac support" |
| 56 | 56 | depends on ARCH_BCM4908 || COMPILE_TEST |
| 57 | − default y | |
| 57 | + default y if ARCH_BCM4908 | |
| 58 | 58 | help |
| 59 | 59 | This driver supports Ethernet controller integrated into Broadcom |
| 60 | 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 | 722 | kvfree(tx_info); |
| 723 | 723 | return 0; |
| 724 | 724 | } |
| 725 | − tx_info->open_state = false; | |
| 725 | + tx_info->open_state = CH_KTLS_OPEN_SUCCESS; | |
| 726 | 726 | spin_unlock(&tx_info->lock); |
| 727 | 727 | |
| 728 | 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 | 1338 | if (unlikely(priv->need_mac_restart)) { |
| 1339 | 1339 | ftgmac100_start_hw(priv); |
| 1340 | + priv->need_mac_restart = false; | |
| 1340 | 1341 | |
| 1341 | 1342 | /* Re-enable "bad" interrupts */ |
| 1342 | 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 | 899 | } else { |
| 900 | 900 | data &= ~IGP02E1000_PM_D0_LPLU; |
| 901 | 901 | ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); |
| 902 | + if (ret_val) | |
| 903 | + return ret_val; | |
| 902 | 904 | /* LPLU and SmartSpeed are mutually exclusive. LPLU is used |
| 903 | 905 | * during Dx states where the power conservation is most |
| 904 | 906 | * important. During driver activity we should enable |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | /* Copyright(c) 1999 - 2018 Intel Corporation. */ |
| 3 | 3 | |
| 4 | −#ifndef _E1000_HW_H_ | |
| 5 | −#define _E1000_HW_H_ | |
| 4 | +#ifndef _E1000E_HW_H_ | |
| 5 | +#define _E1000E_HW_H_ | |
| 6 | 6 | |
| 7 | 7 | #include "regs.h" |
| 8 | 8 | #include "defines.h" |
| @@ -714,4 +714,4 @@ struct e1000_hw { · 705 unmodified lines | ||
| 714 | 714 | #include "80003es2lan.h" |
| 715 | 715 | #include "ich8lan.h" |
| 716 | 716 | |
| 717 | −#endif | |
| 717 | +#endif /* _E1000E_HW_H_ */ | |
| @@ -5974,15 +5974,19 @@ static void e1000_reset_task(struct work_struct *work) · 5973 unmodified lines | ||
| 5974 | 5974 | struct e1000_adapter *adapter; |
| 5975 | 5975 | adapter = container_of(work, struct e1000_adapter, reset_task); |
| 5976 | 5976 | |
| 5977 | + rtnl_lock(); | |
| 5977 | 5978 | /* don't run the task if already down */ |
| 5978 | − if (test_bit(__E1000_DOWN, &adapter->state)) | |
| 5979 | + if (test_bit(__E1000_DOWN, &adapter->state)) { | |
| 5980 | + rtnl_unlock(); | |
| 5979 | 5981 | return; |
| 5982 | + } | |
| 5980 | 5983 | |
| 5981 | 5984 | if (!(adapter->flags & FLAG_RESTART_NOW)) { |
| 5982 | 5985 | e1000e_dump(adapter); |
| 5983 | 5986 | e_err("Reset adapter unexpectedly\n"); |
| 5984 | 5987 | } |
| 5985 | 5988 | e1000e_reinit_locked(adapter); |
| 5989 | + rtnl_unlock(); | |
| 5986 | 5990 | } |
| 5987 | 5991 | |
| 5988 | 5992 | /** |
| @@ -3258,6 +3258,17 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring) · 3257 unmodified lines | ||
| 3258 | 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 | 3273 | * i40e_configure_rx_ring - Configure a receive ring context |
| 3263 | 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 | 3380 | else |
| 3370 | 3381 | set_ring_build_skb_enabled(ring); |
| 3371 | 3382 | |
| 3383 | + ring->rx_offset = i40e_rx_offset(ring); | |
| 3384 | + | |
| 3372 | 3385 | /* cache tail for quicker writes, and clear the reg before use */ |
| 3373 | 3386 | ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q); |
| 3374 | 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 | 1573 | * i40e_setup_rx_descriptors - Allocate Rx descriptors |
| 1585 | 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 | 1597 | rx_ring->next_to_alloc = 0; |
| 1609 | 1598 | rx_ring->next_to_clean = 0; |
| 1610 | 1599 | rx_ring->next_to_use = 0; |
| 1611 | − rx_ring->rx_offset = i40e_rx_offset(rx_ring); | |
| 1612 | 1600 | |
| 1613 | 1601 | /* XDP RX-queue info only needed for RX rings exposed to XDP */ |
| 1614 | 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 | 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 | 294 | * ice_setup_rx_ctx - Configure a receive ring context |
| 279 | 295 | * @ring: The Rx ring to configure |
| @@ -413,11 +429,15 @@ int ice_setup_rx_ctx(struct ice_ring *ring) · 133 unmodified lines | ||
| 413 | 429 | else |
| 414 | 430 | ice_set_ring_build_skb_ena(ring); |
| 415 | 431 | |
| 432 | + ring->rx_offset = ice_rx_offset(ring); | |
| 433 | + | |
| 416 | 434 | /* init queue specific tail register */ |
| 417 | 435 | ring->tail = hw->hw_addr + QRX_TAIL(pf_q); |
| 418 | 436 | writel(0, ring->tail); |
| 419 | 437 | |
| 420 | 438 | if (ring->xsk_pool) { |
| 439 | + bool ok; | |
| 440 | + | |
| 421 | 441 | if (!xsk_buff_can_alloc(ring->xsk_pool, num_bufs)) { |
| 422 | 442 | dev_warn(dev, "XSK buffer pool does not provide enough addresses to fill %d buffers on Rx ring %d\n", |
| 423 | 443 | num_bufs, ring->q_index); |
| @@ -426,8 +446,8 @@ int ice_setup_rx_ctx(struct ice_ring *ring) · 2 unmodified lines | ||
| 426 | 446 | return 0; |
| 427 | 447 | } |
| 428 | 448 | |
| 429 | − err = ice_alloc_rx_bufs_zc(ring, num_bufs); | |
| 430 | − if (err) | |
| 449 | + ok = ice_alloc_rx_bufs_zc(ring, num_bufs); | |
| 450 | + if (!ok) | |
| 431 | 451 | dev_info(dev, "Failed to allocate some buffers on XSK buffer pool enabled Rx ring %d (pf_q %d)\n", |
| 432 | 452 | ring->q_index, pf_q); |
| 433 | 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 | 447 | * ice_setup_rx_ring - Allocate the Rx descriptors |
| 464 | 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 | 478 | rx_ring->next_to_use = 0; |
| 495 | 479 | rx_ring->next_to_clean = 0; |
| 496 | − rx_ring->rx_offset = ice_rx_offset(rx_ring); | |
| 497 | 480 | |
| 498 | 481 | if (ice_is_xdp_ena_vsi(rx_ring->vsi)) |
| 499 | 482 | WRITE_ONCE(rx_ring->xdp_prog, rx_ring->vsi->xdp_prog); |
| @@ -358,18 +358,18 @@ xsk_pool_if_up: · 357 unmodified lines | ||
| 358 | 358 | * This function allocates a number of Rx buffers from the fill ring |
| 359 | 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 | 363 | bool ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, u16 count) |
| 364 | 364 | { |
| 365 | 365 | union ice_32b_rx_flex_desc *rx_desc; |
| 366 | 366 | u16 ntu = rx_ring->next_to_use; |
| 367 | 367 | struct ice_rx_buf *rx_buf; |
| 368 | − bool ret = false; | |
| 368 | + bool ok = true; | |
| 369 | 369 | dma_addr_t dma; |
| 370 | 370 | |
| 371 | 371 | if (!count) |
| 372 | − return false; | |
| 372 | + return true; | |
| 373 | 373 | |
| 374 | 374 | rx_desc = ICE_RX_DESC(rx_ring, ntu); |
| 375 | 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 | 377 | do { |
| 378 | 378 | rx_buf->xdp = xsk_buff_alloc(rx_ring->xsk_pool); |
| 379 | 379 | if (!rx_buf->xdp) { |
| 380 | − ret = true; | |
| 380 | + ok = false; | |
| 381 | 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 | 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 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | /* Copyright(c) 2007 - 2018 Intel Corporation. */ |
| 3 | 3 | |
| 4 | −#ifndef _E1000_HW_H_ | |
| 5 | −#define _E1000_HW_H_ | |
| 4 | +#ifndef _E1000_IGB_HW_H_ | |
| 5 | +#define _E1000_IGB_HW_H_ | |
| 6 | 6 | |
| 7 | 7 | #include <linux/types.h> |
| 8 | 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 | 552 | void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); |
| 553 | 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 | 748 | void igb_ptp_rx_hang(struct igb_adapter *adapter); |
| 749 | 749 | void igb_ptp_tx_hang(struct igb_adapter *adapter); |
| 750 | 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, | |
| 752 | − struct sk_buff *skb); | |
| 751 | +int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, | |
| 752 | + struct sk_buff *skb); | |
| 753 | 753 | int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| 754 | 754 | int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| 755 | 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 | 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 | 8220 | unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; |
| 8220 | 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 | 8227 | #if (PAGE_SIZE < 8192) |
| 8227 | 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 | 8230 | return false; |
| 8230 | 8231 | #else |
| 8231 | 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 | 8302 | return NULL; |
| 8302 | 8303 | |
| 8303 | 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 | − xdp->data += IGB_TS_HDR_LEN; | |
| 8306 | − size -= IGB_TS_HDR_LEN; | |
| 8305 | + if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb)) { | |
| 8306 | + xdp->data += IGB_TS_HDR_LEN; | |
| 8307 | + size -= IGB_TS_HDR_LEN; | |
| 8308 | + } | |
| 8307 | 8309 | } |
| 8308 | 8310 | |
| 8309 | 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 | 8367 | /* pull timestamp out of packet data */ |
| 8366 | 8368 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { |
| 8367 | − igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb); | |
| 8368 | − __skb_pull(skb, IGB_TS_HDR_LEN); | |
| 8369 | + if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb)) | |
| 8370 | + __skb_pull(skb, IGB_TS_HDR_LEN); | |
| 8369 | 8371 | } |
| 8370 | 8372 | |
| 8371 | 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 | 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 | 8621 | struct igb_rx_buffer *rx_buffer; |
| 8620 | 8622 | |
| 8621 | 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 | 8630 | prefetchw(rx_buffer->page); |
| 8623 | 8631 | |
| 8624 | 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 | 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 | 8648 | /* hand second half of page back to the ring */ |
| 8641 | 8649 | igb_reuse_rx_page(rx_ring, rx_buffer); |
| 8642 | 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 | 8672 | unsigned int xdp_xmit = 0; |
| 8665 | 8673 | struct xdp_buff xdp; |
| 8666 | 8674 | u32 frame_sz = 0; |
| 8675 | + int rx_buf_pgcnt; | |
| 8667 | 8676 | |
| 8668 | 8677 | /* Frame size depend on rx_ring setup when PAGE_SIZE=4K */ |
| 8669 | 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 | 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 | 8707 | /* retrieve a buffer from the ring */ |
| 8699 | 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 | 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 | 8749 | cleaned_count++; |
| 8741 | 8750 | |
| 8742 | 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 | 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 | 863 | * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp |
| 861 | 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 | 868 | * This function is meant to retrieve a timestamp from the first buffer of an |
| 866 | 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, | |
| 870 | − struct sk_buff *skb) | |
| 874 | +int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, | |
| 875 | + struct sk_buff *skb) | |
| 871 | 876 | { |
| 872 | − __le64 *regval = (__le64 *)va; | |
| 873 | 877 | struct igb_adapter *adapter = q_vector->adapter; |
| 878 | + __le64 *regval = (__le64 *)va; | |
| 874 | 879 | int adjust = 0; |
| 875 | 880 | |
| 881 | + if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) | |
| 882 | + return IGB_RET_PTP_DISABLED; | |
| 883 | + | |
| 876 | 884 | /* The timestamp is recorded in little endian format. |
| 877 | 885 | * DWORD: 0 1 2 3 |
| 878 | 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 | 893 | igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), |
| 881 | 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 | 910 | skb_hwtstamps(skb)->hwtstamp = |
| 898 | 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 | 921 | * This function is meant to retrieve a timestamp from the internal registers |
| 907 | 922 | * of the adapter and store it in the skb. |
| 908 | 923 | **/ |
| 909 | −void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, | |
| 910 | − struct sk_buff *skb) | |
| 924 | +void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb) | |
| 911 | 925 | { |
| 912 | 926 | struct igb_adapter *adapter = q_vector->adapter; |
| 913 | 927 | struct e1000_hw *hw = &adapter->hw; |
| 914 | − u64 regval; | |
| 915 | 928 | int adjust = 0; |
| 929 | + u64 regval; | |
| 930 | + | |
| 931 | + if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) | |
| 932 | + return; | |
| 916 | 933 | |
| 917 | 934 | /* If this bit is set, then the RX registers contain the time stamp. No |
| 918 | 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 | 547 | void igc_ptp_reset(struct igc_adapter *adapter); |
| 548 | 548 | void igc_ptp_suspend(struct igc_adapter *adapter); |
| 549 | 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 | 551 | struct sk_buff *skb); |
| 552 | 552 | int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); |
| 553 | 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 | 1711 | Autoneg); |
| 1712 | 1712 | } |
| 1713 | 1713 | |
| 1714 | + /* Set pause flow control settings */ | |
| 1715 | + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); | |
| 1716 | + | |
| 1714 | 1717 | switch (hw->fc.requested_mode) { |
| 1715 | 1718 | case igc_fc_full: |
| 1716 | 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 | 1728 | Asym_Pause); |
| 1726 | 1729 | break; |
| 1727 | 1730 | default: |
| 1728 | − ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); | |
| 1729 | − ethtool_link_ksettings_add_link_mode(cmd, advertising, | |
| 1730 | − Asym_Pause); | |
| 1731 | + break; | |
| 1731 | 1732 | } |
| 1732 | 1733 | |
| 1733 | 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 | 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 | 3842 | igc_rings_dump(adapter); |
| 3835 | 3843 | igc_regs_dump(adapter); |
| 3836 | 3844 | netdev_err(adapter->netdev, "Reset adapter\n"); |
| 3837 | 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 | 156 | * @q_vector: Pointer to interrupt specific structure |
| 157 | 157 | * @va: Pointer to address containing Rx buffer |
| 158 | 158 | * @skb: Buffer containing timestamp and packet |
| 159 | 159 | * |
| 160 | − * This function is meant to retrieve the first timestamp from the | |
| 161 | − * first buffer of an incoming frame. The value is stored in little | |
| 162 | − * endian format starting on byte 0. There's a second timestamp | |
| 163 | − * starting on byte 8. | |
| 164 | − **/ | |
| 165 | −void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va, | |
| 160 | + * This function retrieves the timestamp saved in the beginning of packet | |
| 161 | + * buffer. While two timestamps are available, one in timer0 reference and the | |
| 162 | + * other in timer1 reference, this function considers only the timestamp in | |
| 163 | + * timer0 reference. | |
| 164 | + */ | |
| 165 | +void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, __le32 *va, | |
| 166 | 166 | struct sk_buff *skb) |
| 167 | 167 | { |
| 168 | 168 | struct igc_adapter *adapter = q_vector->adapter; |
| 169 | − __le64 *regval = (__le64 *)va; | |
| 170 | − int adjust = 0; | |
| 171 | − | |
| 172 | − /* The timestamp is recorded in little endian format. | |
| 173 | − * DWORD: | 0 | 1 | 2 | 3 | |
| 174 | − * Field: | Timer0 Low | Timer0 High | Timer1 Low | Timer1 High | |
| 169 | + u64 regval; | |
| 170 | + int adjust; | |
| 171 | + | |
| 172 | + /* Timestamps are saved in little endian at the beginning of the packet | |
| 173 | + * buffer following the layout: | |
| 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), | |
| 177 | − le64_to_cpu(regval[0])); | |
| 178 | − | |
| 179 | − /* adjust timestamp for the RX latency based on link speed */ | |
| 180 | − if (adapter->hw.mac.type == igc_i225) { | |
| 181 | − switch (adapter->link_speed) { | |
| 182 | − case SPEED_10: | |
| 183 | − adjust = IGC_I225_RX_LATENCY_10; | |
| 184 | − break; | |
| 185 | − case SPEED_100: | |
| 186 | − adjust = IGC_I225_RX_LATENCY_100; | |
| 187 | − break; | |
| 188 | − case SPEED_1000: | |
| 189 | − adjust = IGC_I225_RX_LATENCY_1000; | |
| 190 | − break; | |
| 191 | − case SPEED_2500: | |
| 192 | − adjust = IGC_I225_RX_LATENCY_2500; | |
| 193 | − break; | |
| 194 | − } | |
| 181 | + regval = le32_to_cpu(va[2]); | |
| 182 | + regval |= (u64)le32_to_cpu(va[3]) << 32; | |
| 183 | + igc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); | |
| 184 | + | |
| 185 | + /* Adjust timestamp for the RX latency based on link speed */ | |
| 186 | + switch (adapter->link_speed) { | |
| 187 | + case SPEED_10: | |
| 188 | + adjust = IGC_I225_RX_LATENCY_10; | |
| 189 | + break; | |
| 190 | + case SPEED_100: | |
| 191 | + adjust = IGC_I225_RX_LATENCY_100; | |
| 192 | + break; | |
| 193 | + case SPEED_1000: | |
| 194 | + adjust = IGC_I225_RX_LATENCY_1000; | |
| 195 | + break; | |
| 196 | + case SPEED_2500: | |
| 197 | + adjust = IGC_I225_RX_LATENCY_2500; | |
| 198 | + break; | |
| 199 | + default: | |
| 200 | + adjust = 0; | |
| 201 | + netdev_warn_once(adapter->netdev, "Imprecise timestamp\n"); | |
| 202 | + break; | |
| 195 | 203 | } |
| 196 | 204 | skb_hwtstamps(skb)->hwtstamp = |
| 197 | 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 | 4118 | #endif |
| 4119 | 4119 | } |
| 4120 | 4120 | |
| 4121 | + ring->rx_offset = ixgbe_rx_offset(ring); | |
| 4122 | + | |
| 4121 | 4123 | if (ring->xsk_pool && hw->mac.type != ixgbe_mac_82599EB) { |
| 4122 | 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 | 6581 | rx_ring->next_to_clean = 0; |
| 6580 | 6582 | rx_ring->next_to_use = 0; |
| 6581 | − rx_ring->rx_offset = ixgbe_rx_offset(rx_ring); | |
| 6582 | 6583 | |
| 6583 | 6584 | /* XDP RX-queue info */ |
| 6584 | 6585 | if (xdp_rxq_info_reg(&rx_ring->xdp_rxq, adapter->netdev, |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | config NET_VENDOR_MARVELL |
| 7 | 7 | bool "Marvell devices" |
| 8 | 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 | 10 | help |
| 11 | 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 | 20 | config MV643XX_ETH |
| 21 | 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 | 23 | depends on INET |
| 24 | 24 | select PHYLIB |
| 25 | 25 | select MVMDIO |
| @@ -2684,7 +2684,7 @@ static const struct of_device_id mv643xx_eth_shared_ids[] = { · 2683 unmodified lines | ||
| 2684 | 2684 | MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids); |
| 2685 | 2685 | #endif |
| 2686 | 2686 | |
| 2687 | −#if defined(CONFIG_OF_IRQ) && !defined(CONFIG_MV64X60) | |
| 2687 | +#ifdef CONFIG_OF_IRQ | |
| 2688 | 2688 | #define mv643xx_eth_property(_np, _name, _v) \ |
| 2689 | 2689 | do { \ |
| 2690 | 2690 | u32 tmp; \ |
| @@ -13499,8 +13499,6 @@ static struct npc_mcam_kex npc_mkex_default = { · 13498 unmodified lines | ||
| 13499 | 13499 | [NPC_LT_LC_IP] = { |
| 13500 | 13500 | /* SIP+DIP: 8 bytes, KW2[63:0] */ |
| 13501 | 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 | 13503 | /* Layer C: IPv6 */ |
| 13506 | 13504 | [NPC_LT_LC_IP6] = { |
| @@ -2462,8 +2462,10 @@ static void rvu_unregister_interrupts(struct rvu *rvu) · 2461 unmodified lines | ||
| 2462 | 2462 | INTR_MASK(rvu->hw->total_pfs) & ~1ULL); |
| 2463 | 2463 | |
| 2464 | 2464 | for (irq = 0; irq < rvu->num_vec; irq++) { |
| 2465 | − if (rvu->irq_allocated[irq]) | |
| 2465 | + if (rvu->irq_allocated[irq]) { | |
| 2466 | 2466 | free_irq(pci_irq_vector(rvu->pdev, irq), rvu); |
| 2467 | + rvu->irq_allocated[irq] = false; | |
| 2468 | + } | |
| 2467 | 2469 | } |
| 2468 | 2470 | |
| 2469 | 2471 | pci_free_irq_vectors(rvu->pdev); |
| @@ -2975,8 +2977,8 @@ static void rvu_remove(struct pci_dev *pdev) · 505 unmodified lines | ||
| 2975 | 2977 | struct rvu *rvu = pci_get_drvdata(pdev); |
| 2976 | 2978 | |
| 2977 | 2979 | rvu_dbg_exit(rvu); |
| 2978 | − rvu_unregister_interrupts(rvu); | |
| 2979 | 2980 | rvu_unregister_dl(rvu); |
| 2981 | + rvu_unregister_interrupts(rvu); | |
| 2980 | 2982 | rvu_flr_wq_destroy(rvu); |
| 2981 | 2983 | rvu_cgx_exit(rvu); |
| 2982 | 2984 | rvu_fwdata_exit(rvu); |
| @@ -678,6 +678,7 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, · 677 unmodified lines | ||
| 678 | 678 | u8 *intf, u8 *ena); |
| 679 | 679 | bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature); |
| 680 | 680 | u32 rvu_cgx_get_fifolen(struct rvu *rvu); |
| 681 | +void *rvu_first_cgx_pdata(struct rvu *rvu); | |
| 681 | 682 | |
| 682 | 683 | /* CPT APIs */ |
| 683 | 684 | int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot); |
| @@ -89,6 +89,21 @@ void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu) · 88 unmodified lines | ||
| 89 | 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 | 107 | /* Based on P2X connectivity find mapped NIX block for a PF */ |
| 93 | 108 | static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf, |
| 94 | 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 | 726 | u32 rvu_cgx_get_fifolen(struct rvu *rvu) |
| 712 | 727 | { |
| 713 | 728 | struct mac_ops *mac_ops; |
| 714 | − int rvu_def_cgx_id = 0; | |
| 715 | 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 | 732 | fifo_len = mac_ops ? mac_ops->fifo_len : 0; |
| 719 | 733 | |
| 720 | 734 | return fifo_len; |
| @@ -234,12 +234,14 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 233 unmodified lines | ||
| 234 | 234 | char __user *buffer, |
| 235 | 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 | 238 | struct rvu *rvu = filp->private_data; |
| 239 | 239 | int lf, pf, vf, pcifunc; |
| 240 | 240 | struct rvu_block block; |
| 241 | 241 | int bytes_not_copied; |
| 242 | + int lf_str_size = 12; | |
| 242 | 243 | int buf_size = 2048; |
| 244 | + char *lfs; | |
| 243 | 245 | char *buf; |
| 244 | 246 | |
| 245 | 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 | 251 | buf = kzalloc(buf_size, GFP_KERNEL); |
| 250 | 252 | if (!buf) |
| 251 | 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 | 262 | for (index = 0; index < BLK_COUNT; index++) |
| 254 | − if (strlen(rvu->hw->block[index].name)) | |
| 255 | − off += scnprintf(&buf[off], buf_size - 1 - off, | |
| 256 | − "%*s\t", (index - 1) * 2, | |
| 257 | − rvu->hw->block[index].name); | |
| 263 | + if (strlen(rvu->hw->block[index].name)) { | |
| 264 | + off += scnprintf(&buf[off], buf_size - 1 - off, | |
| 265 | + "%-*s", lf_str_size, | |
| 266 | + rvu->hw->block[index].name); | |
| 267 | + } | |
| 258 | 268 | off += scnprintf(&buf[off], buf_size - 1 - off, "\n"); |
| 259 | 269 | for (pf = 0; pf < rvu->hw->total_pfs; pf++) { |
| 260 | 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 | 273 | continue; |
| 264 | 274 | |
| 265 | 275 | if (vf) { |
| 276 | + sprintf(lfs, "PF%d:VF%d", pf, vf - 1); | |
| 266 | 277 | go_back = scnprintf(&buf[off], |
| 267 | 278 | buf_size - 1 - off, |
| 268 | − "PF%d:VF%d\t\t", pf, | |
| 269 | − vf - 1); | |
| 279 | + "%-*s", lf_str_size, lfs); | |
| 270 | 280 | } else { |
| 281 | + sprintf(lfs, "PF%d", pf); | |
| 271 | 282 | go_back = scnprintf(&buf[off], |
| 272 | 283 | buf_size - 1 - off, |
| 273 | − "PF%d\t\t", pf); | |
| 284 | + "%-*s", lf_str_size, lfs); | |
| 274 | 285 | } |
| 275 | 286 | |
| 276 | 287 | off += go_back; |
| @@ -278,20 +289,22 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, · 1 unmodified line | ||
| 278 | 289 | block = rvu->hw->block[index]; |
| 279 | 290 | if (!strlen(block.name)) |
| 280 | 291 | continue; |
| 281 | − off_prev = off; | |
| 292 | + len = 0; | |
| 293 | + lfs[len] = '\0'; | |
| 282 | 294 | for (lf = 0; lf < block.lf.max; lf++) { |
| 283 | 295 | if (block.fn_map[lf] != pcifunc) |
| 284 | 296 | continue; |
| 285 | 297 | flag = 1; |
| 286 | − off += scnprintf(&buf[off], buf_size - 1 | |
| 287 | − - off, "%3d,", lf); | |
| 298 | + len += sprintf(&lfs[len], "%d,", lf); | |
| 288 | 299 | } |
| 289 | − if (flag && off_prev != off) | |
| 290 | − off--; | |
| 291 | − else | |
| 292 | − go_back++; | |
| 300 | + | |
| 301 | + if (flag) | |
| 302 | + len--; | |
| 303 | + lfs[len] = '\0'; | |
| 293 | 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 | 309 | if (!flag) |
| 297 | 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 | 318 | bytes_not_copied = copy_to_user(buffer, buf, off); |
| 319 | + kfree(lfs); | |
| 306 | 320 | kfree(buf); |
| 307 | 321 | |
| 308 | 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 | 333 | struct rvu *rvu = filp->private; |
| 320 | 334 | struct pci_dev *pdev = NULL; |
| 321 | 335 | struct mac_ops *mac_ops; |
| 322 | − int rvu_def_cgx_id = 0; | |
| 323 | 336 | char cgx[10], lmac[10]; |
| 324 | 337 | struct rvu_pfvf *pfvf; |
| 325 | 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 | 340 | u16 pcifunc; |
| 328 | 341 | |
| 329 | 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 | 347 | seq_printf(filp, "PCI dev\t\tRVU PF Func\tNIX block\t%s\tLMAC\n", |
| 332 | 348 | mac_ops->name); |
| 333 | 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 | 1835 | struct mac_ops *mac_ops; |
| 1820 | 1836 | unsigned long lmac_bmap; |
| 1821 | − int rvu_def_cgx_id = 0; | |
| 1822 | 1837 | int i, lmac_id; |
| 1823 | 1838 | char dname[20]; |
| 1824 | 1839 | void *cgx; |
| @@ -1826,7 +1841,7 @@ static void rvu_dbg_cgx_init(struct rvu *rvu) · 1 unmodified line | ||
| 1826 | 1841 | if (!cgx_get_cgxcnt_max()) |
| 1827 | 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 | 1845 | if (!mac_ops) |
| 1831 | 1846 | return; |
| 1832 | 1847 | |
| @@ -2629,7 +2629,7 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg) · 2628 unmodified lines | ||
| 2629 | 2629 | struct nix_rx_flowkey_alg *field; |
| 2630 | 2630 | struct nix_rx_flowkey_alg tmp; |
| 2631 | 2631 | u32 key_type, valid_key; |
| 2632 | − int l4_key_offset; | |
| 2632 | + int l4_key_offset = 0; | |
| 2633 | 2633 | |
| 2634 | 2634 | if (!alg) |
| 2635 | 2635 | return -EINVAL; |
| @@ -2490,10 +2490,10 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu, · 2489 unmodified lines | ||
| 2490 | 2490 | index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); |
| 2491 | 2491 | if (index >= mcam->bmap_entries) |
| 2492 | 2492 | break; |
| 2493 | + entry = index + 1; | |
| 2493 | 2494 | if (mcam->entry2cntr_map[index] != req->cntr) |
| 2494 | 2495 | continue; |
| 2495 | 2496 | |
| 2496 | − entry = index + 1; | |
| 2497 | 2497 | npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, |
| 2498 | 2498 | index, req->cntr); |
| 2499 | 2499 | } |
| @@ -257,17 +257,19 @@ int otx2_get_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc, · 256 unmodified lines | ||
| 257 | 257 | int otx2_get_all_flows(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc, |
| 258 | 258 | u32 *rule_locs) |
| 259 | 259 | { |
| 260 | + u32 rule_cnt = nfc->rule_cnt; | |
| 260 | 261 | u32 location = 0; |
| 261 | 262 | int idx = 0; |
| 262 | 263 | int err = 0; |
| 263 | 264 | |
| 264 | 265 | nfc->data = pfvf->flow_cfg->ntuple_max_flows; |
| 265 | − while ((!err || err == -ENOENT) && idx < nfc->rule_cnt) { | |
| 266 | + while ((!err || err == -ENOENT) && idx < rule_cnt) { | |
| 266 | 267 | err = otx2_get_flow(pfvf, nfc, location); |
| 267 | 268 | if (!err) |
| 268 | 269 | rule_locs[idx++] = location; |
| 269 | 270 | location++; |
| 270 | 271 | } |
| 272 | + nfc->rule_cnt = rule_cnt; | |
| 271 | 273 | |
| 272 | 274 | return err; |
| 273 | 275 | } |
| @@ -1672,6 +1672,7 @@ int otx2_stop(struct net_device *netdev) · 1671 unmodified lines | ||
| 1672 | 1672 | struct otx2_nic *pf = netdev_priv(netdev); |
| 1673 | 1673 | struct otx2_cq_poll *cq_poll = NULL; |
| 1674 | 1674 | struct otx2_qset *qset = &pf->qset; |
| 1675 | + struct otx2_rss_info *rss; | |
| 1675 | 1676 | int qidx, vec, wrk; |
| 1676 | 1677 | |
| 1677 | 1678 | netif_carrier_off(netdev); |
| @@ -1684,6 +1685,10 @@ int otx2_stop(struct net_device *netdev) · 6 unmodified lines | ||
| 1684 | 1685 | /* First stop packet Rx/Tx */ |
| 1685 | 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 | 1692 | /* Cleanup Queue IRQ */ |
| 1688 | 1693 | vec = pci_irq_vector(pf->pdev, |
| 1689 | 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 | 1544 | clk_disable_unprepare(pep->clk); |
| 1545 | 1545 | mdiobus_unregister(pep->smi_bus); |
| 1546 | 1546 | mdiobus_free(pep->smi_bus); |
| 1547 | − unregister_netdev(dev); | |
| 1548 | 1547 | cancel_work_sync(&pep->tx_timeout_task); |
| 1548 | + unregister_netdev(dev); | |
| 1549 | 1549 | free_netdev(dev); |
| 1550 | 1550 | return 0; |
| 1551 | 1551 | } |
| @@ -92,14 +92,15 @@ struct page_pool; · 91 unmodified lines | ||
| 92 | 92 | MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0) |
| 93 | 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 | 98 | /* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between |
| 97 | 99 | * WQEs, This page will absorb write overflow by the hardware, when |
| 98 | 100 | * receiving packets larger than MTU. These oversize packets are |
| 99 | 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)) | |
| 102 | −#define MLX5E_LOG_ALIGNED_MPWQE_PPW (ilog2(MLX5E_REQUIRED_WQE_MTTS)) | |
| 103 | +#define MLX5E_REQUIRED_WQE_MTTS (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1)) | |
| 103 | 104 | #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS) |
| 104 | 105 | #define MLX5E_MAX_RQ_NUM_MTTS \ |
| 105 | 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 | 1182 | mlx5e_tc_match_to_reg_get_match(spec, CTSTATE_TO_REG, |
| 1183 | 1183 | &ctstate, &ctstate_mask); |
| 1184 | − if (ctstate_mask) | |
| 1184 | + | |
| 1185 | + if ((ctstate & ctstate_mask) == MLX5_CT_STATE_TRK_BIT) | |
| 1185 | 1186 | return -EOPNOTSUPP; |
| 1186 | 1187 | |
| 1187 | 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 | 685 | u16 vport_num; |
| 686 | 686 | int err = 0; |
| 687 | 687 | |
| 688 | − if (flow_attr->ip_version == 4) { | |
| 688 | + if (flow_attr->tun_ip_version == 4) { | |
| 689 | 689 | /* Addresses are swapped for decap */ |
| 690 | 690 | attr.fl.fl4.saddr = esw_attr->rx_tun_attr->dst_ip.v4; |
| 691 | 691 | attr.fl.fl4.daddr = esw_attr->rx_tun_attr->src_ip.v4; |
| 692 | 692 | err = mlx5e_route_lookup_ipv4_get(priv, priv->netdev, &attr); |
| 693 | 693 | } |
| 694 | 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 | 696 | /* Addresses are swapped for decap */ |
| 697 | 697 | attr.fl.fl6.saddr = esw_attr->rx_tun_attr->dst_ip.v6; |
| 698 | 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 | 718 | esw_attr->rx_tun_attr->decap_vport = vport_num; |
| 719 | 719 | |
| 720 | 720 | out: |
| 721 | − if (flow_attr->ip_version == 4) | |
| 721 | + if (flow_attr->tun_ip_version == 4) | |
| 722 | 722 | mlx5e_route_lookup_ipv4_put(&attr); |
| 723 | 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 | 725 | mlx5e_route_lookup_ipv6_put(&attr); |
| 726 | 726 | #endif |
| 727 | 727 | return err; |
| @@ -89,6 +89,7 @@ int mlx5e_tc_set_attr_rx_tun(struct mlx5e_tc_flow *flow, · 88 unmodified lines | ||
| 89 | 89 | * required to establish routing. |
| 90 | 90 | */ |
| 91 | 91 | flow_flag_set(flow, TUN_RX); |
| 92 | + flow->attr->tun_ip_version = ip_version; | |
| 92 | 93 | return 0; |
| 93 | 94 | } |
| 94 | 95 | |
| @@ -1091,7 +1092,7 @@ int mlx5e_attach_decap_route(struct mlx5e_priv *priv, · 996 unmodified lines | ||
| 1091 | 1092 | if (err || !esw_attr->rx_tun_attr->decap_vport) |
| 1092 | 1093 | goto out; |
| 1093 | 1094 | |
| 1094 | − key.ip_version = attr->ip_version; | |
| 1095 | + key.ip_version = attr->tun_ip_version; | |
| 1095 | 1096 | if (key.ip_version == 4) |
| 1096 | 1097 | key.endpoint_ip.v4 = esw_attr->rx_tun_attr->dst_ip.v4; |
| 1097 | 1098 | else |
| @@ -227,6 +227,10 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv, · 226 unmodified lines | ||
| 227 | 227 | option_key = (struct geneve_opt *)&enc_opts.key->data[0]; |
| 228 | 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 | 234 | if (option_key->length > max_tlv_option_data_len) { |
| 231 | 235 | NL_SET_ERR_MSG_MOD(extack, |
| 232 | 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 | 1888 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 1889 | 1889 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1890 | + int err; | |
| 1890 | 1891 | |
| 1891 | 1892 | if (!MLX5_CAP_GEN(mdev, cqe_compression)) |
| 1892 | 1893 | return -EOPNOTSUPP; |
| @@ -1896,7 +1897,10 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev, · 3 unmodified lines | ||
| 1896 | 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 | 1904 | priv->channels.params.rx_cqe_compress_def = enable; |
| 1901 | 1905 | |
| 1902 | 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 | 2020 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 2021 | + struct mlx5e_params old_params; | |
| 2022 | + | |
| 2023 | + old_params = priv->channels.params; | |
| 2017 | 2024 | priv->channels.params = new_channels.params; |
| 2018 | 2025 | err = mlx5e_num_channels_changed(priv); |
| 2026 | + if (err) | |
| 2027 | + priv->channels.params = old_params; | |
| 2019 | 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 | 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 | 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 | 577 | mlx5_wq_ll_get_wqe(&rq->mpwqe.wq, i); |
| 578 | 578 | u32 byte_count = |
| 579 | 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 | 582 | wqe->data[0].addr = cpu_to_be64(dma_offset + rq->buff.headroom); |
| 583 | 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 | 2369 | switch (params->rq_wq_type) { |
| 2370 | 2370 | case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: |
| 2371 | − return order_base_2(MLX5E_UMR_WQEBBS) + | |
| 2372 | − mlx5e_get_rq_log_wq_sz(rqp->rqc); | |
| 2371 | + return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, | |
| 2372 | + order_base_2(MLX5E_UMR_WQEBBS) + | |
| 2373 | + mlx5e_get_rq_log_wq_sz(rqp->rqc)); | |
| 2373 | 2374 | default: /* MLX5_WQ_TYPE_CYCLIC */ |
| 2374 | 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 | 2504 | int i; |
| 2504 | 2505 | |
| 2505 | − if (chs->port_ptp) | |
| 2506 | + if (chs->port_ptp) { | |
| 2506 | 2507 | mlx5e_port_ptp_close(chs->port_ptp); |
| 2508 | + chs->port_ptp = NULL; | |
| 2509 | + } | |
| 2507 | 2510 | |
| 2508 | 2511 | for (i = 0; i < chs->num; i++) |
| 2509 | 2512 | mlx5e_close_channel(chs->c[i]); |
| @@ -3810,6 +3813,15 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) · 1300 unmodified lines | ||
| 3810 | 3813 | for (j = 0; j < priv->max_opened_tc; j++) { |
| 3811 | 3814 | struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j]; |
| 3812 | 3815 | |
| 3816 | + s->tx_packets += sq_stats->packets; | |
| 3817 | + s->tx_bytes += sq_stats->bytes; | |
| 3818 | + s->tx_dropped += sq_stats->dropped; | |
| 3819 | + } | |
| 3820 | + } | |
| 3821 | + if (priv->port_ptp_opened) { | |
| 3822 | + for (i = 0; i < priv->max_opened_tc; i++) { | |
| 3823 | + struct mlx5e_sq_stats *sq_stats = &priv->port_ptp_stats.sq[i]; | |
| 3824 | + | |
| 3813 | 3825 | s->tx_packets += sq_stats->packets; |
| 3814 | 3826 | s->tx_bytes += sq_stats->bytes; |
| 3815 | 3827 | s->tx_dropped += sq_stats->dropped; |
| @@ -3834,10 +3846,17 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) · 18 unmodified lines | ||
| 3834 | 3846 | } |
| 3835 | 3847 | |
| 3836 | 3848 | if (mlx5e_is_uplink_rep(priv)) { |
| 3849 | + struct mlx5e_vport_stats *vstats = &priv->stats.vport; | |
| 3850 | + | |
| 3837 | 3851 | stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok); |
| 3838 | 3852 | stats->rx_bytes = PPORT_802_3_GET(pstats, a_octets_received_ok); |
| 3839 | 3853 | stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok); |
| 3840 | 3854 | stats->tx_bytes = PPORT_802_3_GET(pstats, a_octets_transmitted_ok); |
| 3855 | + | |
| 3856 | + /* vport multicast also counts packets that are dropped due to steering | |
| 3857 | + * or rx out of buffer | |
| 3858 | + */ | |
| 3859 | + stats->multicast = VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); | |
| 3841 | 3860 | } else { |
| 3842 | 3861 | mlx5e_fold_sw_stats64(priv, stats); |
| 3843 | 3862 | } |
| @@ -4683,8 +4702,10 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog) · 839 unmodified lines | ||
| 4683 | 4702 | struct mlx5e_channel *c = priv->channels.c[i]; |
| 4684 | 4703 | |
| 4685 | 4704 | mlx5e_rq_replace_xdp_prog(&c->rq, prog); |
| 4686 | − if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) | |
| 4705 | + if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) { | |
| 4706 | + bpf_prog_inc(prog); | |
| 4687 | 4707 | mlx5e_rq_replace_xdp_prog(&c->xskrq, prog); |
| 4708 | + } | |
| 4688 | 4709 | } |
| 4689 | 4710 | |
| 4690 | 4711 | unlock: |
| @@ -4958,6 +4979,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 · 267 unmodified lines | ||
| 4958 | 4979 | priv->max_nch); |
| 4959 | 4980 | params->num_tc = 1; |
| 4960 | 4981 | |
| 4982 | + /* Set an initial non-zero value, so that mlx5e_select_queue won't | |
| 4983 | + * divide by zero if called before first activating channels. | |
| 4984 | + */ | |
| 4985 | + priv->num_tc_x_num_ch = params->num_channels * params->num_tc; | |
| 4986 | + | |
| 4961 | 4987 | /* SQ */ |
| 4962 | 4988 | params->log_sq_size = is_kdump_kernel() ? |
| 4963 | 4989 | MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE : |
| @@ -5474,8 +5500,6 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, · 510 unmodified lines | ||
| 5474 | 5500 | struct net_device *netdev, |
| 5475 | 5501 | struct mlx5_core_dev *mdev) |
| 5476 | 5502 | { |
| 5477 | − memset(priv, 0, sizeof(*priv)); | |
| 5478 | − | |
| 5479 | 5503 | /* priv init */ |
| 5480 | 5504 | priv->mdev = mdev; |
| 5481 | 5505 | priv->netdev = netdev; |
| @@ -5508,12 +5532,18 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) · 26 unmodified lines | ||
| 5508 | 5532 | { |
| 5509 | 5533 | int i; |
| 5510 | 5534 | |
| 5535 | + /* bail if change profile failed and also rollback failed */ | |
| 5536 | + if (!priv->mdev) | |
| 5537 | + return; | |
| 5538 | + | |
| 5511 | 5539 | destroy_workqueue(priv->wq); |
| 5512 | 5540 | free_cpumask_var(priv->scratchpad.cpumask); |
| 5513 | 5541 | |
| 5514 | 5542 | for (i = 0; i < priv->htb.max_qos_sqs; i++) |
| 5515 | 5543 | kfree(priv->htb.qos_sq_stats[i]); |
| 5516 | 5544 | kvfree(priv->htb.qos_sq_stats); |
| 5545 | + | |
| 5546 | + memset(priv, 0, sizeof(*priv)); | |
| 5517 | 5547 | } |
| 5518 | 5548 | |
| 5519 | 5549 | struct net_device * |
| @@ -5630,11 +5660,10 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv) · 110 unmodified lines | ||
| 5630 | 5660 | } |
| 5631 | 5661 | |
| 5632 | 5662 | static int |
| 5633 | −mlx5e_netdev_attach_profile(struct mlx5e_priv *priv, | |
| 5663 | +mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mdev, | |
| 5634 | 5664 | const struct mlx5e_profile *new_profile, void *new_ppriv) |
| 5635 | 5665 | { |
| 5636 | − struct net_device *netdev = priv->netdev; | |
| 5637 | − struct mlx5_core_dev *mdev = priv->mdev; | |
| 5666 | + struct mlx5e_priv *priv = netdev_priv(netdev); | |
| 5638 | 5667 | int err; |
| 5639 | 5668 | |
| 5640 | 5669 | err = mlx5e_priv_init(priv, netdev, mdev); |
| @@ -5647,10 +5676,16 @@ mlx5e_netdev_attach_profile(struct mlx5e_priv *priv, · 6 unmodified lines | ||
| 5647 | 5676 | priv->ppriv = new_ppriv; |
| 5648 | 5677 | err = new_profile->init(priv->mdev, priv->netdev); |
| 5649 | 5678 | if (err) |
| 5650 | − return err; | |
| 5679 | + goto priv_cleanup; | |
| 5651 | 5680 | err = mlx5e_attach_netdev(priv); |
| 5652 | 5681 | if (err) |
| 5653 | − new_profile->cleanup(priv); | |
| 5682 | + goto profile_cleanup; | |
| 5683 | + return err; | |
| 5684 | + | |
| 5685 | +profile_cleanup: | |
| 5686 | + new_profile->cleanup(priv); | |
| 5687 | +priv_cleanup: | |
| 5688 | + mlx5e_priv_cleanup(priv); | |
| 5654 | 5689 | return err; |
| 5655 | 5690 | } |
| 5656 | 5691 | |
| @@ -5659,13 +5694,14 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, · 2 unmodified lines | ||
| 5659 | 5694 | { |
| 5660 | 5695 | unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); |
| 5661 | 5696 | const struct mlx5e_profile *orig_profile = priv->profile; |
| 5697 | + struct net_device *netdev = priv->netdev; | |
| 5698 | + struct mlx5_core_dev *mdev = priv->mdev; | |
| 5662 | 5699 | void *orig_ppriv = priv->ppriv; |
| 5663 | 5700 | int err, rollback_err; |
| 5664 | 5701 | |
| 5665 | 5702 | /* sanity */ |
| 5666 | 5703 | if (new_max_nch != priv->max_nch) { |
| 5667 | − netdev_warn(priv->netdev, | |
| 5668 | − "%s: Replacing profile with different max channels\n", | |
| 5704 | + netdev_warn(netdev, "%s: Replacing profile with different max channels\n", | |
| 5669 | 5705 | __func__); |
| 5670 | 5706 | return -EINVAL; |
| 5671 | 5707 | } |
| @@ -5675,22 +5711,19 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, · 3 unmodified lines | ||
| 5675 | 5711 | priv->profile->cleanup(priv); |
| 5676 | 5712 | mlx5e_priv_cleanup(priv); |
| 5677 | 5713 | |
| 5678 | − err = mlx5e_netdev_attach_profile(priv, new_profile, new_ppriv); | |
| 5714 | + err = mlx5e_netdev_attach_profile(netdev, mdev, new_profile, new_ppriv); | |
| 5679 | 5715 | if (err) { /* roll back to original profile */ |
| 5680 | − netdev_warn(priv->netdev, "%s: new profile init failed, %d\n", | |
| 5681 | − __func__, err); | |
| 5716 | + netdev_warn(netdev, "%s: new profile init failed, %d\n", __func__, err); | |
| 5682 | 5717 | goto rollback; |
| 5683 | 5718 | } |
| 5684 | 5719 | |
| 5685 | 5720 | return 0; |
| 5686 | 5721 | |
| 5687 | 5722 | rollback: |
| 5688 | − rollback_err = mlx5e_netdev_attach_profile(priv, orig_profile, orig_ppriv); | |
| 5689 | − if (rollback_err) { | |
| 5690 | − netdev_err(priv->netdev, | |
| 5691 | − "%s: failed to rollback to orig profile, %d\n", | |
| 5723 | + rollback_err = mlx5e_netdev_attach_profile(netdev, mdev, orig_profile, orig_ppriv); | |
| 5724 | + if (rollback_err) | |
| 5725 | + netdev_err(netdev, "%s: failed to rollback to orig profile, %d\n", | |
| 5692 | 5726 | __func__, rollback_err); |
| 5693 | − } | |
| 5694 | 5727 | return err; |
| 5695 | 5728 | } |
| 5696 | 5729 | |
| @@ -500,7 +500,6 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) · 499 unmodified lines | ||
| 500 | 500 | struct mlx5e_icosq *sq = rq->icosq; |
| 501 | 501 | struct mlx5_wq_cyc *wq = &sq->wq; |
| 502 | 502 | struct mlx5e_umr_wqe *umr_wqe; |
| 503 | − u16 xlt_offset = ix << (MLX5E_LOG_ALIGNED_MPWQE_PPW - 1); | |
| 504 | 503 | u16 pi; |
| 505 | 504 | int err; |
| 506 | 505 | int i; |
| @@ -531,7 +530,8 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) · 24 unmodified lines | ||
| 531 | 530 | umr_wqe->ctrl.opmod_idx_opcode = |
| 532 | 531 | cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) | |
| 533 | 532 | MLX5_OPCODE_UMR); |
| 534 | − umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); | |
| 533 | + umr_wqe->uctrl.xlt_offset = | |
| 534 | + cpu_to_be16(MLX5_ALIGNED_MTTS_OCTW(MLX5E_REQUIRED_MTTS(ix))); | |
| 535 | 535 | |
| 536 | 536 | sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) { |
| 537 | 537 | .wqe_type = MLX5E_ICOSQ_WQE_UMR_RX, |
| @@ -2296,6 +2296,16 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, · 2295 unmodified lines | ||
| 2296 | 2296 | *match_level = MLX5_MATCH_L4; |
| 2297 | 2297 | } |
| 2298 | 2298 | |
| 2299 | + /* Currenlty supported only for MPLS over UDP */ | |
| 2300 | + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS) && | |
| 2301 | + !netif_is_bareudp(filter_dev)) { | |
| 2302 | + NL_SET_ERR_MSG_MOD(extack, | |
| 2303 | + "Matching on MPLS is supported only for MPLS over UDP"); | |
| 2304 | + netdev_err(priv->netdev, | |
| 2305 | + "Matching on MPLS is supported only for MPLS over UDP\n"); | |
| 2306 | + return -EOPNOTSUPP; | |
| 2307 | + } | |
| 2308 | + | |
| 2299 | 2309 | return 0; |
| 2300 | 2310 | } |
| 2301 | 2311 | |
| @@ -2899,6 +2909,37 @@ static int is_action_keys_supported(const struct flow_action_entry *act, · 597 unmodified lines | ||
| 2899 | 2909 | return 0; |
| 2900 | 2910 | } |
| 2901 | 2911 | |
| 2912 | +static bool modify_tuple_supported(bool modify_tuple, bool ct_clear, | |
| 2913 | + bool ct_flow, struct netlink_ext_ack *extack, | |
| 2914 | + struct mlx5e_priv *priv, | |
| 2915 | + struct mlx5_flow_spec *spec) | |
| 2916 | +{ | |
| 2917 | + if (!modify_tuple || ct_clear) | |
| 2918 | + return true; | |
| 2919 | + | |
| 2920 | + if (ct_flow) { | |
| 2921 | + NL_SET_ERR_MSG_MOD(extack, | |
| 2922 | + "can't offload tuple modification with non-clear ct()"); | |
| 2923 | + netdev_info(priv->netdev, | |
| 2924 | + "can't offload tuple modification with non-clear ct()"); | |
| 2925 | + return false; | |
| 2926 | + } | |
| 2927 | + | |
| 2928 | + /* Add ct_state=-trk match so it will be offloaded for non ct flows | |
| 2929 | + * (or after clear action), as otherwise, since the tuple is changed, | |
| 2930 | + * we can't restore ct state | |
| 2931 | + */ | |
| 2932 | + if (mlx5_tc_ct_add_no_trk_match(spec)) { | |
| 2933 | + NL_SET_ERR_MSG_MOD(extack, | |
| 2934 | + "can't offload tuple modification with ct matches and no ct(clear) action"); | |
| 2935 | + netdev_info(priv->netdev, | |
| 2936 | + "can't offload tuple modification with ct matches and no ct(clear) action"); | |
| 2937 | + return false; | |
| 2938 | + } | |
| 2939 | + | |
| 2940 | + return true; | |
| 2941 | +} | |
| 2942 | + | |
| 2902 | 2943 | static bool modify_header_match_supported(struct mlx5e_priv *priv, |
| 2903 | 2944 | struct mlx5_flow_spec *spec, |
| 2904 | 2945 | struct flow_action *flow_action, |
| @@ -2937,18 +2978,9 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv, · 32 unmodified lines | ||
| 2937 | 2978 | return err; |
| 2938 | 2979 | } |
| 2939 | 2980 | |
| 2940 | − /* Add ct_state=-trk match so it will be offloaded for non ct flows | |
| 2941 | − * (or after clear action), as otherwise, since the tuple is changed, | |
| 2942 | − * we can't restore ct state | |
| 2943 | − */ | |
| 2944 | − if (!ct_clear && modify_tuple && | |
| 2945 | − mlx5_tc_ct_add_no_trk_match(spec)) { | |
| 2946 | − NL_SET_ERR_MSG_MOD(extack, | |
| 2947 | − "can't offload tuple modify header with ct matches"); | |
| 2948 | − netdev_info(priv->netdev, | |
| 2949 | − "can't offload tuple modify header with ct matches"); | |
| 2981 | + if (!modify_tuple_supported(modify_tuple, ct_clear, ct_flow, extack, | |
| 2982 | + priv, spec)) | |
| 2950 | 2983 | return false; |
| 2951 | − } | |
| 2952 | 2984 | |
| 2953 | 2985 | ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); |
| 2954 | 2986 | if (modify_ip_header && ip_proto != IPPROTO_TCP && |
| @@ -4445,7 +4477,8 @@ static int apply_police_params(struct mlx5e_priv *priv, u64 rate, · 1490 unmodified lines | ||
| 4445 | 4477 | */ |
| 4446 | 4478 | if (rate) { |
| 4447 | 4479 | rate = (rate * BITS_PER_BYTE) + 500000; |
| 4448 | − rate_mbps = max_t(u64, do_div(rate, 1000000), 1); | |
| 4480 | + do_div(rate, 1000000); | |
| 4481 | + rate_mbps = max_t(u32, rate, 1); | |
| 4449 | 4482 | } |
| 4450 | 4483 | |
| 4451 | 4484 | err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps); |
| @@ -79,6 +79,7 @@ struct mlx5_flow_attr { · 78 unmodified lines | ||
| 79 | 79 | u8 inner_match_level; |
| 80 | 80 | u8 outer_match_level; |
| 81 | 81 | u8 ip_version; |
| 82 | + u8 tun_ip_version; | |
| 82 | 83 | u32 flags; |
| 83 | 84 | union { |
| 84 | 85 | struct mlx5_esw_flow_attr esw_attr[0]; |
| @@ -551,7 +551,8 @@ esw_setup_dests(struct mlx5_flow_destination *dest, · 550 unmodified lines | ||
| 551 | 551 | |
| 552 | 552 | if (!mlx5_eswitch_termtbl_required(esw, attr, flow_act, spec) && |
| 553 | 553 | MLX5_CAP_GEN(esw_attr->in_mdev, reg_c_preserve) && |
| 554 | − mlx5_eswitch_vport_match_metadata_enabled(esw)) | |
| 554 | + mlx5_eswitch_vport_match_metadata_enabled(esw) && | |
| 555 | + MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level)) | |
| 555 | 556 | attr->flags |= MLX5_ESW_ATTR_FLAG_SRC_REWRITE; |
| 556 | 557 | |
| 557 | 558 | if (attr->dest_ft) { |
| @@ -575,6 +575,7 @@ static int mlx5_fpga_conn_create_qp(struct mlx5_fpga_conn *conn, · 574 unmodified lines | ||
| 575 | 575 | MLX5_SET(qpc, qpc, log_sq_size, ilog2(conn->qp.sq.size)); |
| 576 | 576 | MLX5_SET(qpc, qpc, cqn_snd, conn->cq.mcq.cqn); |
| 577 | 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 | 579 | MLX5_SET64(qpc, qpc, dbr_addr, conn->qp.wq_ctrl.db.dma); |
| 579 | 580 | if (MLX5_CAP_GEN(mdev, cqe_version) == 1) |
| 580 | 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 | 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 | 237 | MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD); |
| 237 | 238 | MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); |
| 238 | 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 | 695 | static void mlx5_rdma_netdev_free(struct net_device *netdev) |
| 695 | 696 | { |
| 696 | 697 | struct mlx5e_priv *priv = mlx5i_epriv(netdev); |
| 698 | + struct mlx5_core_dev *mdev = priv->mdev; | |
| 697 | 699 | struct mlx5i_priv *ipriv = priv->ppriv; |
| 698 | 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 | 705 | if (!ipriv->sub_interface) { |
| 704 | 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 | 495 | return -EINVAL; |
| 496 | 496 | |
| 497 | 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 | 502 | if (on) { |
| 499 | 503 | bool rt_mode = mlx5_real_time_mode(mdev); |
| 500 | 504 | u32 nsec; |
| 501 | 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 | 507 | pin_mode = MLX5_PIN_MODE_OUT; |
| 508 | 508 | pattern = MLX5_OUT_PATTERN_PERIODIC; |
| 509 | 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 | 181 | u16 max_functions; |
| 182 | 182 | u16 function_id; |
| 183 | 183 | int err = 0; |
| 184 | − bool ecpu; | |
| 185 | 184 | int i; |
| 186 | 185 | |
| 187 | 186 | max_functions = mlx5_sf_max_functions(dev); |
| 188 | 187 | function_id = MLX5_CAP_GEN(dev, sf_base_id); |
| 189 | − ecpu = mlx5_read_embedded_cpu(dev); | |
| 190 | 188 | /* Arm the vhca context as the vhca event notifier */ |
| 191 | 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 | 191 | if (err) |
| 194 | 192 | return err; |
| 195 | 193 | |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "sf.h" |
| 7 | 7 | #include "mlx5_ifc_vhca_event.h" |
| 8 | 8 | #include "vhca_event.h" |
| 9 | −#include "ecpf.h" | |
| 9 | +#include "mlx5_core.h" | |
| 10 | 10 | |
| 11 | 11 | struct mlx5_sf_hw { |
| 12 | 12 | u32 usr_sfnum; |
| @@ -18,7 +18,6 @@ struct mlx5_sf_hw_table { · 5 unmodified lines | ||
| 18 | 18 | struct mlx5_core_dev *dev; |
| 19 | 19 | struct mlx5_sf_hw *sfs; |
| 20 | 20 | int max_local_functions; |
| 21 | − u8 ecpu: 1; | |
| 22 | 21 | struct mutex table_lock; /* Serializes sf deletion and vhca state change handler. */ |
| 23 | 22 | struct notifier_block vhca_nb; |
| 24 | 23 | }; |
| @@ -64,7 +63,7 @@ int mlx5_sf_hw_table_sf_alloc(struct mlx5_core_dev *dev, u32 usr_sfnum) · 39 unmodified lines | ||
| 64 | 63 | } |
| 65 | 64 | if (sw_id == -ENOSPC) { |
| 66 | 65 | err = -ENOSPC; |
| 67 | − goto err; | |
| 66 | + goto exist_err; | |
| 68 | 67 | } |
| 69 | 68 | |
| 70 | 69 | hw_fn_id = mlx5_sf_sw_to_hw_id(table->dev, sw_id); |
| @@ -72,7 +71,7 @@ int mlx5_sf_hw_table_sf_alloc(struct mlx5_core_dev *dev, u32 usr_sfnum) · 1 unmodified line | ||
| 72 | 71 | if (err) |
| 73 | 72 | goto err; |
| 74 | 73 | |
| 75 | − err = mlx5_modify_vhca_sw_id(dev, hw_fn_id, table->ecpu, usr_sfnum); | |
| 74 | + err = mlx5_modify_vhca_sw_id(dev, hw_fn_id, usr_sfnum); | |
| 76 | 75 | if (err) |
| 77 | 76 | goto vhca_err; |
| 78 | 77 | |
| @@ -118,7 +117,7 @@ void mlx5_sf_hw_table_sf_deferred_free(struct mlx5_core_dev *dev, u16 id) · 39 unmodified lines | ||
| 118 | 117 | |
| 119 | 118 | hw_fn_id = mlx5_sf_sw_to_hw_id(dev, id); |
| 120 | 119 | mutex_lock(&table->table_lock); |
| 121 | − err = mlx5_cmd_query_vhca_state(dev, hw_fn_id, table->ecpu, out, sizeof(out)); | |
| 120 | + err = mlx5_cmd_query_vhca_state(dev, hw_fn_id, out, sizeof(out)); | |
| 122 | 121 | if (err) |
| 123 | 122 | goto err; |
| 124 | 123 | state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state); |
| @@ -164,7 +163,6 @@ int mlx5_sf_hw_table_init(struct mlx5_core_dev *dev) · 39 unmodified lines | ||
| 164 | 163 | table->dev = dev; |
| 165 | 164 | table->sfs = sfs; |
| 166 | 165 | table->max_local_functions = max_functions; |
| 167 | − table->ecpu = mlx5_read_embedded_cpu(dev); | |
| 168 | 166 | dev->priv.sf_hw_table = table; |
| 169 | 167 | mlx5_core_dbg(dev, "SF HW table: max sfs = %d\n", max_functions); |
| 170 | 168 | return 0; |
| @@ -20,7 +20,7 @@ struct mlx5_ifc_vhca_state_context_bits { · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 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 | 26 | struct mlx5_ifc_query_vhca_state_out_bits { |
| @@ -19,52 +19,51 @@ struct mlx5_vhca_event_work { · 18 unmodified lines | ||
| 19 | 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, | |
| 23 | − bool ecpu, u32 *out, u32 outlen) | |
| 22 | +int mlx5_cmd_query_vhca_state(struct mlx5_core_dev *dev, u16 function_id, u32 *out, u32 outlen) | |
| 24 | 23 | { |
| 25 | 24 | u32 in[MLX5_ST_SZ_DW(query_vhca_state_in)] = {}; |
| 26 | 25 | |
| 27 | 26 | MLX5_SET(query_vhca_state_in, in, opcode, MLX5_CMD_OP_QUERY_VHCA_STATE); |
| 28 | 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 | 30 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); |
| 32 | 31 | } |
| 33 | 32 | |
| 34 | 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 | 36 | u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {}; |
| 38 | 37 | |
| 39 | 38 | MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE); |
| 40 | 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 | 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 | 47 | u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {}; |
| 49 | 48 | u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {}; |
| 50 | 49 | |
| 51 | 50 | MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE); |
| 52 | 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 | 53 | MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.sw_function_id, 1); |
| 55 | 54 | MLX5_SET(modify_vhca_state_in, in, vhca_state_context.sw_function_id, sw_fn_id); |
| 56 | 55 | |
| 57 | 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 | 61 | u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {}; |
| 63 | 62 | |
| 64 | 63 | MLX5_SET(modify_vhca_state_in, in, vhca_state_context.arm_change_event, 1); |
| 65 | 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 | 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 | 72 | u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {}; |
| 74 | 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 | 76 | if (err) |
| 78 | 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 | 81 | event->new_vhca_state = MLX5_GET(query_vhca_state_out, out, |
| 83 | 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 | 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 | 93 | struct mlx5_core_dev *dev = notifier->dev; |
| 95 | 94 | |
| 96 | 95 | mlx5_vhca_event_notify(dev, &work->event); |
| 96 | + kfree(work); | |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 | static int |
| @@ -110,7 +110,6 @@ mlx5_vhca_state_change_notifier(struct notifier_block *nb, unsigned long type, v · 10 unmodified lines | ||
| 110 | 110 | INIT_WORK(&work->work, &mlx5_vhca_state_work_handler); |
| 111 | 111 | work->notifier = notifier; |
| 112 | 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 | 113 | mlx5_events_work_enqueue(notifier->dev, &work->work); |
| 115 | 114 | return NOTIFY_OK; |
| 116 | 115 | } |
| @@ -10,7 +10,6 @@ struct mlx5_vhca_state_event { · 9 unmodified lines | ||
| 10 | 10 | u16 function_id; |
| 11 | 11 | u16 sw_function_id; |
| 12 | 12 | u8 new_vhca_state; |
| 13 | − bool ecpu; | |
| 14 | 13 | }; |
| 15 | 14 | |
| 16 | 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 | 24 | void mlx5_vhca_event_stop(struct mlx5_core_dev *dev); |
| 26 | 25 | int mlx5_vhca_event_notifier_register(struct mlx5_core_dev *dev, struct notifier_block *nb); |
| 27 | 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); | |
| 29 | −int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id, bool ecpu); | |
| 27 | +int mlx5_modify_vhca_sw_id(struct mlx5_core_dev *dev, u16 function_id, u32 sw_fn_id); | |
| 28 | +int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id); | |
| 30 | 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 | 31 | #else |
| 33 | 32 | |
| 34 | 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 | 169 | MLX5_SET(qpc, qpc, log_rq_size, ilog2(dr_qp->rq.wqe_cnt)); |
| 170 | 170 | MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ); |
| 171 | 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 | 173 | MLX5_SET64(qpc, qpc, dbr_addr, dr_qp->wq_ctrl.db.dma); |
| 173 | 174 | if (MLX5_CAP_GEN(mdev, cqe_version) == 1) |
| 174 | 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 | 264 | static u64 dr_ste_v1_get_miss_addr(u8 *hw_ste_p) |
| 265 | 265 | { |
| 266 | 266 | u64 index = |
| 267 | − (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); | |
| 267 | + ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6) | | |
| 268 | + ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32)) << 26); | |
| 269 | 269 | |
| 270 | 270 | return index << 6; |
| 271 | 271 | } |
| @@ -327,8 +327,14 @@ int nfp_compile_flow_metadata(struct nfp_app *app, · 326 unmodified lines | ||
| 327 | 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 | 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 | 338 | nfp_flow->meta.mask_len, |
| 333 | 339 | &nfp_flow->meta.flags, &new_mask_id)) { |
| 334 | 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 | 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 | 370 | nfp_flow->meta.mask_len, |
| 364 | 371 | NULL, &new_mask_id)) { |
| 365 | 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 | 381 | return 0; |
| 375 | 382 | |
| 376 | 383 | err_remove_mask: |
| 377 | − nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, | |
| 378 | − NULL, &new_mask_id); | |
| 384 | + if (!nfp_flow->pre_tun_rule.dev) | |
| 385 | + nfp_check_mask_remove(app, nfp_flow->mask_data, | |
| 386 | + nfp_flow->meta.mask_len, | |
| 387 | + NULL, &new_mask_id); | |
| 379 | 388 | err_remove_rhash: |
| 380 | 389 | WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, |
| 381 | 390 | &ctx_entry->ht_node, |
| @@ -406,9 +415,10 @@ int nfp_modify_flow_metadata(struct nfp_app *app, · 24 unmodified lines | ||
| 406 | 415 | |
| 407 | 416 | __nfp_modify_flow_metadata(priv, nfp_flow); |
| 408 | 417 | |
| 409 | − nfp_check_mask_remove(app, nfp_flow->mask_data, | |
| 410 | − nfp_flow->meta.mask_len, &nfp_flow->meta.flags, | |
| 411 | − &new_mask_id); | |
| 418 | + if (!nfp_flow->pre_tun_rule.dev) | |
| 419 | + nfp_check_mask_remove(app, nfp_flow->mask_data, | |
| 420 | + nfp_flow->meta.mask_len, &nfp_flow->meta.flags, | |
| 421 | + &new_mask_id); | |
| 412 | 422 | |
| 413 | 423 | /* Update flow payload with mask ids. */ |
| 414 | 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 | 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 | 1151 | /* Skip fields known to exist. */ |
| 1146 | 1152 | mask += sizeof(struct nfp_flower_meta_tci); |
| 1147 | 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 | 1158 | mask += sizeof(struct nfp_flower_in_port); |
| 1153 | 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 | 1168 | /* Ensure destination MAC address is fully matched. */ |
| 1156 | 1169 | mac = (struct nfp_flower_mac_mpls *)mask; |
| 1157 | 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 | 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 | 1180 | mask += sizeof(struct nfp_flower_mac_mpls); |
| 1163 | 1181 | ext += sizeof(struct nfp_flower_mac_mpls); |
| 1164 | 1182 | if (key_layer & NFP_FLOWER_LAYER_IPV4 || |
| @@ -16,8 +16,9 @@ · 15 unmodified lines | ||
| 16 | 16 | #define NFP_FL_MAX_ROUTES 32 |
| 17 | 17 | |
| 18 | 18 | #define NFP_TUN_PRE_TUN_RULE_LIMIT 32 |
| 19 | −#define NFP_TUN_PRE_TUN_RULE_DEL 0x1 | |
| 20 | −#define NFP_TUN_PRE_TUN_IDX_BIT 0x8 | |
| 19 | +#define NFP_TUN_PRE_TUN_RULE_DEL BIT(0) | |
| 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 | 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 | 1270 | struct nfp_flower_priv *app_priv = app->priv; |
| 1270 | 1271 | struct nfp_tun_offloaded_mac *mac_entry; |
| 1272 | + struct nfp_flower_meta_tci *key_meta; | |
| 1271 | 1273 | struct nfp_tun_pre_tun_rule payload; |
| 1272 | 1274 | struct net_device *internal_dev; |
| 1273 | 1275 | int err; |
| @@ -1290,6 +1292,15 @@ int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app, · 16 unmodified lines | ||
| 1290 | 1292 | if (!mac_entry) |
| 1291 | 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 | 1304 | payload.port_idx = cpu_to_be16(mac_entry->index); |
| 1294 | 1305 | |
| 1295 | 1306 | /* Copy mac id and vlan to flow - dev may not exist at delete time. */ |
| @@ -1079,15 +1079,17 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) · 1078 unmodified lines | ||
| 1079 | 1079 | { |
| 1080 | 1080 | int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems; |
| 1081 | 1081 | struct ionic_tx_stats *stats = q_to_tx_stats(q); |
| 1082 | + int ndescs; | |
| 1082 | 1083 | int err; |
| 1083 | 1084 | |
| 1084 | − /* If TSO, need roundup(skb->len/mss) descs */ | |
| 1085 | + /* Each desc is mss long max, so a descriptor for each gso_seg */ | |
| 1085 | 1086 | if (skb_is_gso(skb)) |
| 1086 | − return (skb->len / skb_shinfo(skb)->gso_size) + 1; | |
| 1087 | + ndescs = skb_shinfo(skb)->gso_segs; | |
| 1088 | + else | |
| 1089 | + ndescs = 1; | |
| 1087 | 1090 | |
| 1088 | − /* If non-TSO, just need 1 desc and nr_frags sg elems */ | |
| 1089 | 1091 | if (skb_shinfo(skb)->nr_frags <= sg_elems) |
| 1090 | − return 1; | |
| 1092 | + return ndescs; | |
| 1091 | 1093 | |
| 1092 | 1094 | /* Too many frags, so linearize */ |
| 1093 | 1095 | err = skb_linearize(skb); |
| @@ -1096,8 +1098,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) · 2 unmodified lines | ||
| 1096 | 1098 | |
| 1097 | 1099 | stats->linearize++; |
| 1098 | 1100 | |
| 1099 | − /* Need 1 desc and zero sg elems */ | |
| 1100 | − return 1; | |
| 1101 | + return ndescs; | |
| 1101 | 1102 | } |
| 1102 | 1103 | |
| 1103 | 1104 | 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 | 1426 | if (fw_dump->tmpl_hdr == NULL || current_version > prev_version) { |
| 1427 | 1427 | vfree(fw_dump->tmpl_hdr); |
| 1428 | + fw_dump->tmpl_hdr = NULL; | |
| 1428 | 1429 | |
| 1429 | 1430 | if (qlcnic_83xx_md_check_extended_dump_capability(adapter)) |
| 1430 | 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 | 1444 | struct qlcnic_83xx_dump_template_hdr *hdr; |
| 1444 | 1445 | |
| 1445 | 1446 | hdr = fw_dump->tmpl_hdr; |
| 1447 | + if (!hdr) | |
| 1448 | + return; | |
| 1446 | 1449 | hdr->drv_cap_mask = 0x1f; |
| 1447 | 1450 | fw_dump->cap_mask = 0x1f; |
| 1448 | 1451 | dev_info(&pdev->dev, |
| @@ -4646,6 +4646,9 @@ static void rtl8169_down(struct rtl8169_private *tp) · 4645 unmodified lines | ||
| 4646 | 4646 | |
| 4647 | 4647 | rtl8169_update_counters(tp); |
| 4648 | 4648 | |
| 4649 | + pci_clear_master(tp->pci_dev); | |
| 4650 | + rtl_pci_commit(tp); | |
| 4651 | + | |
| 4649 | 4652 | rtl8169_cleanup(tp, true); |
| 4650 | 4653 | |
| 4651 | 4654 | rtl_prepare_power_down(tp); |
| @@ -4653,6 +4656,7 @@ static void rtl8169_down(struct rtl8169_private *tp) · 1 unmodified line | ||
| 4653 | 4656 | |
| 4654 | 4657 | static void rtl8169_up(struct rtl8169_private *tp) |
| 4655 | 4658 | { |
| 4659 | + pci_set_master(tp->pci_dev); | |
| 4656 | 4660 | phy_resume(tp->phydev); |
| 4657 | 4661 | rtl8169_init_phy(tp); |
| 4658 | 4662 | napi_enable(&tp->napi); |
| @@ -5307,8 +5311,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 648 unmodified lines | ||
| 5307 | 5311 | |
| 5308 | 5312 | rtl_hw_reset(tp); |
| 5309 | 5313 | |
| 5310 | − pci_set_master(pdev); | |
| 5311 | − | |
| 5312 | 5314 | rc = rtl_alloc_irq(tp); |
| 5313 | 5315 | if (rc < 0) { |
| 5314 | 5316 | 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 | 1715 | goto err1; |
| 1716 | 1716 | |
| 1717 | 1717 | /* set phy power down */ |
| 1718 | − data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR) | | |
| 1719 | − BMCR_PDOWN; | |
| 1720 | − netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); | |
| 1718 | + data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR); | |
| 1719 | + netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, | |
| 1720 | + data | BMCR_PDOWN); | |
| 1721 | 1721 | |
| 1722 | 1722 | ret = netsec_reset_hardware(priv, true); |
| 1723 | 1723 | if (ret) |
| 1724 | 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 | 1729 | spin_lock_init(&priv->desc_ring[NETSEC_RING_TX].lock); |
| 1727 | 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 | 1214 | plat_dat->init = sun8i_dwmac_init; |
| 1215 | 1215 | plat_dat->exit = sun8i_dwmac_exit; |
| 1216 | 1216 | plat_dat->setup = sun8i_dwmac_setup; |
| 1217 | + plat_dat->tx_fifo_size = 4096; | |
| 1218 | + plat_dat->rx_fifo_size = 16384; | |
| 1217 | 1219 | |
| 1218 | 1220 | ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); |
| 1219 | 1221 | if (ret) |
| @@ -1880,7 +1880,7 @@ static int axienet_probe(struct platform_device *pdev) · 1879 unmodified lines | ||
| 1880 | 1880 | if (IS_ERR(lp->regs)) { |
| 1881 | 1881 | dev_err(&pdev->dev, "could not map Axi Ethernet regs.\n"); |
| 1882 | 1882 | ret = PTR_ERR(lp->regs); |
| 1883 | − goto free_netdev; | |
| 1883 | + goto cleanup_clk; | |
| 1884 | 1884 | } |
| 1885 | 1885 | lp->regs_start = ethres->start; |
| 1886 | 1886 | |
| @@ -1958,18 +1958,18 @@ static int axienet_probe(struct platform_device *pdev) · 71 unmodified lines | ||
| 1958 | 1958 | break; |
| 1959 | 1959 | default: |
| 1960 | 1960 | ret = -EINVAL; |
| 1961 | − goto free_netdev; | |
| 1961 | + goto cleanup_clk; | |
| 1962 | 1962 | } |
| 1963 | 1963 | } else { |
| 1964 | 1964 | ret = of_get_phy_mode(pdev->dev.of_node, &lp->phy_mode); |
| 1965 | 1965 | if (ret) |
| 1966 | − goto free_netdev; | |
| 1966 | + goto cleanup_clk; | |
| 1967 | 1967 | } |
| 1968 | 1968 | if (lp->switch_x_sgmii && lp->phy_mode != PHY_INTERFACE_MODE_SGMII && |
| 1969 | 1969 | lp->phy_mode != PHY_INTERFACE_MODE_1000BASEX) { |
| 1970 | 1970 | dev_err(&pdev->dev, "xlnx,switch-x-sgmii only supported with SGMII or 1000BaseX\n"); |
| 1971 | 1971 | ret = -EINVAL; |
| 1972 | − goto free_netdev; | |
| 1972 | + goto cleanup_clk; | |
| 1973 | 1973 | } |
| 1974 | 1974 | |
| 1975 | 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 | 1982 | dev_err(&pdev->dev, |
| 1983 | 1983 | "unable to get DMA resource\n"); |
| 1984 | 1984 | of_node_put(np); |
| 1985 | − goto free_netdev; | |
| 1985 | + goto cleanup_clk; | |
| 1986 | 1986 | } |
| 1987 | 1987 | lp->dma_regs = devm_ioremap_resource(&pdev->dev, |
| 1988 | 1988 | &dmares); |
| @@ -2002,12 +2002,12 @@ static int axienet_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 2002 | 2002 | if (IS_ERR(lp->dma_regs)) { |
| 2003 | 2003 | dev_err(&pdev->dev, "could not map DMA regs\n"); |
| 2004 | 2004 | ret = PTR_ERR(lp->dma_regs); |
| 2005 | − goto free_netdev; | |
| 2005 | + goto cleanup_clk; | |
| 2006 | 2006 | } |
| 2007 | 2007 | if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) { |
| 2008 | 2008 | dev_err(&pdev->dev, "could not determine irqs\n"); |
| 2009 | 2009 | ret = -ENOMEM; |
| 2010 | − goto free_netdev; | |
| 2010 | + goto cleanup_clk; | |
| 2011 | 2011 | } |
| 2012 | 2012 | |
| 2013 | 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 | 2037 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); |
| 2038 | 2038 | if (ret) { |
| 2039 | 2039 | dev_err(&pdev->dev, "No suitable DMA available\n"); |
| 2040 | − goto free_netdev; | |
| 2040 | + goto cleanup_clk; | |
| 2041 | 2041 | } |
| 2042 | 2042 | |
| 2043 | 2043 | /* Check for Ethernet core IRQ (optional) */ |
| @@ -2068,12 +2068,12 @@ static int axienet_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 2068 | 2068 | if (!lp->phy_node) { |
| 2069 | 2069 | dev_err(&pdev->dev, "phy-handle required for 1000BaseX/SGMII\n"); |
| 2070 | 2070 | ret = -EINVAL; |
| 2071 | − goto free_netdev; | |
| 2071 | + goto cleanup_mdio; | |
| 2072 | 2072 | } |
| 2073 | 2073 | lp->pcs_phy = of_mdio_find_device(lp->phy_node); |
| 2074 | 2074 | if (!lp->pcs_phy) { |
| 2075 | 2075 | ret = -EPROBE_DEFER; |
| 2076 | − goto free_netdev; | |
| 2076 | + goto cleanup_mdio; | |
| 2077 | 2077 | } |
| 2078 | 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 | 2087 | if (IS_ERR(lp->phylink)) { |
| 2088 | 2088 | ret = PTR_ERR(lp->phylink); |
| 2089 | 2089 | dev_err(&pdev->dev, "phylink_create error (%i)\n", ret); |
| 2090 | − goto free_netdev; | |
| 2090 | + goto cleanup_mdio; | |
| 2091 | 2091 | } |
| 2092 | 2092 | |
| 2093 | 2093 | ret = register_netdev(lp->ndev); |
| 2094 | 2094 | if (ret) { |
| 2095 | 2095 | dev_err(lp->dev, "register_netdev() error (%i)\n", ret); |
| 2096 | − goto free_netdev; | |
| 2096 | + goto cleanup_phylink; | |
| 2097 | 2097 | } |
| 2098 | 2098 | |
| 2099 | 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 | 2114 | free_netdev: |
| 2102 | 2115 | free_netdev(ndev); |
| 2103 | 2116 | |
| @@ -175,21 +175,23 @@ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, · 174 unmodified lines | ||
| 175 | 175 | : field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK); |
| 176 | 176 | if (mem->offset > offset_max || |
| 177 | 177 | ipa->mem_offset > offset_max - mem->offset) { |
| 178 | − dev_err(dev, "IPv%c %s%s table region offset too large " | |
| 179 | − "(0x%04x + 0x%04x > 0x%04x)\n", | |
| 180 | − ipv6 ? '6' : '4', hashed ? "hashed " : "", | |
| 181 | − route ? "route" : "filter", | |
| 182 | − ipa->mem_offset, mem->offset, offset_max); | |
| 178 | + dev_err(dev, "IPv%c %s%s table region offset too large\n", | |
| 179 | + ipv6 ? '6' : '4', hashed ? "hashed " : "", | |
| 180 | + route ? "route" : "filter"); | |
| 181 | + dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", | |
| 182 | + ipa->mem_offset, mem->offset, offset_max); | |
| 183 | + | |
| 183 | 184 | return false; |
| 184 | 185 | } |
| 185 | 186 | |
| 186 | 187 | if (mem->offset > ipa->mem_size || |
| 187 | 188 | mem->size > ipa->mem_size - mem->offset) { |
| 188 | − dev_err(dev, "IPv%c %s%s table region out of range " | |
| 189 | − "(0x%04x + 0x%04x > 0x%04x)\n", | |
| 190 | − ipv6 ? '6' : '4', hashed ? "hashed " : "", | |
| 191 | − route ? "route" : "filter", | |
| 192 | − mem->offset, mem->size, ipa->mem_size); | |
| 189 | + dev_err(dev, "IPv%c %s%s table region out of range\n", | |
| 190 | + ipv6 ? '6' : '4', hashed ? "hashed " : "", | |
| 191 | + route ? "route" : "filter"); | |
| 192 | + dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", | |
| 193 | + mem->offset, mem->size, ipa->mem_size); | |
| 194 | + | |
| 193 | 195 | return false; |
| 194 | 196 | } |
| 195 | 197 | |
| @@ -205,22 +207,36 @@ static bool ipa_cmd_header_valid(struct ipa *ipa) · 9 unmodified lines | ||
| 205 | 207 | u32 size_max; |
| 206 | 208 | u32 size; |
| 207 | 209 | |
| 210 | + /* In ipa_cmd_hdr_init_local_add() we record the offset and size | |
| 211 | + * of the header table memory area. Make sure the offset and size | |
| 212 | + * fit in the fields that need to hold them, and that the entire | |
| 213 | + * range is within the overall IPA memory range. | |
| 214 | + */ | |
| 208 | 215 | offset_max = field_max(HDR_INIT_LOCAL_FLAGS_HDR_ADDR_FMASK); |
| 209 | 216 | if (mem->offset > offset_max || |
| 210 | 217 | ipa->mem_offset > offset_max - mem->offset) { |
| 211 | − dev_err(dev, "header table region offset too large " | |
| 212 | − "(0x%04x + 0x%04x > 0x%04x)\n", | |
| 213 | − ipa->mem_offset + mem->offset, offset_max); | |
| 218 | + dev_err(dev, "header table region offset too large\n"); | |
| 219 | + dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", | |
| 220 | + ipa->mem_offset, mem->offset, offset_max); | |
| 221 | + | |
| 214 | 222 | return false; |
| 215 | 223 | } |
| 216 | 224 | |
| 217 | 225 | size_max = field_max(HDR_INIT_LOCAL_FLAGS_TABLE_SIZE_FMASK); |
| 218 | 226 | size = ipa->mem[IPA_MEM_MODEM_HEADER].size; |
| 219 | 227 | size += ipa->mem[IPA_MEM_AP_HEADER].size; |
| 220 | − if (mem->offset > ipa->mem_size || size > ipa->mem_size - mem->offset) { | |
| 221 | − dev_err(dev, "header table region out of range " | |
| 222 | − "(0x%04x + 0x%04x > 0x%04x)\n", | |
| 223 | − mem->offset, size, ipa->mem_size); | |
| 228 | + | |
| 229 | + if (size > size_max) { | |
| 230 | + dev_err(dev, "header table region size too large\n"); | |
| 231 | + dev_err(dev, " (0x%04x > 0x%08x)\n", size, size_max); | |
| 232 | + | |
| 233 | + return false; | |
| 234 | + } | |
| 235 | + if (size > ipa->mem_size || mem->offset > ipa->mem_size - size) { | |
| 236 | + dev_err(dev, "header table region out of range\n"); | |
| 237 | + dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", | |
| 238 | + mem->offset, size, ipa->mem_size); | |
| 239 | + | |
| 224 | 240 | return false; |
| 225 | 241 | } |
| 226 | 242 | |
| @@ -249,6 +249,7 @@ static const struct qmi_msg_handler ipa_server_msg_handlers[] = { · 248 unmodified lines | ||
| 249 | 249 | .decoded_size = IPA_QMI_DRIVER_INIT_COMPLETE_REQ_SZ, |
| 250 | 250 | .fn = ipa_server_driver_init_complete, |
| 251 | 251 | }, |
| 252 | + { }, | |
| 252 | 253 | }; |
| 253 | 254 | |
| 254 | 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 | 270 | .decoded_size = IPA_QMI_INIT_DRIVER_RSP_SZ, |
| 270 | 271 | .fn = ipa_client_init_driver, |
| 271 | 272 | }, |
| 273 | + { }, | |
| 272 | 274 | }; |
| 273 | 275 | |
| 274 | 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 | 342 | bcm54xx_adjust_rxrefclk(phydev); |
| 343 | 343 | |
| 344 | 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 | 349 | case PHY_ID_BCM54210E: |
| 346 | 350 | err = bcm54210e_config_init(phydev); |
| 347 | 351 | break; |
| @@ -399,6 +403,11 @@ static int bcm54xx_resume(struct phy_device *phydev) · 51 unmodified lines | ||
| 399 | 403 | if (ret < 0) |
| 400 | 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 | 411 | return bcm54xx_config_init(phydev); |
| 403 | 412 | } |
| 404 | 413 | |
| @@ -476,7 +476,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, · 475 unmodified lines | ||
| 476 | 476 | err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, |
| 477 | 477 | state->interface); |
| 478 | 478 | if (err < 0) |
| 479 | − phylink_err(pl, "mac_prepare failed: %pe\n", | |
| 479 | + phylink_err(pl, "mac_finish failed: %pe\n", | |
| 480 | 480 | ERR_PTR(err)); |
| 481 | 481 | } |
| 482 | 482 | } |
| @@ -387,6 +387,8 @@ static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *i · 386 unmodified lines | ||
| 387 | 387 | |
| 388 | 388 | err = register_netdev(dev); |
| 389 | 389 | if (err) { |
| 390 | + /* Set disconnected flag so that disconnect() returns early. */ | |
| 391 | + pnd->disconnected = 1; | |
| 390 | 392 | usb_driver_release_interface(&usbpn_driver, data_intf); |
| 391 | 393 | goto out; |
| 392 | 394 | } |
| @@ -6553,7 +6553,10 @@ static int rtl_ops_init(struct r8152 *tp) · 6552 unmodified lines | ||
| 6553 | 6553 | ops->in_nway = rtl8153_in_nway; |
| 6554 | 6554 | ops->hw_phy_cfg = r8153_hw_phy_cfg; |
| 6555 | 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 | 6560 | tp->eee_en = true; |
| 6558 | 6561 | tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; |
| 6559 | 6562 | break; |
| @@ -302,8 +302,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) · 301 unmodified lines | ||
| 302 | 302 | if (rxq < rcv->real_num_rx_queues) { |
| 303 | 303 | rq = &rcv_priv->rq[rxq]; |
| 304 | 304 | rcv_xdp = rcu_access_pointer(rq->xdp_prog); |
| 305 | − if (rcv_xdp) | |
| 306 | − skb_record_rx_queue(skb, rxq); | |
| 305 | + skb_record_rx_queue(skb, rxq); | |
| 307 | 306 | } |
| 308 | 307 | |
| 309 | 308 | skb_tx_timestamp(skb); |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | struct x25_state { |
| 25 | 25 | x25_hdlc_proto settings; |
| 26 | + bool up; | |
| 27 | + spinlock_t up_lock; /* Protects "up" */ | |
| 26 | 28 | }; |
| 27 | 29 | |
| 28 | 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 | 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 | 111 | int result; |
| 108 | 112 | |
| 109 | 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 | 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 | 128 | switch (skb->data[0]) { |
| 118 | 129 | case X25_IFACE_DATA: /* Data to be transmitted */ |
| 119 | 130 | skb_pull(skb, 1); |
| 120 | 131 | if ((result = lapb_data_request(dev, skb)) != LAPB_OK) |
| 121 | 132 | dev_kfree_skb(skb); |
| 133 | + spin_unlock_bh(&x25st->up_lock); | |
| 122 | 134 | return NETDEV_TX_OK; |
| 123 | 135 | |
| 124 | 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 | 159 | break; |
| 148 | 160 | } |
| 149 | 161 | |
| 162 | + spin_unlock_bh(&x25st->up_lock); | |
| 150 | 163 | dev_kfree_skb(skb); |
| 151 | 164 | return NETDEV_TX_OK; |
| 152 | 165 | } |
| @@ -164,6 +177,7 @@ static int x25_open(struct net_device *dev) · 11 unmodified lines | ||
| 164 | 177 | .data_transmit = x25_data_transmit, |
| 165 | 178 | }; |
| 166 | 179 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 180 | + struct x25_state *x25st = state(hdlc); | |
| 167 | 181 | struct lapb_parms_struct params; |
| 168 | 182 | int result; |
| 169 | 183 | |
| @@ -190,6 +204,10 @@ static int x25_open(struct net_device *dev) · 20 unmodified lines | ||
| 190 | 204 | if (result != LAPB_OK) |
| 191 | 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 | 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 | 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 | 225 | lapb_unregister(dev); |
| 201 | 226 | } |
| 202 | 227 | |
| @@ -205,15 +230,28 @@ static void x25_close(struct net_device *dev) · 2 unmodified lines | ||
| 205 | 230 | static int x25_rx(struct sk_buff *skb) |
| 206 | 231 | { |
| 207 | 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 | 236 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
| 210 | 237 | dev->stats.rx_dropped++; |
| 211 | 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 | 251 | return NET_RX_SUCCESS; |
| 252 | + } | |
| 216 | 253 | |
| 254 | + spin_unlock_bh(&x25st->up_lock); | |
| 217 | 255 | dev->stats.rx_errors++; |
| 218 | 256 | dev_kfree_skb_any(skb); |
| 219 | 257 | return NET_RX_DROP; |
| @@ -298,6 +336,8 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) · 78 unmodified lines | ||
| 298 | 336 | return result; |
| 299 | 337 | |
| 300 | 338 | memcpy(&state(hdlc)->settings, &new_settings, size); |
| 339 | + state(hdlc)->up = false; | |
| 340 | + spin_lock_init(&state(hdlc)->up_lock); | |
| 301 | 341 | |
| 302 | 342 | /* There's no header_ops so hard_header_len should be 0. */ |
| 303 | 343 | dev->hard_header_len = 0; |
| @@ -1357,6 +1357,7 @@ static int intel_pinctrl_add_padgroups_by_gpps(struct intel_pinctrl *pctrl, · 1356 unmodified lines | ||
| 1357 | 1357 | gpps[i].gpio_base = 0; |
| 1358 | 1358 | break; |
| 1359 | 1359 | case INTEL_GPIO_BASE_NOMAP: |
| 1360 | + break; | |
| 1360 | 1361 | default: |
| 1361 | 1362 | break; |
| 1362 | 1363 | } |
| @@ -1393,6 +1394,7 @@ static int intel_pinctrl_add_padgroups_by_size(struct intel_pinctrl *pctrl, · 30 unmodified lines | ||
| 1393 | 1394 | gpps[i].size = min(gpp_size, npins); |
| 1394 | 1395 | npins -= gpps[i].size; |
| 1395 | 1396 | |
| 1397 | + gpps[i].gpio_base = gpps[i].base; | |
| 1396 | 1398 | gpps[i].padown_num = padown_num; |
| 1397 | 1399 | |
| 1398 | 1400 | /* |
| @@ -1491,8 +1493,13 @@ static int intel_pinctrl_probe(struct platform_device *pdev, · 92 unmodified lines | ||
| 1491 | 1493 | if (IS_ERR(regs)) |
| 1492 | 1494 | return PTR_ERR(regs); |
| 1493 | 1495 | |
| 1494 | − /* Determine community features based on the revision */ | |
| 1496 | + /* | |
| 1497 | + * Determine community features based on the revision. | |
| 1498 | + * A value of all ones means the device is not present. | |
| 1499 | + */ | |
| 1495 | 1500 | value = readl(regs + REVID); |
| 1501 | + if (value == ~0u) | |
| 1502 | + return -ENODEV; | |
| 1496 | 1503 | if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) { |
| 1497 | 1504 | community->features |= PINCTRL_FEATURE_DEBOUNCE; |
| 1498 | 1505 | community->features |= PINCTRL_FEATURE_1K_PD; |
| @@ -572,7 +572,7 @@ static void microchip_sgpio_irq_settype(struct irq_data *data, · 571 unmodified lines | ||
| 572 | 572 | /* Type value spread over 2 registers sets: low, high bit */ |
| 573 | 573 | sgpio_clrsetbits(bank->priv, REG_INT_TRIGGER, addr.bit, |
| 574 | 574 | BIT(addr.port), (!!(type & 0x1)) << addr.port); |
| 575 | − sgpio_clrsetbits(bank->priv, REG_INT_TRIGGER + SGPIO_MAX_BITS, addr.bit, | |
| 575 | + sgpio_clrsetbits(bank->priv, REG_INT_TRIGGER, SGPIO_MAX_BITS + addr.bit, | |
| 576 | 576 | BIT(addr.port), (!!(type & 0x2)) << addr.port); |
| 577 | 577 | |
| 578 | 578 | if (type == SGPIO_INT_TRG_LEVEL) |
| @@ -3727,12 +3727,15 @@ static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) · 3726 unmodified lines | ||
| 3727 | 3727 | static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) |
| 3728 | 3728 | { |
| 3729 | 3729 | struct rockchip_pinctrl *info = dev_get_drvdata(dev); |
| 3730 | − int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, | |
| 3731 | − rk3288_grf_gpio6c_iomux | | |
| 3732 | − GPIO6C6_SEL_WRITE_ENABLE); | |
| 3730 | + int ret; | |
| 3733 | 3731 | |
| 3734 | − if (ret) | |
| 3735 | − return ret; | |
| 3732 | + if (info->ctrl->type == RK3288) { | |
| 3733 | + ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, | |
| 3734 | + rk3288_grf_gpio6c_iomux | | |
| 3735 | + GPIO6C6_SEL_WRITE_ENABLE); | |
| 3736 | + if (ret) | |
| 3737 | + return ret; | |
| 3738 | + } | |
| 3736 | 3739 | |
| 3737 | 3740 | return pinctrl_force_default(info->pctl_dev); |
| 3738 | 3741 | } |
| @@ -392,7 +392,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, · 391 unmodified lines | ||
| 392 | 392 | unsigned long *configs, unsigned int nconfs) |
| 393 | 393 | { |
| 394 | 394 | struct lpi_pinctrl *pctrl = dev_get_drvdata(pctldev->dev); |
| 395 | − unsigned int param, arg, pullup, strength; | |
| 395 | + unsigned int param, arg, pullup = LPI_GPIO_BIAS_DISABLE, strength = 2; | |
| 396 | 396 | bool value, output_enabled = false; |
| 397 | 397 | const struct lpi_pingroup *g; |
| 398 | 398 | unsigned long sval; |
| @@ -1439,14 +1439,14 @@ static const struct msm_pingroup sc7280_groups[] = { · 1438 unmodified lines | ||
| 1439 | 1439 | [172] = PINGROUP(172, qdss, _, _, _, _, _, _, _, _), |
| 1440 | 1440 | [173] = PINGROUP(173, qdss, _, _, _, _, _, _, _, _), |
| 1441 | 1441 | [174] = PINGROUP(174, qdss, _, _, _, _, _, _, _, _), |
| 1442 | − [175] = UFS_RESET(ufs_reset, 0x1be000), | |
| 1443 | − [176] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x1b3000, 15, 0), | |
| 1444 | − [177] = SDC_QDSD_PINGROUP(sdc1_clk, 0x1b3000, 13, 6), | |
| 1445 | − [178] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x1b3000, 11, 3), | |
| 1446 | − [179] = SDC_QDSD_PINGROUP(sdc1_data, 0x1b3000, 9, 0), | |
| 1447 | − [180] = SDC_QDSD_PINGROUP(sdc2_clk, 0x1b4000, 14, 6), | |
| 1448 | − [181] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x1b4000, 11, 3), | |
| 1449 | − [182] = SDC_QDSD_PINGROUP(sdc2_data, 0x1b4000, 9, 0), | |
| 1442 | + [175] = UFS_RESET(ufs_reset, 0xbe000), | |
| 1443 | + [176] = SDC_QDSD_PINGROUP(sdc1_rclk, 0xb3004, 0, 6), | |
| 1444 | + [177] = SDC_QDSD_PINGROUP(sdc1_clk, 0xb3000, 13, 6), | |
| 1445 | + [178] = SDC_QDSD_PINGROUP(sdc1_cmd, 0xb3000, 11, 3), | |
| 1446 | + [179] = SDC_QDSD_PINGROUP(sdc1_data, 0xb3000, 9, 0), | |
| 1447 | + [180] = SDC_QDSD_PINGROUP(sdc2_clk, 0xb4000, 14, 6), | |
| 1448 | + [181] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xb4000, 11, 3), | |
| 1449 | + [182] = SDC_QDSD_PINGROUP(sdc2_data, 0xb4000, 9, 0), | |
| 1450 | 1450 | }; |
| 1451 | 1451 | |
| 1452 | 1452 | static const struct msm_pinctrl_soc_data sc7280_pinctrl = { |
| @@ -423,7 +423,7 @@ static const char * const gpio_groups[] = { · 422 unmodified lines | ||
| 423 | 423 | |
| 424 | 424 | static const char * const qdss_stm_groups[] = { |
| 425 | 425 | "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio12", "gpio13", |
| 426 | − "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19" "gpio20", "gpio21", "gpio22", | |
| 426 | + "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", | |
| 427 | 427 | "gpio23", "gpio44", "gpio45", "gpio52", "gpio53", "gpio56", "gpio57", "gpio61", "gpio62", |
| 428 | 428 | "gpio63", "gpio64", "gpio65", "gpio66", |
| 429 | 429 | }; |
| @@ -1173,15 +1173,20 @@ config INTEL_PMC_CORE · 1172 unmodified lines | ||
| 1173 | 1173 | depends on PCI |
| 1174 | 1174 | help |
| 1175 | 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 | 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 | 1182 | Supported features: |
| 1181 | 1183 | - SLP_S0_RESIDENCY counter |
| 1182 | 1184 | - PCH IP Power Gating status |
| 1183 | − - LTR Ignore | |
| 1185 | + - LTR Ignore / LTR Show | |
| 1184 | 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 | 1191 | config INTEL_PMT_CLASS |
| 1187 | 1192 | tristate |
| @@ -185,5 +185,8 @@ void exit_enum_attributes(void) · 184 unmodified lines | ||
| 185 | 185 | sysfs_remove_group(wmi_priv.enumeration_data[instance_id].attr_name_kobj, |
| 186 | 186 | &enumeration_attr_group); |
| 187 | 187 | } |
| 188 | + wmi_priv.enumeration_instances_count = 0; | |
| 189 | + | |
| 188 | 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 | 175 | sysfs_remove_group(wmi_priv.integer_data[instance_id].attr_name_kobj, |
| 176 | 176 | &integer_attr_group); |
| 177 | 177 | } |
| 178 | + wmi_priv.integer_instances_count = 0; | |
| 179 | + | |
| 178 | 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 | 183 | sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj, |
| 184 | 184 | &po_attr_group); |
| 185 | 185 | } |
| 186 | + wmi_priv.po_instances_count = 0; | |
| 187 | + | |
| 186 | 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 | 155 | sysfs_remove_group(wmi_priv.str_data[instance_id].attr_name_kobj, |
| 156 | 156 | &str_attr_group); |
| 157 | 157 | } |
| 158 | + wmi_priv.str_instances_count = 0; | |
| 159 | + | |
| 158 | 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 | 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) { | |
| 216 | − pr_debug("could not create reset_bios file\n"); | |
| 215 | + ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); | |
| 216 | + if (ret) | |
| 217 | 217 | return ret; |
| 218 | − } | |
| 219 | 218 | |
| 220 | 219 | ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); |
| 221 | − if (ret) { | |
| 222 | − pr_debug("could not create changing_pending_reboot file\n"); | |
| 223 | − sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); | |
| 224 | − } | |
| 225 | − return ret; | |
| 226 | −} | |
| 220 | + if (ret) | |
| 221 | + return ret; | |
| 227 | 222 | |
| 228 | −static void release_reset_bios_data(void) | |
| 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); | |
| 223 | + return 0; | |
| 232 | 224 | } |
| 233 | 225 | |
| 234 | 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 | 366 | static void release_attributes_data(void) |
| 375 | 367 | { |
| 376 | − release_reset_bios_data(); | |
| 377 | − | |
| 378 | 368 | mutex_lock(&wmi_priv.mutex); |
| 379 | 369 | exit_enum_attributes(); |
| 380 | 370 | exit_int_attributes(); |
| @@ -386,11 +376,13 @@ static void release_attributes_data(void) · 5 unmodified lines | ||
| 386 | 376 | wmi_priv.authentication_dir_kset = NULL; |
| 387 | 377 | } |
| 388 | 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 | 381 | destroy_attribute_objs(wmi_priv.main_dir_kset); |
| 390 | 382 | kset_unregister(wmi_priv.main_dir_kset); |
| 383 | + wmi_priv.main_dir_kset = NULL; | |
| 391 | 384 | } |
| 392 | 385 | mutex_unlock(&wmi_priv.mutex); |
| 393 | − | |
| 394 | 386 | } |
| 395 | 387 | |
| 396 | 388 | /** |
| @@ -497,7 +489,6 @@ nextobj: · 100 unmodified lines | ||
| 497 | 489 | |
| 498 | 490 | err_attr_init: |
| 499 | 491 | mutex_unlock(&wmi_priv.mutex); |
| 500 | − release_attributes_data(); | |
| 501 | 492 | kfree(obj); |
| 502 | 493 | return retval; |
| 503 | 494 | } |
| @@ -513,102 +504,91 @@ static int __init sysman_init(void) · 9 unmodified lines | ||
| 513 | 504 | } |
| 514 | 505 | |
| 515 | 506 | ret = init_bios_attr_set_interface(); |
| 516 | − if (ret || !wmi_priv.bios_attr_wdev) { | |
| 517 | − pr_debug("failed to initialize set interface\n"); | |
| 518 | − goto fail_set_interface; | |
| 519 | − } | |
| 507 | + if (ret) | |
| 508 | + return ret; | |
| 520 | 509 | |
| 521 | 510 | ret = init_bios_attr_pass_interface(); |
| 522 | − if (ret || !wmi_priv.password_attr_wdev) { | |
| 523 | − pr_debug("failed to initialize pass interface\n"); | |
| 524 | − goto fail_pass_interface; | |
| 511 | + if (ret) | |
| 512 | + goto err_exit_bios_attr_set_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 | 520 | ret = class_register(&firmware_attributes_class); |
| 528 | 521 | if (ret) |
| 529 | − goto fail_class; | |
| 522 | + goto err_exit_bios_attr_pass_interface; | |
| 530 | 523 | |
| 531 | 524 | wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), |
| 532 | 525 | NULL, "%s", DRIVER_NAME); |
| 533 | 526 | if (IS_ERR(wmi_priv.class_dev)) { |
| 534 | 527 | ret = PTR_ERR(wmi_priv.class_dev); |
| 535 | − goto fail_classdev; | |
| 528 | + goto err_unregister_class; | |
| 536 | 529 | } |
| 537 | 530 | |
| 538 | 531 | wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL, |
| 539 | 532 | &wmi_priv.class_dev->kobj); |
| 540 | 533 | if (!wmi_priv.main_dir_kset) { |
| 541 | 534 | ret = -ENOMEM; |
| 542 | − goto fail_main_kset; | |
| 535 | + goto err_destroy_classdev; | |
| 543 | 536 | } |
| 544 | 537 | |
| 545 | 538 | wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL, |
| 546 | 539 | &wmi_priv.class_dev->kobj); |
| 547 | 540 | if (!wmi_priv.authentication_dir_kset) { |
| 548 | 541 | ret = -ENOMEM; |
| 549 | − goto fail_authentication_kset; | |
| 542 | + goto err_release_attributes_data; | |
| 550 | 543 | } |
| 551 | 544 | |
| 552 | 545 | ret = create_attributes_level_sysfs_files(); |
| 553 | 546 | if (ret) { |
| 554 | 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 | 551 | ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); |
| 559 | 552 | if (ret) { |
| 560 | 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 | 557 | ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); |
| 565 | 558 | if (ret) { |
| 566 | 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 | 563 | ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); |
| 571 | 564 | if (ret) { |
| 572 | 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 | 569 | ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); |
| 577 | 570 | if (ret) { |
| 578 | 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 | 575 | return 0; |
| 583 | 576 | |
| 584 | −fail_create_group: | |
| 577 | +err_release_attributes_data: | |
| 585 | 578 | release_attributes_data(); |
| 586 | 579 | |
| 587 | −fail_reset_bios: | |
| 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: | |
| 580 | +err_destroy_classdev: | |
| 600 | 581 | device_destroy(&firmware_attributes_class, MKDEV(0, 0)); |
| 601 | 582 | |
| 602 | −fail_classdev: | |
| 583 | +err_unregister_class: | |
| 603 | 584 | class_unregister(&firmware_attributes_class); |
| 604 | 585 | |
| 605 | −fail_class: | |
| 586 | +err_exit_bios_attr_pass_interface: | |
| 606 | 587 | exit_bios_attr_pass_interface(); |
| 607 | 588 | |
| 608 | −fail_pass_interface: | |
| 589 | +err_exit_bios_attr_set_interface: | |
| 609 | 590 | exit_bios_attr_set_interface(); |
| 610 | 591 | |
| 611 | −fail_set_interface: | |
| 612 | 592 | return ret; |
| 613 | 593 | } |
| 614 | 594 | |
| @@ -90,6 +90,13 @@ static const struct dmi_system_id button_array_table[] = { · 89 unmodified lines | ||
| 90 | 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 | 50 | static const struct key_entry intel_vbtn_switchmap[] = { |
| 51 | − { KE_SW, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ | |
| 52 | − { KE_SW, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ | |
| 51 | + /* | |
| 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 | 61 | { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ |
| 54 | 62 | { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ |
| 55 | 63 | { KE_END } |
| @@ -863,34 +863,45 @@ out_unlock: · 862 unmodified lines | ||
| 863 | 863 | } |
| 864 | 864 | DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); |
| 865 | 865 | |
| 866 | −static ssize_t pmc_core_ltr_ignore_write(struct file *file, | |
| 867 | − const char __user *userbuf, | |
| 868 | − size_t count, loff_t *ppos) | |
| 866 | +static int pmc_core_send_ltr_ignore(u32 value) | |
| 869 | 867 | { |
| 870 | 868 | struct pmc_dev *pmcdev = &pmc; |
| 871 | 869 | const struct pmc_reg_map *map = pmcdev->map; |
| 872 | − u32 val, buf_size, fd; | |
| 873 | − int err; | |
| 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; | |
| 870 | + u32 reg; | |
| 871 | + int err = 0; | |
| 880 | 872 | |
| 881 | 873 | mutex_lock(&pmcdev->lock); |
| 882 | 874 | |
| 883 | − if (val > map->ltr_ignore_max) { | |
| 875 | + if (value > map->ltr_ignore_max) { | |
| 884 | 876 | err = -EINVAL; |
| 885 | 877 | goto out_unlock; |
| 886 | 878 | } |
| 887 | 879 | |
| 888 | − fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); | |
| 889 | − fd |= (1U << val); | |
| 890 | − pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd); | |
| 880 | + reg = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); | |
| 881 | + reg |= BIT(value); | |
| 882 | + pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, reg); | |
| 891 | 883 | |
| 892 | 884 | out_unlock: |
| 893 | 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 | 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 | 1255 | pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); |
| 1245 | 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 | 1267 | pmc_core_dbgfs_register(pmcdev); |
| 1248 | 1268 | |
| 1249 | 1269 | device_initialized = true; |
| @@ -173,7 +173,7 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry, · 172 unmodified lines | ||
| 173 | 173 | struct intel_pmt_namespace *ns, |
| 174 | 174 | struct device *parent) |
| 175 | 175 | { |
| 176 | − struct resource res; | |
| 176 | + struct resource res = {0}; | |
| 177 | 177 | struct device *dev; |
| 178 | 178 | int ret; |
| 179 | 179 | |
| @@ -23,18 +23,17 @@ · 22 unmodified lines | ||
| 23 | 23 | #define CRASH_TYPE_OOBMSM 1 |
| 24 | 24 | |
| 25 | 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. | |
| 32 | − * Bit 29 will immediately trigger a crashlog to be generated, setting bit 31. | |
| 33 | − * Bit 30 is read-only and reserved as 0. | |
| 31 | + * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured. | |
| 32 | + * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31. | |
| 34 | 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) | |
| 37 | −#define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(29) | |
| 35 | +#define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(29) | |
| 36 | +#define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(30) | |
| 38 | 37 | #define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31) |
| 39 | 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 | 4082 | case TP_HKEY_EV_KEY_NUMLOCK: |
| 4083 | 4083 | case TP_HKEY_EV_KEY_FN: |
| 4084 | − case TP_HKEY_EV_KEY_FN_ESC: | |
| 4085 | 4084 | /* key press events, we just ignore them as long as the EC |
| 4086 | 4085 | * is still reporting them in the normal keyboard stream */ |
| 4087 | 4086 | *send_acpi_ev = false; |
| 4088 | 4087 | *ignore_acpi_ev = true; |
| 4089 | 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 | 4097 | case TP_HKEY_EV_TABLET_CHANGED: |
| 4092 | 4098 | tpacpi_input_send_tabletsw(); |
| 4093 | 4099 | hotkey_tablet_mode_notify_change(); |
| @@ -9845,6 +9851,11 @@ static struct ibm_struct lcdshadow_driver_data = { · 5751 unmodified lines | ||
| 9845 | 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 | 9859 | #define DYTC_CMD_GET 2 /* To get current IC function and mode */ |
| 9849 | 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 | 9866 | static bool has_lapsensor; |
| 9856 | 9867 | static bool palm_state; |
| 9857 | 9868 | static bool lap_state; |
| 9869 | +static int dytc_version; | |
| 9858 | 9870 | |
| 9859 | 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 | 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 | 9911 | static int lapsensor_get(bool *present, bool *state) |
| 9873 | 9912 | { |
| 9874 | 9913 | int output, err; |
| @@ -9974,7 +10013,18 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) · 99 unmodified lines | ||
| 9974 | 10013 | if (err) |
| 9975 | 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 | 10028 | err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); |
| 9979 | 10029 | if (err) |
| 9980 | 10030 | return err; |
| @@ -9999,14 +10049,9 @@ static struct ibm_struct proxsensor_driver_data = { · 18 unmodified lines | ||
| 9999 | 10049 | * DYTC Platform Profile interface |
| 10000 | 10050 | */ |
| 10001 | 10051 | |
| 10002 | −#define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ | |
| 10003 | 10052 | #define DYTC_CMD_SET 1 /* To enable/disable IC function mode */ |
| 10004 | 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 | 10055 | #define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */ |
| 10011 | 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 | 10187 | return err; |
| 10143 | 10188 | |
| 10144 | 10189 | if (profile == PLATFORM_PROFILE_BALANCED) { |
| 10145 | − /* To get back to balanced mode we just issue a reset command */ | |
| 10146 | − err = dytc_command(DYTC_CMD_RESET, &output); | |
| 10190 | + /* | |
| 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 | 10197 | if (err) |
| 10148 | 10198 | goto unlock; |
| 10149 | 10199 | } else { |
| @@ -10211,28 +10261,28 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) · 61 unmodified lines | ||
| 10211 | 10261 | if (err) |
| 10212 | 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 | 10270 | /* Check DYTC is enabled and supports mode setting */ |
| 10215 | − if (output & BIT(DYTC_QUERY_ENABLE_BIT)) { | |
| 10216 | − /* Only DYTC v5.0 and later has this feature. */ | |
| 10217 | − int dytc_version; | |
| 10218 | − | |
| 10219 | − dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; | |
| 10220 | − if (dytc_version >= 5) { | |
| 10221 | − dbg_printk(TPACPI_DBG_INIT, | |
| 10222 | − "DYTC version %d: thermal mode available\n", dytc_version); | |
| 10223 | − /* Create platform_profile structure and register */ | |
| 10224 | − err = platform_profile_register(&dytc_profile); | |
| 10225 | − /* | |
| 10226 | − * If for some reason platform_profiles aren't enabled | |
| 10227 | − * don't quit terminally. | |
| 10228 | − */ | |
| 10229 | − if (err) | |
| 10230 | − return 0; | |
| 10271 | + if (dytc_version >= 5) { | |
| 10272 | + dbg_printk(TPACPI_DBG_INIT, | |
| 10273 | + "DYTC version %d: thermal mode available\n", dytc_version); | |
| 10274 | + /* Create platform_profile structure and register */ | |
| 10275 | + err = platform_profile_register(&dytc_profile); | |
| 10276 | + /* | |
| 10277 | + * If for some reason platform_profiles aren't enabled | |
| 10278 | + * don't quit terminally. | |
| 10279 | + */ | |
| 10280 | + if (err) | |
| 10281 | + return 0; | |
| 10231 | 10282 | |
| 10232 | − dytc_profile_available = true; | |
| 10233 | − /* Ensure initial values are correct */ | |
| 10234 | − dytc_profile_refresh(); | |
| 10235 | − } | |
| 10283 | + dytc_profile_available = true; | |
| 10284 | + /* Ensure initial values are correct */ | |
| 10285 | + dytc_profile_refresh(); | |
| 10236 | 10286 | } |
| 10237 | 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 | 189 | tmr_add = ptp_qoriq->tmr_add; |
| 190 | 190 | adj = tmr_add; |
| 191 | 191 | |
| 192 | − /* calculate diff as adj*(scaled_ppm/65536)/1000000 | |
| 193 | − * and round() to the nearest integer | |
| 192 | + /* | |
| 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; | |
| 196 | − diff = div_u64(adj, 8000000); | |
| 197 | − diff = (diff >> 13) + ((diff >> 12) & 1); | |
| 198 | + diff = mul_u64_u64_div_u64(adj, scaled_ppm, 32768000000); | |
| 199 | + diff = DIV64_U64_ROUND_UP(diff, 2); | |
| 198 | 200 | |
| 199 | 201 | tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; |
| 200 | − | |
| 201 | 202 | ptp_qoriq->write(®s->ctrl_regs->tmr_add, tmr_add); |
| 202 | 203 | |
| 203 | 204 | return 0; |
| @@ -2371,6 +2371,24 @@ static int ibmvfc_match_lun(struct ibmvfc_event *evt, void *device) · 2370 unmodified lines | ||
| 2371 | 2371 | return 0; |
| 2372 | 2372 | } |
| 2373 | 2373 | |
| 2374 | +/** | |
| 2375 | + * ibmvfc_event_is_free - Check if event is free or not | |
| 2376 | + * @evt: ibmvfc event struct | |
| 2377 | + * | |
| 2378 | + * Returns: | |
| 2379 | + * true / false | |
| 2380 | + **/ | |
| 2381 | +static bool ibmvfc_event_is_free(struct ibmvfc_event *evt) | |
| 2382 | +{ | |
| 2383 | + struct ibmvfc_event *loop_evt; | |
| 2384 | + | |
| 2385 | + list_for_each_entry(loop_evt, &evt->queue->free, queue_list) | |
| 2386 | + if (loop_evt == evt) | |
| 2387 | + return true; | |
| 2388 | + | |
| 2389 | + return false; | |
| 2390 | +} | |
| 2391 | + | |
| 2374 | 2392 | /** |
| 2375 | 2393 | * ibmvfc_wait_for_ops - Wait for ops to complete |
| 2376 | 2394 | * @vhost: ibmvfc host struct |
| @@ -2385,35 +2403,58 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device, · 8 unmodified lines | ||
| 2385 | 2403 | { |
| 2386 | 2404 | struct ibmvfc_event *evt; |
| 2387 | 2405 | DECLARE_COMPLETION_ONSTACK(comp); |
| 2388 | − int wait; | |
| 2406 | + int wait, i, q_index, q_size; | |
| 2389 | 2407 | unsigned long flags; |
| 2390 | 2408 | signed long timeout = IBMVFC_ABORT_WAIT_TIMEOUT * HZ; |
| 2409 | + struct ibmvfc_queue *queues; | |
| 2391 | 2410 | |
| 2392 | 2411 | ENTER; |
| 2412 | + if (vhost->mq_enabled && vhost->using_channels) { | |
| 2413 | + queues = vhost->scsi_scrqs.scrqs; | |
| 2414 | + q_size = vhost->scsi_scrqs.active_queues; | |
| 2415 | + } else { | |
| 2416 | + queues = &vhost->crq; | |
| 2417 | + q_size = 1; | |
| 2418 | + } | |
| 2419 | + | |
| 2393 | 2420 | do { |
| 2394 | 2421 | wait = 0; |
| 2395 | − spin_lock_irqsave(&vhost->crq.l_lock, flags); | |
| 2396 | − list_for_each_entry(evt, &vhost->crq.sent, queue_list) { | |
| 2397 | − if (match(evt, device)) { | |
| 2398 | − evt->eh_comp = ∁ | |
| 2399 | − wait++; | |
| 2422 | + spin_lock_irqsave(vhost->host->host_lock, flags); | |
| 2423 | + for (q_index = 0; q_index < q_size; q_index++) { | |
| 2424 | + spin_lock(&queues[q_index].l_lock); | |
| 2425 | + for (i = 0; i < queues[q_index].evt_pool.size; i++) { | |
| 2426 | + evt = &queues[q_index].evt_pool.events[i]; | |
| 2427 | + if (!ibmvfc_event_is_free(evt)) { | |
| 2428 | + if (match(evt, device)) { | |
| 2429 | + evt->eh_comp = ∁ | |
| 2430 | + wait++; | |
| 2431 | + } | |
| 2432 | + } | |
| 2400 | 2433 | } |
| 2434 | + spin_unlock(&queues[q_index].l_lock); | |
| 2401 | 2435 | } |
| 2402 | − spin_unlock_irqrestore(&vhost->crq.l_lock, flags); | |
| 2436 | + spin_unlock_irqrestore(vhost->host->host_lock, flags); | |
| 2403 | 2437 | |
| 2404 | 2438 | if (wait) { |
| 2405 | 2439 | timeout = wait_for_completion_timeout(&comp, timeout); |
| 2406 | 2440 | |
| 2407 | 2441 | if (!timeout) { |
| 2408 | 2442 | wait = 0; |
| 2409 | − spin_lock_irqsave(&vhost->crq.l_lock, flags); | |
| 2410 | − list_for_each_entry(evt, &vhost->crq.sent, queue_list) { | |
| 2411 | − if (match(evt, device)) { | |
| 2412 | − evt->eh_comp = NULL; | |
| 2413 | − wait++; | |
| 2443 | + spin_lock_irqsave(vhost->host->host_lock, flags); | |
| 2444 | + for (q_index = 0; q_index < q_size; q_index++) { | |
| 2445 | + spin_lock(&queues[q_index].l_lock); | |
| 2446 | + for (i = 0; i < queues[q_index].evt_pool.size; i++) { | |
| 2447 | + evt = &queues[q_index].evt_pool.events[i]; | |
| 2448 | + if (!ibmvfc_event_is_free(evt)) { | |
| 2449 | + if (match(evt, device)) { | |
| 2450 | + evt->eh_comp = NULL; | |
| 2451 | + wait++; | |
| 2452 | + } | |
| 2453 | + } | |
| 2414 | 2454 | } |
| 2455 | + spin_unlock(&queues[q_index].l_lock); | |
| 2415 | 2456 | } |
| 2416 | − spin_unlock_irqrestore(&vhost->crq.l_lock, flags); | |
| 2457 | + spin_unlock_irqrestore(vhost->host->host_lock, flags); | |
| 2417 | 2458 | if (wait) |
| 2418 | 2459 | dev_err(vhost->dev, "Timed out waiting for aborted commands\n"); |
| 2419 | 2460 | LEAVE; |
| @@ -7806,14 +7806,18 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) · 7805 unmodified lines | ||
| 7806 | 7806 | ioc->pend_os_device_add_sz++; |
| 7807 | 7807 | ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, |
| 7808 | 7808 | GFP_KERNEL); |
| 7809 | − if (!ioc->pend_os_device_add) | |
| 7809 | + if (!ioc->pend_os_device_add) { | |
| 7810 | + r = -ENOMEM; | |
| 7810 | 7811 | goto out_free_resources; |
| 7812 | + } | |
| 7811 | 7813 | |
| 7812 | 7814 | ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz; |
| 7813 | 7815 | ioc->device_remove_in_progress = |
| 7814 | 7816 | kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL); |
| 7815 | − if (!ioc->device_remove_in_progress) | |
| 7817 | + if (!ioc->device_remove_in_progress) { | |
| 7818 | + r = -ENOMEM; | |
| 7816 | 7819 | goto out_free_resources; |
| 7820 | + } | |
| 7817 | 7821 | |
| 7818 | 7822 | ioc->fwfault_debug = mpt3sas_fwfault_debug; |
| 7819 | 7823 | |
| @@ -1675,6 +1675,7 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi) · 1674 unmodified lines | ||
| 1675 | 1675 | if (!qedi->global_queues[i]) { |
| 1676 | 1676 | QEDI_ERR(&qedi->dbg_ctx, |
| 1677 | 1677 | "Unable to allocation global queue %d.\n", i); |
| 1678 | + status = -ENOMEM; | |
| 1678 | 1679 | goto mem_alloc_failure; |
| 1679 | 1680 | } |
| 1680 | 1681 | |
| @@ -3222,8 +3222,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, · 3221 unmodified lines | ||
| 3222 | 3222 | if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || |
| 3223 | 3223 | (cmd->sess && cmd->sess->deleted)) { |
| 3224 | 3224 | cmd->state = QLA_TGT_STATE_PROCESSED; |
| 3225 | − res = 0; | |
| 3226 | − goto free; | |
| 3225 | + return 0; | |
| 3227 | 3226 | } |
| 3228 | 3227 | |
| 3229 | 3228 | ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018, |
| @@ -3234,8 +3233,9 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, · 4 unmodified lines | ||
| 3234 | 3233 | |
| 3235 | 3234 | res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, |
| 3236 | 3235 | &full_req_cnt); |
| 3237 | − if (unlikely(res != 0)) | |
| 3238 | − goto free; | |
| 3236 | + if (unlikely(res != 0)) { | |
| 3237 | + return res; | |
| 3238 | + } | |
| 3239 | 3239 | |
| 3240 | 3240 | spin_lock_irqsave(qpair->qp_lock_ptr, flags); |
| 3241 | 3241 | |
| @@ -3255,8 +3255,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, · 13 unmodified lines | ||
| 3255 | 3255 | vha->flags.online, qla2x00_reset_active(vha), |
| 3256 | 3256 | cmd->reset_count, qpair->chip_reset); |
| 3257 | 3257 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); |
| 3258 | − res = 0; | |
| 3259 | − goto free; | |
| 3258 | + return 0; | |
| 3260 | 3259 | } |
| 3261 | 3260 | |
| 3262 | 3261 | /* Does F/W have an IOCBs for this request */ |
| @@ -3359,8 +3358,6 @@ out_unmap_unlock: · 96 unmodified lines | ||
| 3359 | 3358 | qlt_unmap_sg(vha, cmd); |
| 3360 | 3359 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); |
| 3361 | 3360 | |
| 3362 | −free: | |
| 3363 | − vha->hw->tgt.tgt_ops->free_cmd(cmd); | |
| 3364 | 3361 | return res; |
| 3365 | 3362 | } |
| 3366 | 3363 | EXPORT_SYMBOL(qlt_xmit_response); |
| @@ -644,7 +644,6 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) · 643 unmodified lines | ||
| 644 | 644 | { |
| 645 | 645 | struct qla_tgt_cmd *cmd = container_of(se_cmd, |
| 646 | 646 | struct qla_tgt_cmd, se_cmd); |
| 647 | − struct scsi_qla_host *vha = cmd->vha; | |
| 648 | 647 | |
| 649 | 648 | if (cmd->aborted) { |
| 650 | 649 | /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task |
| @@ -657,7 +656,6 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) · 6 unmodified lines | ||
| 657 | 656 | cmd->se_cmd.transport_state, |
| 658 | 657 | cmd->se_cmd.t_state, |
| 659 | 658 | cmd->se_cmd.se_cmd_flags); |
| 660 | − vha->hw->tgt.tgt_ops->free_cmd(cmd); | |
| 661 | 659 | return 0; |
| 662 | 660 | } |
| 663 | 661 | |
| @@ -685,7 +683,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) · 21 unmodified lines | ||
| 685 | 683 | { |
| 686 | 684 | struct qla_tgt_cmd *cmd = container_of(se_cmd, |
| 687 | 685 | struct qla_tgt_cmd, se_cmd); |
| 688 | − struct scsi_qla_host *vha = cmd->vha; | |
| 689 | 686 | int xmit_type = QLA_TGT_XMIT_STATUS; |
| 690 | 687 | |
| 691 | 688 | if (cmd->aborted) { |
| @@ -699,7 +696,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) · 7 unmodified lines | ||
| 699 | 696 | cmd, kref_read(&cmd->se_cmd.cmd_kref), |
| 700 | 697 | cmd->se_cmd.transport_state, cmd->se_cmd.t_state, |
| 701 | 698 | cmd->se_cmd.se_cmd_flags); |
| 702 | − vha->hw->tgt.tgt_ops->free_cmd(cmd); | |
| 703 | 699 | return 0; |
| 704 | 700 | } |
| 705 | 701 | cmd->bufflen = se_cmd->data_length; |
| @@ -2475,6 +2475,7 @@ static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag) · 2474 unmodified lines | ||
| 2475 | 2475 | */ |
| 2476 | 2476 | mutex_lock(&conn_mutex); |
| 2477 | 2477 | conn->transport->stop_conn(conn, flag); |
| 2478 | + conn->state = ISCSI_CONN_DOWN; | |
| 2478 | 2479 | mutex_unlock(&conn_mutex); |
| 2479 | 2480 | |
| 2480 | 2481 | } |
| @@ -2901,6 +2902,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) · 420 unmodified lines | ||
| 2901 | 2902 | default: |
| 2902 | 2903 | err = transport->set_param(conn, ev->u.set_param.param, |
| 2903 | 2904 | data, ev->u.set_param.len); |
| 2905 | + if ((conn->state == ISCSI_CONN_BOUND) || | |
| 2906 | + (conn->state == ISCSI_CONN_UP)) { | |
| 2907 | + err = transport->set_param(conn, ev->u.set_param.param, | |
| 2908 | + data, ev->u.set_param.len); | |
| 2909 | + } else { | |
| 2910 | + return -ENOTCONN; | |
| 2911 | + } | |
| 2904 | 2912 | } |
| 2905 | 2913 | |
| 2906 | 2914 | return err; |
| @@ -2960,6 +2968,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport, · 53 unmodified lines | ||
| 2960 | 2968 | mutex_lock(&conn->ep_mutex); |
| 2961 | 2969 | conn->ep = NULL; |
| 2962 | 2970 | mutex_unlock(&conn->ep_mutex); |
| 2971 | + conn->state = ISCSI_CONN_DOWN; | |
| 2963 | 2972 | } |
| 2964 | 2973 | |
| 2965 | 2974 | transport->ep_disconnect(ep); |
| @@ -3727,6 +3736,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) · 761 unmodified lines | ||
| 3727 | 3736 | ev->r.retcode = transport->bind_conn(session, conn, |
| 3728 | 3737 | ev->u.b_conn.transport_eph, |
| 3729 | 3738 | ev->u.b_conn.is_leading); |
| 3739 | + if (!ev->r.retcode) | |
| 3740 | + conn->state = ISCSI_CONN_BOUND; | |
| 3730 | 3741 | mutex_unlock(&conn_mutex); |
| 3731 | 3742 | |
| 3732 | 3743 | if (ev->r.retcode || !transport->ep_connect) |
| @@ -3966,7 +3977,8 @@ iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR); · 233 unmodified lines | ||
| 3966 | 3977 | static const char *const connection_state_names[] = { |
| 3967 | 3978 | [ISCSI_CONN_UP] = "up", |
| 3968 | 3979 | [ISCSI_CONN_DOWN] = "down", |
| 3969 | − [ISCSI_CONN_FAILED] = "failed" | |
| 3980 | + [ISCSI_CONN_FAILED] = "failed", | |
| 3981 | + [ISCSI_CONN_BOUND] = "bound" | |
| 3970 | 3982 | }; |
| 3971 | 3983 | |
| 3972 | 3984 | static ssize_t show_conn_state(struct device *dev, |
| @@ -13,7 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/platform_device.h> |
| 14 | 14 | #include <linux/printk.h> |
| 15 | 15 | #include <linux/module.h> |
| 16 | −#include <linux/errno.h> | |
| 17 | 16 | #include <linux/io.h> |
| 18 | 17 | #include <linux/reboot.h> |
| 19 | 18 | |
| @@ -3,7 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | #include <linux/acpi.h> |
| 5 | 5 | #include <linux/clk.h> |
| 6 | −#include <linux/console.h> | |
| 7 | 6 | #include <linux/slab.h> |
| 8 | 7 | #include <linux/dma-mapping.h> |
| 9 | 8 | #include <linux/io.h> |
| @@ -92,14 +91,11 @@ struct geni_wrapper { · 82 unmodified lines | ||
| 92 | 91 | struct device *dev; |
| 93 | 92 | void __iomem *base; |
| 94 | 93 | struct clk_bulk_data ahb_clks[NUM_AHB_CLKS]; |
| 95 | − struct geni_icc_path to_core; | |
| 96 | 94 | }; |
| 97 | 95 | |
| 98 | 96 | static const char * const icc_path_names[] = {"qup-core", "qup-config", |
| 99 | 97 | "qup-memory"}; |
| 100 | 98 | |
| 101 | −static struct geni_wrapper *earlycon_wrapper; | |
| 102 | − | |
| 103 | 99 | #define QUP_HW_VER_REG 0x4 |
| 104 | 100 | |
| 105 | 101 | /* Common SE registers */ |
| @@ -843,44 +839,11 @@ int geni_icc_disable(struct geni_se *se) · 737 unmodified lines | ||
| 843 | 839 | } |
| 844 | 840 | EXPORT_SYMBOL(geni_icc_disable); |
| 845 | 841 | |
| 846 | −void geni_remove_earlycon_icc_vote(void) | |
| 847 | −{ | |
| 848 | − struct platform_device *pdev; | |
| 849 | − struct geni_wrapper *wrapper; | |
| 850 | − struct device_node *parent; | |
| 851 | − struct device_node *child; | |
| 852 | − | |
| 853 | − if (!earlycon_wrapper) | |
| 854 | − return; | |
| 855 | − | |
| 856 | − wrapper = earlycon_wrapper; | |
| 857 | − parent = of_get_next_parent(wrapper->dev->of_node); | |
| 858 | − for_each_child_of_node(parent, child) { | |
| 859 | − if (!of_device_is_compatible(child, "qcom,geni-se-qup")) | |
| 860 | − continue; | |
| 861 | − | |
| 862 | − pdev = of_find_device_by_node(child); | |
| 863 | − if (!pdev) | |
| 864 | − continue; | |
| 865 | − | |
| 866 | − wrapper = platform_get_drvdata(pdev); | |
| 867 | − icc_put(wrapper->to_core.path); | |
| 868 | − wrapper->to_core.path = NULL; | |
| 869 | − | |
| 870 | − } | |
| 871 | − of_node_put(parent); | |
| 872 | − | |
| 873 | − earlycon_wrapper = NULL; | |
| 874 | −} | |
| 875 | −EXPORT_SYMBOL(geni_remove_earlycon_icc_vote); | |
| 876 | − | |
| 877 | 842 | static int geni_se_probe(struct platform_device *pdev) |
| 878 | 843 | { |
| 879 | 844 | struct device *dev = &pdev->dev; |
| 880 | 845 | struct resource *res; |
| 881 | 846 | struct geni_wrapper *wrapper; |
| 882 | − struct console __maybe_unused *bcon; | |
| 883 | − bool __maybe_unused has_earlycon = false; | |
| 884 | 847 | int ret; |
| 885 | 848 | |
| 886 | 849 | wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL); |
| @@ -903,43 +866,6 @@ static int geni_se_probe(struct platform_device *pdev) · 16 unmodified lines | ||
| 903 | 866 | } |
| 904 | 867 | } |
| 905 | 868 | |
| 906 | −#ifdef CONFIG_SERIAL_EARLYCON | |
| 907 | − for_each_console(bcon) { | |
| 908 | − if (!strcmp(bcon->name, "qcom_geni")) { | |
| 909 | − has_earlycon = true; | |
| 910 | − break; | |
| 911 | − } | |
| 912 | − } | |
| 913 | − if (!has_earlycon) | |
| 914 | − goto exit; | |
| 915 | − | |
| 916 | − wrapper->to_core.path = devm_of_icc_get(dev, "qup-core"); | |
| 917 | − if (IS_ERR(wrapper->to_core.path)) | |
| 918 | − return PTR_ERR(wrapper->to_core.path); | |
| 919 | − /* | |
| 920 | − * Put minmal BW request on core clocks on behalf of early console. | |
| 921 | − * The vote will be removed earlycon exit function. | |
| 922 | − * | |
| 923 | − * Note: We are putting vote on each QUP wrapper instead only to which | |
| 924 | − * earlycon is connected because QUP core clock of different wrapper | |
| 925 | − * share same voltage domain. If core1 is put to 0, then core2 will | |
| 926 | − * also run at 0, if not voted. Default ICC vote will be removed ASA | |
| 927 | − * we touch any of the core clock. | |
| 928 | − * core1 = core2 = max(core1, core2) | |
| 929 | − */ | |
| 930 | − ret = icc_set_bw(wrapper->to_core.path, GENI_DEFAULT_BW, | |
| 931 | − GENI_DEFAULT_BW); | |
| 932 | − if (ret) { | |
| 933 | − dev_err(&pdev->dev, "%s: ICC BW voting failed for core: %d\n", | |
| 934 | − __func__, ret); | |
| 935 | − return ret; | |
| 936 | − } | |
| 937 | − | |
| 938 | − if (of_get_compatible_child(pdev->dev.of_node, "qcom,geni-debug-uart")) | |
| 939 | − earlycon_wrapper = wrapper; | |
| 940 | − of_node_put(pdev->dev.of_node); | |
| 941 | −exit: | |
| 942 | −#endif | |
| 943 | 869 | dev_set_drvdata(dev, wrapper); |
| 944 | 870 | dev_dbg(dev, "GENI SE Driver probed\n"); |
| 945 | 871 | return devm_of_platform_populate(dev); |
| @@ -332,7 +332,7 @@ static const struct omap_prm_data dra7_prm_data[] = { · 331 unmodified lines | ||
| 332 | 332 | { |
| 333 | 333 | .name = "l3init", .base = 0x4ae07300, |
| 334 | 334 | .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon, |
| 335 | − .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012, | |
| 335 | + .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01, | |
| 336 | 336 | .clkdm_name = "pcie" |
| 337 | 337 | }, |
| 338 | 338 | { |
| @@ -830,8 +830,12 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev, · 491 unmodified lines | ||
| 830 | 830 | reset->prm->data->name, id); |
| 831 | 831 | |
| 832 | 832 | exit: |
| 833 | − if (reset->clkdm) | |
| 833 | + if (reset->clkdm) { | |
| 834 | + /* At least dra7 iva needs a delay before clkdm idle */ | |
| 835 | + if (has_rstst) | |
| 836 | + udelay(1); | |
| 834 | 837 | pdata->clkdm_allow_idle(reset->clkdm); |
| 838 | + } | |
| 835 | 839 | |
| 836 | 840 | return ret; |
| 837 | 841 | } |
| @@ -1105,7 +1105,7 @@ struct rtllib_network { · 1104 unmodified lines | ||
| 1105 | 1105 | bool bWithAironetIE; |
| 1106 | 1106 | bool bCkipSupported; |
| 1107 | 1107 | bool bCcxRmEnable; |
| 1108 | − u16 CcxRmState[2]; | |
| 1108 | + u8 CcxRmState[2]; | |
| 1109 | 1109 | bool bMBssidValid; |
| 1110 | 1110 | u8 MBssidMask; |
| 1111 | 1111 | u8 MBssid[ETH_ALEN]; |
| @@ -1967,7 +1967,7 @@ static void rtllib_parse_mife_generic(struct rtllib_device *ieee, · 1966 unmodified lines | ||
| 1967 | 1967 | info_element->data[2] == 0x96 && |
| 1968 | 1968 | info_element->data[3] == 0x01) { |
| 1969 | 1969 | if (info_element->len == 6) { |
| 1970 | − memcpy(network->CcxRmState, &info_element[4], 2); | |
| 1970 | + memcpy(network->CcxRmState, &info_element->data[4], 2); | |
| 1971 | 1971 | if (network->CcxRmState[0] != 0) |
| 1972 | 1972 | network->bCcxRmEnable = true; |
| 1973 | 1973 | else |
| @@ -882,7 +882,6 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, · 881 unmodified lines | ||
| 882 | 882 | if (!bio) { |
| 883 | 883 | new_bio: |
| 884 | 884 | nr_vecs = bio_max_segs(nr_pages); |
| 885 | − nr_pages -= nr_vecs; | |
| 886 | 885 | /* |
| 887 | 886 | * Calls bio_kmalloc() and sets bio->bi_end_io() |
| 888 | 887 | */ |
| @@ -939,6 +938,14 @@ new_bio: · 50 unmodified lines | ||
| 939 | 938 | |
| 940 | 939 | return 0; |
| 941 | 940 | fail: |
| 941 | + if (bio) | |
| 942 | + bio_put(bio); | |
| 943 | + while (req->bio) { | |
| 944 | + bio = req->bio; | |
| 945 | + req->bio = bio->bi_next; | |
| 946 | + bio_put(bio); | |
| 947 | + } | |
| 948 | + req->biotail = NULL; | |
| 942 | 949 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 943 | 950 | } |
| 944 | 951 | |
| @@ -1177,12 +1177,6 @@ static inline void qcom_geni_serial_enable_early_read(struct geni_se *se, · 1176 unmodified lines | ||
| 1177 | 1177 | struct console *con) { } |
| 1178 | 1178 | #endif |
| 1179 | 1179 | |
| 1180 | −static int qcom_geni_serial_earlycon_exit(struct console *con) | |
| 1181 | −{ | |
| 1182 | − geni_remove_earlycon_icc_vote(); | |
| 1183 | − return 0; | |
| 1184 | −} | |
| 1185 | − | |
| 1186 | 1180 | static struct qcom_geni_private_data earlycon_private_data; |
| 1187 | 1181 | |
| 1188 | 1182 | static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev, |
| @@ -1233,7 +1227,6 @@ static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev, · 44 unmodified lines | ||
| 1233 | 1227 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); |
| 1234 | 1228 | |
| 1235 | 1229 | dev->con->write = qcom_geni_serial_earlycon_write; |
| 1236 | − dev->con->exit = qcom_geni_serial_earlycon_exit; | |
| 1237 | 1230 | dev->con->setup = NULL; |
| 1238 | 1231 | qcom_geni_serial_enable_early_read(&se, dev->con); |
| 1239 | 1232 | |
| @@ -147,17 +147,29 @@ static inline int acm_set_control(struct acm *acm, int control) · 146 unmodified lines | ||
| 147 | 147 | #define acm_send_break(acm, ms) \ |
| 148 | 148 | acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) |
| 149 | 149 | |
| 150 | −static void acm_kill_urbs(struct acm *acm) | |
| 150 | +static void acm_poison_urbs(struct acm *acm) | |
| 151 | 151 | { |
| 152 | 152 | int i; |
| 153 | 153 | |
| 154 | − usb_kill_urb(acm->ctrlurb); | |
| 154 | + usb_poison_urb(acm->ctrlurb); | |
| 155 | 155 | for (i = 0; i < ACM_NW; i++) |
| 156 | − usb_kill_urb(acm->wb[i].urb); | |
| 156 | + usb_poison_urb(acm->wb[i].urb); | |
| 157 | 157 | for (i = 0; i < acm->rx_buflimit; i++) |
| 158 | − usb_kill_urb(acm->read_urbs[i]); | |
| 158 | + usb_poison_urb(acm->read_urbs[i]); | |
| 159 | +} | |
| 160 | + | |
| 161 | +static void acm_unpoison_urbs(struct acm *acm) | |
| 162 | +{ | |
| 163 | + int i; | |
| 164 | + | |
| 165 | + for (i = 0; i < acm->rx_buflimit; i++) | |
| 166 | + usb_unpoison_urb(acm->read_urbs[i]); | |
| 167 | + for (i = 0; i < ACM_NW; i++) | |
| 168 | + usb_unpoison_urb(acm->wb[i].urb); | |
| 169 | + usb_unpoison_urb(acm->ctrlurb); | |
| 159 | 170 | } |
| 160 | 171 | |
| 172 | + | |
| 161 | 173 | /* |
| 162 | 174 | * Write buffer management. |
| 163 | 175 | * All of these assume proper locks taken by the caller. |
| @@ -226,9 +238,10 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) · 62 unmodified lines | ||
| 226 | 238 | |
| 227 | 239 | rc = usb_submit_urb(wb->urb, GFP_ATOMIC); |
| 228 | 240 | if (rc < 0) { |
| 229 | − dev_err(&acm->data->dev, | |
| 230 | − "%s - usb_submit_urb(write bulk) failed: %d\n", | |
| 231 | − __func__, rc); | |
| 241 | + if (rc != -EPERM) | |
| 242 | + dev_err(&acm->data->dev, | |
| 243 | + "%s - usb_submit_urb(write bulk) failed: %d\n", | |
| 244 | + __func__, rc); | |
| 232 | 245 | acm_write_done(acm, wb); |
| 233 | 246 | } |
| 234 | 247 | return rc; |
| @@ -313,8 +326,10 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) · 78 unmodified lines | ||
| 313 | 326 | acm->iocount.dsr++; |
| 314 | 327 | if (difference & ACM_CTRL_DCD) |
| 315 | 328 | acm->iocount.dcd++; |
| 316 | − if (newctrl & ACM_CTRL_BRK) | |
| 329 | + if (newctrl & ACM_CTRL_BRK) { | |
| 317 | 330 | acm->iocount.brk++; |
| 331 | + tty_insert_flip_char(&acm->port, 0, TTY_BREAK); | |
| 332 | + } | |
| 318 | 333 | if (newctrl & ACM_CTRL_RI) |
| 319 | 334 | acm->iocount.rng++; |
| 320 | 335 | if (newctrl & ACM_CTRL_FRAMING) |
| @@ -480,11 +495,6 @@ static void acm_read_bulk_callback(struct urb *urb) · 159 unmodified lines | ||
| 480 | 495 | dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", |
| 481 | 496 | rb->index, urb->actual_length, status); |
| 482 | 497 | |
| 483 | − if (!acm->dev) { | |
| 484 | − dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__); | |
| 485 | − return; | |
| 486 | − } | |
| 487 | − | |
| 488 | 498 | switch (status) { |
| 489 | 499 | case 0: |
| 490 | 500 | usb_mark_last_busy(acm->dev); |
| @@ -649,7 +659,8 @@ static void acm_port_dtr_rts(struct tty_port *port, int raise) · 158 unmodified lines | ||
| 649 | 659 | |
| 650 | 660 | res = acm_set_control(acm, val); |
| 651 | 661 | if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE)) |
| 652 | − dev_err(&acm->control->dev, "failed to set dtr/rts\n"); | |
| 662 | + /* This is broken in too many devices to spam the logs */ | |
| 663 | + dev_dbg(&acm->control->dev, "failed to set dtr/rts\n"); | |
| 653 | 664 | } |
| 654 | 665 | |
| 655 | 666 | static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) |
| @@ -731,6 +742,7 @@ static void acm_port_shutdown(struct tty_port *port) · 75 unmodified lines | ||
| 731 | 742 | * Need to grab write_lock to prevent race with resume, but no need to |
| 732 | 743 | * hold it due to the tty-port initialised flag. |
| 733 | 744 | */ |
| 745 | + acm_poison_urbs(acm); | |
| 734 | 746 | spin_lock_irq(&acm->write_lock); |
| 735 | 747 | spin_unlock_irq(&acm->write_lock); |
| 736 | 748 | |
| @@ -747,7 +759,8 @@ static void acm_port_shutdown(struct tty_port *port) · 10 unmodified lines | ||
| 747 | 759 | usb_autopm_put_interface_async(acm->control); |
| 748 | 760 | } |
| 749 | 761 | |
| 750 | − acm_kill_urbs(acm); | |
| 762 | + acm_unpoison_urbs(acm); | |
| 763 | + | |
| 751 | 764 | } |
| 752 | 765 | |
| 753 | 766 | static void acm_tty_cleanup(struct tty_struct *tty) |
| @@ -1296,13 +1309,6 @@ skip_normal_probe: · 542 unmodified lines | ||
| 1296 | 1309 | if (!combined_interfaces && intf != control_interface) |
| 1297 | 1310 | return -ENODEV; |
| 1298 | 1311 | |
| 1299 | − if (!combined_interfaces && usb_interface_claimed(data_interface)) { | |
| 1300 | − /* valid in this context */ | |
| 1301 | − dev_dbg(&intf->dev, "The data interface isn't available\n"); | |
| 1302 | − return -EBUSY; | |
| 1303 | − } | |
| 1304 | − | |
| 1305 | − | |
| 1306 | 1312 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || |
| 1307 | 1313 | control_interface->cur_altsetting->desc.bNumEndpoints == 0) |
| 1308 | 1314 | return -EINVAL; |
| @@ -1323,8 +1329,8 @@ made_compressed_probe: · 14 unmodified lines | ||
| 1323 | 1329 | dev_dbg(&intf->dev, "interfaces are valid\n"); |
| 1324 | 1330 | |
| 1325 | 1331 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); |
| 1326 | − if (acm == NULL) | |
| 1327 | − goto alloc_fail; | |
| 1332 | + if (!acm) | |
| 1333 | + return -ENOMEM; | |
| 1328 | 1334 | |
| 1329 | 1335 | tty_port_init(&acm->port); |
| 1330 | 1336 | acm->port.ops = &acm_port_ops; |
| @@ -1341,7 +1347,7 @@ made_compressed_probe: · 10 unmodified lines | ||
| 1341 | 1347 | |
| 1342 | 1348 | minor = acm_alloc_minor(acm); |
| 1343 | 1349 | if (minor < 0) |
| 1344 | − goto alloc_fail1; | |
| 1350 | + goto err_put_port; | |
| 1345 | 1351 | |
| 1346 | 1352 | acm->minor = minor; |
| 1347 | 1353 | acm->dev = usb_dev; |
| @@ -1372,15 +1378,15 @@ made_compressed_probe: · 24 unmodified lines | ||
| 1372 | 1378 | |
| 1373 | 1379 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
| 1374 | 1380 | if (!buf) |
| 1375 | − goto alloc_fail1; | |
| 1381 | + goto err_put_port; | |
| 1376 | 1382 | acm->ctrl_buffer = buf; |
| 1377 | 1383 | |
| 1378 | 1384 | if (acm_write_buffers_alloc(acm) < 0) |
| 1379 | − goto alloc_fail2; | |
| 1385 | + goto err_free_ctrl_buffer; | |
| 1380 | 1386 | |
| 1381 | 1387 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); |
| 1382 | 1388 | if (!acm->ctrlurb) |
| 1383 | − goto alloc_fail3; | |
| 1389 | + goto err_free_write_buffers; | |
| 1384 | 1390 | |
| 1385 | 1391 | for (i = 0; i < num_rx_buf; i++) { |
| 1386 | 1392 | struct acm_rb *rb = &(acm->read_buffers[i]); |
| @@ -1389,13 +1395,13 @@ made_compressed_probe: · 2 unmodified lines | ||
| 1389 | 1395 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, |
| 1390 | 1396 | &rb->dma); |
| 1391 | 1397 | if (!rb->base) |
| 1392 | − goto alloc_fail4; | |
| 1398 | + goto err_free_read_urbs; | |
| 1393 | 1399 | rb->index = i; |
| 1394 | 1400 | rb->instance = acm; |
| 1395 | 1401 | |
| 1396 | 1402 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 1397 | 1403 | if (!urb) |
| 1398 | − goto alloc_fail4; | |
| 1404 | + goto err_free_read_urbs; | |
| 1399 | 1405 | |
| 1400 | 1406 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 1401 | 1407 | urb->transfer_dma = rb->dma; |
| @@ -1416,8 +1422,8 @@ made_compressed_probe: · 14 unmodified lines | ||
| 1416 | 1422 | struct acm_wb *snd = &(acm->wb[i]); |
| 1417 | 1423 | |
| 1418 | 1424 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); |
| 1419 | − if (snd->urb == NULL) | |
| 1420 | − goto alloc_fail5; | |
| 1425 | + if (!snd->urb) | |
| 1426 | + goto err_free_write_urbs; | |
| 1421 | 1427 | |
| 1422 | 1428 | if (usb_endpoint_xfer_int(epwrite)) |
| 1423 | 1429 | usb_fill_int_urb(snd->urb, usb_dev, acm->out, |
| @@ -1435,7 +1441,7 @@ made_compressed_probe: · 11 unmodified lines | ||
| 1435 | 1441 | |
| 1436 | 1442 | i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); |
| 1437 | 1443 | if (i < 0) |
| 1438 | − goto alloc_fail5; | |
| 1444 | + goto err_free_write_urbs; | |
| 1439 | 1445 | |
| 1440 | 1446 | if (h.usb_cdc_country_functional_desc) { /* export the country data */ |
| 1441 | 1447 | struct usb_cdc_country_functional_desc * cfd = |
| @@ -1480,20 +1486,21 @@ skip_countries: · 38 unmodified lines | ||
| 1480 | 1486 | acm->nb_index = 0; |
| 1481 | 1487 | acm->nb_size = 0; |
| 1482 | 1488 | |
| 1483 | − dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); | |
| 1484 | − | |
| 1485 | 1489 | acm->line.dwDTERate = cpu_to_le32(9600); |
| 1486 | 1490 | acm->line.bDataBits = 8; |
| 1487 | 1491 | acm_set_line(acm, &acm->line); |
| 1488 | 1492 | |
| 1489 | − usb_driver_claim_interface(&acm_driver, data_interface, acm); | |
| 1490 | − usb_set_intfdata(data_interface, acm); | |
| 1493 | + if (!acm->combined_interfaces) { | |
| 1494 | + rv = usb_driver_claim_interface(&acm_driver, data_interface, acm); | |
| 1495 | + if (rv) | |
| 1496 | + goto err_remove_files; | |
| 1497 | + } | |
| 1491 | 1498 | |
| 1492 | 1499 | tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, |
| 1493 | 1500 | &control_interface->dev); |
| 1494 | 1501 | if (IS_ERR(tty_dev)) { |
| 1495 | 1502 | rv = PTR_ERR(tty_dev); |
| 1496 | − goto alloc_fail6; | |
| 1503 | + goto err_release_data_interface; | |
| 1497 | 1504 | } |
| 1498 | 1505 | |
| 1499 | 1506 | if (quirks & CLEAR_HALT_CONDITIONS) { |
| @@ -1501,32 +1508,39 @@ skip_countries: · 1 unmodified line | ||
| 1501 | 1508 | usb_clear_halt(usb_dev, acm->out); |
| 1502 | 1509 | } |
| 1503 | 1510 | |
| 1511 | + dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); | |
| 1512 | + | |
| 1504 | 1513 | return 0; |
| 1505 | −alloc_fail6: | |
| 1514 | + | |
| 1515 | +err_release_data_interface: | |
| 1516 | + if (!acm->combined_interfaces) { | |
| 1517 | + /* Clear driver data so that disconnect() returns early. */ | |
| 1518 | + usb_set_intfdata(data_interface, NULL); | |
| 1519 | + usb_driver_release_interface(&acm_driver, data_interface); | |
| 1520 | + } | |
| 1521 | +err_remove_files: | |
| 1506 | 1522 | if (acm->country_codes) { |
| 1507 | 1523 | device_remove_file(&acm->control->dev, |
| 1508 | 1524 | &dev_attr_wCountryCodes); |
| 1509 | 1525 | device_remove_file(&acm->control->dev, |
| 1510 | 1526 | &dev_attr_iCountryCodeRelDate); |
| 1511 | − kfree(acm->country_codes); | |
| 1512 | 1527 | } |
| 1513 | 1528 | device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); |
| 1514 | −alloc_fail5: | |
| 1515 | − usb_set_intfdata(intf, NULL); | |
| 1529 | +err_free_write_urbs: | |
| 1516 | 1530 | for (i = 0; i < ACM_NW; i++) |
| 1517 | 1531 | usb_free_urb(acm->wb[i].urb); |
| 1518 | −alloc_fail4: | |
| 1532 | +err_free_read_urbs: | |
| 1519 | 1533 | for (i = 0; i < num_rx_buf; i++) |
| 1520 | 1534 | usb_free_urb(acm->read_urbs[i]); |
| 1521 | 1535 | acm_read_buffers_free(acm); |
| 1522 | 1536 | usb_free_urb(acm->ctrlurb); |
| 1523 | −alloc_fail3: | |
| 1537 | +err_free_write_buffers: | |
| 1524 | 1538 | acm_write_buffers_free(acm); |
| 1525 | −alloc_fail2: | |
| 1539 | +err_free_ctrl_buffer: | |
| 1526 | 1540 | usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
| 1527 | −alloc_fail1: | |
| 1541 | +err_put_port: | |
| 1528 | 1542 | tty_port_put(&acm->port); |
| 1529 | −alloc_fail: | |
| 1543 | + | |
| 1530 | 1544 | return rv; |
| 1531 | 1545 | } |
| 1532 | 1546 | |
| @@ -1540,8 +1554,14 @@ static void acm_disconnect(struct usb_interface *intf) · 7 unmodified lines | ||
| 1540 | 1554 | if (!acm) |
| 1541 | 1555 | return; |
| 1542 | 1556 | |
| 1543 | − mutex_lock(&acm->mutex); | |
| 1544 | 1557 | acm->disconnected = true; |
| 1558 | + /* | |
| 1559 | + * there is a circular dependency. acm_softint() can resubmit | |
| 1560 | + * the URBs in error handling so we need to block any | |
| 1561 | + * submission right away | |
| 1562 | + */ | |
| 1563 | + acm_poison_urbs(acm); | |
| 1564 | + mutex_lock(&acm->mutex); | |
| 1545 | 1565 | if (acm->country_codes) { |
| 1546 | 1566 | device_remove_file(&acm->control->dev, |
| 1547 | 1567 | &dev_attr_wCountryCodes); |
| @@ -1560,7 +1580,6 @@ static void acm_disconnect(struct usb_interface *intf) · 12 unmodified lines | ||
| 1560 | 1580 | tty_kref_put(tty); |
| 1561 | 1581 | } |
| 1562 | 1582 | |
| 1563 | − acm_kill_urbs(acm); | |
| 1564 | 1583 | cancel_delayed_work_sync(&acm->dwork); |
| 1565 | 1584 | |
| 1566 | 1585 | tty_unregister_device(acm_tty_driver, acm->minor); |
| @@ -1602,7 +1621,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) · 35 unmodified lines | ||
| 1602 | 1621 | if (cnt) |
| 1603 | 1622 | return 0; |
| 1604 | 1623 | |
| 1605 | − acm_kill_urbs(acm); | |
| 1624 | + acm_poison_urbs(acm); | |
| 1606 | 1625 | cancel_delayed_work_sync(&acm->dwork); |
| 1607 | 1626 | acm->urbs_in_error_delay = 0; |
| 1608 | 1627 | |
| @@ -1615,6 +1634,7 @@ static int acm_resume(struct usb_interface *intf) · 6 unmodified lines | ||
| 1615 | 1634 | struct urb *urb; |
| 1616 | 1635 | int rv = 0; |
| 1617 | 1636 | |
| 1637 | + acm_unpoison_urbs(acm); | |
| 1618 | 1638 | spin_lock_irq(&acm->write_lock); |
| 1619 | 1639 | |
| 1620 | 1640 | if (--acm->susp_count) |
| @@ -498,6 +498,10 @@ static const struct usb_device_id usb_quirk_list[] = { · 497 unmodified lines | ||
| 498 | 498 | /* DJI CineSSD */ |
| 499 | 499 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, |
| 500 | 500 | |
| 501 | + /* Fibocom L850-GL LTE Modem */ | |
| 502 | + { USB_DEVICE(0x2cb7, 0x0007), .driver_info = | |
| 503 | + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, | |
| 504 | + | |
| 501 | 505 | /* INTEL VALUE SSD */ |
| 502 | 506 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 503 | 507 | |
| @@ -4322,7 +4322,8 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) · 4321 unmodified lines | ||
| 4322 | 4322 | if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) |
| 4323 | 4323 | goto unlock; |
| 4324 | 4324 | |
| 4325 | − if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) | |
| 4325 | + if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL || | |
| 4326 | + hsotg->flags.b.port_connect_status == 0) | |
| 4326 | 4327 | goto skip_power_saving; |
| 4327 | 4328 | |
| 4328 | 4329 | /* |
| @@ -5398,7 +5399,7 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) · 1069 unmodified lines | ||
| 5398 | 5399 | dwc2_writel(hsotg, hprt0, HPRT0); |
| 5399 | 5400 | |
| 5400 | 5401 | /* Wait for the HPRT0.PrtSusp register field to be set */ |
| 5401 | − if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000)) | |
| 5402 | + if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 5000)) | |
| 5402 | 5403 | dev_warn(hsotg->dev, "Suspend wasn't generated\n"); |
| 5403 | 5404 | |
| 5404 | 5405 | /* |
| @@ -120,6 +120,8 @@ static const struct property_entry dwc3_pci_intel_properties[] = { · 119 unmodified lines | ||
| 120 | 120 | static const struct property_entry dwc3_pci_mrfld_properties[] = { |
| 121 | 121 | PROPERTY_ENTRY_STRING("dr_mode", "otg"), |
| 122 | 122 | PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), |
| 123 | + PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), | |
| 124 | + PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), | |
| 123 | 125 | PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), |
| 124 | 126 | {} |
| 125 | 127 | }; |
| @@ -244,6 +244,9 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) · 243 unmodified lines | ||
| 244 | 244 | struct device *dev = qcom->dev; |
| 245 | 245 | int ret; |
| 246 | 246 | |
| 247 | + if (has_acpi_companion(dev)) | |
| 248 | + return 0; | |
| 249 | + | |
| 247 | 250 | qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); |
| 248 | 251 | if (IS_ERR(qcom->icc_path_ddr)) { |
| 249 | 252 | dev_err(dev, "failed to get usb-ddr path: %ld\n", |
| @@ -791,10 +791,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) · 790 unmodified lines | ||
| 791 | 791 | reg &= ~DWC3_DALEPENA_EP(dep->number); |
| 792 | 792 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); |
| 793 | 793 | |
| 794 | − dep->stream_capable = false; | |
| 795 | − dep->type = 0; | |
| 796 | − dep->flags = 0; | |
| 797 | − | |
| 798 | 794 | /* Clear out the ep descriptors for non-ep0 */ |
| 799 | 795 | if (dep->number > 1) { |
| 800 | 796 | dep->endpoint.comp_desc = NULL; |
| @@ -803,6 +799,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) · 2 unmodified lines | ||
| 803 | 799 | |
| 804 | 800 | dwc3_remove_requests(dwc, dep); |
| 805 | 801 | |
| 802 | + dep->stream_capable = false; | |
| 803 | + dep->type = 0; | |
| 804 | + dep->flags = 0; | |
| 805 | + | |
| 806 | 806 | return 0; |
| 807 | 807 | } |
| 808 | 808 | |
| @@ -2099,7 +2099,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc) · 1290 unmodified lines | ||
| 2099 | 2099 | u32 reg; |
| 2100 | 2100 | |
| 2101 | 2101 | speed = dwc->gadget_max_speed; |
| 2102 | − if (speed > dwc->maximum_speed) | |
| 2102 | + if (speed == USB_SPEED_UNKNOWN || speed > dwc->maximum_speed) | |
| 2103 | 2103 | speed = dwc->maximum_speed; |
| 2104 | 2104 | |
| 2105 | 2105 | if (speed == USB_SPEED_SUPER_PLUS && |
| @@ -2534,6 +2534,7 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g, · 428 unmodified lines | ||
| 2534 | 2534 | unsigned long flags; |
| 2535 | 2535 | |
| 2536 | 2536 | spin_lock_irqsave(&dwc->lock, flags); |
| 2537 | + dwc->gadget_max_speed = USB_SPEED_SUPER_PLUS; | |
| 2537 | 2538 | dwc->gadget_ssp_rate = rate; |
| 2538 | 2539 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2539 | 2540 | } |
| @@ -153,6 +153,11 @@ static int udc_pci_probe( · 152 unmodified lines | ||
| 153 | 153 | pci_set_master(pdev); |
| 154 | 154 | pci_try_set_mwi(pdev); |
| 155 | 155 | |
| 156 | + dev->phys_addr = resource; | |
| 157 | + dev->irq = pdev->irq; | |
| 158 | + dev->pdev = pdev; | |
| 159 | + dev->dev = &pdev->dev; | |
| 160 | + | |
| 156 | 161 | /* init dma pools */ |
| 157 | 162 | if (use_dma) { |
| 158 | 163 | retval = init_dma_pools(dev); |
| @@ -160,11 +165,6 @@ static int udc_pci_probe( · 1 unmodified line | ||
| 160 | 165 | goto err_dma; |
| 161 | 166 | } |
| 162 | 167 | |
| 163 | − dev->phys_addr = resource; | |
| 164 | − dev->irq = pdev->irq; | |
| 165 | − dev->pdev = pdev; | |
| 166 | − dev->dev = &pdev->dev; | |
| 167 | − | |
| 168 | 168 | /* general probing */ |
| 169 | 169 | if (udc_probe(dev)) { |
| 170 | 170 | retval = -ENODEV; |
| @@ -2004,10 +2004,14 @@ static void musb_pm_runtime_check_session(struct musb *musb) · 2003 unmodified lines | ||
| 2004 | 2004 | MUSB_DEVCTL_HR; |
| 2005 | 2005 | switch (devctl & ~s) { |
| 2006 | 2006 | case MUSB_QUIRK_B_DISCONNECT_99: |
| 2007 | − musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); | |
| 2008 | − schedule_delayed_work(&musb->irq_work, | |
| 2009 | − msecs_to_jiffies(1000)); | |
| 2010 | − break; | |
| 2007 | + if (musb->quirk_retries && !musb->flush_irq_work) { | |
| 2008 | + musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); | |
| 2009 | + schedule_delayed_work(&musb->irq_work, | |
| 2010 | + msecs_to_jiffies(1000)); | |
| 2011 | + musb->quirk_retries--; | |
| 2012 | + break; | |
| 2013 | + } | |
| 2014 | + fallthrough; | |
| 2011 | 2015 | case MUSB_QUIRK_B_INVALID_VBUS_91: |
| 2012 | 2016 | if (musb->quirk_retries && !musb->flush_irq_work) { |
| 2013 | 2017 | musb_dbg(musb, |
| @@ -594,6 +594,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 593 unmodified lines | ||
| 594 | 594 | pr_err("invalid port number %d\n", wIndex); |
| 595 | 595 | goto error; |
| 596 | 596 | } |
| 597 | + if (wValue >= 32) | |
| 598 | + goto error; | |
| 597 | 599 | if (hcd->speed == HCD_USB3) { |
| 598 | 600 | if ((vhci_hcd->port_status[rhport] & |
| 599 | 601 | USB_SS_PORT_STAT_POWER) != 0) { |
| @@ -42,6 +42,6 @@ config VFIO_PCI_IGD · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | config VFIO_PCI_NVLINK2 |
| 44 | 44 | def_bool y |
| 45 | − depends on VFIO_PCI && PPC_POWERNV | |
| 45 | + depends on VFIO_PCI && PPC_POWERNV && SPAPR_TCE_IOMMU | |
| 46 | 46 | help |
| 47 | 47 | VFIO PCI support for P9 Witherspoon machine with NVIDIA V100 GPUs |
| @@ -739,6 +739,12 @@ out: · 738 unmodified lines | ||
| 739 | 739 | ret = vfio_lock_acct(dma, lock_acct, false); |
| 740 | 740 | |
| 741 | 741 | unpin_out: |
| 742 | + if (batch->size == 1 && !batch->offset) { | |
| 743 | + /* May be a VM_PFNMAP pfn, which the batch can't remember. */ | |
| 744 | + put_pfn(pfn, dma->prot); | |
| 745 | + batch->size = 0; | |
| 746 | + } | |
| 747 | + | |
| 742 | 748 | if (ret < 0) { |
| 743 | 749 | if (pinned && !rsvd) { |
| 744 | 750 | for (pfn = *pfn_base ; pinned ; pfn++, pinned--) |
| @@ -1333,6 +1333,9 @@ static void fbcon_cursor(struct vc_data *vc, int mode) · 1332 unmodified lines | ||
| 1333 | 1333 | |
| 1334 | 1334 | ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; |
| 1335 | 1335 | |
| 1336 | + if (!ops->cursor) | |
| 1337 | + return; | |
| 1338 | + | |
| 1336 | 1339 | ops->cursor(vc, info, mode, get_color(vc, info, c, 1), |
| 1337 | 1340 | get_color(vc, info, c, 0)); |
| 1338 | 1341 | } |
| @@ -1031,7 +1031,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) · 1030 unmodified lines | ||
| 1031 | 1031 | PCI_DEVICE_ID_HYPERV_VIDEO, NULL); |
| 1032 | 1032 | if (!pdev) { |
| 1033 | 1033 | pr_err("Unable to find PCI Hyper-V video\n"); |
| 1034 | − kfree(info->apertures); | |
| 1035 | 1034 | return -ENODEV; |
| 1036 | 1035 | } |
| 1037 | 1036 | |
| @@ -1129,7 +1128,6 @@ getmem_done: · 91 unmodified lines | ||
| 1129 | 1128 | } else { |
| 1130 | 1129 | pci_dev_put(pdev); |
| 1131 | 1130 | } |
| 1132 | − kfree(info->apertures); | |
| 1133 | 1131 | |
| 1134 | 1132 | return 0; |
| 1135 | 1133 | |
| @@ -1141,7 +1139,6 @@ err2: · 5 unmodified lines | ||
| 1141 | 1139 | err1: |
| 1142 | 1140 | if (!gen2vm) |
| 1143 | 1141 | pci_dev_put(pdev); |
| 1144 | − kfree(info->apertures); | |
| 1145 | 1142 | |
| 1146 | 1143 | return -ENOMEM; |
| 1147 | 1144 | } |
| @@ -50,11 +50,11 @@ config XEN_BALLOON_MEMORY_HOTPLUG · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | SUBSYSTEM=="memory", ACTION=="add", RUN+="/bin/sh -c '[ -f /sys$devpath/state ] && echo online > /sys$devpath/state'" |
| 52 | 52 | |
| 53 | −config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT | |
| 53 | +config XEN_MEMORY_HOTPLUG_LIMIT | |
| 54 | 54 | int "Hotplugged memory limit (in GiB) for a PV guest" |
| 55 | 55 | default 512 |
| 56 | 56 | depends on XEN_HAVE_PVMMU |
| 57 | − depends on XEN_BALLOON_MEMORY_HOTPLUG | |
| 57 | + depends on MEMORY_HOTPLUG | |
| 58 | 58 | help |
| 59 | 59 | Maxmium amount of memory (in GiB) that a PV guest can be |
| 60 | 60 | expanded to when using memory hotplug. |
| @@ -851,8 +851,7 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf) · 850 unmodified lines | ||
| 851 | 851 | fscache_wait_on_page_write(vnode->cache, vmf->page); |
| 852 | 852 | #endif |
| 853 | 853 | |
| 854 | − if (PageWriteback(vmf->page) && | |
| 855 | − wait_on_page_bit_killable(vmf->page, PG_writeback) < 0) | |
| 854 | + if (wait_on_page_writeback_killable(vmf->page)) | |
| 856 | 855 | return VM_FAULT_RETRY; |
| 857 | 856 | |
| 858 | 857 | if (lock_page_killable(vmf->page) < 0) |
| @@ -275,6 +275,8 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, · 274 unmodified lines | ||
| 275 | 275 | bio.bi_opf = dio_bio_write_op(iocb); |
| 276 | 276 | task_io_account_write(ret); |
| 277 | 277 | } |
| 278 | + if (iocb->ki_flags & IOCB_NOWAIT) | |
| 279 | + bio.bi_opf |= REQ_NOWAIT; | |
| 278 | 280 | if (iocb->ki_flags & IOCB_HIPRI) |
| 279 | 281 | bio_set_polled(&bio, iocb); |
| 280 | 282 | |
| @@ -428,6 +430,8 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, · 147 unmodified lines | ||
| 428 | 430 | bio->bi_opf = dio_bio_write_op(iocb); |
| 429 | 431 | task_io_account_write(bio->bi_iter.bi_size); |
| 430 | 432 | } |
| 433 | + if (iocb->ki_flags & IOCB_NOWAIT) | |
| 434 | + bio->bi_opf |= REQ_NOWAIT; | |
| 431 | 435 | |
| 432 | 436 | dio->size += bio->bi_iter.bi_size; |
| 433 | 437 | pos += bio->bi_iter.bi_size; |
| @@ -1240,13 +1244,13 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) · 806 unmodified lines | ||
| 1240 | 1244 | |
| 1241 | 1245 | lockdep_assert_held(&bdev->bd_mutex); |
| 1242 | 1246 | |
| 1243 | − clear_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state); | |
| 1244 | − | |
| 1245 | 1247 | rescan: |
| 1246 | 1248 | ret = blk_drop_partitions(bdev); |
| 1247 | 1249 | if (ret) |
| 1248 | 1250 | return ret; |
| 1249 | 1251 | |
| 1252 | + clear_bit(GD_NEED_PART_SCAN, &disk->state); | |
| 1253 | + | |
| 1250 | 1254 | /* |
| 1251 | 1255 | * Historically we only set the capacity to zero for devices that |
| 1252 | 1256 | * support partitions (independ of actually having partitions created). |
| @@ -7,10 +7,12 @@ subdir-ccflags-y += -Wmissing-format-attribute · 6 unmodified lines | ||
| 7 | 7 | subdir-ccflags-y += -Wmissing-prototypes |
| 8 | 8 | subdir-ccflags-y += -Wold-style-definition |
| 9 | 9 | subdir-ccflags-y += -Wmissing-include-dirs |
| 10 | −subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable) | |
| 11 | −subdir-ccflags-y += $(call cc-option, -Wunused-const-variable) | |
| 12 | −subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned) | |
| 13 | −subdir-ccflags-y += $(call cc-option, -Wstringop-truncation) | |
| 10 | +condflags := \ | |
| 11 | + $(call cc-option, -Wunused-but-set-variable) \ | |
| 12 | + $(call cc-option, -Wunused-const-variable) \ | |
| 13 | + $(call cc-option, -Wpacked-not-aligned) \ | |
| 14 | + $(call cc-option, -Wstringop-truncation) | |
| 15 | +subdir-ccflags-y += $(condflags) | |
| 14 | 16 | # The following turn off the warnings enabled by -Wextra |
| 15 | 17 | subdir-ccflags-y += -Wno-missing-field-initializers |
| 16 | 18 | subdir-ccflags-y += -Wno-sign-compare |
| @@ -81,6 +81,9 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info) · 80 unmodified lines | ||
| 81 | 81 | struct btrfs_dev_replace_item *ptr; |
| 82 | 82 | u64 src_devid; |
| 83 | 83 | |
| 84 | + if (!dev_root) | |
| 85 | + return 0; | |
| 86 | + | |
| 84 | 87 | path = btrfs_alloc_path(); |
| 85 | 88 | if (!path) { |
| 86 | 89 | ret = -ENOMEM; |
| @@ -2387,8 +2387,9 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info) · 2386 unmodified lines | ||
| 2387 | 2387 | } else { |
| 2388 | 2388 | set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state); |
| 2389 | 2389 | fs_info->dev_root = root; |
| 2390 | − btrfs_init_devices_late(fs_info); | |
| 2391 | 2390 | } |
| 2391 | + /* Initialize fs_info for all devices in any case */ | |
| 2392 | + btrfs_init_devices_late(fs_info); | |
| 2392 | 2393 | |
| 2393 | 2394 | /* If IGNOREDATACSUMS is set don't bother reading the csum root. */ |
| 2394 | 2395 | if (!btrfs_test_opt(fs_info, IGNOREDATACSUMS)) { |
| @@ -3009,6 +3010,21 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info) · 614 unmodified lines | ||
| 3009 | 3010 | } |
| 3010 | 3011 | } |
| 3011 | 3012 | |
| 3013 | + /* | |
| 3014 | + * btrfs_find_orphan_roots() is responsible for finding all the dead | |
| 3015 | + * roots (with 0 refs), flag them with BTRFS_ROOT_DEAD_TREE and load | |
| 3016 | + * them into the fs_info->fs_roots_radix tree. This must be done before | |
| 3017 | + * calling btrfs_orphan_cleanup() on the tree root. If we don't do it | |
| 3018 | + * first, then btrfs_orphan_cleanup() will delete a dead root's orphan | |
| 3019 | + * item before the root's tree is deleted - this means that if we unmount | |
| 3020 | + * or crash before the deletion completes, on the next mount we will not | |
| 3021 | + * delete what remains of the tree because the orphan item does not | |
| 3022 | + * exists anymore, which is what tells us we have a pending deletion. | |
| 3023 | + */ | |
| 3024 | + ret = btrfs_find_orphan_roots(fs_info); | |
| 3025 | + if (ret) | |
| 3026 | + goto out; | |
| 3027 | + | |
| 3012 | 3028 | ret = btrfs_cleanup_fs_roots(fs_info); |
| 3013 | 3029 | if (ret) |
| 3014 | 3030 | goto out; |
| @@ -3068,7 +3084,6 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info) · 53 unmodified lines | ||
| 3068 | 3084 | } |
| 3069 | 3085 | } |
| 3070 | 3086 | |
| 3071 | − ret = btrfs_find_orphan_roots(fs_info); | |
| 3072 | 3087 | out: |
| 3073 | 3088 | return ret; |
| 3074 | 3089 | } |
| @@ -3099,11 +3099,13 @@ void btrfs_writepage_endio_finish_ordered(struct page *page, u64 start, · 3098 unmodified lines | ||
| 3099 | 3099 | * @bio_offset: offset to the beginning of the bio (in bytes) |
| 3100 | 3100 | * @page: page where is the data to be verified |
| 3101 | 3101 | * @pgoff: offset inside the page |
| 3102 | + * @start: logical offset in the file | |
| 3102 | 3103 | * |
| 3103 | 3104 | * The length of such check is always one sector size. |
| 3104 | 3105 | */ |
| 3105 | 3106 | static int check_data_csum(struct inode *inode, struct btrfs_io_bio *io_bio, |
| 3106 | − u32 bio_offset, struct page *page, u32 pgoff) | |
| 3107 | + u32 bio_offset, struct page *page, u32 pgoff, | |
| 3108 | + u64 start) | |
| 3107 | 3109 | { |
| 3108 | 3110 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
| 3109 | 3111 | SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); |
| @@ -3130,8 +3132,8 @@ static int check_data_csum(struct inode *inode, struct btrfs_io_bio *io_bio, · 20 unmodified lines | ||
| 3130 | 3132 | kunmap_atomic(kaddr); |
| 3131 | 3133 | return 0; |
| 3132 | 3134 | zeroit: |
| 3133 | − btrfs_print_data_csum_error(BTRFS_I(inode), page_offset(page) + pgoff, | |
| 3134 | − csum, csum_expected, io_bio->mirror_num); | |
| 3135 | + btrfs_print_data_csum_error(BTRFS_I(inode), start, csum, csum_expected, | |
| 3136 | + io_bio->mirror_num); | |
| 3135 | 3137 | if (io_bio->device) |
| 3136 | 3138 | btrfs_dev_stat_inc_and_print(io_bio->device, |
| 3137 | 3139 | BTRFS_DEV_STAT_CORRUPTION_ERRS); |
| @@ -3184,7 +3186,8 @@ int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u32 bio_offset, · 46 unmodified lines | ||
| 3184 | 3186 | pg_off += sectorsize, bio_offset += sectorsize) { |
| 3185 | 3187 | int ret; |
| 3186 | 3188 | |
| 3187 | − ret = check_data_csum(inode, io_bio, bio_offset, page, pg_off); | |
| 3189 | + ret = check_data_csum(inode, io_bio, bio_offset, page, pg_off, | |
| 3190 | + page_offset(page) + pg_off); | |
| 3188 | 3191 | if (ret < 0) |
| 3189 | 3192 | return -EIO; |
| 3190 | 3193 | } |
| @@ -7910,7 +7913,8 @@ static blk_status_t btrfs_check_read_dio_bio(struct inode *inode, · 4719 unmodified lines | ||
| 7910 | 7913 | ASSERT(pgoff < PAGE_SIZE); |
| 7911 | 7914 | if (uptodate && |
| 7912 | 7915 | (!csum || !check_data_csum(inode, io_bio, |
| 7913 | − bio_offset, bvec.bv_page, pgoff))) { | |
| 7916 | + bio_offset, bvec.bv_page, | |
| 7917 | + pgoff, start))) { | |
| 7914 | 7918 | clean_io_failure(fs_info, failure_tree, io_tree, |
| 7915 | 7919 | start, bvec.bv_page, |
| 7916 | 7920 | btrfs_ino(BTRFS_I(inode)), |
| @@ -8169,10 +8173,6 @@ static blk_qc_t btrfs_submit_direct(struct inode *inode, struct iomap *iomap, · 252 unmodified lines | ||
| 8169 | 8173 | bio->bi_end_io = btrfs_end_dio_bio; |
| 8170 | 8174 | btrfs_io_bio(bio)->logical = file_offset; |
| 8171 | 8175 | |
| 8172 | − WARN_ON_ONCE(write && btrfs_is_zoned(fs_info) && | |
| 8173 | − fs_info->max_zone_append_size && | |
| 8174 | − bio_op(bio) != REQ_OP_ZONE_APPEND); | |
| 8175 | − | |
| 8176 | 8176 | if (bio_op(bio) == REQ_OP_ZONE_APPEND) { |
| 8177 | 8177 | status = extract_ordered_extent(BTRFS_I(inode), bio, |
| 8178 | 8178 | file_offset); |
| @@ -226,7 +226,6 @@ static void __del_qgroup_rb(struct btrfs_fs_info *fs_info, · 225 unmodified lines | ||
| 226 | 226 | { |
| 227 | 227 | struct btrfs_qgroup_list *list; |
| 228 | 228 | |
| 229 | − btrfs_sysfs_del_one_qgroup(fs_info, qgroup); | |
| 230 | 229 | list_del(&qgroup->dirty); |
| 231 | 230 | while (!list_empty(&qgroup->groups)) { |
| 232 | 231 | list = list_first_entry(&qgroup->groups, |
| @@ -243,7 +242,6 @@ static void __del_qgroup_rb(struct btrfs_fs_info *fs_info, · 10 unmodified lines | ||
| 243 | 242 | list_del(&list->next_member); |
| 244 | 243 | kfree(list); |
| 245 | 244 | } |
| 246 | − kfree(qgroup); | |
| 247 | 245 | } |
| 248 | 246 | |
| 249 | 247 | /* must be called with qgroup_lock held */ |
| @@ -569,6 +567,8 @@ void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info) · 319 unmodified lines | ||
| 569 | 567 | qgroup = rb_entry(n, struct btrfs_qgroup, node); |
| 570 | 568 | rb_erase(n, &fs_info->qgroup_tree); |
| 571 | 569 | __del_qgroup_rb(fs_info, qgroup); |
| 570 | + btrfs_sysfs_del_one_qgroup(fs_info, qgroup); | |
| 571 | + kfree(qgroup); | |
| 572 | 572 | } |
| 573 | 573 | /* |
| 574 | 574 | * We call btrfs_free_qgroup_config() when unmounting |
| @@ -1578,6 +1578,14 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) · 1003 unmodified lines | ||
| 1578 | 1578 | spin_lock(&fs_info->qgroup_lock); |
| 1579 | 1579 | del_qgroup_rb(fs_info, qgroupid); |
| 1580 | 1580 | spin_unlock(&fs_info->qgroup_lock); |
| 1581 | + | |
| 1582 | + /* | |
| 1583 | + * Remove the qgroup from sysfs now without holding the qgroup_lock | |
| 1584 | + * spinlock, since the sysfs_remove_group() function needs to take | |
| 1585 | + * the mutex kernfs_mutex through kernfs_remove_by_name_ns(). | |
| 1586 | + */ | |
| 1587 | + btrfs_sysfs_del_one_qgroup(fs_info, qgroup); | |
| 1588 | + kfree(qgroup); | |
| 1581 | 1589 | out: |
| 1582 | 1590 | mutex_unlock(&fs_info->qgroup_ioctl_lock); |
| 1583 | 1591 | return ret; |
| @@ -7448,6 +7448,9 @@ static int btrfs_device_init_dev_stats(struct btrfs_device *device, · 7447 unmodified lines | ||
| 7448 | 7448 | int item_size; |
| 7449 | 7449 | int i, ret, slot; |
| 7450 | 7450 | |
| 7451 | + if (!device->fs_info->dev_root) | |
| 7452 | + return 0; | |
| 7453 | + | |
| 7451 | 7454 | key.objectid = BTRFS_DEV_STATS_OBJECTID; |
| 7452 | 7455 | key.type = BTRFS_PERSISTENT_ITEM_KEY; |
| 7453 | 7456 | key.offset = device->devid; |
| @@ -118,6 +118,12 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) · 117 unmodified lines | ||
| 118 | 118 | cache->mnt = path.mnt; |
| 119 | 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 | 127 | /* check parameters */ |
| 122 | 128 | ret = -EOPNOTSUPP; |
| 123 | 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 | 24 | container_of(wait, struct cachefiles_one_read, monitor); |
| 25 | 25 | struct cachefiles_object *object; |
| 26 | 26 | struct fscache_retrieval *op = monitor->op; |
| 27 | − struct wait_bit_key *key = _key; | |
| 27 | + struct wait_page_key *key = _key; | |
| 28 | 28 | struct page *page = wait->private; |
| 29 | 29 | |
| 30 | 30 | ASSERT(key); |
| 31 | 31 | |
| 32 | 32 | _enter("{%lu},%u,%d,{%p,%u}", |
| 33 | 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 || | |
| 37 | − key->bit_nr != PG_locked) | |
| 36 | + if (key->page != page || key->bit_nr != PG_locked) | |
| 38 | 37 | return 0; |
| 39 | 38 | |
| 40 | 39 | _debug("--- monitor %p %lx ---", page, page->flags); |
| @@ -1130,8 +1130,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, · 1129 unmodified lines | ||
| 1130 | 1130 | } |
| 1131 | 1131 | |
| 1132 | 1132 | /* If it's any one of the ACE we're replacing, skip! */ |
| 1133 | − if (!mode_from_sid && | |
| 1134 | − ((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) || | |
| 1133 | + if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) || | |
| 1135 | 1134 | (compare_sids(&pntace->sid, pownersid) == 0) || |
| 1136 | 1135 | (compare_sids(&pntace->sid, pgrpsid) == 0) || |
| 1137 | 1136 | (compare_sids(&pntace->sid, &sid_everyone) == 0) || |
| @@ -919,8 +919,8 @@ struct cifs_ses { · 918 unmodified lines | ||
| 919 | 919 | bool binding:1; /* are we binding the session? */ |
| 920 | 920 | __u16 session_flags; |
| 921 | 921 | __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; |
| 922 | − __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; | |
| 923 | − __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; | |
| 922 | + __u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE]; | |
| 923 | + __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; | |
| 924 | 924 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
| 925 | 925 | |
| 926 | 926 | __u8 binding_preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
| @@ -147,6 +147,11 @@ · 146 unmodified lines | ||
| 147 | 147 | */ |
| 148 | 148 | #define SMB3_SIGN_KEY_SIZE (16) |
| 149 | 149 | |
| 150 | +/* | |
| 151 | + * Size of the smb3 encryption/decryption keys | |
| 152 | + */ | |
| 153 | +#define SMB3_ENC_DEC_KEY_SIZE (32) | |
| 154 | + | |
| 150 | 155 | #define CIFS_CLIENT_CHALLENGE_SIZE (8) |
| 151 | 156 | #define CIFS_SERVER_CHALLENGE_SIZE (8) |
| 152 | 157 | #define CIFS_HMAC_MD5_HASH_SIZE (16) |
| @@ -165,6 +165,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, · 164 unmodified lines | ||
| 165 | 165 | goto posix_open_ret; |
| 166 | 166 | } |
| 167 | 167 | } else { |
| 168 | + cifs_revalidate_mapping(*pinode); | |
| 168 | 169 | cifs_fattr_to_inode(*pinode, &fattr); |
| 169 | 170 | } |
| 170 | 171 | |
| @@ -58,6 +58,7 @@ · 57 unmodified lines | ||
| 58 | 58 | #define SMB2_HMACSHA256_SIZE (32) |
| 59 | 59 | #define SMB2_CMACAES_SIZE (16) |
| 60 | 60 | #define SMB3_SIGNKEY_SIZE (16) |
| 61 | +#define SMB3_GCM128_CRYPTKEY_SIZE (16) | |
| 61 | 62 | #define SMB3_GCM256_CRYPTKEY_SIZE (32) |
| 62 | 63 | |
| 63 | 64 | /* Maximum buffer size value we can send with 1 credit */ |
| @@ -754,8 +754,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) · 753 unmodified lines | ||
| 754 | 754 | } |
| 755 | 755 | } |
| 756 | 756 | spin_unlock(&cifs_tcp_ses_lock); |
| 757 | − cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n"); | |
| 758 | − return false; | |
| 757 | + cifs_dbg(FYI, "No file id matched, oplock break ignored\n"); | |
| 758 | + return true; | |
| 759 | 759 | } |
| 760 | 760 | |
| 761 | 761 | void |
| @@ -2038,6 +2038,7 @@ smb2_duplicate_extents(const unsigned int xid, · 2037 unmodified lines | ||
| 2038 | 2038 | { |
| 2039 | 2039 | int rc; |
| 2040 | 2040 | unsigned int ret_data_len; |
| 2041 | + struct inode *inode; | |
| 2041 | 2042 | struct duplicate_extents_to_file dup_ext_buf; |
| 2042 | 2043 | struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink); |
| 2043 | 2044 | |
| @@ -2054,10 +2055,21 @@ smb2_duplicate_extents(const unsigned int xid, · 10 unmodified lines | ||
| 2054 | 2055 | cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n", |
| 2055 | 2056 | src_off, dest_off, len); |
| 2056 | 2057 | |
| 2057 | − rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); | |
| 2058 | − if (rc) | |
| 2059 | − goto duplicate_extents_out; | |
| 2058 | + inode = d_inode(trgtfile->dentry); | |
| 2059 | + if (inode->i_size < dest_off + len) { | |
| 2060 | + rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); | |
| 2061 | + if (rc) | |
| 2062 | + goto duplicate_extents_out; | |
| 2060 | 2063 | |
| 2064 | + /* | |
| 2065 | + * Although also could set plausible allocation size (i_blocks) | |
| 2066 | + * here in addition to setting the file size, in reflink | |
| 2067 | + * it is likely that the target file is sparse. Its allocation | |
| 2068 | + * size will be queried on next revalidate, but it is important | |
| 2069 | + * to make sure that file's cached size is updated immediately | |
| 2070 | + */ | |
| 2071 | + cifs_setsize(inode, dest_off + len); | |
| 2072 | + } | |
| 2061 | 2073 | rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, |
| 2062 | 2074 | trgtfile->fid.volatile_fid, |
| 2063 | 2075 | FSCTL_DUPLICATE_EXTENTS_TO_FILE, |
| @@ -4158,7 +4170,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key) · 2094 unmodified lines | ||
| 4158 | 4170 | if (ses->Suid == ses_id) { |
| 4159 | 4171 | ses_enc_key = enc ? ses->smb3encryptionkey : |
| 4160 | 4172 | ses->smb3decryptionkey; |
| 4161 | − memcpy(key, ses_enc_key, SMB3_SIGN_KEY_SIZE); | |
| 4173 | + memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE); | |
| 4162 | 4174 | spin_unlock(&cifs_tcp_ses_lock); |
| 4163 | 4175 | return 0; |
| 4164 | 4176 | } |
| @@ -4185,7 +4197,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, · 20 unmodified lines | ||
| 4185 | 4197 | int rc = 0; |
| 4186 | 4198 | struct scatterlist *sg; |
| 4187 | 4199 | u8 sign[SMB2_SIGNATURE_SIZE] = {}; |
| 4188 | − u8 key[SMB3_SIGN_KEY_SIZE]; | |
| 4200 | + u8 key[SMB3_ENC_DEC_KEY_SIZE]; | |
| 4189 | 4201 | struct aead_request *req; |
| 4190 | 4202 | char *iv; |
| 4191 | 4203 | unsigned int iv_len; |
| @@ -4209,10 +4221,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, · 17 unmodified lines | ||
| 4209 | 4221 | tfm = enc ? server->secmech.ccmaesencrypt : |
| 4210 | 4222 | server->secmech.ccmaesdecrypt; |
| 4211 | 4223 | |
| 4212 | − if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM) | |
| 4224 | + if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || | |
| 4225 | + (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) | |
| 4213 | 4226 | rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE); |
| 4214 | 4227 | else |
| 4215 | − rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE); | |
| 4228 | + rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE); | |
| 4216 | 4229 | |
| 4217 | 4230 | if (rc) { |
| 4218 | 4231 | cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); |
| @@ -298,7 +298,8 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, · 297 unmodified lines | ||
| 298 | 298 | { |
| 299 | 299 | unsigned char zero = 0x0; |
| 300 | 300 | __u8 i[4] = {0, 0, 0, 1}; |
| 301 | − __u8 L[4] = {0, 0, 0, 128}; | |
| 301 | + __u8 L128[4] = {0, 0, 0, 128}; | |
| 302 | + __u8 L256[4] = {0, 0, 1, 0}; | |
| 302 | 303 | int rc = 0; |
| 303 | 304 | unsigned char prfhash[SMB2_HMACSHA256_SIZE]; |
| 304 | 305 | unsigned char *hashptr = prfhash; |
| @@ -354,8 +355,14 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, · 49 unmodified lines | ||
| 354 | 355 | goto smb3signkey_ret; |
| 355 | 356 | } |
| 356 | 357 | |
| 357 | − rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, | |
| 358 | − L, 4); | |
| 358 | + if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || | |
| 359 | + (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) { | |
| 360 | + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, | |
| 361 | + L256, 4); | |
| 362 | + } else { | |
| 363 | + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, | |
| 364 | + L128, 4); | |
| 365 | + } | |
| 359 | 366 | if (rc) { |
| 360 | 367 | cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__); |
| 361 | 368 | goto smb3signkey_ret; |
| @@ -390,6 +397,9 @@ generate_smb3signingkey(struct cifs_ses *ses, · 28 unmodified lines | ||
| 390 | 397 | const struct derivation_triplet *ptriplet) |
| 391 | 398 | { |
| 392 | 399 | int rc; |
| 400 | +#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS | |
| 401 | + struct TCP_Server_Info *server = ses->server; | |
| 402 | +#endif | |
| 393 | 403 | |
| 394 | 404 | /* |
| 395 | 405 | * All channels use the same encryption/decryption keys but |
| @@ -422,11 +432,11 @@ generate_smb3signingkey(struct cifs_ses *ses, · 26 unmodified lines | ||
| 422 | 432 | rc = generate_key(ses, ptriplet->encryption.label, |
| 423 | 433 | ptriplet->encryption.context, |
| 424 | 434 | ses->smb3encryptionkey, |
| 425 | − SMB3_SIGN_KEY_SIZE); | |
| 435 | + SMB3_ENC_DEC_KEY_SIZE); | |
| 426 | 436 | rc = generate_key(ses, ptriplet->decryption.label, |
| 427 | 437 | ptriplet->decryption.context, |
| 428 | 438 | ses->smb3decryptionkey, |
| 429 | − SMB3_SIGN_KEY_SIZE); | |
| 439 | + SMB3_ENC_DEC_KEY_SIZE); | |
| 430 | 440 | if (rc) |
| 431 | 441 | return rc; |
| 432 | 442 | } |
| @@ -442,14 +452,23 @@ generate_smb3signingkey(struct cifs_ses *ses, · 9 unmodified lines | ||
| 442 | 452 | */ |
| 443 | 453 | cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid), |
| 444 | 454 | &ses->Suid); |
| 455 | + cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type); | |
| 445 | 456 | cifs_dbg(VFS, "Session Key %*ph\n", |
| 446 | 457 | SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response); |
| 447 | 458 | cifs_dbg(VFS, "Signing Key %*ph\n", |
| 448 | 459 | SMB3_SIGN_KEY_SIZE, ses->smb3signingkey); |
| 449 | − cifs_dbg(VFS, "ServerIn Key %*ph\n", | |
| 450 | − SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey); | |
| 451 | − cifs_dbg(VFS, "ServerOut Key %*ph\n", | |
| 452 | − SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey); | |
| 460 | + if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || | |
| 461 | + (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) { | |
| 462 | + cifs_dbg(VFS, "ServerIn Key %*ph\n", | |
| 463 | + SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey); | |
| 464 | + cifs_dbg(VFS, "ServerOut Key %*ph\n", | |
| 465 | + SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey); | |
| 466 | + } else { | |
| 467 | + cifs_dbg(VFS, "ServerIn Key %*ph\n", | |
| 468 | + SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey); | |
| 469 | + cifs_dbg(VFS, "ServerOut Key %*ph\n", | |
| 470 | + SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey); | |
| 471 | + } | |
| 453 | 472 | #endif |
| 454 | 473 | return rc; |
| 455 | 474 | } |
| @@ -162,8 +162,10 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) · 161 unmodified lines | ||
| 162 | 162 | int error; |
| 163 | 163 | |
| 164 | 164 | error = init_threads(sdp); |
| 165 | − if (error) | |
| 165 | + if (error) { | |
| 166 | + gfs2_withdraw_delayed(sdp); | |
| 166 | 167 | return error; |
| 168 | + } | |
| 167 | 169 | |
| 168 | 170 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
| 169 | 171 | if (gfs2_withdrawn(sdp)) { |
| @@ -750,11 +752,13 @@ void gfs2_freeze_func(struct work_struct *work) · 580 unmodified lines | ||
| 750 | 752 | static int gfs2_freeze(struct super_block *sb) |
| 751 | 753 | { |
| 752 | 754 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 753 | − int error = 0; | |
| 755 | + int error; | |
| 754 | 756 | |
| 755 | 757 | mutex_lock(&sdp->sd_freeze_mutex); |
| 756 | − if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) | |
| 758 | + if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) { | |
| 759 | + error = -EBUSY; | |
| 757 | 760 | goto out; |
| 761 | + } | |
| 758 | 762 | |
| 759 | 763 | for (;;) { |
| 760 | 764 | if (gfs2_withdrawn(sdp)) { |
| @@ -795,10 +799,10 @@ static int gfs2_unfreeze(struct super_block *sb) · 34 unmodified lines | ||
| 795 | 799 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 796 | 800 | |
| 797 | 801 | mutex_lock(&sdp->sd_freeze_mutex); |
| 798 | − if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || | |
| 802 | + if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || | |
| 799 | 803 | !gfs2_holder_initialized(&sdp->sd_freeze_gh)) { |
| 800 | 804 | mutex_unlock(&sdp->sd_freeze_mutex); |
| 801 | − return 0; | |
| 805 | + return -EINVAL; | |
| 802 | 806 | } |
| 803 | 807 | |
| 804 | 808 | gfs2_freeze_unlock(&sdp->sd_freeze_gh); |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/rculist_nulls.h> |
| 17 | 17 | #include <linux/cpu.h> |
| 18 | 18 | #include <linux/tracehook.h> |
| 19 | −#include <linux/freezer.h> | |
| 20 | 19 | |
| 21 | 20 | #include "../kernel/sched/sched.h" |
| 22 | 21 | #include "io-wq.h" |
| @@ -388,11 +387,9 @@ static struct io_wq_work *io_get_next_work(struct io_wqe *wqe) · 365 unmodified lines | ||
| 388 | 387 | |
| 389 | 388 | static bool io_flush_signals(void) |
| 390 | 389 | { |
| 391 | − if (unlikely(test_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL))) { | |
| 390 | + if (unlikely(test_thread_flag(TIF_NOTIFY_SIGNAL))) { | |
| 392 | 391 | __set_current_state(TASK_RUNNING); |
| 393 | − if (current->task_works) | |
| 394 | − task_work_run(); | |
| 395 | − clear_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL); | |
| 392 | + tracehook_notify_signal(); | |
| 396 | 393 | return true; |
| 397 | 394 | } |
| 398 | 395 | return false; |
| @@ -487,7 +484,7 @@ static int io_wqe_worker(void *data) · 88 unmodified lines | ||
| 487 | 484 | worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING); |
| 488 | 485 | io_wqe_inc_running(worker); |
| 489 | 486 | |
| 490 | − sprintf(buf, "iou-wrk-%d", wq->task_pid); | |
| 487 | + snprintf(buf, sizeof(buf), "iou-wrk-%d", wq->task_pid); | |
| 491 | 488 | set_task_comm(current, buf); |
| 492 | 489 | |
| 493 | 490 | while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) { |
| @@ -505,10 +502,15 @@ loop: · 11 unmodified lines | ||
| 505 | 502 | if (io_flush_signals()) |
| 506 | 503 | continue; |
| 507 | 504 | ret = schedule_timeout(WORKER_IDLE_TIMEOUT); |
| 508 | − if (try_to_freeze() || ret) | |
| 509 | − continue; | |
| 510 | − if (fatal_signal_pending(current)) | |
| 505 | + if (signal_pending(current)) { | |
| 506 | + struct ksignal ksig; | |
| 507 | + | |
| 508 | + if (!get_signal(&ksig)) | |
| 509 | + continue; | |
| 511 | 510 | break; |
| 511 | + } | |
| 512 | + if (ret) | |
| 513 | + continue; | |
| 512 | 514 | /* timed out, exit unless we're the fixed worker */ |
| 513 | 515 | if (test_bit(IO_WQ_BIT_EXIT, &wq->state) || |
| 514 | 516 | !(worker->flags & IO_WORKER_F_FIXED)) |
| @@ -709,16 +711,20 @@ static int io_wq_manager(void *data) · 194 unmodified lines | ||
| 709 | 711 | char buf[TASK_COMM_LEN]; |
| 710 | 712 | int node; |
| 711 | 713 | |
| 712 | − sprintf(buf, "iou-mgr-%d", wq->task_pid); | |
| 714 | + snprintf(buf, sizeof(buf), "iou-mgr-%d", wq->task_pid); | |
| 713 | 715 | set_task_comm(current, buf); |
| 714 | 716 | |
| 715 | 717 | do { |
| 716 | 718 | set_current_state(TASK_INTERRUPTIBLE); |
| 717 | 719 | io_wq_check_workers(wq); |
| 718 | 720 | schedule_timeout(HZ); |
| 719 | − try_to_freeze(); | |
| 720 | − if (fatal_signal_pending(current)) | |
| 721 | + if (signal_pending(current)) { | |
| 722 | + struct ksignal ksig; | |
| 723 | + | |
| 724 | + if (!get_signal(&ksig)) | |
| 725 | + continue; | |
| 721 | 726 | set_bit(IO_WQ_BIT_EXIT, &wq->state); |
| 727 | + } | |
| 722 | 728 | } while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)); |
| 723 | 729 | |
| 724 | 730 | io_wq_check_workers(wq); |
| @@ -1065,7 +1071,11 @@ static void io_wq_destroy(struct io_wq *wq) · 340 unmodified lines | ||
| 1065 | 1071 | |
| 1066 | 1072 | for_each_node(node) { |
| 1067 | 1073 | struct io_wqe *wqe = wq->wqes[node]; |
| 1068 | − WARN_ON_ONCE(!wq_list_empty(&wqe->work_list)); | |
| 1074 | + struct io_cb_cancel_data match = { | |
| 1075 | + .fn = io_wq_work_match_all, | |
| 1076 | + .cancel_all = true, | |
| 1077 | + }; | |
| 1078 | + io_wqe_cancel_pending_work(wqe, &match); | |
| 1069 | 1079 | kfree(wqe); |
| 1070 | 1080 | } |
| 1071 | 1081 | io_wq_put_hash(wq->hash); |
| @@ -78,7 +78,6 @@ · 77 unmodified lines | ||
| 78 | 78 | #include <linux/task_work.h> |
| 79 | 79 | #include <linux/pagemap.h> |
| 80 | 80 | #include <linux/io_uring.h> |
| 81 | −#include <linux/freezer.h> | |
| 82 | 81 | |
| 83 | 82 | #define CREATE_TRACE_POINTS |
| 84 | 83 | #include <trace/events/io_uring.h> |
| @@ -698,6 +697,7 @@ enum { · 613 unmodified lines | ||
| 698 | 697 | REQ_F_NO_FILE_TABLE_BIT, |
| 699 | 698 | REQ_F_LTIMEOUT_ACTIVE_BIT, |
| 700 | 699 | REQ_F_COMPLETE_INLINE_BIT, |
| 700 | + REQ_F_REISSUE_BIT, | |
| 701 | 701 | |
| 702 | 702 | /* not a real bit, just to check we're not overflowing the space */ |
| 703 | 703 | __REQ_F_LAST_BIT, |
| @@ -741,6 +741,8 @@ enum { · 37 unmodified lines | ||
| 741 | 741 | REQ_F_LTIMEOUT_ACTIVE = BIT(REQ_F_LTIMEOUT_ACTIVE_BIT), |
| 742 | 742 | /* completion is deferred through io_comp_state */ |
| 743 | 743 | REQ_F_COMPLETE_INLINE = BIT(REQ_F_COMPLETE_INLINE_BIT), |
| 744 | + /* caller should reissue async */ | |
| 745 | + REQ_F_REISSUE = BIT(REQ_F_REISSUE_BIT), | |
| 744 | 746 | }; |
| 745 | 747 | |
| 746 | 748 | struct async_poll { |
| @@ -1095,8 +1097,6 @@ static bool io_match_task(struct io_kiocb *head, · 348 unmodified lines | ||
| 1095 | 1097 | io_for_each_link(req, head) { |
| 1096 | 1098 | if (req->flags & REQ_F_INFLIGHT) |
| 1097 | 1099 | return true; |
| 1098 | − if (req->task->files == files) | |
| 1099 | − return true; | |
| 1100 | 1100 | } |
| 1101 | 1101 | return false; |
| 1102 | 1102 | } |
| @@ -1216,7 +1216,7 @@ static void io_prep_async_work(struct io_kiocb *req) · 113 unmodified lines | ||
| 1216 | 1216 | if (req->flags & REQ_F_ISREG) { |
| 1217 | 1217 | if (def->hash_reg_file || (ctx->flags & IORING_SETUP_IOPOLL)) |
| 1218 | 1218 | io_wq_hash_work(&req->work, file_inode(req->file)); |
| 1219 | − } else { | |
| 1219 | + } else if (!req->file || !S_ISBLK(file_inode(req->file)->i_mode)) { | |
| 1220 | 1220 | if (def->unbound_nonreg_file) |
| 1221 | 1221 | req->work.flags |= IO_WQ_WORK_UNBOUND; |
| 1222 | 1222 | } |
| @@ -1239,16 +1239,16 @@ static void io_queue_async_work(struct io_kiocb *req) · 16 unmodified lines | ||
| 1239 | 1239 | BUG_ON(!tctx); |
| 1240 | 1240 | BUG_ON(!tctx->io_wq); |
| 1241 | 1241 | |
| 1242 | − trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req, | |
| 1243 | − &req->work, req->flags); | |
| 1244 | 1242 | /* init ->work of the whole link before punting */ |
| 1245 | 1243 | io_prep_async_link(req); |
| 1244 | + trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req, | |
| 1245 | + &req->work, req->flags); | |
| 1246 | 1246 | io_wq_enqueue(tctx->io_wq, &req->work); |
| 1247 | 1247 | if (link) |
| 1248 | 1248 | io_queue_linked_timeout(link); |
| 1249 | 1249 | } |
| 1250 | 1250 | |
| 1251 | −static void io_kill_timeout(struct io_kiocb *req) | |
| 1251 | +static void io_kill_timeout(struct io_kiocb *req, int status) | |
| 1252 | 1252 | { |
| 1253 | 1253 | struct io_timeout_data *io = req->async_data; |
| 1254 | 1254 | int ret; |
| @@ -1258,31 +1258,11 @@ static void io_kill_timeout(struct io_kiocb *req) · 3 unmodified lines | ||
| 1258 | 1258 | atomic_set(&req->ctx->cq_timeouts, |
| 1259 | 1259 | atomic_read(&req->ctx->cq_timeouts) + 1); |
| 1260 | 1260 | list_del_init(&req->timeout.list); |
| 1261 | − io_cqring_fill_event(req, 0); | |
| 1261 | + io_cqring_fill_event(req, status); | |
| 1262 | 1262 | io_put_req_deferred(req, 1); |
| 1263 | 1263 | } |
| 1264 | 1264 | } |
| 1265 | 1265 | |
| 1266 | −/* | |
| 1267 | − * Returns true if we found and killed one or more timeouts | |
| 1268 | − */ | |
| 1269 | −static bool io_kill_timeouts(struct io_ring_ctx *ctx, struct task_struct *tsk, | |
| 1270 | − struct files_struct *files) | |
| 1271 | −{ | |
| 1272 | − struct io_kiocb *req, *tmp; | |
| 1273 | − int canceled = 0; | |
| 1274 | − | |
| 1275 | − spin_lock_irq(&ctx->completion_lock); | |
| 1276 | − list_for_each_entry_safe(req, tmp, &ctx->timeout_list, timeout.list) { | |
| 1277 | − if (io_match_task(req, tsk, files)) { | |
| 1278 | − io_kill_timeout(req); | |
| 1279 | − canceled++; | |
| 1280 | − } | |
| 1281 | − } | |
| 1282 | − spin_unlock_irq(&ctx->completion_lock); | |
| 1283 | − return canceled != 0; | |
| 1284 | −} | |
| 1285 | − | |
| 1286 | 1266 | static void __io_queue_deferred(struct io_ring_ctx *ctx) |
| 1287 | 1267 | { |
| 1288 | 1268 | do { |
| @@ -1327,7 +1307,7 @@ static void io_flush_timeouts(struct io_ring_ctx *ctx) · 38 unmodified lines | ||
| 1327 | 1307 | break; |
| 1328 | 1308 | |
| 1329 | 1309 | list_del_init(&req->timeout.list); |
| 1330 | − io_kill_timeout(req); | |
| 1310 | + io_kill_timeout(req, 0); | |
| 1331 | 1311 | } while (!list_empty(&ctx->timeout_list)); |
| 1332 | 1312 | |
| 1333 | 1313 | ctx->cq_last_tm_flush = seq; |
| @@ -2499,6 +2479,11 @@ static bool io_rw_should_reissue(struct io_kiocb *req) · 1165 unmodified lines | ||
| 2499 | 2479 | return false; |
| 2500 | 2480 | return true; |
| 2501 | 2481 | } |
| 2482 | +#else | |
| 2483 | +static bool io_rw_should_reissue(struct io_kiocb *req) | |
| 2484 | +{ | |
| 2485 | + return false; | |
| 2486 | +} | |
| 2502 | 2487 | #endif |
| 2503 | 2488 | |
| 2504 | 2489 | static bool io_rw_reissue(struct io_kiocb *req) |
| @@ -2524,13 +2509,14 @@ static void __io_complete_rw(struct io_kiocb *req, long res, long res2, · 19 unmodified lines | ||
| 2524 | 2509 | { |
| 2525 | 2510 | int cflags = 0; |
| 2526 | 2511 | |
| 2527 | − if ((res == -EAGAIN || res == -EOPNOTSUPP) && io_rw_reissue(req)) | |
| 2512 | + if (req->rw.kiocb.ki_flags & IOCB_WRITE) | |
| 2513 | + kiocb_end_write(req); | |
| 2514 | + if ((res == -EAGAIN || res == -EOPNOTSUPP) && io_rw_should_reissue(req)) { | |
| 2515 | + req->flags |= REQ_F_REISSUE; | |
| 2528 | 2516 | return; |
| 2517 | + } | |
| 2529 | 2518 | if (res != req->result) |
| 2530 | 2519 | req_set_fail_links(req); |
| 2531 | − | |
| 2532 | − if (req->rw.kiocb.ki_flags & IOCB_WRITE) | |
| 2533 | − kiocb_end_write(req); | |
| 2534 | 2520 | if (req->flags & REQ_F_BUFFER_SELECTED) |
| 2535 | 2521 | cflags = io_put_rw_kbuf(req); |
| 2536 | 2522 | __io_req_complete(req, issue_flags, res, cflags); |
| @@ -3307,11 +3293,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags) · 770 unmodified lines | ||
| 3307 | 3293 | |
| 3308 | 3294 | ret = io_iter_do_read(req, iter); |
| 3309 | 3295 | |
| 3310 | − if (ret == -EIOCBQUEUED) { | |
| 3311 | − if (req->async_data) | |
| 3312 | − iov_iter_revert(iter, io_size - iov_iter_count(iter)); | |
| 3313 | − goto out_free; | |
| 3314 | − } else if (ret == -EAGAIN) { | |
| 3296 | + if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) { | |
| 3315 | 3297 | /* IOPOLL retry should happen for io-wq threads */ |
| 3316 | 3298 | if (!force_nonblock && !(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 3317 | 3299 | goto done; |
| @@ -3321,6 +3303,8 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags) · 3 unmodified lines | ||
| 3321 | 3303 | /* some cases will consume bytes even on error returns */ |
| 3322 | 3304 | iov_iter_revert(iter, io_size - iov_iter_count(iter)); |
| 3323 | 3305 | ret = 0; |
| 3306 | + } else if (ret == -EIOCBQUEUED) { | |
| 3307 | + goto out_free; | |
| 3324 | 3308 | } else if (ret <= 0 || ret == io_size || !force_nonblock || |
| 3325 | 3309 | (req->flags & REQ_F_NOWAIT) || !(req->flags & REQ_F_ISREG)) { |
| 3326 | 3310 | /* read all, failed, already did sync or don't want to retry */ |
| @@ -3433,6 +3417,9 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) · 106 unmodified lines | ||
| 3433 | 3417 | else |
| 3434 | 3418 | ret2 = -EINVAL; |
| 3435 | 3419 | |
| 3420 | + if (req->flags & REQ_F_REISSUE) | |
| 3421 | + ret2 = -EAGAIN; | |
| 3422 | + | |
| 3436 | 3423 | /* |
| 3437 | 3424 | * Raw bdev writes will return -EOPNOTSUPP for IOCB_NOWAIT. Just |
| 3438 | 3425 | * retry them without IOCB_NOWAIT. |
| @@ -3442,8 +3429,6 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) · 3 unmodified lines | ||
| 3442 | 3429 | /* no retry on NONBLOCK nor RWF_NOWAIT */ |
| 3443 | 3430 | if (ret2 == -EAGAIN && (req->flags & REQ_F_NOWAIT)) |
| 3444 | 3431 | goto done; |
| 3445 | − if (ret2 == -EIOCBQUEUED && req->async_data) | |
| 3446 | − iov_iter_revert(iter, io_size - iov_iter_count(iter)); | |
| 3447 | 3432 | if (!force_nonblock || ret2 != -EAGAIN) { |
| 3448 | 3433 | /* IOPOLL retry should happen for io-wq threads */ |
| 3449 | 3434 | if ((req->ctx->flags & IORING_SETUP_IOPOLL) && ret2 == -EAGAIN) |
| @@ -3978,6 +3963,7 @@ static int io_remove_buffers(struct io_kiocb *req, unsigned int issue_flags) · 528 unmodified lines | ||
| 3978 | 3963 | static int io_provide_buffers_prep(struct io_kiocb *req, |
| 3979 | 3964 | const struct io_uring_sqe *sqe) |
| 3980 | 3965 | { |
| 3966 | + unsigned long size; | |
| 3981 | 3967 | struct io_provide_buf *p = &req->pbuf; |
| 3982 | 3968 | u64 tmp; |
| 3983 | 3969 | |
| @@ -3991,7 +3977,8 @@ static int io_provide_buffers_prep(struct io_kiocb *req, · 7 unmodified lines | ||
| 3991 | 3977 | p->addr = READ_ONCE(sqe->addr); |
| 3992 | 3978 | p->len = READ_ONCE(sqe->len); |
| 3993 | 3979 | |
| 3994 | − if (!access_ok(u64_to_user_ptr(p->addr), (p->len * p->nbufs))) | |
| 3980 | + size = (unsigned long)p->len * p->nbufs; | |
| 3981 | + if (!access_ok(u64_to_user_ptr(p->addr), size)) | |
| 3995 | 3982 | return -EFAULT; |
| 3996 | 3983 | |
| 3997 | 3984 | p->bgid = READ_ONCE(sqe->buf_group); |
| @@ -4820,7 +4807,6 @@ static int io_connect(struct io_kiocb *req, unsigned int issue_flags) · 822 unmodified lines | ||
| 4820 | 4807 | ret = -ENOMEM; |
| 4821 | 4808 | goto out; |
| 4822 | 4809 | } |
| 4823 | − io = req->async_data; | |
| 4824 | 4810 | memcpy(req->async_data, &__io, sizeof(__io)); |
| 4825 | 4811 | return -EAGAIN; |
| 4826 | 4812 | } |
| @@ -5583,7 +5569,8 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 756 unmodified lines | ||
| 5583 | 5569 | |
| 5584 | 5570 | data->mode = io_translate_timeout_mode(flags); |
| 5585 | 5571 | hrtimer_init(&data->timer, CLOCK_MONOTONIC, data->mode); |
| 5586 | − io_req_track_inflight(req); | |
| 5572 | + if (is_timeout_link) | |
| 5573 | + io_req_track_inflight(req); | |
| 5587 | 5574 | return 0; |
| 5588 | 5575 | } |
| 5589 | 5576 | |
| @@ -6186,6 +6173,7 @@ static void io_wq_submit_work(struct io_wq_work *work) · 596 unmodified lines | ||
| 6186 | 6173 | ret = -ECANCELED; |
| 6187 | 6174 | |
| 6188 | 6175 | if (!ret) { |
| 6176 | + req->flags &= ~REQ_F_REISSUE; | |
| 6189 | 6177 | do { |
| 6190 | 6178 | ret = io_issue_sqe(req, 0); |
| 6191 | 6179 | /* |
| @@ -6479,8 +6467,6 @@ static int io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 287 unmodified lines | ||
| 6479 | 6467 | ret = io_init_req(ctx, req, sqe); |
| 6480 | 6468 | if (unlikely(ret)) { |
| 6481 | 6469 | fail_req: |
| 6482 | − io_put_req(req); | |
| 6483 | − io_req_complete(req, ret); | |
| 6484 | 6470 | if (link->head) { |
| 6485 | 6471 | /* fail even hard links since we don't submit */ |
| 6486 | 6472 | link->head->flags |= REQ_F_FAIL_LINK; |
| @@ -6488,6 +6474,8 @@ fail_req: · 1 unmodified line | ||
| 6488 | 6474 | io_req_complete(link->head, -ECANCELED); |
| 6489 | 6475 | link->head = NULL; |
| 6490 | 6476 | } |
| 6477 | + io_put_req(req); | |
| 6478 | + io_req_complete(req, ret); | |
| 6491 | 6479 | return ret; |
| 6492 | 6480 | } |
| 6493 | 6481 | ret = io_req_prep(req, sqe); |
| @@ -6740,7 +6728,7 @@ static int io_sq_thread(void *data) · 246 unmodified lines | ||
| 6740 | 6728 | char buf[TASK_COMM_LEN]; |
| 6741 | 6729 | DEFINE_WAIT(wait); |
| 6742 | 6730 | |
| 6743 | − sprintf(buf, "iou-sqp-%d", sqd->task_pid); | |
| 6731 | + snprintf(buf, sizeof(buf), "iou-sqp-%d", sqd->task_pid); | |
| 6744 | 6732 | set_task_comm(current, buf); |
| 6745 | 6733 | current->pf_io_worker = NULL; |
| 6746 | 6734 | |
| @@ -6755,17 +6743,25 @@ static int io_sq_thread(void *data) · 8 unmodified lines | ||
| 6755 | 6743 | int ret; |
| 6756 | 6744 | bool cap_entries, sqt_spin, needs_sched; |
| 6757 | 6745 | |
| 6758 | − if (test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state)) { | |
| 6746 | + if (test_bit(IO_SQ_THREAD_SHOULD_PARK, &sqd->state) || | |
| 6747 | + signal_pending(current)) { | |
| 6748 | + bool did_sig = false; | |
| 6749 | + | |
| 6759 | 6750 | mutex_unlock(&sqd->lock); |
| 6751 | + if (signal_pending(current)) { | |
| 6752 | + struct ksignal ksig; | |
| 6753 | + | |
| 6754 | + did_sig = get_signal(&ksig); | |
| 6755 | + } | |
| 6760 | 6756 | cond_resched(); |
| 6761 | 6757 | mutex_lock(&sqd->lock); |
| 6758 | + if (did_sig) | |
| 6759 | + break; | |
| 6762 | 6760 | io_run_task_work(); |
| 6763 | 6761 | io_run_task_work_head(&sqd->park_task_work); |
| 6764 | 6762 | timeout = jiffies + sqd->sq_thread_idle; |
| 6765 | 6763 | continue; |
| 6766 | 6764 | } |
| 6767 | − if (fatal_signal_pending(current)) | |
| 6768 | − break; | |
| 6769 | 6765 | sqt_spin = false; |
| 6770 | 6766 | cap_entries = !list_is_singular(&sqd->ctx_list); |
| 6771 | 6767 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { |
| @@ -6808,7 +6804,6 @@ static int io_sq_thread(void *data) · 36 unmodified lines | ||
| 6808 | 6804 | |
| 6809 | 6805 | mutex_unlock(&sqd->lock); |
| 6810 | 6806 | schedule(); |
| 6811 | − try_to_freeze(); | |
| 6812 | 6807 | mutex_lock(&sqd->lock); |
| 6813 | 6808 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) |
| 6814 | 6809 | io_ring_clear_wakeup_flag(ctx); |
| @@ -6873,7 +6868,7 @@ static int io_run_task_work_sig(void) · 58 unmodified lines | ||
| 6873 | 6868 | return 1; |
| 6874 | 6869 | if (!signal_pending(current)) |
| 6875 | 6870 | return 0; |
| 6876 | − if (test_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL)) | |
| 6871 | + if (test_thread_flag(TIF_NOTIFY_SIGNAL)) | |
| 6877 | 6872 | return -ERESTARTSYS; |
| 6878 | 6873 | return -EINTR; |
| 6879 | 6874 | } |
| @@ -8563,6 +8558,14 @@ static void io_ring_exit_work(struct work_struct *work) · 1683 unmodified lines | ||
| 8563 | 8558 | struct io_tctx_node *node; |
| 8564 | 8559 | int ret; |
| 8565 | 8560 | |
| 8561 | + /* prevent SQPOLL from submitting new requests */ | |
| 8562 | + if (ctx->sq_data) { | |
| 8563 | + io_sq_thread_park(ctx->sq_data); | |
| 8564 | + list_del_init(&ctx->sqd_list); | |
| 8565 | + io_sqd_update_thread_idle(ctx->sq_data); | |
| 8566 | + io_sq_thread_unpark(ctx->sq_data); | |
| 8567 | + } | |
| 8568 | + | |
| 8566 | 8569 | /* |
| 8567 | 8570 | * If we're doing polled IO and end up having requests being |
| 8568 | 8571 | * submitted async (out-of-line), then completions can come in while |
| @@ -8599,6 +8602,28 @@ static void io_ring_exit_work(struct work_struct *work) · 30 unmodified lines | ||
| 8599 | 8602 | io_ring_ctx_free(ctx); |
| 8600 | 8603 | } |
| 8601 | 8604 | |
| 8605 | +/* Returns true if we found and killed one or more timeouts */ | |
| 8606 | +static bool io_kill_timeouts(struct io_ring_ctx *ctx, struct task_struct *tsk, | |
| 8607 | + struct files_struct *files) | |
| 8608 | +{ | |
| 8609 | + struct io_kiocb *req, *tmp; | |
| 8610 | + int canceled = 0; | |
| 8611 | + | |
| 8612 | + spin_lock_irq(&ctx->completion_lock); | |
| 8613 | + list_for_each_entry_safe(req, tmp, &ctx->timeout_list, timeout.list) { | |
| 8614 | + if (io_match_task(req, tsk, files)) { | |
| 8615 | + io_kill_timeout(req, -ECANCELED); | |
| 8616 | + canceled++; | |
| 8617 | + } | |
| 8618 | + } | |
| 8619 | + if (canceled != 0) | |
| 8620 | + io_commit_cqring(ctx); | |
| 8621 | + spin_unlock_irq(&ctx->completion_lock); | |
| 8622 | + if (canceled != 0) | |
| 8623 | + io_cqring_ev_posted(ctx); | |
| 8624 | + return canceled != 0; | |
| 8625 | +} | |
| 8626 | + | |
| 8602 | 8627 | static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) |
| 8603 | 8628 | { |
| 8604 | 8629 | unsigned long index; |
| @@ -8614,14 +8639,6 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) · 9 unmodified lines | ||
| 8614 | 8639 | io_unregister_personality(ctx, index); |
| 8615 | 8640 | mutex_unlock(&ctx->uring_lock); |
| 8616 | 8641 | |
| 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 | − | |
| 8625 | 8642 | io_kill_timeouts(ctx, NULL, NULL); |
| 8626 | 8643 | io_poll_remove_all(ctx, NULL, NULL); |
| 8627 | 8644 | |
| @@ -8998,6 +9015,8 @@ void __io_uring_task_cancel(void) · 370 unmodified lines | ||
| 8998 | 9015 | |
| 8999 | 9016 | /* make sure overflow events are dropped */ |
| 9000 | 9017 | atomic_inc(&tctx->in_idle); |
| 9018 | + __io_uring_files_cancel(NULL); | |
| 9019 | + | |
| 9001 | 9020 | do { |
| 9002 | 9021 | /* read completions before cancelations */ |
| 9003 | 9022 | inflight = tctx_inflight(tctx); |
| @@ -44,7 +44,7 @@ void reiserfs_security_free(struct reiserfs_security_handle *sec); · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | static inline int reiserfs_xattrs_initialized(struct super_block *sb) |
| 46 | 46 | { |
| 47 | − return REISERFS_SB(sb)->priv_root != NULL; | |
| 47 | + return REISERFS_SB(sb)->priv_root && REISERFS_SB(sb)->xattr_root; | |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | #define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header)) |
| @@ -152,14 +152,18 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, · 151 unmodified lines | ||
| 152 | 152 | start = le64_to_cpu(table[n]); |
| 153 | 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 | 158 | kfree(table); |
| 157 | 159 | return ERR_PTR(-EINVAL); |
| 158 | 160 | } |
| 159 | 161 | } |
| 160 | 162 | |
| 161 | 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 | 167 | kfree(table); |
| 164 | 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 | 97 | start = le64_to_cpu(table[n]); |
| 98 | 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 | 102 | kfree(table); |
| 102 | 103 | return ERR_PTR(-EINVAL); |
| 103 | 104 | } |
| 104 | 105 | } |
| 105 | 106 | |
| 106 | 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 | 110 | kfree(table); |
| 109 | 111 | return ERR_PTR(-EINVAL); |
| 110 | 112 | } |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | /* size of metadata (inode and directory) blocks */ |
| 19 | 19 | #define SQUASHFS_METADATA_SIZE 8192 |
| 20 | +#define SQUASHFS_BLOCK_OFFSET 2 | |
| 20 | 21 | |
| 21 | 22 | /* default size of block device I/O */ |
| 22 | 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 | 109 | start = le64_to_cpu(table[n]); |
| 110 | 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 | 114 | kfree(table); |
| 114 | 115 | return ERR_PTR(-EINVAL); |
| 115 | 116 | } |
| 116 | 117 | } |
| 117 | 118 | |
| 118 | 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 | 122 | kfree(table); |
| 121 | 123 | return ERR_PTR(-EINVAL); |
| 122 | 124 | } |
| @@ -233,6 +233,7 @@ struct acpi_pnp_type { · 232 unmodified lines | ||
| 233 | 233 | |
| 234 | 234 | struct acpi_device_pnp { |
| 235 | 235 | acpi_bus_id bus_id; /* Object name */ |
| 236 | + int instance_no; /* Instance number of this object */ | |
| 236 | 237 | struct acpi_pnp_type type; /* ID type */ |
| 237 | 238 | acpi_bus_address bus_address; /* _ADR */ |
| 238 | 239 | char *unique_id; /* _UID */ |
| @@ -222,10 +222,14 @@ void __iomem *__acpi_map_table(unsigned long phys, unsigned long size); · 221 unmodified lines | ||
| 222 | 222 | void __acpi_unmap_table(void __iomem *map, unsigned long size); |
| 223 | 223 | int early_acpi_boot_init(void); |
| 224 | 224 | int acpi_boot_init (void); |
| 225 | +void acpi_boot_table_prepare (void); | |
| 225 | 226 | void acpi_boot_table_init (void); |
| 226 | 227 | int acpi_mps_check (void); |
| 227 | 228 | int acpi_numa_init (void); |
| 228 | 229 | |
| 230 | +int acpi_locate_initial_tables (void); | |
| 231 | +void acpi_reserve_initial_tables (void); | |
| 232 | +void acpi_table_init_complete (void); | |
| 229 | 233 | int acpi_table_init (void); |
| 230 | 234 | int acpi_table_parse(char *id, acpi_tbl_table_handler handler); |
| 231 | 235 | int __init acpi_table_parse_entries(char *id, unsigned long table_size, |
| @@ -814,9 +818,12 @@ static inline int acpi_boot_init(void) · 582 unmodified lines | ||
| 814 | 818 | return 0; |
| 815 | 819 | } |
| 816 | 820 | |
| 821 | +static inline void acpi_boot_table_prepare(void) | |
| 822 | +{ | |
| 823 | +} | |
| 824 | + | |
| 817 | 825 | static inline void acpi_boot_table_init(void) |
| 818 | 826 | { |
| 819 | − return; | |
| 820 | 827 | } |
| 821 | 828 | |
| 822 | 829 | static inline int acpi_mps_check(void) |
| @@ -85,8 +85,6 @@ typedef __u32 __bitwise req_flags_t; · 84 unmodified lines | ||
| 85 | 85 | #define RQF_ELVPRIV ((__force req_flags_t)(1 << 12)) |
| 86 | 86 | /* account into disk and partition IO statistics */ |
| 87 | 87 | #define RQF_IO_STAT ((__force req_flags_t)(1 << 13)) |
| 88 | −/* request came from our alloc pool */ | |
| 89 | −#define RQF_ALLOCED ((__force req_flags_t)(1 << 14)) | |
| 90 | 88 | /* runtime pm request */ |
| 91 | 89 | #define RQF_PM ((__force req_flags_t)(1 << 15)) |
| 92 | 90 | /* on IO scheduler merge hash */ |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/capability.h> |
| 22 | 22 | #include <linux/sched/mm.h> |
| 23 | 23 | #include <linux/slab.h> |
| 24 | +#include <linux/percpu-refcount.h> | |
| 24 | 25 | |
| 25 | 26 | struct bpf_verifier_env; |
| 26 | 27 | struct bpf_verifier_log; |
| @@ -556,7 +557,8 @@ struct bpf_tramp_progs { · 529 unmodified lines | ||
| 556 | 557 | * fentry = a set of program to run before calling original function |
| 557 | 558 | * fexit = a set of program to run after original function |
| 558 | 559 | */ |
| 559 | −int arch_prepare_bpf_trampoline(void *image, void *image_end, | |
| 560 | +struct bpf_tramp_image; | |
| 561 | +int arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end, | |
| 560 | 562 | const struct btf_func_model *m, u32 flags, |
| 561 | 563 | struct bpf_tramp_progs *tprogs, |
| 562 | 564 | void *orig_call); |
| @@ -565,6 +567,8 @@ u64 notrace __bpf_prog_enter(struct bpf_prog *prog); · 2 unmodified lines | ||
| 565 | 567 | void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start); |
| 566 | 568 | u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog); |
| 567 | 569 | void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start); |
| 570 | +void notrace __bpf_tramp_enter(struct bpf_tramp_image *tr); | |
| 571 | +void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr); | |
| 568 | 572 | |
| 569 | 573 | struct bpf_ksym { |
| 570 | 574 | unsigned long start; |
| @@ -583,6 +587,18 @@ enum bpf_tramp_prog_type { · 12 unmodified lines | ||
| 583 | 587 | BPF_TRAMP_REPLACE, /* more than MAX */ |
| 584 | 588 | }; |
| 585 | 589 | |
| 590 | +struct bpf_tramp_image { | |
| 591 | + void *image; | |
| 592 | + struct bpf_ksym ksym; | |
| 593 | + struct percpu_ref pcref; | |
| 594 | + void *ip_after_call; | |
| 595 | + void *ip_epilogue; | |
| 596 | + union { | |
| 597 | + struct rcu_head rcu; | |
| 598 | + struct work_struct work; | |
| 599 | + }; | |
| 600 | +}; | |
| 601 | + | |
| 586 | 602 | struct bpf_trampoline { |
| 587 | 603 | /* hlist for trampoline_table */ |
| 588 | 604 | struct hlist_node hlist; |
| @@ -605,9 +621,8 @@ struct bpf_trampoline { · 16 unmodified lines | ||
| 605 | 621 | /* Number of attached programs. A counter per kind. */ |
| 606 | 622 | int progs_cnt[BPF_TRAMP_MAX]; |
| 607 | 623 | /* Executable image of trampoline */ |
| 608 | − void *image; | |
| 624 | + struct bpf_tramp_image *cur_image; | |
| 609 | 625 | u64 selector; |
| 610 | − struct bpf_ksym ksym; | |
| 611 | 626 | }; |
| 612 | 627 | |
| 613 | 628 | struct bpf_attach_target_info { |
| @@ -691,6 +706,8 @@ void bpf_image_ksym_add(void *data, struct bpf_ksym *ksym); · 77 unmodified lines | ||
| 691 | 706 | void bpf_image_ksym_del(struct bpf_ksym *ksym); |
| 692 | 707 | void bpf_ksym_add(struct bpf_ksym *ksym); |
| 693 | 708 | void bpf_ksym_del(struct bpf_ksym *ksym); |
| 709 | +int bpf_jit_charge_modmem(u32 pages); | |
| 710 | +void bpf_jit_uncharge_modmem(u32 pages); | |
| 694 | 711 | #else |
| 695 | 712 | static inline int bpf_trampoline_link_prog(struct bpf_prog *prog, |
| 696 | 713 | struct bpf_trampoline *tr) |
| @@ -787,7 +804,6 @@ struct bpf_prog_aux { · 90 unmodified lines | ||
| 787 | 804 | bool func_proto_unreliable; |
| 788 | 805 | bool sleepable; |
| 789 | 806 | bool tail_call_reachable; |
| 790 | − enum bpf_tramp_prog_type trampoline_prog_type; | |
| 791 | 807 | struct hlist_node tramp_hlist; |
| 792 | 808 | /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */ |
| 793 | 809 | const struct btf_type *attach_func_proto; |
| @@ -1093,7 +1109,7 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array, · 299 unmodified lines | ||
| 1093 | 1109 | _ret; \ |
| 1094 | 1110 | }) |
| 1095 | 1111 | |
| 1096 | −#define __BPF_PROG_RUN_ARRAY(array, ctx, func, check_non_null) \ | |
| 1112 | +#define __BPF_PROG_RUN_ARRAY(array, ctx, func, check_non_null, set_cg_storage) \ | |
| 1097 | 1113 | ({ \ |
| 1098 | 1114 | struct bpf_prog_array_item *_item; \ |
| 1099 | 1115 | struct bpf_prog *_prog; \ |
| @@ -1106,7 +1122,8 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array, · 6 unmodified lines | ||
| 1106 | 1122 | goto _out; \ |
| 1107 | 1123 | _item = &_array->items[0]; \ |
| 1108 | 1124 | while ((_prog = READ_ONCE(_item->prog))) { \ |
| 1109 | − bpf_cgroup_storage_set(_item->cgroup_storage); \ | |
| 1125 | + if (set_cg_storage) \ | |
| 1126 | + bpf_cgroup_storage_set(_item->cgroup_storage); \ | |
| 1110 | 1127 | _ret &= func(_prog, ctx); \ |
| 1111 | 1128 | _item++; \ |
| 1112 | 1129 | } \ |
| @@ -1153,10 +1170,10 @@ _out: \ · 40 unmodified lines | ||
| 1153 | 1170 | }) |
| 1154 | 1171 | |
| 1155 | 1172 | #define BPF_PROG_RUN_ARRAY(array, ctx, func) \ |
| 1156 | − __BPF_PROG_RUN_ARRAY(array, ctx, func, false) | |
| 1173 | + __BPF_PROG_RUN_ARRAY(array, ctx, func, false, true) | |
| 1157 | 1174 | |
| 1158 | 1175 | #define BPF_PROG_RUN_ARRAY_CHECK(array, ctx, func) \ |
| 1159 | − __BPF_PROG_RUN_ARRAY(array, ctx, func, true) | |
| 1176 | + __BPF_PROG_RUN_ARRAY(array, ctx, func, true, false) | |
| 1160 | 1177 | |
| 1161 | 1178 | #ifdef CONFIG_BPF_SYSCALL |
| 1162 | 1179 | DECLARE_PER_CPU(int, bpf_prog_active); |
| @@ -253,7 +253,11 @@ struct target_type { · 252 unmodified lines | ||
| 253 | 253 | #define dm_target_passes_integrity(type) ((type)->features & DM_TARGET_PASSES_INTEGRITY) |
| 254 | 254 | |
| 255 | 255 | /* |
| 256 | − * Indicates that a target supports host-managed zoned block devices. | |
| 256 | + * Indicates support for zoned block devices: | |
| 257 | + * - DM_TARGET_ZONED_HM: the target also supports host-managed zoned | |
| 258 | + * block devices but does not support combining different zoned models. | |
| 259 | + * - DM_TARGET_MIXED_ZONED_MODEL: the target supports combining multiple | |
| 260 | + * devices with different zoned models. | |
| 257 | 261 | */ |
| 258 | 262 | #ifdef CONFIG_BLK_DEV_ZONED |
| 259 | 263 | #define DM_TARGET_ZONED_HM 0x00000040 |
| @@ -275,6 +279,15 @@ struct target_type { · 15 unmodified lines | ||
| 275 | 279 | #define DM_TARGET_PASSES_CRYPTO 0x00000100 |
| 276 | 280 | #define dm_target_passes_crypto(type) ((type)->features & DM_TARGET_PASSES_CRYPTO) |
| 277 | 281 | |
| 282 | +#ifdef CONFIG_BLK_DEV_ZONED | |
| 283 | +#define DM_TARGET_MIXED_ZONED_MODEL 0x00000200 | |
| 284 | +#define dm_target_supports_mixed_zoned_model(type) \ | |
| 285 | + ((type)->features & DM_TARGET_MIXED_ZONED_MODEL) | |
| 286 | +#else | |
| 287 | +#define DM_TARGET_MIXED_ZONED_MODEL 0x00000000 | |
| 288 | +#define dm_target_supports_mixed_zoned_model(type) (false) | |
| 289 | +#endif | |
| 290 | + | |
| 278 | 291 | struct dm_target { |
| 279 | 292 | struct dm_table *table; |
| 280 | 293 | struct target_type *type; |
| @@ -271,6 +271,29 @@ static inline void devm_extcon_unregister_notifier(struct device *dev, · 270 unmodified lines | ||
| 271 | 271 | struct extcon_dev *edev, unsigned int id, |
| 272 | 272 | struct notifier_block *nb) { } |
| 273 | 273 | |
| 274 | +static inline int extcon_register_notifier_all(struct extcon_dev *edev, | |
| 275 | + struct notifier_block *nb) | |
| 276 | +{ | |
| 277 | + return 0; | |
| 278 | +} | |
| 279 | + | |
| 280 | +static inline int extcon_unregister_notifier_all(struct extcon_dev *edev, | |
| 281 | + struct notifier_block *nb) | |
| 282 | +{ | |
| 283 | + return 0; | |
| 284 | +} | |
| 285 | + | |
| 286 | +static inline int devm_extcon_register_notifier_all(struct device *dev, | |
| 287 | + struct extcon_dev *edev, | |
| 288 | + struct notifier_block *nb) | |
| 289 | +{ | |
| 290 | + return 0; | |
| 291 | +} | |
| 292 | + | |
| 293 | +static inline void devm_extcon_unregister_notifier_all(struct device *dev, | |
| 294 | + struct extcon_dev *edev, | |
| 295 | + struct notifier_block *nb) { } | |
| 296 | + | |
| 274 | 297 | static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) |
| 275 | 298 | { |
| 276 | 299 | return ERR_PTR(-ENODEV); |
| @@ -56,7 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | * COMMAND_RECONFIG_FLAG_PARTIAL: |
| 57 | 57 | * Set to FPGA configuration type (full or partial). |
| 58 | 58 | */ |
| 59 | −#define COMMAND_RECONFIG_FLAG_PARTIAL 1 | |
| 59 | +#define COMMAND_RECONFIG_FLAG_PARTIAL 0 | |
| 60 | 60 | |
| 61 | 61 | /* |
| 62 | 62 | * Timeout settings for service clients: |
| @@ -320,7 +320,14 @@ static inline struct host1x_device *to_host1x_device(struct device *dev) · 319 unmodified lines | ||
| 320 | 320 | int host1x_device_init(struct host1x_device *device); |
| 321 | 321 | int host1x_device_exit(struct host1x_device *device); |
| 322 | 322 | |
| 323 | −int host1x_client_register(struct host1x_client *client); | |
| 323 | +int __host1x_client_register(struct host1x_client *client, | |
| 324 | + struct lock_class_key *key); | |
| 325 | +#define host1x_client_register(class) \ | |
| 326 | + ({ \ | |
| 327 | + static struct lock_class_key __key; \ | |
| 328 | + __host1x_client_register(class, &__key); \ | |
| 329 | + }) | |
| 330 | + | |
| 324 | 331 | int host1x_client_unregister(struct host1x_client *client); |
| 325 | 332 | |
| 326 | 333 | int host1x_client_suspend(struct host1x_client *client); |
| @@ -113,6 +113,11 @@ static inline bool hugetlb_cgroup_disabled(void) · 112 unmodified lines | ||
| 113 | 113 | return !cgroup_subsys_enabled(hugetlb_cgrp_subsys); |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | +static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) | |
| 117 | +{ | |
| 118 | + css_put(&h_cg->css); | |
| 119 | +} | |
| 120 | + | |
| 116 | 121 | extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, |
| 117 | 122 | struct hugetlb_cgroup **ptr); |
| 118 | 123 | extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages, |
| @@ -138,7 +143,8 @@ extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, · 19 unmodified lines | ||
| 138 | 143 | |
| 139 | 144 | extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, |
| 140 | 145 | struct file_region *rg, |
| 141 | − unsigned long nr_pages); | |
| 146 | + unsigned long nr_pages, | |
| 147 | + bool region_del); | |
| 142 | 148 | |
| 143 | 149 | extern void hugetlb_cgroup_file_init(void) __init; |
| 144 | 150 | extern void hugetlb_cgroup_migrate(struct page *oldhpage, |
| @@ -147,7 +153,8 @@ extern void hugetlb_cgroup_migrate(struct page *oldhpage, · 2 unmodified lines | ||
| 147 | 153 | #else |
| 148 | 154 | static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, |
| 149 | 155 | struct file_region *rg, |
| 150 | − unsigned long nr_pages) | |
| 156 | + unsigned long nr_pages, | |
| 157 | + bool region_del) | |
| 151 | 158 | { |
| 152 | 159 | } |
| 153 | 160 | |
| @@ -185,6 +192,10 @@ static inline bool hugetlb_cgroup_disabled(void) · 31 unmodified lines | ||
| 185 | 192 | return true; |
| 186 | 193 | } |
| 187 | 194 | |
| 195 | +static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) | |
| 196 | +{ | |
| 197 | +} | |
| 198 | + | |
| 188 | 199 | static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, |
| 189 | 200 | struct hugetlb_cgroup **ptr) |
| 190 | 201 | { |
| @@ -43,13 +43,14 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, · 42 unmodified lines | ||
| 43 | 43 | if (likely(success)) { |
| 44 | 44 | struct vlan_pcpu_stats *pcpu_stats; |
| 45 | 45 | |
| 46 | − pcpu_stats = this_cpu_ptr(vlan->pcpu_stats); | |
| 46 | + pcpu_stats = get_cpu_ptr(vlan->pcpu_stats); | |
| 47 | 47 | u64_stats_update_begin(&pcpu_stats->syncp); |
| 48 | 48 | pcpu_stats->rx_packets++; |
| 49 | 49 | pcpu_stats->rx_bytes += len; |
| 50 | 50 | if (multicast) |
| 51 | 51 | pcpu_stats->rx_multicast++; |
| 52 | 52 | u64_stats_update_end(&pcpu_stats->syncp); |
| 53 | + put_cpu_ptr(vlan->pcpu_stats); | |
| 53 | 54 | } else { |
| 54 | 55 | this_cpu_inc(vlan->pcpu_stats->rx_errors); |
| 55 | 56 | } |
| @@ -460,7 +460,7 @@ static inline void memblock_free_late(phys_addr_t base, phys_addr_t size) · 459 unmodified lines | ||
| 460 | 460 | /* |
| 461 | 461 | * Set the allocation direction to bottom-up or top-down. |
| 462 | 462 | */ |
| 463 | −static inline __init void memblock_set_bottom_up(bool enable) | |
| 463 | +static inline __init_memblock void memblock_set_bottom_up(bool enable) | |
| 464 | 464 | { |
| 465 | 465 | memblock.bottom_up = enable; |
| 466 | 466 | } |
| @@ -470,7 +470,7 @@ static inline __init void memblock_set_bottom_up(bool enable) · 3 unmodified lines | ||
| 470 | 470 | * if this is true, that said, memblock will allocate memory |
| 471 | 471 | * in bottom-up direction. |
| 472 | 472 | */ |
| 473 | −static inline __init bool memblock_bottom_up(void) | |
| 473 | +static inline __init_memblock bool memblock_bottom_up(void) | |
| 474 | 474 | { |
| 475 | 475 | return memblock.bottom_up; |
| 476 | 476 | } |
| @@ -547,4 +547,11 @@ static inline const char *mlx5_qp_state_str(int state) · 546 unmodified lines | ||
| 547 | 547 | } |
| 548 | 548 | } |
| 549 | 549 | |
| 550 | +static inline int mlx5_get_qp_default_ts(struct mlx5_core_dev *dev) | |
| 551 | +{ | |
| 552 | + return !MLX5_CAP_ROCE(dev, qp_ts_format) ? | |
| 553 | + MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING : | |
| 554 | + MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT; | |
| 555 | +} | |
| 556 | + | |
| 550 | 557 | #endif /* MLX5_QP_H */ |
| @@ -1461,16 +1461,28 @@ static inline bool cpupid_match_pid(struct task_struct *task, int cpupid) · 1460 unmodified lines | ||
| 1461 | 1461 | |
| 1462 | 1462 | #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) |
| 1463 | 1463 | |
| 1464 | +/* | |
| 1465 | + * KASAN per-page tags are stored xor'ed with 0xff. This allows to avoid | |
| 1466 | + * setting tags for all pages to native kernel tag value 0xff, as the default | |
| 1467 | + * value 0x00 maps to 0xff. | |
| 1468 | + */ | |
| 1469 | + | |
| 1464 | 1470 | static inline u8 page_kasan_tag(const struct page *page) |
| 1465 | 1471 | { |
| 1466 | − if (kasan_enabled()) | |
| 1467 | − return (page->flags >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; | |
| 1468 | − return 0xff; | |
| 1472 | + u8 tag = 0xff; | |
| 1473 | + | |
| 1474 | + if (kasan_enabled()) { | |
| 1475 | + tag = (page->flags >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; | |
| 1476 | + tag ^= 0xff; | |
| 1477 | + } | |
| 1478 | + | |
| 1479 | + return tag; | |
| 1469 | 1480 | } |
| 1470 | 1481 | |
| 1471 | 1482 | static inline void page_kasan_tag_set(struct page *page, u8 tag) |
| 1472 | 1483 | { |
| 1473 | 1484 | if (kasan_enabled()) { |
| 1485 | + tag ^= 0xff; | |
| 1474 | 1486 | page->flags &= ~(KASAN_TAG_MASK << KASAN_TAG_PGSHIFT); |
| 1475 | 1487 | page->flags |= (tag & KASAN_TAG_MASK) << KASAN_TAG_PGSHIFT; |
| 1476 | 1488 | } |
| @@ -169,11 +169,11 @@ struct mmu_notifier_ops { · 168 unmodified lines | ||
| 169 | 169 | * the last refcount is dropped. |
| 170 | 170 | * |
| 171 | 171 | * If blockable argument is set to false then the callback cannot |
| 172 | − * sleep and has to return with -EAGAIN. 0 should be returned | |
| 173 | − * otherwise. Please note that if invalidate_range_start approves | |
| 174 | − * a non-blocking behavior then the same applies to | |
| 175 | − * invalidate_range_end. | |
| 176 | − * | |
| 172 | + * sleep and has to return with -EAGAIN if sleeping would be required. | |
| 173 | + * 0 should be returned otherwise. Please note that notifiers that can | |
| 174 | + * fail invalidate_range_start are not allowed to implement | |
| 175 | + * invalidate_range_end, as there is no mechanism for informing the | |
| 176 | + * notifier that its start failed. | |
| 177 | 177 | */ |
| 178 | 178 | int (*invalidate_range_start)(struct mmu_notifier *subscription, |
| 179 | 179 | const struct mmu_notifier_range *range); |
| @@ -185,7 +185,7 @@ extern void mutex_lock_io(struct mutex *lock); · 184 unmodified lines | ||
| 185 | 185 | # define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock) |
| 186 | 186 | # define mutex_lock_killable_nested(lock, subclass) mutex_lock_killable(lock) |
| 187 | 187 | # define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) |
| 188 | −# define mutex_lock_io_nested(lock, subclass) mutex_lock(lock) | |
| 188 | +# define mutex_lock_io_nested(lock, subclass) mutex_lock_io(lock) | |
| 189 | 189 | #endif |
| 190 | 190 | |
| 191 | 191 | /* |
| @@ -360,6 +360,7 @@ enum { · 359 unmodified lines | ||
| 360 | 360 | NAPI_STATE_IN_BUSY_POLL, /* sk_busy_loop() owns this NAPI */ |
| 361 | 361 | NAPI_STATE_PREFER_BUSY_POLL, /* prefer busy-polling over softirq processing*/ |
| 362 | 362 | NAPI_STATE_THREADED, /* The poll is performed inside its own thread*/ |
| 363 | + NAPI_STATE_SCHED_THREADED, /* Napi is currently scheduled in threaded mode */ | |
| 363 | 364 | }; |
| 364 | 365 | |
| 365 | 366 | enum { |
| @@ -372,6 +373,7 @@ enum { · 6 unmodified lines | ||
| 372 | 373 | NAPIF_STATE_IN_BUSY_POLL = BIT(NAPI_STATE_IN_BUSY_POLL), |
| 373 | 374 | NAPIF_STATE_PREFER_BUSY_POLL = BIT(NAPI_STATE_PREFER_BUSY_POLL), |
| 374 | 375 | NAPIF_STATE_THREADED = BIT(NAPI_STATE_THREADED), |
| 376 | + NAPIF_STATE_SCHED_THREADED = BIT(NAPI_STATE_SCHED_THREADED), | |
| 375 | 377 | }; |
| 376 | 378 | |
| 377 | 379 | enum gro_result { |
| @@ -227,7 +227,7 @@ struct xt_table { · 226 unmodified lines | ||
| 227 | 227 | unsigned int valid_hooks; |
| 228 | 228 | |
| 229 | 229 | /* Man behind the curtain... */ |
| 230 | − struct xt_table_info __rcu *private; | |
| 230 | + struct xt_table_info *private; | |
| 231 | 231 | |
| 232 | 232 | /* Set this to THIS_MODULE if you are a module, otherwise NULL */ |
| 233 | 233 | struct module *me; |
| @@ -376,7 +376,7 @@ static inline unsigned int xt_write_recseq_begin(void) · 142 unmodified lines | ||
| 376 | 376 | * since addend is most likely 1 |
| 377 | 377 | */ |
| 378 | 378 | __this_cpu_add(xt_recseq.sequence, addend); |
| 379 | − smp_wmb(); | |
| 379 | + smp_mb(); | |
| 380 | 380 | |
| 381 | 381 | return addend; |
| 382 | 382 | } |
| @@ -448,9 +448,6 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu) · 65 unmodified lines | ||
| 448 | 448 | |
| 449 | 449 | struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *); |
| 450 | 450 | |
| 451 | −struct xt_table_info | |
| 452 | −*xt_table_get_private_protected(const struct xt_table *table); | |
| 453 | − | |
| 454 | 451 | #ifdef CONFIG_COMPAT |
| 455 | 452 | #include <net/compat.h> |
| 456 | 453 | |
| @@ -559,7 +559,6 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma, · 558 unmodified lines | ||
| 559 | 559 | return pgoff; |
| 560 | 560 | } |
| 561 | 561 | |
| 562 | −/* This has the same layout as wait_bit_key - see fs/cachefiles/rdwr.c */ | |
| 563 | 562 | struct wait_page_key { |
| 564 | 563 | struct page *page; |
| 565 | 564 | int bit_nr; |
| @@ -683,6 +682,7 @@ static inline int wait_on_page_locked_killable(struct page *page) · 117 unmodified lines | ||
| 683 | 682 | |
| 684 | 683 | int put_and_wait_on_page_locked(struct page *page, int state); |
| 685 | 684 | void wait_on_page_writeback(struct page *page); |
| 685 | +int wait_on_page_writeback_killable(struct page *page); | |
| 686 | 686 | extern void end_page_writeback(struct page *page); |
| 687 | 687 | void wait_for_stable_page(struct page *page); |
| 688 | 688 | |
| @@ -460,7 +460,5 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag); · 459 unmodified lines | ||
| 460 | 460 | int geni_icc_enable(struct geni_se *se); |
| 461 | 461 | |
| 462 | 462 | int geni_icc_disable(struct geni_se *se); |
| 463 | − | |
| 464 | −void geni_remove_earlycon_icc_vote(void); | |
| 465 | 463 | #endif |
| 466 | 464 | #endif |
| @@ -285,6 +285,7 @@ struct nf_bridge_info { · 284 unmodified lines | ||
| 285 | 285 | struct tc_skb_ext { |
| 286 | 286 | __u32 chain; |
| 287 | 287 | __u16 mru; |
| 288 | + bool post_ct; | |
| 288 | 289 | }; |
| 289 | 290 | #endif |
| 290 | 291 | |
| @@ -14,5 +14,6 @@ struct umd_info { · 13 unmodified lines | ||
| 14 | 14 | int umd_load_blob(struct umd_info *info, const void *data, size_t len); |
| 15 | 15 | int umd_unload_blob(struct umd_info *info); |
| 16 | 16 | int fork_usermode_driver(struct umd_info *info); |
| 17 | +void umd_cleanup_helper(struct umd_info *info); | |
| 17 | 18 | |
| 18 | 19 | #endif /* __LINUX_USERMODE_DRIVER_H__ */ |
| @@ -229,9 +229,10 @@ static inline int xa_err(void *entry) · 228 unmodified lines | ||
| 229 | 229 | * |
| 230 | 230 | * This structure is used either directly or via the XA_LIMIT() macro |
| 231 | 231 | * to communicate the range of IDs that are valid for allocation. |
| 232 | − * Two common ranges are predefined for you: | |
| 232 | + * Three common ranges are predefined for you: | |
| 233 | 233 | * * xa_limit_32b - [0 - UINT_MAX] |
| 234 | 234 | * * xa_limit_31b - [0 - INT_MAX] |
| 235 | + * * xa_limit_16b - [0 - USHRT_MAX] | |
| 235 | 236 | */ |
| 236 | 237 | struct xa_limit { |
| 237 | 238 | u32 max; |
| @@ -242,6 +243,7 @@ struct xa_limit { · 4 unmodified lines | ||
| 242 | 243 | |
| 243 | 244 | #define xa_limit_32b XA_LIMIT(0, UINT_MAX) |
| 244 | 245 | #define xa_limit_31b XA_LIMIT(0, INT_MAX) |
| 246 | +#define xa_limit_16b XA_LIMIT(0, USHRT_MAX) | |
| 245 | 247 | |
| 246 | 248 | typedef unsigned __bitwise xa_mark_t; |
| 247 | 249 | #define XA_MARK_0 ((__force xa_mark_t)0U) |
| @@ -550,4 +550,15 @@ static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu) · 549 unmodified lines | ||
| 550 | 550 | dst->ops->update_pmtu(dst, NULL, skb, mtu, false); |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | +struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); | |
| 554 | +void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, | |
| 555 | + struct sk_buff *skb, u32 mtu, bool confirm_neigh); | |
| 556 | +void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk, | |
| 557 | + struct sk_buff *skb); | |
| 558 | +u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old); | |
| 559 | +struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst, | |
| 560 | + struct sk_buff *skb, | |
| 561 | + const void *daddr); | |
| 562 | +unsigned int dst_blackhole_mtu(const struct dst_entry *dst); | |
| 563 | + | |
| 553 | 564 | #endif /* _NET_DST_H */ |
| @@ -282,7 +282,7 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) · 281 unmodified lines | ||
| 282 | 282 | return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog; |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | −void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); | |
| 285 | +bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); | |
| 286 | 286 | void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req); |
| 287 | 287 | |
| 288 | 288 | static inline void inet_csk_prepare_for_destroy_sock(struct sock *sk) |
| @@ -1536,6 +1536,7 @@ struct nft_trans_flowtable { · 1535 unmodified lines | ||
| 1536 | 1536 | struct nft_flowtable *flowtable; |
| 1537 | 1537 | bool update; |
| 1538 | 1538 | struct list_head hook_list; |
| 1539 | + u32 flags; | |
| 1539 | 1540 | }; |
| 1540 | 1541 | |
| 1541 | 1542 | #define nft_trans_flowtable(trans) \ |
| @@ -1544,6 +1545,8 @@ struct nft_trans_flowtable { · 2 unmodified lines | ||
| 1544 | 1545 | (((struct nft_trans_flowtable *)trans->data)->update) |
| 1545 | 1546 | #define nft_trans_flowtable_hooks(trans) \ |
| 1546 | 1547 | (((struct nft_trans_flowtable *)trans->data)->hook_list) |
| 1548 | +#define nft_trans_flowtable_flags(trans) \ | |
| 1549 | + (((struct nft_trans_flowtable *)trans->data)->flags) | |
| 1547 | 1550 | |
| 1548 | 1551 | int __init nft_chain_filter_init(void); |
| 1549 | 1552 | void nft_chain_filter_fini(void); |
| @@ -410,6 +410,7 @@ static inline struct fib_nh *fib_info_nh(struct fib_info *fi, int nhsel) · 409 unmodified lines | ||
| 410 | 410 | int fib6_check_nexthop(struct nexthop *nh, struct fib6_config *cfg, |
| 411 | 411 | struct netlink_ext_ack *extack); |
| 412 | 412 | |
| 413 | +/* Caller should either hold rcu_read_lock(), or RTNL. */ | |
| 413 | 414 | static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) |
| 414 | 415 | { |
| 415 | 416 | struct nh_info *nhi; |
| @@ -430,6 +431,29 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) · 14 unmodified lines | ||
| 430 | 431 | return NULL; |
| 431 | 432 | } |
| 432 | 433 | |
| 434 | +/* Variant of nexthop_fib6_nh(). | |
| 435 | + * Caller should either hold rcu_read_lock_bh(), or RTNL. | |
| 436 | + */ | |
| 437 | +static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh) | |
| 438 | +{ | |
| 439 | + struct nh_info *nhi; | |
| 440 | + | |
| 441 | + if (nh->is_group) { | |
| 442 | + struct nh_group *nh_grp; | |
| 443 | + | |
| 444 | + nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp); | |
| 445 | + nh = nexthop_mpath_select(nh_grp, 0); | |
| 446 | + if (!nh) | |
| 447 | + return NULL; | |
| 448 | + } | |
| 449 | + | |
| 450 | + nhi = rcu_dereference_bh_rtnl(nh->nh_info); | |
| 451 | + if (nhi->family == AF_INET6) | |
| 452 | + return &nhi->fib6_nh; | |
| 453 | + | |
| 454 | + return NULL; | |
| 455 | +} | |
| 456 | + | |
| 433 | 457 | static inline struct net_device *fib6_info_nh_dev(struct fib6_info *f6i) |
| 434 | 458 | { |
| 435 | 459 | struct fib6_nh *fib6_nh; |
| @@ -168,7 +168,8 @@ static inline void red_set_vars(struct red_vars *v) · 167 unmodified lines | ||
| 168 | 168 | v->qcount = -1; |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | −static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_log) | |
| 171 | +static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, | |
| 172 | + u8 Scell_log, u8 *stab) | |
| 172 | 173 | { |
| 173 | 174 | if (fls(qth_min) + Wlog > 32) |
| 174 | 175 | return false; |
| @@ -178,6 +179,13 @@ static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_ · 3 unmodified lines | ||
| 178 | 179 | return false; |
| 179 | 180 | if (qth_max < qth_min) |
| 180 | 181 | return false; |
| 182 | + if (stab) { | |
| 183 | + int i; | |
| 184 | + | |
| 185 | + for (i = 0; i < RED_STAB_SIZE; i++) | |
| 186 | + if (stab[i] >= 32) | |
| 187 | + return false; | |
| 188 | + } | |
| 181 | 189 | return true; |
| 182 | 190 | } |
| 183 | 191 | |
| @@ -287,7 +295,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(const struct red_parms · 103 unmodified lines | ||
| 287 | 295 | int shift; |
| 288 | 296 | |
| 289 | 297 | /* |
| 290 | − * The problem: ideally, average length queue recalcultion should | |
| 298 | + * The problem: ideally, average length queue recalculation should | |
| 291 | 299 | * be done over constant clock intervals. This is too expensive, so |
| 292 | 300 | * that the calculation is driven by outgoing packets. |
| 293 | 301 | * When the queue is idle we have to model this clock by hand. |
| @@ -33,6 +33,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh) · 32 unmodified lines | ||
| 33 | 33 | * |
| 34 | 34 | * @list: Used internally |
| 35 | 35 | * @kind: Identifier |
| 36 | + * @netns_refund: Physical device, move to init_net on netns exit | |
| 36 | 37 | * @maxtype: Highest device specific netlink attribute number |
| 37 | 38 | * @policy: Netlink policy for device specific attribute validation |
| 38 | 39 | * @validate: Optional validation function for netlink/changelink parameters |
| @@ -64,6 +65,7 @@ struct rtnl_link_ops { · 25 unmodified lines | ||
| 64 | 65 | size_t priv_size; |
| 65 | 66 | void (*setup)(struct net_device *dev); |
| 66 | 67 | |
| 68 | + bool netns_refund; | |
| 67 | 69 | unsigned int maxtype; |
| 68 | 70 | const struct nla_policy *policy; |
| 69 | 71 | int (*validate)(struct nlattr *tb[], |
| @@ -936,7 +936,7 @@ static inline void sk_acceptq_added(struct sock *sk) · 935 unmodified lines | ||
| 936 | 936 | |
| 937 | 937 | static inline bool sk_acceptq_is_full(const struct sock *sk) |
| 938 | 938 | { |
| 939 | − return READ_ONCE(sk->sk_ack_backlog) > READ_ONCE(sk->sk_max_ack_backlog); | |
| 939 | + return READ_ONCE(sk->sk_ack_backlog) >= READ_ONCE(sk->sk_max_ack_backlog); | |
| 940 | 940 | } |
| 941 | 941 | |
| 942 | 942 | /* |
| @@ -193,6 +193,7 @@ enum iscsi_connection_state { · 192 unmodified lines | ||
| 193 | 193 | ISCSI_CONN_UP = 0, |
| 194 | 194 | ISCSI_CONN_DOWN, |
| 195 | 195 | ISCSI_CONN_FAILED, |
| 196 | + ISCSI_CONN_BOUND, | |
| 196 | 197 | }; |
| 197 | 198 | |
| 198 | 199 | struct iscsi_cls_conn { |
| @@ -2,29 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _UAPI__LINUX_BLKPG_H |
| 3 | 3 | #define _UAPI__LINUX_BLKPG_H |
| 4 | 4 | |
| 5 | −/* | |
| 6 | − * Partition table and disk geometry handling | |
| 7 | − * | |
| 8 | − * A single ioctl with lots of subfunctions: | |
| 9 | − * | |
| 10 | − * Device number stuff: | |
| 11 | − * get_whole_disk() (given the device number of a partition, | |
| 12 | − * find the device number of the encompassing disk) | |
| 13 | − * get_all_partitions() (given the device number of a disk, return the | |
| 14 | − * device numbers of all its known partitions) | |
| 15 | − * | |
| 16 | − * Partition stuff: | |
| 17 | − * add_partition() | |
| 18 | − * delete_partition() | |
| 19 | − * test_partition_in_use() (also for test_disk_in_use) | |
| 20 | − * | |
| 21 | − * Geometry stuff: | |
| 22 | − * get_geometry() | |
| 23 | − * set_geometry() | |
| 24 | − * get_bios_drivedata() | |
| 25 | − * | |
| 26 | − * For today, only the partition stuff - aeb, 990515 | |
| 27 | − */ | |
| 28 | 5 | #include <linux/compiler.h> |
| 29 | 6 | #include <linux/ioctl.h> |
| 30 | 7 | |
| @@ -52,9 +29,8 @@ struct blkpg_partition { · 21 unmodified lines | ||
| 52 | 29 | long long start; /* starting offset in bytes */ |
| 53 | 30 | long long length; /* length in bytes */ |
| 54 | 31 | int pno; /* partition number */ |
| 55 | − char devname[BLKPG_DEVNAMELTH]; /* partition name, like sda5 or c0d1p2, | |
| 56 | − to be used in kernel messages */ | |
| 57 | − char volname[BLKPG_VOLNAMELTH]; /* volume label */ | |
| 32 | + char devname[BLKPG_DEVNAMELTH]; /* unused / ignored */ | |
| 33 | + char volname[BLKPG_VOLNAMELTH]; /* unused / ignore */ | |
| 58 | 34 | }; |
| 59 | 35 | |
| 60 | 36 | #endif /* _UAPI__LINUX_BLKPG_H */ |
| @@ -3850,7 +3850,7 @@ union bpf_attr { · 3849 unmodified lines | ||
| 3850 | 3850 | * |
| 3851 | 3851 | * long bpf_check_mtu(void *ctx, u32 ifindex, u32 *mtu_len, s32 len_diff, u64 flags) |
| 3852 | 3852 | * Description |
| 3853 | − * Check ctx packet size against exceeding MTU of net device (based | |
| 3853 | + * Check packet size against exceeding MTU of net device (based | |
| 3854 | 3854 | * on *ifindex*). This helper will likely be used in combination |
| 3855 | 3855 | * with helpers that adjust/change the packet size. |
| 3856 | 3856 | * |
| @@ -3867,6 +3867,14 @@ union bpf_attr { · 10 unmodified lines | ||
| 3867 | 3867 | * against the current net device. This is practical if this isn't |
| 3868 | 3868 | * used prior to redirect. |
| 3869 | 3869 | * |
| 3870 | + * On input *mtu_len* must be a valid pointer, else verifier will | |
| 3871 | + * reject BPF program. If the value *mtu_len* is initialized to | |
| 3872 | + * zero then the ctx packet size is use. When value *mtu_len* is | |
| 3873 | + * provided as input this specify the L3 length that the MTU check | |
| 3874 | + * is done against. Remember XDP and TC length operate at L2, but | |
| 3875 | + * this value is L3 as this correlate to MTU and IP-header tot_len | |
| 3876 | + * values which are L3 (similar behavior as bpf_fib_lookup). | |
| 3877 | + * | |
| 3870 | 3878 | * The Linux kernel route table can configure MTUs on a more |
| 3871 | 3879 | * specific per route level, which is not provided by this helper. |
| 3872 | 3880 | * For route level MTU checks use the **bpf_fib_lookup**\ () |
| @@ -3891,11 +3899,9 @@ union bpf_attr { · 18 unmodified lines | ||
| 3891 | 3899 | * |
| 3892 | 3900 | * On return *mtu_len* pointer contains the MTU value of the net |
| 3893 | 3901 | * device. Remember the net device configured MTU is the L3 size, |
| 3894 | − * which is returned here and XDP and TX length operate at L2. | |
| 3902 | + * which is returned here and XDP and TC length operate at L2. | |
| 3895 | 3903 | * Helper take this into account for you, but remember when using |
| 3896 | − * MTU value in your BPF-code. On input *mtu_len* must be a valid | |
| 3897 | − * pointer and be initialized (to zero), else verifier will reject | |
| 3898 | − * BPF program. | |
| 3904 | + * MTU value in your BPF-code. | |
| 3899 | 3905 | * |
| 3900 | 3906 | * Return |
| 3901 | 3907 | * * 0 on success, and populate MTU value in *mtu_len* pointer. |
| @@ -3,7 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | #define __UAPI_PSAMPLE_H |
| 4 | 4 | |
| 5 | 5 | enum { |
| 6 | − /* sampled packet metadata */ | |
| 7 | 6 | PSAMPLE_ATTR_IIFINDEX, |
| 8 | 7 | PSAMPLE_ATTR_OIFINDEX, |
| 9 | 8 | PSAMPLE_ATTR_ORIGSIZE, |
| @@ -11,10 +10,8 @@ enum { · 1 unmodified line | ||
| 11 | 10 | PSAMPLE_ATTR_GROUP_SEQ, |
| 12 | 11 | PSAMPLE_ATTR_SAMPLE_RATE, |
| 13 | 12 | PSAMPLE_ATTR_DATA, |
| 14 | − PSAMPLE_ATTR_TUNNEL, | |
| 15 | − | |
| 16 | − /* commands attributes */ | |
| 17 | 13 | PSAMPLE_ATTR_GROUP_REFCOUNT, |
| 14 | + PSAMPLE_ATTR_TUNNEL, | |
| 18 | 15 | |
| 19 | 16 | __PSAMPLE_ATTR_MAX |
| 20 | 17 | }; |
| @@ -109,7 +109,7 @@ static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key) · 108 unmodified lines | ||
| 109 | 109 | fd = *(int *)key; |
| 110 | 110 | f = fget_raw(fd); |
| 111 | 111 | if (!f) |
| 112 | − return NULL; | |
| 112 | + return ERR_PTR(-EBADF); | |
| 113 | 113 | |
| 114 | 114 | sdata = inode_storage_lookup(f->f_inode, map, true); |
| 115 | 115 | fput(f); |
| @@ -430,7 +430,7 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, · 429 unmodified lines | ||
| 430 | 430 | |
| 431 | 431 | tprogs[BPF_TRAMP_FENTRY].progs[0] = prog; |
| 432 | 432 | tprogs[BPF_TRAMP_FENTRY].nr_progs = 1; |
| 433 | − err = arch_prepare_bpf_trampoline(image, | |
| 433 | + err = arch_prepare_bpf_trampoline(NULL, image, | |
| 434 | 434 | st_map->image + PAGE_SIZE, |
| 435 | 435 | &st_ops->func_models[i], 0, |
| 436 | 436 | tprogs, NULL); |
| @@ -827,7 +827,7 @@ static int __init bpf_jit_charge_init(void) · 826 unmodified lines | ||
| 827 | 827 | } |
| 828 | 828 | pure_initcall(bpf_jit_charge_init); |
| 829 | 829 | |
| 830 | −static int bpf_jit_charge_modmem(u32 pages) | |
| 830 | +int bpf_jit_charge_modmem(u32 pages) | |
| 831 | 831 | { |
| 832 | 832 | if (atomic_long_add_return(pages, &bpf_jit_current) > |
| 833 | 833 | (bpf_jit_limit >> PAGE_SHIFT)) { |
| @@ -840,7 +840,7 @@ static int bpf_jit_charge_modmem(u32 pages) · 6 unmodified lines | ||
| 840 | 840 | return 0; |
| 841 | 841 | } |
| 842 | 842 | |
| 843 | −static void bpf_jit_uncharge_modmem(u32 pages) | |
| 843 | +void bpf_jit_uncharge_modmem(u32 pages) | |
| 844 | 844 | { |
| 845 | 845 | atomic_long_sub(pages, &bpf_jit_current); |
| 846 | 846 | } |
| @@ -60,9 +60,12 @@ static int finish(void) · 59 unmodified lines | ||
| 60 | 60 | &magic, sizeof(magic), &pos); |
| 61 | 61 | if (n != sizeof(magic)) |
| 62 | 62 | return -EPIPE; |
| 63 | + | |
| 63 | 64 | tgid = umd_ops.info.tgid; |
| 64 | − wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); | |
| 65 | − umd_ops.info.tgid = NULL; | |
| 65 | + if (tgid) { | |
| 66 | + wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); | |
| 67 | + umd_cleanup_helper(&umd_ops.info); | |
| 68 | + } | |
| 66 | 69 | return 0; |
| 67 | 70 | } |
| 68 | 71 | |
| @@ -80,10 +83,18 @@ static int __init load_umd(void) · 11 unmodified lines | ||
| 80 | 83 | |
| 81 | 84 | static void __exit fini_umd(void) |
| 82 | 85 | { |
| 86 | + struct pid *tgid; | |
| 87 | + | |
| 83 | 88 | bpf_preload_ops = NULL; |
| 89 | + | |
| 84 | 90 | /* kill UMD in case it's still there due to earlier error */ |
| 85 | − kill_pid(umd_ops.info.tgid, SIGKILL, 1); | |
| 86 | − umd_ops.info.tgid = NULL; | |
| 91 | + tgid = umd_ops.info.tgid; | |
| 92 | + if (tgid) { | |
| 93 | + kill_pid(tgid, SIGKILL, 1); | |
| 94 | + | |
| 95 | + wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); | |
| 96 | + umd_cleanup_helper(&umd_ops.info); | |
| 97 | + } | |
| 87 | 98 | umd_unload_blob(&umd_ops.info); |
| 88 | 99 | } |
| 89 | 100 | late_initcall(load_umd); |
| @@ -854,6 +854,11 @@ static int map_create(union bpf_attr *attr) · 853 unmodified lines | ||
| 854 | 854 | err = PTR_ERR(btf); |
| 855 | 855 | goto free_map; |
| 856 | 856 | } |
| 857 | + if (btf_is_kernel(btf)) { | |
| 858 | + btf_put(btf); | |
| 859 | + err = -EACCES; | |
| 860 | + goto free_map; | |
| 861 | + } | |
| 857 | 862 | map->btf = btf; |
| 858 | 863 | |
| 859 | 864 | if (attr->btf_value_type_id) { |
| @@ -57,19 +57,10 @@ void bpf_image_ksym_del(struct bpf_ksym *ksym) · 56 unmodified lines | ||
| 57 | 57 | PAGE_SIZE, true, ksym->name); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | −static void bpf_trampoline_ksym_add(struct bpf_trampoline *tr) | |
| 61 | −{ | |
| 62 | − struct bpf_ksym *ksym = &tr->ksym; | |
| 63 | − | |
| 64 | − snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu", tr->key); | |
| 65 | − bpf_image_ksym_add(tr->image, ksym); | |
| 66 | −} | |
| 67 | − | |
| 68 | 60 | static struct bpf_trampoline *bpf_trampoline_lookup(u64 key) |
| 69 | 61 | { |
| 70 | 62 | struct bpf_trampoline *tr; |
| 71 | 63 | struct hlist_head *head; |
| 72 | − void *image; | |
| 73 | 64 | int i; |
| 74 | 65 | |
| 75 | 66 | mutex_lock(&trampoline_mutex); |
| @@ -84,14 +75,6 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key) · 8 unmodified lines | ||
| 84 | 75 | if (!tr) |
| 85 | 76 | goto out; |
| 86 | 77 | |
| 87 | − /* is_root was checked earlier. No need for bpf_jit_charge_modmem() */ | |
| 88 | − image = bpf_jit_alloc_exec_page(); | |
| 89 | − if (!image) { | |
| 90 | − kfree(tr); | |
| 91 | − tr = NULL; | |
| 92 | − goto out; | |
| 93 | − } | |
| 94 | − | |
| 95 | 78 | tr->key = key; |
| 96 | 79 | INIT_HLIST_NODE(&tr->hlist); |
| 97 | 80 | hlist_add_head(&tr->hlist, head); |
| @@ -99,9 +82,6 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key) · 1 unmodified line | ||
| 99 | 82 | mutex_init(&tr->mutex); |
| 100 | 83 | for (i = 0; i < BPF_TRAMP_MAX; i++) |
| 101 | 84 | INIT_HLIST_HEAD(&tr->progs_hlist[i]); |
| 102 | − tr->image = image; | |
| 103 | − INIT_LIST_HEAD_RCU(&tr->ksym.lnode); | |
| 104 | − bpf_trampoline_ksym_add(tr); | |
| 105 | 85 | out: |
| 106 | 86 | mutex_unlock(&trampoline_mutex); |
| 107 | 87 | return tr; |
| @@ -185,10 +165,142 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total) · 77 unmodified lines | ||
| 185 | 165 | return tprogs; |
| 186 | 166 | } |
| 187 | 167 | |
| 168 | +static void __bpf_tramp_image_put_deferred(struct work_struct *work) | |
| 169 | +{ | |
| 170 | + struct bpf_tramp_image *im; | |
| 171 | + | |
| 172 | + im = container_of(work, struct bpf_tramp_image, work); | |
| 173 | + bpf_image_ksym_del(&im->ksym); | |
| 174 | + bpf_jit_free_exec(im->image); | |
| 175 | + bpf_jit_uncharge_modmem(1); | |
| 176 | + percpu_ref_exit(&im->pcref); | |
| 177 | + kfree_rcu(im, rcu); | |
| 178 | +} | |
| 179 | + | |
| 180 | +/* callback, fexit step 3 or fentry step 2 */ | |
| 181 | +static void __bpf_tramp_image_put_rcu(struct rcu_head *rcu) | |
| 182 | +{ | |
| 183 | + struct bpf_tramp_image *im; | |
| 184 | + | |
| 185 | + im = container_of(rcu, struct bpf_tramp_image, rcu); | |
| 186 | + INIT_WORK(&im->work, __bpf_tramp_image_put_deferred); | |
| 187 | + schedule_work(&im->work); | |
| 188 | +} | |
| 189 | + | |
| 190 | +/* callback, fexit step 2. Called after percpu_ref_kill confirms. */ | |
| 191 | +static void __bpf_tramp_image_release(struct percpu_ref *pcref) | |
| 192 | +{ | |
| 193 | + struct bpf_tramp_image *im; | |
| 194 | + | |
| 195 | + im = container_of(pcref, struct bpf_tramp_image, pcref); | |
| 196 | + call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu); | |
| 197 | +} | |
| 198 | + | |
| 199 | +/* callback, fexit or fentry step 1 */ | |
| 200 | +static void __bpf_tramp_image_put_rcu_tasks(struct rcu_head *rcu) | |
| 201 | +{ | |
| 202 | + struct bpf_tramp_image *im; | |
| 203 | + | |
| 204 | + im = container_of(rcu, struct bpf_tramp_image, rcu); | |
| 205 | + if (im->ip_after_call) | |
| 206 | + /* the case of fmod_ret/fexit trampoline and CONFIG_PREEMPTION=y */ | |
| 207 | + percpu_ref_kill(&im->pcref); | |
| 208 | + else | |
| 209 | + /* the case of fentry trampoline */ | |
| 210 | + call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu); | |
| 211 | +} | |
| 212 | + | |
| 213 | +static void bpf_tramp_image_put(struct bpf_tramp_image *im) | |
| 214 | +{ | |
| 215 | + /* The trampoline image that calls original function is using: | |
| 216 | + * rcu_read_lock_trace to protect sleepable bpf progs | |
| 217 | + * rcu_read_lock to protect normal bpf progs | |
| 218 | + * percpu_ref to protect trampoline itself | |
| 219 | + * rcu tasks to protect trampoline asm not covered by percpu_ref | |
| 220 | + * (which are few asm insns before __bpf_tramp_enter and | |
| 221 | + * after __bpf_tramp_exit) | |
| 222 | + * | |
| 223 | + * The trampoline is unreachable before bpf_tramp_image_put(). | |
| 224 | + * | |
| 225 | + * First, patch the trampoline to avoid calling into fexit progs. | |
| 226 | + * The progs will be freed even if the original function is still | |
| 227 | + * executing or sleeping. | |
| 228 | + * In case of CONFIG_PREEMPT=y use call_rcu_tasks() to wait on | |
| 229 | + * first few asm instructions to execute and call into | |
| 230 | + * __bpf_tramp_enter->percpu_ref_get. | |
| 231 | + * Then use percpu_ref_kill to wait for the trampoline and the original | |
| 232 | + * function to finish. | |
| 233 | + * Then use call_rcu_tasks() to make sure few asm insns in | |
| 234 | + * the trampoline epilogue are done as well. | |
| 235 | + * | |
| 236 | + * In !PREEMPT case the task that got interrupted in the first asm | |
| 237 | + * insns won't go through an RCU quiescent state which the | |
| 238 | + * percpu_ref_kill will be waiting for. Hence the first | |
| 239 | + * call_rcu_tasks() is not necessary. | |
| 240 | + */ | |
| 241 | + if (im->ip_after_call) { | |
| 242 | + int err = bpf_arch_text_poke(im->ip_after_call, BPF_MOD_JUMP, | |
| 243 | + NULL, im->ip_epilogue); | |
| 244 | + WARN_ON(err); | |
| 245 | + if (IS_ENABLED(CONFIG_PREEMPTION)) | |
| 246 | + call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu_tasks); | |
| 247 | + else | |
| 248 | + percpu_ref_kill(&im->pcref); | |
| 249 | + return; | |
| 250 | + } | |
| 251 | + | |
| 252 | + /* The trampoline without fexit and fmod_ret progs doesn't call original | |
| 253 | + * function and doesn't use percpu_ref. | |
| 254 | + * Use call_rcu_tasks_trace() to wait for sleepable progs to finish. | |
| 255 | + * Then use call_rcu_tasks() to wait for the rest of trampoline asm | |
| 256 | + * and normal progs. | |
| 257 | + */ | |
| 258 | + call_rcu_tasks_trace(&im->rcu, __bpf_tramp_image_put_rcu_tasks); | |
| 259 | +} | |
| 260 | + | |
| 261 | +static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx) | |
| 262 | +{ | |
| 263 | + struct bpf_tramp_image *im; | |
| 264 | + struct bpf_ksym *ksym; | |
| 265 | + void *image; | |
| 266 | + int err = -ENOMEM; | |
| 267 | + | |
| 268 | + im = kzalloc(sizeof(*im), GFP_KERNEL); | |
| 269 | + if (!im) | |
| 270 | + goto out; | |
| 271 | + | |
| 272 | + err = bpf_jit_charge_modmem(1); | |
| 273 | + if (err) | |
| 274 | + goto out_free_im; | |
| 275 | + | |
| 276 | + err = -ENOMEM; | |
| 277 | + im->image = image = bpf_jit_alloc_exec_page(); | |
| 278 | + if (!image) | |
| 279 | + goto out_uncharge; | |
| 280 | + | |
| 281 | + err = percpu_ref_init(&im->pcref, __bpf_tramp_image_release, 0, GFP_KERNEL); | |
| 282 | + if (err) | |
| 283 | + goto out_free_image; | |
| 284 | + | |
| 285 | + ksym = &im->ksym; | |
| 286 | + INIT_LIST_HEAD_RCU(&ksym->lnode); | |
| 287 | + snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu_%u", key, idx); | |
| 288 | + bpf_image_ksym_add(image, ksym); | |
| 289 | + return im; | |
| 290 | + | |
| 291 | +out_free_image: | |
| 292 | + bpf_jit_free_exec(im->image); | |
| 293 | +out_uncharge: | |
| 294 | + bpf_jit_uncharge_modmem(1); | |
| 295 | +out_free_im: | |
| 296 | + kfree(im); | |
| 297 | +out: | |
| 298 | + return ERR_PTR(err); | |
| 299 | +} | |
| 300 | + | |
| 188 | 301 | static int bpf_trampoline_update(struct bpf_trampoline *tr) |
| 189 | 302 | { |
| 190 | − void *old_image = tr->image + ((tr->selector + 1) & 1) * PAGE_SIZE/2; | |
| 191 | − void *new_image = tr->image + (tr->selector & 1) * PAGE_SIZE/2; | |
| 303 | + struct bpf_tramp_image *im; | |
| 192 | 304 | struct bpf_tramp_progs *tprogs; |
| 193 | 305 | u32 flags = BPF_TRAMP_F_RESTORE_REGS; |
| 194 | 306 | int err, total; |
| @@ -198,41 +310,42 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr) · 3 unmodified lines | ||
| 198 | 310 | return PTR_ERR(tprogs); |
| 199 | 311 | |
| 200 | 312 | if (total == 0) { |
| 201 | − err = unregister_fentry(tr, old_image); | |
| 313 | + err = unregister_fentry(tr, tr->cur_image->image); | |
| 314 | + bpf_tramp_image_put(tr->cur_image); | |
| 315 | + tr->cur_image = NULL; | |
| 202 | 316 | tr->selector = 0; |
| 203 | 317 | goto out; |
| 204 | 318 | } |
| 205 | 319 | |
| 320 | + im = bpf_tramp_image_alloc(tr->key, tr->selector); | |
| 321 | + if (IS_ERR(im)) { | |
| 322 | + err = PTR_ERR(im); | |
| 323 | + goto out; | |
| 324 | + } | |
| 325 | + | |
| 206 | 326 | if (tprogs[BPF_TRAMP_FEXIT].nr_progs || |
| 207 | 327 | tprogs[BPF_TRAMP_MODIFY_RETURN].nr_progs) |
| 208 | 328 | flags = BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_SKIP_FRAME; |
| 209 | 329 | |
| 210 | − /* Though the second half of trampoline page is unused a task could be | |
| 211 | − * preempted in the middle of the first half of trampoline and two | |
| 212 | − * updates to trampoline would change the code from underneath the | |
| 213 | − * preempted task. Hence wait for tasks to voluntarily schedule or go | |
| 214 | − * to userspace. | |
| 215 | − * The same trampoline can hold both sleepable and non-sleepable progs. | |
| 216 | − * synchronize_rcu_tasks_trace() is needed to make sure all sleepable | |
| 217 | − * programs finish executing. | |
| 218 | − * Wait for these two grace periods together. | |
| 219 | − */ | |
| 220 | − synchronize_rcu_mult(call_rcu_tasks, call_rcu_tasks_trace); | |
| 221 | − | |
| 222 | − err = arch_prepare_bpf_trampoline(new_image, new_image + PAGE_SIZE / 2, | |
| 330 | + err = arch_prepare_bpf_trampoline(im, im->image, im->image + PAGE_SIZE, | |
| 223 | 331 | &tr->func.model, flags, tprogs, |
| 224 | 332 | tr->func.addr); |
| 225 | 333 | if (err < 0) |
| 226 | 334 | goto out; |
| 227 | 335 | |
| 228 | − if (tr->selector) | |
| 336 | + WARN_ON(tr->cur_image && tr->selector == 0); | |
| 337 | + WARN_ON(!tr->cur_image && tr->selector); | |
| 338 | + if (tr->cur_image) | |
| 229 | 339 | /* progs already running at this address */ |
| 230 | − err = modify_fentry(tr, old_image, new_image); | |
| 340 | + err = modify_fentry(tr, tr->cur_image->image, im->image); | |
| 231 | 341 | else |
| 232 | 342 | /* first time registering */ |
| 233 | − err = register_fentry(tr, new_image); | |
| 343 | + err = register_fentry(tr, im->image); | |
| 234 | 344 | if (err) |
| 235 | 345 | goto out; |
| 346 | + if (tr->cur_image) | |
| 347 | + bpf_tramp_image_put(tr->cur_image); | |
| 348 | + tr->cur_image = im; | |
| 236 | 349 | tr->selector++; |
| 237 | 350 | out: |
| 238 | 351 | kfree(tprogs); |
| @@ -364,17 +477,12 @@ void bpf_trampoline_put(struct bpf_trampoline *tr) · 125 unmodified lines | ||
| 364 | 477 | goto out; |
| 365 | 478 | if (WARN_ON_ONCE(!hlist_empty(&tr->progs_hlist[BPF_TRAMP_FEXIT]))) |
| 366 | 479 | goto out; |
| 367 | − bpf_image_ksym_del(&tr->ksym); | |
| 368 | − /* This code will be executed when all bpf progs (both sleepable and | |
| 369 | − * non-sleepable) went through | |
| 370 | − * bpf_prog_put()->call_rcu[_tasks_trace]()->bpf_prog_free_deferred(). | |
| 371 | − * Hence no need for another synchronize_rcu_tasks_trace() here, | |
| 372 | − * but synchronize_rcu_tasks() is still needed, since trampoline | |
| 373 | − * may not have had any sleepable programs and we need to wait | |
| 374 | − * for tasks to get out of trampoline code before freeing it. | |
| 480 | + /* This code will be executed even when the last bpf_tramp_image | |
| 481 | + * is alive. All progs are detached from the trampoline and the | |
| 482 | + * trampoline image is patched with jmp into epilogue to skip | |
| 483 | + * fexit progs. The fentry-only trampoline will be freed via | |
| 484 | + * multiple rcu callbacks. | |
| 375 | 485 | */ |
| 376 | − synchronize_rcu_tasks(); | |
| 377 | − bpf_jit_free_exec(tr->image); | |
| 378 | 486 | hlist_del(&tr->hlist); |
| 379 | 487 | kfree(tr); |
| 380 | 488 | out: |
| @@ -478,8 +586,18 @@ void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start) · 97 unmodified lines | ||
| 478 | 586 | rcu_read_unlock_trace(); |
| 479 | 587 | } |
| 480 | 588 | |
| 589 | +void notrace __bpf_tramp_enter(struct bpf_tramp_image *tr) | |
| 590 | +{ | |
| 591 | + percpu_ref_get(&tr->pcref); | |
| 592 | +} | |
| 593 | + | |
| 594 | +void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr) | |
| 595 | +{ | |
| 596 | + percpu_ref_put(&tr->pcref); | |
| 597 | +} | |
| 598 | + | |
| 481 | 599 | int __weak |
| 482 | −arch_prepare_bpf_trampoline(void *image, void *image_end, | |
| 600 | +arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end, | |
| 483 | 601 | const struct btf_func_model *m, u32 flags, |
| 484 | 602 | struct bpf_tramp_progs *tprogs, |
| 485 | 603 | void *orig_call) |
| @@ -5861,10 +5861,14 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, · 5860 unmodified lines | ||
| 5861 | 5861 | { |
| 5862 | 5862 | bool mask_to_left = (opcode == BPF_ADD && off_is_neg) || |
| 5863 | 5863 | (opcode == BPF_SUB && !off_is_neg); |
| 5864 | − u32 off; | |
| 5864 | + u32 off, max; | |
| 5865 | 5865 | |
| 5866 | 5866 | switch (ptr_reg->type) { |
| 5867 | 5867 | case PTR_TO_STACK: |
| 5868 | + /* Offset 0 is out-of-bounds, but acceptable start for the | |
| 5869 | + * left direction, see BPF_REG_FP. | |
| 5870 | + */ | |
| 5871 | + max = MAX_BPF_STACK + mask_to_left; | |
| 5868 | 5872 | /* Indirect variable offset stack access is prohibited in |
| 5869 | 5873 | * unprivileged mode so it's not handled here. |
| 5870 | 5874 | */ |
| @@ -5872,16 +5876,17 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, · 1 unmodified line | ||
| 5872 | 5876 | if (mask_to_left) |
| 5873 | 5877 | *ptr_limit = MAX_BPF_STACK + off; |
| 5874 | 5878 | else |
| 5875 | − *ptr_limit = -off; | |
| 5876 | − return 0; | |
| 5879 | + *ptr_limit = -off - 1; | |
| 5880 | + return *ptr_limit >= max ? -ERANGE : 0; | |
| 5877 | 5881 | case PTR_TO_MAP_VALUE: |
| 5882 | + max = ptr_reg->map_ptr->value_size; | |
| 5878 | 5883 | if (mask_to_left) { |
| 5879 | 5884 | *ptr_limit = ptr_reg->umax_value + ptr_reg->off; |
| 5880 | 5885 | } else { |
| 5881 | 5886 | off = ptr_reg->smin_value + ptr_reg->off; |
| 5882 | − *ptr_limit = ptr_reg->map_ptr->value_size - off; | |
| 5887 | + *ptr_limit = ptr_reg->map_ptr->value_size - off - 1; | |
| 5883 | 5888 | } |
| 5884 | − return 0; | |
| 5889 | + return *ptr_limit >= max ? -ERANGE : 0; | |
| 5885 | 5890 | default: |
| 5886 | 5891 | return -EINVAL; |
| 5887 | 5892 | } |
| @@ -5934,6 +5939,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, · 46 unmodified lines | ||
| 5934 | 5939 | u32 alu_state, alu_limit; |
| 5935 | 5940 | struct bpf_reg_state tmp; |
| 5936 | 5941 | bool ret; |
| 5942 | + int err; | |
| 5937 | 5943 | |
| 5938 | 5944 | if (can_skip_alu_sanitation(env, insn)) |
| 5939 | 5945 | return 0; |
| @@ -5949,10 +5955,13 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, · 9 unmodified lines | ||
| 5949 | 5955 | alu_state |= ptr_is_dst_reg ? |
| 5950 | 5956 | BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; |
| 5951 | 5957 | |
| 5952 | − if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg)) | |
| 5953 | − return 0; | |
| 5954 | − if (update_alu_sanitation_state(aux, alu_state, alu_limit)) | |
| 5955 | − return -EACCES; | |
| 5958 | + err = retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg); | |
| 5959 | + if (err < 0) | |
| 5960 | + return err; | |
| 5961 | + | |
| 5962 | + err = update_alu_sanitation_state(aux, alu_state, alu_limit); | |
| 5963 | + if (err < 0) | |
| 5964 | + return err; | |
| 5956 | 5965 | do_sim: |
| 5957 | 5966 | /* Simulate and find potential out-of-bounds access under |
| 5958 | 5967 | * speculative execution from truncation as a result of |
| @@ -6103,7 +6112,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, · 144 unmodified lines | ||
| 6103 | 6112 | case BPF_ADD: |
| 6104 | 6113 | ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); |
| 6105 | 6114 | if (ret < 0) { |
| 6106 | − verbose(env, "R%d tried to add from different maps or paths\n", dst); | |
| 6115 | + verbose(env, "R%d tried to add from different maps, paths, or prohibited types\n", dst); | |
| 6107 | 6116 | return ret; |
| 6108 | 6117 | } |
| 6109 | 6118 | /* We can take a fixed offset as long as it doesn't overflow |
| @@ -6158,7 +6167,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, · 48 unmodified lines | ||
| 6158 | 6167 | case BPF_SUB: |
| 6159 | 6168 | ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); |
| 6160 | 6169 | if (ret < 0) { |
| 6161 | − verbose(env, "R%d tried to sub from different maps or paths\n", dst); | |
| 6170 | + verbose(env, "R%d tried to sub from different maps, paths, or prohibited types\n", dst); | |
| 6162 | 6171 | return ret; |
| 6163 | 6172 | } |
| 6164 | 6173 | if (dst_reg == off_reg) { |
| @@ -9056,6 +9065,10 @@ static int check_btf_info(struct bpf_verifier_env *env, · 2891 unmodified lines | ||
| 9056 | 9065 | btf = btf_get_by_fd(attr->prog_btf_fd); |
| 9057 | 9066 | if (IS_ERR(btf)) |
| 9058 | 9067 | return PTR_ERR(btf); |
| 9068 | + if (btf_is_kernel(btf)) { | |
| 9069 | + btf_put(btf); | |
| 9070 | + return -EACCES; | |
| 9071 | + } | |
| 9059 | 9072 | env->prog->aux->btf = btf; |
| 9060 | 9073 | |
| 9061 | 9074 | err = check_btf_func(env, attr, uattr); |
| @@ -11660,7 +11673,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) · 2598 unmodified lines | ||
| 11660 | 11673 | off_reg = issrc ? insn->src_reg : insn->dst_reg; |
| 11661 | 11674 | if (isneg) |
| 11662 | 11675 | *patch++ = BPF_ALU64_IMM(BPF_MUL, off_reg, -1); |
| 11663 | − *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit - 1); | |
| 11676 | + *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit); | |
| 11664 | 11677 | *patch++ = BPF_ALU64_REG(BPF_SUB, BPF_REG_AX, off_reg); |
| 11665 | 11678 | *patch++ = BPF_ALU64_REG(BPF_OR, BPF_REG_AX, off_reg); |
| 11666 | 11679 | *patch++ = BPF_ALU64_IMM(BPF_NEG, BPF_REG_AX, 0); |
| @@ -1948,8 +1948,14 @@ static __latent_entropy struct task_struct *copy_process( · 1947 unmodified lines | ||
| 1948 | 1948 | p = dup_task_struct(current, node); |
| 1949 | 1949 | if (!p) |
| 1950 | 1950 | goto fork_out; |
| 1951 | − if (args->io_thread) | |
| 1951 | + if (args->io_thread) { | |
| 1952 | + /* | |
| 1953 | + * Mark us an IO worker, and block any signal that isn't | |
| 1954 | + * fatal or STOP | |
| 1955 | + */ | |
| 1952 | 1956 | p->flags |= PF_IO_WORKER; |
| 1957 | + siginitsetinv(&p->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); | |
| 1958 | + } | |
| 1953 | 1959 | |
| 1954 | 1960 | /* |
| 1955 | 1961 | * This _must_ happen before we call free_task(), i.e. before we jump |
| @@ -2438,14 +2444,8 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) · 482 unmodified lines | ||
| 2438 | 2444 | .stack_size = (unsigned long)arg, |
| 2439 | 2445 | .io_thread = 1, |
| 2440 | 2446 | }; |
| 2441 | − struct task_struct *tsk; | |
| 2442 | 2447 | |
| 2443 | − tsk = copy_process(NULL, 0, node, &args); | |
| 2444 | − if (!IS_ERR(tsk)) { | |
| 2445 | − sigfillset(&tsk->blocked); | |
| 2446 | − sigdelsetmask(&tsk->blocked, sigmask(SIGKILL)); | |
| 2447 | − } | |
| 2448 | − return tsk; | |
| 2448 | + return copy_process(NULL, 0, node, &args); | |
| 2449 | 2449 | } |
| 2450 | 2450 | |
| 2451 | 2451 | /* |
| @@ -134,7 +134,7 @@ bool freeze_task(struct task_struct *p) · 133 unmodified lines | ||
| 134 | 134 | return false; |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | − if (!(p->flags & (PF_KTHREAD | PF_IO_WORKER))) | |
| 137 | + if (!(p->flags & PF_KTHREAD)) | |
| 138 | 138 | fake_signal_wake_up(p); |
| 139 | 139 | else |
| 140 | 140 | wake_up_state(p, TASK_INTERRUPTIBLE); |
| @@ -75,7 +75,9 @@ struct gcov_fn_info { · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | u32 num_counters; |
| 77 | 77 | u64 *counters; |
| 78 | +#if CONFIG_CLANG_VERSION < 110000 | |
| 78 | 79 | const char *function_name; |
| 80 | +#endif | |
| 79 | 81 | }; |
| 80 | 82 | |
| 81 | 83 | static struct gcov_info *current_info; |
| @@ -105,6 +107,7 @@ void llvm_gcov_init(llvm_gcov_callback writeout, llvm_gcov_callback flush) · 23 unmodified lines | ||
| 105 | 107 | } |
| 106 | 108 | EXPORT_SYMBOL(llvm_gcov_init); |
| 107 | 109 | |
| 110 | +#if CONFIG_CLANG_VERSION < 110000 | |
| 108 | 111 | void llvm_gcda_start_file(const char *orig_filename, const char version[4], |
| 109 | 112 | u32 checksum) |
| 110 | 113 | { |
| @@ -113,7 +116,17 @@ void llvm_gcda_start_file(const char *orig_filename, const char version[4], · 2 unmodified lines | ||
| 113 | 116 | current_info->checksum = checksum; |
| 114 | 117 | } |
| 115 | 118 | EXPORT_SYMBOL(llvm_gcda_start_file); |
| 119 | +#else | |
| 120 | +void llvm_gcda_start_file(const char *orig_filename, u32 version, u32 checksum) | |
| 121 | +{ | |
| 122 | + current_info->filename = orig_filename; | |
| 123 | + current_info->version = version; | |
| 124 | + current_info->checksum = checksum; | |
| 125 | +} | |
| 126 | +EXPORT_SYMBOL(llvm_gcda_start_file); | |
| 127 | +#endif | |
| 116 | 128 | |
| 129 | +#if CONFIG_CLANG_VERSION < 110000 | |
| 117 | 130 | void llvm_gcda_emit_function(u32 ident, const char *function_name, |
| 118 | 131 | u32 func_checksum, u8 use_extra_checksum, u32 cfg_checksum) |
| 119 | 132 | { |
| @@ -133,6 +146,24 @@ void llvm_gcda_emit_function(u32 ident, const char *function_name, · 13 unmodified lines | ||
| 133 | 146 | list_add_tail(&info->head, ¤t_info->functions); |
| 134 | 147 | } |
| 135 | 148 | EXPORT_SYMBOL(llvm_gcda_emit_function); |
| 149 | +#else | |
| 150 | +void llvm_gcda_emit_function(u32 ident, u32 func_checksum, | |
| 151 | + u8 use_extra_checksum, u32 cfg_checksum) | |
| 152 | +{ | |
| 153 | + struct gcov_fn_info *info = kzalloc(sizeof(*info), GFP_KERNEL); | |
| 154 | + | |
| 155 | + if (!info) | |
| 156 | + return; | |
| 157 | + | |
| 158 | + INIT_LIST_HEAD(&info->head); | |
| 159 | + info->ident = ident; | |
| 160 | + info->checksum = func_checksum; | |
| 161 | + info->use_extra_checksum = use_extra_checksum; | |
| 162 | + info->cfg_checksum = cfg_checksum; | |
| 163 | + list_add_tail(&info->head, ¤t_info->functions); | |
| 164 | +} | |
| 165 | +EXPORT_SYMBOL(llvm_gcda_emit_function); | |
| 166 | +#endif | |
| 136 | 167 | |
| 137 | 168 | void llvm_gcda_emit_arcs(u32 num_counters, u64 *counters) |
| 138 | 169 | { |
| @@ -295,6 +326,7 @@ void gcov_info_add(struct gcov_info *dst, struct gcov_info *src) · 156 unmodified lines | ||
| 295 | 326 | } |
| 296 | 327 | } |
| 297 | 328 | |
| 329 | +#if CONFIG_CLANG_VERSION < 110000 | |
| 298 | 330 | static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn) |
| 299 | 331 | { |
| 300 | 332 | size_t cv_size; /* counter values size */ |
| @@ -322,6 +354,28 @@ err_name: · 21 unmodified lines | ||
| 322 | 354 | kfree(fn_dup); |
| 323 | 355 | return NULL; |
| 324 | 356 | } |
| 357 | +#else | |
| 358 | +static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn) | |
| 359 | +{ | |
| 360 | + size_t cv_size; /* counter values size */ | |
| 361 | + struct gcov_fn_info *fn_dup = kmemdup(fn, sizeof(*fn), | |
| 362 | + GFP_KERNEL); | |
| 363 | + if (!fn_dup) | |
| 364 | + return NULL; | |
| 365 | + INIT_LIST_HEAD(&fn_dup->head); | |
| 366 | + | |
| 367 | + cv_size = fn->num_counters * sizeof(fn->counters[0]); | |
| 368 | + fn_dup->counters = vmalloc(cv_size); | |
| 369 | + if (!fn_dup->counters) { | |
| 370 | + kfree(fn_dup); | |
| 371 | + return NULL; | |
| 372 | + } | |
| 373 | + | |
| 374 | + memcpy(fn_dup->counters, fn->counters, cv_size); | |
| 375 | + | |
| 376 | + return fn_dup; | |
| 377 | +} | |
| 378 | +#endif | |
| 325 | 379 | |
| 326 | 380 | /** |
| 327 | 381 | * gcov_info_dup - duplicate profiling data set |
| @@ -362,6 +416,7 @@ err: · 34 unmodified lines | ||
| 362 | 416 | * gcov_info_free - release memory for profiling data set duplicate |
| 363 | 417 | * @info: profiling data set duplicate to free |
| 364 | 418 | */ |
| 419 | +#if CONFIG_CLANG_VERSION < 110000 | |
| 365 | 420 | void gcov_info_free(struct gcov_info *info) |
| 366 | 421 | { |
| 367 | 422 | struct gcov_fn_info *fn, *tmp; |
| @@ -375,6 +430,20 @@ void gcov_info_free(struct gcov_info *info) · 7 unmodified lines | ||
| 375 | 430 | kfree(info->filename); |
| 376 | 431 | kfree(info); |
| 377 | 432 | } |
| 433 | +#else | |
| 434 | +void gcov_info_free(struct gcov_info *info) | |
| 435 | +{ | |
| 436 | + struct gcov_fn_info *fn, *tmp; | |
| 437 | + | |
| 438 | + list_for_each_entry_safe(fn, tmp, &info->functions, head) { | |
| 439 | + vfree(fn->counters); | |
| 440 | + list_del(&fn->head); | |
| 441 | + kfree(fn); | |
| 442 | + } | |
| 443 | + kfree(info->filename); | |
| 444 | + kfree(info); | |
| 445 | +} | |
| 446 | +#endif | |
| 378 | 447 | |
| 379 | 448 | #define ITER_STRIDE PAGE_SIZE |
| 380 | 449 | |
| @@ -98,7 +98,7 @@ static int __init em_debug_init(void) · 97 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | return 0; |
| 100 | 100 | } |
| 101 | −core_initcall(em_debug_init); | |
| 101 | +fs_initcall(em_debug_init); | |
| 102 | 102 | #else /* CONFIG_DEBUG_FS */ |
| 103 | 103 | static void em_debug_create_pd(struct device *dev) {} |
| 104 | 104 | static void em_debug_remove_pd(struct device *dev) {} |
| @@ -375,7 +375,7 @@ static int ptrace_attach(struct task_struct *task, long request, · 374 unmodified lines | ||
| 375 | 375 | audit_ptrace(task); |
| 376 | 376 | |
| 377 | 377 | retval = -EPERM; |
| 378 | − if (unlikely(task->flags & (PF_KTHREAD | PF_IO_WORKER))) | |
| 378 | + if (unlikely(task->flags & PF_KTHREAD)) | |
| 379 | 379 | goto out; |
| 380 | 380 | if (same_thread_group(task, current)) |
| 381 | 381 | goto out; |
| @@ -91,7 +91,7 @@ static bool sig_task_ignored(struct task_struct *t, int sig, bool force) · 90 unmodified lines | ||
| 91 | 91 | return true; |
| 92 | 92 | |
| 93 | 93 | /* Only allow kernel generated signals to this kthread */ |
| 94 | − if (unlikely((t->flags & (PF_KTHREAD | PF_IO_WORKER)) && | |
| 94 | + if (unlikely((t->flags & PF_KTHREAD) && | |
| 95 | 95 | (handler == SIG_KTHREAD_KERNEL) && !force)) |
| 96 | 96 | return true; |
| 97 | 97 | |
| @@ -288,8 +288,7 @@ bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask) · 190 unmodified lines | ||
| 288 | 288 | JOBCTL_STOP_SIGMASK | JOBCTL_TRAPPING)); |
| 289 | 289 | BUG_ON((mask & JOBCTL_TRAPPING) && !(mask & JOBCTL_PENDING_MASK)); |
| 290 | 290 | |
| 291 | − if (unlikely(fatal_signal_pending(task) || | |
| 292 | − (task->flags & (PF_EXITING | PF_IO_WORKER)))) | |
| 291 | + if (unlikely(fatal_signal_pending(task) || (task->flags & PF_EXITING))) | |
| 293 | 292 | return false; |
| 294 | 293 | |
| 295 | 294 | if (mask & JOBCTL_STOP_SIGMASK) |
| @@ -834,9 +833,6 @@ static int check_kill_permission(int sig, struct kernel_siginfo *info, · 538 unmodified lines | ||
| 834 | 833 | |
| 835 | 834 | if (!valid_signal(sig)) |
| 836 | 835 | return -EINVAL; |
| 837 | − /* PF_IO_WORKER threads don't take any signals */ | |
| 838 | − if (t->flags & PF_IO_WORKER) | |
| 839 | − return -ESRCH; | |
| 840 | 836 | |
| 841 | 837 | if (!si_fromuser(info)) |
| 842 | 838 | return 0; |
| @@ -1100,7 +1096,7 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc · 257 unmodified lines | ||
| 1100 | 1096 | /* |
| 1101 | 1097 | * Skip useless siginfo allocation for SIGKILL and kernel threads. |
| 1102 | 1098 | */ |
| 1103 | − if ((sig == SIGKILL) || (t->flags & (PF_KTHREAD | PF_IO_WORKER))) | |
| 1099 | + if ((sig == SIGKILL) || (t->flags & PF_KTHREAD)) | |
| 1104 | 1100 | goto out_set; |
| 1105 | 1101 | |
| 1106 | 1102 | /* |
| @@ -2771,6 +2767,14 @@ relock: · 1664 unmodified lines | ||
| 2771 | 2767 | do_coredump(&ksig->info); |
| 2772 | 2768 | } |
| 2773 | 2769 | |
| 2770 | + /* | |
| 2771 | + * PF_IO_WORKER threads will catch and exit on fatal signals | |
| 2772 | + * themselves. They have cleanup that must be performed, so | |
| 2773 | + * we cannot call do_exit() on their behalf. | |
| 2774 | + */ | |
| 2775 | + if (current->flags & PF_IO_WORKER) | |
| 2776 | + goto out; | |
| 2777 | + | |
| 2774 | 2778 | /* |
| 2775 | 2779 | * Death signals, no core dump. |
| 2776 | 2780 | */ |
| @@ -2778,7 +2782,7 @@ relock: · 1 unmodified line | ||
| 2778 | 2782 | /* NOTREACHED */ |
| 2779 | 2783 | } |
| 2780 | 2784 | spin_unlock_irq(&sighand->siglock); |
| 2781 | − | |
| 2785 | +out: | |
| 2782 | 2786 | ksig->sig = signr; |
| 2783 | 2787 | |
| 2784 | 2788 | if (!(ksig->ka.sa.sa_flags & SA_EXPOSE_TAGBITS)) |
| @@ -3231,7 +3231,8 @@ ftrace_allocate_pages(unsigned long num_to_init) · 3230 unmodified lines | ||
| 3231 | 3231 | pg = start_pg; |
| 3232 | 3232 | while (pg) { |
| 3233 | 3233 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); |
| 3234 | − free_pages((unsigned long)pg->records, order); | |
| 3234 | + if (order >= 0) | |
| 3235 | + free_pages((unsigned long)pg->records, order); | |
| 3235 | 3236 | start_pg = pg->next; |
| 3236 | 3237 | kfree(pg); |
| 3237 | 3238 | pg = start_pg; |
| @@ -5045,6 +5046,20 @@ struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr) · 1807 unmodified lines | ||
| 5045 | 5046 | return NULL; |
| 5046 | 5047 | } |
| 5047 | 5048 | |
| 5049 | +static struct ftrace_direct_func *ftrace_alloc_direct_func(unsigned long addr) | |
| 5050 | +{ | |
| 5051 | + struct ftrace_direct_func *direct; | |
| 5052 | + | |
| 5053 | + direct = kmalloc(sizeof(*direct), GFP_KERNEL); | |
| 5054 | + if (!direct) | |
| 5055 | + return NULL; | |
| 5056 | + direct->addr = addr; | |
| 5057 | + direct->count = 0; | |
| 5058 | + list_add_rcu(&direct->next, &ftrace_direct_funcs); | |
| 5059 | + ftrace_direct_func_count++; | |
| 5060 | + return direct; | |
| 5061 | +} | |
| 5062 | + | |
| 5048 | 5063 | /** |
| 5049 | 5064 | * register_ftrace_direct - Call a custom trampoline directly |
| 5050 | 5065 | * @ip: The address of the nop at the beginning of a function |
| @@ -5120,15 +5135,11 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr) · 69 unmodified lines | ||
| 5120 | 5135 | |
| 5121 | 5136 | direct = ftrace_find_direct_func(addr); |
| 5122 | 5137 | if (!direct) { |
| 5123 | − direct = kmalloc(sizeof(*direct), GFP_KERNEL); | |
| 5138 | + direct = ftrace_alloc_direct_func(addr); | |
| 5124 | 5139 | if (!direct) { |
| 5125 | 5140 | kfree(entry); |
| 5126 | 5141 | goto out_unlock; |
| 5127 | 5142 | } |
| 5128 | − direct->addr = addr; | |
| 5129 | − direct->count = 0; | |
| 5130 | − list_add_rcu(&direct->next, &ftrace_direct_funcs); | |
| 5131 | − ftrace_direct_func_count++; | |
| 5132 | 5143 | } |
| 5133 | 5144 | |
| 5134 | 5145 | entry->ip = ip; |
| @@ -5329,6 +5340,7 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry, · 194 unmodified lines | ||
| 5329 | 5340 | int modify_ftrace_direct(unsigned long ip, |
| 5330 | 5341 | unsigned long old_addr, unsigned long new_addr) |
| 5331 | 5342 | { |
| 5343 | + struct ftrace_direct_func *direct, *new_direct = NULL; | |
| 5332 | 5344 | struct ftrace_func_entry *entry; |
| 5333 | 5345 | struct dyn_ftrace *rec; |
| 5334 | 5346 | int ret = -ENODEV; |
| @@ -5344,6 +5356,20 @@ int modify_ftrace_direct(unsigned long ip, · 9 unmodified lines | ||
| 5344 | 5356 | if (entry->direct != old_addr) |
| 5345 | 5357 | goto out_unlock; |
| 5346 | 5358 | |
| 5359 | + direct = ftrace_find_direct_func(old_addr); | |
| 5360 | + if (WARN_ON(!direct)) | |
| 5361 | + goto out_unlock; | |
| 5362 | + if (direct->count > 1) { | |
| 5363 | + ret = -ENOMEM; | |
| 5364 | + new_direct = ftrace_alloc_direct_func(new_addr); | |
| 5365 | + if (!new_direct) | |
| 5366 | + goto out_unlock; | |
| 5367 | + direct->count--; | |
| 5368 | + new_direct->count++; | |
| 5369 | + } else { | |
| 5370 | + direct->addr = new_addr; | |
| 5371 | + } | |
| 5372 | + | |
| 5347 | 5373 | /* |
| 5348 | 5374 | * If there's no other ftrace callback on the rec->ip location, |
| 5349 | 5375 | * then it can be changed directly by the architecture. |
| @@ -5357,6 +5383,14 @@ int modify_ftrace_direct(unsigned long ip, · 7 unmodified lines | ||
| 5357 | 5383 | ret = 0; |
| 5358 | 5384 | } |
| 5359 | 5385 | |
| 5386 | + if (unlikely(ret && new_direct)) { | |
| 5387 | + direct->count++; | |
| 5388 | + list_del_rcu(&new_direct->next); | |
| 5389 | + synchronize_rcu_tasks(); | |
| 5390 | + kfree(new_direct); | |
| 5391 | + ftrace_direct_func_count--; | |
| 5392 | + } | |
| 5393 | + | |
| 5360 | 5394 | out_unlock: |
| 5361 | 5395 | mutex_unlock(&ftrace_lock); |
| 5362 | 5396 | mutex_unlock(&direct_mutex); |
| @@ -6418,7 +6452,8 @@ void ftrace_release_mod(struct module *mod) · 1055 unmodified lines | ||
| 6418 | 6452 | clear_mod_from_hashes(pg); |
| 6419 | 6453 | |
| 6420 | 6454 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); |
| 6421 | − free_pages((unsigned long)pg->records, order); | |
| 6455 | + if (order >= 0) | |
| 6456 | + free_pages((unsigned long)pg->records, order); | |
| 6422 | 6457 | tmp_page = pg->next; |
| 6423 | 6458 | kfree(pg); |
| 6424 | 6459 | ftrace_number_of_pages -= 1 << order; |
| @@ -6778,7 +6813,8 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) · 353 unmodified lines | ||
| 6778 | 6813 | if (!pg->index) { |
| 6779 | 6814 | *last_pg = pg->next; |
| 6780 | 6815 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); |
| 6781 | − free_pages((unsigned long)pg->records, order); | |
| 6816 | + if (order >= 0) | |
| 6817 | + free_pages((unsigned long)pg->records, order); | |
| 6782 | 6818 | ftrace_number_of_pages -= 1 << order; |
| 6783 | 6819 | ftrace_number_of_groups--; |
| 6784 | 6820 | kfree(pg); |
| @@ -2984,7 +2984,8 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer, · 2983 unmodified lines | ||
| 2984 | 2984 | |
| 2985 | 2985 | size = nr_entries * sizeof(unsigned long); |
| 2986 | 2986 | event = __trace_buffer_lock_reserve(buffer, TRACE_STACK, |
| 2987 | − sizeof(*entry) + size, trace_ctx); | |
| 2987 | + (sizeof(*entry) - sizeof(entry->caller)) + size, | |
| 2988 | + trace_ctx); | |
| 2988 | 2989 | if (!event) |
| 2989 | 2990 | goto out; |
| 2990 | 2991 | entry = ring_buffer_event_data(event); |
| @@ -139,13 +139,22 @@ static void umd_cleanup(struct subprocess_info *info) · 138 unmodified lines | ||
| 139 | 139 | struct umd_info *umd_info = info->data; |
| 140 | 140 | |
| 141 | 141 | /* cleanup if umh_setup() was successful but exec failed */ |
| 142 | − if (info->retval) { | |
| 143 | − fput(umd_info->pipe_to_umh); | |
| 144 | − fput(umd_info->pipe_from_umh); | |
| 145 | − put_pid(umd_info->tgid); | |
| 146 | − umd_info->tgid = NULL; | |
| 147 | − } | |
| 142 | + if (info->retval) | |
| 143 | + umd_cleanup_helper(umd_info); | |
| 144 | +} | |
| 145 | + | |
| 146 | +/** | |
| 147 | + * umd_cleanup_helper - release the resources which were allocated in umd_setup | |
| 148 | + * @info: information about usermode driver | |
| 149 | + */ | |
| 150 | +void umd_cleanup_helper(struct umd_info *info) | |
| 151 | +{ | |
| 152 | + fput(info->pipe_to_umh); | |
| 153 | + fput(info->pipe_from_umh); | |
| 154 | + put_pid(info->tgid); | |
| 155 | + info->tgid = NULL; | |
| 148 | 156 | } |
| 157 | +EXPORT_SYMBOL_GPL(umd_cleanup_helper); | |
| 149 | 158 | |
| 150 | 159 | /** |
| 151 | 160 | * fork_usermode_driver - fork a usermode driver |
| @@ -232,4 +232,5 @@ u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c) · 231 unmodified lines | ||
| 232 | 232 | |
| 233 | 233 | return res + div64_u64(a * b, c); |
| 234 | 234 | } |
| 235 | +EXPORT_SYMBOL(mul_u64_u64_div_u64); | |
| 235 | 236 | #endif |
| @@ -1530,24 +1530,24 @@ static noinline void check_store_range(struct xarray *xa) · 1529 unmodified lines | ||
| 1530 | 1530 | |
| 1531 | 1531 | #ifdef CONFIG_XARRAY_MULTI |
| 1532 | 1532 | static void check_split_1(struct xarray *xa, unsigned long index, |
| 1533 | − unsigned int order) | |
| 1533 | + unsigned int order, unsigned int new_order) | |
| 1534 | 1534 | { |
| 1535 | − XA_STATE(xas, xa, index); | |
| 1536 | − void *entry; | |
| 1537 | − unsigned int i = 0; | |
| 1535 | + XA_STATE_ORDER(xas, xa, index, new_order); | |
| 1536 | + unsigned int i; | |
| 1538 | 1537 | |
| 1539 | 1538 | xa_store_order(xa, index, order, xa, GFP_KERNEL); |
| 1540 | 1539 | |
| 1541 | 1540 | xas_split_alloc(&xas, xa, order, GFP_KERNEL); |
| 1542 | 1541 | xas_lock(&xas); |
| 1543 | 1542 | xas_split(&xas, xa, order); |
| 1543 | + for (i = 0; i < (1 << order); i += (1 << new_order)) | |
| 1544 | + __xa_store(xa, index + i, xa_mk_index(index + i), 0); | |
| 1544 | 1545 | xas_unlock(&xas); |
| 1545 | 1546 | |
| 1546 | − xa_for_each(xa, index, entry) { | |
| 1547 | − XA_BUG_ON(xa, entry != xa); | |
| 1548 | − i++; | |
| 1547 | + for (i = 0; i < (1 << order); i++) { | |
| 1548 | + unsigned int val = index + (i & ~((1 << new_order) - 1)); | |
| 1549 | + XA_BUG_ON(xa, xa_load(xa, index + i) != xa_mk_index(val)); | |
| 1549 | 1550 | } |
| 1550 | − XA_BUG_ON(xa, i != 1 << order); | |
| 1551 | 1551 | |
| 1552 | 1552 | xa_set_mark(xa, index, XA_MARK_0); |
| 1553 | 1553 | XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0)); |
| @@ -1557,14 +1557,16 @@ static void check_split_1(struct xarray *xa, unsigned long index, · 3 unmodified lines | ||
| 1557 | 1557 | |
| 1558 | 1558 | static noinline void check_split(struct xarray *xa) |
| 1559 | 1559 | { |
| 1560 | − unsigned int order; | |
| 1560 | + unsigned int order, new_order; | |
| 1561 | 1561 | |
| 1562 | 1562 | XA_BUG_ON(xa, !xa_empty(xa)); |
| 1563 | 1563 | |
| 1564 | 1564 | for (order = 1; order < 2 * XA_CHUNK_SHIFT; order++) { |
| 1565 | − check_split_1(xa, 0, order); | |
| 1566 | − check_split_1(xa, 1UL << order, order); | |
| 1567 | − check_split_1(xa, 3UL << order, order); | |
| 1565 | + for (new_order = 0; new_order < order; new_order++) { | |
| 1566 | + check_split_1(xa, 0, order, new_order); | |
| 1567 | + check_split_1(xa, 1UL << order, order, new_order); | |
| 1568 | + check_split_1(xa, 3UL << order, order, new_order); | |
| 1569 | + } | |
| 1568 | 1570 | } |
| 1569 | 1571 | } |
| 1570 | 1572 | #else |
| @@ -987,7 +987,7 @@ static void node_set_marks(struct xa_node *node, unsigned int offset, · 986 unmodified lines | ||
| 987 | 987 | * xas_split_alloc() - Allocate memory for splitting an entry. |
| 988 | 988 | * @xas: XArray operation state. |
| 989 | 989 | * @entry: New entry which will be stored in the array. |
| 990 | − * @order: New entry order. | |
| 990 | + * @order: Current entry order. | |
| 991 | 991 | * @gfp: Memory allocation flags. |
| 992 | 992 | * |
| 993 | 993 | * This function should be called before calling xas_split(). |
| @@ -1011,7 +1011,7 @@ void xas_split_alloc(struct xa_state *xas, void *entry, unsigned int order, · 17 unmodified lines | ||
| 1011 | 1011 | |
| 1012 | 1012 | do { |
| 1013 | 1013 | unsigned int i; |
| 1014 | − void *sibling; | |
| 1014 | + void *sibling = NULL; | |
| 1015 | 1015 | struct xa_node *node; |
| 1016 | 1016 | |
| 1017 | 1017 | node = kmem_cache_alloc(radix_tree_node_cachep, gfp); |
| @@ -1021,7 +1021,7 @@ void xas_split_alloc(struct xa_state *xas, void *entry, unsigned int order, · 3 unmodified lines | ||
| 1021 | 1021 | for (i = 0; i < XA_CHUNK_SIZE; i++) { |
| 1022 | 1022 | if ((i & mask) == 0) { |
| 1023 | 1023 | RCU_INIT_POINTER(node->slots[i], entry); |
| 1024 | − sibling = xa_mk_sibling(0); | |
| 1024 | + sibling = xa_mk_sibling(i); | |
| 1025 | 1025 | } else { |
| 1026 | 1026 | RCU_INIT_POINTER(node->slots[i], sibling); |
| 1027 | 1027 | } |
| @@ -1041,9 +1041,10 @@ EXPORT_SYMBOL_GPL(xas_split_alloc); · 13 unmodified lines | ||
| 1041 | 1041 | * xas_split() - Split a multi-index entry into smaller entries. |
| 1042 | 1042 | * @xas: XArray operation state. |
| 1043 | 1043 | * @entry: New entry to store in the array. |
| 1044 | − * @order: New entry order. | |
| 1044 | + * @order: Current entry order. | |
| 1045 | 1045 | * |
| 1046 | − * The value in the entry is copied to all the replacement entries. | |
| 1046 | + * The size of the new entries is set in @xas. The value in @entry is | |
| 1047 | + * copied to all the replacement entries. | |
| 1047 | 1048 | * |
| 1048 | 1049 | * Context: Any context. The caller should hold the xa_lock. |
| 1049 | 1050 | */ |
| @@ -618,7 +618,7 @@ void __kmap_local_sched_out(void) · 617 unmodified lines | ||
| 618 | 618 | int idx; |
| 619 | 619 | |
| 620 | 620 | /* With debug all even slots are unmapped and act as guard */ |
| 621 | − if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !(i & 0x01)) { | |
| 621 | + if (IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL) && !(i & 0x01)) { | |
| 622 | 622 | WARN_ON_ONCE(!pte_none(pteval)); |
| 623 | 623 | continue; |
| 624 | 624 | } |
| @@ -654,7 +654,7 @@ void __kmap_local_sched_in(void) · 29 unmodified lines | ||
| 654 | 654 | int idx; |
| 655 | 655 | |
| 656 | 656 | /* With debug all even slots are unmapped and act as guard */ |
| 657 | − if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !(i & 0x01)) { | |
| 657 | + if (IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL) && !(i & 0x01)) { | |
| 658 | 658 | WARN_ON_ONCE(!pte_none(pteval)); |
| 659 | 659 | continue; |
| 660 | 660 | } |
| @@ -280,6 +280,17 @@ static void record_hugetlb_cgroup_uncharge_info(struct hugetlb_cgroup *h_cg, · 279 unmodified lines | ||
| 280 | 280 | nrg->reservation_counter = |
| 281 | 281 | &h_cg->rsvd_hugepage[hstate_index(h)]; |
| 282 | 282 | nrg->css = &h_cg->css; |
| 283 | + /* | |
| 284 | + * The caller will hold exactly one h_cg->css reference for the | |
| 285 | + * whole contiguous reservation region. But this area might be | |
| 286 | + * scattered when there are already some file_regions reside in | |
| 287 | + * it. As a result, many file_regions may share only one css | |
| 288 | + * reference. In order to ensure that one file_region must hold | |
| 289 | + * exactly one h_cg->css reference, we should do css_get for | |
| 290 | + * each file_region and leave the reference held by caller | |
| 291 | + * untouched. | |
| 292 | + */ | |
| 293 | + css_get(&h_cg->css); | |
| 283 | 294 | if (!resv->pages_per_hpage) |
| 284 | 295 | resv->pages_per_hpage = pages_per_huge_page(h); |
| 285 | 296 | /* pages_per_hpage should be the same for all entries in |
| @@ -293,6 +304,14 @@ static void record_hugetlb_cgroup_uncharge_info(struct hugetlb_cgroup *h_cg, · 7 unmodified lines | ||
| 293 | 304 | #endif |
| 294 | 305 | } |
| 295 | 306 | |
| 307 | +static void put_uncharge_info(struct file_region *rg) | |
| 308 | +{ | |
| 309 | +#ifdef CONFIG_CGROUP_HUGETLB | |
| 310 | + if (rg->css) | |
| 311 | + css_put(rg->css); | |
| 312 | +#endif | |
| 313 | +} | |
| 314 | + | |
| 296 | 315 | static bool has_same_uncharge_info(struct file_region *rg, |
| 297 | 316 | struct file_region *org) |
| 298 | 317 | { |
| @@ -316,6 +335,7 @@ static void coalesce_file_region(struct resv_map *resv, struct file_region *rg) · 17 unmodified lines | ||
| 316 | 335 | prg->to = rg->to; |
| 317 | 336 | |
| 318 | 337 | list_del(&rg->link); |
| 338 | + put_uncharge_info(rg); | |
| 319 | 339 | kfree(rg); |
| 320 | 340 | |
| 321 | 341 | rg = prg; |
| @@ -327,6 +347,7 @@ static void coalesce_file_region(struct resv_map *resv, struct file_region *rg) · 5 unmodified lines | ||
| 327 | 347 | nrg->from = rg->from; |
| 328 | 348 | |
| 329 | 349 | list_del(&rg->link); |
| 350 | + put_uncharge_info(rg); | |
| 330 | 351 | kfree(rg); |
| 331 | 352 | } |
| 332 | 353 | } |
| @@ -662,7 +683,7 @@ retry: · 329 unmodified lines | ||
| 662 | 683 | |
| 663 | 684 | del += t - f; |
| 664 | 685 | hugetlb_cgroup_uncharge_file_region( |
| 665 | − resv, rg, t - f); | |
| 686 | + resv, rg, t - f, false); | |
| 666 | 687 | |
| 667 | 688 | /* New entry for end of split region */ |
| 668 | 689 | nrg->from = t; |
| @@ -683,7 +704,7 @@ retry: · 14 unmodified lines | ||
| 683 | 704 | if (f <= rg->from && t >= rg->to) { /* Remove entire region */ |
| 684 | 705 | del += rg->to - rg->from; |
| 685 | 706 | hugetlb_cgroup_uncharge_file_region(resv, rg, |
| 686 | − rg->to - rg->from); | |
| 707 | + rg->to - rg->from, true); | |
| 687 | 708 | list_del(&rg->link); |
| 688 | 709 | kfree(rg); |
| 689 | 710 | continue; |
| @@ -691,13 +712,13 @@ retry: · 1 unmodified line | ||
| 691 | 712 | |
| 692 | 713 | if (f <= rg->from) { /* Trim beginning of region */ |
| 693 | 714 | hugetlb_cgroup_uncharge_file_region(resv, rg, |
| 694 | − t - rg->from); | |
| 715 | + t - rg->from, false); | |
| 695 | 716 | |
| 696 | 717 | del += t - rg->from; |
| 697 | 718 | rg->from = t; |
| 698 | 719 | } else { /* Trim end of region */ |
| 699 | 720 | hugetlb_cgroup_uncharge_file_region(resv, rg, |
| 700 | − rg->to - f); | |
| 721 | + rg->to - f, false); | |
| 701 | 722 | |
| 702 | 723 | del += rg->to - f; |
| 703 | 724 | rg->to = f; |
| @@ -5187,6 +5208,10 @@ bool hugetlb_reserve_pages(struct inode *inode, · 4483 unmodified lines | ||
| 5187 | 5208 | */ |
| 5188 | 5209 | long rsv_adjust; |
| 5189 | 5210 | |
| 5211 | + /* | |
| 5212 | + * hugetlb_cgroup_uncharge_cgroup_rsvd() will put the | |
| 5213 | + * reference to h_cg->css. See comment below for detail. | |
| 5214 | + */ | |
| 5190 | 5215 | hugetlb_cgroup_uncharge_cgroup_rsvd( |
| 5191 | 5216 | hstate_index(h), |
| 5192 | 5217 | (chg - add) * pages_per_huge_page(h), h_cg); |
| @@ -5194,6 +5219,14 @@ bool hugetlb_reserve_pages(struct inode *inode, · 1 unmodified line | ||
| 5194 | 5219 | rsv_adjust = hugepage_subpool_put_pages(spool, |
| 5195 | 5220 | chg - add); |
| 5196 | 5221 | hugetlb_acct_memory(h, -rsv_adjust); |
| 5222 | + } else if (h_cg) { | |
| 5223 | + /* | |
| 5224 | + * The file_regions will hold their own reference to | |
| 5225 | + * h_cg->css. So we should release the reference held | |
| 5226 | + * via hugetlb_cgroup_charge_cgroup_rsvd() when we are | |
| 5227 | + * done. | |
| 5228 | + */ | |
| 5229 | + hugetlb_cgroup_put_rsvd_cgroup(h_cg); | |
| 5197 | 5230 | } |
| 5198 | 5231 | } |
| 5199 | 5232 | return true; |
| @@ -391,7 +391,8 @@ void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, unsigned long start, · 390 unmodified lines | ||
| 391 | 391 | |
| 392 | 392 | void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, |
| 393 | 393 | struct file_region *rg, |
| 394 | − unsigned long nr_pages) | |
| 394 | + unsigned long nr_pages, | |
| 395 | + bool region_del) | |
| 395 | 396 | { |
| 396 | 397 | if (hugetlb_cgroup_disabled() || !resv || !rg || !nr_pages) |
| 397 | 398 | return; |
| @@ -400,7 +401,12 @@ void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, · 2 unmodified lines | ||
| 400 | 401 | !resv->reservation_counter) { |
| 401 | 402 | page_counter_uncharge(rg->reservation_counter, |
| 402 | 403 | nr_pages * resv->pages_per_hpage); |
| 403 | − css_put(rg->css); | |
| 404 | + /* | |
| 405 | + * Only do css_put(rg->css) when we delete the entire region | |
| 406 | + * because one file_region must hold exactly one css reference. | |
| 407 | + */ | |
| 408 | + if (region_del) | |
| 409 | + css_put(rg->css); | |
| 404 | 410 | } |
| 405 | 411 | } |
| 406 | 412 | |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/debugfs.h> |
| 13 | 13 | #include <linux/kcsan-checks.h> |
| 14 | 14 | #include <linux/kfence.h> |
| 15 | +#include <linux/kmemleak.h> | |
| 15 | 16 | #include <linux/list.h> |
| 16 | 17 | #include <linux/lockdep.h> |
| 17 | 18 | #include <linux/memblock.h> |
| @@ -480,6 +481,14 @@ static bool __init kfence_init_pool(void) · 462 unmodified lines | ||
| 480 | 481 | addr += 2 * PAGE_SIZE; |
| 481 | 482 | } |
| 482 | 483 | |
| 484 | + /* | |
| 485 | + * The pool is live and will never be deallocated from this point on. | |
| 486 | + * Remove the pool object from the kmemleak object tree, as it would | |
| 487 | + * otherwise overlap with allocations returned by kfence_alloc(), which | |
| 488 | + * are registered with kmemleak through the slab post-alloc hook. | |
| 489 | + */ | |
| 490 | + kmemleak_free(__kfence_pool); | |
| 491 | + | |
| 483 | 492 | return true; |
| 484 | 493 | |
| 485 | 494 | err: |
| @@ -97,6 +97,7 @@ · 96 unmodified lines | ||
| 97 | 97 | #include <linux/atomic.h> |
| 98 | 98 | |
| 99 | 99 | #include <linux/kasan.h> |
| 100 | +#include <linux/kfence.h> | |
| 100 | 101 | #include <linux/kmemleak.h> |
| 101 | 102 | #include <linux/memory_hotplug.h> |
| 102 | 103 | |
| @@ -589,7 +590,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, · 486 unmodified lines | ||
| 589 | 590 | atomic_set(&object->use_count, 1); |
| 590 | 591 | object->flags = OBJECT_ALLOCATED; |
| 591 | 592 | object->pointer = ptr; |
| 592 | − object->size = size; | |
| 593 | + object->size = kfence_ksize((void *)ptr) ?: size; | |
| 593 | 594 | object->excess_ref = 0; |
| 594 | 595 | object->min_count = min_count; |
| 595 | 596 | object->count = 0; /* white color initially */ |
| @@ -166,7 +166,7 @@ static int __init init_zero_pfn(void) · 165 unmodified lines | ||
| 166 | 166 | zero_pfn = page_to_pfn(ZERO_PAGE(0)); |
| 167 | 167 | return 0; |
| 168 | 168 | } |
| 169 | −core_initcall(init_zero_pfn); | |
| 169 | +early_initcall(init_zero_pfn); | |
| 170 | 170 | |
| 171 | 171 | void mm_trace_rss_stat(struct mm_struct *mm, int member, long count) |
| 172 | 172 | { |
| @@ -501,10 +501,33 @@ static int mn_hlist_invalidate_range_start( · 500 unmodified lines | ||
| 501 | 501 | ""); |
| 502 | 502 | WARN_ON(mmu_notifier_range_blockable(range) || |
| 503 | 503 | _ret != -EAGAIN); |
| 504 | + /* | |
| 505 | + * We call all the notifiers on any EAGAIN, | |
| 506 | + * there is no way for a notifier to know if | |
| 507 | + * its start method failed, thus a start that | |
| 508 | + * does EAGAIN can't also do end. | |
| 509 | + */ | |
| 510 | + WARN_ON(ops->invalidate_range_end); | |
| 504 | 511 | ret = _ret; |
| 505 | 512 | } |
| 506 | 513 | } |
| 507 | 514 | } |
| 515 | + | |
| 516 | + if (ret) { | |
| 517 | + /* | |
| 518 | + * Must be non-blocking to get here. If there are multiple | |
| 519 | + * notifiers and one or more failed start, any that succeeded | |
| 520 | + * start are expecting their end to be called. Do so now. | |
| 521 | + */ | |
| 522 | + hlist_for_each_entry_rcu(subscription, &subscriptions->list, | |
| 523 | + hlist, srcu_read_lock_held(&srcu)) { | |
| 524 | + if (!subscription->ops->invalidate_range_end) | |
| 525 | + continue; | |
| 526 | + | |
| 527 | + subscription->ops->invalidate_range_end(subscription, | |
| 528 | + range); | |
| 529 | + } | |
| 530 | + } | |
| 508 | 531 | srcu_read_unlock(&srcu, id); |
| 509 | 532 | |
| 510 | 533 | return ret; |
| @@ -2833,6 +2833,22 @@ void wait_on_page_writeback(struct page *page) · 2832 unmodified lines | ||
| 2833 | 2833 | } |
| 2834 | 2834 | EXPORT_SYMBOL_GPL(wait_on_page_writeback); |
| 2835 | 2835 | |
| 2836 | +/* | |
| 2837 | + * Wait for a page to complete writeback. Returns -EINTR if we get a | |
| 2838 | + * fatal signal while waiting. | |
| 2839 | + */ | |
| 2840 | +int wait_on_page_writeback_killable(struct page *page) | |
| 2841 | +{ | |
| 2842 | + while (PageWriteback(page)) { | |
| 2843 | + trace_wait_on_page_writeback(page, page_mapping(page)); | |
| 2844 | + if (wait_on_page_bit_killable(page, PG_writeback)) | |
| 2845 | + return -EINTR; | |
| 2846 | + } | |
| 2847 | + | |
| 2848 | + return 0; | |
| 2849 | +} | |
| 2850 | +EXPORT_SYMBOL_GPL(wait_on_page_writeback_killable); | |
| 2851 | + | |
| 2836 | 2852 | /** |
| 2837 | 2853 | * wait_for_stable_page() - wait for writeback to finish, if necessary. |
| 2838 | 2854 | * @page: The page to wait on. |
| @@ -1346,8 +1346,22 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) · 1345 unmodified lines | ||
| 1346 | 1346 | page = list_entry(pos, struct page, lru); |
| 1347 | 1347 | |
| 1348 | 1348 | zhdr = page_address(page); |
| 1349 | − if (test_bit(PAGE_HEADLESS, &page->private)) | |
| 1349 | + if (test_bit(PAGE_HEADLESS, &page->private)) { | |
| 1350 | + /* | |
| 1351 | + * For non-headless pages, we wait to do this | |
| 1352 | + * until we have the page lock to avoid racing | |
| 1353 | + * with __z3fold_alloc(). Headless pages don't | |
| 1354 | + * have a lock (and __z3fold_alloc() will never | |
| 1355 | + * see them), but we still need to test and set | |
| 1356 | + * PAGE_CLAIMED to avoid racing with | |
| 1357 | + * z3fold_free(), so just do it now before | |
| 1358 | + * leaving the loop. | |
| 1359 | + */ | |
| 1360 | + if (test_and_set_bit(PAGE_CLAIMED, &page->private)) | |
| 1361 | + continue; | |
| 1362 | + | |
| 1350 | 1363 | break; |
| 1364 | + } | |
| 1351 | 1365 | |
| 1352 | 1366 | if (kref_get_unless_zero(&zhdr->refcount) == 0) { |
| 1353 | 1367 | zhdr = NULL; |
| @@ -128,6 +128,8 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) · 127 unmodified lines | ||
| 128 | 128 | { |
| 129 | 129 | if (!fdb->dst) |
| 130 | 130 | return; |
| 131 | + if (test_bit(BR_FDB_LOCAL, &fdb->flags)) | |
| 132 | + return; | |
| 131 | 133 | |
| 132 | 134 | switch (type) { |
| 133 | 135 | case RTM_DELNEIGH: |
| @@ -196,7 +196,7 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus) · 195 unmodified lines | ||
| 196 | 196 | nskb->dev = dev; |
| 197 | 197 | can_skb_set_owner(nskb, sk); |
| 198 | 198 | ncf = (struct canfd_frame *)nskb->data; |
| 199 | − skb_put(nskb, so->ll.mtu); | |
| 199 | + skb_put_zero(nskb, so->ll.mtu); | |
| 200 | 200 | |
| 201 | 201 | /* create & send flow control reply */ |
| 202 | 202 | ncf->can_id = so->txid; |
| @@ -215,8 +215,7 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus) · 12 unmodified lines | ||
| 215 | 215 | if (ae) |
| 216 | 216 | ncf->data[0] = so->opt.ext_address; |
| 217 | 217 | |
| 218 | − if (so->ll.mtu == CANFD_MTU) | |
| 219 | − ncf->flags = so->ll.tx_flags; | |
| 218 | + ncf->flags = so->ll.tx_flags; | |
| 220 | 219 | |
| 221 | 220 | can_send_ret = can_send(nskb, 1); |
| 222 | 221 | if (can_send_ret) |
| @@ -780,7 +779,7 @@ isotp_tx_burst: · 557 unmodified lines | ||
| 780 | 779 | can_skb_prv(skb)->skbcnt = 0; |
| 781 | 780 | |
| 782 | 781 | cf = (struct canfd_frame *)skb->data; |
| 783 | − skb_put(skb, so->ll.mtu); | |
| 782 | + skb_put_zero(skb, so->ll.mtu); | |
| 784 | 783 | |
| 785 | 784 | /* create consecutive frame */ |
| 786 | 785 | isotp_fill_dataframe(cf, so, ae, 0); |
| @@ -790,8 +789,7 @@ isotp_tx_burst: · 3 unmodified lines | ||
| 790 | 789 | so->tx.sn %= 16; |
| 791 | 790 | so->tx.bs++; |
| 792 | 791 | |
| 793 | − if (so->ll.mtu == CANFD_MTU) | |
| 794 | − cf->flags = so->ll.tx_flags; | |
| 792 | + cf->flags = so->ll.tx_flags; | |
| 795 | 793 | |
| 796 | 794 | skb->dev = dev; |
| 797 | 795 | can_skb_set_owner(skb, sk); |
| @@ -897,7 +895,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) · 99 unmodified lines | ||
| 897 | 895 | so->tx.idx = 0; |
| 898 | 896 | |
| 899 | 897 | cf = (struct canfd_frame *)skb->data; |
| 900 | − skb_put(skb, so->ll.mtu); | |
| 898 | + skb_put_zero(skb, so->ll.mtu); | |
| 901 | 899 | |
| 902 | 900 | /* check for single frame transmission depending on TX_DL */ |
| 903 | 901 | if (size <= so->tx.ll_dl - SF_PCI_SZ4 - ae - off) { |
| @@ -939,8 +937,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) · 35 unmodified lines | ||
| 939 | 937 | } |
| 940 | 938 | |
| 941 | 939 | /* send the first or only CAN frame */ |
| 942 | − if (so->ll.mtu == CANFD_MTU) | |
| 943 | − cf->flags = so->ll.tx_flags; | |
| 940 | + cf->flags = so->ll.tx_flags; | |
| 944 | 941 | |
| 945 | 942 | skb->dev = dev; |
| 946 | 943 | skb->sk = sk; |
| @@ -1228,7 +1225,8 @@ static int isotp_setsockopt(struct socket *sock, int level, int optname, · 281 unmodified lines | ||
| 1228 | 1225 | if (ll.mtu != CAN_MTU && ll.mtu != CANFD_MTU) |
| 1229 | 1226 | return -EINVAL; |
| 1230 | 1227 | |
| 1231 | − if (ll.mtu == CAN_MTU && ll.tx_dl > CAN_MAX_DLEN) | |
| 1228 | + if (ll.mtu == CAN_MTU && | |
| 1229 | + (ll.tx_dl > CAN_MAX_DLEN || ll.tx_flags != 0)) | |
| 1232 | 1230 | return -EINVAL; |
| 1233 | 1231 | |
| 1234 | 1232 | memcpy(&so->ll, &ll, sizeof(ll)); |
| @@ -1184,6 +1184,18 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) · 1183 unmodified lines | ||
| 1184 | 1184 | return -ENOMEM; |
| 1185 | 1185 | |
| 1186 | 1186 | for_each_netdev(net, d) { |
| 1187 | + struct netdev_name_node *name_node; | |
| 1188 | + list_for_each_entry(name_node, &d->name_node->list, list) { | |
| 1189 | + if (!sscanf(name_node->name, name, &i)) | |
| 1190 | + continue; | |
| 1191 | + if (i < 0 || i >= max_netdevices) | |
| 1192 | + continue; | |
| 1193 | + | |
| 1194 | + /* avoid cases where sscanf is not exact inverse of printf */ | |
| 1195 | + snprintf(buf, IFNAMSIZ, name, i); | |
| 1196 | + if (!strncmp(buf, name_node->name, IFNAMSIZ)) | |
| 1197 | + set_bit(i, inuse); | |
| 1198 | + } | |
| 1187 | 1199 | if (!sscanf(d->name, name, &i)) |
| 1188 | 1200 | continue; |
| 1189 | 1201 | if (i < 0 || i >= max_netdevices) |
| @@ -4294,6 +4306,13 @@ static inline void ____napi_schedule(struct softnet_data *sd, · 3104 unmodified lines | ||
| 4294 | 4306 | */ |
| 4295 | 4307 | thread = READ_ONCE(napi->thread); |
| 4296 | 4308 | if (thread) { |
| 4309 | + /* Avoid doing set_bit() if the thread is in | |
| 4310 | + * INTERRUPTIBLE state, cause napi_thread_wait() | |
| 4311 | + * makes sure to proceed with napi polling | |
| 4312 | + * if the thread is explicitly woken from here. | |
| 4313 | + */ | |
| 4314 | + if (READ_ONCE(thread->state) != TASK_INTERRUPTIBLE) | |
| 4315 | + set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); | |
| 4297 | 4316 | wake_up_process(thread); |
| 4298 | 4317 | return; |
| 4299 | 4318 | } |
| @@ -6486,6 +6505,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done) · 2186 unmodified lines | ||
| 6486 | 6505 | WARN_ON_ONCE(!(val & NAPIF_STATE_SCHED)); |
| 6487 | 6506 | |
| 6488 | 6507 | new = val & ~(NAPIF_STATE_MISSED | NAPIF_STATE_SCHED | |
| 6508 | + NAPIF_STATE_SCHED_THREADED | | |
| 6489 | 6509 | NAPIF_STATE_PREFER_BUSY_POLL); |
| 6490 | 6510 | |
| 6491 | 6511 | /* If STATE_MISSED was set, leave STATE_SCHED set, |
| @@ -6968,16 +6988,25 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll) · 476 unmodified lines | ||
| 6968 | 6988 | |
| 6969 | 6989 | static int napi_thread_wait(struct napi_struct *napi) |
| 6970 | 6990 | { |
| 6991 | + bool woken = false; | |
| 6992 | + | |
| 6971 | 6993 | set_current_state(TASK_INTERRUPTIBLE); |
| 6972 | 6994 | |
| 6973 | 6995 | while (!kthread_should_stop() && !napi_disable_pending(napi)) { |
| 6974 | − if (test_bit(NAPI_STATE_SCHED, &napi->state)) { | |
| 6996 | + /* Testing SCHED_THREADED bit here to make sure the current | |
| 6997 | + * kthread owns this napi and could poll on this napi. | |
| 6998 | + * Testing SCHED bit is not enough because SCHED bit might be | |
| 6999 | + * set by some other busy poll thread or by napi_disable(). | |
| 7000 | + */ | |
| 7001 | + if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) { | |
| 6975 | 7002 | WARN_ON(!list_empty(&napi->poll_list)); |
| 6976 | 7003 | __set_current_state(TASK_RUNNING); |
| 6977 | 7004 | return 0; |
| 6978 | 7005 | } |
| 6979 | 7006 | |
| 6980 | 7007 | schedule(); |
| 7008 | + /* woken being true indicates this thread owns this napi. */ | |
| 7009 | + woken = true; | |
| 6981 | 7010 | set_current_state(TASK_INTERRUPTIBLE); |
| 6982 | 7011 | } |
| 6983 | 7012 | __set_current_state(TASK_RUNNING); |
| @@ -11346,7 +11375,7 @@ static void __net_exit default_device_exit(struct net *net) · 4362 unmodified lines | ||
| 11346 | 11375 | continue; |
| 11347 | 11376 | |
| 11348 | 11377 | /* Leave virtual devices for the generic cleanup */ |
| 11349 | − if (dev->rtnl_link_ops) | |
| 11378 | + if (dev->rtnl_link_ops && !dev->rtnl_link_ops->netns_refund) | |
| 11350 | 11379 | continue; |
| 11351 | 11380 | |
| 11352 | 11381 | /* Push remaining network devices to init_net */ |
| @@ -1053,6 +1053,20 @@ static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack) · 1052 unmodified lines | ||
| 1053 | 1053 | return 0; |
| 1054 | 1054 | |
| 1055 | 1055 | err_module_put: |
| 1056 | + for_each_possible_cpu(cpu) { | |
| 1057 | + struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu); | |
| 1058 | + struct sk_buff *skb; | |
| 1059 | + | |
| 1060 | + del_timer_sync(&hw_data->send_timer); | |
| 1061 | + cancel_work_sync(&hw_data->dm_alert_work); | |
| 1062 | + while ((skb = __skb_dequeue(&hw_data->drop_queue))) { | |
| 1063 | + struct devlink_trap_metadata *hw_metadata; | |
| 1064 | + | |
| 1065 | + hw_metadata = NET_DM_SKB_CB(skb)->hw_metadata; | |
| 1066 | + net_dm_hw_metadata_free(hw_metadata); | |
| 1067 | + consume_skb(skb); | |
| 1068 | + } | |
| 1069 | + } | |
| 1056 | 1070 | module_put(THIS_MODULE); |
| 1057 | 1071 | return rc; |
| 1058 | 1072 | } |
| @@ -1134,6 +1148,15 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) · 75 unmodified lines | ||
| 1134 | 1148 | err_unregister_trace: |
| 1135 | 1149 | unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL); |
| 1136 | 1150 | err_module_put: |
| 1151 | + for_each_possible_cpu(cpu) { | |
| 1152 | + struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu); | |
| 1153 | + struct sk_buff *skb; | |
| 1154 | + | |
| 1155 | + del_timer_sync(&data->send_timer); | |
| 1156 | + cancel_work_sync(&data->dm_alert_work); | |
| 1157 | + while ((skb = __skb_dequeue(&data->drop_queue))) | |
| 1158 | + consume_skb(skb); | |
| 1159 | + } | |
| 1137 | 1160 | module_put(THIS_MODULE); |
| 1138 | 1161 | return rc; |
| 1139 | 1162 | } |
| @@ -237,37 +237,62 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) · 236 unmodified lines | ||
| 237 | 237 | } |
| 238 | 238 | EXPORT_SYMBOL(__dst_destroy_metrics_generic); |
| 239 | 239 | |
| 240 | −static struct dst_ops md_dst_ops = { | |
| 241 | − .family = AF_UNSPEC, | |
| 242 | −}; | |
| 240 | +struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie) | |
| 241 | +{ | |
| 242 | + return NULL; | |
| 243 | +} | |
| 243 | 244 | |
| 244 | −static int dst_md_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb) | |
| 245 | +u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old) | |
| 245 | 246 | { |
| 246 | − WARN_ONCE(1, "Attempting to call output on metadata dst\n"); | |
| 247 | − kfree_skb(skb); | |
| 248 | − return 0; | |
| 247 | + return NULL; | |
| 249 | 248 | } |
| 250 | 249 | |
| 251 | −static int dst_md_discard(struct sk_buff *skb) | |
| 250 | +struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst, | |
| 251 | + struct sk_buff *skb, | |
| 252 | + const void *daddr) | |
| 252 | 253 | { |
| 253 | − WARN_ONCE(1, "Attempting to call input on metadata dst\n"); | |
| 254 | − kfree_skb(skb); | |
| 255 | − return 0; | |
| 254 | + return NULL; | |
| 255 | +} | |
| 256 | + | |
| 257 | +void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, | |
| 258 | + struct sk_buff *skb, u32 mtu, | |
| 259 | + bool confirm_neigh) | |
| 260 | +{ | |
| 261 | +} | |
| 262 | +EXPORT_SYMBOL_GPL(dst_blackhole_update_pmtu); | |
| 263 | + | |
| 264 | +void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk, | |
| 265 | + struct sk_buff *skb) | |
| 266 | +{ | |
| 267 | +} | |
| 268 | +EXPORT_SYMBOL_GPL(dst_blackhole_redirect); | |
| 269 | + | |
| 270 | +unsigned int dst_blackhole_mtu(const struct dst_entry *dst) | |
| 271 | +{ | |
| 272 | + unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); | |
| 273 | + | |
| 274 | + return mtu ? : dst->dev->mtu; | |
| 256 | 275 | } |
| 276 | +EXPORT_SYMBOL_GPL(dst_blackhole_mtu); | |
| 277 | + | |
| 278 | +static struct dst_ops dst_blackhole_ops = { | |
| 279 | + .family = AF_UNSPEC, | |
| 280 | + .neigh_lookup = dst_blackhole_neigh_lookup, | |
| 281 | + .check = dst_blackhole_check, | |
| 282 | + .cow_metrics = dst_blackhole_cow_metrics, | |
| 283 | + .update_pmtu = dst_blackhole_update_pmtu, | |
| 284 | + .redirect = dst_blackhole_redirect, | |
| 285 | + .mtu = dst_blackhole_mtu, | |
| 286 | +}; | |
| 257 | 287 | |
| 258 | 288 | static void __metadata_dst_init(struct metadata_dst *md_dst, |
| 259 | 289 | enum metadata_type type, u8 optslen) |
| 260 | − | |
| 261 | 290 | { |
| 262 | 291 | struct dst_entry *dst; |
| 263 | 292 | |
| 264 | 293 | dst = &md_dst->dst; |
| 265 | − dst_init(dst, &md_dst_ops, NULL, 1, DST_OBSOLETE_NONE, | |
| 294 | + dst_init(dst, &dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, | |
| 266 | 295 | DST_METADATA | DST_NOCOUNT); |
| 267 | − | |
| 268 | − dst->input = dst_md_discard; | |
| 269 | − dst->output = dst_md_discard_out; | |
| 270 | − | |
| 271 | 296 | memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst)); |
| 272 | 297 | md_dst->type = type; |
| 273 | 298 | } |
| @@ -5658,7 +5658,7 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, · 5657 unmodified lines | ||
| 5658 | 5658 | if (unlikely(flags & ~(BPF_MTU_CHK_SEGS))) |
| 5659 | 5659 | return -EINVAL; |
| 5660 | 5660 | |
| 5661 | − if (unlikely(flags & BPF_MTU_CHK_SEGS && len_diff)) | |
| 5661 | + if (unlikely(flags & BPF_MTU_CHK_SEGS && (len_diff || *mtu_len))) | |
| 5662 | 5662 | return -EINVAL; |
| 5663 | 5663 | |
| 5664 | 5664 | dev = __dev_via_ifindex(dev, ifindex); |
| @@ -5668,7 +5668,11 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, · 3 unmodified lines | ||
| 5668 | 5668 | mtu = READ_ONCE(dev->mtu); |
| 5669 | 5669 | |
| 5670 | 5670 | dev_len = mtu + dev->hard_header_len; |
| 5671 | − skb_len = skb->len + len_diff; /* minus result pass check */ | |
| 5671 | + | |
| 5672 | + /* If set use *mtu_len as input, L3 as iph->tot_len (like fib_lookup) */ | |
| 5673 | + skb_len = *mtu_len ? *mtu_len + dev->hard_header_len : skb->len; | |
| 5674 | + | |
| 5675 | + skb_len += len_diff; /* minus result pass check */ | |
| 5672 | 5676 | if (skb_len <= dev_len) { |
| 5673 | 5677 | ret = BPF_MTU_CHK_RET_SUCCESS; |
| 5674 | 5678 | goto out; |
| @@ -5713,6 +5717,10 @@ BPF_CALL_5(bpf_xdp_check_mtu, struct xdp_buff *, xdp, · 38 unmodified lines | ||
| 5713 | 5717 | /* Add L2-header as dev MTU is L3 size */ |
| 5714 | 5718 | dev_len = mtu + dev->hard_header_len; |
| 5715 | 5719 | |
| 5720 | + /* Use *mtu_len as input, L3 as iph->tot_len (like fib_lookup) */ | |
| 5721 | + if (*mtu_len) | |
| 5722 | + xdp_len = *mtu_len + dev->hard_header_len; | |
| 5723 | + | |
| 5716 | 5724 | xdp_len += len_diff; /* minus result pass check */ |
| 5717 | 5725 | if (xdp_len > dev_len) |
| 5718 | 5726 | ret = BPF_MTU_CHK_RET_FRAG_NEEDED; |
| @@ -176,7 +176,7 @@ void skb_flow_get_icmp_tci(const struct sk_buff *skb, · 175 unmodified lines | ||
| 176 | 176 | * avoid confusion with packets without such field |
| 177 | 177 | */ |
| 178 | 178 | if (icmp_has_id(ih->type)) |
| 179 | − key_icmp->id = ih->un.echo.id ? : 1; | |
| 179 | + key_icmp->id = ih->un.echo.id ? ntohs(ih->un.echo.id) : 1; | |
| 180 | 180 | else |
| 181 | 181 | key_icmp->id = 0; |
| 182 | 182 | } |
| @@ -3440,6 +3440,32 @@ static void tw_prot_cleanup(struct timewait_sock_ops *twsk_prot) · 3439 unmodified lines | ||
| 3440 | 3440 | twsk_prot->twsk_slab = NULL; |
| 3441 | 3441 | } |
| 3442 | 3442 | |
| 3443 | +static int tw_prot_init(const struct proto *prot) | |
| 3444 | +{ | |
| 3445 | + struct timewait_sock_ops *twsk_prot = prot->twsk_prot; | |
| 3446 | + | |
| 3447 | + if (!twsk_prot) | |
| 3448 | + return 0; | |
| 3449 | + | |
| 3450 | + twsk_prot->twsk_slab_name = kasprintf(GFP_KERNEL, "tw_sock_%s", | |
| 3451 | + prot->name); | |
| 3452 | + if (!twsk_prot->twsk_slab_name) | |
| 3453 | + return -ENOMEM; | |
| 3454 | + | |
| 3455 | + twsk_prot->twsk_slab = | |
| 3456 | + kmem_cache_create(twsk_prot->twsk_slab_name, | |
| 3457 | + twsk_prot->twsk_obj_size, 0, | |
| 3458 | + SLAB_ACCOUNT | prot->slab_flags, | |
| 3459 | + NULL); | |
| 3460 | + if (!twsk_prot->twsk_slab) { | |
| 3461 | + pr_crit("%s: Can't create timewait sock SLAB cache!\n", | |
| 3462 | + prot->name); | |
| 3463 | + return -ENOMEM; | |
| 3464 | + } | |
| 3465 | + | |
| 3466 | + return 0; | |
| 3467 | +} | |
| 3468 | + | |
| 3443 | 3469 | static void req_prot_cleanup(struct request_sock_ops *rsk_prot) |
| 3444 | 3470 | { |
| 3445 | 3471 | if (!rsk_prot) |
| @@ -3496,22 +3522,8 @@ int proto_register(struct proto *prot, int alloc_slab) · 50 unmodified lines | ||
| 3496 | 3522 | if (req_prot_init(prot)) |
| 3497 | 3523 | goto out_free_request_sock_slab; |
| 3498 | 3524 | |
| 3499 | − if (prot->twsk_prot != NULL) { | |
| 3500 | − prot->twsk_prot->twsk_slab_name = kasprintf(GFP_KERNEL, "tw_sock_%s", prot->name); | |
| 3501 | − | |
| 3502 | − if (prot->twsk_prot->twsk_slab_name == NULL) | |
| 3503 | − goto out_free_request_sock_slab; | |
| 3504 | − | |
| 3505 | − prot->twsk_prot->twsk_slab = | |
| 3506 | − kmem_cache_create(prot->twsk_prot->twsk_slab_name, | |
| 3507 | − prot->twsk_prot->twsk_obj_size, | |
| 3508 | − 0, | |
| 3509 | − SLAB_ACCOUNT | | |
| 3510 | − prot->slab_flags, | |
| 3511 | − NULL); | |
| 3512 | − if (prot->twsk_prot->twsk_slab == NULL) | |
| 3513 | − goto out_free_timewait_sock_slab; | |
| 3514 | − } | |
| 3525 | + if (tw_prot_init(prot)) | |
| 3526 | + goto out_free_timewait_sock_slab; | |
| 3515 | 3527 | } |
| 3516 | 3528 | |
| 3517 | 3529 | mutex_lock(&proto_list_mutex); |
| @@ -319,6 +319,11 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) · 318 unmodified lines | ||
| 319 | 319 | if (!ipv6_unicast_destination(skb)) |
| 320 | 320 | return 0; /* discard, don't send a reset here */ |
| 321 | 321 | |
| 322 | + if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { | |
| 323 | + __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); | |
| 324 | + return 0; | |
| 325 | + } | |
| 326 | + | |
| 322 | 327 | if (dccp_bad_service_code(sk, service)) { |
| 323 | 328 | dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE; |
| 324 | 329 | goto drop; |
| @@ -1066,6 +1066,7 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) · 1065 unmodified lines | ||
| 1066 | 1066 | { |
| 1067 | 1067 | struct dsa_switch *ds = dp->ds; |
| 1068 | 1068 | struct dsa_switch_tree *dst = ds->dst; |
| 1069 | + const struct dsa_device_ops *tag_ops; | |
| 1069 | 1070 | enum dsa_tag_protocol tag_protocol; |
| 1070 | 1071 | |
| 1071 | 1072 | tag_protocol = dsa_get_tag_protocol(dp, master); |
| @@ -1080,14 +1081,16 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) · 8 unmodified lines | ||
| 1080 | 1081 | * nothing to do here. |
| 1081 | 1082 | */ |
| 1082 | 1083 | } else { |
| 1083 | − dst->tag_ops = dsa_tag_driver_get(tag_protocol); | |
| 1084 | − if (IS_ERR(dst->tag_ops)) { | |
| 1085 | − if (PTR_ERR(dst->tag_ops) == -ENOPROTOOPT) | |
| 1084 | + tag_ops = dsa_tag_driver_get(tag_protocol); | |
| 1085 | + if (IS_ERR(tag_ops)) { | |
| 1086 | + if (PTR_ERR(tag_ops) == -ENOPROTOOPT) | |
| 1086 | 1087 | return -EPROBE_DEFER; |
| 1087 | 1088 | dev_warn(ds->dev, "No tagger for this switch\n"); |
| 1088 | 1089 | dp->master = NULL; |
| 1089 | − return PTR_ERR(dst->tag_ops); | |
| 1090 | + return PTR_ERR(tag_ops); | |
| 1090 | 1091 | } |
| 1092 | + | |
| 1093 | + dst->tag_ops = tag_ops; | |
| 1091 | 1094 | } |
| 1092 | 1095 | |
| 1093 | 1096 | dp->master = master; |
| @@ -705,12 +705,15 @@ static bool reqsk_queue_unlink(struct request_sock *req) · 704 unmodified lines | ||
| 705 | 705 | return found; |
| 706 | 706 | } |
| 707 | 707 | |
| 708 | −void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) | |
| 708 | +bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) | |
| 709 | 709 | { |
| 710 | − if (reqsk_queue_unlink(req)) { | |
| 710 | + bool unlinked = reqsk_queue_unlink(req); | |
| 711 | + | |
| 712 | + if (unlinked) { | |
| 711 | 713 | reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); |
| 712 | 714 | reqsk_put(req); |
| 713 | 715 | } |
| 716 | + return unlinked; | |
| 714 | 717 | } |
| 715 | 718 | EXPORT_SYMBOL(inet_csk_reqsk_queue_drop); |
| 716 | 719 | |
| @@ -309,7 +309,7 @@ have_carrier: · 308 unmodified lines | ||
| 309 | 309 | */ |
| 310 | 310 | static void __init ic_close_devs(void) |
| 311 | 311 | { |
| 312 | − struct net_device *selected_dev = ic_dev->dev; | |
| 312 | + struct net_device *selected_dev = ic_dev ? ic_dev->dev : NULL; | |
| 313 | 313 | struct ic_device *d, *next; |
| 314 | 314 | struct net_device *dev; |
| 315 | 315 | |
| @@ -317,16 +317,18 @@ static void __init ic_close_devs(void) · 1 unmodified line | ||
| 317 | 317 | next = ic_first_dev; |
| 318 | 318 | while ((d = next)) { |
| 319 | 319 | bool bring_down = (d != ic_dev); |
| 320 | − struct net_device *lower_dev; | |
| 320 | + struct net_device *lower; | |
| 321 | 321 | struct list_head *iter; |
| 322 | 322 | |
| 323 | 323 | next = d->next; |
| 324 | 324 | dev = d->dev; |
| 325 | 325 | |
| 326 | − netdev_for_each_lower_dev(selected_dev, lower_dev, iter) { | |
| 327 | − if (dev == lower_dev) { | |
| 328 | − bring_down = false; | |
| 329 | − break; | |
| 326 | + if (selected_dev) { | |
| 327 | + netdev_for_each_lower_dev(selected_dev, lower, iter) { | |
| 328 | + if (dev == lower) { | |
| 329 | + bring_down = false; | |
| 330 | + break; | |
| 331 | + } | |
| 330 | 332 | } |
| 331 | 333 | } |
| 332 | 334 | if (bring_down) { |
| @@ -203,7 +203,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, · 202 unmodified lines | ||
| 203 | 203 | |
| 204 | 204 | local_bh_disable(); |
| 205 | 205 | addend = xt_write_recseq_begin(); |
| 206 | − private = rcu_access_pointer(table->private); | |
| 206 | + private = READ_ONCE(table->private); /* Address dependency. */ | |
| 207 | 207 | cpu = smp_processor_id(); |
| 208 | 208 | table_base = private->entries; |
| 209 | 209 | jumpstack = (struct arpt_entry **)private->jumpstack[cpu]; |
| @@ -649,7 +649,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) · 439 unmodified lines | ||
| 649 | 649 | { |
| 650 | 650 | unsigned int countersize; |
| 651 | 651 | struct xt_counters *counters; |
| 652 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 652 | + const struct xt_table_info *private = table->private; | |
| 653 | 653 | |
| 654 | 654 | /* We need atomic snapshot of counters: rest doesn't change |
| 655 | 655 | * (other than comefrom, which userspace doesn't care |
| @@ -673,7 +673,7 @@ static int copy_entries_to_user(unsigned int total_size, · 17 unmodified lines | ||
| 673 | 673 | unsigned int off, num; |
| 674 | 674 | const struct arpt_entry *e; |
| 675 | 675 | struct xt_counters *counters; |
| 676 | − struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 676 | + struct xt_table_info *private = table->private; | |
| 677 | 677 | int ret = 0; |
| 678 | 678 | void *loc_cpu_entry; |
| 679 | 679 | |
| @@ -807,7 +807,7 @@ static int get_info(struct net *net, void __user *user, const int *len) · 127 unmodified lines | ||
| 807 | 807 | t = xt_request_find_table_lock(net, NFPROTO_ARP, name); |
| 808 | 808 | if (!IS_ERR(t)) { |
| 809 | 809 | struct arpt_getinfo info; |
| 810 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 810 | + const struct xt_table_info *private = t->private; | |
| 811 | 811 | #ifdef CONFIG_COMPAT |
| 812 | 812 | struct xt_table_info tmp; |
| 813 | 813 | |
| @@ -860,7 +860,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, · 46 unmodified lines | ||
| 860 | 860 | |
| 861 | 861 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
| 862 | 862 | if (!IS_ERR(t)) { |
| 863 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 863 | + const struct xt_table_info *private = t->private; | |
| 864 | 864 | |
| 865 | 865 | if (get.size == private->size) |
| 866 | 866 | ret = copy_entries_to_user(private->size, |
| @@ -1017,7 +1017,7 @@ static int do_add_counters(struct net *net, sockptr_t arg, unsigned int len) · 150 unmodified lines | ||
| 1017 | 1017 | } |
| 1018 | 1018 | |
| 1019 | 1019 | local_bh_disable(); |
| 1020 | − private = xt_table_get_private_protected(t); | |
| 1020 | + private = t->private; | |
| 1021 | 1021 | if (private->number != tmp.num_counters) { |
| 1022 | 1022 | ret = -EINVAL; |
| 1023 | 1023 | goto unlock_up_free; |
| @@ -1330,7 +1330,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, · 306 unmodified lines | ||
| 1330 | 1330 | void __user *userptr) |
| 1331 | 1331 | { |
| 1332 | 1332 | struct xt_counters *counters; |
| 1333 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 1333 | + const struct xt_table_info *private = table->private; | |
| 1334 | 1334 | void __user *pos; |
| 1335 | 1335 | unsigned int size; |
| 1336 | 1336 | int ret = 0; |
| @@ -1379,7 +1379,7 @@ static int compat_get_entries(struct net *net, · 42 unmodified lines | ||
| 1379 | 1379 | xt_compat_lock(NFPROTO_ARP); |
| 1380 | 1380 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
| 1381 | 1381 | if (!IS_ERR(t)) { |
| 1382 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 1382 | + const struct xt_table_info *private = t->private; | |
| 1383 | 1383 | struct xt_table_info info; |
| 1384 | 1384 | |
| 1385 | 1385 | ret = compat_table_info(private, &info); |
| @@ -258,7 +258,7 @@ ipt_do_table(struct sk_buff *skb, · 257 unmodified lines | ||
| 258 | 258 | WARN_ON(!(table->valid_hooks & (1 << hook))); |
| 259 | 259 | local_bh_disable(); |
| 260 | 260 | addend = xt_write_recseq_begin(); |
| 261 | − private = rcu_access_pointer(table->private); | |
| 261 | + private = READ_ONCE(table->private); /* Address dependency. */ | |
| 262 | 262 | cpu = smp_processor_id(); |
| 263 | 263 | table_base = private->entries; |
| 264 | 264 | jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; |
| @@ -791,7 +791,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) · 526 unmodified lines | ||
| 791 | 791 | { |
| 792 | 792 | unsigned int countersize; |
| 793 | 793 | struct xt_counters *counters; |
| 794 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 794 | + const struct xt_table_info *private = table->private; | |
| 795 | 795 | |
| 796 | 796 | /* We need atomic snapshot of counters: rest doesn't change |
| 797 | 797 | (other than comefrom, which userspace doesn't care |
| @@ -815,7 +815,7 @@ copy_entries_to_user(unsigned int total_size, · 17 unmodified lines | ||
| 815 | 815 | unsigned int off, num; |
| 816 | 816 | const struct ipt_entry *e; |
| 817 | 817 | struct xt_counters *counters; |
| 818 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 818 | + const struct xt_table_info *private = table->private; | |
| 819 | 819 | int ret = 0; |
| 820 | 820 | const void *loc_cpu_entry; |
| 821 | 821 | |
| @@ -964,7 +964,7 @@ static int get_info(struct net *net, void __user *user, const int *len) · 142 unmodified lines | ||
| 964 | 964 | t = xt_request_find_table_lock(net, AF_INET, name); |
| 965 | 965 | if (!IS_ERR(t)) { |
| 966 | 966 | struct ipt_getinfo info; |
| 967 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 967 | + const struct xt_table_info *private = t->private; | |
| 968 | 968 | #ifdef CONFIG_COMPAT |
| 969 | 969 | struct xt_table_info tmp; |
| 970 | 970 | |
| @@ -1018,7 +1018,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, · 47 unmodified lines | ||
| 1018 | 1018 | |
| 1019 | 1019 | t = xt_find_table_lock(net, AF_INET, get.name); |
| 1020 | 1020 | if (!IS_ERR(t)) { |
| 1021 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 1021 | + const struct xt_table_info *private = t->private; | |
| 1022 | 1022 | if (get.size == private->size) |
| 1023 | 1023 | ret = copy_entries_to_user(private->size, |
| 1024 | 1024 | t, uptr->entrytable); |
| @@ -1173,7 +1173,7 @@ do_add_counters(struct net *net, sockptr_t arg, unsigned int len) · 148 unmodified lines | ||
| 1173 | 1173 | } |
| 1174 | 1174 | |
| 1175 | 1175 | local_bh_disable(); |
| 1176 | − private = xt_table_get_private_protected(t); | |
| 1176 | + private = t->private; | |
| 1177 | 1177 | if (private->number != tmp.num_counters) { |
| 1178 | 1178 | ret = -EINVAL; |
| 1179 | 1179 | goto unlock_up_free; |
| @@ -1543,7 +1543,7 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, · 363 unmodified lines | ||
| 1543 | 1543 | void __user *userptr) |
| 1544 | 1544 | { |
| 1545 | 1545 | struct xt_counters *counters; |
| 1546 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 1546 | + const struct xt_table_info *private = table->private; | |
| 1547 | 1547 | void __user *pos; |
| 1548 | 1548 | unsigned int size; |
| 1549 | 1549 | int ret = 0; |
| @@ -1589,7 +1589,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, · 39 unmodified lines | ||
| 1589 | 1589 | xt_compat_lock(AF_INET); |
| 1590 | 1590 | t = xt_find_table_lock(net, AF_INET, get.name); |
| 1591 | 1591 | if (!IS_ERR(t)) { |
| 1592 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 1592 | + const struct xt_table_info *private = t->private; | |
| 1593 | 1593 | struct xt_table_info info; |
| 1594 | 1594 | ret = compat_table_info(private, &info); |
| 1595 | 1595 | if (!ret && get.size == info.size) |
| @@ -2687,44 +2687,15 @@ out: · 2686 unmodified lines | ||
| 2687 | 2687 | return rth; |
| 2688 | 2688 | } |
| 2689 | 2689 | |
| 2690 | −static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie) | |
| 2691 | −{ | |
| 2692 | − return NULL; | |
| 2693 | −} | |
| 2694 | − | |
| 2695 | −static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst) | |
| 2696 | −{ | |
| 2697 | − unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); | |
| 2698 | − | |
| 2699 | − return mtu ? : dst->dev->mtu; | |
| 2700 | −} | |
| 2701 | − | |
| 2702 | −static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, | |
| 2703 | − struct sk_buff *skb, u32 mtu, | |
| 2704 | − bool confirm_neigh) | |
| 2705 | −{ | |
| 2706 | −} | |
| 2707 | − | |
| 2708 | −static void ipv4_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk, | |
| 2709 | − struct sk_buff *skb) | |
| 2710 | −{ | |
| 2711 | −} | |
| 2712 | − | |
| 2713 | −static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst, | |
| 2714 | − unsigned long old) | |
| 2715 | −{ | |
| 2716 | − return NULL; | |
| 2717 | −} | |
| 2718 | − | |
| 2719 | 2690 | static struct dst_ops ipv4_dst_blackhole_ops = { |
| 2720 | − .family = AF_INET, | |
| 2721 | − .check = ipv4_blackhole_dst_check, | |
| 2722 | − .mtu = ipv4_blackhole_mtu, | |
| 2723 | − .default_advmss = ipv4_default_advmss, | |
| 2724 | − .update_pmtu = ipv4_rt_blackhole_update_pmtu, | |
| 2725 | − .redirect = ipv4_rt_blackhole_redirect, | |
| 2726 | − .cow_metrics = ipv4_rt_blackhole_cow_metrics, | |
| 2727 | − .neigh_lookup = ipv4_neigh_lookup, | |
| 2691 | + .family = AF_INET, | |
| 2692 | + .default_advmss = ipv4_default_advmss, | |
| 2693 | + .neigh_lookup = ipv4_neigh_lookup, | |
| 2694 | + .check = dst_blackhole_check, | |
| 2695 | + .cow_metrics = dst_blackhole_cow_metrics, | |
| 2696 | + .update_pmtu = dst_blackhole_update_pmtu, | |
| 2697 | + .redirect = dst_blackhole_redirect, | |
| 2698 | + .mtu = dst_blackhole_mtu, | |
| 2728 | 2699 | }; |
| 2729 | 2700 | |
| 2730 | 2701 | struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) |
| @@ -804,8 +804,11 @@ embryonic_reset: · 803 unmodified lines | ||
| 804 | 804 | tcp_reset(sk, skb); |
| 805 | 805 | } |
| 806 | 806 | if (!fastopen) { |
| 807 | − inet_csk_reqsk_queue_drop(sk, req); | |
| 808 | − __NET_INC_STATS(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); | |
| 807 | + bool unlinked = inet_csk_reqsk_queue_drop(sk, req); | |
| 808 | + | |
| 809 | + if (unlinked) | |
| 810 | + __NET_INC_STATS(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); | |
| 811 | + *req_stolen = !unlinked; | |
| 809 | 812 | } |
| 810 | 813 | return NULL; |
| 811 | 814 | } |
| @@ -2486,7 +2486,7 @@ static int ipv6_route_native_seq_show(struct seq_file *seq, void *v) · 2485 unmodified lines | ||
| 2486 | 2486 | const struct net_device *dev; |
| 2487 | 2487 | |
| 2488 | 2488 | if (rt->nh) |
| 2489 | − fib6_nh = nexthop_fib6_nh(rt->nh); | |
| 2489 | + fib6_nh = nexthop_fib6_nh_bh(rt->nh); | |
| 2490 | 2490 | |
| 2491 | 2491 | seq_printf(seq, "%pi6 %02x ", &rt->fib6_dst.addr, rt->fib6_dst.plen); |
| 2492 | 2492 | |
| @@ -245,16 +245,6 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev, · 244 unmodified lines | ||
| 245 | 245 | if (ipv6_addr_is_multicast(&hdr->saddr)) |
| 246 | 246 | goto err; |
| 247 | 247 | |
| 248 | − /* While RFC4291 is not explicit about v4mapped addresses | |
| 249 | − * in IPv6 headers, it seems clear linux dual-stack | |
| 250 | − * model can not deal properly with these. | |
| 251 | − * Security models could be fooled by ::ffff:127.0.0.1 for example. | |
| 252 | − * | |
| 253 | − * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02 | |
| 254 | − */ | |
| 255 | − if (ipv6_addr_v4mapped(&hdr->saddr)) | |
| 256 | − goto err; | |
| 257 | − | |
| 258 | 248 | skb->transport_header = skb->network_header + sizeof(*hdr); |
| 259 | 249 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); |
| 260 | 250 | |
| @@ -280,7 +280,7 @@ ip6t_do_table(struct sk_buff *skb, · 279 unmodified lines | ||
| 280 | 280 | |
| 281 | 281 | local_bh_disable(); |
| 282 | 282 | addend = xt_write_recseq_begin(); |
| 283 | − private = rcu_access_pointer(table->private); | |
| 283 | + private = READ_ONCE(table->private); /* Address dependency. */ | |
| 284 | 284 | cpu = smp_processor_id(); |
| 285 | 285 | table_base = private->entries; |
| 286 | 286 | jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; |
| @@ -807,7 +807,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) · 520 unmodified lines | ||
| 807 | 807 | { |
| 808 | 808 | unsigned int countersize; |
| 809 | 809 | struct xt_counters *counters; |
| 810 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 810 | + const struct xt_table_info *private = table->private; | |
| 811 | 811 | |
| 812 | 812 | /* We need atomic snapshot of counters: rest doesn't change |
| 813 | 813 | (other than comefrom, which userspace doesn't care |
| @@ -831,7 +831,7 @@ copy_entries_to_user(unsigned int total_size, · 17 unmodified lines | ||
| 831 | 831 | unsigned int off, num; |
| 832 | 832 | const struct ip6t_entry *e; |
| 833 | 833 | struct xt_counters *counters; |
| 834 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 834 | + const struct xt_table_info *private = table->private; | |
| 835 | 835 | int ret = 0; |
| 836 | 836 | const void *loc_cpu_entry; |
| 837 | 837 | |
| @@ -980,7 +980,7 @@ static int get_info(struct net *net, void __user *user, const int *len) · 142 unmodified lines | ||
| 980 | 980 | t = xt_request_find_table_lock(net, AF_INET6, name); |
| 981 | 981 | if (!IS_ERR(t)) { |
| 982 | 982 | struct ip6t_getinfo info; |
| 983 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 983 | + const struct xt_table_info *private = t->private; | |
| 984 | 984 | #ifdef CONFIG_COMPAT |
| 985 | 985 | struct xt_table_info tmp; |
| 986 | 986 | |
| @@ -1035,7 +1035,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, · 48 unmodified lines | ||
| 1035 | 1035 | |
| 1036 | 1036 | t = xt_find_table_lock(net, AF_INET6, get.name); |
| 1037 | 1037 | if (!IS_ERR(t)) { |
| 1038 | − struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 1038 | + struct xt_table_info *private = t->private; | |
| 1039 | 1039 | if (get.size == private->size) |
| 1040 | 1040 | ret = copy_entries_to_user(private->size, |
| 1041 | 1041 | t, uptr->entrytable); |
| @@ -1189,7 +1189,7 @@ do_add_counters(struct net *net, sockptr_t arg, unsigned int len) · 147 unmodified lines | ||
| 1189 | 1189 | } |
| 1190 | 1190 | |
| 1191 | 1191 | local_bh_disable(); |
| 1192 | − private = xt_table_get_private_protected(t); | |
| 1192 | + private = t->private; | |
| 1193 | 1193 | if (private->number != tmp.num_counters) { |
| 1194 | 1194 | ret = -EINVAL; |
| 1195 | 1195 | goto unlock_up_free; |
| @@ -1552,7 +1552,7 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, · 356 unmodified lines | ||
| 1552 | 1552 | void __user *userptr) |
| 1553 | 1553 | { |
| 1554 | 1554 | struct xt_counters *counters; |
| 1555 | − const struct xt_table_info *private = xt_table_get_private_protected(table); | |
| 1555 | + const struct xt_table_info *private = table->private; | |
| 1556 | 1556 | void __user *pos; |
| 1557 | 1557 | unsigned int size; |
| 1558 | 1558 | int ret = 0; |
| @@ -1598,7 +1598,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, · 39 unmodified lines | ||
| 1598 | 1598 | xt_compat_lock(AF_INET6); |
| 1599 | 1599 | t = xt_find_table_lock(net, AF_INET6, get.name); |
| 1600 | 1600 | if (!IS_ERR(t)) { |
| 1601 | − const struct xt_table_info *private = xt_table_get_private_protected(t); | |
| 1601 | + const struct xt_table_info *private = t->private; | |
| 1602 | 1602 | struct xt_table_info info; |
| 1603 | 1603 | ret = compat_table_info(private, &info); |
| 1604 | 1604 | if (!ret && get.size == info.size) |
| @@ -260,34 +260,16 @@ static struct dst_ops ip6_dst_ops_template = { · 259 unmodified lines | ||
| 260 | 260 | .confirm_neigh = ip6_confirm_neigh, |
| 261 | 261 | }; |
| 262 | 262 | |
| 263 | −static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst) | |
| 264 | −{ | |
| 265 | − unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); | |
| 266 | − | |
| 267 | − return mtu ? : dst->dev->mtu; | |
| 268 | −} | |
| 269 | − | |
| 270 | −static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, | |
| 271 | − struct sk_buff *skb, u32 mtu, | |
| 272 | − bool confirm_neigh) | |
| 273 | −{ | |
| 274 | −} | |
| 275 | − | |
| 276 | −static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk, | |
| 277 | − struct sk_buff *skb) | |
| 278 | −{ | |
| 279 | −} | |
| 280 | − | |
| 281 | 263 | static struct dst_ops ip6_dst_blackhole_ops = { |
| 282 | − .family = AF_INET6, | |
| 283 | − .destroy = ip6_dst_destroy, | |
| 284 | − .check = ip6_dst_check, | |
| 285 | − .mtu = ip6_blackhole_mtu, | |
| 286 | − .default_advmss = ip6_default_advmss, | |
| 287 | − .update_pmtu = ip6_rt_blackhole_update_pmtu, | |
| 288 | − .redirect = ip6_rt_blackhole_redirect, | |
| 289 | − .cow_metrics = dst_cow_metrics_generic, | |
| 290 | − .neigh_lookup = ip6_dst_neigh_lookup, | |
| 264 | + .family = AF_INET6, | |
| 265 | + .default_advmss = ip6_default_advmss, | |
| 266 | + .neigh_lookup = ip6_dst_neigh_lookup, | |
| 267 | + .check = ip6_dst_check, | |
| 268 | + .destroy = ip6_dst_destroy, | |
| 269 | + .cow_metrics = dst_cow_metrics_generic, | |
| 270 | + .update_pmtu = dst_blackhole_update_pmtu, | |
| 271 | + .redirect = dst_blackhole_redirect, | |
| 272 | + .mtu = dst_blackhole_mtu, | |
| 291 | 273 | }; |
| 292 | 274 | |
| 293 | 275 | static const u32 ip6_template_metrics[RTAX_MAX] = { |
| @@ -1175,6 +1175,11 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) · 1174 unmodified lines | ||
| 1175 | 1175 | if (!ipv6_unicast_destination(skb)) |
| 1176 | 1176 | goto drop; |
| 1177 | 1177 | |
| 1178 | + if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { | |
| 1179 | + __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); | |
| 1180 | + return 0; | |
| 1181 | + } | |
| 1182 | + | |
| 1178 | 1183 | return tcp_conn_request(&tcp6_request_sock_ops, |
| 1179 | 1184 | &tcp_request_sock_ipv6_ops, sk, skb); |
| 1180 | 1185 | |
| @@ -23,6 +23,7 @@ int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, · 22 unmodified lines | ||
| 23 | 23 | struct aead_request *aead_req; |
| 24 | 24 | int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); |
| 25 | 25 | u8 *__aad; |
| 26 | + int ret; | |
| 26 | 27 | |
| 27 | 28 | aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); |
| 28 | 29 | if (!aead_req) |
| @@ -40,10 +41,10 @@ int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, · 11 unmodified lines | ||
| 40 | 41 | aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); |
| 41 | 42 | aead_request_set_ad(aead_req, sg[0].length); |
| 42 | 43 | |
| 43 | − crypto_aead_encrypt(aead_req); | |
| 44 | + ret = crypto_aead_encrypt(aead_req); | |
| 44 | 45 | kfree_sensitive(aead_req); |
| 45 | 46 | |
| 46 | − return 0; | |
| 47 | + return ret; | |
| 47 | 48 | } |
| 48 | 49 | |
| 49 | 50 | int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, |
| @@ -22,6 +22,7 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, · 21 unmodified lines | ||
| 22 | 22 | struct aead_request *aead_req; |
| 23 | 23 | int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); |
| 24 | 24 | const __le16 *fc; |
| 25 | + int ret; | |
| 25 | 26 | |
| 26 | 27 | if (data_len < GMAC_MIC_LEN) |
| 27 | 28 | return -EINVAL; |
| @@ -59,10 +60,10 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, · 31 unmodified lines | ||
| 59 | 60 | aead_request_set_crypt(aead_req, sg, sg, 0, iv); |
| 60 | 61 | aead_request_set_ad(aead_req, GMAC_AAD_LEN + data_len); |
| 61 | 62 | |
| 62 | − crypto_aead_encrypt(aead_req); | |
| 63 | + ret = crypto_aead_encrypt(aead_req); | |
| 63 | 64 | kfree_sensitive(aead_req); |
| 64 | 65 | |
| 65 | − return 0; | |
| 66 | + return ret; | |
| 66 | 67 | } |
| 67 | 68 | |
| 68 | 69 | struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], |
| @@ -2950,14 +2950,14 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, · 2949 unmodified lines | ||
| 2950 | 2950 | continue; |
| 2951 | 2951 | |
| 2952 | 2952 | for (j = 0; j < IEEE80211_HT_MCS_MASK_LEN; j++) { |
| 2953 | − if (~sdata->rc_rateidx_mcs_mask[i][j]) { | |
| 2953 | + if (sdata->rc_rateidx_mcs_mask[i][j] != 0xff) { | |
| 2954 | 2954 | sdata->rc_has_mcs_mask[i] = true; |
| 2955 | 2955 | break; |
| 2956 | 2956 | } |
| 2957 | 2957 | } |
| 2958 | 2958 | |
| 2959 | 2959 | for (j = 0; j < NL80211_VHT_NSS_MAX; j++) { |
| 2960 | − if (~sdata->rc_rateidx_vht_mcs_mask[i][j]) { | |
| 2960 | + if (sdata->rc_rateidx_vht_mcs_mask[i][j] != 0xffff) { | |
| 2961 | 2961 | sdata->rc_has_vht_mcs_mask[i] = true; |
| 2962 | 2962 | break; |
| 2963 | 2963 | } |
| @@ -1874,6 +1874,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) · 1873 unmodified lines | ||
| 1874 | 1874 | |
| 1875 | 1875 | /* remove beacon */ |
| 1876 | 1876 | kfree(sdata->u.ibss.ie); |
| 1877 | + sdata->u.ibss.ie = NULL; | |
| 1878 | + sdata->u.ibss.ie_len = 0; | |
| 1877 | 1879 | |
| 1878 | 1880 | /* on the next join, re-program HT parameters */ |
| 1879 | 1881 | memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa)); |
| @@ -973,8 +973,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) · 972 unmodified lines | ||
| 973 | 973 | continue; |
| 974 | 974 | |
| 975 | 975 | if (!dflt_chandef.chan) { |
| 976 | + /* | |
| 977 | + * Assign the first enabled channel to dflt_chandef | |
| 978 | + * from the list of channels | |
| 979 | + */ | |
| 980 | + for (i = 0; i < sband->n_channels; i++) | |
| 981 | + if (!(sband->channels[i].flags & | |
| 982 | + IEEE80211_CHAN_DISABLED)) | |
| 983 | + break; | |
| 984 | + /* if none found then use the first anyway */ | |
| 985 | + if (i == sband->n_channels) | |
| 986 | + i = 0; | |
| 976 | 987 | cfg80211_chandef_create(&dflt_chandef, |
| 977 | − &sband->channels[0], | |
| 988 | + &sband->channels[i], | |
| 978 | 989 | NL80211_CHAN_NO_HT); |
| 979 | 990 | /* init channel we're on */ |
| 980 | 991 | if (!local->use_chanctx && !local->_oper_chandef.chan) { |
| @@ -5071,7 +5071,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, · 5070 unmodified lines | ||
| 5071 | 5071 | he_oper_ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, |
| 5072 | 5072 | ies->data, ies->len); |
| 5073 | 5073 | if (he_oper_ie && |
| 5074 | − he_oper_ie[1] == ieee80211_he_oper_size(&he_oper_ie[3])) | |
| 5074 | + he_oper_ie[1] >= ieee80211_he_oper_size(&he_oper_ie[3])) | |
| 5075 | 5075 | he_oper = (void *)(he_oper_ie + 3); |
| 5076 | 5076 | else |
| 5077 | 5077 | he_oper = NULL; |
| @@ -805,7 +805,6 @@ minstrel_ht_group_min_rate_offset(struct minstrel_ht_sta *mi, int group, · 804 unmodified lines | ||
| 805 | 805 | static u16 |
| 806 | 806 | minstrel_ht_next_inc_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur) |
| 807 | 807 | { |
| 808 | − struct minstrel_mcs_group_data *mg; | |
| 809 | 808 | u8 type = MINSTREL_SAMPLE_TYPE_INC; |
| 810 | 809 | int i, index = 0; |
| 811 | 810 | u8 group; |
| @@ -813,7 +812,6 @@ minstrel_ht_next_inc_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur) · 1 unmodified line | ||
| 813 | 812 | group = mi->sample[type].sample_group; |
| 814 | 813 | for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) { |
| 815 | 814 | group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups); |
| 816 | − mg = &mi->groups[group]; | |
| 817 | 815 | |
| 818 | 816 | index = minstrel_ht_group_min_rate_offset(mi, group, |
| 819 | 817 | fast_rate_dur); |
| @@ -968,7 +968,7 @@ static void ieee80211_parse_extension_element(u32 *crc, · 967 unmodified lines | ||
| 968 | 968 | break; |
| 969 | 969 | case WLAN_EID_EXT_HE_OPERATION: |
| 970 | 970 | if (len >= sizeof(*elems->he_operation) && |
| 971 | − len == ieee80211_he_oper_size(data) - 1) { | |
| 971 | + len >= ieee80211_he_oper_size(data) - 1) { | |
| 972 | 972 | if (crc) |
| 973 | 973 | *crc = crc32_be(*crc, (void *)elem, |
| 974 | 974 | elem->datalen + 2); |
| @@ -567,15 +567,15 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, · 566 unmodified lines | ||
| 567 | 567 | } |
| 568 | 568 | |
| 569 | 569 | static u64 add_addr_generate_hmac(u64 key1, u64 key2, u8 addr_id, |
| 570 | − struct in_addr *addr) | |
| 570 | + struct in_addr *addr, u16 port) | |
| 571 | 571 | { |
| 572 | 572 | u8 hmac[SHA256_DIGEST_SIZE]; |
| 573 | 573 | u8 msg[7]; |
| 574 | 574 | |
| 575 | 575 | msg[0] = addr_id; |
| 576 | 576 | memcpy(&msg[1], &addr->s_addr, 4); |
| 577 | − msg[5] = 0; | |
| 578 | − msg[6] = 0; | |
| 577 | + msg[5] = port >> 8; | |
| 578 | + msg[6] = port & 0xFF; | |
| 579 | 579 | |
| 580 | 580 | mptcp_crypto_hmac_sha(key1, key2, msg, 7, hmac); |
| 581 | 581 | |
| @@ -584,15 +584,15 @@ static u64 add_addr_generate_hmac(u64 key1, u64 key2, u8 addr_id, · 2 unmodified lines | ||
| 584 | 584 | |
| 585 | 585 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
| 586 | 586 | static u64 add_addr6_generate_hmac(u64 key1, u64 key2, u8 addr_id, |
| 587 | − struct in6_addr *addr) | |
| 587 | + struct in6_addr *addr, u16 port) | |
| 588 | 588 | { |
| 589 | 589 | u8 hmac[SHA256_DIGEST_SIZE]; |
| 590 | 590 | u8 msg[19]; |
| 591 | 591 | |
| 592 | 592 | msg[0] = addr_id; |
| 593 | 593 | memcpy(&msg[1], &addr->s6_addr, 16); |
| 594 | − msg[17] = 0; | |
| 595 | − msg[18] = 0; | |
| 594 | + msg[17] = port >> 8; | |
| 595 | + msg[18] = port & 0xFF; | |
| 596 | 596 | |
| 597 | 597 | mptcp_crypto_hmac_sha(key1, key2, msg, 19, hmac); |
| 598 | 598 | |
| @@ -646,7 +646,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * · 47 unmodified lines | ||
| 646 | 646 | opts->ahmac = add_addr_generate_hmac(msk->local_key, |
| 647 | 647 | msk->remote_key, |
| 648 | 648 | opts->addr_id, |
| 649 | − &opts->addr); | |
| 649 | + &opts->addr, | |
| 650 | + opts->port); | |
| 650 | 651 | } |
| 651 | 652 | } |
| 652 | 653 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
| @@ -657,7 +658,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * · 4 unmodified lines | ||
| 657 | 658 | opts->ahmac = add_addr6_generate_hmac(msk->local_key, |
| 658 | 659 | msk->remote_key, |
| 659 | 660 | opts->addr_id, |
| 660 | − &opts->addr6); | |
| 661 | + &opts->addr6, | |
| 662 | + opts->port); | |
| 661 | 663 | } |
| 662 | 664 | } |
| 663 | 665 | #endif |
| @@ -962,12 +964,14 @@ static bool add_addr_hmac_valid(struct mptcp_sock *msk, · 298 unmodified lines | ||
| 962 | 964 | if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) |
| 963 | 965 | hmac = add_addr_generate_hmac(msk->remote_key, |
| 964 | 966 | msk->local_key, |
| 965 | − mp_opt->addr_id, &mp_opt->addr); | |
| 967 | + mp_opt->addr_id, &mp_opt->addr, | |
| 968 | + mp_opt->port); | |
| 966 | 969 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
| 967 | 970 | else |
| 968 | 971 | hmac = add_addr6_generate_hmac(msk->remote_key, |
| 969 | 972 | msk->local_key, |
| 970 | − mp_opt->addr_id, &mp_opt->addr6); | |
| 973 | + mp_opt->addr_id, &mp_opt->addr6, | |
| 974 | + mp_opt->port); | |
| 971 | 975 | #endif |
| 972 | 976 | |
| 973 | 977 | pr_debug("msk=%p, ahmac=%llu, mp_opt->ahmac=%llu\n", |
| @@ -2968,7 +2968,7 @@ static void mptcp_release_cb(struct sock *sk) · 2967 unmodified lines | ||
| 2968 | 2968 | for (;;) { |
| 2969 | 2969 | flags = 0; |
| 2970 | 2970 | if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags)) |
| 2971 | − flags |= MPTCP_PUSH_PENDING; | |
| 2971 | + flags |= BIT(MPTCP_PUSH_PENDING); | |
| 2972 | 2972 | if (!flags) |
| 2973 | 2973 | break; |
| 2974 | 2974 | |
| @@ -2981,7 +2981,7 @@ static void mptcp_release_cb(struct sock *sk) · 6 unmodified lines | ||
| 2981 | 2981 | */ |
| 2982 | 2982 | |
| 2983 | 2983 | spin_unlock_bh(&sk->sk_lock.slock); |
| 2984 | − if (flags & MPTCP_PUSH_PENDING) | |
| 2984 | + if (flags & BIT(MPTCP_PUSH_PENDING)) | |
| 2985 | 2985 | __mptcp_push_pending(sk, 0); |
| 2986 | 2986 | |
| 2987 | 2987 | cond_resched(); |
| @@ -477,6 +477,11 @@ static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb) · 476 unmodified lines | ||
| 477 | 477 | if (!ipv6_unicast_destination(skb)) |
| 478 | 478 | goto drop; |
| 479 | 479 | |
| 480 | + if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { | |
| 481 | + __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); | |
| 482 | + return 0; | |
| 483 | + } | |
| 484 | + | |
| 480 | 485 | return tcp_conn_request(&mptcp_subflow_request_sock_ops, |
| 481 | 486 | &subflow_request_sock_ipv6_ops, sk, skb); |
| 482 | 487 | |
| @@ -2962,6 +2962,7 @@ static int ctnetlink_exp_dump_mask(struct sk_buff *skb, · 2961 unmodified lines | ||
| 2962 | 2962 | memset(&m, 0xFF, sizeof(m)); |
| 2963 | 2963 | memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3)); |
| 2964 | 2964 | m.src.u.all = mask->src.u.all; |
| 2965 | + m.src.l3num = tuple->src.l3num; | |
| 2965 | 2966 | m.dst.protonum = tuple->dst.protonum; |
| 2966 | 2967 | |
| 2967 | 2968 | nest_parms = nla_nest_start(skb, CTA_EXPECT_MASK); |
| @@ -218,9 +218,6 @@ int nf_conntrack_gre_packet(struct nf_conn *ct, · 217 unmodified lines | ||
| 218 | 218 | enum ip_conntrack_info ctinfo, |
| 219 | 219 | const struct nf_hook_state *state) |
| 220 | 220 | { |
| 221 | − if (state->pf != NFPROTO_IPV4) | |
| 222 | − return -NF_ACCEPT; | |
| 223 | − | |
| 224 | 221 | if (!nf_ct_is_confirmed(ct)) { |
| 225 | 222 | unsigned int *timeouts = nf_ct_timeout_lookup(ct); |
| 226 | 223 | |
| @@ -506,7 +506,7 @@ int nf_flow_table_init(struct nf_flowtable *flowtable) · 505 unmodified lines | ||
| 506 | 506 | { |
| 507 | 507 | int err; |
| 508 | 508 | |
| 509 | − INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); | |
| 509 | + INIT_DELAYED_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); | |
| 510 | 510 | flow_block_init(&flowtable->flow_block); |
| 511 | 511 | init_rwsem(&flowtable->flow_block_lock); |
| 512 | 512 | |
| @@ -6783,6 +6783,9 @@ static int nft_register_flowtable_net_hooks(struct net *net, · 6782 unmodified lines | ||
| 6783 | 6783 | |
| 6784 | 6784 | list_for_each_entry(hook, hook_list, list) { |
| 6785 | 6785 | list_for_each_entry(ft, &table->flowtables, list) { |
| 6786 | + if (!nft_is_active_next(net, ft)) | |
| 6787 | + continue; | |
| 6788 | + | |
| 6786 | 6789 | list_for_each_entry(hook2, &ft->hook_list, list) { |
| 6787 | 6790 | if (hook->ops.dev == hook2->ops.dev && |
| 6788 | 6791 | hook->ops.pf == hook2->ops.pf) { |
| @@ -6842,6 +6845,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, · 53 unmodified lines | ||
| 6842 | 6845 | struct nft_hook *hook, *next; |
| 6843 | 6846 | struct nft_trans *trans; |
| 6844 | 6847 | bool unregister = false; |
| 6848 | + u32 flags; | |
| 6845 | 6849 | int err; |
| 6846 | 6850 | |
| 6847 | 6851 | err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK], |
| @@ -6856,6 +6860,17 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, · 8 unmodified lines | ||
| 6856 | 6860 | } |
| 6857 | 6861 | } |
| 6858 | 6862 | |
| 6863 | + if (nla[NFTA_FLOWTABLE_FLAGS]) { | |
| 6864 | + flags = ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS])); | |
| 6865 | + if (flags & ~NFT_FLOWTABLE_MASK) | |
| 6866 | + return -EOPNOTSUPP; | |
| 6867 | + if ((flowtable->data.flags & NFT_FLOWTABLE_HW_OFFLOAD) ^ | |
| 6868 | + (flags & NFT_FLOWTABLE_HW_OFFLOAD)) | |
| 6869 | + return -EOPNOTSUPP; | |
| 6870 | + } else { | |
| 6871 | + flags = flowtable->data.flags; | |
| 6872 | + } | |
| 6873 | + | |
| 6859 | 6874 | err = nft_register_flowtable_net_hooks(ctx->net, ctx->table, |
| 6860 | 6875 | &flowtable_hook.list, flowtable); |
| 6861 | 6876 | if (err < 0) |
| @@ -6869,6 +6884,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, · 7 unmodified lines | ||
| 6869 | 6884 | goto err_flowtable_update_hook; |
| 6870 | 6885 | } |
| 6871 | 6886 | |
| 6887 | + nft_trans_flowtable_flags(trans) = flags; | |
| 6872 | 6888 | nft_trans_flowtable(trans) = flowtable; |
| 6873 | 6889 | nft_trans_flowtable_update(trans) = true; |
| 6874 | 6890 | INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans)); |
| @@ -6963,8 +6979,10 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, · 88 unmodified lines | ||
| 6963 | 6979 | if (nla[NFTA_FLOWTABLE_FLAGS]) { |
| 6964 | 6980 | flowtable->data.flags = |
| 6965 | 6981 | ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS])); |
| 6966 | − if (flowtable->data.flags & ~NFT_FLOWTABLE_MASK) | |
| 6982 | + if (flowtable->data.flags & ~NFT_FLOWTABLE_MASK) { | |
| 6983 | + err = -EOPNOTSUPP; | |
| 6967 | 6984 | goto err3; |
| 6985 | + } | |
| 6968 | 6986 | } |
| 6969 | 6987 | |
| 6970 | 6988 | write_pnet(&flowtable->data.net, net); |
| @@ -8176,6 +8194,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 1205 unmodified lines | ||
| 8176 | 8194 | break; |
| 8177 | 8195 | case NFT_MSG_NEWFLOWTABLE: |
| 8178 | 8196 | if (nft_trans_flowtable_update(trans)) { |
| 8197 | + nft_trans_flowtable(trans)->data.flags = | |
| 8198 | + nft_trans_flowtable_flags(trans); | |
| 8179 | 8199 | nf_tables_flowtable_notify(&trans->ctx, |
| 8180 | 8200 | nft_trans_flowtable(trans), |
| 8181 | 8201 | &nft_trans_flowtable_hooks(trans), |
| @@ -1351,14 +1351,6 @@ struct xt_counters *xt_counters_alloc(unsigned int counters) · 1350 unmodified lines | ||
| 1351 | 1351 | } |
| 1352 | 1352 | EXPORT_SYMBOL(xt_counters_alloc); |
| 1353 | 1353 | |
| 1354 | −struct xt_table_info | |
| 1355 | −*xt_table_get_private_protected(const struct xt_table *table) | |
| 1356 | −{ | |
| 1357 | − return rcu_dereference_protected(table->private, | |
| 1358 | − mutex_is_locked(&xt[table->af].mutex)); | |
| 1359 | −} | |
| 1360 | −EXPORT_SYMBOL(xt_table_get_private_protected); | |
| 1361 | − | |
| 1362 | 1354 | struct xt_table_info * |
| 1363 | 1355 | xt_replace_table(struct xt_table *table, |
| 1364 | 1356 | unsigned int num_counters, |
| @@ -1366,6 +1358,7 @@ xt_replace_table(struct xt_table *table, · 1 unmodified line | ||
| 1366 | 1358 | int *error) |
| 1367 | 1359 | { |
| 1368 | 1360 | struct xt_table_info *private; |
| 1361 | + unsigned int cpu; | |
| 1369 | 1362 | int ret; |
| 1370 | 1363 | |
| 1371 | 1364 | ret = xt_jumpstack_alloc(newinfo); |
| @@ -1375,20 +1368,47 @@ xt_replace_table(struct xt_table *table, · 3 unmodified lines | ||
| 1375 | 1368 | } |
| 1376 | 1369 | |
| 1377 | 1370 | /* Do the substitution. */ |
| 1378 | − private = xt_table_get_private_protected(table); | |
| 1371 | + local_bh_disable(); | |
| 1372 | + private = table->private; | |
| 1379 | 1373 | |
| 1380 | 1374 | /* Check inside lock: is the old number correct? */ |
| 1381 | 1375 | if (num_counters != private->number) { |
| 1382 | 1376 | pr_debug("num_counters != table->private->number (%u/%u)\n", |
| 1383 | 1377 | num_counters, private->number); |
| 1378 | + local_bh_enable(); | |
| 1384 | 1379 | *error = -EAGAIN; |
| 1385 | 1380 | return NULL; |
| 1386 | 1381 | } |
| 1387 | 1382 | |
| 1388 | 1383 | newinfo->initial_entries = private->initial_entries; |
| 1384 | + /* | |
| 1385 | + * Ensure contents of newinfo are visible before assigning to | |
| 1386 | + * private. | |
| 1387 | + */ | |
| 1388 | + smp_wmb(); | |
| 1389 | + table->private = newinfo; | |
| 1390 | + | |
| 1391 | + /* make sure all cpus see new ->private value */ | |
| 1392 | + smp_mb(); | |
| 1389 | 1393 | |
| 1390 | − rcu_assign_pointer(table->private, newinfo); | |
| 1391 | − synchronize_rcu(); | |
| 1394 | + /* | |
| 1395 | + * Even though table entries have now been swapped, other CPU's | |
| 1396 | + * may still be using the old entries... | |
| 1397 | + */ | |
| 1398 | + local_bh_enable(); | |
| 1399 | + | |
| 1400 | + /* ... so wait for even xt_recseq on all cpus */ | |
| 1401 | + for_each_possible_cpu(cpu) { | |
| 1402 | + seqcount_t *s = &per_cpu(xt_recseq, cpu); | |
| 1403 | + u32 seq = raw_read_seqcount(s); | |
| 1404 | + | |
| 1405 | + if (seq & 1) { | |
| 1406 | + do { | |
| 1407 | + cond_resched(); | |
| 1408 | + cpu_relax(); | |
| 1409 | + } while (seq == raw_read_seqcount(s)); | |
| 1410 | + } | |
| 1411 | + } | |
| 1392 | 1412 | |
| 1393 | 1413 | audit_log_nfcfg(table->name, table->af, private->number, |
| 1394 | 1414 | !private->number ? AUDIT_XT_OP_REGISTER : |
| @@ -1424,12 +1444,12 @@ struct xt_table *xt_register_table(struct net *net, · 29 unmodified lines | ||
| 1424 | 1444 | } |
| 1425 | 1445 | |
| 1426 | 1446 | /* Simplifies replace_table code. */ |
| 1427 | − rcu_assign_pointer(table->private, bootstrap); | |
| 1447 | + table->private = bootstrap; | |
| 1428 | 1448 | |
| 1429 | 1449 | if (!xt_replace_table(table, 0, newinfo, &ret)) |
| 1430 | 1450 | goto unlock; |
| 1431 | 1451 | |
| 1432 | − private = xt_table_get_private_protected(table); | |
| 1452 | + private = table->private; | |
| 1433 | 1453 | pr_debug("table->private->number = %u\n", private->number); |
| 1434 | 1454 | |
| 1435 | 1455 | /* save number of initial entries */ |
| @@ -1452,8 +1472,7 @@ void *xt_unregister_table(struct xt_table *table) · 16 unmodified lines | ||
| 1452 | 1472 | struct xt_table_info *private; |
| 1453 | 1473 | |
| 1454 | 1474 | mutex_lock(&xt[table->af].mutex); |
| 1455 | − private = xt_table_get_private_protected(table); | |
| 1456 | − RCU_INIT_POINTER(table->private, NULL); | |
| 1475 | + private = table->private; | |
| 1457 | 1476 | list_del(&table->list); |
| 1458 | 1477 | mutex_unlock(&xt[table->af].mutex); |
| 1459 | 1478 | audit_log_nfcfg(table->name, table->af, private->number, |
| @@ -271,9 +271,11 @@ static void ovs_ct_update_key(const struct sk_buff *skb, · 270 unmodified lines | ||
| 271 | 271 | /* This is called to initialize CT key fields possibly coming in from the local |
| 272 | 272 | * stack. |
| 273 | 273 | */ |
| 274 | −void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key) | |
| 274 | +void ovs_ct_fill_key(const struct sk_buff *skb, | |
| 275 | + struct sw_flow_key *key, | |
| 276 | + bool post_ct) | |
| 275 | 277 | { |
| 276 | − ovs_ct_update_key(skb, NULL, key, false, false); | |
| 278 | + ovs_ct_update_key(skb, NULL, key, post_ct, false); | |
| 277 | 279 | } |
| 278 | 280 | |
| 279 | 281 | int ovs_ct_put_key(const struct sw_flow_key *swkey, |
| @@ -1332,7 +1334,7 @@ int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key) · 1052 unmodified lines | ||
| 1332 | 1334 | if (skb_nfct(skb)) { |
| 1333 | 1335 | nf_conntrack_put(skb_nfct(skb)); |
| 1334 | 1336 | nf_ct_set(skb, NULL, IP_CT_UNTRACKED); |
| 1335 | − ovs_ct_fill_key(skb, key); | |
| 1337 | + ovs_ct_fill_key(skb, key, false); | |
| 1336 | 1338 | } |
| 1337 | 1339 | |
| 1338 | 1340 | return 0; |
| @@ -25,7 +25,8 @@ int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *, · 24 unmodified lines | ||
| 25 | 25 | const struct ovs_conntrack_info *); |
| 26 | 26 | int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key); |
| 27 | 27 | |
| 28 | −void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key); | |
| 28 | +void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key, | |
| 29 | + bool post_ct); | |
| 29 | 30 | int ovs_ct_put_key(const struct sw_flow_key *swkey, |
| 30 | 31 | const struct sw_flow_key *output, struct sk_buff *skb); |
| 31 | 32 | void ovs_ct_free_action(const struct nlattr *a); |
| @@ -74,7 +75,8 @@ static inline int ovs_ct_clear(struct sk_buff *skb, · 42 unmodified lines | ||
| 74 | 75 | } |
| 75 | 76 | |
| 76 | 77 | static inline void ovs_ct_fill_key(const struct sk_buff *skb, |
| 77 | − struct sw_flow_key *key) | |
| 78 | + struct sw_flow_key *key, | |
| 79 | + bool post_ct) | |
| 78 | 80 | { |
| 79 | 81 | key->ct_state = 0; |
| 80 | 82 | key->ct_zone = 0; |
| @@ -857,6 +857,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, · 856 unmodified lines | ||
| 857 | 857 | #if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) |
| 858 | 858 | struct tc_skb_ext *tc_ext; |
| 859 | 859 | #endif |
| 860 | + bool post_ct = false; | |
| 860 | 861 | int res, err; |
| 861 | 862 | |
| 862 | 863 | /* Extract metadata from packet. */ |
| @@ -895,6 +896,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, · 32 unmodified lines | ||
| 895 | 896 | tc_ext = skb_ext_find(skb, TC_SKB_EXT); |
| 896 | 897 | key->recirc_id = tc_ext ? tc_ext->chain : 0; |
| 897 | 898 | OVS_CB(skb)->mru = tc_ext ? tc_ext->mru : 0; |
| 899 | + post_ct = tc_ext ? tc_ext->post_ct : false; | |
| 898 | 900 | } else { |
| 899 | 901 | key->recirc_id = 0; |
| 900 | 902 | } |
| @@ -904,7 +906,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, · 3 unmodified lines | ||
| 904 | 906 | |
| 905 | 907 | err = key_extract(skb, key); |
| 906 | 908 | if (!err) |
| 907 | − ovs_ct_fill_key(skb, key); /* Must be after key_extract(). */ | |
| 909 | + ovs_ct_fill_key(skb, key, post_ct); /* Must be after key_extract(). */ | |
| 908 | 910 | return err; |
| 909 | 911 | } |
| 910 | 912 | |
| @@ -1058,6 +1058,11 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, · 1057 unmodified lines | ||
| 1058 | 1058 | rc = copied; |
| 1059 | 1059 | |
| 1060 | 1060 | if (addr) { |
| 1061 | + /* There is an anonymous 2-byte hole after sq_family, | |
| 1062 | + * make sure to clear it. | |
| 1063 | + */ | |
| 1064 | + memset(addr, 0, sizeof(*addr)); | |
| 1065 | + | |
| 1061 | 1066 | addr->sq_family = AF_QIPCRTR; |
| 1062 | 1067 | addr->sq_node = cb->src_node; |
| 1063 | 1068 | addr->sq_port = cb->src_port; |
| @@ -945,13 +945,14 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, · 944 unmodified lines | ||
| 945 | 945 | tcf_lastuse_update(&c->tcf_tm); |
| 946 | 946 | |
| 947 | 947 | if (clear) { |
| 948 | + qdisc_skb_cb(skb)->post_ct = false; | |
| 948 | 949 | ct = nf_ct_get(skb, &ctinfo); |
| 949 | 950 | if (ct) { |
| 950 | 951 | nf_conntrack_put(&ct->ct_general); |
| 951 | 952 | nf_ct_set(skb, NULL, IP_CT_UNTRACKED); |
| 952 | 953 | } |
| 953 | 954 | |
| 954 | − goto out; | |
| 955 | + goto out_clear; | |
| 955 | 956 | } |
| 956 | 957 | |
| 957 | 958 | family = tcf_ct_skb_nf_family(skb); |
| @@ -1030,8 +1031,9 @@ out_push: · 72 unmodified lines | ||
| 1030 | 1031 | skb_push_rcsum(skb, nh_ofs); |
| 1031 | 1032 | |
| 1032 | 1033 | out: |
| 1033 | − tcf_action_update_bstats(&c->common, skb); | |
| 1034 | 1034 | qdisc_skb_cb(skb)->post_ct = true; |
| 1035 | +out_clear: | |
| 1036 | + tcf_action_update_bstats(&c->common, skb); | |
| 1035 | 1037 | if (defrag) |
| 1036 | 1038 | qdisc_skb_cb(skb)->pkt_len = skb->len; |
| 1037 | 1039 | return retval; |
| @@ -1629,6 +1629,7 @@ int tcf_classify_ingress(struct sk_buff *skb, · 1628 unmodified lines | ||
| 1629 | 1629 | return TC_ACT_SHOT; |
| 1630 | 1630 | ext->chain = last_executed_chain; |
| 1631 | 1631 | ext->mru = qdisc_skb_cb(skb)->mru; |
| 1632 | + ext->post_ct = qdisc_skb_cb(skb)->post_ct; | |
| 1632 | 1633 | } |
| 1633 | 1634 | |
| 1634 | 1635 | return ret; |
| @@ -1451,7 +1451,7 @@ static int fl_set_key_ct(struct nlattr **tb, · 1450 unmodified lines | ||
| 1451 | 1451 | &mask->ct_state, TCA_FLOWER_KEY_CT_STATE_MASK, |
| 1452 | 1452 | sizeof(key->ct_state)); |
| 1453 | 1453 | |
| 1454 | − err = fl_validate_ct_state(mask->ct_state, | |
| 1454 | + err = fl_validate_ct_state(key->ct_state & mask->ct_state, | |
| 1455 | 1455 | tb[TCA_FLOWER_KEY_CT_STATE_MASK], |
| 1456 | 1456 | extack); |
| 1457 | 1457 | if (err) |
| @@ -345,6 +345,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, · 344 unmodified lines | ||
| 345 | 345 | struct sk_buff **old = NULL; |
| 346 | 346 | unsigned int mask; |
| 347 | 347 | u32 max_P; |
| 348 | + u8 *stab; | |
| 348 | 349 | |
| 349 | 350 | if (opt == NULL) |
| 350 | 351 | return -EINVAL; |
| @@ -361,8 +362,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, · 10 unmodified lines | ||
| 361 | 362 | max_P = tb[TCA_CHOKE_MAX_P] ? nla_get_u32(tb[TCA_CHOKE_MAX_P]) : 0; |
| 362 | 363 | |
| 363 | 364 | ctl = nla_data(tb[TCA_CHOKE_PARMS]); |
| 364 | − | |
| 365 | − if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) | |
| 365 | + stab = nla_data(tb[TCA_CHOKE_STAB]); | |
| 366 | + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log, stab)) | |
| 366 | 367 | return -EINVAL; |
| 367 | 368 | |
| 368 | 369 | if (ctl->limit > CHOKE_MAX_QUEUE) |
| @@ -412,7 +413,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, · 43 unmodified lines | ||
| 412 | 413 | |
| 413 | 414 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, |
| 414 | 415 | ctl->Plog, ctl->Scell_log, |
| 415 | − nla_data(tb[TCA_CHOKE_STAB]), | |
| 416 | + stab, | |
| 416 | 417 | max_P); |
| 417 | 418 | red_set_vars(&q->vars); |
| 418 | 419 | |
| @@ -480,7 +480,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, · 479 unmodified lines | ||
| 480 | 480 | struct gred_sched *table = qdisc_priv(sch); |
| 481 | 481 | struct gred_sched_data *q = table->tab[dp]; |
| 482 | 482 | |
| 483 | − if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) { | |
| 483 | + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log, stab)) { | |
| 484 | 484 | NL_SET_ERR_MSG_MOD(extack, "invalid RED parameters"); |
| 485 | 485 | return -EINVAL; |
| 486 | 486 | } |
| @@ -1020,6 +1020,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, · 1019 unmodified lines | ||
| 1020 | 1020 | struct nlattr *tb[TCA_HTB_MAX + 1]; |
| 1021 | 1021 | struct tc_htb_glob *gopt; |
| 1022 | 1022 | unsigned int ntx; |
| 1023 | + bool offload; | |
| 1023 | 1024 | int err; |
| 1024 | 1025 | |
| 1025 | 1026 | qdisc_watchdog_init(&q->watchdog, sch); |
| @@ -1044,9 +1045,9 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, · 18 unmodified lines | ||
| 1044 | 1045 | if (gopt->version != HTB_VER >> 16) |
| 1045 | 1046 | return -EINVAL; |
| 1046 | 1047 | |
| 1047 | − q->offload = nla_get_flag(tb[TCA_HTB_OFFLOAD]); | |
| 1048 | + offload = nla_get_flag(tb[TCA_HTB_OFFLOAD]); | |
| 1048 | 1049 | |
| 1049 | − if (q->offload) { | |
| 1050 | + if (offload) { | |
| 1050 | 1051 | if (sch->parent != TC_H_ROOT) |
| 1051 | 1052 | return -EOPNOTSUPP; |
| 1052 | 1053 | |
| @@ -1076,7 +1077,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, · 23 unmodified lines | ||
| 1076 | 1077 | q->rate2quantum = 1; |
| 1077 | 1078 | q->defcls = gopt->defcls; |
| 1078 | 1079 | |
| 1079 | − if (!q->offload) | |
| 1080 | + if (!offload) | |
| 1080 | 1081 | return 0; |
| 1081 | 1082 | |
| 1082 | 1083 | for (ntx = 0; ntx < q->num_direct_qdiscs; ntx++) { |
| @@ -1107,12 +1108,14 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, · 24 unmodified lines | ||
| 1107 | 1108 | if (err) |
| 1108 | 1109 | goto err_free_qdiscs; |
| 1109 | 1110 | |
| 1111 | + /* Defer this assignment, so that htb_destroy skips offload-related | |
| 1112 | + * parts (especially calling ndo_setup_tc) on errors. | |
| 1113 | + */ | |
| 1114 | + q->offload = true; | |
| 1115 | + | |
| 1110 | 1116 | return 0; |
| 1111 | 1117 | |
| 1112 | 1118 | err_free_qdiscs: |
| 1113 | − /* TC_HTB_CREATE call failed, avoid any further calls to the driver. */ | |
| 1114 | − q->offload = false; | |
| 1115 | − | |
| 1116 | 1119 | for (ntx = 0; ntx < q->num_direct_qdiscs && q->direct_qdiscs[ntx]; |
| 1117 | 1120 | ntx++) |
| 1118 | 1121 | qdisc_put(q->direct_qdiscs[ntx]); |
| @@ -1340,8 +1343,12 @@ htb_select_queue(struct Qdisc *sch, struct tcmsg *tcm) · 221 unmodified lines | ||
| 1340 | 1343 | { |
| 1341 | 1344 | struct net_device *dev = qdisc_dev(sch); |
| 1342 | 1345 | struct tc_htb_qopt_offload offload_opt; |
| 1346 | + struct htb_sched *q = qdisc_priv(sch); | |
| 1343 | 1347 | int err; |
| 1344 | 1348 | |
| 1349 | + if (!q->offload) | |
| 1350 | + return sch->dev_queue; | |
| 1351 | + | |
| 1345 | 1352 | offload_opt = (struct tc_htb_qopt_offload) { |
| 1346 | 1353 | .command = TC_HTB_LEAF_QUERY_QUEUE, |
| 1347 | 1354 | .classid = TC_H_MIN(tcm->tcm_parent), |
| @@ -242,6 +242,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, · 241 unmodified lines | ||
| 242 | 242 | unsigned char flags; |
| 243 | 243 | int err; |
| 244 | 244 | u32 max_P; |
| 245 | + u8 *stab; | |
| 245 | 246 | |
| 246 | 247 | if (tb[TCA_RED_PARMS] == NULL || |
| 247 | 248 | tb[TCA_RED_STAB] == NULL) |
| @@ -250,7 +251,9 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, · 2 unmodified lines | ||
| 250 | 251 | max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; |
| 251 | 252 | |
| 252 | 253 | ctl = nla_data(tb[TCA_RED_PARMS]); |
| 253 | − if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) | |
| 254 | + stab = nla_data(tb[TCA_RED_STAB]); | |
| 255 | + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, | |
| 256 | + ctl->Scell_log, stab)) | |
| 254 | 257 | return -EINVAL; |
| 255 | 258 | |
| 256 | 259 | err = red_get_flags(ctl->flags, TC_RED_HISTORIC_FLAGS, |
| @@ -288,7 +291,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, · 31 unmodified lines | ||
| 288 | 291 | red_set_parms(&q->parms, |
| 289 | 292 | ctl->qth_min, ctl->qth_max, ctl->Wlog, |
| 290 | 293 | ctl->Plog, ctl->Scell_log, |
| 291 | − nla_data(tb[TCA_RED_STAB]), | |
| 294 | + stab, | |
| 292 | 295 | max_P); |
| 293 | 296 | red_set_vars(&q->vars); |
| 294 | 297 | |
| @@ -647,7 +647,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) · 646 unmodified lines | ||
| 647 | 647 | } |
| 648 | 648 | |
| 649 | 649 | if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, |
| 650 | − ctl_v1->Wlog, ctl_v1->Scell_log)) | |
| 650 | + ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) | |
| 651 | 651 | return -EINVAL; |
| 652 | 652 | if (ctl_v1 && ctl_v1->qth_min) { |
| 653 | 653 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
| @@ -584,13 +584,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) · 583 unmodified lines | ||
| 584 | 584 | goto out; |
| 585 | 585 | } |
| 586 | 586 | |
| 587 | − rcu_read_lock(); | |
| 588 | − if (__sk_dst_get(sk) != tp->dst) { | |
| 589 | − dst_hold(tp->dst); | |
| 590 | − sk_setup_caps(sk, tp->dst); | |
| 591 | − } | |
| 592 | − rcu_read_unlock(); | |
| 593 | − | |
| 594 | 587 | /* pack up chunks */ |
| 595 | 588 | pkt_count = sctp_packet_pack(packet, head, gso, gfp); |
| 596 | 589 | if (!pkt_count) { |
| @@ -1135,6 +1135,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, · 1134 unmodified lines | ||
| 1135 | 1135 | |
| 1136 | 1136 | static void sctp_outq_flush_transports(struct sctp_flush_ctx *ctx) |
| 1137 | 1137 | { |
| 1138 | + struct sock *sk = ctx->asoc->base.sk; | |
| 1138 | 1139 | struct list_head *ltransport; |
| 1139 | 1140 | struct sctp_packet *packet; |
| 1140 | 1141 | struct sctp_transport *t; |
| @@ -1144,6 +1145,12 @@ static void sctp_outq_flush_transports(struct sctp_flush_ctx *ctx) · 3 unmodified lines | ||
| 1144 | 1145 | t = list_entry(ltransport, struct sctp_transport, send_ready); |
| 1145 | 1146 | packet = &t->packet; |
| 1146 | 1147 | if (!sctp_packet_empty(packet)) { |
| 1148 | + rcu_read_lock(); | |
| 1149 | + if (t->dst && __sk_dst_get(sk) != t->dst) { | |
| 1150 | + dst_hold(t->dst); | |
| 1151 | + sk_setup_caps(sk, t->dst); | |
| 1152 | + } | |
| 1153 | + rcu_read_unlock(); | |
| 1147 | 1154 | error = sctp_packet_transmit(packet, ctx->gfp); |
| 1148 | 1155 | if (error < 0) |
| 1149 | 1156 | ctx->q->asoc->base.sk->sk_err = -error; |
| @@ -2895,17 +2895,22 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, · 2894 unmodified lines | ||
| 2895 | 2895 | |
| 2896 | 2896 | #ifdef CONFIG_TIPC_CRYPTO |
| 2897 | 2897 | static int tipc_nl_retrieve_key(struct nlattr **attrs, |
| 2898 | − struct tipc_aead_key **key) | |
| 2898 | + struct tipc_aead_key **pkey) | |
| 2899 | 2899 | { |
| 2900 | 2900 | struct nlattr *attr = attrs[TIPC_NLA_NODE_KEY]; |
| 2901 | + struct tipc_aead_key *key; | |
| 2901 | 2902 | |
| 2902 | 2903 | if (!attr) |
| 2903 | 2904 | return -ENODATA; |
| 2904 | 2905 | |
| 2905 | − *key = (struct tipc_aead_key *)nla_data(attr); | |
| 2906 | − if (nla_len(attr) < tipc_aead_key_size(*key)) | |
| 2906 | + if (nla_len(attr) < sizeof(*key)) | |
| 2907 | + return -EINVAL; | |
| 2908 | + key = (struct tipc_aead_key *)nla_data(attr); | |
| 2909 | + if (key->keylen > TIPC_AEAD_KEYLEN_MAX || | |
| 2910 | + nla_len(attr) < tipc_aead_key_size(key)) | |
| 2907 | 2911 | return -EINVAL; |
| 2908 | 2912 | |
| 2913 | + *pkey = key; | |
| 2909 | 2914 | return 0; |
| 2910 | 2915 | } |
| 2911 | 2916 | |
| @@ -755,6 +755,7 @@ static struct sock *__vsock_create(struct net *net, · 754 unmodified lines | ||
| 755 | 755 | vsk->buffer_size = psk->buffer_size; |
| 756 | 756 | vsk->buffer_min_size = psk->buffer_min_size; |
| 757 | 757 | vsk->buffer_max_size = psk->buffer_max_size; |
| 758 | + security_sk_clone(parent, sk); | |
| 758 | 759 | } else { |
| 759 | 760 | vsk->trusted = ns_capable_noaudit(&init_user_ns, CAP_NET_ADMIN); |
| 760 | 761 | vsk->owner = get_current_cred(); |
| @@ -70,7 +70,7 @@ __cfg80211_wdev_from_attrs(struct cfg80211_registered_device *rdev, · 69 unmodified lines | ||
| 70 | 70 | struct wireless_dev *result = NULL; |
| 71 | 71 | bool have_ifidx = attrs[NL80211_ATTR_IFINDEX]; |
| 72 | 72 | bool have_wdev_id = attrs[NL80211_ATTR_WDEV]; |
| 73 | − u64 wdev_id; | |
| 73 | + u64 wdev_id = 0; | |
| 74 | 74 | int wiphy_idx = -1; |
| 75 | 75 | int ifidx = -1; |
| 76 | 76 | |
| @@ -14789,6 +14789,7 @@ bad_tid_conf: · 14712 unmodified lines | ||
| 14789 | 14789 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ |
| 14790 | 14790 | NL80211_FLAG_CHECK_NETDEV_UP) |
| 14791 | 14791 | #define NL80211_FLAG_CLEAR_SKB 0x20 |
| 14792 | +#define NL80211_FLAG_NO_WIPHY_MTX 0x40 | |
| 14792 | 14793 | |
| 14793 | 14794 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, |
| 14794 | 14795 | struct genl_info *info) |
| @@ -14840,7 +14841,7 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, · 45 unmodified lines | ||
| 14840 | 14841 | info->user_ptr[0] = rdev; |
| 14841 | 14842 | } |
| 14842 | 14843 | |
| 14843 | − if (rdev) { | |
| 14844 | + if (rdev && !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) { | |
| 14844 | 14845 | wiphy_lock(&rdev->wiphy); |
| 14845 | 14846 | /* we keep the mutex locked until post_doit */ |
| 14846 | 14847 | __release(&rdev->wiphy.mtx); |
| @@ -14865,7 +14866,8 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, · 18 unmodified lines | ||
| 14865 | 14866 | } |
| 14866 | 14867 | } |
| 14867 | 14868 | |
| 14868 | − if (info->user_ptr[0]) { | |
| 14869 | + if (info->user_ptr[0] && | |
| 14870 | + !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) { | |
| 14869 | 14871 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| 14870 | 14872 | |
| 14871 | 14873 | /* we kept the mutex locked since pre_doit */ |
| @@ -15329,7 +15331,9 @@ static const struct genl_small_ops nl80211_small_ops[] = { · 457 unmodified lines | ||
| 15329 | 15331 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
| 15330 | 15332 | .doit = nl80211_wiphy_netns, |
| 15331 | 15333 | .flags = GENL_UNS_ADMIN_PERM, |
| 15332 | − .internal_flags = NL80211_FLAG_NEED_WIPHY, | |
| 15334 | + .internal_flags = NL80211_FLAG_NEED_WIPHY | | |
| 15335 | + NL80211_FLAG_NEED_RTNL | | |
| 15336 | + NL80211_FLAG_NO_WIPHY_MTX, | |
| 15333 | 15337 | }, |
| 15334 | 15338 | { |
| 15335 | 15339 | .cmd = NL80211_CMD_GET_SURVEY, |
| @@ -20,6 +20,7 @@ SECTIONS { · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | __patchable_function_entries : { *(__patchable_function_entries) } |
| 22 | 22 | |
| 23 | +#ifdef CONFIG_LTO_CLANG | |
| 23 | 24 | /* |
| 24 | 25 | * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and |
| 25 | 26 | * -ffunction-sections, which increases the size of the final module. |
| @@ -41,6 +42,7 @@ SECTIONS { · 15 unmodified lines | ||
| 41 | 42 | } |
| 42 | 43 | |
| 43 | 44 | .text : { *(.text .text.[0-9a-zA-Z_]*) } |
| 45 | +#endif | |
| 44 | 46 | } |
| 45 | 47 | |
| 46 | 48 | /* bring in arch-specific sections */ |
| @@ -98,6 +98,14 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode) · 97 unmodified lines | ||
| 98 | 98 | struct rb_node *node, *parent = NULL; |
| 99 | 99 | struct integrity_iint_cache *iint, *test_iint; |
| 100 | 100 | |
| 101 | + /* | |
| 102 | + * The integrity's "iint_cache" is initialized at security_init(), | |
| 103 | + * unless it is not included in the ordered list of LSMs enabled | |
| 104 | + * on the boot command line. | |
| 105 | + */ | |
| 106 | + if (!iint_cache) | |
| 107 | + panic("%s: lsm=integrity required.\n", __func__); | |
| 108 | + | |
| 101 | 109 | iint = integrity_iint_find(inode); |
| 102 | 110 | if (iint) |
| 103 | 111 | return iint; |
| @@ -219,14 +219,21 @@ static inline bool selinux_policycap_genfs_seclabel_symlinks(void) · 218 unmodified lines | ||
| 219 | 219 | return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]); |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | +struct selinux_policy_convert_data; | |
| 223 | + | |
| 224 | +struct selinux_load_state { | |
| 225 | + struct selinux_policy *policy; | |
| 226 | + struct selinux_policy_convert_data *convert_data; | |
| 227 | +}; | |
| 228 | + | |
| 222 | 229 | int security_mls_enabled(struct selinux_state *state); |
| 223 | 230 | int security_load_policy(struct selinux_state *state, |
| 224 | − void *data, size_t len, | |
| 225 | − struct selinux_policy **newpolicyp); | |
| 231 | + void *data, size_t len, | |
| 232 | + struct selinux_load_state *load_state); | |
| 226 | 233 | void selinux_policy_commit(struct selinux_state *state, |
| 227 | − struct selinux_policy *newpolicy); | |
| 234 | + struct selinux_load_state *load_state); | |
| 228 | 235 | void selinux_policy_cancel(struct selinux_state *state, |
| 229 | − struct selinux_policy *policy); | |
| 236 | + struct selinux_load_state *load_state); | |
| 230 | 237 | int security_read_policy(struct selinux_state *state, |
| 231 | 238 | void **data, size_t *len); |
| 232 | 239 | int security_read_state_kernel(struct selinux_state *state, |
| @@ -563,17 +563,13 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi, · 562 unmodified lines | ||
| 563 | 563 | |
| 564 | 564 | ret = sel_make_bools(newpolicy, tmp_bool_dir, &tmp_bool_num, |
| 565 | 565 | &tmp_bool_names, &tmp_bool_values); |
| 566 | − if (ret) { | |
| 567 | − pr_err("SELinux: failed to load policy booleans\n"); | |
| 566 | + if (ret) | |
| 568 | 567 | goto out; |
| 569 | − } | |
| 570 | 568 | |
| 571 | 569 | ret = sel_make_classes(newpolicy, tmp_class_dir, |
| 572 | 570 | &fsi->last_class_ino); |
| 573 | − if (ret) { | |
| 574 | − pr_err("SELinux: failed to load policy classes\n"); | |
| 571 | + if (ret) | |
| 575 | 572 | goto out; |
| 576 | − } | |
| 577 | 573 | |
| 578 | 574 | /* booleans */ |
| 579 | 575 | old_dentry = fsi->bool_dir; |
| @@ -616,7 +612,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, · 36 unmodified lines | ||
| 616 | 612 | |
| 617 | 613 | { |
| 618 | 614 | struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info; |
| 619 | − struct selinux_policy *newpolicy; | |
| 615 | + struct selinux_load_state load_state; | |
| 620 | 616 | ssize_t length; |
| 621 | 617 | void *data = NULL; |
| 622 | 618 | |
| @@ -642,23 +638,23 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, · 19 unmodified lines | ||
| 642 | 638 | if (copy_from_user(data, buf, count) != 0) |
| 643 | 639 | goto out; |
| 644 | 640 | |
| 645 | − length = security_load_policy(fsi->state, data, count, &newpolicy); | |
| 641 | + length = security_load_policy(fsi->state, data, count, &load_state); | |
| 646 | 642 | if (length) { |
| 647 | 643 | pr_warn_ratelimited("SELinux: failed to load policy\n"); |
| 648 | 644 | goto out; |
| 649 | 645 | } |
| 650 | 646 | |
| 651 | − length = sel_make_policy_nodes(fsi, newpolicy); | |
| 647 | + length = sel_make_policy_nodes(fsi, load_state.policy); | |
| 652 | 648 | if (length) { |
| 653 | − selinux_policy_cancel(fsi->state, newpolicy); | |
| 654 | − goto out1; | |
| 649 | + pr_warn_ratelimited("SELinux: failed to initialize selinuxfs\n"); | |
| 650 | + selinux_policy_cancel(fsi->state, &load_state); | |
| 651 | + goto out; | |
| 655 | 652 | } |
| 656 | 653 | |
| 657 | − selinux_policy_commit(fsi->state, newpolicy); | |
| 654 | + selinux_policy_commit(fsi->state, &load_state); | |
| 658 | 655 | |
| 659 | 656 | length = count; |
| 660 | 657 | |
| 661 | −out1: | |
| 662 | 658 | audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, |
| 663 | 659 | "auid=%u ses=%u lsm=selinux res=1", |
| 664 | 660 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
| @@ -67,6 +67,17 @@ · 66 unmodified lines | ||
| 67 | 67 | #include "policycap_names.h" |
| 68 | 68 | #include "ima.h" |
| 69 | 69 | |
| 70 | +struct convert_context_args { | |
| 71 | + struct selinux_state *state; | |
| 72 | + struct policydb *oldp; | |
| 73 | + struct policydb *newp; | |
| 74 | +}; | |
| 75 | + | |
| 76 | +struct selinux_policy_convert_data { | |
| 77 | + struct convert_context_args args; | |
| 78 | + struct sidtab_convert_params sidtab_params; | |
| 79 | +}; | |
| 80 | + | |
| 70 | 81 | /* Forward declaration. */ |
| 71 | 82 | static int context_struct_to_string(struct policydb *policydb, |
| 72 | 83 | struct context *context, |
| @@ -1974,12 +1985,6 @@ static inline int convert_context_handle_invalid_context( · 1901 unmodified lines | ||
| 1974 | 1985 | return 0; |
| 1975 | 1986 | } |
| 1976 | 1987 | |
| 1977 | −struct convert_context_args { | |
| 1978 | − struct selinux_state *state; | |
| 1979 | − struct policydb *oldp; | |
| 1980 | − struct policydb *newp; | |
| 1981 | −}; | |
| 1982 | − | |
| 1983 | 1988 | /* |
| 1984 | 1989 | * Convert the values in the security context |
| 1985 | 1990 | * structure `oldc' from the values specified |
| @@ -2159,7 +2164,7 @@ static void selinux_policy_cond_free(struct selinux_policy *policy) · 173 unmodified lines | ||
| 2159 | 2164 | } |
| 2160 | 2165 | |
| 2161 | 2166 | void selinux_policy_cancel(struct selinux_state *state, |
| 2162 | − struct selinux_policy *policy) | |
| 2167 | + struct selinux_load_state *load_state) | |
| 2163 | 2168 | { |
| 2164 | 2169 | struct selinux_policy *oldpolicy; |
| 2165 | 2170 | |
| @@ -2167,7 +2172,8 @@ void selinux_policy_cancel(struct selinux_state *state, · 1 unmodified line | ||
| 2167 | 2172 | lockdep_is_held(&state->policy_mutex)); |
| 2168 | 2173 | |
| 2169 | 2174 | sidtab_cancel_convert(oldpolicy->sidtab); |
| 2170 | − selinux_policy_free(policy); | |
| 2175 | + selinux_policy_free(load_state->policy); | |
| 2176 | + kfree(load_state->convert_data); | |
| 2171 | 2177 | } |
| 2172 | 2178 | |
| 2173 | 2179 | static void selinux_notify_policy_change(struct selinux_state *state, |
| @@ -2183,9 +2189,9 @@ static void selinux_notify_policy_change(struct selinux_state *state, · 9 unmodified lines | ||
| 2183 | 2189 | } |
| 2184 | 2190 | |
| 2185 | 2191 | void selinux_policy_commit(struct selinux_state *state, |
| 2186 | − struct selinux_policy *newpolicy) | |
| 2192 | + struct selinux_load_state *load_state) | |
| 2187 | 2193 | { |
| 2188 | − struct selinux_policy *oldpolicy; | |
| 2194 | + struct selinux_policy *oldpolicy, *newpolicy = load_state->policy; | |
| 2189 | 2195 | u32 seqno; |
| 2190 | 2196 | |
| 2191 | 2197 | oldpolicy = rcu_dereference_protected(state->policy, |
| @@ -2225,6 +2231,7 @@ void selinux_policy_commit(struct selinux_state *state, · 33 unmodified lines | ||
| 2225 | 2231 | /* Free the old policy */ |
| 2226 | 2232 | synchronize_rcu(); |
| 2227 | 2233 | selinux_policy_free(oldpolicy); |
| 2234 | + kfree(load_state->convert_data); | |
| 2228 | 2235 | |
| 2229 | 2236 | /* Notify others of the policy change */ |
| 2230 | 2237 | selinux_notify_policy_change(state, seqno); |
| @@ -2241,11 +2248,10 @@ void selinux_policy_commit(struct selinux_state *state, · 10 unmodified lines | ||
| 2241 | 2248 | * loading the new policy. |
| 2242 | 2249 | */ |
| 2243 | 2250 | int security_load_policy(struct selinux_state *state, void *data, size_t len, |
| 2244 | − struct selinux_policy **newpolicyp) | |
| 2251 | + struct selinux_load_state *load_state) | |
| 2245 | 2252 | { |
| 2246 | 2253 | struct selinux_policy *newpolicy, *oldpolicy; |
| 2247 | − struct sidtab_convert_params convert_params; | |
| 2248 | − struct convert_context_args args; | |
| 2254 | + struct selinux_policy_convert_data *convert_data; | |
| 2249 | 2255 | int rc = 0; |
| 2250 | 2256 | struct policy_file file = { data, len }, *fp = &file; |
| 2251 | 2257 | |
| @@ -2275,10 +2281,10 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len, · 23 unmodified lines | ||
| 2275 | 2281 | goto err_mapping; |
| 2276 | 2282 | } |
| 2277 | 2283 | |
| 2278 | − | |
| 2279 | 2284 | if (!selinux_initialized(state)) { |
| 2280 | 2285 | /* First policy load, so no need to preserve state from old policy */ |
| 2281 | − *newpolicyp = newpolicy; | |
| 2286 | + load_state->policy = newpolicy; | |
| 2287 | + load_state->convert_data = NULL; | |
| 2282 | 2288 | return 0; |
| 2283 | 2289 | } |
| 2284 | 2290 | |
| @@ -2292,29 +2298,38 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len, · 7 unmodified lines | ||
| 2292 | 2298 | goto err_free_isids; |
| 2293 | 2299 | } |
| 2294 | 2300 | |
| 2301 | + convert_data = kmalloc(sizeof(*convert_data), GFP_KERNEL); | |
| 2302 | + if (!convert_data) { | |
| 2303 | + rc = -ENOMEM; | |
| 2304 | + goto err_free_isids; | |
| 2305 | + } | |
| 2306 | + | |
| 2295 | 2307 | /* |
| 2296 | 2308 | * Convert the internal representations of contexts |
| 2297 | 2309 | * in the new SID table. |
| 2298 | 2310 | */ |
| 2299 | − args.state = state; | |
| 2300 | − args.oldp = &oldpolicy->policydb; | |
| 2301 | − args.newp = &newpolicy->policydb; | |
| 2311 | + convert_data->args.state = state; | |
| 2312 | + convert_data->args.oldp = &oldpolicy->policydb; | |
| 2313 | + convert_data->args.newp = &newpolicy->policydb; | |
| 2302 | 2314 | |
| 2303 | − convert_params.func = convert_context; | |
| 2304 | − convert_params.args = &args; | |
| 2305 | − convert_params.target = newpolicy->sidtab; | |
| 2315 | + convert_data->sidtab_params.func = convert_context; | |
| 2316 | + convert_data->sidtab_params.args = &convert_data->args; | |
| 2317 | + convert_data->sidtab_params.target = newpolicy->sidtab; | |
| 2306 | 2318 | |
| 2307 | − rc = sidtab_convert(oldpolicy->sidtab, &convert_params); | |
| 2319 | + rc = sidtab_convert(oldpolicy->sidtab, &convert_data->sidtab_params); | |
| 2308 | 2320 | if (rc) { |
| 2309 | 2321 | pr_err("SELinux: unable to convert the internal" |
| 2310 | 2322 | " representation of contexts in the new SID" |
| 2311 | 2323 | " table\n"); |
| 2312 | − goto err_free_isids; | |
| 2324 | + goto err_free_convert_data; | |
| 2313 | 2325 | } |
| 2314 | 2326 | |
| 2315 | − *newpolicyp = newpolicy; | |
| 2327 | + load_state->policy = newpolicy; | |
| 2328 | + load_state->convert_data = convert_data; | |
| 2316 | 2329 | return 0; |
| 2317 | 2330 | |
| 2331 | +err_free_convert_data: | |
| 2332 | + kfree(convert_data); | |
| 2318 | 2333 | err_free_isids: |
| 2319 | 2334 | sidtab_destroy(newpolicy->sidtab); |
| 2320 | 2335 | err_mapping: |
| @@ -613,7 +613,7 @@ static int tomoyo_check_unix_address(struct sockaddr *addr, · 612 unmodified lines | ||
| 613 | 613 | static bool tomoyo_kernel_service(void) |
| 614 | 614 | { |
| 615 | 615 | /* Nothing to do if I am a kernel service. */ |
| 616 | − return (current->flags & (PF_KTHREAD | PF_IO_WORKER)) == PF_KTHREAD; | |
| 616 | + return current->flags & PF_KTHREAD; | |
| 617 | 617 | } |
| 618 | 618 | |
| 619 | 619 | /** |
| @@ -989,8 +989,12 @@ static int azx_prepare(struct device *dev) · 988 unmodified lines | ||
| 989 | 989 | struct snd_card *card = dev_get_drvdata(dev); |
| 990 | 990 | struct azx *chip; |
| 991 | 991 | |
| 992 | + if (!azx_is_pm_ready(card)) | |
| 993 | + return 0; | |
| 994 | + | |
| 992 | 995 | chip = card->private_data; |
| 993 | 996 | chip->pm_prepared = 1; |
| 997 | + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | |
| 994 | 998 | |
| 995 | 999 | flush_work(&azx_bus(chip)->unsol_work); |
| 996 | 1000 | |
| @@ -1005,7 +1009,11 @@ static void azx_complete(struct device *dev) · 8 unmodified lines | ||
| 1005 | 1009 | struct snd_card *card = dev_get_drvdata(dev); |
| 1006 | 1010 | struct azx *chip; |
| 1007 | 1011 | |
| 1012 | + if (!azx_is_pm_ready(card)) | |
| 1013 | + return; | |
| 1014 | + | |
| 1008 | 1015 | chip = card->private_data; |
| 1016 | + snd_power_change_state(card, SNDRV_CTL_POWER_D0); | |
| 1009 | 1017 | chip->pm_prepared = 0; |
| 1010 | 1018 | } |
| 1011 | 1019 | |
| @@ -5256,7 +5256,7 @@ static void alc_determine_headset_type(struct hda_codec *codec) · 5255 unmodified lines | ||
| 5256 | 5256 | case 0x10ec0274: |
| 5257 | 5257 | case 0x10ec0294: |
| 5258 | 5258 | alc_process_coef_fw(codec, coef0274); |
| 5259 | − msleep(80); | |
| 5259 | + msleep(850); | |
| 5260 | 5260 | val = alc_read_coef_idx(codec, 0x46); |
| 5261 | 5261 | is_ctia = (val & 0x00f0) == 0x00f0; |
| 5262 | 5262 | break; |
| @@ -5440,6 +5440,7 @@ static void alc_update_headset_jack_cb(struct hda_codec *codec, · 177 unmodified lines | ||
| 5440 | 5440 | struct hda_jack_callback *jack) |
| 5441 | 5441 | { |
| 5442 | 5442 | snd_hda_gen_hp_automute(codec, jack); |
| 5443 | + alc_update_headset_mode(codec); | |
| 5443 | 5444 | } |
| 5444 | 5445 | |
| 5445 | 5446 | static void alc_probe_headset_mode(struct hda_codec *codec) |
| @@ -8057,6 +8058,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 2611 unmodified lines | ||
| 8057 | 8058 | ALC285_FIXUP_HP_GPIO_AMP_INIT), |
| 8058 | 8059 | SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 8059 | 8060 | SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), |
| 8061 | + SND_PCI_QUIRK(0x103c, 0x87f2, "HP ProBook 640 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), | |
| 8060 | 8062 | SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 8061 | 8063 | SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 8062 | 8064 | SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), |
| @@ -1521,6 +1521,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) · 1520 unmodified lines | ||
| 1521 | 1521 | case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ |
| 1522 | 1522 | case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */ |
| 1523 | 1523 | case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */ |
| 1524 | + case USB_ID(0x046d, 0x084c): /* Logitech ConferenceCam Connect */ | |
| 1524 | 1525 | return true; |
| 1525 | 1526 | } |
| 1526 | 1527 | |
| @@ -1154,6 +1154,7 @@ struct kvm_x86_mce { · 1153 unmodified lines | ||
| 1154 | 1154 | #define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0) |
| 1155 | 1155 | #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1) |
| 1156 | 1156 | #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) |
| 1157 | +#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3) | |
| 1157 | 1158 | |
| 1158 | 1159 | struct kvm_xen_hvm_config { |
| 1159 | 1160 | __u32 flags; |
| @@ -1621,12 +1622,24 @@ struct kvm_xen_vcpu_attr { · 461 unmodified lines | ||
| 1621 | 1622 | union { |
| 1622 | 1623 | __u64 gpa; |
| 1623 | 1624 | __u64 pad[8]; |
| 1625 | + struct { | |
| 1626 | + __u64 state; | |
| 1627 | + __u64 state_entry_time; | |
| 1628 | + __u64 time_running; | |
| 1629 | + __u64 time_runnable; | |
| 1630 | + __u64 time_blocked; | |
| 1631 | + __u64 time_offline; | |
| 1632 | + } runstate; | |
| 1624 | 1633 | } u; |
| 1625 | 1634 | }; |
| 1626 | 1635 | |
| 1627 | 1636 | /* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ |
| 1628 | 1637 | #define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0 |
| 1629 | 1638 | #define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1 |
| 1639 | +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2 | |
| 1640 | +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3 | |
| 1641 | +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4 | |
| 1642 | +#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5 | |
| 1630 | 1643 | |
| 1631 | 1644 | /* Secure Encrypted Virtualization command */ |
| 1632 | 1645 | enum sev_cmd_id { |
| @@ -9,6 +9,7 @@ Type=simple · 8 unmodified lines | ||
| 9 | 9 | ExecStart=/usr/bin/kvm_stat -dtcz -s 10 -L /var/log/kvm_stat.csv |
| 10 | 10 | ExecReload=/bin/kill -HUP $MAINPID |
| 11 | 11 | Restart=always |
| 12 | +RestartSec=60s | |
| 12 | 13 | SyslogIdentifier=kvm_stat |
| 13 | 14 | SyslogLevel=debug |
| 14 | 15 | |
| @@ -215,7 +215,7 @@ define do_install · 214 unmodified lines | ||
| 215 | 215 | if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ |
| 216 | 216 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ |
| 217 | 217 | fi; \ |
| 218 | − $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' | |
| 218 | + $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2' | |
| 219 | 219 | endef |
| 220 | 220 | |
| 221 | 221 | install_lib: all_cmd |
| @@ -462,7 +462,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) · 461 unmodified lines | ||
| 462 | 462 | return err; |
| 463 | 463 | |
| 464 | 464 | case BTF_KIND_ARRAY: |
| 465 | − return btf_dump_order_type(d, btf_array(t)->type, through_ptr); | |
| 465 | + return btf_dump_order_type(d, btf_array(t)->type, false); | |
| 466 | 466 | |
| 467 | 467 | case BTF_KIND_STRUCT: |
| 468 | 468 | case BTF_KIND_UNION: { |
| @@ -1181,7 +1181,8 @@ static int bpf_object__elf_init(struct bpf_object *obj) · 1180 unmodified lines | ||
| 1181 | 1181 | if (!elf_rawdata(elf_getscn(obj->efile.elf, obj->efile.shstrndx), NULL)) { |
| 1182 | 1182 | pr_warn("elf: failed to get section names strings from %s: %s\n", |
| 1183 | 1183 | obj->path, elf_errmsg(-1)); |
| 1184 | − return -LIBBPF_ERRNO__FORMAT; | |
| 1184 | + err = -LIBBPF_ERRNO__FORMAT; | |
| 1185 | + goto errout; | |
| 1185 | 1186 | } |
| 1186 | 1187 | |
| 1187 | 1188 | /* Old LLVM set e_machine to EM_NONE */ |
| @@ -40,7 +40,7 @@ static int libbpf_netlink_open(__u32 *nl_pid) · 39 unmodified lines | ||
| 40 | 40 | memset(&sa, 0, sizeof(sa)); |
| 41 | 41 | sa.nl_family = AF_NETLINK; |
| 42 | 42 | |
| 43 | − sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | |
| 43 | + sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); | |
| 44 | 44 | if (sock < 0) |
| 45 | 45 | return -errno; |
| 46 | 46 | |
| @@ -402,35 +402,42 @@ static pid_t handle_signalfd(struct daemon *daemon) · 401 unmodified lines | ||
| 402 | 402 | int status; |
| 403 | 403 | pid_t pid; |
| 404 | 404 | |
| 405 | + /* | |
| 406 | + * Take signal fd data as pure signal notification and check all | |
| 407 | + * the sessions state. The reason is that multiple signals can get | |
| 408 | + * coalesced in kernel and we can receive only single signal even | |
| 409 | + * if multiple SIGCHLD were generated. | |
| 410 | + */ | |
| 405 | 411 | err = read(daemon->signal_fd, &si, sizeof(struct signalfd_siginfo)); |
| 406 | − if (err != sizeof(struct signalfd_siginfo)) | |
| 412 | + if (err != sizeof(struct signalfd_siginfo)) { | |
| 413 | + pr_err("failed to read signal fd\n"); | |
| 407 | 414 | return -1; |
| 415 | + } | |
| 408 | 416 | |
| 409 | 417 | list_for_each_entry(session, &daemon->sessions, list) { |
| 418 | + if (session->pid == -1) | |
| 419 | + continue; | |
| 410 | 420 | |
| 411 | − if (session->pid != (int) si.ssi_pid) | |
| 421 | + pid = waitpid(session->pid, &status, WNOHANG); | |
| 422 | + if (pid <= 0) | |
| 412 | 423 | continue; |
| 413 | 424 | |
| 414 | − pid = waitpid(session->pid, &status, 0); | |
| 415 | − if (pid == session->pid) { | |
| 416 | − if (WIFEXITED(status)) { | |
| 417 | − pr_info("session '%s' exited, status=%d\n", | |
| 418 | − session->name, WEXITSTATUS(status)); | |
| 419 | − } else if (WIFSIGNALED(status)) { | |
| 420 | − pr_info("session '%s' killed (signal %d)\n", | |
| 421 | − session->name, WTERMSIG(status)); | |
| 422 | − } else if (WIFSTOPPED(status)) { | |
| 423 | − pr_info("session '%s' stopped (signal %d)\n", | |
| 424 | − session->name, WSTOPSIG(status)); | |
| 425 | − } else { | |
| 426 | − pr_info("session '%s' Unexpected status (0x%x)\n", | |
| 427 | − session->name, status); | |
| 428 | − } | |
| 425 | + if (WIFEXITED(status)) { | |
| 426 | + pr_info("session '%s' exited, status=%d\n", | |
| 427 | + session->name, WEXITSTATUS(status)); | |
| 428 | + } else if (WIFSIGNALED(status)) { | |
| 429 | + pr_info("session '%s' killed (signal %d)\n", | |
| 430 | + session->name, WTERMSIG(status)); | |
| 431 | + } else if (WIFSTOPPED(status)) { | |
| 432 | + pr_info("session '%s' stopped (signal %d)\n", | |
| 433 | + session->name, WSTOPSIG(status)); | |
| 434 | + } else { | |
| 435 | + pr_info("session '%s' Unexpected status (0x%x)\n", | |
| 436 | + session->name, status); | |
| 429 | 437 | } |
| 430 | 438 | |
| 431 | 439 | session->state = KILL; |
| 432 | 440 | session->pid = -1; |
| 433 | − return pid; | |
| 434 | 441 | } |
| 435 | 442 | |
| 436 | 443 | return 0; |
| @@ -443,7 +450,6 @@ static int daemon_session__wait(struct daemon_session *session, struct daemon *d · 6 unmodified lines | ||
| 443 | 450 | .fd = daemon->signal_fd, |
| 444 | 451 | .events = POLLIN, |
| 445 | 452 | }; |
| 446 | − pid_t wpid = 0, pid = session->pid; | |
| 447 | 453 | time_t start; |
| 448 | 454 | |
| 449 | 455 | start = time(NULL); |
| @@ -452,7 +458,7 @@ static int daemon_session__wait(struct daemon_session *session, struct daemon *d · 2 unmodified lines | ||
| 452 | 458 | int err = poll(&pollfd, 1, 1000); |
| 453 | 459 | |
| 454 | 460 | if (err > 0) { |
| 455 | − wpid = handle_signalfd(daemon); | |
| 461 | + handle_signalfd(daemon); | |
| 456 | 462 | } else if (err < 0) { |
| 457 | 463 | perror("failed: poll\n"); |
| 458 | 464 | return -1; |
| @@ -460,7 +466,7 @@ static int daemon_session__wait(struct daemon_session *session, struct daemon *d · 1 unmodified line | ||
| 460 | 466 | |
| 461 | 467 | if (start + secs < time(NULL)) |
| 462 | 468 | return -1; |
| 463 | − } while (wpid != pid); | |
| 469 | + } while (session->pid != -1); | |
| 464 | 470 | |
| 465 | 471 | return 0; |
| 466 | 472 | } |
| @@ -902,7 +908,9 @@ static void daemon_session__kill(struct daemon_session *session, · 435 unmodified lines | ||
| 902 | 908 | daemon_session__signal(session, SIGKILL); |
| 903 | 909 | break; |
| 904 | 910 | default: |
| 905 | − break; | |
| 911 | + pr_err("failed to wait for session %s\n", | |
| 912 | + session->name); | |
| 913 | + return; | |
| 906 | 914 | } |
| 907 | 915 | how++; |
| 908 | 916 | |
| @@ -955,7 +963,8 @@ static void daemon__kill(struct daemon *daemon) · 46 unmodified lines | ||
| 955 | 963 | daemon__signal(daemon, SIGKILL); |
| 956 | 964 | break; |
| 957 | 965 | default: |
| 958 | − break; | |
| 966 | + pr_err("failed to wait for sessions\n"); | |
| 967 | + return; | |
| 959 | 968 | } |
| 960 | 969 | how++; |
| 961 | 970 | |
| @@ -1344,7 +1353,7 @@ out: · 382 unmodified lines | ||
| 1344 | 1353 | close(sock_fd); |
| 1345 | 1354 | if (conf_fd != -1) |
| 1346 | 1355 | close(conf_fd); |
| 1347 | − if (conf_fd != -1) | |
| 1356 | + if (signal_fd != -1) | |
| 1348 | 1357 | close(signal_fd); |
| 1349 | 1358 | |
| 1350 | 1359 | pr_info("daemon exited\n"); |
| @@ -86,7 +86,7 @@ static struct { · 85 unmodified lines | ||
| 86 | 86 | .msg_load_fail = "check your vmlinux setting?", |
| 87 | 87 | .target_func = &epoll_pwait_loop, |
| 88 | 88 | .expect_result = (NR_ITERS + 1) / 2, |
| 89 | − .pin = true, | |
| 89 | + .pin = true, | |
| 90 | 90 | }, |
| 91 | 91 | #ifdef HAVE_BPF_PROLOGUE |
| 92 | 92 | { |
| @@ -99,13 +99,6 @@ static struct { · 6 unmodified lines | ||
| 99 | 99 | .expect_result = (NR_ITERS + 1) / 4, |
| 100 | 100 | }, |
| 101 | 101 | #endif |
| 102 | − { | |
| 103 | − .prog_id = LLVM_TESTCASE_BPF_RELOCATION, | |
| 104 | − .desc = "BPF relocation checker", | |
| 105 | − .name = "[bpf_relocation_test]", | |
| 106 | − .msg_compile_fail = "fix 'perf test LLVM' first", | |
| 107 | − .msg_load_fail = "libbpf error when dealing with relocation", | |
| 108 | − }, | |
| 109 | 102 | }; |
| 110 | 103 | |
| 111 | 104 | static int do_test(struct bpf_object *obj, int (*func)(void), |
| @@ -1,4 +1,4 @@ | ||
| 1 | −#!/bin/sh | |
| 1 | +#!/bin/bash | |
| 2 | 2 | # daemon operations |
| 3 | 3 | # SPDX-License-Identifier: GPL-2.0 |
| 4 | 4 | |
| @@ -298,10 +298,6 @@ static int auxtrace_queues__queue_buffer(struct auxtrace_queues *queues, · 297 unmodified lines | ||
| 298 | 298 | queue->set = true; |
| 299 | 299 | queue->tid = buffer->tid; |
| 300 | 300 | queue->cpu = buffer->cpu; |
| 301 | − } else if (buffer->cpu != queue->cpu || buffer->tid != queue->tid) { | |
| 302 | − pr_err("auxtrace queue conflict: cpu %d, tid %d vs cpu %d, tid %d\n", | |
| 303 | − queue->cpu, queue->tid, buffer->cpu, buffer->tid); | |
| 304 | − return -EINVAL; | |
| 305 | 301 | } |
| 306 | 302 | |
| 307 | 303 | buffer->buffer_nr = queues->next_buffer_nr++; |
| @@ -196,25 +196,32 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, · 195 unmodified lines | ||
| 196 | 196 | } |
| 197 | 197 | |
| 198 | 198 | if (info_linear->info_len < offsetof(struct bpf_prog_info, prog_tags)) { |
| 199 | + free(info_linear); | |
| 199 | 200 | pr_debug("%s: the kernel is too old, aborting\n", __func__); |
| 200 | 201 | return -2; |
| 201 | 202 | } |
| 202 | 203 | |
| 203 | 204 | info = &info_linear->info; |
| 205 | + if (!info->jited_ksyms) { | |
| 206 | + free(info_linear); | |
| 207 | + return -1; | |
| 208 | + } | |
| 204 | 209 | |
| 205 | 210 | /* number of ksyms, func_lengths, and tags should match */ |
| 206 | 211 | sub_prog_cnt = info->nr_jited_ksyms; |
| 207 | 212 | if (sub_prog_cnt != info->nr_prog_tags || |
| 208 | − sub_prog_cnt != info->nr_jited_func_lens) | |
| 213 | + sub_prog_cnt != info->nr_jited_func_lens) { | |
| 214 | + free(info_linear); | |
| 209 | 215 | return -1; |
| 216 | + } | |
| 210 | 217 | |
| 211 | 218 | /* check BTF func info support */ |
| 212 | 219 | if (info->btf_id && info->nr_func_info && info->func_info_rec_size) { |
| 213 | 220 | /* btf func info number should be same as sub_prog_cnt */ |
| 214 | 221 | if (sub_prog_cnt != info->nr_func_info) { |
| 215 | 222 | pr_debug("%s: mismatch in BPF sub program count and BTF function info count, aborting\n", __func__); |
| 216 | − err = -1; | |
| 217 | − goto out; | |
| 223 | + free(info_linear); | |
| 224 | + return -1; | |
| 218 | 225 | } |
| 219 | 226 | if (btf__get_from_id(info->btf_id, &btf)) { |
| 220 | 227 | pr_debug("%s: failed to get BTF of id %u, aborting\n", __func__, info->btf_id); |
| @@ -356,6 +356,9 @@ __add_event(struct list_head *list, int *idx, · 355 unmodified lines | ||
| 356 | 356 | struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) : |
| 357 | 357 | cpu_list ? perf_cpu_map__new(cpu_list) : NULL; |
| 358 | 358 | |
| 359 | + if (pmu && attr->type == PERF_TYPE_RAW) | |
| 360 | + perf_pmu__warn_invalid_config(pmu, attr->config, name); | |
| 361 | + | |
| 359 | 362 | if (init_attr) |
| 360 | 363 | event_attr_init(attr); |
| 361 | 364 | |
| @@ -1812,3 +1812,36 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu) · 1811 unmodified lines | ||
| 1812 | 1812 | |
| 1813 | 1813 | return nr_caps; |
| 1814 | 1814 | } |
| 1815 | + | |
| 1816 | +void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, | |
| 1817 | + char *name) | |
| 1818 | +{ | |
| 1819 | + struct perf_pmu_format *format; | |
| 1820 | + __u64 masks = 0, bits; | |
| 1821 | + char buf[100]; | |
| 1822 | + unsigned int i; | |
| 1823 | + | |
| 1824 | + list_for_each_entry(format, &pmu->format, list) { | |
| 1825 | + if (format->value != PERF_PMU_FORMAT_VALUE_CONFIG) | |
| 1826 | + continue; | |
| 1827 | + | |
| 1828 | + for_each_set_bit(i, format->bits, PERF_PMU_FORMAT_BITS) | |
| 1829 | + masks |= 1ULL << i; | |
| 1830 | + } | |
| 1831 | + | |
| 1832 | + /* | |
| 1833 | + * Kernel doesn't export any valid format bits. | |
| 1834 | + */ | |
| 1835 | + if (masks == 0) | |
| 1836 | + return; | |
| 1837 | + | |
| 1838 | + bits = config & ~masks; | |
| 1839 | + if (bits == 0) | |
| 1840 | + return; | |
| 1841 | + | |
| 1842 | + bitmap_scnprintf((unsigned long *)&bits, sizeof(bits) * 8, buf, sizeof(buf)); | |
| 1843 | + | |
| 1844 | + pr_warning("WARNING: event '%s' not valid (bits %s of config " | |
| 1845 | + "'%llx' not supported by kernel)!\n", | |
| 1846 | + name ?: "N/A", buf, config); | |
| 1847 | +} | |
| @@ -123,4 +123,7 @@ int perf_pmu__convert_scale(const char *scale, char **end, double *sval); · 122 unmodified lines | ||
| 123 | 123 | |
| 124 | 124 | int perf_pmu__caps_parse(struct perf_pmu *pmu); |
| 125 | 125 | |
| 126 | +void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, | |
| 127 | + char *name); | |
| 128 | + | |
| 126 | 129 | #endif /* __PMU_H */ |
| @@ -424,7 +424,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, · 423 unmodified lines | ||
| 424 | 424 | |
| 425 | 425 | while (!io.eof) { |
| 426 | 426 | static const char anonstr[] = "//anon"; |
| 427 | − size_t size; | |
| 427 | + size_t size, aligned_size; | |
| 428 | 428 | |
| 429 | 429 | /* ensure null termination since stack will be reused. */ |
| 430 | 430 | event->mmap2.filename[0] = '\0'; |
| @@ -484,11 +484,12 @@ out: · 53 unmodified lines | ||
| 484 | 484 | } |
| 485 | 485 | |
| 486 | 486 | size = strlen(event->mmap2.filename) + 1; |
| 487 | − size = PERF_ALIGN(size, sizeof(u64)); | |
| 487 | + aligned_size = PERF_ALIGN(size, sizeof(u64)); | |
| 488 | 488 | event->mmap2.len -= event->mmap.start; |
| 489 | 489 | event->mmap2.header.size = (sizeof(event->mmap2) - |
| 490 | − (sizeof(event->mmap2.filename) - size)); | |
| 491 | − memset(event->mmap2.filename + size, 0, machine->id_hdr_size); | |
| 490 | + (sizeof(event->mmap2.filename) - aligned_size)); | |
| 491 | + memset(event->mmap2.filename + size, 0, machine->id_hdr_size + | |
| 492 | + (aligned_size - size)); | |
| 492 | 493 | event->mmap2.header.size += machine->id_hdr_size; |
| 493 | 494 | event->mmap2.pid = tgid; |
| 494 | 495 | event->mmap2.tid = pid; |
| @@ -758,7 +759,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, · 263 unmodified lines | ||
| 758 | 759 | for (i = 0; i < n; i++) { |
| 759 | 760 | char *end; |
| 760 | 761 | pid_t _pid; |
| 761 | − bool kernel_thread; | |
| 762 | + bool kernel_thread = false; | |
| 762 | 763 | |
| 763 | 764 | _pid = strtol(dirent[i]->d_name, &end, 10); |
| 764 | 765 | if (*end) |
| @@ -133,6 +133,8 @@ static struct dso *__machine__addnew_vdso(struct machine *machine, const char *s · 132 unmodified lines | ||
| 133 | 133 | if (dso != NULL) { |
| 134 | 134 | __dsos__add(&machine->dsos, dso); |
| 135 | 135 | dso__set_long_name(dso, long_name, false); |
| 136 | + /* Put dso here because __dsos_add already got it */ | |
| 137 | + dso__put(dso); | |
| 136 | 138 | } |
| 137 | 139 | |
| 138 | 140 | return dso; |
| @@ -40,3 +40,5 @@ · 39 unmodified lines | ||
| 40 | 40 | # CONFIG_RESET_BRCMSTB_RESCAL is not set |
| 41 | 41 | # CONFIG_RESET_INTEL_GW is not set |
| 42 | 42 | # CONFIG_ADI_AXI_ADC is not set |
| 43 | +# CONFIG_DEBUG_PAGEALLOC is not set | |
| 44 | +# CONFIG_PAGE_POISONING is not set | |
| @@ -13,7 +13,7 @@ from typing import List, Set · 12 unmodified lines | ||
| 13 | 13 | CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$' |
| 14 | 14 | CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$' |
| 15 | 15 | |
| 16 | −KconfigEntryBase = collections.namedtuple('KconfigEntry', ['name', 'value']) | |
| 16 | +KconfigEntryBase = collections.namedtuple('KconfigEntryBase', ['name', 'value']) | |
| 17 | 17 | |
| 18 | 18 | class KconfigEntry(KconfigEntryBase): |
| 19 | 19 | |
| @@ -296,21 +296,34 @@ static void *idr_throbber(void *arg) · 295 unmodified lines | ||
| 296 | 296 | return NULL; |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | +/* | |
| 300 | + * There are always either 1 or 2 objects in the IDR. If we find nothing, | |
| 301 | + * or we find something at an ID we didn't expect, that's a bug. | |
| 302 | + */ | |
| 299 | 303 | void idr_find_test_1(int anchor_id, int throbber_id) |
| 300 | 304 | { |
| 301 | 305 | pthread_t throbber; |
| 302 | 306 | time_t start = time(NULL); |
| 303 | 307 | |
| 304 | − pthread_create(&throbber, NULL, idr_throbber, &throbber_id); | |
| 305 | − | |
| 306 | 308 | BUG_ON(idr_alloc(&find_idr, xa_mk_value(anchor_id), anchor_id, |
| 307 | 309 | anchor_id + 1, GFP_KERNEL) != anchor_id); |
| 308 | 310 | |
| 311 | + pthread_create(&throbber, NULL, idr_throbber, &throbber_id); | |
| 312 | + | |
| 313 | + rcu_read_lock(); | |
| 309 | 314 | do { |
| 310 | 315 | int id = 0; |
| 311 | 316 | void *entry = idr_get_next(&find_idr, &id); |
| 312 | − BUG_ON(entry != xa_mk_value(id)); | |
| 317 | + rcu_read_unlock(); | |
| 318 | + if ((id != anchor_id && id != throbber_id) || | |
| 319 | + entry != xa_mk_value(id)) { | |
| 320 | + printf("%s(%d, %d): %p at %d\n", __func__, anchor_id, | |
| 321 | + throbber_id, entry, id); | |
| 322 | + abort(); | |
| 323 | + } | |
| 324 | + rcu_read_lock(); | |
| 313 | 325 | } while (time(NULL) < start + 11); |
| 326 | + rcu_read_unlock(); | |
| 314 | 327 | |
| 315 | 328 | pthread_join(throbber, NULL); |
| 316 | 329 | |
| @@ -577,6 +590,7 @@ void ida_tests(void) · 260 unmodified lines | ||
| 577 | 590 | |
| 578 | 591 | int __weak main(void) |
| 579 | 592 | { |
| 593 | + rcu_register_thread(); | |
| 580 | 594 | radix_tree_init(); |
| 581 | 595 | idr_checks(); |
| 582 | 596 | ida_tests(); |
| @@ -584,5 +598,6 @@ int __weak main(void) · 1 unmodified line | ||
| 584 | 598 | rcu_barrier(); |
| 585 | 599 | if (nr_allocated) |
| 586 | 600 | printf("nr_allocated = %d\n", nr_allocated); |
| 601 | + rcu_unregister_thread(); | |
| 587 | 602 | return 0; |
| 588 | 603 | } |
Empty file deleted.
| @@ -224,7 +224,9 @@ void multiorder_checks(void) · 223 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | int __weak main(void) |
| 226 | 226 | { |
| 227 | + rcu_register_thread(); | |
| 227 | 228 | radix_tree_init(); |
| 228 | 229 | multiorder_checks(); |
| 230 | + rcu_unregister_thread(); | |
| 229 | 231 | return 0; |
| 230 | 232 | } |
| @@ -25,11 +25,13 @@ void xarray_tests(void) · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | int __weak main(void) |
| 27 | 27 | { |
| 28 | + rcu_register_thread(); | |
| 28 | 29 | radix_tree_init(); |
| 29 | 30 | xarray_tests(); |
| 30 | 31 | radix_tree_cpu_dead(1); |
| 31 | 32 | rcu_barrier(); |
| 32 | 33 | if (nr_allocated) |
| 33 | 34 | printf("nr_allocated = %d\n", nr_allocated); |
| 35 | + rcu_unregister_thread(); | |
| 34 | 36 | return 0; |
| 35 | 37 | } |
| @@ -284,16 +284,28 @@ endfunction · 283 unmodified lines | ||
| 284 | 284 | // Set up test pattern in the FFR |
| 285 | 285 | // x0: pid |
| 286 | 286 | // x2: generation |
| 287 | +// | |
| 288 | +// We need to generate a canonical FFR value, which consists of a number of | |
| 289 | +// low "1" bits, followed by a number of zeros. This gives us 17 unique values | |
| 290 | +// per 16 bits of FFR, so we create a 4 bit signature out of the PID and | |
| 291 | +// generation, and use that as the initial number of ones in the pattern. | |
| 292 | +// We fill the upper lanes of FFR with zeros. | |
| 287 | 293 | // Beware: corrupts P0. |
| 288 | 294 | function setup_ffr |
| 289 | 295 | mov x4, x30 |
| 290 | 296 | |
| 291 | − bl pattern | |
| 297 | + and w0, w0, #0x3 | |
| 298 | + bfi w0, w2, #2, #2 | |
| 299 | + mov w1, #1 | |
| 300 | + lsl w1, w1, w0 | |
| 301 | + sub w1, w1, #1 | |
| 302 | + | |
| 292 | 303 | ldr x0, =ffrref |
| 293 | − ldr x1, =scratch | |
| 294 | − rdvl x2, #1 | |
| 295 | − lsr x2, x2, #3 | |
| 296 | − bl memcpy | |
| 304 | + strh w1, [x0], 2 | |
| 305 | + rdvl x1, #1 | |
| 306 | + lsr x1, x1, #3 | |
| 307 | + sub x1, x1, #2 | |
| 308 | + bl memclr | |
| 297 | 309 | |
| 298 | 310 | mov x0, #0 |
| 299 | 311 | ldr x1, =ffrref |
| @@ -128,6 +128,8 @@ static void test_check_mtu_xdp(__u32 mtu, __u32 ifindex) · 127 unmodified lines | ||
| 128 | 128 | test_check_mtu_run_xdp(skel, skel->progs.xdp_use_helper, mtu); |
| 129 | 129 | test_check_mtu_run_xdp(skel, skel->progs.xdp_exceed_mtu, mtu); |
| 130 | 130 | test_check_mtu_run_xdp(skel, skel->progs.xdp_minus_delta, mtu); |
| 131 | + test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len, mtu); | |
| 132 | + test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len_exceed, mtu); | |
| 131 | 133 | |
| 132 | 134 | cleanup: |
| 133 | 135 | test_check_mtu__destroy(skel); |
| @@ -187,6 +189,8 @@ static void test_check_mtu_tc(__u32 mtu, __u32 ifindex) · 53 unmodified lines | ||
| 187 | 189 | test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu, mtu); |
| 188 | 190 | test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu_da, mtu); |
| 189 | 191 | test_check_mtu_run_tc(skel, skel->progs.tc_minus_delta, mtu); |
| 192 | + test_check_mtu_run_tc(skel, skel->progs.tc_input_len, mtu); | |
| 193 | + test_check_mtu_run_tc(skel, skel->progs.tc_input_len_exceed, mtu); | |
| 190 | 194 | cleanup: |
| 191 | 195 | test_check_mtu__destroy(skel); |
| 192 | 196 | } |
| @@ -0,0 +1,82 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* Copyright (c) 2021 Facebook */ | |
| 3 | +#define _GNU_SOURCE | |
| 4 | +#include <sched.h> | |
| 5 | +#include <test_progs.h> | |
| 6 | +#include <time.h> | |
| 7 | +#include <sys/mman.h> | |
| 8 | +#include <sys/syscall.h> | |
| 9 | +#include "fexit_sleep.skel.h" | |
| 10 | + | |
| 11 | +static int do_sleep(void *skel) | |
| 12 | +{ | |
| 13 | + struct fexit_sleep *fexit_skel = skel; | |
| 14 | + struct timespec ts1 = { .tv_nsec = 1 }; | |
| 15 | + struct timespec ts2 = { .tv_sec = 10 }; | |
| 16 | + | |
| 17 | + fexit_skel->bss->pid = getpid(); | |
| 18 | + (void)syscall(__NR_nanosleep, &ts1, NULL); | |
| 19 | + (void)syscall(__NR_nanosleep, &ts2, NULL); | |
| 20 | + return 0; | |
| 21 | +} | |
| 22 | + | |
| 23 | +#define STACK_SIZE (1024 * 1024) | |
| 24 | +static char child_stack[STACK_SIZE]; | |
| 25 | + | |
| 26 | +void test_fexit_sleep(void) | |
| 27 | +{ | |
| 28 | + struct fexit_sleep *fexit_skel = NULL; | |
| 29 | + int wstatus, duration = 0; | |
| 30 | + pid_t cpid; | |
| 31 | + int err, fexit_cnt; | |
| 32 | + | |
| 33 | + fexit_skel = fexit_sleep__open_and_load(); | |
| 34 | + if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n")) | |
| 35 | + goto cleanup; | |
| 36 | + | |
| 37 | + err = fexit_sleep__attach(fexit_skel); | |
| 38 | + if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) | |
| 39 | + goto cleanup; | |
| 40 | + | |
| 41 | + cpid = clone(do_sleep, child_stack + STACK_SIZE, CLONE_FILES | SIGCHLD, fexit_skel); | |
| 42 | + if (CHECK(cpid == -1, "clone", strerror(errno))) | |
| 43 | + goto cleanup; | |
| 44 | + | |
| 45 | + /* wait until first sys_nanosleep ends and second sys_nanosleep starts */ | |
| 46 | + while (READ_ONCE(fexit_skel->bss->fentry_cnt) != 2); | |
| 47 | + fexit_cnt = READ_ONCE(fexit_skel->bss->fexit_cnt); | |
| 48 | + if (CHECK(fexit_cnt != 1, "fexit_cnt", "%d", fexit_cnt)) | |
| 49 | + goto cleanup; | |
| 50 | + | |
| 51 | + /* close progs and detach them. That will trigger two nop5->jmp5 rewrites | |
| 52 | + * in the trampolines to skip nanosleep_fexit prog. | |
| 53 | + * The nanosleep_fentry prog will get detached first. | |
| 54 | + * The nanosleep_fexit prog will get detached second. | |
| 55 | + * Detaching will trigger freeing of both progs JITed images. | |
| 56 | + * There will be two dying bpf_tramp_image-s, but only the initial | |
| 57 | + * bpf_tramp_image (with both _fentry and _fexit progs will be stuck | |
| 58 | + * waiting for percpu_ref_kill to confirm). The other one | |
| 59 | + * will be freed quickly. | |
| 60 | + */ | |
| 61 | + close(bpf_program__fd(fexit_skel->progs.nanosleep_fentry)); | |
| 62 | + close(bpf_program__fd(fexit_skel->progs.nanosleep_fexit)); | |
| 63 | + fexit_sleep__detach(fexit_skel); | |
| 64 | + | |
| 65 | + /* kill the thread to unwind sys_nanosleep stack through the trampoline */ | |
| 66 | + kill(cpid, 9); | |
| 67 | + | |
| 68 | + if (CHECK(waitpid(cpid, &wstatus, 0) == -1, "waitpid", strerror(errno))) | |
| 69 | + goto cleanup; | |
| 70 | + if (CHECK(WEXITSTATUS(wstatus) != 0, "exitstatus", "failed")) | |
| 71 | + goto cleanup; | |
| 72 | + | |
| 73 | + /* The bypassed nanosleep_fexit prog shouldn't have executed. | |
| 74 | + * Unlike progs the maps were not freed and directly accessible. | |
| 75 | + */ | |
| 76 | + fexit_cnt = READ_ONCE(fexit_skel->bss->fexit_cnt); | |
| 77 | + if (CHECK(fexit_cnt != 1, "fexit_cnt", "%d", fexit_cnt)) | |
| 78 | + goto cleanup; | |
| 79 | + | |
| 80 | +cleanup: | |
| 81 | + fexit_sleep__destroy(fexit_skel); | |
| 82 | +} | |
| @@ -174,6 +174,12 @@ struct struct_in_struct { · 173 unmodified lines | ||
| 174 | 174 | }; |
| 175 | 175 | }; |
| 176 | 176 | |
| 177 | +struct struct_in_array {}; | |
| 178 | + | |
| 179 | +struct struct_in_array_typed {}; | |
| 180 | + | |
| 181 | +typedef struct struct_in_array_typed struct_in_array_t[2]; | |
| 182 | + | |
| 177 | 183 | struct struct_with_embedded_stuff { |
| 178 | 184 | int a; |
| 179 | 185 | struct { |
| @@ -203,6 +209,8 @@ struct struct_with_embedded_stuff { · 23 unmodified lines | ||
| 203 | 209 | } r[5]; |
| 204 | 210 | struct struct_in_struct s[10]; |
| 205 | 211 | int t[11]; |
| 212 | + struct struct_in_array (*u)[2]; | |
| 213 | + struct_in_array_t *v; | |
| 206 | 214 | }; |
| 207 | 215 | |
| 208 | 216 | struct root_struct { |
| @@ -0,0 +1,31 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* Copyright (c) 2021 Facebook */ | |
| 3 | +#include "vmlinux.h" | |
| 4 | +#include <bpf/bpf_helpers.h> | |
| 5 | +#include <bpf/bpf_tracing.h> | |
| 6 | + | |
| 7 | +char LICENSE[] SEC("license") = "GPL"; | |
| 8 | + | |
| 9 | +int pid = 0; | |
| 10 | +int fentry_cnt = 0; | |
| 11 | +int fexit_cnt = 0; | |
| 12 | + | |
| 13 | +SEC("fentry/__x64_sys_nanosleep") | |
| 14 | +int BPF_PROG(nanosleep_fentry, const struct pt_regs *regs) | |
| 15 | +{ | |
| 16 | + if ((int)bpf_get_current_pid_tgid() != pid) | |
| 17 | + return 0; | |
| 18 | + | |
| 19 | + fentry_cnt++; | |
| 20 | + return 0; | |
| 21 | +} | |
| 22 | + | |
| 23 | +SEC("fexit/__x64_sys_nanosleep") | |
| 24 | +int BPF_PROG(nanosleep_fexit, const struct pt_regs *regs, int ret) | |
| 25 | +{ | |
| 26 | + if ((int)bpf_get_current_pid_tgid() != pid) | |
| 27 | + return 0; | |
| 28 | + | |
| 29 | + fexit_cnt++; | |
| 30 | + return 0; | |
| 31 | +} | |
| @@ -105,6 +105,54 @@ int xdp_minus_delta(struct xdp_md *ctx) · 104 unmodified lines | ||
| 105 | 105 | return retval; |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | +SEC("xdp") | |
| 109 | +int xdp_input_len(struct xdp_md *ctx) | |
| 110 | +{ | |
| 111 | + int retval = XDP_PASS; /* Expected retval on successful test */ | |
| 112 | + void *data_end = (void *)(long)ctx->data_end; | |
| 113 | + void *data = (void *)(long)ctx->data; | |
| 114 | + __u32 ifindex = GLOBAL_USER_IFINDEX; | |
| 115 | + __u32 data_len = data_end - data; | |
| 116 | + | |
| 117 | + /* API allow user give length to check as input via mtu_len param, | |
| 118 | + * resulting MTU value is still output in mtu_len param after call. | |
| 119 | + * | |
| 120 | + * Input len is L3, like MTU and iph->tot_len. | |
| 121 | + * Remember XDP data_len is L2. | |
| 122 | + */ | |
| 123 | + __u32 mtu_len = data_len - ETH_HLEN; | |
| 124 | + | |
| 125 | + if (bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0)) | |
| 126 | + retval = XDP_ABORTED; | |
| 127 | + | |
| 128 | + global_bpf_mtu_xdp = mtu_len; | |
| 129 | + return retval; | |
| 130 | +} | |
| 131 | + | |
| 132 | +SEC("xdp") | |
| 133 | +int xdp_input_len_exceed(struct xdp_md *ctx) | |
| 134 | +{ | |
| 135 | + int retval = XDP_ABORTED; /* Fail */ | |
| 136 | + __u32 ifindex = GLOBAL_USER_IFINDEX; | |
| 137 | + int err; | |
| 138 | + | |
| 139 | + /* API allow user give length to check as input via mtu_len param, | |
| 140 | + * resulting MTU value is still output in mtu_len param after call. | |
| 141 | + * | |
| 142 | + * Input length value is L3 size like MTU. | |
| 143 | + */ | |
| 144 | + __u32 mtu_len = GLOBAL_USER_MTU; | |
| 145 | + | |
| 146 | + mtu_len += 1; /* Exceed with 1 */ | |
| 147 | + | |
| 148 | + err = bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0); | |
| 149 | + if (err == BPF_MTU_CHK_RET_FRAG_NEEDED) | |
| 150 | + retval = XDP_PASS ; /* Success in exceeding MTU check */ | |
| 151 | + | |
| 152 | + global_bpf_mtu_xdp = mtu_len; | |
| 153 | + return retval; | |
| 154 | +} | |
| 155 | + | |
| 108 | 156 | SEC("classifier") |
| 109 | 157 | int tc_use_helper(struct __sk_buff *ctx) |
| 110 | 158 | { |
| @@ -196,3 +244,47 @@ int tc_minus_delta(struct __sk_buff *ctx) · 85 unmodified lines | ||
| 196 | 244 | global_bpf_mtu_xdp = mtu_len; |
| 197 | 245 | return retval; |
| 198 | 246 | } |
| 247 | + | |
| 248 | +SEC("classifier") | |
| 249 | +int tc_input_len(struct __sk_buff *ctx) | |
| 250 | +{ | |
| 251 | + int retval = BPF_OK; /* Expected retval on successful test */ | |
| 252 | + __u32 ifindex = GLOBAL_USER_IFINDEX; | |
| 253 | + | |
| 254 | + /* API allow user give length to check as input via mtu_len param, | |
| 255 | + * resulting MTU value is still output in mtu_len param after call. | |
| 256 | + * | |
| 257 | + * Input length value is L3 size. | |
| 258 | + */ | |
| 259 | + __u32 mtu_len = GLOBAL_USER_MTU; | |
| 260 | + | |
| 261 | + if (bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0)) | |
| 262 | + retval = BPF_DROP; | |
| 263 | + | |
| 264 | + global_bpf_mtu_xdp = mtu_len; | |
| 265 | + return retval; | |
| 266 | +} | |
| 267 | + | |
| 268 | +SEC("classifier") | |
| 269 | +int tc_input_len_exceed(struct __sk_buff *ctx) | |
| 270 | +{ | |
| 271 | + int retval = BPF_DROP; /* Fail */ | |
| 272 | + __u32 ifindex = GLOBAL_USER_IFINDEX; | |
| 273 | + int err; | |
| 274 | + | |
| 275 | + /* API allow user give length to check as input via mtu_len param, | |
| 276 | + * resulting MTU value is still output in mtu_len param after call. | |
| 277 | + * | |
| 278 | + * Input length value is L3 size like MTU. | |
| 279 | + */ | |
| 280 | + __u32 mtu_len = GLOBAL_USER_MTU; | |
| 281 | + | |
| 282 | + mtu_len += 1; /* Exceed with 1 */ | |
| 283 | + | |
| 284 | + err = bpf_check_mtu(ctx, ifindex, &mtu_len, 0, 0); | |
| 285 | + if (err == BPF_MTU_CHK_RET_FRAG_NEEDED) | |
| 286 | + retval = BPF_OK; /* Success in exceeding MTU check */ | |
| 287 | + | |
| 288 | + global_bpf_mtu_xdp = mtu_len; | |
| 289 | + return retval; | |
| 290 | +} | |
| @@ -508,10 +508,8 @@ int _ip6geneve_get_tunnel(struct __sk_buff *skb) · 507 unmodified lines | ||
| 508 | 508 | } |
| 509 | 509 | |
| 510 | 510 | ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt)); |
| 511 | − if (ret < 0) { | |
| 512 | − ERROR(ret); | |
| 513 | − return TC_ACT_SHOT; | |
| 514 | − } | |
| 511 | + if (ret < 0) | |
| 512 | + gopt.opt_class = 0; | |
| 515 | 513 | |
| 516 | 514 | bpf_trace_printk(fmt, sizeof(fmt), |
| 517 | 515 | key.tunnel_id, key.remote_ipv4, gopt.opt_class); |
| @@ -6,8 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| 7 | 7 | BPF_EXIT_INSN(), |
| 8 | 8 | }, |
| 9 | − .result = REJECT, | |
| 9 | + .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", | |
| 10 | 10 | .errstr = "R0 tried to subtract pointer from scalar", |
| 11 | + .result = REJECT, | |
| 11 | 12 | }, |
| 12 | 13 | { |
| 13 | 14 | "check deducing bounds from const, 2", |
| @@ -20,6 +21,8 @@ · 6 unmodified lines | ||
| 20 | 21 | BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), |
| 21 | 22 | BPF_EXIT_INSN(), |
| 22 | 23 | }, |
| 24 | + .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", | |
| 25 | + .result_unpriv = REJECT, | |
| 23 | 26 | .result = ACCEPT, |
| 24 | 27 | .retval = 1, |
| 25 | 28 | }, |
| @@ -31,8 +34,9 @@ · 5 unmodified lines | ||
| 31 | 34 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| 32 | 35 | BPF_EXIT_INSN(), |
| 33 | 36 | }, |
| 34 | − .result = REJECT, | |
| 37 | + .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", | |
| 35 | 38 | .errstr = "R0 tried to subtract pointer from scalar", |
| 39 | + .result = REJECT, | |
| 36 | 40 | }, |
| 37 | 41 | { |
| 38 | 42 | "check deducing bounds from const, 4", |
| @@ -45,6 +49,8 @@ · 6 unmodified lines | ||
| 45 | 49 | BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), |
| 46 | 50 | BPF_EXIT_INSN(), |
| 47 | 51 | }, |
| 52 | + .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", | |
| 53 | + .result_unpriv = REJECT, | |
| 48 | 54 | .result = ACCEPT, |
| 49 | 55 | }, |
| 50 | 56 | { |
| @@ -55,8 +61,9 @@ · 4 unmodified lines | ||
| 55 | 61 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| 56 | 62 | BPF_EXIT_INSN(), |
| 57 | 63 | }, |
| 58 | − .result = REJECT, | |
| 64 | + .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", | |
| 59 | 65 | .errstr = "R0 tried to subtract pointer from scalar", |
| 66 | + .result = REJECT, | |
| 60 | 67 | }, |
| 61 | 68 | { |
| 62 | 69 | "check deducing bounds from const, 6", |
| @@ -67,8 +74,9 @@ · 4 unmodified lines | ||
| 67 | 74 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| 68 | 75 | BPF_EXIT_INSN(), |
| 69 | 76 | }, |
| 70 | − .result = REJECT, | |
| 77 | + .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", | |
| 71 | 78 | .errstr = "R0 tried to subtract pointer from scalar", |
| 79 | + .result = REJECT, | |
| 72 | 80 | }, |
| 73 | 81 | { |
| 74 | 82 | "check deducing bounds from const, 7", |
| @@ -80,8 +88,9 @@ · 5 unmodified lines | ||
| 80 | 88 | offsetof(struct __sk_buff, mark)), |
| 81 | 89 | BPF_EXIT_INSN(), |
| 82 | 90 | }, |
| 83 | − .result = REJECT, | |
| 91 | + .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", | |
| 84 | 92 | .errstr = "dereference of modified ctx ptr", |
| 93 | + .result = REJECT, | |
| 85 | 94 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 86 | 95 | }, |
| 87 | 96 | { |
| @@ -94,8 +103,9 @@ · 6 unmodified lines | ||
| 94 | 103 | offsetof(struct __sk_buff, mark)), |
| 95 | 104 | BPF_EXIT_INSN(), |
| 96 | 105 | }, |
| 97 | − .result = REJECT, | |
| 106 | + .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", | |
| 98 | 107 | .errstr = "dereference of modified ctx ptr", |
| 108 | + .result = REJECT, | |
| 99 | 109 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 100 | 110 | }, |
| 101 | 111 | { |
| @@ -106,8 +116,9 @@ · 4 unmodified lines | ||
| 106 | 116 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| 107 | 117 | BPF_EXIT_INSN(), |
| 108 | 118 | }, |
| 109 | − .result = REJECT, | |
| 119 | + .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", | |
| 110 | 120 | .errstr = "R0 tried to subtract pointer from scalar", |
| 121 | + .result = REJECT, | |
| 111 | 122 | }, |
| 112 | 123 | { |
| 113 | 124 | "check deducing bounds from const, 10", |
| @@ -119,6 +130,6 @@ · 5 unmodified lines | ||
| 119 | 130 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| 120 | 131 | BPF_EXIT_INSN(), |
| 121 | 132 | }, |
| 122 | − .result = REJECT, | |
| 123 | 133 | .errstr = "math between ctx pointer and register with unbounded min value is not allowed", |
| 134 | + .result = REJECT, | |
| 124 | 135 | }, |
| @@ -75,6 +75,8 @@ · 74 unmodified lines | ||
| 75 | 75 | BPF_EXIT_INSN(), |
| 76 | 76 | }, |
| 77 | 77 | .fixup_map_hash_16b = { 4 }, |
| 78 | + .result_unpriv = REJECT, | |
| 79 | + .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", | |
| 78 | 80 | .result = ACCEPT, |
| 79 | 81 | }, |
| 80 | 82 | { |
| @@ -91,5 +93,7 @@ · 10 unmodified lines | ||
| 91 | 93 | BPF_EXIT_INSN(), |
| 92 | 94 | }, |
| 93 | 95 | .fixup_map_hash_16b = { 4 }, |
| 96 | + .result_unpriv = REJECT, | |
| 97 | + .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", | |
| 94 | 98 | .result = ACCEPT, |
| 95 | 99 | }, |
| @@ -497,7 +497,7 @@ · 496 unmodified lines | ||
| 497 | 497 | .result = ACCEPT, |
| 498 | 498 | }, |
| 499 | 499 | { |
| 500 | − "unpriv: adding of fp", | |
| 500 | + "unpriv: adding of fp, reg", | |
| 501 | 501 | .insns = { |
| 502 | 502 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 503 | 503 | BPF_MOV64_IMM(BPF_REG_1, 0), |
| @@ -505,6 +505,19 @@ · 1 unmodified line | ||
| 505 | 505 | BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8), |
| 506 | 506 | BPF_EXIT_INSN(), |
| 507 | 507 | }, |
| 508 | + .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", | |
| 509 | + .result_unpriv = REJECT, | |
| 510 | + .result = ACCEPT, | |
| 511 | +}, | |
| 512 | +{ | |
| 513 | + "unpriv: adding of fp, imm", | |
| 514 | + .insns = { | |
| 515 | + BPF_MOV64_IMM(BPF_REG_0, 0), | |
| 516 | + BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), | |
| 517 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0), | |
| 518 | + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8), | |
| 519 | + BPF_EXIT_INSN(), | |
| 520 | + }, | |
| 508 | 521 | .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", |
| 509 | 522 | .result_unpriv = REJECT, |
| 510 | 523 | .result = ACCEPT, |
| @@ -169,7 +169,7 @@ · 168 unmodified lines | ||
| 169 | 169 | .fixup_map_array_48b = { 1 }, |
| 170 | 170 | .result = ACCEPT, |
| 171 | 171 | .result_unpriv = REJECT, |
| 172 | − .errstr_unpriv = "R2 tried to add from different maps or paths", | |
| 172 | + .errstr_unpriv = "R2 tried to add from different maps, paths, or prohibited types", | |
| 173 | 173 | .retval = 0, |
| 174 | 174 | }, |
| 175 | 175 | { |
| @@ -516,6 +516,27 @@ · 340 unmodified lines | ||
| 516 | 516 | .result = ACCEPT, |
| 517 | 517 | .retval = 0xabcdef12, |
| 518 | 518 | }, |
| 519 | +{ | |
| 520 | + "map access: value_ptr += N, value_ptr -= N known scalar", | |
| 521 | + .insns = { | |
| 522 | + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | |
| 523 | + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | |
| 524 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | |
| 525 | + BPF_LD_MAP_FD(BPF_REG_1, 0), | |
| 526 | + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), | |
| 527 | + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), | |
| 528 | + BPF_MOV32_IMM(BPF_REG_1, 0x12345678), | |
| 529 | + BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), | |
| 530 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2), | |
| 531 | + BPF_MOV64_IMM(BPF_REG_1, 2), | |
| 532 | + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), | |
| 533 | + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0), | |
| 534 | + BPF_EXIT_INSN(), | |
| 535 | + }, | |
| 536 | + .fixup_map_array_48b = { 3 }, | |
| 537 | + .result = ACCEPT, | |
| 538 | + .retval = 0x12345678, | |
| 539 | +}, | |
| 519 | 540 | { |
| 520 | 541 | "map access: unknown scalar += value_ptr, 1", |
| 521 | 542 | .insns = { |
| @@ -108,7 +108,7 @@ static void run_test(uint32_t run) · 107 unmodified lines | ||
| 108 | 108 | kvm_vm_elf_load(vm, program_invocation_name, 0, 0); |
| 109 | 109 | vm_create_irqchip(vm); |
| 110 | 110 | |
| 111 | − fprintf(stderr, "%s: [%d] start vcpus\n", __func__, run); | |
| 111 | + pr_debug("%s: [%d] start vcpus\n", __func__, run); | |
| 112 | 112 | for (i = 0; i < VCPU_NUM; ++i) { |
| 113 | 113 | vm_vcpu_add_default(vm, i, guest_code); |
| 114 | 114 | payloads[i].vm = vm; |
| @@ -124,7 +124,7 @@ static void run_test(uint32_t run) · 9 unmodified lines | ||
| 124 | 124 | check_set_affinity(throw_away, &cpu_set); |
| 125 | 125 | } |
| 126 | 126 | } |
| 127 | − fprintf(stderr, "%s: [%d] all threads launched\n", __func__, run); | |
| 127 | + pr_debug("%s: [%d] all threads launched\n", __func__, run); | |
| 128 | 128 | sem_post(sem); |
| 129 | 129 | for (i = 0; i < VCPU_NUM; ++i) |
| 130 | 130 | check_join(threads[i], &b); |
| @@ -147,16 +147,16 @@ int main(int argc, char **argv) · 16 unmodified lines | ||
| 147 | 147 | if (pid == 0) |
| 148 | 148 | run_test(i); /* This function always exits */ |
| 149 | 149 | |
| 150 | − fprintf(stderr, "%s: [%d] waiting semaphore\n", __func__, i); | |
| 150 | + pr_debug("%s: [%d] waiting semaphore\n", __func__, i); | |
| 151 | 151 | sem_wait(sem); |
| 152 | 152 | r = (rand() % DELAY_US_MAX) + 1; |
| 153 | − fprintf(stderr, "%s: [%d] waiting %dus\n", __func__, i, r); | |
| 153 | + pr_debug("%s: [%d] waiting %dus\n", __func__, i, r); | |
| 154 | 154 | usleep(r); |
| 155 | 155 | r = waitpid(pid, &s, WNOHANG); |
| 156 | 156 | TEST_ASSERT(r != pid, |
| 157 | 157 | "%s: [%d] child exited unexpectedly status: [%d]", |
| 158 | 158 | __func__, i, s); |
| 159 | − fprintf(stderr, "%s: [%d] killing child\n", __func__, i); | |
| 159 | + pr_debug("%s: [%d] killing child\n", __func__, i); | |
| 160 | 160 | kill(pid, SIGKILL); |
| 161 | 161 | } |
| 162 | 162 | |
| @@ -80,19 +80,24 @@ static inline void check_tsc_msr_rdtsc(void) · 79 unmodified lines | ||
| 80 | 80 | GUEST_ASSERT(delta_ns * 100 < (t2 - t1) * 100); |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | +static inline u64 get_tscpage_ts(struct ms_hyperv_tsc_page *tsc_page) | |
| 84 | +{ | |
| 85 | + return mul_u64_u64_shr64(rdtsc(), tsc_page->tsc_scale) + tsc_page->tsc_offset; | |
| 86 | +} | |
| 87 | + | |
| 83 | 88 | static inline void check_tsc_msr_tsc_page(struct ms_hyperv_tsc_page *tsc_page) |
| 84 | 89 | { |
| 85 | 90 | u64 r1, r2, t1, t2; |
| 86 | 91 | |
| 87 | 92 | /* Compare TSC page clocksource with HV_X64_MSR_TIME_REF_COUNT */ |
| 88 | − t1 = mul_u64_u64_shr64(rdtsc(), tsc_page->tsc_scale) + tsc_page->tsc_offset; | |
| 93 | + t1 = get_tscpage_ts(tsc_page); | |
| 89 | 94 | r1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT); |
| 90 | 95 | |
| 91 | 96 | /* 10 ms tolerance */ |
| 92 | 97 | GUEST_ASSERT(r1 >= t1 && r1 - t1 < 100000); |
| 93 | 98 | nop_loop(); |
| 94 | 99 | |
| 95 | − t2 = mul_u64_u64_shr64(rdtsc(), tsc_page->tsc_scale) + tsc_page->tsc_offset; | |
| 100 | + t2 = get_tscpage_ts(tsc_page); | |
| 96 | 101 | r2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT); |
| 97 | 102 | GUEST_ASSERT(r2 >= t1 && r2 - t2 < 100000); |
| 98 | 103 | } |
| @@ -130,7 +135,11 @@ static void guest_main(struct ms_hyperv_tsc_page *tsc_page, vm_paddr_t tsc_page_ · 31 unmodified lines | ||
| 130 | 135 | |
| 131 | 136 | tsc_offset = tsc_page->tsc_offset; |
| 132 | 137 | /* Call KVM_SET_CLOCK from userspace, check that TSC page was updated */ |
| 138 | + | |
| 133 | 139 | GUEST_SYNC(7); |
| 140 | + /* Sanity check TSC page timestamp, it should be close to 0 */ | |
| 141 | + GUEST_ASSERT(get_tscpage_ts(tsc_page) < 100000); | |
| 142 | + | |
| 134 | 143 | GUEST_ASSERT(tsc_page->tsc_offset != tsc_offset); |
| 135 | 144 | |
| 136 | 145 | nop_loop(); |
| @@ -658,7 +658,7 @@ test_ecn_decap() · 657 unmodified lines | ||
| 658 | 658 | # In accordance with INET_ECN_decapsulate() |
| 659 | 659 | __test_ecn_decap 00 00 0x00 |
| 660 | 660 | __test_ecn_decap 01 01 0x01 |
| 661 | − __test_ecn_decap 02 01 0x02 | |
| 661 | + __test_ecn_decap 02 01 0x01 | |
| 662 | 662 | __test_ecn_decap 01 03 0x03 |
| 663 | 663 | __test_ecn_decap 02 03 0x03 |
| 664 | 664 | test_ecn_decap_error |
| @@ -11,6 +11,7 @@ ksft_skip=4 · 10 unmodified lines | ||
| 11 | 11 | timeout=30 |
| 12 | 12 | mptcp_connect="" |
| 13 | 13 | capture=0 |
| 14 | +do_all_tests=1 | |
| 14 | 15 | |
| 15 | 16 | TEST_COUNT=0 |
| 16 | 17 | |
| @@ -121,12 +122,6 @@ reset_with_add_addr_timeout() · 104 unmodified lines | ||
| 121 | 122 | -j DROP |
| 122 | 123 | } |
| 123 | 124 | |
| 124 | −for arg in "$@"; do | |
| 125 | − if [ "$arg" = "-c" ]; then | |
| 126 | − capture=1 | |
| 127 | − fi | |
| 128 | −done | |
| 129 | − | |
| 130 | 125 | ip -Version > /dev/null 2>&1 |
| 131 | 126 | if [ $? -ne 0 ];then |
| 132 | 127 | echo "SKIP: Could not run test without ip tool" |
| @@ -1221,7 +1216,8 @@ usage() · 1088 unmodified lines | ||
| 1221 | 1216 | echo " -4 v4mapped_tests" |
| 1222 | 1217 | echo " -b backup_tests" |
| 1223 | 1218 | echo " -p add_addr_ports_tests" |
| 1224 | − echo " -c syncookies_tests" | |
| 1219 | + echo " -k syncookies_tests" | |
| 1220 | + echo " -c capture pcap files" | |
| 1225 | 1221 | echo " -h help" |
| 1226 | 1222 | } |
| 1227 | 1223 | |
| @@ -1235,12 +1231,24 @@ make_file "$cin" "client" 1 · 7 unmodified lines | ||
| 1235 | 1231 | make_file "$sin" "server" 1 |
| 1236 | 1232 | trap cleanup EXIT |
| 1237 | 1233 | |
| 1238 | −if [ -z $1 ]; then | |
| 1234 | +for arg in "$@"; do | |
| 1235 | + # check for "capture" arg before launching tests | |
| 1236 | + if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"c"[0-9a-zA-Z]*$ ]]; then | |
| 1237 | + capture=1 | |
| 1238 | + fi | |
| 1239 | + | |
| 1240 | + # exception for the capture option, the rest means: a part of the tests | |
| 1241 | + if [ "${arg}" != "-c" ]; then | |
| 1242 | + do_all_tests=0 | |
| 1243 | + fi | |
| 1244 | +done | |
| 1245 | + | |
| 1246 | +if [ $do_all_tests -eq 1 ]; then | |
| 1239 | 1247 | all_tests |
| 1240 | 1248 | exit $ret |
| 1241 | 1249 | fi |
| 1242 | 1250 | |
| 1243 | −while getopts 'fsltra64bpch' opt; do | |
| 1251 | +while getopts 'fsltra64bpkch' opt; do | |
| 1244 | 1252 | case $opt in |
| 1245 | 1253 | f) |
| 1246 | 1254 | subflows_tests |
| @@ -1272,9 +1280,11 @@ while getopts 'fsltra64bpch' opt; do · 25 unmodified lines | ||
| 1272 | 1280 | p) |
| 1273 | 1281 | add_addr_ports_tests |
| 1274 | 1282 | ;; |
| 1275 | − c) | |
| 1283 | + k) | |
| 1276 | 1284 | syncookies_tests |
| 1277 | 1285 | ;; |
| 1286 | + c) | |
| 1287 | + ;; | |
| 1278 | 1288 | h | *) |
| 1279 | 1289 | usage |
| 1280 | 1290 | ;; |
| @@ -30,25 +30,25 @@ struct reuse_opts { · 29 unmodified lines | ||
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | 32 | struct reuse_opts unreusable_opts[12] = { |
| 33 | − {0, 0, 0, 0}, | |
| 34 | − {0, 0, 0, 1}, | |
| 35 | − {0, 0, 1, 0}, | |
| 36 | − {0, 0, 1, 1}, | |
| 37 | − {0, 1, 0, 0}, | |
| 38 | − {0, 1, 0, 1}, | |
| 39 | − {0, 1, 1, 0}, | |
| 40 | − {0, 1, 1, 1}, | |
| 41 | − {1, 0, 0, 0}, | |
| 42 | − {1, 0, 0, 1}, | |
| 43 | − {1, 0, 1, 0}, | |
| 44 | − {1, 0, 1, 1}, | |
| 33 | + {{0, 0}, {0, 0}}, | |
| 34 | + {{0, 0}, {0, 1}}, | |
| 35 | + {{0, 0}, {1, 0}}, | |
| 36 | + {{0, 0}, {1, 1}}, | |
| 37 | + {{0, 1}, {0, 0}}, | |
| 38 | + {{0, 1}, {0, 1}}, | |
| 39 | + {{0, 1}, {1, 0}}, | |
| 40 | + {{0, 1}, {1, 1}}, | |
| 41 | + {{1, 0}, {0, 0}}, | |
| 42 | + {{1, 0}, {0, 1}}, | |
| 43 | + {{1, 0}, {1, 0}}, | |
| 44 | + {{1, 0}, {1, 1}}, | |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | 47 | struct reuse_opts reusable_opts[4] = { |
| 48 | − {1, 1, 0, 0}, | |
| 49 | − {1, 1, 0, 1}, | |
| 50 | − {1, 1, 1, 0}, | |
| 51 | − {1, 1, 1, 1}, | |
| 48 | + {{1, 1}, {0, 0}}, | |
| 49 | + {{1, 1}, {0, 1}}, | |
| 50 | + {{1, 1}, {1, 0}}, | |
| 51 | + {{1, 1}, {1, 1}}, | |
| 52 | 52 | }; |
| 53 | 53 | |
| 54 | 54 | int bind_port(struct __test_metadata *_metadata, int reuseaddr, int reuseport) |
| @@ -101,7 +101,7 @@ endef · 100 unmodified lines | ||
| 101 | 101 | ifeq ($(CAN_BUILD_I386),1) |
| 102 | 102 | $(BINARIES_32): CFLAGS += -m32 |
| 103 | 103 | $(BINARIES_32): LDLIBS += -lrt -ldl -lm |
| 104 | −$(BINARIES_32): %_32: %.c | |
| 104 | +$(BINARIES_32): $(OUTPUT)/%_32: %.c | |
| 105 | 105 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@ |
| 106 | 106 | $(foreach t,$(TARGETS),$(eval $(call gen-target-rule-32,$(t)))) |
| 107 | 107 | endif |
| @@ -109,7 +109,7 @@ endif · 1 unmodified line | ||
| 109 | 109 | ifeq ($(CAN_BUILD_X86_64),1) |
| 110 | 110 | $(BINARIES_64): CFLAGS += -m64 |
| 111 | 111 | $(BINARIES_64): LDLIBS += -lrt -ldl |
| 112 | −$(BINARIES_64): %_64: %.c | |
| 112 | +$(BINARIES_64): $(OUTPUT)/%_64: %.c | |
| 113 | 113 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@ |
| 114 | 114 | $(foreach t,$(TARGETS),$(eval $(call gen-target-rule-64,$(t)))) |
| 115 | 115 | endif |