Linux 6.8-rc4 Pulling this for a bugfix upstream with which the gpio/for-next branch conflicts.
Unified · Split
| @@ -289,6 +289,7 @@ Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com> · 288 unmodified lines | |||
| 289 | John Crispin <john@phrozen.org> <blogic@openwrt.org> | 289 | John Crispin <john@phrozen.org> <blogic@openwrt.org> |
| 290 | John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com> | 290 | John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com> |
| 291 | John Keeping <john@keeping.me.uk> <john@metanate.com> | 291 | John Keeping <john@keeping.me.uk> <john@metanate.com> |
| 292 | John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com> | ||
| 292 | John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> | 293 | John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> |
| 293 | John Stultz <johnstul@us.ibm.com> | 294 | John Stultz <johnstul@us.ibm.com> |
| 294 | <jon.toppins+linux@gmail.com> <jtoppins@cumulusnetworks.com> | 295 | <jon.toppins+linux@gmail.com> <jtoppins@cumulusnetworks.com> |
| @@ -344,6 +345,7 @@ Leonid I Ananiev <leonid.i.ananiev@intel.com> · 49 unmodified lines | |||
| 344 | Leon Romanovsky <leon@kernel.org> <leon@leon.nu> | 345 | Leon Romanovsky <leon@kernel.org> <leon@leon.nu> |
| 345 | Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com> | 346 | Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com> |
| 346 | Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com> | 347 | Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com> |
| 348 | Leo Yan <leo.yan@linux.dev> <leo.yan@linaro.org> | ||
| 347 | Liam Mark <quic_lmark@quicinc.com> <lmark@codeaurora.org> | 349 | Liam Mark <quic_lmark@quicinc.com> <lmark@codeaurora.org> |
| 348 | Linas Vepstas <linas@austin.ibm.com> | 350 | Linas Vepstas <linas@austin.ibm.com> |
| 349 | Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch> | 351 | Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch> |
| @@ -2161,6 +2161,19 @@ N: Mike Kravetz · 2160 unmodified lines | |||
| 2161 | E: mike.kravetz@oracle.com | 2161 | E: mike.kravetz@oracle.com |
| 2162 | D: Maintenance and development of the hugetlb subsystem | 2162 | D: Maintenance and development of the hugetlb subsystem |
| 2163 | 2163 | ||
| 2164 | N: Seth Jennings | ||
| 2165 | E: sjenning@redhat.com | ||
| 2166 | D: Creation and maintenance of zswap | ||
| 2167 | |||
| 2168 | N: Dan Streetman | ||
| 2169 | E: ddstreet@ieee.org | ||
| 2170 | D: Maintenance and development of zswap | ||
| 2171 | D: Creation and maintenance of the zpool API | ||
| 2172 | |||
| 2173 | N: Vitaly Wool | ||
| 2174 | E: vitaly.wool@konsulko.com | ||
| 2175 | D: Maintenance and development of zswap | ||
| 2176 | |||
| 2164 | N: Andreas S. Krebs | 2177 | N: Andreas S. Krebs |
| 2165 | E: akrebs@altavista.net | 2178 | E: akrebs@altavista.net |
| 2166 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards | 2179 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards |
| @@ -1,4 +1,4 @@ | |||
| 1 | What: /sys/class/<iface>/queues/rx-<queue>/rps_cpus | 1 | What: /sys/class/net/<iface>/queues/rx-<queue>/rps_cpus |
| 2 | Date: March 2010 | 2 | Date: March 2010 |
| 3 | KernelVersion: 2.6.35 | 3 | KernelVersion: 2.6.35 |
| 4 | Contact: netdev@vger.kernel.org | 4 | Contact: netdev@vger.kernel.org |
| @@ -8,7 +8,7 @@ Description: · 3 unmodified lines | |||
| 8 | network device queue. Possible values depend on the number | 8 | network device queue. Possible values depend on the number |
| 9 | of available CPU(s) in the system. | 9 | of available CPU(s) in the system. |
| 10 | 10 | ||
| 11 | What: /sys/class/<iface>/queues/rx-<queue>/rps_flow_cnt | 11 | What: /sys/class/net/<iface>/queues/rx-<queue>/rps_flow_cnt |
| 12 | Date: April 2010 | 12 | Date: April 2010 |
| 13 | KernelVersion: 2.6.35 | 13 | KernelVersion: 2.6.35 |
| 14 | Contact: netdev@vger.kernel.org | 14 | Contact: netdev@vger.kernel.org |
| @@ -16,7 +16,7 @@ Description: · 1 unmodified line | |||
| 16 | Number of Receive Packet Steering flows being currently | 16 | Number of Receive Packet Steering flows being currently |
| 17 | processed by this particular network device receive queue. | 17 | processed by this particular network device receive queue. |
| 18 | 18 | ||
| 19 | What: /sys/class/<iface>/queues/tx-<queue>/tx_timeout | 19 | What: /sys/class/net/<iface>/queues/tx-<queue>/tx_timeout |
| 20 | Date: November 2011 | 20 | Date: November 2011 |
| 21 | KernelVersion: 3.3 | 21 | KernelVersion: 3.3 |
| 22 | Contact: netdev@vger.kernel.org | 22 | Contact: netdev@vger.kernel.org |
| @@ -24,7 +24,7 @@ Description: · 1 unmodified line | |||
| 24 | Indicates the number of transmit timeout events seen by this | 24 | Indicates the number of transmit timeout events seen by this |
| 25 | network interface transmit queue. | 25 | network interface transmit queue. |
| 26 | 26 | ||
| 27 | What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate | 27 | What: /sys/class/net/<iface>/queues/tx-<queue>/tx_maxrate |
| 28 | Date: March 2015 | 28 | Date: March 2015 |
| 29 | KernelVersion: 4.1 | 29 | KernelVersion: 4.1 |
| 30 | Contact: netdev@vger.kernel.org | 30 | Contact: netdev@vger.kernel.org |
| @@ -32,7 +32,7 @@ Description: · 1 unmodified line | |||
| 32 | A Mbps max-rate set for the queue, a value of zero means disabled, | 32 | A Mbps max-rate set for the queue, a value of zero means disabled, |
| 33 | default is disabled. | 33 | default is disabled. |
| 34 | 34 | ||
| 35 | What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus | 35 | What: /sys/class/net/<iface>/queues/tx-<queue>/xps_cpus |
| 36 | Date: November 2010 | 36 | Date: November 2010 |
| 37 | KernelVersion: 2.6.38 | 37 | KernelVersion: 2.6.38 |
| 38 | Contact: netdev@vger.kernel.org | 38 | Contact: netdev@vger.kernel.org |
| @@ -42,7 +42,7 @@ Description: · 3 unmodified lines | |||
| 42 | network device transmit queue. Possible values depend on the | 42 | network device transmit queue. Possible values depend on the |
| 43 | number of available CPU(s) in the system. | 43 | number of available CPU(s) in the system. |
| 44 | 44 | ||
| 45 | What: /sys/class/<iface>/queues/tx-<queue>/xps_rxqs | 45 | What: /sys/class/net/<iface>/queues/tx-<queue>/xps_rxqs |
| 46 | Date: June 2018 | 46 | Date: June 2018 |
| 47 | KernelVersion: 4.18.0 | 47 | KernelVersion: 4.18.0 |
| 48 | Contact: netdev@vger.kernel.org | 48 | Contact: netdev@vger.kernel.org |
| @@ -53,7 +53,7 @@ Description: · 4 unmodified lines | |||
| 53 | number of available receive queue(s) in the network device. | 53 | number of available receive queue(s) in the network device. |
| 54 | Default is disabled. | 54 | Default is disabled. |
| 55 | 55 | ||
| 56 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time | 56 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time |
| 57 | Date: November 2011 | 57 | Date: November 2011 |
| 58 | KernelVersion: 3.3 | 58 | KernelVersion: 3.3 |
| 59 | Contact: netdev@vger.kernel.org | 59 | Contact: netdev@vger.kernel.org |
| @@ -62,7 +62,7 @@ Description: · 2 unmodified lines | |||
| 62 | of this particular network device transmit queue. | 62 | of this particular network device transmit queue. |
| 63 | Default value is 1000. | 63 | Default value is 1000. |
| 64 | 64 | ||
| 65 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/inflight | 65 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/inflight |
| 66 | Date: November 2011 | 66 | Date: November 2011 |
| 67 | KernelVersion: 3.3 | 67 | KernelVersion: 3.3 |
| 68 | Contact: netdev@vger.kernel.org | 68 | Contact: netdev@vger.kernel.org |
| @@ -70,7 +70,7 @@ Description: · 1 unmodified line | |||
| 70 | Indicates the number of bytes (objects) in flight on this | 70 | Indicates the number of bytes (objects) in flight on this |
| 71 | network device transmit queue. | 71 | network device transmit queue. |
| 72 | 72 | ||
| 73 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit | 73 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit |
| 74 | Date: November 2011 | 74 | Date: November 2011 |
| 75 | KernelVersion: 3.3 | 75 | KernelVersion: 3.3 |
| 76 | Contact: netdev@vger.kernel.org | 76 | Contact: netdev@vger.kernel.org |
| @@ -79,7 +79,7 @@ Description: · 2 unmodified lines | |||
| 79 | on this network device transmit queue. This value is clamped | 79 | on this network device transmit queue. This value is clamped |
| 80 | to be within the bounds defined by limit_max and limit_min. | 80 | to be within the bounds defined by limit_max and limit_min. |
| 81 | 81 | ||
| 82 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max | 82 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max |
| 83 | Date: November 2011 | 83 | Date: November 2011 |
| 84 | KernelVersion: 3.3 | 84 | KernelVersion: 3.3 |
| 85 | Contact: netdev@vger.kernel.org | 85 | Contact: netdev@vger.kernel.org |
| @@ -88,7 +88,7 @@ Description: · 2 unmodified lines | |||
| 88 | queued on this network device transmit queue. See | 88 | queued on this network device transmit queue. See |
| 89 | include/linux/dynamic_queue_limits.h for the default value. | 89 | include/linux/dynamic_queue_limits.h for the default value. |
| 90 | 90 | ||
| 91 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min | 91 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min |
| 92 | Date: November 2011 | 92 | Date: November 2011 |
| 93 | KernelVersion: 3.3 | 93 | KernelVersion: 3.3 |
| 94 | Contact: netdev@vger.kernel.org | 94 | Contact: netdev@vger.kernel.org |
| @@ -1,4 +1,4 @@ | |||
| 1 | What: /sys/devices/.../hwmon/hwmon<i>/in0_input | 1 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/in0_input |
| 2 | Date: February 2023 | 2 | Date: February 2023 |
| 3 | KernelVersion: 6.2 | 3 | KernelVersion: 6.2 |
| 4 | Contact: intel-gfx@lists.freedesktop.org | 4 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -6,7 +6,7 @@ Description: RO. Current Voltage in millivolt. · 1 unmodified line | |||
| 6 | 6 | ||
| 7 | Only supported for particular Intel i915 graphics platforms. | 7 | Only supported for particular Intel i915 graphics platforms. |
| 8 | 8 | ||
| 9 | What: /sys/devices/.../hwmon/hwmon<i>/power1_max | 9 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_max |
| 10 | Date: February 2023 | 10 | Date: February 2023 |
| 11 | KernelVersion: 6.2 | 11 | KernelVersion: 6.2 |
| 12 | Contact: intel-gfx@lists.freedesktop.org | 12 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -20,7 +20,7 @@ Description: RW. Card reactive sustained (PL1/Tau) power limit in microwatts. · 7 unmodified lines | |||
| 20 | 20 | ||
| 21 | Only supported for particular Intel i915 graphics platforms. | 21 | Only supported for particular Intel i915 graphics platforms. |
| 22 | 22 | ||
| 23 | What: /sys/devices/.../hwmon/hwmon<i>/power1_rated_max | 23 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_rated_max |
| 24 | Date: February 2023 | 24 | Date: February 2023 |
| 25 | KernelVersion: 6.2 | 25 | KernelVersion: 6.2 |
| 26 | Contact: intel-gfx@lists.freedesktop.org | 26 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -28,7 +28,7 @@ Description: RO. Card default power limit (default TDP setting). · 1 unmodified line | |||
| 28 | 28 | ||
| 29 | Only supported for particular Intel i915 graphics platforms. | 29 | Only supported for particular Intel i915 graphics platforms. |
| 30 | 30 | ||
| 31 | What: /sys/devices/.../hwmon/hwmon<i>/power1_max_interval | 31 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_max_interval |
| 32 | Date: February 2023 | 32 | Date: February 2023 |
| 33 | KernelVersion: 6.2 | 33 | KernelVersion: 6.2 |
| 34 | Contact: intel-gfx@lists.freedesktop.org | 34 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -37,7 +37,7 @@ Description: RW. Sustained power limit interval (Tau in PL1/Tau) in · 2 unmodified lines | |||
| 37 | 37 | ||
| 38 | Only supported for particular Intel i915 graphics platforms. | 38 | Only supported for particular Intel i915 graphics platforms. |
| 39 | 39 | ||
| 40 | What: /sys/devices/.../hwmon/hwmon<i>/power1_crit | 40 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_crit |
| 41 | Date: February 2023 | 41 | Date: February 2023 |
| 42 | KernelVersion: 6.2 | 42 | KernelVersion: 6.2 |
| 43 | Contact: intel-gfx@lists.freedesktop.org | 43 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -50,7 +50,7 @@ Description: RW. Card reactive critical (I1) power limit in microwatts. · 6 unmodified lines | |||
| 50 | 50 | ||
| 51 | Only supported for particular Intel i915 graphics platforms. | 51 | Only supported for particular Intel i915 graphics platforms. |
| 52 | 52 | ||
| 53 | What: /sys/devices/.../hwmon/hwmon<i>/curr1_crit | 53 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/curr1_crit |
| 54 | Date: February 2023 | 54 | Date: February 2023 |
| 55 | KernelVersion: 6.2 | 55 | KernelVersion: 6.2 |
| 56 | Contact: intel-gfx@lists.freedesktop.org | 56 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -63,7 +63,7 @@ Description: RW. Card reactive critical (I1) power limit in milliamperes. · 6 unmodified lines | |||
| 63 | 63 | ||
| 64 | Only supported for particular Intel i915 graphics platforms. | 64 | Only supported for particular Intel i915 graphics platforms. |
| 65 | 65 | ||
| 66 | What: /sys/devices/.../hwmon/hwmon<i>/energy1_input | 66 | What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/energy1_input |
| 67 | Date: February 2023 | 67 | Date: February 2023 |
| 68 | KernelVersion: 6.2 | 68 | KernelVersion: 6.2 |
| 69 | Contact: intel-gfx@lists.freedesktop.org | 69 | Contact: intel-gfx@lists.freedesktop.org |
| @@ -1,4 +1,4 @@ | |||
| 1 | What: /sys/devices/.../hwmon/hwmon<i>/power1_max | 1 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_max |
| 2 | Date: September 2023 | 2 | Date: September 2023 |
| 3 | KernelVersion: 6.5 | 3 | KernelVersion: 6.5 |
| 4 | Contact: intel-xe@lists.freedesktop.org | 4 | Contact: intel-xe@lists.freedesktop.org |
| @@ -12,7 +12,7 @@ Description: RW. Card reactive sustained (PL1) power limit in microwatts. · 7 unmodified lines | |||
| 12 | 12 | ||
| 13 | Only supported for particular Intel xe graphics platforms. | 13 | Only supported for particular Intel xe graphics platforms. |
| 14 | 14 | ||
| 15 | What: /sys/devices/.../hwmon/hwmon<i>/power1_rated_max | 15 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_rated_max |
| 16 | Date: September 2023 | 16 | Date: September 2023 |
| 17 | KernelVersion: 6.5 | 17 | KernelVersion: 6.5 |
| 18 | Contact: intel-xe@lists.freedesktop.org | 18 | Contact: intel-xe@lists.freedesktop.org |
| @@ -20,7 +20,7 @@ Description: RO. Card default power limit (default TDP setting). · 1 unmodified line | |||
| 20 | 20 | ||
| 21 | Only supported for particular Intel xe graphics platforms. | 21 | Only supported for particular Intel xe graphics platforms. |
| 22 | 22 | ||
| 23 | What: /sys/devices/.../hwmon/hwmon<i>/power1_crit | 23 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_crit |
| 24 | Date: September 2023 | 24 | Date: September 2023 |
| 25 | KernelVersion: 6.5 | 25 | KernelVersion: 6.5 |
| 26 | Contact: intel-xe@lists.freedesktop.org | 26 | Contact: intel-xe@lists.freedesktop.org |
| @@ -33,7 +33,7 @@ Description: RW. Card reactive critical (I1) power limit in microwatts. · 6 unmodified lines | |||
| 33 | 33 | ||
| 34 | Only supported for particular Intel xe graphics platforms. | 34 | Only supported for particular Intel xe graphics platforms. |
| 35 | 35 | ||
| 36 | What: /sys/devices/.../hwmon/hwmon<i>/curr1_crit | 36 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/curr1_crit |
| 37 | Date: September 2023 | 37 | Date: September 2023 |
| 38 | KernelVersion: 6.5 | 38 | KernelVersion: 6.5 |
| 39 | Contact: intel-xe@lists.freedesktop.org | 39 | Contact: intel-xe@lists.freedesktop.org |
| @@ -44,7 +44,7 @@ Description: RW. Card reactive critical (I1) power limit in milliamperes. · 4 unmodified lines | |||
| 44 | the operating frequency if the power averaged over a window | 44 | the operating frequency if the power averaged over a window |
| 45 | exceeds this limit. | 45 | exceeds this limit. |
| 46 | 46 | ||
| 47 | What: /sys/devices/.../hwmon/hwmon<i>/in0_input | 47 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/in0_input |
| 48 | Date: September 2023 | 48 | Date: September 2023 |
| 49 | KernelVersion: 6.5 | 49 | KernelVersion: 6.5 |
| 50 | Contact: intel-xe@lists.freedesktop.org | 50 | Contact: intel-xe@lists.freedesktop.org |
| @@ -52,7 +52,7 @@ Description: RO. Current Voltage in millivolt. · 1 unmodified line | |||
| 52 | 52 | ||
| 53 | Only supported for particular Intel xe graphics platforms. | 53 | Only supported for particular Intel xe graphics platforms. |
| 54 | 54 | ||
| 55 | What: /sys/devices/.../hwmon/hwmon<i>/energy1_input | 55 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/energy1_input |
| 56 | Date: September 2023 | 56 | Date: September 2023 |
| 57 | KernelVersion: 6.5 | 57 | KernelVersion: 6.5 |
| 58 | Contact: intel-xe@lists.freedesktop.org | 58 | Contact: intel-xe@lists.freedesktop.org |
| @@ -60,7 +60,7 @@ Description: RO. Energy input of device in microjoules. · 1 unmodified line | |||
| 60 | 60 | ||
| 61 | Only supported for particular Intel xe graphics platforms. | 61 | Only supported for particular Intel xe graphics platforms. |
| 62 | 62 | ||
| 63 | What: /sys/devices/.../hwmon/hwmon<i>/power1_max_interval | 63 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_max_interval |
| 64 | Date: October 2023 | 64 | Date: October 2023 |
| 65 | KernelVersion: 6.6 | 65 | KernelVersion: 6.6 |
| 66 | Contact: intel-xe@lists.freedesktop.org | 66 | Contact: intel-xe@lists.freedesktop.org |
| @@ -10,6 +10,7 @@ What: /sys/devices/platform/silicom-platform/power_cycle · 9 unmodified lines | |||
| 10 | Date: November 2023 | 10 | Date: November 2023 |
| 11 | KernelVersion: 6.7 | 11 | KernelVersion: 6.7 |
| 12 | Contact: Henry Shi <henrys@silicom-usa.com> | 12 | Contact: Henry Shi <henrys@silicom-usa.com> |
| 13 | Description: | ||
| 13 | This file allow user to power cycle the platform. | 14 | This file allow user to power cycle the platform. |
| 14 | Default value is 0; when set to 1, it powers down | 15 | Default value is 0; when set to 1, it powers down |
| 15 | the platform, waits 5 seconds, then powers on the | 16 | the platform, waits 5 seconds, then powers on the |
| @@ -101,8 +101,8 @@ External References · 100 unmodified lines | |||
| 101 | email threads | 101 | email threads |
| 102 | ------------- | 102 | ------------- |
| 103 | 103 | ||
| 104 | * `Initial discussion on the New subsystem for acceleration devices <https://lkml.org/lkml/2022/7/31/83>`_ - Oded Gabbay (2022) | 104 | * `Initial discussion on the New subsystem for acceleration devices <https://lore.kernel.org/lkml/CAFCwf11=9qpNAepL7NL+YAV_QO=Wv6pnWPhKHKAepK3fNn+2Dg@mail.gmail.com/>`_ - Oded Gabbay (2022) |
| 105 | * `patch-set to add the new subsystem <https://lkml.org/lkml/2022/10/22/544>`_ - Oded Gabbay (2022) | 105 | * `patch-set to add the new subsystem <https://lore.kernel.org/lkml/20221022214622.18042-1-ogabbay@kernel.org/>`_ - Oded Gabbay (2022) |
| 106 | 106 | ||
| 107 | Conference talks | 107 | Conference talks |
| 108 | ---------------- | 108 | ---------------- |
| @@ -218,8 +218,3 @@ bytes respectively. Such letter suffixes can also be entirely omitted: · 217 unmodified lines | |||
| 218 | 218 | ||
| 219 | .. include:: kernel-parameters.txt | 219 | .. include:: kernel-parameters.txt |
| 220 | :literal: | 220 | :literal: |
| 221 | |||
| 222 | Todo | ||
| 223 | ---- | ||
| 224 | |||
| 225 | Add more DRM drivers. | ||
| @@ -243,13 +243,9 @@ To reduce its OS jitter, do any of the following: · 242 unmodified lines | |||
| 243 | 3. Do any of the following needed to avoid jitter that your | 243 | 3. Do any of the following needed to avoid jitter that your |
| 244 | application cannot tolerate: | 244 | application cannot tolerate: |
| 245 | 245 | ||
| 246 | a. Build your kernel with CONFIG_SLUB=y rather than | 246 | a. Avoid using oprofile, thus avoiding OS jitter from |
| 247 | CONFIG_SLAB=y, thus avoiding the slab allocator's periodic | ||
| 248 | use of each CPU's workqueues to run its cache_reap() | ||
| 249 | function. | ||
| 250 | b. Avoid using oprofile, thus avoiding OS jitter from | ||
| 251 | wq_sync_buffer(). | 247 | wq_sync_buffer(). |
| 252 | c. Limit your CPU frequency so that a CPU-frequency | 248 | b. Limit your CPU frequency so that a CPU-frequency |
| 253 | governor is not required, possibly enlisting the aid of | 249 | governor is not required, possibly enlisting the aid of |
| 254 | special heatsinks or other cooling technologies. If done | 250 | special heatsinks or other cooling technologies. If done |
| 255 | correctly, and if you CPU architecture permits, you should | 251 | correctly, and if you CPU architecture permits, you should |
| @@ -259,7 +255,7 @@ To reduce its OS jitter, do any of the following: · 3 unmodified lines | |||
| 259 | 255 | ||
| 260 | WARNING: Please check your CPU specifications to | 256 | WARNING: Please check your CPU specifications to |
| 261 | make sure that this is safe on your particular system. | 257 | make sure that this is safe on your particular system. |
| 262 | d. As of v3.18, Christoph Lameter's on-demand vmstat workers | 258 | c. As of v3.18, Christoph Lameter's on-demand vmstat workers |
| 263 | commit prevents OS jitter due to vmstat_update() on | 259 | commit prevents OS jitter due to vmstat_update() on |
| 264 | CONFIG_SMP=y systems. Before v3.18, is not possible | 260 | CONFIG_SMP=y systems. Before v3.18, is not possible |
| 265 | to entirely get rid of the OS jitter, but you can | 261 | to entirely get rid of the OS jitter, but you can |
| @@ -274,7 +270,7 @@ To reduce its OS jitter, do any of the following: · 8 unmodified lines | |||
| 274 | (based on an earlier one from Gilad Ben-Yossef) that | 270 | (based on an earlier one from Gilad Ben-Yossef) that |
| 275 | reduces or even eliminates vmstat overhead for some | 271 | reduces or even eliminates vmstat overhead for some |
| 276 | workloads at https://lore.kernel.org/r/00000140e9dfd6bd-40db3d4f-c1be-434f-8132-7820f81bb586-000000@email.amazonses.com. | 272 | workloads at https://lore.kernel.org/r/00000140e9dfd6bd-40db3d4f-c1be-434f-8132-7820f81bb586-000000@email.amazonses.com. |
| 277 | e. If running on high-end powerpc servers, build with | 273 | d. If running on high-end powerpc servers, build with |
| 278 | CONFIG_PPC_RTAS_DAEMON=n. This prevents the RTAS | 274 | CONFIG_PPC_RTAS_DAEMON=n. This prevents the RTAS |
| 279 | daemon from running on each CPU every second or so. | 275 | daemon from running on each CPU every second or so. |
| 280 | (This will require editing Kconfig files and will defeat | 276 | (This will require editing Kconfig files and will defeat |
| @@ -282,12 +278,12 @@ To reduce its OS jitter, do any of the following: · 1 unmodified line | |||
| 282 | due to the rtas_event_scan() function. | 278 | due to the rtas_event_scan() function. |
| 283 | WARNING: Please check your CPU specifications to | 279 | WARNING: Please check your CPU specifications to |
| 284 | make sure that this is safe on your particular system. | 280 | make sure that this is safe on your particular system. |
| 285 | f. If running on Cell Processor, build your kernel with | 281 | e. If running on Cell Processor, build your kernel with |
| 286 | CBE_CPUFREQ_SPU_GOVERNOR=n to avoid OS jitter from | 282 | CBE_CPUFREQ_SPU_GOVERNOR=n to avoid OS jitter from |
| 287 | spu_gov_work(). | 283 | spu_gov_work(). |
| 288 | WARNING: Please check your CPU specifications to | 284 | WARNING: Please check your CPU specifications to |
| 289 | make sure that this is safe on your particular system. | 285 | make sure that this is safe on your particular system. |
| 290 | g. If running on PowerMAC, build your kernel with | 286 | f. If running on PowerMAC, build your kernel with |
| 291 | CONFIG_PMAC_RACKMETER=n to disable the CPU-meter, | 287 | CONFIG_PMAC_RACKMETER=n to disable the CPU-meter, |
| 292 | avoiding OS jitter from rackmeter_do_timer(). | 288 | avoiding OS jitter from rackmeter_do_timer(). |
| 293 | 289 | ||
| @@ -671,8 +671,23 @@ Testing Static Functions · 670 unmodified lines | |||
| 671 | ------------------------ | 671 | ------------------------ |
| 672 | 672 | ||
| 673 | If we do not want to expose functions or variables for testing, one option is to | 673 | If we do not want to expose functions or variables for testing, one option is to |
| 674 | conditionally ``#include`` the test file at the end of your .c file. For | 674 | conditionally export the used symbol. For example: |
| 675 | example: | 675 | |
| 676 | .. code-block:: c | ||
| 677 | |||
| 678 | /* In my_file.c */ | ||
| 679 | |||
| 680 | VISIBLE_IF_KUNIT int do_interesting_thing(); | ||
| 681 | EXPORT_SYMBOL_IF_KUNIT(do_interesting_thing); | ||
| 682 | |||
| 683 | /* In my_file.h */ | ||
| 684 | |||
| 685 | #if IS_ENABLED(CONFIG_KUNIT) | ||
| 686 | int do_interesting_thing(void); | ||
| 687 | #endif | ||
| 688 | |||
| 689 | Alternatively, you could conditionally ``#include`` the test file at the end of | ||
| 690 | your .c file. For example: | ||
| 676 | 691 | ||
| 677 | .. code-block:: c | 692 | .. code-block:: c |
| 678 | 693 | ||
| @@ -85,7 +85,7 @@ allOf: · 84 unmodified lines | |||
| 85 | clocks: | 85 | clocks: |
| 86 | minItems: 6 | 86 | minItems: 6 |
| 87 | maxItems: 6 | 87 | maxItems: 6 |
| 88 | regs: | 88 | reg: |
| 89 | minItems: 2 | 89 | minItems: 2 |
| 90 | maxItems: 2 | 90 | maxItems: 2 |
| 91 | 91 | ||
| @@ -99,7 +99,7 @@ allOf: · 7 unmodified lines | |||
| 99 | clocks: | 99 | clocks: |
| 100 | minItems: 4 | 100 | minItems: 4 |
| 101 | maxItems: 4 | 101 | maxItems: 4 |
| 102 | regs: | 102 | reg: |
| 103 | minItems: 2 | 103 | minItems: 2 |
| 104 | maxItems: 2 | 104 | maxItems: 2 |
| 105 | 105 | ||
| @@ -116,7 +116,7 @@ allOf: · 10 unmodified lines | |||
| 116 | clocks: | 116 | clocks: |
| 117 | minItems: 3 | 117 | minItems: 3 |
| 118 | maxItems: 3 | 118 | maxItems: 3 |
| 119 | regs: | 119 | reg: |
| 120 | minItems: 1 | 120 | minItems: 1 |
| 121 | maxItems: 1 | 121 | maxItems: 1 |
| 122 | 122 | ||
| @@ -17,7 +17,7 @@ properties: · 16 unmodified lines | |||
| 17 | compatible: | 17 | compatible: |
| 18 | items: | 18 | items: |
| 19 | - enum: | 19 | - enum: |
| 20 | - ti,k3-j721s2-wave521c | 20 | - ti,j721s2-wave521c |
| 21 | - const: cnm,wave521c | 21 | - const: cnm,wave521c |
| 22 | 22 | ||
| 23 | reg: | 23 | reg: |
| @@ -53,7 +53,7 @@ additionalProperties: false · 29 unmodified lines | |||
| 53 | examples: | 53 | examples: |
| 54 | - | | 54 | - | |
| 55 | vpu: video-codec@12345678 { | 55 | vpu: video-codec@12345678 { |
| 56 | compatible = "ti,k3-j721s2-wave521c", "cnm,wave521c"; | 56 | compatible = "ti,j721s2-wave521c", "cnm,wave521c"; |
| 57 | reg = <0x12345678 0x1000>; | 57 | reg = <0x12345678 0x1000>; |
| 58 | clocks = <&clks 42>; | 58 | clocks = <&clks 42>; |
| 59 | interrupts = <42>; | 59 | interrupts = <42>; |
| @@ -22,6 +22,7 @@ properties: · 21 unmodified lines | |||
| 22 | - const: allwinner,sun6i-a31-spdif | 22 | - const: allwinner,sun6i-a31-spdif |
| 23 | - const: allwinner,sun8i-h3-spdif | 23 | - const: allwinner,sun8i-h3-spdif |
| 24 | - const: allwinner,sun50i-h6-spdif | 24 | - const: allwinner,sun50i-h6-spdif |
| 25 | - const: allwinner,sun50i-h616-spdif | ||
| 25 | - items: | 26 | - items: |
| 26 | - const: allwinner,sun8i-a83t-spdif | 27 | - const: allwinner,sun8i-a83t-spdif |
| 27 | - const: allwinner,sun8i-h3-spdif | 28 | - const: allwinner,sun8i-h3-spdif |
| @@ -62,6 +63,8 @@ allOf: · 34 unmodified lines | |||
| 62 | enum: | 63 | enum: |
| 63 | - allwinner,sun6i-a31-spdif | 64 | - allwinner,sun6i-a31-spdif |
| 64 | - allwinner,sun8i-h3-spdif | 65 | - allwinner,sun8i-h3-spdif |
| 66 | - allwinner,sun50i-h6-spdif | ||
| 67 | - allwinner,sun50i-h616-spdif | ||
| 65 | 68 | ||
| 66 | then: | 69 | then: |
| 67 | required: | 70 | required: |
| @@ -73,7 +76,7 @@ allOf: · 5 unmodified lines | |||
| 73 | contains: | 76 | contains: |
| 74 | enum: | 77 | enum: |
| 75 | - allwinner,sun8i-h3-spdif | 78 | - allwinner,sun8i-h3-spdif |
| 76 | - allwinner,sun50i-h6-spdif | 79 | - allwinner,sun50i-h616-spdif |
| 77 | 80 | ||
| 78 | then: | 81 | then: |
| 79 | properties: | 82 | properties: |
| @@ -145,7 +145,9 @@ filesystem, an overlay filesystem needs to record in the upper filesystem · 144 unmodified lines | |||
| 145 | that files have been removed. This is done using whiteouts and opaque | 145 | that files have been removed. This is done using whiteouts and opaque |
| 146 | directories (non-directories are always opaque). | 146 | directories (non-directories are always opaque). |
| 147 | 147 | ||
| 148 | A whiteout is created as a character device with 0/0 device number. | 148 | A whiteout is created as a character device with 0/0 device number or |
| 149 | as a zero-size regular file with the xattr "trusted.overlay.whiteout". | ||
| 150 | |||
| 149 | When a whiteout is found in the upper level of a merged directory, any | 151 | When a whiteout is found in the upper level of a merged directory, any |
| 150 | matching name in the lower level is ignored, and the whiteout itself | 152 | matching name in the lower level is ignored, and the whiteout itself |
| 151 | is also hidden. | 153 | is also hidden. |
| @@ -154,6 +156,13 @@ A directory is made opaque by setting the xattr "trusted.overlay.opaque" · 2 unmodified lines | |||
| 154 | to "y". Where the upper filesystem contains an opaque directory, any | 156 | to "y". Where the upper filesystem contains an opaque directory, any |
| 155 | directory in the lower filesystem with the same name is ignored. | 157 | directory in the lower filesystem with the same name is ignored. |
| 156 | 158 | ||
| 159 | An opaque directory should not conntain any whiteouts, because they do not | ||
| 160 | serve any purpose. A merge directory containing regular files with the xattr | ||
| 161 | "trusted.overlay.whiteout", should be additionally marked by setting the xattr | ||
| 162 | "trusted.overlay.opaque" to "x" on the merge directory itself. | ||
| 163 | This is needed to avoid the overhead of checking the "trusted.overlay.whiteout" | ||
| 164 | on all entries during readdir in the common case. | ||
| 165 | |||
| 157 | readdir | 166 | readdir |
| 158 | ------- | 167 | ------- |
| 159 | 168 | ||
| @@ -534,8 +543,9 @@ A lower dir with a regular whiteout will always be handled by the overlayfs · 374 unmodified lines | |||
| 534 | mount, so to support storing an effective whiteout file in an overlayfs mount an | 543 | mount, so to support storing an effective whiteout file in an overlayfs mount an |
| 535 | alternative form of whiteout is supported. This form is a regular, zero-size | 544 | alternative form of whiteout is supported. This form is a regular, zero-size |
| 536 | file with the "overlay.whiteout" xattr set, inside a directory with the | 545 | file with the "overlay.whiteout" xattr set, inside a directory with the |
| 537 | "overlay.whiteouts" xattr set. Such whiteouts are never created by overlayfs, | 546 | "overlay.opaque" xattr set to "x" (see `whiteouts and opaque directories`_). |
| 538 | but can be used by userspace tools (like containers) that generate lower layers. | 547 | These alternative whiteouts are never created by overlayfs, but can be used by |
| 548 | userspace tools (like containers) that generate lower layers. | ||
| 539 | These alternative whiteouts can be escaped using the standard xattr escape | 549 | These alternative whiteouts can be escaped using the standard xattr escape |
| 540 | mechanism in order to properly nest to any depth. | 550 | mechanism in order to properly nest to any depth. |
| 541 | 551 | ||
| @@ -942,6 +942,10 @@ attribute-sets: · 941 unmodified lines | |||
| 942 | - | 942 | - |
| 943 | name: gro-ipv4-max-size | 943 | name: gro-ipv4-max-size |
| 944 | type: u32 | 944 | type: u32 |
| 945 | - | ||
| 946 | name: dpll-pin | ||
| 947 | type: nest | ||
| 948 | nested-attributes: link-dpll-pin-attrs | ||
| 945 | - | 949 | - |
| 946 | name: af-spec-attrs | 950 | name: af-spec-attrs |
| 947 | attributes: | 951 | attributes: |
| @@ -1627,6 +1631,12 @@ attribute-sets: · 679 unmodified lines | |||
| 1627 | - | 1631 | - |
| 1628 | name: used | 1632 | name: used |
| 1629 | type: u8 | 1633 | type: u8 |
| 1634 | - | ||
| 1635 | name: link-dpll-pin-attrs | ||
| 1636 | attributes: | ||
| 1637 | - | ||
| 1638 | name: id | ||
| 1639 | type: u32 | ||
| 1630 | 1640 | ||
| 1631 | sub-messages: | 1641 | sub-messages: |
| 1632 | - | 1642 | - |
| @@ -12,5 +12,7 @@ · 11 unmodified lines | |||
| 12 | <script type="text/javascript"> <!-- | 12 | <script type="text/javascript"> <!-- |
| 13 | var sbar = document.getElementsByClassName("sphinxsidebar")[0]; | 13 | var sbar = document.getElementsByClassName("sphinxsidebar")[0]; |
| 14 | let currents = document.getElementsByClassName("current") | 14 | let currents = document.getElementsByClassName("current") |
| 15 | sbar.scrollTop = currents[currents.length - 1].offsetTop; | 15 | if (currents.length) { |
| 16 | sbar.scrollTop = currents[currents.length - 1].offsetTop; | ||
| 17 | } | ||
| 16 | --> </script> | 18 | --> </script> |
| @@ -448,17 +448,17 @@ Function-specific configfs interface · 447 unmodified lines | |||
| 448 | The function name to use when creating the function directory is "ncm". | 448 | The function name to use when creating the function directory is "ncm". |
| 449 | The NCM function provides these attributes in its function directory: | 449 | The NCM function provides these attributes in its function directory: |
| 450 | 450 | ||
| 451 | =============== ================================================== | 451 | ======================= ================================================== |
| 452 | ifname network device interface name associated with this | 452 | ifname network device interface name associated with this |
| 453 | function instance | 453 | function instance |
| 454 | qmult queue length multiplier for high and super speed | 454 | qmult queue length multiplier for high and super speed |
| 455 | host_addr MAC address of host's end of this | 455 | host_addr MAC address of host's end of this |
| 456 | Ethernet over USB link | 456 | Ethernet over USB link |
| 457 | dev_addr MAC address of device's end of this | 457 | dev_addr MAC address of device's end of this |
| 458 | Ethernet over USB link | 458 | Ethernet over USB link |
| 459 | max_segment_size Segment size required for P2P connections. This | 459 | max_segment_size Segment size required for P2P connections. This |
| 460 | will set MTU to (max_segment_size - 14 bytes) | 460 | will set MTU to 14 bytes |
| 461 | =============== ================================================== | 461 | ======================= ================================================== |
| 462 | 462 | ||
| 463 | and after creating the functions/ncm.<instance name> they contain default | 463 | and after creating the functions/ncm.<instance name> they contain default |
| 464 | values: qmult is 5, dev_addr and host_addr are randomly selected. | 464 | values: qmult is 5, dev_addr and host_addr are randomly selected. |
| @@ -3168,10 +3168,10 @@ F: drivers/hwmon/asus-ec-sensors.c · 3167 unmodified lines | |||
| 3168 | 3168 | ||
| 3169 | ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS | 3169 | ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS |
| 3170 | M: Corentin Chary <corentin.chary@gmail.com> | 3170 | M: Corentin Chary <corentin.chary@gmail.com> |
| 3171 | L: acpi4asus-user@lists.sourceforge.net | 3171 | M: Luke D. Jones <luke@ljones.dev> |
| 3172 | L: platform-driver-x86@vger.kernel.org | 3172 | L: platform-driver-x86@vger.kernel.org |
| 3173 | S: Maintained | 3173 | S: Maintained |
| 3174 | W: http://acpi4asus.sf.net | 3174 | W: https://asus-linux.org/ |
| 3175 | F: drivers/platform/x86/asus*.c | 3175 | F: drivers/platform/x86/asus*.c |
| 3176 | F: drivers/platform/x86/eeepc*.c | 3176 | F: drivers/platform/x86/eeepc*.c |
| 3177 | 3177 | ||
| @@ -4169,14 +4169,14 @@ F: drivers/firmware/broadcom/tee_bnxt_fw.c · 991 unmodified lines | |||
| 4169 | F: drivers/net/ethernet/broadcom/bnxt/ | 4169 | F: drivers/net/ethernet/broadcom/bnxt/ |
| 4170 | F: include/linux/firmware/broadcom/tee_bnxt_fw.h | 4170 | F: include/linux/firmware/broadcom/tee_bnxt_fw.h |
| 4171 | 4171 | ||
| 4172 | BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER | 4172 | BROADCOM BRCM80211 IEEE802.11 WIRELESS DRIVERS |
| 4173 | M: Arend van Spriel <aspriel@gmail.com> | 4173 | M: Arend van Spriel <arend.vanspriel@broadcom.com> |
| 4174 | M: Franky Lin <franky.lin@broadcom.com> | ||
| 4175 | M: Hante Meuleman <hante.meuleman@broadcom.com> | ||
| 4176 | L: linux-wireless@vger.kernel.org | 4174 | L: linux-wireless@vger.kernel.org |
| 4175 | L: brcm80211@lists.linux.dev | ||
| 4177 | L: brcm80211-dev-list.pdl@broadcom.com | 4176 | L: brcm80211-dev-list.pdl@broadcom.com |
| 4178 | S: Supported | 4177 | S: Supported |
| 4179 | F: drivers/net/wireless/broadcom/brcm80211/ | 4178 | F: drivers/net/wireless/broadcom/brcm80211/ |
| 4179 | F: include/linux/platform_data/brcmfmac.h | ||
| 4180 | 4180 | ||
| 4181 | BROADCOM BRCMSTB GPIO DRIVER | 4181 | BROADCOM BRCMSTB GPIO DRIVER |
| 4182 | M: Doug Berger <opendmb@gmail.com> | 4182 | M: Doug Berger <opendmb@gmail.com> |
| @@ -4547,7 +4547,7 @@ F: drivers/net/ieee802154/ca8210.c · 364 unmodified lines | |||
| 4547 | 4547 | ||
| 4548 | CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS | 4548 | CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS |
| 4549 | M: David Howells <dhowells@redhat.com> | 4549 | M: David Howells <dhowells@redhat.com> |
| 4550 | L: linux-cachefs@redhat.com (moderated for non-subscribers) | 4550 | L: netfs@lists.linux.dev |
| 4551 | S: Supported | 4551 | S: Supported |
| 4552 | F: Documentation/filesystems/caching/cachefiles.rst | 4552 | F: Documentation/filesystems/caching/cachefiles.rst |
| 4553 | F: fs/cachefiles/ | 4553 | F: fs/cachefiles/ |
| @@ -5958,7 +5958,6 @@ S: Maintained · 1404 unmodified lines | |||
| 5958 | F: drivers/platform/x86/dell/dell-wmi-descriptor.c | 5958 | F: drivers/platform/x86/dell/dell-wmi-descriptor.c |
| 5959 | 5959 | ||
| 5960 | DELL WMI HARDWARE PRIVACY SUPPORT | 5960 | DELL WMI HARDWARE PRIVACY SUPPORT |
| 5961 | M: Perry Yuan <Perry.Yuan@dell.com> | ||
| 5962 | L: Dell.Client.Kernel@dell.com | 5961 | L: Dell.Client.Kernel@dell.com |
| 5963 | L: platform-driver-x86@vger.kernel.org | 5962 | L: platform-driver-x86@vger.kernel.org |
| 5964 | S: Maintained | 5963 | S: Maintained |
| @@ -7955,12 +7954,13 @@ L: rust-for-linux@vger.kernel.org · 1990 unmodified lines | |||
| 7955 | S: Maintained | 7954 | S: Maintained |
| 7956 | F: rust/kernel/net/phy.rs | 7955 | F: rust/kernel/net/phy.rs |
| 7957 | 7956 | ||
| 7958 | EXEC & BINFMT API | 7957 | EXEC & BINFMT API, ELF |
| 7959 | R: Eric Biederman <ebiederm@xmission.com> | 7958 | R: Eric Biederman <ebiederm@xmission.com> |
| 7960 | R: Kees Cook <keescook@chromium.org> | 7959 | R: Kees Cook <keescook@chromium.org> |
| 7961 | L: linux-mm@kvack.org | 7960 | L: linux-mm@kvack.org |
| 7962 | S: Supported | 7961 | S: Supported |
| 7963 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve | 7962 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve |
| 7963 | F: Documentation/userspace-api/ELF.rst | ||
| 7964 | F: fs/*binfmt_*.c | 7964 | F: fs/*binfmt_*.c |
| 7965 | F: fs/exec.c | 7965 | F: fs/exec.c |
| 7966 | F: include/linux/binfmts.h | 7966 | F: include/linux/binfmts.h |
| @@ -8223,7 +8223,8 @@ F: include/linux/iomap.h · 256 unmodified lines | |||
| 8223 | 8223 | ||
| 8224 | FILESYSTEMS [NETFS LIBRARY] | 8224 | FILESYSTEMS [NETFS LIBRARY] |
| 8225 | M: David Howells <dhowells@redhat.com> | 8225 | M: David Howells <dhowells@redhat.com> |
| 8226 | L: linux-cachefs@redhat.com (moderated for non-subscribers) | 8226 | R: Jeff Layton <jlayton@kernel.org> |
| 8227 | L: netfs@lists.linux.dev | ||
| 8227 | L: linux-fsdevel@vger.kernel.org | 8228 | L: linux-fsdevel@vger.kernel.org |
| 8228 | S: Supported | 8229 | S: Supported |
| 8229 | F: Documentation/filesystems/caching/ | 8230 | F: Documentation/filesystems/caching/ |
| @@ -10091,7 +10092,7 @@ L: linux-i2c@vger.kernel.org · 1861 unmodified lines | |||
| 10091 | S: Maintained | 10092 | S: Maintained |
| 10092 | W: https://i2c.wiki.kernel.org/ | 10093 | W: https://i2c.wiki.kernel.org/ |
| 10093 | Q: https://patchwork.ozlabs.org/project/linux-i2c/list/ | 10094 | Q: https://patchwork.ozlabs.org/project/linux-i2c/list/ |
| 10094 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git | 10095 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git |
| 10095 | F: Documentation/devicetree/bindings/i2c/ | 10096 | F: Documentation/devicetree/bindings/i2c/ |
| 10096 | F: drivers/i2c/algos/ | 10097 | F: drivers/i2c/algos/ |
| 10097 | F: drivers/i2c/busses/ | 10098 | F: drivers/i2c/busses/ |
| @@ -10283,7 +10284,7 @@ F: drivers/scsi/ibmvscsi/ibmvscsi* · 185 unmodified lines | |||
| 10283 | F: include/scsi/viosrp.h | 10284 | F: include/scsi/viosrp.h |
| 10284 | 10285 | ||
| 10285 | IBM Power Virtual SCSI Device Target Driver | 10286 | IBM Power Virtual SCSI Device Target Driver |
| 10286 | M: Michael Cyr <mikecyr@linux.ibm.com> | 10287 | M: Tyrel Datwyler <tyreld@linux.ibm.com> |
| 10287 | L: linux-scsi@vger.kernel.org | 10288 | L: linux-scsi@vger.kernel.org |
| 10288 | L: target-devel@vger.kernel.org | 10289 | L: target-devel@vger.kernel.org |
| 10289 | S: Supported | 10290 | S: Supported |
| @@ -10801,11 +10802,11 @@ F: drivers/gpio/gpio-tangier.h · 511 unmodified lines | |||
| 10801 | 10802 | ||
| 10802 | INTEL GVT-g DRIVERS (Intel GPU Virtualization) | 10803 | INTEL GVT-g DRIVERS (Intel GPU Virtualization) |
| 10803 | M: Zhenyu Wang <zhenyuw@linux.intel.com> | 10804 | M: Zhenyu Wang <zhenyuw@linux.intel.com> |
| 10804 | M: Zhi Wang <zhi.a.wang@intel.com> | 10805 | M: Zhi Wang <zhi.wang.linux@gmail.com> |
| 10805 | L: intel-gvt-dev@lists.freedesktop.org | 10806 | L: intel-gvt-dev@lists.freedesktop.org |
| 10806 | L: intel-gfx@lists.freedesktop.org | 10807 | L: intel-gfx@lists.freedesktop.org |
| 10807 | S: Supported | 10808 | S: Supported |
| 10808 | W: https://01.org/igvt-g | 10809 | W: https://github.com/intel/gvt-linux/wiki |
| 10809 | T: git https://github.com/intel/gvt-linux.git | 10810 | T: git https://github.com/intel/gvt-linux.git |
| 10810 | F: drivers/gpu/drm/i915/gvt/ | 10811 | F: drivers/gpu/drm/i915/gvt/ |
| 10811 | 10812 | ||
| @@ -11127,7 +11128,6 @@ S: Supported · 315 unmodified lines | |||
| 11127 | F: drivers/net/wireless/intel/iwlegacy/ | 11128 | F: drivers/net/wireless/intel/iwlegacy/ |
| 11128 | 11129 | ||
| 11129 | INTEL WIRELESS WIFI LINK (iwlwifi) | 11130 | INTEL WIRELESS WIFI LINK (iwlwifi) |
| 11130 | M: Gregory Greenman <gregory.greenman@intel.com> | ||
| 11131 | M: Miri Korenblit <miriam.rachel.korenblit@intel.com> | 11131 | M: Miri Korenblit <miriam.rachel.korenblit@intel.com> |
| 11132 | L: linux-wireless@vger.kernel.org | 11132 | L: linux-wireless@vger.kernel.org |
| 11133 | S: Supported | 11133 | S: Supported |
| @@ -11725,6 +11725,7 @@ F: fs/smb/server/ · 591 unmodified lines | |||
| 11725 | KERNEL UNIT TESTING FRAMEWORK (KUnit) | 11725 | KERNEL UNIT TESTING FRAMEWORK (KUnit) |
| 11726 | M: Brendan Higgins <brendanhiggins@google.com> | 11726 | M: Brendan Higgins <brendanhiggins@google.com> |
| 11727 | M: David Gow <davidgow@google.com> | 11727 | M: David Gow <davidgow@google.com> |
| 11728 | R: Rae Moar <rmoar@google.com> | ||
| 11728 | L: linux-kselftest@vger.kernel.org | 11729 | L: linux-kselftest@vger.kernel.org |
| 11729 | L: kunit-dev@googlegroups.com | 11730 | L: kunit-dev@googlegroups.com |
| 11730 | S: Maintained | 11731 | S: Maintained |
| @@ -12903,6 +12904,8 @@ M: Alejandro Colomar <alx@kernel.org> · 1172 unmodified lines | |||
| 12903 | L: linux-man@vger.kernel.org | 12904 | L: linux-man@vger.kernel.org |
| 12904 | S: Maintained | 12905 | S: Maintained |
| 12905 | W: http://www.kernel.org/doc/man-pages | 12906 | W: http://www.kernel.org/doc/man-pages |
| 12907 | T: git git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git | ||
| 12908 | T: git git://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git | ||
| 12906 | 12909 | ||
| 12907 | MANAGEMENT COMPONENT TRANSPORT PROTOCOL (MCTP) | 12910 | MANAGEMENT COMPONENT TRANSPORT PROTOCOL (MCTP) |
| 12908 | M: Jeremy Kerr <jk@codeconstruct.com.au> | 12911 | M: Jeremy Kerr <jk@codeconstruct.com.au> |
| @@ -15178,6 +15181,7 @@ F: Documentation/networking/net_cachelines/net_device.rst · 2269 unmodified lines | |||
| 15178 | F: drivers/connector/ | 15181 | F: drivers/connector/ |
| 15179 | F: drivers/net/ | 15182 | F: drivers/net/ |
| 15180 | F: include/dt-bindings/net/ | 15183 | F: include/dt-bindings/net/ |
| 15184 | F: include/linux/cn_proc.h | ||
| 15181 | F: include/linux/etherdevice.h | 15185 | F: include/linux/etherdevice.h |
| 15182 | F: include/linux/fcdevice.h | 15186 | F: include/linux/fcdevice.h |
| 15183 | F: include/linux/fddidevice.h | 15187 | F: include/linux/fddidevice.h |
| @@ -15185,6 +15189,7 @@ F: include/linux/hippidevice.h · 1 unmodified line | |||
| 15185 | F: include/linux/if_* | 15189 | F: include/linux/if_* |
| 15186 | F: include/linux/inetdevice.h | 15190 | F: include/linux/inetdevice.h |
| 15187 | F: include/linux/netdevice.h | 15191 | F: include/linux/netdevice.h |
| 15192 | F: include/uapi/linux/cn_proc.h | ||
| 15188 | F: include/uapi/linux/if_* | 15193 | F: include/uapi/linux/if_* |
| 15189 | F: include/uapi/linux/netdevice.h | 15194 | F: include/uapi/linux/netdevice.h |
| 15190 | X: drivers/net/wireless/ | 15195 | X: drivers/net/wireless/ |
| @@ -16857,9 +16862,8 @@ F: Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml · 1666 unmodified lines | |||
| 16857 | F: drivers/pci/controller/pcie-xilinx-cpm.c | 16862 | F: drivers/pci/controller/pcie-xilinx-cpm.c |
| 16858 | 16863 | ||
| 16859 | PCI ENDPOINT SUBSYSTEM | 16864 | PCI ENDPOINT SUBSYSTEM |
| 16860 | M: Lorenzo Pieralisi <lpieralisi@kernel.org> | 16865 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| 16861 | M: Krzysztof Wilczyński <kw@linux.com> | 16866 | M: Krzysztof Wilczyński <kw@linux.com> |
| 16862 | R: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | ||
| 16863 | R: Kishon Vijay Abraham I <kishon@kernel.org> | 16867 | R: Kishon Vijay Abraham I <kishon@kernel.org> |
| 16864 | L: linux-pci@vger.kernel.org | 16868 | L: linux-pci@vger.kernel.org |
| 16865 | S: Supported | 16869 | S: Supported |
| @@ -17179,7 +17183,7 @@ R: John Garry <john.g.garry@oracle.com> · 313 unmodified lines | |||
| 17179 | R: Will Deacon <will@kernel.org> | 17183 | R: Will Deacon <will@kernel.org> |
| 17180 | R: James Clark <james.clark@arm.com> | 17184 | R: James Clark <james.clark@arm.com> |
| 17181 | R: Mike Leach <mike.leach@linaro.org> | 17185 | R: Mike Leach <mike.leach@linaro.org> |
| 17182 | R: Leo Yan <leo.yan@linaro.org> | 17186 | R: Leo Yan <leo.yan@linux.dev> |
| 17183 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 17187 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 17184 | S: Supported | 17188 | S: Supported |
| 17185 | F: tools/build/feature/test-libopencsd.c | 17189 | F: tools/build/feature/test-libopencsd.c |
| @@ -18082,7 +18086,6 @@ F: drivers/net/ethernet/qualcomm/emac/ · 896 unmodified lines | |||
| 18082 | 18086 | ||
| 18083 | QUALCOMM ETHQOS ETHERNET DRIVER | 18087 | QUALCOMM ETHQOS ETHERNET DRIVER |
| 18084 | M: Vinod Koul <vkoul@kernel.org> | 18088 | M: Vinod Koul <vkoul@kernel.org> |
| 18085 | R: Bhupesh Sharma <bhupesh.sharma@linaro.org> | ||
| 18086 | L: netdev@vger.kernel.org | 18089 | L: netdev@vger.kernel.org |
| 18087 | L: linux-arm-msm@vger.kernel.org | 18090 | L: linux-arm-msm@vger.kernel.org |
| 18088 | S: Maintained | 18091 | S: Maintained |
| @@ -18429,7 +18432,7 @@ S: Supported · 340 unmodified lines | |||
| 18429 | F: drivers/infiniband/sw/rdmavt | 18432 | F: drivers/infiniband/sw/rdmavt |
| 18430 | 18433 | ||
| 18431 | RDS - RELIABLE DATAGRAM SOCKETS | 18434 | RDS - RELIABLE DATAGRAM SOCKETS |
| 18432 | M: Santosh Shilimkar <santosh.shilimkar@oracle.com> | 18435 | M: Allison Henderson <allison.henderson@oracle.com> |
| 18433 | L: netdev@vger.kernel.org | 18436 | L: netdev@vger.kernel.org |
| 18434 | L: linux-rdma@vger.kernel.org | 18437 | L: linux-rdma@vger.kernel.org |
| 18435 | L: rds-devel@oss.oracle.com (moderated for non-subscribers) | 18438 | L: rds-devel@oss.oracle.com (moderated for non-subscribers) |
| @@ -20550,6 +20553,7 @@ F: Documentation/translations/sp_SP/ · 2114 unmodified lines | |||
| 20550 | 20553 | ||
| 20551 | SPARC + UltraSPARC (sparc/sparc64) | 20554 | SPARC + UltraSPARC (sparc/sparc64) |
| 20552 | M: "David S. Miller" <davem@davemloft.net> | 20555 | M: "David S. Miller" <davem@davemloft.net> |
| 20556 | M: Andreas Larsson <andreas@gaisler.com> | ||
| 20553 | L: sparclinux@vger.kernel.org | 20557 | L: sparclinux@vger.kernel.org |
| 20554 | S: Maintained | 20558 | S: Maintained |
| 20555 | Q: http://patchwork.ozlabs.org/project/sparclinux/list/ | 20559 | Q: http://patchwork.ozlabs.org/project/sparclinux/list/ |
| @@ -24340,13 +24344,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs.git · 3784 unmodified lines | |||
| 24340 | F: Documentation/filesystems/zonefs.rst | 24344 | F: Documentation/filesystems/zonefs.rst |
| 24341 | F: fs/zonefs/ | 24345 | F: fs/zonefs/ |
| 24342 | 24346 | ||
| 24343 | ZPOOL COMPRESSED PAGE STORAGE API | ||
| 24344 | M: Dan Streetman <ddstreet@ieee.org> | ||
| 24345 | L: linux-mm@kvack.org | ||
| 24346 | S: Maintained | ||
| 24347 | F: include/linux/zpool.h | ||
| 24348 | F: mm/zpool.c | ||
| 24349 | |||
| 24350 | ZR36067 VIDEO FOR LINUX DRIVER | 24347 | ZR36067 VIDEO FOR LINUX DRIVER |
| 24351 | M: Corentin Labbe <clabbe@baylibre.com> | 24348 | M: Corentin Labbe <clabbe@baylibre.com> |
| 24352 | L: mjpeg-users@lists.sourceforge.net | 24349 | L: mjpeg-users@lists.sourceforge.net |
| @@ -24398,7 +24395,9 @@ M: Nhat Pham <nphamcs@gmail.com> · 45 unmodified lines | |||
| 24398 | L: linux-mm@kvack.org | 24395 | L: linux-mm@kvack.org |
| 24399 | S: Maintained | 24396 | S: Maintained |
| 24400 | F: Documentation/admin-guide/mm/zswap.rst | 24397 | F: Documentation/admin-guide/mm/zswap.rst |
| 24398 | F: include/linux/zpool.h | ||
| 24401 | F: include/linux/zswap.h | 24399 | F: include/linux/zswap.h |
| 24400 | F: mm/zpool.c | ||
| 24402 | F: mm/zswap.c | 24401 | F: mm/zswap.c |
| 24403 | 24402 | ||
| 24404 | THE REST | 24403 | THE REST |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 8 | 3 | PATCHLEVEL = 8 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc1 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Hurr durr I'ma ninja sloth | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -294,15 +294,15 @@ may-sync-config := 1 · 285 unmodified lines | |||
| 294 | single-build := | 294 | single-build := |
| 295 | 295 | ||
| 296 | ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) | 296 | ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) |
| 297 | ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) | 297 | ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) |
| 298 | need-config := | 298 | need-config := |
| 299 | endif | 299 | endif |
| 300 | endif | 300 | endif |
| 301 | 301 | ||
| 302 | ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),) | 302 | ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),) |
| 303 | ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),) | 303 | ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),) |
| 304 | may-sync-config := | 304 | may-sync-config := |
| 305 | endif | 305 | endif |
| 306 | endif | 306 | endif |
| 307 | 307 | ||
| 308 | need-compiler := $(may-sync-config) | 308 | need-compiler := $(may-sync-config) |
| @@ -323,9 +323,9 @@ endif · 14 unmodified lines | |||
| 323 | # We cannot build single targets and the others at the same time | 323 | # We cannot build single targets and the others at the same time |
| 324 | ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),) | 324 | ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),) |
| 325 | single-build := 1 | 325 | single-build := 1 |
| 326 | ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),) | 326 | ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),) |
| 327 | mixed-build := 1 | 327 | mixed-build := 1 |
| 328 | endif | 328 | endif |
| 329 | endif | 329 | endif |
| 330 | 330 | ||
| 331 | # For "make -j clean all", "make -j mrproper defconfig all", etc. | 331 | # For "make -j clean all", "make -j mrproper defconfig all", etc. |
| @@ -986,6 +986,10 @@ NOSTDINC_FLAGS += -nostdinc · 654 unmodified lines | |||
| 986 | # perform bounds checking. | 986 | # perform bounds checking. |
| 987 | KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) | 987 | KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) |
| 988 | 988 | ||
| 989 | #Currently, disable -Wstringop-overflow for GCC 11, globally. | ||
| 990 | KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) | ||
| 991 | KBUILD_CFLAGS-$(CONFIG_CC_STRINGOP_OVERFLOW) += $(call cc-option, -Wstringop-overflow) | ||
| 992 | |||
| 989 | # disable invalid "can't wrap" optimizations for signed / pointers | 993 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 990 | KBUILD_CFLAGS += -fno-strict-overflow | 994 | KBUILD_CFLAGS += -fno-strict-overflow |
| 991 | 995 | ||
| @@ -1662,7 +1666,7 @@ help: · 670 unmodified lines | |||
| 1662 | @echo ' (sparse by default)' | 1666 | @echo ' (sparse by default)' |
| 1663 | @echo ' make C=2 [targets] Force check of all c source with $$CHECK' | 1667 | @echo ' make C=2 [targets] Force check of all c source with $$CHECK' |
| 1664 | @echo ' make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections' | 1668 | @echo ' make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections' |
| 1665 | @echo ' make W=n [targets] Enable extra build checks, n=1,2,3 where' | 1669 | @echo ' make W=n [targets] Enable extra build checks, n=1,2,3,c,e where' |
| 1666 | @echo ' 1: warnings which may be relevant and do not occur too often' | 1670 | @echo ' 1: warnings which may be relevant and do not occur too often' |
| 1667 | @echo ' 2: warnings which occur quite often but may still be relevant' | 1671 | @echo ' 2: warnings which occur quite often but may still be relevant' |
| 1668 | @echo ' 3: more obscure warnings, can most likely be ignored' | 1672 | @echo ' 3: more obscure warnings, can most likely be ignored' |
| @@ -673,6 +673,7 @@ config SHADOW_CALL_STACK · 672 unmodified lines | |||
| 673 | bool "Shadow Call Stack" | 673 | bool "Shadow Call Stack" |
| 674 | depends on ARCH_SUPPORTS_SHADOW_CALL_STACK | 674 | depends on ARCH_SUPPORTS_SHADOW_CALL_STACK |
| 675 | depends on DYNAMIC_FTRACE_WITH_ARGS || DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER | 675 | depends on DYNAMIC_FTRACE_WITH_ARGS || DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER |
| 676 | depends on MMU | ||
| 676 | help | 677 | help |
| 677 | This option enables the compiler's Shadow Call Stack, which | 678 | This option enables the compiler's Shadow Call Stack, which |
| 678 | uses a shadow stack to protect function return addresses from | 679 | uses a shadow stack to protect function return addresses from |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | |||
| 31 | static __always_inline bool arch_static_branch(struct static_key *key, | 31 | static __always_inline bool arch_static_branch(struct static_key *key, |
| 32 | bool branch) | 32 | bool branch) |
| 33 | { | 33 | { |
| 34 | asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" | 34 | asm goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" |
| 35 | "1: \n" | 35 | "1: \n" |
| 36 | "nop \n" | 36 | "nop \n" |
| 37 | ".pushsection __jump_table, \"aw\" \n" | 37 | ".pushsection __jump_table, \"aw\" \n" |
| @@ -47,7 +47,7 @@ l_yes: · 9 unmodified lines | |||
| 47 | static __always_inline bool arch_static_branch_jump(struct static_key *key, | 47 | static __always_inline bool arch_static_branch_jump(struct static_key *key, |
| 48 | bool branch) | 48 | bool branch) |
| 49 | { | 49 | { |
| 50 | asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" | 50 | asm goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" |
| 51 | "1: \n" | 51 | "1: \n" |
| 52 | "b %l[l_yes] \n" | 52 | "b %l[l_yes] \n" |
| 53 | ".pushsection __jump_table, \"aw\" \n" | 53 | ".pushsection __jump_table, \"aw\" \n" |
| @@ -45,8 +45,8 @@ · 44 unmodified lines | |||
| 45 | num-chipselects = <1>; | 45 | num-chipselects = <1>; |
| 46 | cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>; | 46 | cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>; |
| 47 | 47 | ||
| 48 | tpmdev@0 { | 48 | tpm@0 { |
| 49 | compatible = "tcg,tpm_tis-spi"; | 49 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 50 | spi-max-frequency = <33000000>; | 50 | spi-max-frequency = <33000000>; |
| 51 | reg = <0>; | 51 | reg = <0>; |
| 52 | }; | 52 | }; |
| @@ -80,8 +80,8 @@ · 79 unmodified lines | |||
| 80 | gpio-miso = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_HIGH>; | 80 | gpio-miso = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_HIGH>; |
| 81 | num-chipselects = <1>; | 81 | num-chipselects = <1>; |
| 82 | 82 | ||
| 83 | tpmdev@0 { | 83 | tpm@0 { |
| 84 | compatible = "tcg,tpm_tis-spi"; | 84 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 85 | spi-max-frequency = <33000000>; | 85 | spi-max-frequency = <33000000>; |
| 86 | reg = <0>; | 86 | reg = <0>; |
| 87 | }; | 87 | }; |
| @@ -456,7 +456,7 @@ · 455 unmodified lines | |||
| 456 | status = "okay"; | 456 | status = "okay"; |
| 457 | 457 | ||
| 458 | tpm: tpm@2e { | 458 | tpm: tpm@2e { |
| 459 | compatible = "tcg,tpm-tis-i2c"; | 459 | compatible = "nuvoton,npct75x", "tcg,tpm-tis-i2c"; |
| 460 | reg = <0x2e>; | 460 | reg = <0x2e>; |
| 461 | }; | 461 | }; |
| 462 | }; | 462 | }; |
| @@ -35,8 +35,8 @@ · 34 unmodified lines | |||
| 35 | gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>; | 35 | gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>; |
| 36 | gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>; | 36 | gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>; |
| 37 | 37 | ||
| 38 | tpmdev@0 { | 38 | tpm@0 { |
| 39 | compatible = "tcg,tpm_tis-spi"; | 39 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 40 | spi-max-frequency = <33000000>; | 40 | spi-max-frequency = <33000000>; |
| 41 | reg = <0>; | 41 | reg = <0>; |
| 42 | }; | 42 | }; |
| @@ -116,7 +116,7 @@ · 115 unmodified lines | |||
| 116 | tpm_tis: tpm@1 { | 116 | tpm_tis: tpm@1 { |
| 117 | pinctrl-names = "default"; | 117 | pinctrl-names = "default"; |
| 118 | pinctrl-0 = <&pinctrl_tpm>; | 118 | pinctrl-0 = <&pinctrl_tpm>; |
| 119 | compatible = "tcg,tpm_tis-spi"; | 119 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 120 | reg = <1>; | 120 | reg = <1>; |
| 121 | spi-max-frequency = <20000000>; | 121 | spi-max-frequency = <20000000>; |
| 122 | interrupt-parent = <&gpio5>; | 122 | interrupt-parent = <&gpio5>; |
| @@ -130,7 +130,7 @@ · 129 unmodified lines | |||
| 130 | * TCG specification - Section 6.4.1 Clocking: | 130 | * TCG specification - Section 6.4.1 Clocking: |
| 131 | * TPM shall support a SPI clock frequency range of 10-24 MHz. | 131 | * TPM shall support a SPI clock frequency range of 10-24 MHz. |
| 132 | */ | 132 | */ |
| 133 | st33htph: tpm-tis@0 { | 133 | st33htph: tpm@0 { |
| 134 | compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; | 134 | compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; |
| 135 | reg = <0>; | 135 | reg = <0>; |
| 136 | spi-max-frequency = <24000000>; | 136 | spi-max-frequency = <24000000>; |
| @@ -434,6 +434,7 @@ · 433 unmodified lines | |||
| 434 | }; | 434 | }; |
| 435 | 435 | ||
| 436 | &fimd { | 436 | &fimd { |
| 437 | samsung,invert-vclk; | ||
| 437 | status = "okay"; | 438 | status = "okay"; |
| 438 | }; | 439 | }; |
| 439 | 440 | ||
| @@ -217,7 +217,7 @@ · 216 unmodified lines | |||
| 217 | pinctrl-names = "default"; | 217 | pinctrl-names = "default"; |
| 218 | pinctrl-0 = <&spi1_pins>; | 218 | pinctrl-0 = <&spi1_pins>; |
| 219 | 219 | ||
| 220 | tpm_spi_tis@0 { | 220 | tpm@0 { |
| 221 | compatible = "tcg,tpm_tis-spi"; | 221 | compatible = "tcg,tpm_tis-spi"; |
| 222 | reg = <0>; | 222 | reg = <0>; |
| 223 | spi-max-frequency = <500000>; | 223 | spi-max-frequency = <500000>; |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 12 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 13 | { | 13 | { |
| 14 | asm_volatile_goto("1:\n\t" | 14 | asm goto("1:\n\t" |
| 15 | WASM(nop) "\n\t" | 15 | WASM(nop) "\n\t" |
| 16 | ".pushsection __jump_table, \"aw\"\n\t" | 16 | ".pushsection __jump_table, \"aw\"\n\t" |
| 17 | ".word 1b, %l[l_yes], %c0\n\t" | 17 | ".word 1b, %l[l_yes], %c0\n\t" |
| @@ -25,7 +25,7 @@ l_yes: · 7 unmodified lines | |||
| 25 | 25 | ||
| 26 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) | 26 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) |
| 27 | { | 27 | { |
| 28 | asm_volatile_goto("1:\n\t" | 28 | asm goto("1:\n\t" |
| 29 | WASM(b) " %l[l_yes]\n\t" | 29 | WASM(b) " %l[l_yes]\n\t" |
| 30 | ".pushsection __jump_table, \"aw\"\n\t" | 30 | ".pushsection __jump_table, \"aw\"\n\t" |
| 31 | ".word 1b, %l[l_yes], %c0\n\t" | 31 | ".word 1b, %l[l_yes], %c0\n\t" |
| @@ -298,6 +298,8 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 297 unmodified lines | |||
| 298 | goto done; | 298 | goto done; |
| 299 | } | 299 | } |
| 300 | count_vm_vma_lock_event(VMA_LOCK_RETRY); | 300 | count_vm_vma_lock_event(VMA_LOCK_RETRY); |
| 301 | if (fault & VM_FAULT_MAJOR) | ||
| 302 | flags |= FAULT_FLAG_TRIED; | ||
| 301 | 303 | ||
| 302 | /* Quick path to respond to signals */ | 304 | /* Quick path to respond to signals */ |
| 303 | if (fault_signal_pending(fault, regs)) { | 305 | if (fault_signal_pending(fault, regs)) { |
| @@ -195,7 +195,7 @@ vdso_prepare: prepare0 · 194 unmodified lines | |||
| 195 | include/generated/vdso-offsets.h arch/arm64/kernel/vdso/vdso.so | 195 | include/generated/vdso-offsets.h arch/arm64/kernel/vdso/vdso.so |
| 196 | ifdef CONFIG_COMPAT_VDSO | 196 | ifdef CONFIG_COMPAT_VDSO |
| 197 | $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 \ | 197 | $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 \ |
| 198 | include/generated/vdso32-offsets.h arch/arm64/kernel/vdso32/vdso.so | 198 | arch/arm64/kernel/vdso32/vdso.so |
| 199 | endif | 199 | endif |
| 200 | endif | 200 | endif |
| 201 | 201 | ||
| @@ -289,7 +289,7 @@ · 288 unmodified lines | |||
| 289 | #clock-cells = <1>; | 289 | #clock-cells = <1>; |
| 290 | clocks = <&cmu_top CLK_DOUT_CMU_MISC_BUS>, | 290 | clocks = <&cmu_top CLK_DOUT_CMU_MISC_BUS>, |
| 291 | <&cmu_top CLK_DOUT_CMU_MISC_SSS>; | 291 | <&cmu_top CLK_DOUT_CMU_MISC_SSS>; |
| 292 | clock-names = "dout_cmu_misc_bus", "dout_cmu_misc_sss"; | 292 | clock-names = "bus", "sss"; |
| 293 | }; | 293 | }; |
| 294 | 294 | ||
| 295 | watchdog_cl0: watchdog@10060000 { | 295 | watchdog_cl0: watchdog@10060000 { |
| @@ -120,7 +120,7 @@ · 119 unmodified lines | |||
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | tpm: tpm@1 { | 122 | tpm: tpm@1 { |
| 123 | compatible = "tcg,tpm_tis-spi"; | 123 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 124 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | 124 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; |
| 125 | interrupt-parent = <&gpio2>; | 125 | interrupt-parent = <&gpio2>; |
| 126 | pinctrl-names = "default"; | 126 | pinctrl-names = "default"; |
| @@ -89,7 +89,7 @@ · 88 unmodified lines | |||
| 89 | status = "okay"; | 89 | status = "okay"; |
| 90 | 90 | ||
| 91 | tpm@1 { | 91 | tpm@1 { |
| 92 | compatible = "tcg,tpm_tis-spi"; | 92 | compatible = "atmel,attpm20p", "tcg,tpm_tis-spi"; |
| 93 | reg = <0x1>; | 93 | reg = <0x1>; |
| 94 | spi-max-frequency = <36000000>; | 94 | spi-max-frequency = <36000000>; |
| 95 | }; | 95 | }; |
| @@ -109,7 +109,7 @@ · 108 unmodified lines | |||
| 109 | status = "okay"; | 109 | status = "okay"; |
| 110 | 110 | ||
| 111 | tpm@1 { | 111 | tpm@1 { |
| 112 | compatible = "tcg,tpm_tis-spi"; | 112 | compatible = "atmel,attpm20p", "tcg,tpm_tis-spi"; |
| 113 | reg = <0x1>; | 113 | reg = <0x1>; |
| 114 | spi-max-frequency = <36000000>; | 114 | spi-max-frequency = <36000000>; |
| 115 | }; | 115 | }; |
| @@ -234,7 +234,7 @@ · 233 unmodified lines | |||
| 234 | status = "okay"; | 234 | status = "okay"; |
| 235 | 235 | ||
| 236 | tpm: tpm@0 { | 236 | tpm: tpm@0 { |
| 237 | compatible = "infineon,slb9670"; | 237 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 238 | reg = <0>; | 238 | reg = <0>; |
| 239 | pinctrl-names = "default"; | 239 | pinctrl-names = "default"; |
| 240 | pinctrl-0 = <&pinctrl_tpm>; | 240 | pinctrl-0 = <&pinctrl_tpm>; |
| @@ -103,7 +103,7 @@ · 102 unmodified lines | |||
| 103 | status = "okay"; | 103 | status = "okay"; |
| 104 | 104 | ||
| 105 | tpm@1 { | 105 | tpm@1 { |
| 106 | compatible = "tcg,tpm_tis-spi"; | 106 | compatible = "atmel,attpm20p", "tcg,tpm_tis-spi"; |
| 107 | reg = <0x1>; | 107 | reg = <0x1>; |
| 108 | spi-max-frequency = <36000000>; | 108 | spi-max-frequency = <36000000>; |
| 109 | }; | 109 | }; |
| @@ -115,7 +115,7 @@ · 114 unmodified lines | |||
| 115 | status = "okay"; | 115 | status = "okay"; |
| 116 | 116 | ||
| 117 | tpm@1 { | 117 | tpm@1 { |
| 118 | compatible = "tcg,tpm_tis-spi"; | 118 | compatible = "atmel,attpm20p", "tcg,tpm_tis-spi"; |
| 119 | reg = <0x1>; | 119 | reg = <0x1>; |
| 120 | spi-max-frequency = <36000000>; | 120 | spi-max-frequency = <36000000>; |
| 121 | }; | 121 | }; |
| @@ -196,7 +196,7 @@ · 195 unmodified lines | |||
| 196 | status = "okay"; | 196 | status = "okay"; |
| 197 | 197 | ||
| 198 | tpm@0 { | 198 | tpm@0 { |
| 199 | compatible = "tcg,tpm_tis-spi"; | 199 | compatible = "atmel,attpm20p", "tcg,tpm_tis-spi"; |
| 200 | reg = <0x0>; | 200 | reg = <0x0>; |
| 201 | spi-max-frequency = <36000000>; | 201 | spi-max-frequency = <36000000>; |
| 202 | }; | 202 | }; |
| @@ -65,7 +65,7 @@ · 64 unmodified lines | |||
| 65 | status = "okay"; | 65 | status = "okay"; |
| 66 | 66 | ||
| 67 | tpm@0 { | 67 | tpm@0 { |
| 68 | compatible = "infineon,slb9670"; | 68 | compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; |
| 69 | reg = <0>; | 69 | reg = <0>; |
| 70 | spi-max-frequency = <43000000>; | 70 | spi-max-frequency = <43000000>; |
| 71 | }; | 71 | }; |
| @@ -888,7 +888,7 @@ · 887 unmodified lines | |||
| 888 | status = "okay"; | 888 | status = "okay"; |
| 889 | cs-gpios = <&pio 86 GPIO_ACTIVE_LOW>; | 889 | cs-gpios = <&pio 86 GPIO_ACTIVE_LOW>; |
| 890 | 890 | ||
| 891 | cr50@0 { | 891 | tpm@0 { |
| 892 | compatible = "google,cr50"; | 892 | compatible = "google,cr50"; |
| 893 | reg = <0>; | 893 | reg = <0>; |
| 894 | spi-max-frequency = <1000000>; | 894 | spi-max-frequency = <1000000>; |
| @@ -1402,7 +1402,7 @@ · 1401 unmodified lines | |||
| 1402 | pinctrl-names = "default"; | 1402 | pinctrl-names = "default"; |
| 1403 | pinctrl-0 = <&spi5_pins>; | 1403 | pinctrl-0 = <&spi5_pins>; |
| 1404 | 1404 | ||
| 1405 | cr50@0 { | 1405 | tpm@0 { |
| 1406 | compatible = "google,cr50"; | 1406 | compatible = "google,cr50"; |
| 1407 | reg = <0>; | 1407 | reg = <0>; |
| 1408 | interrupts-extended = <&pio 171 IRQ_TYPE_EDGE_RISING>; | 1408 | interrupts-extended = <&pio 171 IRQ_TYPE_EDGE_RISING>; |
| @@ -70,7 +70,7 @@ · 69 unmodified lines | |||
| 70 | &spi0 { | 70 | &spi0 { |
| 71 | status = "okay"; | 71 | status = "okay"; |
| 72 | 72 | ||
| 73 | cr50@0 { | 73 | tpm@0 { |
| 74 | compatible = "google,cr50"; | 74 | compatible = "google,cr50"; |
| 75 | reg = <0>; | 75 | reg = <0>; |
| 76 | interrupt-parent = <&gpio0>; | 76 | interrupt-parent = <&gpio0>; |
| @@ -706,7 +706,7 @@ camera: &i2c7 { · 705 unmodified lines | |||
| 706 | &spi2 { | 706 | &spi2 { |
| 707 | status = "okay"; | 707 | status = "okay"; |
| 708 | 708 | ||
| 709 | cr50@0 { | 709 | tpm@0 { |
| 710 | compatible = "google,cr50"; | 710 | compatible = "google,cr50"; |
| 711 | reg = <0>; | 711 | reg = <0>; |
| 712 | interrupt-parent = <&gpio1>; | 712 | interrupt-parent = <&gpio1>; |
| @@ -229,7 +229,7 @@ alternative_has_cap_likely(const unsigned long cpucap) · 228 unmodified lines | |||
| 229 | if (!cpucap_is_possible(cpucap)) | 229 | if (!cpucap_is_possible(cpucap)) |
| 230 | return false; | 230 | return false; |
| 231 | 231 | ||
| 232 | asm_volatile_goto( | 232 | asm goto( |
| 233 | ALTERNATIVE_CB("b %l[l_no]", %[cpucap], alt_cb_patch_nops) | 233 | ALTERNATIVE_CB("b %l[l_no]", %[cpucap], alt_cb_patch_nops) |
| 234 | : | 234 | : |
| 235 | : [cpucap] "i" (cpucap) | 235 | : [cpucap] "i" (cpucap) |
| @@ -247,7 +247,7 @@ alternative_has_cap_unlikely(const unsigned long cpucap) · 11 unmodified lines | |||
| 247 | if (!cpucap_is_possible(cpucap)) | 247 | if (!cpucap_is_possible(cpucap)) |
| 248 | return false; | 248 | return false; |
| 249 | 249 | ||
| 250 | asm_volatile_goto( | 250 | asm goto( |
| 251 | ALTERNATIVE("nop", "b %l[l_yes]", %[cpucap]) | 251 | ALTERNATIVE("nop", "b %l[l_yes]", %[cpucap]) |
| 252 | : | 252 | : |
| 253 | : [cpucap] "i" (cpucap) | 253 | : [cpucap] "i" (cpucap) |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | |||
| 18 | static __always_inline bool arch_static_branch(struct static_key * const key, | 18 | static __always_inline bool arch_static_branch(struct static_key * const key, |
| 19 | const bool branch) | 19 | const bool branch) |
| 20 | { | 20 | { |
| 21 | asm_volatile_goto( | 21 | asm goto( |
| 22 | "1: nop \n\t" | 22 | "1: nop \n\t" |
| 23 | " .pushsection __jump_table, \"aw\" \n\t" | 23 | " .pushsection __jump_table, \"aw\" \n\t" |
| 24 | " .align 3 \n\t" | 24 | " .align 3 \n\t" |
| @@ -35,7 +35,7 @@ l_yes: · 10 unmodified lines | |||
| 35 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, | 35 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, |
| 36 | const bool branch) | 36 | const bool branch) |
| 37 | { | 37 | { |
| 38 | asm_volatile_goto( | 38 | asm goto( |
| 39 | "1: b %l[l_yes] \n\t" | 39 | "1: b %l[l_yes] \n\t" |
| 40 | " .pushsection __jump_table, \"aw\" \n\t" | 40 | " .pushsection __jump_table, \"aw\" \n\t" |
| 41 | " .align 3 \n\t" | 41 | " .align 3 \n\t" |
| @@ -17,9 +17,6 @@ · 16 unmodified lines | |||
| 17 | #ifndef __ASSEMBLY__ | 17 | #ifndef __ASSEMBLY__ |
| 18 | 18 | ||
| 19 | #include <generated/vdso-offsets.h> | 19 | #include <generated/vdso-offsets.h> |
| 20 | #ifdef CONFIG_COMPAT_VDSO | ||
| 21 | #include <generated/vdso32-offsets.h> | ||
| 22 | #endif | ||
| 23 | 20 | ||
| 24 | #define VDSO_SYMBOL(base, name) \ | 21 | #define VDSO_SYMBOL(base, name) \ |
| 25 | ({ \ | 22 | ({ \ |
| @@ -77,9 +77,9 @@ obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) += patch-scs.o · 76 unmodified lines | |||
| 77 | # We need to prevent the SCS patching code from patching itself. Using | 77 | # We need to prevent the SCS patching code from patching itself. Using |
| 78 | # -mbranch-protection=none here to avoid the patchable PAC opcodes from being | 78 | # -mbranch-protection=none here to avoid the patchable PAC opcodes from being |
| 79 | # generated triggers an issue with full LTO on Clang, which stops emitting PAC | 79 | # generated triggers an issue with full LTO on Clang, which stops emitting PAC |
| 80 | # instructions altogether. So instead, omit the unwind tables used by the | 80 | # instructions altogether. So disable LTO as well for the compilation unit. |
| 81 | # patching code, so it will not be able to locate its own PAC instructions. | 81 | CFLAGS_patch-scs.o += -mbranch-protection=none |
| 82 | CFLAGS_patch-scs.o += -fno-asynchronous-unwind-tables -fno-unwind-tables | 82 | CFLAGS_REMOVE_patch-scs.o += $(CC_FLAGS_LTO) |
| 83 | 83 | ||
| 84 | # Force dependency (vdso*-wrap.S includes vdso.so through incbin) | 84 | # Force dependency (vdso*-wrap.S includes vdso.so through incbin) |
| 85 | $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so | 85 | $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so |
| @@ -127,9 +127,6 @@ obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso) · 126 unmodified lines | |||
| 127 | targets += vdso.lds | 127 | targets += vdso.lds |
| 128 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) | 128 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
| 129 | 129 | ||
| 130 | include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE | ||
| 131 | $(call if_changed,vdsosym) | ||
| 132 | |||
| 133 | # Strip rule for vdso.so | 130 | # Strip rule for vdso.so |
| 134 | $(obj)/vdso.so: OBJCOPYFLAGS := -S | 131 | $(obj)/vdso.so: OBJCOPYFLAGS := -S |
| 135 | $(obj)/vdso.so: $(obj)/vdso32.so.dbg FORCE | 132 | $(obj)/vdso.so: $(obj)/vdso32.so.dbg FORCE |
| @@ -166,9 +163,3 @@ quiet_cmd_vdsoas = AS32 $@ · 30 unmodified lines | |||
| 166 | 163 | ||
| 167 | quiet_cmd_vdsomunge = MUNGE $@ | 164 | quiet_cmd_vdsomunge = MUNGE $@ |
| 168 | cmd_vdsomunge = $(obj)/$(munge) $< $@ | 165 | cmd_vdsomunge = $(obj)/$(munge) $< $@ |
| 169 | |||
| 170 | # Generate vDSO offsets using helper script (borrowed from the 64-bit vDSO) | ||
| 171 | gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh | ||
| 172 | quiet_cmd_vdsosym = VDSOSYM $@ | ||
| 173 | # The AArch64 nm should be able to read an AArch32 binary | ||
| 174 | cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ | ||
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | static __always_inline bool arch_static_branch(struct static_key *key, | 12 | static __always_inline bool arch_static_branch(struct static_key *key, |
| 13 | bool branch) | 13 | bool branch) |
| 14 | { | 14 | { |
| 15 | asm_volatile_goto( | 15 | asm goto( |
| 16 | "1: nop32 \n" | 16 | "1: nop32 \n" |
| 17 | " .pushsection __jump_table, \"aw\" \n" | 17 | " .pushsection __jump_table, \"aw\" \n" |
| 18 | " .align 2 \n" | 18 | " .align 2 \n" |
| @@ -29,7 +29,7 @@ label: · 10 unmodified lines | |||
| 29 | static __always_inline bool arch_static_branch_jump(struct static_key *key, | 29 | static __always_inline bool arch_static_branch_jump(struct static_key *key, |
| 30 | bool branch) | 30 | bool branch) |
| 31 | { | 31 | { |
| 32 | asm_volatile_goto( | 32 | asm goto( |
| 33 | "1: bsr32 %l[label] \n" | 33 | "1: bsr32 %l[label] \n" |
| 34 | " .pushsection __jump_table, \"aw\" \n" | 34 | " .pushsection __jump_table, \"aw\" \n" |
| 35 | " .align 2 \n" | 35 | " .align 2 \n" |
| @@ -12,6 +12,7 @@ config LOONGARCH · 11 unmodified lines | |||
| 12 | select ARCH_DISABLE_KASAN_INLINE | 12 | select ARCH_DISABLE_KASAN_INLINE |
| 13 | select ARCH_ENABLE_MEMORY_HOTPLUG | 13 | select ARCH_ENABLE_MEMORY_HOTPLUG |
| 14 | select ARCH_ENABLE_MEMORY_HOTREMOVE | 14 | select ARCH_ENABLE_MEMORY_HOTREMOVE |
| 15 | select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE | ||
| 15 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI | 16 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI |
| 16 | select ARCH_HAS_CPU_FINALIZE_INIT | 17 | select ARCH_HAS_CPU_FINALIZE_INIT |
| 17 | select ARCH_HAS_FORTIFY_SOURCE | 18 | select ARCH_HAS_FORTIFY_SOURCE |
| @@ -99,6 +100,7 @@ config LOONGARCH · 81 unmodified lines | |||
| 99 | select HAVE_ARCH_KFENCE | 100 | select HAVE_ARCH_KFENCE |
| 100 | select HAVE_ARCH_KGDB if PERF_EVENTS | 101 | select HAVE_ARCH_KGDB if PERF_EVENTS |
| 101 | select HAVE_ARCH_MMAP_RND_BITS if MMU | 102 | select HAVE_ARCH_MMAP_RND_BITS if MMU |
| 103 | select HAVE_ARCH_SECCOMP | ||
| 102 | select HAVE_ARCH_SECCOMP_FILTER | 104 | select HAVE_ARCH_SECCOMP_FILTER |
| 103 | select HAVE_ARCH_TRACEHOOK | 105 | select HAVE_ARCH_TRACEHOOK |
| 104 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE | 106 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE |
| @@ -632,23 +634,6 @@ config RANDOMIZE_BASE_MAX_OFFSET · 527 unmodified lines | |||
| 632 | 634 | ||
| 633 | This is limited by the size of the lower address memory, 256MB. | 635 | This is limited by the size of the lower address memory, 256MB. |
| 634 | 636 | ||
| 635 | config SECCOMP | ||
| 636 | bool "Enable seccomp to safely compute untrusted bytecode" | ||
| 637 | depends on PROC_FS | ||
| 638 | default y | ||
| 639 | help | ||
| 640 | This kernel feature is useful for number crunching applications | ||
| 641 | that may need to compute untrusted bytecode during their | ||
| 642 | execution. By using pipes or other transports made available to | ||
| 643 | the process as file descriptors supporting the read/write | ||
| 644 | syscalls, it's possible to isolate those applications in | ||
| 645 | their own address space using seccomp. Once seccomp is | ||
| 646 | enabled via /proc/<pid>/seccomp, it cannot be disabled | ||
| 647 | and the task is only allowed to execute a few safe syscalls | ||
| 648 | defined by each seccomp mode. | ||
| 649 | |||
| 650 | If unsure, say Y. Only embedded should say N here. | ||
| 651 | |||
| 652 | endmenu | 637 | endmenu |
| 653 | 638 | ||
| 654 | config ARCH_SELECT_MEMORY_MODEL | 639 | config ARCH_SELECT_MEMORY_MODEL |
| @@ -667,10 +652,6 @@ config ARCH_SPARSEMEM_ENABLE · 12 unmodified lines | |||
| 667 | or have huge holes in the physical address space for other reasons. | 652 | or have huge holes in the physical address space for other reasons. |
| 668 | See <file:Documentation/mm/numa.rst> for more. | 653 | See <file:Documentation/mm/numa.rst> for more. |
| 669 | 654 | ||
| 670 | config ARCH_ENABLE_THP_MIGRATION | ||
| 671 | def_bool y | ||
| 672 | depends on TRANSPARENT_HUGEPAGE | ||
| 673 | |||
| 674 | config ARCH_MEMORY_PROBE | 655 | config ARCH_MEMORY_PROBE |
| 675 | def_bool y | 656 | def_bool y |
| 676 | depends on MEMORY_HOTPLUG | 657 | depends on MEMORY_HOTPLUG |
| @@ -32,8 +32,10 @@ static inline bool acpi_has_cpu_in_madt(void) · 31 unmodified lines | |||
| 32 | return true; | 32 | return true; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | #define MAX_CORE_PIC 256 | ||
| 36 | |||
| 35 | extern struct list_head acpi_wakeup_device_list; | 37 | extern struct list_head acpi_wakeup_device_list; |
| 36 | extern struct acpi_madt_core_pic acpi_core_pic[NR_CPUS]; | 38 | extern struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC]; |
| 37 | 39 | ||
| 38 | extern int __init parse_acpi_topology(void); | 40 | extern int __init parse_acpi_topology(void); |
| 39 | 41 | ||
| @@ -22,7 +22,7 @@ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) | 23 | static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) |
| 24 | { | 24 | { |
| 25 | asm_volatile_goto( | 25 | asm goto( |
| 26 | "1: nop \n\t" | 26 | "1: nop \n\t" |
| 27 | JUMP_TABLE_ENTRY | 27 | JUMP_TABLE_ENTRY |
| 28 | : : "i"(&((char *)key)[branch]) : : l_yes); | 28 | : : "i"(&((char *)key)[branch]) : : l_yes); |
| @@ -35,7 +35,7 @@ l_yes: · 6 unmodified lines | |||
| 35 | 35 | ||
| 36 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) | 36 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) |
| 37 | { | 37 | { |
| 38 | asm_volatile_goto( | 38 | asm goto( |
| 39 | "1: b %l[l_yes] \n\t" | 39 | "1: b %l[l_yes] \n\t" |
| 40 | JUMP_TABLE_ENTRY | 40 | JUMP_TABLE_ENTRY |
| 41 | : : "i"(&((char *)key)[branch]) : : l_yes); | 41 | : : "i"(&((char *)key)[branch]) : : l_yes); |
| @@ -60,7 +60,7 @@ int kvm_own_lsx(struct kvm_vcpu *vcpu); · 59 unmodified lines | |||
| 60 | void kvm_save_lsx(struct loongarch_fpu *fpu); | 60 | void kvm_save_lsx(struct loongarch_fpu *fpu); |
| 61 | void kvm_restore_lsx(struct loongarch_fpu *fpu); | 61 | void kvm_restore_lsx(struct loongarch_fpu *fpu); |
| 62 | #else | 62 | #else |
| 63 | static inline int kvm_own_lsx(struct kvm_vcpu *vcpu) { } | 63 | static inline int kvm_own_lsx(struct kvm_vcpu *vcpu) { return -EINVAL; } |
| 64 | static inline void kvm_save_lsx(struct loongarch_fpu *fpu) { } | 64 | static inline void kvm_save_lsx(struct loongarch_fpu *fpu) { } |
| 65 | static inline void kvm_restore_lsx(struct loongarch_fpu *fpu) { } | 65 | static inline void kvm_restore_lsx(struct loongarch_fpu *fpu) { } |
| 66 | #endif | 66 | #endif |
| @@ -70,7 +70,7 @@ int kvm_own_lasx(struct kvm_vcpu *vcpu); · 3 unmodified lines | |||
| 70 | void kvm_save_lasx(struct loongarch_fpu *fpu); | 70 | void kvm_save_lasx(struct loongarch_fpu *fpu); |
| 71 | void kvm_restore_lasx(struct loongarch_fpu *fpu); | 71 | void kvm_restore_lasx(struct loongarch_fpu *fpu); |
| 72 | #else | 72 | #else |
| 73 | static inline int kvm_own_lasx(struct kvm_vcpu *vcpu) { } | 73 | static inline int kvm_own_lasx(struct kvm_vcpu *vcpu) { return -EINVAL; } |
| 74 | static inline void kvm_save_lasx(struct loongarch_fpu *fpu) { } | 74 | static inline void kvm_save_lasx(struct loongarch_fpu *fpu) { } |
| 75 | static inline void kvm_restore_lasx(struct loongarch_fpu *fpu) { } | 75 | static inline void kvm_restore_lasx(struct loongarch_fpu *fpu) { } |
| 76 | #endif | 76 | #endif |
| @@ -29,11 +29,9 @@ int disabled_cpus; · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | u64 acpi_saved_sp; | 30 | u64 acpi_saved_sp; |
| 31 | 31 | ||
| 32 | #define MAX_CORE_PIC 256 | ||
| 33 | |||
| 34 | #define PREFIX "ACPI: " | 32 | #define PREFIX "ACPI: " |
| 35 | 33 | ||
| 36 | struct acpi_madt_core_pic acpi_core_pic[NR_CPUS]; | 34 | struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC]; |
| 37 | 35 | ||
| 38 | void __init __iomem * __acpi_map_table(unsigned long phys, unsigned long size) | 36 | void __init __iomem * __acpi_map_table(unsigned long phys, unsigned long size) |
| 39 | { | 37 | { |
| @@ -509,7 +509,6 @@ asmlinkage void start_secondary(void) · 508 unmodified lines | |||
| 509 | sync_counter(); | 509 | sync_counter(); |
| 510 | cpu = raw_smp_processor_id(); | 510 | cpu = raw_smp_processor_id(); |
| 511 | set_my_cpu_offset(per_cpu_offset(cpu)); | 511 | set_my_cpu_offset(per_cpu_offset(cpu)); |
| 512 | rcutree_report_cpu_starting(cpu); | ||
| 513 | 512 | ||
| 514 | cpu_probe(); | 513 | cpu_probe(); |
| 515 | constant_clockevent_init(); | 514 | constant_clockevent_init(); |
| @@ -675,7 +675,7 @@ static bool fault_supports_huge_mapping(struct kvm_memory_slot *memslot, · 674 unmodified lines | |||
| 675 | * | 675 | * |
| 676 | * There are several ways to safely use this helper: | 676 | * There are several ways to safely use this helper: |
| 677 | * | 677 | * |
| 678 | * - Check mmu_invalidate_retry_hva() after grabbing the mapping level, before | 678 | * - Check mmu_invalidate_retry_gfn() after grabbing the mapping level, before |
| 679 | * consuming it. In this case, mmu_lock doesn't need to be held during the | 679 | * consuming it. In this case, mmu_lock doesn't need to be held during the |
| 680 | * lookup, but it does need to be held while checking the MMU notifier. | 680 | * lookup, but it does need to be held while checking the MMU notifier. |
| 681 | * | 681 | * |
| @@ -855,7 +855,7 @@ retry: · 173 unmodified lines | |||
| 855 | 855 | ||
| 856 | /* Check if an invalidation has taken place since we got pfn */ | 856 | /* Check if an invalidation has taken place since we got pfn */ |
| 857 | spin_lock(&kvm->mmu_lock); | 857 | spin_lock(&kvm->mmu_lock); |
| 858 | if (mmu_invalidate_retry_hva(kvm, mmu_seq, hva)) { | 858 | if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn)) { |
| 859 | /* | 859 | /* |
| 860 | * This can happen when mappings are changed asynchronously, but | 860 | * This can happen when mappings are changed asynchronously, but |
| 861 | * also synchronously if a COW is triggered by | 861 | * also synchronously if a COW is triggered by |
| @@ -44,6 +44,9 @@ void *kasan_mem_to_shadow(const void *addr) · 43 unmodified lines | |||
| 44 | unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; | 44 | unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; |
| 45 | unsigned long offset = 0; | 45 | unsigned long offset = 0; |
| 46 | 46 | ||
| 47 | if (maddr >= FIXADDR_START) | ||
| 48 | return (void *)(kasan_early_shadow_page); | ||
| 49 | |||
| 47 | maddr &= XRANGE_SHADOW_MASK; | 50 | maddr &= XRANGE_SHADOW_MASK; |
| 48 | switch (xrange) { | 51 | switch (xrange) { |
| 49 | case XKPRANGE_CC_SEG: | 52 | case XKPRANGE_CC_SEG: |
| @@ -284,12 +284,16 @@ static void setup_tlb_handler(int cpu) · 283 unmodified lines | |||
| 284 | set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE); | 284 | set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE); |
| 285 | set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE); | 285 | set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE); |
| 286 | set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE); | 286 | set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE); |
| 287 | } | 287 | } else { |
| 288 | int vec_sz __maybe_unused; | ||
| 289 | void *addr __maybe_unused; | ||
| 290 | struct page *page __maybe_unused; | ||
| 291 | |||
| 292 | /* Avoid lockdep warning */ | ||
| 293 | rcutree_report_cpu_starting(cpu); | ||
| 294 | |||
| 288 | #ifdef CONFIG_NUMA | 295 | #ifdef CONFIG_NUMA |
| 289 | else { | 296 | vec_sz = sizeof(exception_handlers); |
| 290 | void *addr; | ||
| 291 | struct page *page; | ||
| 292 | const int vec_sz = sizeof(exception_handlers); | ||
| 293 | 297 | ||
| 294 | if (pcpu_handlers[cpu]) | 298 | if (pcpu_handlers[cpu]) |
| 295 | return; | 299 | return; |
| @@ -305,8 +309,8 @@ static void setup_tlb_handler(int cpu) · 9 unmodified lines | |||
| 305 | csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY); | 309 | csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY); |
| 306 | csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY); | 310 | csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY); |
| 307 | csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY); | 311 | csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY); |
| 308 | } | ||
| 309 | #endif | 312 | #endif |
| 313 | } | ||
| 310 | } | 314 | } |
| 311 | 315 | ||
| 312 | void tlb_init(int cpu) | 316 | void tlb_init(int cpu) |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | # Objects to go into the VDSO. | 2 | # Objects to go into the VDSO. |
| 3 | 3 | ||
| 4 | KASAN_SANITIZE := n | 4 | KASAN_SANITIZE := n |
| 5 | UBSAN_SANITIZE := n | ||
| 5 | KCOV_INSTRUMENT := n | 6 | KCOV_INSTRUMENT := n |
| 6 | 7 | ||
| 7 | # Include the generic Makefile to check the built vdso. | 8 | # Include the generic Makefile to check the built vdso. |
| @@ -15,10 +15,10 @@ · 14 unmodified lines | |||
| 15 | KBUILD_DEFCONFIG := multi_defconfig | 15 | KBUILD_DEFCONFIG := multi_defconfig |
| 16 | 16 | ||
| 17 | ifdef cross_compiling | 17 | ifdef cross_compiling |
| 18 | ifeq ($(CROSS_COMPILE),) | 18 | ifeq ($(CROSS_COMPILE),) |
| 19 | CROSS_COMPILE := $(call cc-cross-prefix, \ | 19 | CROSS_COMPILE := $(call cc-cross-prefix, \ |
| 20 | m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) | 20 | m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) |
| 21 | endif | 21 | endif |
| 22 | endif | 22 | endif |
| 23 | 23 | ||
| 24 | # | 24 | # |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | |||
| 40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
| 41 | 41 | ||
| 42 | #include <asm/bootinfo.h> | 42 | #include <asm/bootinfo.h> |
| 43 | #include <prom.h> | ||
| 43 | 44 | ||
| 44 | int prom_argc; | 45 | int prom_argc; |
| 45 | char **prom_argv; | 46 | char **prom_argv; |
| @@ -30,13 +30,11 @@ · 29 unmodified lines | |||
| 30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
| 31 | #include <linux/dma-map-ops.h> /* for dma_default_coherent */ | 31 | #include <linux/dma-map-ops.h> /* for dma_default_coherent */ |
| 32 | 32 | ||
| 33 | #include <asm/bootinfo.h> | ||
| 33 | #include <asm/mipsregs.h> | 34 | #include <asm/mipsregs.h> |
| 34 | 35 | ||
| 35 | #include <au1000.h> | 36 | #include <au1000.h> |
| 36 | 37 | ||
| 37 | extern void __init board_setup(void); | ||
| 38 | extern void __init alchemy_set_lpj(void); | ||
| 39 | |||
| 40 | static bool alchemy_dma_coherent(void) | 38 | static bool alchemy_dma_coherent(void) |
| 41 | { | 39 | { |
| 42 | switch (alchemy_get_cputype()) { | 40 | switch (alchemy_get_cputype()) { |
| @@ -702,7 +702,7 @@ static struct ssb_sprom bcm63xx_sprom = { · 701 unmodified lines | |||
| 702 | .boardflags_hi = 0x0000, | 702 | .boardflags_hi = 0x0000, |
| 703 | }; | 703 | }; |
| 704 | 704 | ||
| 705 | int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) | 705 | static int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) |
| 706 | { | 706 | { |
| 707 | if (bus->bustype == SSB_BUSTYPE_PCI) { | 707 | if (bus->bustype == SSB_BUSTYPE_PCI) { |
| 708 | memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom)); | 708 | memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom)); |
| @@ -26,7 +26,7 @@ static struct platform_device bcm63xx_rng_device = { · 25 unmodified lines | |||
| 26 | .resource = rng_resources, | 26 | .resource = rng_resources, |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | int __init bcm63xx_rng_register(void) | 29 | static int __init bcm63xx_rng_register(void) |
| 30 | { | 30 | { |
| 31 | if (!BCMCPU_IS_6368()) | 31 | if (!BCMCPU_IS_6368()) |
| 32 | return -ENODEV; | 32 | return -ENODEV; |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 12 | #include <bcm63xx_cpu.h> | 12 | #include <bcm63xx_cpu.h> |
| 13 | #include <bcm63xx_dev_uart.h> | ||
| 13 | 14 | ||
| 14 | static struct resource uart0_resources[] = { | 15 | static struct resource uart0_resources[] = { |
| 15 | { | 16 | { |
| @@ -34,7 +34,7 @@ static struct platform_device bcm63xx_wdt_device = { · 33 unmodified lines | |||
| 34 | }, | 34 | }, |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | int __init bcm63xx_wdt_register(void) | 37 | static int __init bcm63xx_wdt_register(void) |
| 38 | { | 38 | { |
| 39 | wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT); | 39 | wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT); |
| 40 | wdt_resources[0].end = wdt_resources[0].start; | 40 | wdt_resources[0].end = wdt_resources[0].start; |
| @@ -72,7 +72,7 @@ static inline int enable_irq_for_cpu(int cpu, struct irq_data *d, · 71 unmodified lines | |||
| 72 | */ | 72 | */ |
| 73 | 73 | ||
| 74 | #define BUILD_IPIC_INTERNAL(width) \ | 74 | #define BUILD_IPIC_INTERNAL(width) \ |
| 75 | void __dispatch_internal_##width(int cpu) \ | 75 | static void __dispatch_internal_##width(int cpu) \ |
| 76 | { \ | 76 | { \ |
| 77 | u32 pending[width / 32]; \ | 77 | u32 pending[width / 32]; \ |
| 78 | unsigned int src, tgt; \ | 78 | unsigned int src, tgt; \ |
| @@ -159,7 +159,7 @@ void __init plat_mem_setup(void) · 158 unmodified lines | |||
| 159 | board_setup(); | 159 | board_setup(); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | int __init bcm63xx_register_devices(void) | 162 | static int __init bcm63xx_register_devices(void) |
| 163 | { | 163 | { |
| 164 | /* register gpiochip */ | 164 | /* register gpiochip */ |
| 165 | bcm63xx_gpio_init(); | 165 | bcm63xx_gpio_init(); |
| @@ -178,7 +178,7 @@ int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us) · 177 unmodified lines | |||
| 178 | 178 | ||
| 179 | EXPORT_SYMBOL(bcm63xx_timer_set); | 179 | EXPORT_SYMBOL(bcm63xx_timer_set); |
| 180 | 180 | ||
| 181 | int bcm63xx_timer_init(void) | 181 | static int bcm63xx_timer_init(void) |
| 182 | { | 182 | { |
| 183 | int ret, irq; | 183 | int ret, irq; |
| 184 | u32 reg; | 184 | u32 reg; |
| @@ -23,9 +23,6 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include <cobalt.h> | 24 | #include <cobalt.h> |
| 25 | 25 | ||
| 26 | extern void cobalt_machine_restart(char *command); | ||
| 27 | extern void cobalt_machine_halt(void); | ||
| 28 | |||
| 29 | const char *get_system_type(void) | 26 | const char *get_system_type(void) |
| 30 | { | 27 | { |
| 31 | switch (cobalt_board_id) { | 28 | switch (cobalt_board_id) { |
| @@ -37,7 +37,7 @@ static unsigned int nr_prom_mem __initdata; · 36 unmodified lines | |||
| 37 | */ | 37 | */ |
| 38 | #define ARC_PAGE_SHIFT 12 | 38 | #define ARC_PAGE_SHIFT 12 |
| 39 | 39 | ||
| 40 | struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current) | 40 | static struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current) |
| 41 | { | 41 | { |
| 42 | return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); | 42 | return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); |
| 43 | } | 43 | } |
| @@ -39,7 +39,7 @@ extern void jump_label_apply_nops(struct module *mod); · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 40 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 41 | { | 41 | { |
| 42 | asm_volatile_goto("1:\t" B_INSN " 2f\n\t" | 42 | asm goto("1:\t" B_INSN " 2f\n\t" |
| 43 | "2:\t.insn\n\t" | 43 | "2:\t.insn\n\t" |
| 44 | ".pushsection __jump_table, \"aw\"\n\t" | 44 | ".pushsection __jump_table, \"aw\"\n\t" |
| 45 | WORD_INSN " 1b, %l[l_yes], %0\n\t" | 45 | WORD_INSN " 1b, %l[l_yes], %0\n\t" |
| @@ -53,7 +53,7 @@ l_yes: · 7 unmodified lines | |||
| 53 | 53 | ||
| 54 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) | 54 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) |
| 55 | { | 55 | { |
| 56 | asm_volatile_goto("1:\t" J_INSN " %l[l_yes]\n\t" | 56 | asm goto("1:\t" J_INSN " %l[l_yes]\n\t" |
| 57 | ".pushsection __jump_table, \"aw\"\n\t" | 57 | ".pushsection __jump_table, \"aw\"\n\t" |
| 58 | WORD_INSN " 1b, %l[l_yes], %0\n\t" | 58 | WORD_INSN " 1b, %l[l_yes], %0\n\t" |
| 59 | ".popsection\n\t" | 59 | ".popsection\n\t" |
| @@ -597,6 +597,9 @@ · 596 unmodified lines | |||
| 597 | 597 | ||
| 598 | #include <asm/cpu.h> | 598 | #include <asm/cpu.h> |
| 599 | 599 | ||
| 600 | void alchemy_set_lpj(void); | ||
| 601 | void board_setup(void); | ||
| 602 | |||
| 600 | /* helpers to access the SYS_* registers */ | 603 | /* helpers to access the SYS_* registers */ |
| 601 | static inline unsigned long alchemy_rdsys(int regofs) | 604 | static inline unsigned long alchemy_rdsys(int regofs) |
| 602 | { | 605 | { |
| @@ -19,4 +19,7 @@ extern int cobalt_board_id; · 18 unmodified lines | |||
| 19 | #define COBALT_BRD_ID_QUBE2 0x5 | 19 | #define COBALT_BRD_ID_QUBE2 0x5 |
| 20 | #define COBALT_BRD_ID_RAQ2 0x6 | 20 | #define COBALT_BRD_ID_RAQ2 0x6 |
| 21 | 21 | ||
| 22 | void cobalt_machine_halt(void); | ||
| 23 | void cobalt_machine_restart(char *command); | ||
| 24 | |||
| 22 | #endif /* __ASM_COBALT_H */ | 25 | #endif /* __ASM_COBALT_H */ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include <asm/cpu-features.h> | 12 | #include <asm/cpu-features.h> |
| 13 | #include <asm/cpu-info.h> | 13 | #include <asm/cpu-info.h> |
| 14 | #include <asm/fpu.h> | ||
| 14 | 15 | ||
| 15 | #ifdef CONFIG_MIPS_FP_SUPPORT | 16 | #ifdef CONFIG_MIPS_FP_SUPPORT |
| 16 | 17 | ||
| @@ -309,6 +310,11 @@ void mips_set_personality_nan(struct arch_elf_state *state) · 292 unmodified lines | |||
| 309 | struct cpuinfo_mips *c = &boot_cpu_data; | 310 | struct cpuinfo_mips *c = &boot_cpu_data; |
| 310 | struct task_struct *t = current; | 311 | struct task_struct *t = current; |
| 311 | 312 | ||
| 313 | /* Do this early so t->thread.fpu.fcr31 won't be clobbered in case | ||
| 314 | * we are preempted before the lose_fpu(0) in start_thread. | ||
| 315 | */ | ||
| 316 | lose_fpu(0); | ||
| 317 | |||
| 312 | t->thread.fpu.fcr31 = c->fpu_csr31; | 318 | t->thread.fpu.fcr31 = c->fpu_csr31; |
| 313 | switch (state->nan_2008) { | 319 | switch (state->nan_2008) { |
| 314 | case 0: | 320 | case 0: |
| @@ -2007,7 +2007,13 @@ unsigned long vi_handlers[64]; · 2006 unmodified lines | |||
| 2007 | 2007 | ||
| 2008 | void reserve_exception_space(phys_addr_t addr, unsigned long size) | 2008 | void reserve_exception_space(phys_addr_t addr, unsigned long size) |
| 2009 | { | 2009 | { |
| 2010 | memblock_reserve(addr, size); | 2010 | /* |
| 2011 | * reserve exception space on CPUs other than CPU0 | ||
| 2012 | * is too late, since memblock is unavailable when APs | ||
| 2013 | * up | ||
| 2014 | */ | ||
| 2015 | if (smp_processor_id() == 0) | ||
| 2016 | memblock_reserve(addr, size); | ||
| 2011 | } | 2017 | } |
| 2012 | 2018 | ||
| 2013 | void __init *set_except_vector(int n, void *addr) | 2019 | void __init *set_except_vector(int n, void *addr) |
| @@ -108,10 +108,9 @@ void __init prom_init(void) · 107 unmodified lines | |||
| 108 | prom_init_cmdline(); | 108 | prom_init_cmdline(); |
| 109 | 109 | ||
| 110 | #if defined(CONFIG_MIPS_MT_SMP) | 110 | #if defined(CONFIG_MIPS_MT_SMP) |
| 111 | if (cpu_has_mipsmt) { | 111 | lantiq_smp_ops = vsmp_smp_ops; |
| 112 | lantiq_smp_ops = vsmp_smp_ops; | 112 | if (cpu_has_mipsmt) |
| 113 | lantiq_smp_ops.init_secondary = lantiq_init_secondary; | 113 | lantiq_smp_ops.init_secondary = lantiq_init_secondary; |
| 114 | register_smp_ops(&lantiq_smp_ops); | 114 | register_smp_ops(&lantiq_smp_ops); |
| 115 | } | ||
| 116 | #endif | 115 | #endif |
| 117 | } | 116 | } |
| @@ -103,6 +103,9 @@ void __init szmem(unsigned int node) · 102 unmodified lines | |||
| 103 | if (loongson_sysconf.vgabios_addr) | 103 | if (loongson_sysconf.vgabios_addr) |
| 104 | memblock_reserve(virt_to_phys((void *)loongson_sysconf.vgabios_addr), | 104 | memblock_reserve(virt_to_phys((void *)loongson_sysconf.vgabios_addr), |
| 105 | SZ_256K); | 105 | SZ_256K); |
| 106 | /* set nid for reserved memory */ | ||
| 107 | memblock_set_node((u64)node << 44, (u64)(node + 1) << 44, | ||
| 108 | &memblock.reserved, node); | ||
| 106 | } | 109 | } |
| 107 | 110 | ||
| 108 | #ifndef CONFIG_NUMA | 111 | #ifndef CONFIG_NUMA |
| @@ -132,6 +132,8 @@ static void __init node_mem_init(unsigned int node) · 131 unmodified lines | |||
| 132 | 132 | ||
| 133 | /* Reserve pfn range 0~node[0]->node_start_pfn */ | 133 | /* Reserve pfn range 0~node[0]->node_start_pfn */ |
| 134 | memblock_reserve(0, PAGE_SIZE * start_pfn); | 134 | memblock_reserve(0, PAGE_SIZE * start_pfn); |
| 135 | /* set nid for reserved memory on node 0 */ | ||
| 136 | memblock_set_node(0, 1ULL << 44, &memblock.reserved, 0); | ||
| 135 | } | 137 | } |
| 136 | } | 138 | } |
| 137 | 139 | ||
| @@ -5,7 +5,7 @@ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o \ | 6 | obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o \ |
| 7 | ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \ | 7 | ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \ |
| 8 | ip27-hubio.o ip27-xtalk.o | 8 | ip27-xtalk.o |
| 9 | 9 | ||
| 10 | obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o | 10 | obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o |
| 11 | obj-$(CONFIG_SMP) += ip27-smp.o | 11 | obj-$(CONFIG_SMP) += ip27-smp.o |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | |||
| 22 | #include <asm/traps.h> | 22 | #include <asm/traps.h> |
| 23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
| 24 | 24 | ||
| 25 | #include "ip27-common.h" | ||
| 26 | |||
| 25 | static void dump_hub_information(unsigned long errst0, unsigned long errst1) | 27 | static void dump_hub_information(unsigned long errst0, unsigned long errst1) |
| 26 | { | 28 | { |
| 27 | static char *err_type[2][8] = { | 29 | static char *err_type[2][8] = { |
| @@ -57,7 +59,7 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1) · 29 unmodified lines | |||
| 57 | [st0.pi_stat0_fmt.s0_err_type] ? : "invalid"); | 59 | [st0.pi_stat0_fmt.s0_err_type] ? : "invalid"); |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | int ip27_be_handler(struct pt_regs *regs, int is_fixup) | 62 | static int ip27_be_handler(struct pt_regs *regs, int is_fixup) |
| 61 | { | 63 | { |
| 62 | unsigned long errst0, errst1; | 64 | unsigned long errst0, errst1; |
| 63 | int data = regs->cp0_cause & 4; | 65 | int data = regs->cp0_cause & 4; |
| @@ -10,6 +10,7 @@ extern void hub_rt_clock_event_init(void); · 9 unmodified lines | |||
| 10 | extern void hub_rtc_init(nasid_t nasid); | 10 | extern void hub_rtc_init(nasid_t nasid); |
| 11 | extern void install_cpu_nmi_handler(int slice); | 11 | extern void install_cpu_nmi_handler(int slice); |
| 12 | extern void install_ipi(void); | 12 | extern void install_ipi(void); |
| 13 | extern void ip27_be_init(void); | ||
| 13 | extern void ip27_reboot_setup(void); | 14 | extern void ip27_reboot_setup(void); |
| 14 | extern const struct plat_smp_ops ip27_smp_ops; | 15 | extern const struct plat_smp_ops ip27_smp_ops; |
| 15 | extern unsigned long node_getfirstfree(nasid_t nasid); | 16 | extern unsigned long node_getfirstfree(nasid_t nasid); |
| @@ -17,4 +18,5 @@ extern void per_cpu_init(void); · 1 unmodified line | |||
| 17 | extern void replicate_kernel_text(void); | 18 | extern void replicate_kernel_text(void); |
| 18 | extern void setup_replication_mask(void); | 19 | extern void setup_replication_mask(void); |
| 19 | 20 | ||
| 21 | |||
| 20 | #endif /* __IP27_COMMON_H */ | 22 | #endif /* __IP27_COMMON_H */ |
| @@ -1,185 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. | ||
| 4 | * Copyright (C) 2004 Christoph Hellwig. | ||
| 5 | * | ||
| 6 | * Support functions for the HUB ASIC - mostly PIO mapping related. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/bitops.h> | ||
| 10 | #include <linux/string.h> | ||
| 11 | #include <linux/mmzone.h> | ||
| 12 | #include <asm/sn/addrs.h> | ||
| 13 | #include <asm/sn/arch.h> | ||
| 14 | #include <asm/sn/agent.h> | ||
| 15 | #include <asm/sn/io.h> | ||
| 16 | #include <asm/xtalk/xtalk.h> | ||
| 17 | |||
| 18 | |||
| 19 | static int force_fire_and_forget = 1; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * hub_pio_map - establish a HUB PIO mapping | ||
| 23 | * | ||
| 24 | * @nasid: nasid to perform PIO mapping on | ||
| 25 | * @widget: widget ID to perform PIO mapping for | ||
| 26 | * @xtalk_addr: xtalk_address that needs to be mapped | ||
| 27 | * @size: size of the PIO mapping | ||
| 28 | * | ||
| 29 | **/ | ||
| 30 | unsigned long hub_pio_map(nasid_t nasid, xwidgetnum_t widget, | ||
| 31 | unsigned long xtalk_addr, size_t size) | ||
| 32 | { | ||
| 33 | unsigned i; | ||
| 34 | |||
| 35 | /* use small-window mapping if possible */ | ||
| 36 | if ((xtalk_addr % SWIN_SIZE) + size <= SWIN_SIZE) | ||
| 37 | return NODE_SWIN_BASE(nasid, widget) + (xtalk_addr % SWIN_SIZE); | ||
| 38 | |||
| 39 | if ((xtalk_addr % BWIN_SIZE) + size > BWIN_SIZE) { | ||
| 40 | printk(KERN_WARNING "PIO mapping at hub %d widget %d addr 0x%lx" | ||
| 41 | " too big (%ld)\n", | ||
| 42 | nasid, widget, xtalk_addr, size); | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | xtalk_addr &= ~(BWIN_SIZE-1); | ||
| 47 | for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) { | ||
| 48 | if (test_and_set_bit(i, hub_data(nasid)->h_bigwin_used)) | ||
| 49 | continue; | ||
| 50 | |||
| 51 | /* | ||
| 52 | * The code below does a PIO write to setup an ITTE entry. | ||
| 53 | * | ||
| 54 | * We need to prevent other CPUs from seeing our updated | ||
| 55 | * memory shadow of the ITTE (in the piomap) until the ITTE | ||
| 56 | * entry is actually set up; otherwise, another CPU might | ||
| 57 | * attempt a PIO prematurely. | ||
| 58 | * | ||
| 59 | * Also, the only way we can know that an entry has been | ||
| 60 | * received by the hub and can be used by future PIO reads/ | ||
| 61 | * writes is by reading back the ITTE entry after writing it. | ||
| 62 | * | ||
| 63 | * For these two reasons, we PIO read back the ITTE entry | ||
| 64 | * after we write it. | ||
| 65 | */ | ||
| 66 | IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr); | ||
| 67 | __raw_readq(IIO_ITTE_GET(nasid, i)); | ||
| 68 | |||
| 69 | return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE); | ||
| 70 | } | ||
| 71 | |||
| 72 | printk(KERN_WARNING "unable to establish PIO mapping for at" | ||
| 73 | " hub %d widget %d addr 0x%lx\n", | ||
| 74 | nasid, widget, xtalk_addr); | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | /* | ||
| 80 | * hub_setup_prb(nasid, prbnum, credits, conveyor) | ||
| 81 | * | ||
| 82 | * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise, | ||
| 83 | * put it into conveyor belt mode with the specified number of credits. | ||
| 84 | */ | ||
| 85 | static void hub_setup_prb(nasid_t nasid, int prbnum, int credits) | ||
| 86 | { | ||
| 87 | union iprb_u prb; | ||
| 88 | int prb_offset; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * Get the current register value. | ||
| 92 | */ | ||
| 93 | prb_offset = IIO_IOPRB(prbnum); | ||
| 94 | prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset); | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Clear out some fields. | ||
| 98 | */ | ||
| 99 | prb.iprb_ovflow = 1; | ||
| 100 | prb.iprb_bnakctr = 0; | ||
| 101 | prb.iprb_anakctr = 0; | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Enable or disable fire-and-forget mode. | ||
| 105 | */ | ||
| 106 | prb.iprb_ff = force_fire_and_forget ? 1 : 0; | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Set the appropriate number of PIO credits for the widget. | ||
| 110 | */ | ||
| 111 | prb.iprb_xtalkctr = credits; | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Store the new value to the register. | ||
| 115 | */ | ||
| 116 | REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval); | ||
| 117 | } | ||
| 118 | |||
| 119 | /** | ||
| 120 | * hub_set_piomode - set pio mode for a given hub | ||
| 121 | * | ||
| 122 | * @nasid: physical node ID for the hub in question | ||
| 123 | * | ||
| 124 | * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget" mode. | ||
| 125 | * To do this, we have to make absolutely sure that no PIOs are in progress | ||
| 126 | * so we turn off access to all widgets for the duration of the function. | ||
| 127 | * | ||
| 128 | * XXX - This code should really check what kind of widget we're talking | ||
| 129 | * to. Bridges can only handle three requests, but XG will do more. | ||
| 130 | * How many can crossbow handle to widget 0? We're assuming 1. | ||
| 131 | * | ||
| 132 | * XXX - There is a bug in the crossbow that link reset PIOs do not | ||
| 133 | * return write responses. The easiest solution to this problem is to | ||
| 134 | * leave widget 0 (xbow) in fire-and-forget mode at all times. This | ||
| 135 | * only affects pio's to xbow registers, which should be rare. | ||
| 136 | **/ | ||
| 137 | static void hub_set_piomode(nasid_t nasid) | ||
| 138 | { | ||
| 139 | u64 ii_iowa; | ||
| 140 | union hubii_wcr_u ii_wcr; | ||
| 141 | unsigned i; | ||
| 142 | |||
| 143 | ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS); | ||
| 144 | REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0); | ||
| 145 | |||
| 146 | ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR); | ||
| 147 | |||
| 148 | if (ii_wcr.iwcr_dir_con) { | ||
| 149 | /* | ||
| 150 | * Assume a bridge here. | ||
| 151 | */ | ||
| 152 | hub_setup_prb(nasid, 0, 3); | ||
| 153 | } else { | ||
| 154 | /* | ||
| 155 | * Assume a crossbow here. | ||
| 156 | */ | ||
| 157 | hub_setup_prb(nasid, 0, 1); | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * XXX - Here's where we should take the widget type into | ||
| 162 | * when account assigning credits. | ||
| 163 | */ | ||
| 164 | for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) | ||
| 165 | hub_setup_prb(nasid, i, 3); | ||
| 166 | |||
| 167 | REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa); | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * hub_pio_init - PIO-related hub initialization | ||
| 172 | * | ||
| 173 | * @hub: hubinfo structure for our hub | ||
| 174 | */ | ||
| 175 | void hub_pio_init(nasid_t nasid) | ||
| 176 | { | ||
| 177 | unsigned i; | ||
| 178 | |||
| 179 | /* initialize big window piomaps for this hub */ | ||
| 180 | bitmap_zero(hub_data(nasid)->h_bigwin_used, HUB_NUM_BIG_WINDOW); | ||
| 181 | for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) | ||
| 182 | IIO_ITTE_DISABLE(nasid, i); | ||
| 183 | |||
| 184 | hub_set_piomode(nasid); | ||
| 185 | } | ||
| @@ -23,6 +23,8 @@ · 22 unmodified lines | |||
| 23 | #include <asm/sn/intr.h> | 23 | #include <asm/sn/intr.h> |
| 24 | #include <asm/sn/irq_alloc.h> | 24 | #include <asm/sn/irq_alloc.h> |
| 25 | 25 | ||
| 26 | #include "ip27-common.h" | ||
| 27 | |||
| 26 | struct hub_irq_data { | 28 | struct hub_irq_data { |
| 27 | u64 *irq_mask[2]; | 29 | u64 *irq_mask[2]; |
| 28 | cpuid_t cpu; | 30 | cpuid_t cpu; |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #include <asm/page.h> | 23 | #include <asm/page.h> |
| 24 | #include <asm/pgalloc.h> | 24 | #include <asm/pgalloc.h> |
| 25 | #include <asm/sections.h> | 25 | #include <asm/sections.h> |
| 26 | #include <asm/sgialib.h> | ||
| 26 | 27 | ||
| 27 | #include <asm/sn/arch.h> | 28 | #include <asm/sn/arch.h> |
| 28 | #include <asm/sn/agent.h> | 29 | #include <asm/sn/agent.h> |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include <asm/sn/arch.h> | 11 | #include <asm/sn/arch.h> |
| 12 | #include <asm/sn/agent.h> | 12 | #include <asm/sn/agent.h> |
| 13 | 13 | ||
| 14 | #include "ip27-common.h" | ||
| 15 | |||
| 14 | #if 0 | 16 | #if 0 |
| 15 | #define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n) | 17 | #define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n) |
| 16 | #else | 18 | #else |
| @@ -23,16 +25,7 @@ · 6 unmodified lines | |||
| 23 | typedef unsigned long machreg_t; | 25 | typedef unsigned long machreg_t; |
| 24 | 26 | ||
| 25 | static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED; | 27 | static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED; |
| 26 | 28 | static void nmi_dump(void); | |
| 27 | /* | ||
| 28 | * Let's see what else we need to do here. Set up sp, gp? | ||
| 29 | */ | ||
| 30 | void nmi_dump(void) | ||
| 31 | { | ||
| 32 | void cont_nmi_dump(void); | ||
| 33 | |||
| 34 | cont_nmi_dump(); | ||
| 35 | } | ||
| 36 | 29 | ||
| 37 | void install_cpu_nmi_handler(int slice) | 30 | void install_cpu_nmi_handler(int slice) |
| 38 | { | 31 | { |
| @@ -53,7 +46,7 @@ void install_cpu_nmi_handler(int slice) · 14 unmodified lines | |||
| 53 | * into the eframe format for the node under consideration. | 46 | * into the eframe format for the node under consideration. |
| 54 | */ | 47 | */ |
| 55 | 48 | ||
| 56 | void nmi_cpu_eframe_save(nasid_t nasid, int slice) | 49 | static void nmi_cpu_eframe_save(nasid_t nasid, int slice) |
| 57 | { | 50 | { |
| 58 | struct reg_struct *nr; | 51 | struct reg_struct *nr; |
| 59 | int i; | 52 | int i; |
| @@ -129,7 +122,7 @@ void nmi_cpu_eframe_save(nasid_t nasid, int slice) · 69 unmodified lines | |||
| 129 | pr_emerg("\n"); | 122 | pr_emerg("\n"); |
| 130 | } | 123 | } |
| 131 | 124 | ||
| 132 | void nmi_dump_hub_irq(nasid_t nasid, int slice) | 125 | static void nmi_dump_hub_irq(nasid_t nasid, int slice) |
| 133 | { | 126 | { |
| 134 | u64 mask0, mask1, pend0, pend1; | 127 | u64 mask0, mask1, pend0, pend1; |
| 135 | 128 | ||
| @@ -153,7 +146,7 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice) · 17 unmodified lines | |||
| 153 | * Copy the cpu registers which have been saved in the IP27prom format | 146 | * Copy the cpu registers which have been saved in the IP27prom format |
| 154 | * into the eframe format for the node under consideration. | 147 | * into the eframe format for the node under consideration. |
| 155 | */ | 148 | */ |
| 156 | void nmi_node_eframe_save(nasid_t nasid) | 149 | static void nmi_node_eframe_save(nasid_t nasid) |
| 157 | { | 150 | { |
| 158 | int slice; | 151 | int slice; |
| 159 | 152 | ||
| @@ -170,8 +163,7 @@ void nmi_node_eframe_save(nasid_t nasid) · 10 unmodified lines | |||
| 170 | /* | 163 | /* |
| 171 | * Save the nmi cpu registers for all cpus in the system. | 164 | * Save the nmi cpu registers for all cpus in the system. |
| 172 | */ | 165 | */ |
| 173 | void | 166 | static void nmi_eframes_save(void) |
| 174 | nmi_eframes_save(void) | ||
| 175 | { | 167 | { |
| 176 | nasid_t nasid; | 168 | nasid_t nasid; |
| 177 | 169 | ||
| @@ -179,8 +171,7 @@ nmi_eframes_save(void) · 1 unmodified line | |||
| 179 | nmi_node_eframe_save(nasid); | 171 | nmi_node_eframe_save(nasid); |
| 180 | } | 172 | } |
| 181 | 173 | ||
| 182 | void | 174 | static void nmi_dump(void) |
| 183 | cont_nmi_dump(void) | ||
| 184 | { | 175 | { |
| 185 | #ifndef REAL_NMI_SIGNAL | 176 | #ifndef REAL_NMI_SIGNAL |
| 186 | static atomic_t nmied_cpus = ATOMIC_INIT(0); | 177 | static atomic_t nmied_cpus = ATOMIC_INIT(0); |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | #include <linux/io.h> | 3 | #include <linux/io.h> |
| 4 | 4 | ||
| 5 | #include <asm/sn/ioc3.h> | 5 | #include <asm/sn/ioc3.h> |
| 6 | #include <asm/setup.h> | ||
| 6 | 7 | ||
| 7 | static inline struct ioc3_uartregs *console_uart(void) | 8 | static inline struct ioc3_uartregs *console_uart(void) |
| 8 | { | 9 | { |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/percpu.h> | 14 | #include <linux/percpu.h> |
| 15 | #include <linux/memblock.h> | 15 | #include <linux/memblock.h> |
| 16 | 16 | ||
| 17 | #include <asm/bootinfo.h> | ||
| 17 | #include <asm/smp-ops.h> | 18 | #include <asm/smp-ops.h> |
| 18 | #include <asm/sgialib.h> | 19 | #include <asm/sgialib.h> |
| 19 | #include <asm/time.h> | 20 | #include <asm/time.h> |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <asm/ip32/crime.h> | 18 | #include <asm/ip32/crime.h> |
| 19 | #include <asm/ip32/mace.h> | 19 | #include <asm/ip32/mace.h> |
| 20 | 20 | ||
| 21 | #include "ip32-common.h" | ||
| 22 | |||
| 21 | struct sgi_crime __iomem *crime; | 23 | struct sgi_crime __iomem *crime; |
| 22 | struct sgi_mace __iomem *mace; | 24 | struct sgi_mace __iomem *mace; |
| 23 | 25 | ||
| @@ -39,7 +41,7 @@ void __init crime_init(void) · 15 unmodified lines | |||
| 39 | id, rev, field, (unsigned long) CRIME_BASE); | 41 | id, rev, field, (unsigned long) CRIME_BASE); |
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id) | 44 | irqreturn_t crime_memerr_intr(int irq, void *dev_id) |
| 43 | { | 45 | { |
| 44 | unsigned long stat, addr; | 46 | unsigned long stat, addr; |
| 45 | int fatal = 0; | 47 | int fatal = 0; |
| @@ -90,7 +92,7 @@ irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id) · 44 unmodified lines | |||
| 90 | return IRQ_HANDLED; | 92 | return IRQ_HANDLED; |
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | irqreturn_t crime_cpuerr_intr(unsigned int irq, void *dev_id) | 95 | irqreturn_t crime_cpuerr_intr(int irq, void *dev_id) |
| 94 | { | 96 | { |
| 95 | unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK; | 97 | unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK; |
| 96 | unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK; | 98 | unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK; |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <asm/ptrace.h> | 18 | #include <asm/ptrace.h> |
| 19 | #include <asm/tlbdebug.h> | 19 | #include <asm/tlbdebug.h> |
| 20 | 20 | ||
| 21 | #include "ip32-common.h" | ||
| 22 | |||
| 21 | static int ip32_be_handler(struct pt_regs *regs, int is_fixup) | 23 | static int ip32_be_handler(struct pt_regs *regs, int is_fixup) |
| 22 | { | 24 | { |
| 23 | int data = regs->cp0_cause & 4; | 25 | int data = regs->cp0_cause & 4; |
| @@ -0,0 +1,15 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | |||
| 3 | #ifndef __IP32_COMMON_H | ||
| 4 | #define __IP32_COMMON_H | ||
| 5 | |||
| 6 | #include <linux/init.h> | ||
| 7 | #include <linux/interrupt.h> | ||
| 8 | |||
| 9 | void __init crime_init(void); | ||
| 10 | irqreturn_t crime_memerr_intr(int irq, void *dev_id); | ||
| 11 | irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); | ||
| 12 | void __init ip32_be_init(void); | ||
| 13 | void ip32_prepare_poweroff(void); | ||
| 14 | |||
| 15 | #endif /* __IP32_COMMON_H */ | ||
| @@ -28,6 +28,8 @@ · 27 unmodified lines | |||
| 28 | #include <asm/ip32/mace.h> | 28 | #include <asm/ip32/mace.h> |
| 29 | #include <asm/ip32/ip32_ints.h> | 29 | #include <asm/ip32/ip32_ints.h> |
| 30 | 30 | ||
| 31 | #include "ip32-common.h" | ||
| 32 | |||
| 31 | /* issue a PIO read to make sure no PIO writes are pending */ | 33 | /* issue a PIO read to make sure no PIO writes are pending */ |
| 32 | static inline void flush_crime_bus(void) | 34 | static inline void flush_crime_bus(void) |
| 33 | { | 35 | { |
| @@ -107,10 +109,6 @@ static inline void flush_mace_bus(void) · 73 unmodified lines | |||
| 107 | * is quite different anyway. | 109 | * is quite different anyway. |
| 108 | */ | 110 | */ |
| 109 | 111 | ||
| 110 | /* Some initial interrupts to set up */ | ||
| 111 | extern irqreturn_t crime_memerr_intr(int irq, void *dev_id); | ||
| 112 | extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); | ||
| 113 | |||
| 114 | /* | 112 | /* |
| 115 | * This is for pure CRIME interrupts - ie not MACE. The advantage? | 113 | * This is for pure CRIME interrupts - ie not MACE. The advantage? |
| 116 | * We get to split the register in half and do faster lookups. | 114 | * We get to split the register in half and do faster lookups. |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <asm/ip32/crime.h> | 15 | #include <asm/ip32/crime.h> |
| 16 | #include <asm/bootinfo.h> | 16 | #include <asm/bootinfo.h> |
| 17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
| 18 | #include <asm/sgialib.h> | ||
| 18 | 19 | ||
| 19 | extern void crime_init(void); | 20 | extern void crime_init(void); |
| 20 | 21 | ||
| @@ -29,6 +29,8 @@ · 28 unmodified lines | |||
| 29 | #include <asm/ip32/crime.h> | 29 | #include <asm/ip32/crime.h> |
| 30 | #include <asm/ip32/ip32_ints.h> | 30 | #include <asm/ip32/ip32_ints.h> |
| 31 | 31 | ||
| 32 | #include "ip32-common.h" | ||
| 33 | |||
| 32 | #define POWERDOWN_TIMEOUT 120 | 34 | #define POWERDOWN_TIMEOUT 120 |
| 33 | /* | 35 | /* |
| 34 | * Blink frequency during reboot grace period and when panicked. | 36 | * Blink frequency during reboot grace period and when panicked. |
| @@ -26,8 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <asm/ip32/mace.h> | 26 | #include <asm/ip32/mace.h> |
| 27 | #include <asm/ip32/ip32_ints.h> | 27 | #include <asm/ip32/ip32_ints.h> |
| 28 | 28 | ||
| 29 | extern void ip32_be_init(void); | 29 | #include "ip32-common.h" |
| 30 | extern void crime_init(void); | ||
| 31 | 30 | ||
| 32 | #ifdef CONFIG_SGI_O2MACE_ETH | 31 | #ifdef CONFIG_SGI_O2MACE_ETH |
| 33 | /* | 32 | /* |
| @@ -25,7 +25,6 @@ config PARISC · 24 unmodified lines | |||
| 25 | select RTC_DRV_GENERIC | 25 | select RTC_DRV_GENERIC |
| 26 | select INIT_ALL_POSSIBLE | 26 | select INIT_ALL_POSSIBLE |
| 27 | select BUG | 27 | select BUG |
| 28 | select BUILDTIME_TABLE_SORT | ||
| 29 | select HAVE_KERNEL_UNCOMPRESSED | 28 | select HAVE_KERNEL_UNCOMPRESSED |
| 30 | select HAVE_PCI | 29 | select HAVE_PCI |
| 31 | select HAVE_PERF_EVENTS | 30 | select HAVE_PERF_EVENTS |
| @@ -50,12 +50,12 @@ export CROSS32CC · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | # Set default cross compiler for kernel build | 51 | # Set default cross compiler for kernel build |
| 52 | ifdef cross_compiling | 52 | ifdef cross_compiling |
| 53 | ifeq ($(CROSS_COMPILE),) | 53 | ifeq ($(CROSS_COMPILE),) |
| 54 | CC_SUFFIXES = linux linux-gnu unknown-linux-gnu suse-linux | 54 | CC_SUFFIXES = linux linux-gnu unknown-linux-gnu suse-linux |
| 55 | CROSS_COMPILE := $(call cc-cross-prefix, \ | 55 | CROSS_COMPILE := $(call cc-cross-prefix, \ |
| 56 | $(foreach a,$(CC_ARCHES), \ | 56 | $(foreach a,$(CC_ARCHES), \ |
| 57 | $(foreach s,$(CC_SUFFIXES),$(a)-$(s)-))) | 57 | $(foreach s,$(CC_SUFFIXES),$(a)-$(s)-))) |
| 58 | endif | 58 | endif |
| 59 | endif | 59 | endif |
| 60 | 60 | ||
| 61 | ifdef CONFIG_DYNAMIC_FTRACE | 61 | ifdef CONFIG_DYNAMIC_FTRACE |
| @@ -576,6 +576,7 @@ · 575 unmodified lines | |||
| 576 | .section __ex_table,"aw" ! \ | 576 | .section __ex_table,"aw" ! \ |
| 577 | .align 4 ! \ | 577 | .align 4 ! \ |
| 578 | .word (fault_addr - .), (except_addr - .) ! \ | 578 | .word (fault_addr - .), (except_addr - .) ! \ |
| 579 | or %r0,%r0,%r0 ! \ | ||
| 579 | .previous | 580 | .previous |
| 580 | 581 | ||
| 581 | 582 | ||
| @@ -0,0 +1,64 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef __PARISC_EXTABLE_H | ||
| 3 | #define __PARISC_EXTABLE_H | ||
| 4 | |||
| 5 | #include <asm/ptrace.h> | ||
| 6 | #include <linux/compiler.h> | ||
| 7 | |||
| 8 | /* | ||
| 9 | * The exception table consists of three addresses: | ||
| 10 | * | ||
| 11 | * - A relative address to the instruction that is allowed to fault. | ||
| 12 | * - A relative address at which the program should continue (fixup routine) | ||
| 13 | * - An asm statement which specifies which CPU register will | ||
| 14 | * receive -EFAULT when an exception happens if the lowest bit in | ||
| 15 | * the fixup address is set. | ||
| 16 | * | ||
| 17 | * Note: The register specified in the err_opcode instruction will be | ||
| 18 | * modified at runtime if a fault happens. Register %r0 will be ignored. | ||
| 19 | * | ||
| 20 | * Since relative addresses are used, 32bit values are sufficient even on | ||
| 21 | * 64bit kernel. | ||
| 22 | */ | ||
| 23 | |||
| 24 | struct pt_regs; | ||
| 25 | int fixup_exception(struct pt_regs *regs); | ||
| 26 | |||
| 27 | #define ARCH_HAS_RELATIVE_EXTABLE | ||
| 28 | struct exception_table_entry { | ||
| 29 | int insn; /* relative address of insn that is allowed to fault. */ | ||
| 30 | int fixup; /* relative address of fixup routine */ | ||
| 31 | int err_opcode; /* sample opcode with register which holds error code */ | ||
| 32 | }; | ||
| 33 | |||
| 34 | #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr, opcode )\ | ||
| 35 | ".section __ex_table,\"aw\"\n" \ | ||
| 36 | ".align 4\n" \ | ||
| 37 | ".word (" #fault_addr " - .), (" #except_addr " - .)\n" \ | ||
| 38 | opcode "\n" \ | ||
| 39 | ".previous\n" | ||
| 40 | |||
| 41 | /* | ||
| 42 | * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry | ||
| 43 | * (with lowest bit set) for which the fault handler in fixup_exception() will | ||
| 44 | * load -EFAULT on fault into the register specified by the err_opcode instruction, | ||
| 45 | * and zeroes the target register in case of a read fault in get_user(). | ||
| 46 | */ | ||
| 47 | #define ASM_EXCEPTIONTABLE_VAR(__err_var) \ | ||
| 48 | int __err_var = 0 | ||
| 49 | #define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr, register )\ | ||
| 50 | ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1, "or %%r0,%%r0," register) | ||
| 51 | |||
| 52 | static inline void swap_ex_entry_fixup(struct exception_table_entry *a, | ||
| 53 | struct exception_table_entry *b, | ||
| 54 | struct exception_table_entry tmp, | ||
| 55 | int delta) | ||
| 56 | { | ||
| 57 | a->fixup = b->fixup + delta; | ||
| 58 | b->fixup = tmp.fixup - delta; | ||
| 59 | a->err_opcode = b->err_opcode; | ||
| 60 | b->err_opcode = tmp.err_opcode; | ||
| 61 | } | ||
| 62 | #define swap_ex_entry_fixup swap_ex_entry_fixup | ||
| 63 | |||
| 64 | #endif | ||
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 13 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 14 | { | 14 | { |
| 15 | asm_volatile_goto("1:\n\t" | 15 | asm goto("1:\n\t" |
| 16 | "nop\n\t" | 16 | "nop\n\t" |
| 17 | ".pushsection __jump_table, \"aw\"\n\t" | 17 | ".pushsection __jump_table, \"aw\"\n\t" |
| 18 | ".align %1\n\t" | 18 | ".align %1\n\t" |
| @@ -29,7 +29,7 @@ l_yes: · 10 unmodified lines | |||
| 29 | 29 | ||
| 30 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) | 30 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) |
| 31 | { | 31 | { |
| 32 | asm_volatile_goto("1:\n\t" | 32 | asm goto("1:\n\t" |
| 33 | "b,n %l[l_yes]\n\t" | 33 | "b,n %l[l_yes]\n\t" |
| 34 | ".pushsection __jump_table, \"aw\"\n\t" | 34 | ".pushsection __jump_table, \"aw\"\n\t" |
| 35 | ".align %1\n\t" | 35 | ".align %1\n\t" |
| @@ -8,7 +8,8 @@ · 7 unmodified lines | |||
| 8 | "copy %%r0,%0\n" \ | 8 | "copy %%r0,%0\n" \ |
| 9 | "8:\tlpa %%r0(%1),%0\n" \ | 9 | "8:\tlpa %%r0(%1),%0\n" \ |
| 10 | "9:\n" \ | 10 | "9:\n" \ |
| 11 | ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ | 11 | ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ |
| 12 | "or %%r0,%%r0,%%r0") \ | ||
| 12 | : "=&r" (pa) \ | 13 | : "=&r" (pa) \ |
| 13 | : "r" (va) \ | 14 | : "r" (va) \ |
| 14 | : "memory" \ | 15 | : "memory" \ |
| @@ -22,7 +23,8 @@ · 7 unmodified lines | |||
| 22 | "copy %%r0,%0\n" \ | 23 | "copy %%r0,%0\n" \ |
| 23 | "8:\tlpa %%r0(%%sr3,%1),%0\n" \ | 24 | "8:\tlpa %%r0(%%sr3,%1),%0\n" \ |
| 24 | "9:\n" \ | 25 | "9:\n" \ |
| 25 | ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ | 26 | ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ |
| 27 | "or %%r0,%%r0,%%r0") \ | ||
| 26 | : "=&r" (pa) \ | 28 | : "=&r" (pa) \ |
| 27 | : "r" (va) \ | 29 | : "r" (va) \ |
| 28 | : "memory" \ | 30 | : "memory" \ |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | */ | 7 | */ |
| 8 | #include <asm/page.h> | 8 | #include <asm/page.h> |
| 9 | #include <asm/cache.h> | 9 | #include <asm/cache.h> |
| 10 | #include <asm/extable.h> | ||
| 10 | 11 | ||
| 11 | #include <linux/bug.h> | 12 | #include <linux/bug.h> |
| 12 | #include <linux/string.h> | 13 | #include <linux/string.h> |
| @@ -26,37 +27,6 @@ · 13 unmodified lines | |||
| 26 | #define STD_USER(sr, x, ptr) __put_user_asm(sr, "std", x, ptr) | 27 | #define STD_USER(sr, x, ptr) __put_user_asm(sr, "std", x, ptr) |
| 27 | #endif | 28 | #endif |
| 28 | 29 | ||
| 29 | /* | ||
| 30 | * The exception table contains two values: the first is the relative offset to | ||
| 31 | * the address of the instruction that is allowed to fault, and the second is | ||
| 32 | * the relative offset to the address of the fixup routine. Since relative | ||
| 33 | * addresses are used, 32bit values are sufficient even on 64bit kernel. | ||
| 34 | */ | ||
| 35 | |||
| 36 | #define ARCH_HAS_RELATIVE_EXTABLE | ||
| 37 | struct exception_table_entry { | ||
| 38 | int insn; /* relative address of insn that is allowed to fault. */ | ||
| 39 | int fixup; /* relative address of fixup routine */ | ||
| 40 | }; | ||
| 41 | |||
| 42 | #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ | ||
| 43 | ".section __ex_table,\"aw\"\n" \ | ||
| 44 | ".align 4\n" \ | ||
| 45 | ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \ | ||
| 46 | ".previous\n" | ||
| 47 | |||
| 48 | /* | ||
| 49 | * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry | ||
| 50 | * (with lowest bit set) for which the fault handler in fixup_exception() will | ||
| 51 | * load -EFAULT into %r29 for a read or write fault, and zeroes the target | ||
| 52 | * register in case of a read fault in get_user(). | ||
| 53 | */ | ||
| 54 | #define ASM_EXCEPTIONTABLE_REG 29 | ||
| 55 | #define ASM_EXCEPTIONTABLE_VAR(__variable) \ | ||
| 56 | register long __variable __asm__ ("r29") = 0 | ||
| 57 | #define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\ | ||
| 58 | ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1) | ||
| 59 | |||
| 60 | #define __get_user_internal(sr, val, ptr) \ | 30 | #define __get_user_internal(sr, val, ptr) \ |
| 61 | ({ \ | 31 | ({ \ |
| 62 | ASM_EXCEPTIONTABLE_VAR(__gu_err); \ | 32 | ASM_EXCEPTIONTABLE_VAR(__gu_err); \ |
| @@ -83,7 +53,7 @@ struct exception_table_entry { · 20 unmodified lines | |||
| 83 | \ | 53 | \ |
| 84 | __asm__("1: " ldx " 0(%%sr%2,%3),%0\n" \ | 54 | __asm__("1: " ldx " 0(%%sr%2,%3),%0\n" \ |
| 85 | "9:\n" \ | 55 | "9:\n" \ |
| 86 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ | 56 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%1") \ |
| 87 | : "=r"(__gu_val), "+r"(__gu_err) \ | 57 | : "=r"(__gu_val), "+r"(__gu_err) \ |
| 88 | : "i"(sr), "r"(ptr)); \ | 58 | : "i"(sr), "r"(ptr)); \ |
| 89 | \ | 59 | \ |
| @@ -115,8 +85,8 @@ struct exception_table_entry { · 25 unmodified lines | |||
| 115 | "1: ldw 0(%%sr%2,%3),%0\n" \ | 85 | "1: ldw 0(%%sr%2,%3),%0\n" \ |
| 116 | "2: ldw 4(%%sr%2,%3),%R0\n" \ | 86 | "2: ldw 4(%%sr%2,%3),%R0\n" \ |
| 117 | "9:\n" \ | 87 | "9:\n" \ |
| 118 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ | 88 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%1") \ |
| 119 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ | 89 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b, "%1") \ |
| 120 | : "=&r"(__gu_tmp.l), "+r"(__gu_err) \ | 90 | : "=&r"(__gu_tmp.l), "+r"(__gu_err) \ |
| 121 | : "i"(sr), "r"(ptr)); \ | 91 | : "i"(sr), "r"(ptr)); \ |
| 122 | \ | 92 | \ |
| @@ -174,7 +144,7 @@ struct exception_table_entry { · 51 unmodified lines | |||
| 174 | __asm__ __volatile__ ( \ | 144 | __asm__ __volatile__ ( \ |
| 175 | "1: " stx " %1,0(%%sr%2,%3)\n" \ | 145 | "1: " stx " %1,0(%%sr%2,%3)\n" \ |
| 176 | "9:\n" \ | 146 | "9:\n" \ |
| 177 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ | 147 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%0") \ |
| 178 | : "+r"(__pu_err) \ | 148 | : "+r"(__pu_err) \ |
| 179 | : "r"(x), "i"(sr), "r"(ptr)) | 149 | : "r"(x), "i"(sr), "r"(ptr)) |
| 180 | 150 | ||
| @@ -186,15 +156,14 @@ struct exception_table_entry { · 5 unmodified lines | |||
| 186 | "1: stw %1,0(%%sr%2,%3)\n" \ | 156 | "1: stw %1,0(%%sr%2,%3)\n" \ |
| 187 | "2: stw %R1,4(%%sr%2,%3)\n" \ | 157 | "2: stw %R1,4(%%sr%2,%3)\n" \ |
| 188 | "9:\n" \ | 158 | "9:\n" \ |
| 189 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ | 159 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%0") \ |
| 190 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ | 160 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b, "%0") \ |
| 191 | : "+r"(__pu_err) \ | 161 | : "+r"(__pu_err) \ |
| 192 | : "r"(__val), "i"(sr), "r"(ptr)); \ | 162 | : "r"(__val), "i"(sr), "r"(ptr)); \ |
| 193 | } while (0) | 163 | } while (0) |
| 194 | 164 | ||
| 195 | #endif /* !defined(CONFIG_64BIT) */ | 165 | #endif /* !defined(CONFIG_64BIT) */ |
| 196 | 166 | ||
| 197 | |||
| 198 | /* | 167 | /* |
| 199 | * Complex access routines -- external declarations | 168 | * Complex access routines -- external declarations |
| 200 | */ | 169 | */ |
| @@ -216,7 +185,4 @@ unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src, · 15 unmodified lines | |||
| 216 | #define INLINE_COPY_TO_USER | 185 | #define INLINE_COPY_TO_USER |
| 217 | #define INLINE_COPY_FROM_USER | 186 | #define INLINE_COPY_FROM_USER |
| 218 | 187 | ||
| 219 | struct pt_regs; | ||
| 220 | int fixup_exception(struct pt_regs *regs); | ||
| 221 | |||
| 222 | #endif /* __PARISC_UACCESS_H */ | 188 | #endif /* __PARISC_UACCESS_H */ |
| @@ -58,7 +58,7 @@ int pa_serialize_tlb_flushes __ro_after_init; · 57 unmodified lines | |||
| 58 | 58 | ||
| 59 | struct pdc_cache_info cache_info __ro_after_init; | 59 | struct pdc_cache_info cache_info __ro_after_init; |
| 60 | #ifndef CONFIG_PA20 | 60 | #ifndef CONFIG_PA20 |
| 61 | struct pdc_btlb_info btlb_info __ro_after_init; | 61 | struct pdc_btlb_info btlb_info; |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | DEFINE_STATIC_KEY_TRUE(parisc_has_cache); | 64 | DEFINE_STATIC_KEY_TRUE(parisc_has_cache); |
| @@ -264,6 +264,10 @@ parisc_cache_init(void) · 199 unmodified lines | |||
| 264 | icache_stride = CAFL_STRIDE(cache_info.ic_conf); | 264 | icache_stride = CAFL_STRIDE(cache_info.ic_conf); |
| 265 | #undef CAFL_STRIDE | 265 | #undef CAFL_STRIDE |
| 266 | 266 | ||
| 267 | /* stride needs to be non-zero, otherwise cache flushes will not work */ | ||
| 268 | WARN_ON(cache_info.dc_size && dcache_stride == 0); | ||
| 269 | WARN_ON(cache_info.ic_size && icache_stride == 0); | ||
| 270 | |||
| 267 | if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == | 271 | if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == |
| 268 | PDC_MODEL_NVA_UNSUPPORTED) { | 272 | PDC_MODEL_NVA_UNSUPPORTED) { |
| 269 | printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n"); | 273 | printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n"); |
| @@ -850,7 +854,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, · 580 unmodified lines | |||
| 850 | #endif | 854 | #endif |
| 851 | " fic,m %3(%4,%0)\n" | 855 | " fic,m %3(%4,%0)\n" |
| 852 | "2: sync\n" | 856 | "2: sync\n" |
| 853 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b) | 857 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b, "%1") |
| 854 | : "+r" (start), "+r" (error) | 858 | : "+r" (start), "+r" (error) |
| 855 | : "r" (end), "r" (dcache_stride), "i" (SR_USER)); | 859 | : "r" (end), "r" (dcache_stride), "i" (SR_USER)); |
| 856 | } | 860 | } |
| @@ -865,7 +869,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, · 8 unmodified lines | |||
| 865 | #endif | 869 | #endif |
| 866 | " fdc,m %3(%4,%0)\n" | 870 | " fdc,m %3(%4,%0)\n" |
| 867 | "2: sync\n" | 871 | "2: sync\n" |
| 868 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b) | 872 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b, "%1") |
| 869 | : "+r" (start), "+r" (error) | 873 | : "+r" (start), "+r" (error) |
| 870 | : "r" (end), "r" (icache_stride), "i" (SR_USER)); | 874 | : "r" (end), "r" (icache_stride), "i" (SR_USER)); |
| 871 | } | 875 | } |
| @@ -742,7 +742,7 @@ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath) · 741 unmodified lines | |||
| 742 | }; | 742 | }; |
| 743 | 743 | ||
| 744 | if (device_for_each_child(parent, &recurse_data, descend_children)) | 744 | if (device_for_each_child(parent, &recurse_data, descend_children)) |
| 745 | { /* nothing */ }; | 745 | { /* nothing */ } |
| 746 | 746 | ||
| 747 | return d.dev; | 747 | return d.dev; |
| 748 | } | 748 | } |
| @@ -1004,6 +1004,9 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) · 255 unmodified lines | |||
| 1004 | 1004 | ||
| 1005 | pr_info("\n"); | 1005 | pr_info("\n"); |
| 1006 | 1006 | ||
| 1007 | /* Prevent hung task messages when printing on serial console */ | ||
| 1008 | cond_resched(); | ||
| 1009 | |||
| 1007 | pr_info("#define HPA_%08lx_DESCRIPTION \"%s\"\n", | 1010 | pr_info("#define HPA_%08lx_DESCRIPTION \"%s\"\n", |
| 1008 | hpa, parisc_hardware_description(&dev->id)); | 1011 | hpa, parisc_hardware_description(&dev->id)); |
| 1009 | 1012 | ||
| @@ -120,8 +120,8 @@ static int emulate_ldh(struct pt_regs *regs, int toreg) · 119 unmodified lines | |||
| 120 | "2: ldbs 1(%%sr1,%3), %0\n" | 120 | "2: ldbs 1(%%sr1,%3), %0\n" |
| 121 | " depw %2, 23, 24, %0\n" | 121 | " depw %2, 23, 24, %0\n" |
| 122 | "3: \n" | 122 | "3: \n" |
| 123 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) | 123 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") |
| 124 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) | 124 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") |
| 125 | : "+r" (val), "+r" (ret), "=&r" (temp1) | 125 | : "+r" (val), "+r" (ret), "=&r" (temp1) |
| 126 | : "r" (saddr), "r" (regs->isr) ); | 126 | : "r" (saddr), "r" (regs->isr) ); |
| 127 | 127 | ||
| @@ -152,8 +152,8 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) · 24 unmodified lines | |||
| 152 | " mtctl %2,11\n" | 152 | " mtctl %2,11\n" |
| 153 | " vshd %0,%3,%0\n" | 153 | " vshd %0,%3,%0\n" |
| 154 | "3: \n" | 154 | "3: \n" |
| 155 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) | 155 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") |
| 156 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) | 156 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") |
| 157 | : "+r" (val), "+r" (ret), "=&r" (temp1), "=&r" (temp2) | 157 | : "+r" (val), "+r" (ret), "=&r" (temp1), "=&r" (temp2) |
| 158 | : "r" (saddr), "r" (regs->isr) ); | 158 | : "r" (saddr), "r" (regs->isr) ); |
| 159 | 159 | ||
| @@ -189,8 +189,8 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) · 29 unmodified lines | |||
| 189 | " mtsar %%r19\n" | 189 | " mtsar %%r19\n" |
| 190 | " shrpd %0,%%r20,%%sar,%0\n" | 190 | " shrpd %0,%%r20,%%sar,%0\n" |
| 191 | "3: \n" | 191 | "3: \n" |
| 192 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) | 192 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") |
| 193 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) | 193 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") |
| 194 | : "=r" (val), "+r" (ret) | 194 | : "=r" (val), "+r" (ret) |
| 195 | : "0" (val), "r" (saddr), "r" (regs->isr) | 195 | : "0" (val), "r" (saddr), "r" (regs->isr) |
| 196 | : "r19", "r20" ); | 196 | : "r19", "r20" ); |
| @@ -209,9 +209,9 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) · 12 unmodified lines | |||
| 209 | " vshd %0,%R0,%0\n" | 209 | " vshd %0,%R0,%0\n" |
| 210 | " vshd %R0,%4,%R0\n" | 210 | " vshd %R0,%4,%R0\n" |
| 211 | "4: \n" | 211 | "4: \n" |
| 212 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 4b) | 212 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 4b, "%1") |
| 213 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 4b) | 213 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 4b, "%1") |
| 214 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b) | 214 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b, "%1") |
| 215 | : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1) | 215 | : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1) |
| 216 | : "r" (regs->isr) ); | 216 | : "r" (regs->isr) ); |
| 217 | } | 217 | } |
| @@ -244,8 +244,8 @@ static int emulate_sth(struct pt_regs *regs, int frreg) · 26 unmodified lines | |||
| 244 | "1: stb %1, 0(%%sr1, %3)\n" | 244 | "1: stb %1, 0(%%sr1, %3)\n" |
| 245 | "2: stb %2, 1(%%sr1, %3)\n" | 245 | "2: stb %2, 1(%%sr1, %3)\n" |
| 246 | "3: \n" | 246 | "3: \n" |
| 247 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) | 247 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%0") |
| 248 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) | 248 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%0") |
| 249 | : "+r" (ret), "=&r" (temp1) | 249 | : "+r" (ret), "=&r" (temp1) |
| 250 | : "r" (val), "r" (regs->ior), "r" (regs->isr) ); | 250 | : "r" (val), "r" (regs->ior), "r" (regs->isr) ); |
| 251 | 251 | ||
| @@ -285,8 +285,8 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) · 33 unmodified lines | |||
| 285 | " stw %%r20,0(%%sr1,%2)\n" | 285 | " stw %%r20,0(%%sr1,%2)\n" |
| 286 | " stw %%r21,4(%%sr1,%2)\n" | 286 | " stw %%r21,4(%%sr1,%2)\n" |
| 287 | "3: \n" | 287 | "3: \n" |
| 288 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) | 288 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%0") |
| 289 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) | 289 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%0") |
| 290 | : "+r" (ret) | 290 | : "+r" (ret) |
| 291 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 291 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 292 | : "r19", "r20", "r21", "r22", "r1" ); | 292 | : "r19", "r20", "r21", "r22", "r1" ); |
| @@ -329,10 +329,10 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) · 36 unmodified lines | |||
| 329 | "3: std %%r20,0(%%sr1,%2)\n" | 329 | "3: std %%r20,0(%%sr1,%2)\n" |
| 330 | "4: std %%r21,8(%%sr1,%2)\n" | 330 | "4: std %%r21,8(%%sr1,%2)\n" |
| 331 | "5: \n" | 331 | "5: \n" |
| 332 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 5b) | 332 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 5b, "%0") |
| 333 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 5b) | 333 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 5b, "%0") |
| 334 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 5b) | 334 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 5b, "%0") |
| 335 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 5b) | 335 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 5b, "%0") |
| 336 | : "+r" (ret) | 336 | : "+r" (ret) |
| 337 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 337 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 338 | : "r19", "r20", "r21", "r22", "r1" ); | 338 | : "r19", "r20", "r21", "r22", "r1" ); |
| @@ -357,11 +357,11 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) · 18 unmodified lines | |||
| 357 | "4: stw %%r1,4(%%sr1,%2)\n" | 357 | "4: stw %%r1,4(%%sr1,%2)\n" |
| 358 | "5: stw %R1,8(%%sr1,%2)\n" | 358 | "5: stw %R1,8(%%sr1,%2)\n" |
| 359 | "6: \n" | 359 | "6: \n" |
| 360 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 6b) | 360 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 6b, "%0") |
| 361 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 6b) | 361 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 6b, "%0") |
| 362 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 6b) | 362 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 6b, "%0") |
| 363 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 6b) | 363 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 6b, "%0") |
| 364 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(5b, 6b) | 364 | ASM_EXCEPTIONTABLE_ENTRY_EFAULT(5b, 6b, "%0") |
| 365 | : "+r" (ret) | 365 | : "+r" (ret) |
| 366 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 366 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 367 | : "r19", "r20", "r21", "r1" ); | 367 | : "r19", "r20", "r21", "r1" ); |
| @@ -127,7 +127,7 @@ SECTIONS · 126 unmodified lines | |||
| 127 | } | 127 | } |
| 128 | #endif | 128 | #endif |
| 129 | 129 | ||
| 130 | RO_DATA(8) | 130 | RO_DATA(PAGE_SIZE) |
| 131 | 131 | ||
| 132 | /* unwind info */ | 132 | /* unwind info */ |
| 133 | . = ALIGN(4); | 133 | . = ALIGN(4); |
| @@ -150,11 +150,16 @@ int fixup_exception(struct pt_regs *regs) · 149 unmodified lines | |||
| 150 | * Fix up get_user() and put_user(). | 150 | * Fix up get_user() and put_user(). |
| 151 | * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant | 151 | * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant |
| 152 | * bit in the relative address of the fixup routine to indicate | 152 | * bit in the relative address of the fixup routine to indicate |
| 153 | * that gr[ASM_EXCEPTIONTABLE_REG] should be loaded with | 153 | * that the register encoded in the "or %r0,%r0,register" |
| 154 | * -EFAULT to report a userspace access error. | 154 | * opcode should be loaded with -EFAULT to report a userspace |
| 155 | * access error. | ||
| 155 | */ | 156 | */ |
| 156 | if (fix->fixup & 1) { | 157 | if (fix->fixup & 1) { |
| 157 | regs->gr[ASM_EXCEPTIONTABLE_REG] = -EFAULT; | 158 | int fault_error_reg = fix->err_opcode & 0x1f; |
| 159 | if (!WARN_ON(!fault_error_reg)) | ||
| 160 | regs->gr[fault_error_reg] = -EFAULT; | ||
| 161 | pr_debug("Unalignment fixup of register %d at %pS\n", | ||
| 162 | fault_error_reg, (void*)regs->iaoq[0]); | ||
| 158 | 163 | ||
| 159 | /* zero target register for get_user() */ | 164 | /* zero target register for get_user() */ |
| 160 | if (parisc_acctyp(0, regs->iir) == VM_READ) { | 165 | if (parisc_acctyp(0, regs->iir) == VM_READ) { |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 18 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 19 | { | 19 | { |
| 20 | asm_volatile_goto("1:\n\t" | 20 | asm goto("1:\n\t" |
| 21 | "nop # arch_static_branch\n\t" | 21 | "nop # arch_static_branch\n\t" |
| 22 | ".pushsection __jump_table, \"aw\"\n\t" | 22 | ".pushsection __jump_table, \"aw\"\n\t" |
| 23 | ".long 1b - ., %l[l_yes] - .\n\t" | 23 | ".long 1b - ., %l[l_yes] - .\n\t" |
| @@ -32,7 +32,7 @@ l_yes: · 8 unmodified lines | |||
| 32 | 32 | ||
| 33 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) | 33 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) |
| 34 | { | 34 | { |
| 35 | asm_volatile_goto("1:\n\t" | 35 | asm goto("1:\n\t" |
| 36 | "b %l[l_yes] # arch_static_branch_jump\n\t" | 36 | "b %l[l_yes] # arch_static_branch_jump\n\t" |
| 37 | ".pushsection __jump_table, \"aw\"\n\t" | 37 | ".pushsection __jump_table, \"aw\"\n\t" |
| 38 | ".long 1b - ., %l[l_yes] - .\n\t" | 38 | ".long 1b - ., %l[l_yes] - .\n\t" |
| @@ -74,7 +74,7 @@ __pu_failed: \ · 73 unmodified lines | |||
| 74 | /* -mprefixed can generate offsets beyond range, fall back hack */ | 74 | /* -mprefixed can generate offsets beyond range, fall back hack */ |
| 75 | #ifdef CONFIG_PPC_KERNEL_PREFIXED | 75 | #ifdef CONFIG_PPC_KERNEL_PREFIXED |
| 76 | #define __put_user_asm_goto(x, addr, label, op) \ | 76 | #define __put_user_asm_goto(x, addr, label, op) \ |
| 77 | asm_volatile_goto( \ | 77 | asm goto( \ |
| 78 | "1: " op " %0,0(%1) # put_user\n" \ | 78 | "1: " op " %0,0(%1) # put_user\n" \ |
| 79 | EX_TABLE(1b, %l2) \ | 79 | EX_TABLE(1b, %l2) \ |
| 80 | : \ | 80 | : \ |
| @@ -83,7 +83,7 @@ __pu_failed: \ · 2 unmodified lines | |||
| 83 | : label) | 83 | : label) |
| 84 | #else | 84 | #else |
| 85 | #define __put_user_asm_goto(x, addr, label, op) \ | 85 | #define __put_user_asm_goto(x, addr, label, op) \ |
| 86 | asm_volatile_goto( \ | 86 | asm goto( \ |
| 87 | "1: " op "%U1%X1 %0,%1 # put_user\n" \ | 87 | "1: " op "%U1%X1 %0,%1 # put_user\n" \ |
| 88 | EX_TABLE(1b, %l2) \ | 88 | EX_TABLE(1b, %l2) \ |
| 89 | : \ | 89 | : \ |
| @@ -97,7 +97,7 @@ __pu_failed: \ · 7 unmodified lines | |||
| 97 | __put_user_asm_goto(x, ptr, label, "std") | 97 | __put_user_asm_goto(x, ptr, label, "std") |
| 98 | #else /* __powerpc64__ */ | 98 | #else /* __powerpc64__ */ |
| 99 | #define __put_user_asm2_goto(x, addr, label) \ | 99 | #define __put_user_asm2_goto(x, addr, label) \ |
| 100 | asm_volatile_goto( \ | 100 | asm goto( \ |
| 101 | "1: stw%X1 %0, %1\n" \ | 101 | "1: stw%X1 %0, %1\n" \ |
| 102 | "2: stw%X1 %L0, %L1\n" \ | 102 | "2: stw%X1 %L0, %L1\n" \ |
| 103 | EX_TABLE(1b, %l2) \ | 103 | EX_TABLE(1b, %l2) \ |
| @@ -146,7 +146,7 @@ do { \ · 42 unmodified lines | |||
| 146 | /* -mprefixed can generate offsets beyond range, fall back hack */ | 146 | /* -mprefixed can generate offsets beyond range, fall back hack */ |
| 147 | #ifdef CONFIG_PPC_KERNEL_PREFIXED | 147 | #ifdef CONFIG_PPC_KERNEL_PREFIXED |
| 148 | #define __get_user_asm_goto(x, addr, label, op) \ | 148 | #define __get_user_asm_goto(x, addr, label, op) \ |
| 149 | asm_volatile_goto( \ | 149 | asm_goto_output( \ |
| 150 | "1: "op" %0,0(%1) # get_user\n" \ | 150 | "1: "op" %0,0(%1) # get_user\n" \ |
| 151 | EX_TABLE(1b, %l2) \ | 151 | EX_TABLE(1b, %l2) \ |
| 152 | : "=r" (x) \ | 152 | : "=r" (x) \ |
| @@ -155,7 +155,7 @@ do { \ · 2 unmodified lines | |||
| 155 | : label) | 155 | : label) |
| 156 | #else | 156 | #else |
| 157 | #define __get_user_asm_goto(x, addr, label, op) \ | 157 | #define __get_user_asm_goto(x, addr, label, op) \ |
| 158 | asm_volatile_goto( \ | 158 | asm_goto_output( \ |
| 159 | "1: "op"%U1%X1 %0, %1 # get_user\n" \ | 159 | "1: "op"%U1%X1 %0, %1 # get_user\n" \ |
| 160 | EX_TABLE(1b, %l2) \ | 160 | EX_TABLE(1b, %l2) \ |
| 161 | : "=r" (x) \ | 161 | : "=r" (x) \ |
| @@ -169,7 +169,7 @@ do { \ · 7 unmodified lines | |||
| 169 | __get_user_asm_goto(x, addr, label, "ld") | 169 | __get_user_asm_goto(x, addr, label, "ld") |
| 170 | #else /* __powerpc64__ */ | 170 | #else /* __powerpc64__ */ |
| 171 | #define __get_user_asm2_goto(x, addr, label) \ | 171 | #define __get_user_asm2_goto(x, addr, label) \ |
| 172 | asm_volatile_goto( \ | 172 | asm_goto_output( \ |
| 173 | "1: lwz%X1 %0, %1\n" \ | 173 | "1: lwz%X1 %0, %1\n" \ |
| 174 | "2: lwz%X1 %L0, %L1\n" \ | 174 | "2: lwz%X1 %L0, %L1\n" \ |
| 175 | EX_TABLE(1b, %l2) \ | 175 | EX_TABLE(1b, %l2) \ |
| @@ -1287,20 +1287,20 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain, · 1286 unmodified lines | |||
| 1287 | struct iommu_domain *domain = iommu_get_domain_for_dev(dev); | 1287 | struct iommu_domain *domain = iommu_get_domain_for_dev(dev); |
| 1288 | struct iommu_group *grp = iommu_group_get(dev); | 1288 | struct iommu_group *grp = iommu_group_get(dev); |
| 1289 | struct iommu_table_group *table_group; | 1289 | struct iommu_table_group *table_group; |
| 1290 | int ret = -EINVAL; | ||
| 1291 | 1290 | ||
| 1292 | /* At first attach the ownership is already set */ | 1291 | /* At first attach the ownership is already set */ |
| 1293 | if (!domain) | 1292 | if (!domain) |
| 1294 | return 0; | 1293 | return 0; |
| 1295 | 1294 | ||
| 1296 | if (!grp) | ||
| 1297 | return -ENODEV; | ||
| 1298 | |||
| 1299 | table_group = iommu_group_get_iommudata(grp); | 1295 | table_group = iommu_group_get_iommudata(grp); |
| 1300 | ret = table_group->ops->take_ownership(table_group); | 1296 | /* |
| 1297 | * The domain being set to PLATFORM from earlier | ||
| 1298 | * BLOCKED. The table_group ownership has to be released. | ||
| 1299 | */ | ||
| 1300 | table_group->ops->release_ownership(table_group); | ||
| 1301 | iommu_group_put(grp); | 1301 | iommu_group_put(grp); |
| 1302 | 1302 | ||
| 1303 | return ret; | 1303 | return 0; |
| 1304 | } | 1304 | } |
| 1305 | 1305 | ||
| 1306 | static const struct iommu_domain_ops spapr_tce_platform_domain_ops = { | 1306 | static const struct iommu_domain_ops spapr_tce_platform_domain_ops = { |
| @@ -1312,13 +1312,32 @@ static struct iommu_domain spapr_tce_platform_domain = { · 5 unmodified lines | |||
| 1312 | .ops = &spapr_tce_platform_domain_ops, | 1312 | .ops = &spapr_tce_platform_domain_ops, |
| 1313 | }; | 1313 | }; |
| 1314 | 1314 | ||
| 1315 | static struct iommu_domain spapr_tce_blocked_domain = { | 1315 | static int |
| 1316 | .type = IOMMU_DOMAIN_BLOCKED, | 1316 | spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain, |
| 1317 | struct device *dev) | ||
| 1318 | { | ||
| 1319 | struct iommu_group *grp = iommu_group_get(dev); | ||
| 1320 | struct iommu_table_group *table_group; | ||
| 1321 | int ret = -EINVAL; | ||
| 1322 | |||
| 1317 | /* | 1323 | /* |
| 1318 | * FIXME: SPAPR mixes blocked and platform behaviors, the blocked domain | 1324 | * FIXME: SPAPR mixes blocked and platform behaviors, the blocked domain |
| 1319 | * also sets the dma_api ops | 1325 | * also sets the dma_api ops |
| 1320 | */ | 1326 | */ |
| 1321 | .ops = &spapr_tce_platform_domain_ops, | 1327 | table_group = iommu_group_get_iommudata(grp); |
| 1328 | ret = table_group->ops->take_ownership(table_group); | ||
| 1329 | iommu_group_put(grp); | ||
| 1330 | |||
| 1331 | return ret; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | static const struct iommu_domain_ops spapr_tce_blocked_domain_ops = { | ||
| 1335 | .attach_dev = spapr_tce_blocked_iommu_attach_dev, | ||
| 1336 | }; | ||
| 1337 | |||
| 1338 | static struct iommu_domain spapr_tce_blocked_domain = { | ||
| 1339 | .type = IOMMU_DOMAIN_BLOCKED, | ||
| 1340 | .ops = &spapr_tce_blocked_domain_ops, | ||
| 1322 | }; | 1341 | }; |
| 1323 | 1342 | ||
| 1324 | static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap) | 1343 | static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap) |
| @@ -230,7 +230,7 @@ again: · 229 unmodified lines | |||
| 230 | * This allows interrupts to be unmasked without hard disabling, and | 230 | * This allows interrupts to be unmasked without hard disabling, and |
| 231 | * also without new hard interrupts coming in ahead of pending ones. | 231 | * also without new hard interrupts coming in ahead of pending ones. |
| 232 | */ | 232 | */ |
| 233 | asm_volatile_goto( | 233 | asm goto( |
| 234 | "1: \n" | 234 | "1: \n" |
| 235 | " lbz 9,%0(13) \n" | 235 | " lbz 9,%0(13) \n" |
| 236 | " cmpwi 9,0 \n" | 236 | " cmpwi 9,0 \n" |
| @@ -93,144 +93,160 @@ · 92 unmodified lines | |||
| 93 | <&cpu63_intc 3>; | 93 | <&cpu63_intc 3>; |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | clint_mtimer0: timer@70ac000000 { | 96 | clint_mtimer0: timer@70ac004000 { |
| 97 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 97 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 98 | reg = <0x00000070 0xac000000 0x00000000 0x00007ff8>; | 98 | reg = <0x00000070 0xac004000 0x00000000 0x0000c000>; |
| 99 | reg-names = "mtimecmp"; | ||
| 99 | interrupts-extended = <&cpu0_intc 7>, | 100 | interrupts-extended = <&cpu0_intc 7>, |
| 100 | <&cpu1_intc 7>, | 101 | <&cpu1_intc 7>, |
| 101 | <&cpu2_intc 7>, | 102 | <&cpu2_intc 7>, |
| 102 | <&cpu3_intc 7>; | 103 | <&cpu3_intc 7>; |
| 103 | }; | 104 | }; |
| 104 | 105 | ||
| 105 | clint_mtimer1: timer@70ac010000 { | 106 | clint_mtimer1: timer@70ac014000 { |
| 106 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 107 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 107 | reg = <0x00000070 0xac010000 0x00000000 0x00007ff8>; | 108 | reg = <0x00000070 0xac014000 0x00000000 0x0000c000>; |
| 109 | reg-names = "mtimecmp"; | ||
| 108 | interrupts-extended = <&cpu4_intc 7>, | 110 | interrupts-extended = <&cpu4_intc 7>, |
| 109 | <&cpu5_intc 7>, | 111 | <&cpu5_intc 7>, |
| 110 | <&cpu6_intc 7>, | 112 | <&cpu6_intc 7>, |
| 111 | <&cpu7_intc 7>; | 113 | <&cpu7_intc 7>; |
| 112 | }; | 114 | }; |
| 113 | 115 | ||
| 114 | clint_mtimer2: timer@70ac020000 { | 116 | clint_mtimer2: timer@70ac024000 { |
| 115 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 117 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 116 | reg = <0x00000070 0xac020000 0x00000000 0x00007ff8>; | 118 | reg = <0x00000070 0xac024000 0x00000000 0x0000c000>; |
| 119 | reg-names = "mtimecmp"; | ||
| 117 | interrupts-extended = <&cpu8_intc 7>, | 120 | interrupts-extended = <&cpu8_intc 7>, |
| 118 | <&cpu9_intc 7>, | 121 | <&cpu9_intc 7>, |
| 119 | <&cpu10_intc 7>, | 122 | <&cpu10_intc 7>, |
| 120 | <&cpu11_intc 7>; | 123 | <&cpu11_intc 7>; |
| 121 | }; | 124 | }; |
| 122 | 125 | ||
| 123 | clint_mtimer3: timer@70ac030000 { | 126 | clint_mtimer3: timer@70ac034000 { |
| 124 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 127 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 125 | reg = <0x00000070 0xac030000 0x00000000 0x00007ff8>; | 128 | reg = <0x00000070 0xac034000 0x00000000 0x0000c000>; |
| 129 | reg-names = "mtimecmp"; | ||
| 126 | interrupts-extended = <&cpu12_intc 7>, | 130 | interrupts-extended = <&cpu12_intc 7>, |
| 127 | <&cpu13_intc 7>, | 131 | <&cpu13_intc 7>, |
| 128 | <&cpu14_intc 7>, | 132 | <&cpu14_intc 7>, |
| 129 | <&cpu15_intc 7>; | 133 | <&cpu15_intc 7>; |
| 130 | }; | 134 | }; |
| 131 | 135 | ||
| 132 | clint_mtimer4: timer@70ac040000 { | 136 | clint_mtimer4: timer@70ac044000 { |
| 133 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 137 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 134 | reg = <0x00000070 0xac040000 0x00000000 0x00007ff8>; | 138 | reg = <0x00000070 0xac044000 0x00000000 0x0000c000>; |
| 139 | reg-names = "mtimecmp"; | ||
| 135 | interrupts-extended = <&cpu16_intc 7>, | 140 | interrupts-extended = <&cpu16_intc 7>, |
| 136 | <&cpu17_intc 7>, | 141 | <&cpu17_intc 7>, |
| 137 | <&cpu18_intc 7>, | 142 | <&cpu18_intc 7>, |
| 138 | <&cpu19_intc 7>; | 143 | <&cpu19_intc 7>; |
| 139 | }; | 144 | }; |
| 140 | 145 | ||
| 141 | clint_mtimer5: timer@70ac050000 { | 146 | clint_mtimer5: timer@70ac054000 { |
| 142 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 147 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 143 | reg = <0x00000070 0xac050000 0x00000000 0x00007ff8>; | 148 | reg = <0x00000070 0xac054000 0x00000000 0x0000c000>; |
| 149 | reg-names = "mtimecmp"; | ||
| 144 | interrupts-extended = <&cpu20_intc 7>, | 150 | interrupts-extended = <&cpu20_intc 7>, |
| 145 | <&cpu21_intc 7>, | 151 | <&cpu21_intc 7>, |
| 146 | <&cpu22_intc 7>, | 152 | <&cpu22_intc 7>, |
| 147 | <&cpu23_intc 7>; | 153 | <&cpu23_intc 7>; |
| 148 | }; | 154 | }; |
| 149 | 155 | ||
| 150 | clint_mtimer6: timer@70ac060000 { | 156 | clint_mtimer6: timer@70ac064000 { |
| 151 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 157 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 152 | reg = <0x00000070 0xac060000 0x00000000 0x00007ff8>; | 158 | reg = <0x00000070 0xac064000 0x00000000 0x0000c000>; |
| 159 | reg-names = "mtimecmp"; | ||
| 153 | interrupts-extended = <&cpu24_intc 7>, | 160 | interrupts-extended = <&cpu24_intc 7>, |
| 154 | <&cpu25_intc 7>, | 161 | <&cpu25_intc 7>, |
| 155 | <&cpu26_intc 7>, | 162 | <&cpu26_intc 7>, |
| 156 | <&cpu27_intc 7>; | 163 | <&cpu27_intc 7>; |
| 157 | }; | 164 | }; |
| 158 | 165 | ||
| 159 | clint_mtimer7: timer@70ac070000 { | 166 | clint_mtimer7: timer@70ac074000 { |
| 160 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 167 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 161 | reg = <0x00000070 0xac070000 0x00000000 0x00007ff8>; | 168 | reg = <0x00000070 0xac074000 0x00000000 0x0000c000>; |
| 169 | reg-names = "mtimecmp"; | ||
| 162 | interrupts-extended = <&cpu28_intc 7>, | 170 | interrupts-extended = <&cpu28_intc 7>, |
| 163 | <&cpu29_intc 7>, | 171 | <&cpu29_intc 7>, |
| 164 | <&cpu30_intc 7>, | 172 | <&cpu30_intc 7>, |
| 165 | <&cpu31_intc 7>; | 173 | <&cpu31_intc 7>; |
| 166 | }; | 174 | }; |
| 167 | 175 | ||
| 168 | clint_mtimer8: timer@70ac080000 { | 176 | clint_mtimer8: timer@70ac084000 { |
| 169 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 177 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 170 | reg = <0x00000070 0xac080000 0x00000000 0x00007ff8>; | 178 | reg = <0x00000070 0xac084000 0x00000000 0x0000c000>; |
| 179 | reg-names = "mtimecmp"; | ||
| 171 | interrupts-extended = <&cpu32_intc 7>, | 180 | interrupts-extended = <&cpu32_intc 7>, |
| 172 | <&cpu33_intc 7>, | 181 | <&cpu33_intc 7>, |
| 173 | <&cpu34_intc 7>, | 182 | <&cpu34_intc 7>, |
| 174 | <&cpu35_intc 7>; | 183 | <&cpu35_intc 7>; |
| 175 | }; | 184 | }; |
| 176 | 185 | ||
| 177 | clint_mtimer9: timer@70ac090000 { | 186 | clint_mtimer9: timer@70ac094000 { |
| 178 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 187 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 179 | reg = <0x00000070 0xac090000 0x00000000 0x00007ff8>; | 188 | reg = <0x00000070 0xac094000 0x00000000 0x0000c000>; |
| 189 | reg-names = "mtimecmp"; | ||
| 180 | interrupts-extended = <&cpu36_intc 7>, | 190 | interrupts-extended = <&cpu36_intc 7>, |
| 181 | <&cpu37_intc 7>, | 191 | <&cpu37_intc 7>, |
| 182 | <&cpu38_intc 7>, | 192 | <&cpu38_intc 7>, |
| 183 | <&cpu39_intc 7>; | 193 | <&cpu39_intc 7>; |
| 184 | }; | 194 | }; |
| 185 | 195 | ||
| 186 | clint_mtimer10: timer@70ac0a0000 { | 196 | clint_mtimer10: timer@70ac0a4000 { |
| 187 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 197 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 188 | reg = <0x00000070 0xac0a0000 0x00000000 0x00007ff8>; | 198 | reg = <0x00000070 0xac0a4000 0x00000000 0x0000c000>; |
| 199 | reg-names = "mtimecmp"; | ||
| 189 | interrupts-extended = <&cpu40_intc 7>, | 200 | interrupts-extended = <&cpu40_intc 7>, |
| 190 | <&cpu41_intc 7>, | 201 | <&cpu41_intc 7>, |
| 191 | <&cpu42_intc 7>, | 202 | <&cpu42_intc 7>, |
| 192 | <&cpu43_intc 7>; | 203 | <&cpu43_intc 7>; |
| 193 | }; | 204 | }; |
| 194 | 205 | ||
| 195 | clint_mtimer11: timer@70ac0b0000 { | 206 | clint_mtimer11: timer@70ac0b4000 { |
| 196 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 207 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 197 | reg = <0x00000070 0xac0b0000 0x00000000 0x00007ff8>; | 208 | reg = <0x00000070 0xac0b4000 0x00000000 0x0000c000>; |
| 209 | reg-names = "mtimecmp"; | ||
| 198 | interrupts-extended = <&cpu44_intc 7>, | 210 | interrupts-extended = <&cpu44_intc 7>, |
| 199 | <&cpu45_intc 7>, | 211 | <&cpu45_intc 7>, |
| 200 | <&cpu46_intc 7>, | 212 | <&cpu46_intc 7>, |
| 201 | <&cpu47_intc 7>; | 213 | <&cpu47_intc 7>; |
| 202 | }; | 214 | }; |
| 203 | 215 | ||
| 204 | clint_mtimer12: timer@70ac0c0000 { | 216 | clint_mtimer12: timer@70ac0c4000 { |
| 205 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 217 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 206 | reg = <0x00000070 0xac0c0000 0x00000000 0x00007ff8>; | 218 | reg = <0x00000070 0xac0c4000 0x00000000 0x0000c000>; |
| 219 | reg-names = "mtimecmp"; | ||
| 207 | interrupts-extended = <&cpu48_intc 7>, | 220 | interrupts-extended = <&cpu48_intc 7>, |
| 208 | <&cpu49_intc 7>, | 221 | <&cpu49_intc 7>, |
| 209 | <&cpu50_intc 7>, | 222 | <&cpu50_intc 7>, |
| 210 | <&cpu51_intc 7>; | 223 | <&cpu51_intc 7>; |
| 211 | }; | 224 | }; |
| 212 | 225 | ||
| 213 | clint_mtimer13: timer@70ac0d0000 { | 226 | clint_mtimer13: timer@70ac0d4000 { |
| 214 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 227 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 215 | reg = <0x00000070 0xac0d0000 0x00000000 0x00007ff8>; | 228 | reg = <0x00000070 0xac0d4000 0x00000000 0x0000c000>; |
| 229 | reg-names = "mtimecmp"; | ||
| 216 | interrupts-extended = <&cpu52_intc 7>, | 230 | interrupts-extended = <&cpu52_intc 7>, |
| 217 | <&cpu53_intc 7>, | 231 | <&cpu53_intc 7>, |
| 218 | <&cpu54_intc 7>, | 232 | <&cpu54_intc 7>, |
| 219 | <&cpu55_intc 7>; | 233 | <&cpu55_intc 7>; |
| 220 | }; | 234 | }; |
| 221 | 235 | ||
| 222 | clint_mtimer14: timer@70ac0e0000 { | 236 | clint_mtimer14: timer@70ac0e4000 { |
| 223 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 237 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 224 | reg = <0x00000070 0xac0e0000 0x00000000 0x00007ff8>; | 238 | reg = <0x00000070 0xac0e4000 0x00000000 0x0000c000>; |
| 239 | reg-names = "mtimecmp"; | ||
| 225 | interrupts-extended = <&cpu56_intc 7>, | 240 | interrupts-extended = <&cpu56_intc 7>, |
| 226 | <&cpu57_intc 7>, | 241 | <&cpu57_intc 7>, |
| 227 | <&cpu58_intc 7>, | 242 | <&cpu58_intc 7>, |
| 228 | <&cpu59_intc 7>; | 243 | <&cpu59_intc 7>; |
| 229 | }; | 244 | }; |
| 230 | 245 | ||
| 231 | clint_mtimer15: timer@70ac0f0000 { | 246 | clint_mtimer15: timer@70ac0f4000 { |
| 232 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; | 247 | compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer"; |
| 233 | reg = <0x00000070 0xac0f0000 0x00000000 0x00007ff8>; | 248 | reg = <0x00000070 0xac0f4000 0x00000000 0x0000c000>; |
| 249 | reg-names = "mtimecmp"; | ||
| 234 | interrupts-extended = <&cpu60_intc 7>, | 250 | interrupts-extended = <&cpu60_intc 7>, |
| 235 | <&cpu61_intc 7>, | 251 | <&cpu61_intc 7>, |
| 236 | <&cpu62_intc 7>, | 252 | <&cpu62_intc 7>, |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | |||
| 20 | static __always_inline unsigned int __arch_hweight32(unsigned int w) | 20 | static __always_inline unsigned int __arch_hweight32(unsigned int w) |
| 21 | { | 21 | { |
| 22 | #ifdef CONFIG_RISCV_ISA_ZBB | 22 | #ifdef CONFIG_RISCV_ISA_ZBB |
| 23 | asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, | 23 | asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, |
| 24 | RISCV_ISA_EXT_ZBB, 1) | 24 | RISCV_ISA_EXT_ZBB, 1) |
| 25 | : : : : legacy); | 25 | : : : : legacy); |
| 26 | 26 | ||
| @@ -51,7 +51,7 @@ static inline unsigned int __arch_hweight8(unsigned int w) · 24 unmodified lines | |||
| 51 | static __always_inline unsigned long __arch_hweight64(__u64 w) | 51 | static __always_inline unsigned long __arch_hweight64(__u64 w) |
| 52 | { | 52 | { |
| 53 | # ifdef CONFIG_RISCV_ISA_ZBB | 53 | # ifdef CONFIG_RISCV_ISA_ZBB |
| 54 | asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, | 54 | asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, |
| 55 | RISCV_ISA_EXT_ZBB, 1) | 55 | RISCV_ISA_EXT_ZBB, 1) |
| 56 | : : : : legacy); | 56 | : : : : legacy); |
| 57 | 57 | ||
| @@ -39,7 +39,7 @@ static __always_inline unsigned long variable__ffs(unsigned long word) · 38 unmodified lines | |||
| 39 | { | 39 | { |
| 40 | int num; | 40 | int num; |
| 41 | 41 | ||
| 42 | asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, | 42 | asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, |
| 43 | RISCV_ISA_EXT_ZBB, 1) | 43 | RISCV_ISA_EXT_ZBB, 1) |
| 44 | : : : : legacy); | 44 | : : : : legacy); |
| 45 | 45 | ||
| @@ -95,7 +95,7 @@ static __always_inline unsigned long variable__fls(unsigned long word) · 49 unmodified lines | |||
| 95 | { | 95 | { |
| 96 | int num; | 96 | int num; |
| 97 | 97 | ||
| 98 | asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, | 98 | asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, |
| 99 | RISCV_ISA_EXT_ZBB, 1) | 99 | RISCV_ISA_EXT_ZBB, 1) |
| 100 | : : : : legacy); | 100 | : : : : legacy); |
| 101 | 101 | ||
| @@ -154,7 +154,7 @@ static __always_inline int variable_ffs(int x) · 52 unmodified lines | |||
| 154 | if (!x) | 154 | if (!x) |
| 155 | return 0; | 155 | return 0; |
| 156 | 156 | ||
| 157 | asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, | 157 | asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, |
| 158 | RISCV_ISA_EXT_ZBB, 1) | 158 | RISCV_ISA_EXT_ZBB, 1) |
| 159 | : : : : legacy); | 159 | : : : : legacy); |
| 160 | 160 | ||
| @@ -209,7 +209,7 @@ static __always_inline int variable_fls(unsigned int x) · 48 unmodified lines | |||
| 209 | if (!x) | 209 | if (!x) |
| 210 | return 0; | 210 | return 0; |
| 211 | 211 | ||
| 212 | asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, | 212 | asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, |
| 213 | RISCV_ISA_EXT_ZBB, 1) | 213 | RISCV_ISA_EXT_ZBB, 1) |
| 214 | : : : : legacy); | 214 | : : : : legacy); |
| 215 | 215 | ||
| @@ -53,7 +53,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) · 52 unmodified lines | |||
| 53 | IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { | 53 | IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { |
| 54 | unsigned long fold_temp; | 54 | unsigned long fold_temp; |
| 55 | 55 | ||
| 56 | asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, | 56 | asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, |
| 57 | RISCV_ISA_EXT_ZBB, 1) | 57 | RISCV_ISA_EXT_ZBB, 1) |
| 58 | : | 58 | : |
| 59 | : | 59 | : |
| @@ -80,7 +80,7 @@ riscv_has_extension_likely(const unsigned long ext) · 79 unmodified lines | |||
| 80 | "ext must be < RISCV_ISA_EXT_MAX"); | 80 | "ext must be < RISCV_ISA_EXT_MAX"); |
| 81 | 81 | ||
| 82 | if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { | 82 | if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { |
| 83 | asm_volatile_goto( | 83 | asm goto( |
| 84 | ALTERNATIVE("j %l[l_no]", "nop", 0, %[ext], 1) | 84 | ALTERNATIVE("j %l[l_no]", "nop", 0, %[ext], 1) |
| 85 | : | 85 | : |
| 86 | : [ext] "i" (ext) | 86 | : [ext] "i" (ext) |
| @@ -103,7 +103,7 @@ riscv_has_extension_unlikely(const unsigned long ext) · 16 unmodified lines | |||
| 103 | "ext must be < RISCV_ISA_EXT_MAX"); | 103 | "ext must be < RISCV_ISA_EXT_MAX"); |
| 104 | 104 | ||
| 105 | if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { | 105 | if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { |
| 106 | asm_volatile_goto( | 106 | asm goto( |
| 107 | ALTERNATIVE("nop", "j %l[l_yes]", 0, %[ext], 1) | 107 | ALTERNATIVE("nop", "j %l[l_yes]", 0, %[ext], 1) |
| 108 | : | 108 | : |
| 109 | : [ext] "i" (ext) | 109 | : [ext] "i" (ext) |
| @@ -11,6 +11,9 @@ static inline void arch_clear_hugepage_flags(struct page *page) · 10 unmodified lines | |||
| 11 | } | 11 | } |
| 12 | #define arch_clear_hugepage_flags arch_clear_hugepage_flags | 12 | #define arch_clear_hugepage_flags arch_clear_hugepage_flags |
| 13 | 13 | ||
| 14 | bool arch_hugetlb_migration_supported(struct hstate *h); | ||
| 15 | #define arch_hugetlb_migration_supported arch_hugetlb_migration_supported | ||
| 16 | |||
| 14 | #ifdef CONFIG_RISCV_ISA_SVNAPOT | 17 | #ifdef CONFIG_RISCV_ISA_SVNAPOT |
| 15 | #define __HAVE_ARCH_HUGE_PTE_CLEAR | 18 | #define __HAVE_ARCH_HUGE_PTE_CLEAR |
| 16 | void huge_pte_clear(struct mm_struct *mm, unsigned long addr, | 19 | void huge_pte_clear(struct mm_struct *mm, unsigned long addr, |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | static __always_inline bool arch_static_branch(struct static_key * const key, | 17 | static __always_inline bool arch_static_branch(struct static_key * const key, |
| 18 | const bool branch) | 18 | const bool branch) |
| 19 | { | 19 | { |
| 20 | asm_volatile_goto( | 20 | asm goto( |
| 21 | " .align 2 \n\t" | 21 | " .align 2 \n\t" |
| 22 | " .option push \n\t" | 22 | " .option push \n\t" |
| 23 | " .option norelax \n\t" | 23 | " .option norelax \n\t" |
| @@ -39,7 +39,7 @@ label: · 15 unmodified lines | |||
| 39 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, | 39 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, |
| 40 | const bool branch) | 40 | const bool branch) |
| 41 | { | 41 | { |
| 42 | asm_volatile_goto( | 42 | asm goto( |
| 43 | " .align 2 \n\t" | 43 | " .align 2 \n\t" |
| 44 | " .option push \n\t" | 44 | " .option push \n\t" |
| 45 | " .option norelax \n\t" | 45 | " .option norelax \n\t" |
| @@ -21,4 +21,9 @@ static inline bool on_thread_stack(void) · 20 unmodified lines | |||
| 21 | return !(((unsigned long)(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE - 1)); | 21 | return !(((unsigned long)(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE - 1)); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | |||
| 25 | #ifdef CONFIG_VMAP_STACK | ||
| 26 | DECLARE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack); | ||
| 27 | #endif /* CONFIG_VMAP_STACK */ | ||
| 28 | |||
| 24 | #endif /* _ASM_RISCV_STACKTRACE_H */ | 29 | #endif /* _ASM_RISCV_STACKTRACE_H */ |
| @@ -16,7 +16,7 @@ static void tlb_flush(struct mmu_gather *tlb); · 15 unmodified lines | |||
| 16 | static inline void tlb_flush(struct mmu_gather *tlb) | 16 | static inline void tlb_flush(struct mmu_gather *tlb) |
| 17 | { | 17 | { |
| 18 | #ifdef CONFIG_MMU | 18 | #ifdef CONFIG_MMU |
| 19 | if (tlb->fullmm || tlb->need_flush_all) | 19 | if (tlb->fullmm || tlb->need_flush_all || tlb->freed_tables) |
| 20 | flush_tlb_mm(tlb->mm); | 20 | flush_tlb_mm(tlb->mm); |
| 21 | else | 21 | else |
| 22 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, | 22 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, |
| @@ -75,6 +75,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, · 74 unmodified lines | |||
| 75 | 75 | ||
| 76 | #define flush_tlb_mm(mm) flush_tlb_all() | 76 | #define flush_tlb_mm(mm) flush_tlb_all() |
| 77 | #define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all() | 77 | #define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all() |
| 78 | #define local_flush_tlb_kernel_range(start, end) flush_tlb_all() | ||
| 78 | #endif /* !CONFIG_SMP || !CONFIG_MMU */ | 79 | #endif /* !CONFIG_SMP || !CONFIG_MMU */ |
| 79 | 80 | ||
| 80 | #endif /* _ASM_RISCV_TLBFLUSH_H */ | 81 | #endif /* _ASM_RISCV_TLBFLUSH_H */ |
| @@ -139,6 +139,33 @@ enum KVM_RISCV_ISA_EXT_ID { · 138 unmodified lines | |||
| 139 | KVM_RISCV_ISA_EXT_ZIHPM, | 139 | KVM_RISCV_ISA_EXT_ZIHPM, |
| 140 | KVM_RISCV_ISA_EXT_SMSTATEEN, | 140 | KVM_RISCV_ISA_EXT_SMSTATEEN, |
| 141 | KVM_RISCV_ISA_EXT_ZICOND, | 141 | KVM_RISCV_ISA_EXT_ZICOND, |
| 142 | KVM_RISCV_ISA_EXT_ZBC, | ||
| 143 | KVM_RISCV_ISA_EXT_ZBKB, | ||
| 144 | KVM_RISCV_ISA_EXT_ZBKC, | ||
| 145 | KVM_RISCV_ISA_EXT_ZBKX, | ||
| 146 | KVM_RISCV_ISA_EXT_ZKND, | ||
| 147 | KVM_RISCV_ISA_EXT_ZKNE, | ||
| 148 | KVM_RISCV_ISA_EXT_ZKNH, | ||
| 149 | KVM_RISCV_ISA_EXT_ZKR, | ||
| 150 | KVM_RISCV_ISA_EXT_ZKSED, | ||
| 151 | KVM_RISCV_ISA_EXT_ZKSH, | ||
| 152 | KVM_RISCV_ISA_EXT_ZKT, | ||
| 153 | KVM_RISCV_ISA_EXT_ZVBB, | ||
| 154 | KVM_RISCV_ISA_EXT_ZVBC, | ||
| 155 | KVM_RISCV_ISA_EXT_ZVKB, | ||
| 156 | KVM_RISCV_ISA_EXT_ZVKG, | ||
| 157 | KVM_RISCV_ISA_EXT_ZVKNED, | ||
| 158 | KVM_RISCV_ISA_EXT_ZVKNHA, | ||
| 159 | KVM_RISCV_ISA_EXT_ZVKNHB, | ||
| 160 | KVM_RISCV_ISA_EXT_ZVKSED, | ||
| 161 | KVM_RISCV_ISA_EXT_ZVKSH, | ||
| 162 | KVM_RISCV_ISA_EXT_ZVKT, | ||
| 163 | KVM_RISCV_ISA_EXT_ZFH, | ||
| 164 | KVM_RISCV_ISA_EXT_ZFHMIN, | ||
| 165 | KVM_RISCV_ISA_EXT_ZIHINTNTL, | ||
| 166 | KVM_RISCV_ISA_EXT_ZVFH, | ||
| 167 | KVM_RISCV_ISA_EXT_ZVFHMIN, | ||
| 168 | KVM_RISCV_ISA_EXT_ZFA, | ||
| 142 | KVM_RISCV_ISA_EXT_MAX, | 169 | KVM_RISCV_ISA_EXT_MAX, |
| 143 | }; | 170 | }; |
| 144 | 171 | ||
| @@ -42,15 +42,42 @@ static const unsigned long kvm_isa_ext_arr[] = { · 41 unmodified lines | |||
| 42 | KVM_ISA_EXT_ARR(SVPBMT), | 42 | KVM_ISA_EXT_ARR(SVPBMT), |
| 43 | KVM_ISA_EXT_ARR(ZBA), | 43 | KVM_ISA_EXT_ARR(ZBA), |
| 44 | KVM_ISA_EXT_ARR(ZBB), | 44 | KVM_ISA_EXT_ARR(ZBB), |
| 45 | KVM_ISA_EXT_ARR(ZBC), | ||
| 46 | KVM_ISA_EXT_ARR(ZBKB), | ||
| 47 | KVM_ISA_EXT_ARR(ZBKC), | ||
| 48 | KVM_ISA_EXT_ARR(ZBKX), | ||
| 45 | KVM_ISA_EXT_ARR(ZBS), | 49 | KVM_ISA_EXT_ARR(ZBS), |
| 50 | KVM_ISA_EXT_ARR(ZFA), | ||
| 51 | KVM_ISA_EXT_ARR(ZFH), | ||
| 52 | KVM_ISA_EXT_ARR(ZFHMIN), | ||
| 46 | KVM_ISA_EXT_ARR(ZICBOM), | 53 | KVM_ISA_EXT_ARR(ZICBOM), |
| 47 | KVM_ISA_EXT_ARR(ZICBOZ), | 54 | KVM_ISA_EXT_ARR(ZICBOZ), |
| 48 | KVM_ISA_EXT_ARR(ZICNTR), | 55 | KVM_ISA_EXT_ARR(ZICNTR), |
| 49 | KVM_ISA_EXT_ARR(ZICOND), | 56 | KVM_ISA_EXT_ARR(ZICOND), |
| 50 | KVM_ISA_EXT_ARR(ZICSR), | 57 | KVM_ISA_EXT_ARR(ZICSR), |
| 51 | KVM_ISA_EXT_ARR(ZIFENCEI), | 58 | KVM_ISA_EXT_ARR(ZIFENCEI), |
| 59 | KVM_ISA_EXT_ARR(ZIHINTNTL), | ||
| 52 | KVM_ISA_EXT_ARR(ZIHINTPAUSE), | 60 | KVM_ISA_EXT_ARR(ZIHINTPAUSE), |
| 53 | KVM_ISA_EXT_ARR(ZIHPM), | 61 | KVM_ISA_EXT_ARR(ZIHPM), |
| 62 | KVM_ISA_EXT_ARR(ZKND), | ||
| 63 | KVM_ISA_EXT_ARR(ZKNE), | ||
| 64 | KVM_ISA_EXT_ARR(ZKNH), | ||
| 65 | KVM_ISA_EXT_ARR(ZKR), | ||
| 66 | KVM_ISA_EXT_ARR(ZKSED), | ||
| 67 | KVM_ISA_EXT_ARR(ZKSH), | ||
| 68 | KVM_ISA_EXT_ARR(ZKT), | ||
| 69 | KVM_ISA_EXT_ARR(ZVBB), | ||
| 70 | KVM_ISA_EXT_ARR(ZVBC), | ||
| 71 | KVM_ISA_EXT_ARR(ZVFH), | ||
| 72 | KVM_ISA_EXT_ARR(ZVFHMIN), | ||
| 73 | KVM_ISA_EXT_ARR(ZVKB), | ||
| 74 | KVM_ISA_EXT_ARR(ZVKG), | ||
| 75 | KVM_ISA_EXT_ARR(ZVKNED), | ||
| 76 | KVM_ISA_EXT_ARR(ZVKNHA), | ||
| 77 | KVM_ISA_EXT_ARR(ZVKNHB), | ||
| 78 | KVM_ISA_EXT_ARR(ZVKSED), | ||
| 79 | KVM_ISA_EXT_ARR(ZVKSH), | ||
| 80 | KVM_ISA_EXT_ARR(ZVKT), | ||
| 54 | }; | 81 | }; |
| 55 | 82 | ||
| 56 | static unsigned long kvm_riscv_vcpu_base2isa_ext(unsigned long base_ext) | 83 | static unsigned long kvm_riscv_vcpu_base2isa_ext(unsigned long base_ext) |
| @@ -92,13 +119,40 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext) · 35 unmodified lines | |||
| 92 | case KVM_RISCV_ISA_EXT_SVNAPOT: | 119 | case KVM_RISCV_ISA_EXT_SVNAPOT: |
| 93 | case KVM_RISCV_ISA_EXT_ZBA: | 120 | case KVM_RISCV_ISA_EXT_ZBA: |
| 94 | case KVM_RISCV_ISA_EXT_ZBB: | 121 | case KVM_RISCV_ISA_EXT_ZBB: |
| 122 | case KVM_RISCV_ISA_EXT_ZBC: | ||
| 123 | case KVM_RISCV_ISA_EXT_ZBKB: | ||
| 124 | case KVM_RISCV_ISA_EXT_ZBKC: | ||
| 125 | case KVM_RISCV_ISA_EXT_ZBKX: | ||
| 95 | case KVM_RISCV_ISA_EXT_ZBS: | 126 | case KVM_RISCV_ISA_EXT_ZBS: |
| 127 | case KVM_RISCV_ISA_EXT_ZFA: | ||
| 128 | case KVM_RISCV_ISA_EXT_ZFH: | ||
| 129 | case KVM_RISCV_ISA_EXT_ZFHMIN: | ||
| 96 | case KVM_RISCV_ISA_EXT_ZICNTR: | 130 | case KVM_RISCV_ISA_EXT_ZICNTR: |
| 97 | case KVM_RISCV_ISA_EXT_ZICOND: | 131 | case KVM_RISCV_ISA_EXT_ZICOND: |
| 98 | case KVM_RISCV_ISA_EXT_ZICSR: | 132 | case KVM_RISCV_ISA_EXT_ZICSR: |
| 99 | case KVM_RISCV_ISA_EXT_ZIFENCEI: | 133 | case KVM_RISCV_ISA_EXT_ZIFENCEI: |
| 134 | case KVM_RISCV_ISA_EXT_ZIHINTNTL: | ||
| 100 | case KVM_RISCV_ISA_EXT_ZIHINTPAUSE: | 135 | case KVM_RISCV_ISA_EXT_ZIHINTPAUSE: |
| 101 | case KVM_RISCV_ISA_EXT_ZIHPM: | 136 | case KVM_RISCV_ISA_EXT_ZIHPM: |
| 137 | case KVM_RISCV_ISA_EXT_ZKND: | ||
| 138 | case KVM_RISCV_ISA_EXT_ZKNE: | ||
| 139 | case KVM_RISCV_ISA_EXT_ZKNH: | ||
| 140 | case KVM_RISCV_ISA_EXT_ZKR: | ||
| 141 | case KVM_RISCV_ISA_EXT_ZKSED: | ||
| 142 | case KVM_RISCV_ISA_EXT_ZKSH: | ||
| 143 | case KVM_RISCV_ISA_EXT_ZKT: | ||
| 144 | case KVM_RISCV_ISA_EXT_ZVBB: | ||
| 145 | case KVM_RISCV_ISA_EXT_ZVBC: | ||
| 146 | case KVM_RISCV_ISA_EXT_ZVFH: | ||
| 147 | case KVM_RISCV_ISA_EXT_ZVFHMIN: | ||
| 148 | case KVM_RISCV_ISA_EXT_ZVKB: | ||
| 149 | case KVM_RISCV_ISA_EXT_ZVKG: | ||
| 150 | case KVM_RISCV_ISA_EXT_ZVKNED: | ||
| 151 | case KVM_RISCV_ISA_EXT_ZVKNHA: | ||
| 152 | case KVM_RISCV_ISA_EXT_ZVKNHB: | ||
| 153 | case KVM_RISCV_ISA_EXT_ZVKSED: | ||
| 154 | case KVM_RISCV_ISA_EXT_ZVKSH: | ||
| 155 | case KVM_RISCV_ISA_EXT_ZVKT: | ||
| 102 | return false; | 156 | return false; |
| 103 | /* Extensions which can be disabled using Smstateen */ | 157 | /* Extensions which can be disabled using Smstateen */ |
| 104 | case KVM_RISCV_ISA_EXT_SSAIA: | 158 | case KVM_RISCV_ISA_EXT_SSAIA: |
| @@ -53,7 +53,7 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, · 52 unmodified lines | |||
| 53 | * support, so nop when Zbb is available and jump when Zbb is | 53 | * support, so nop when Zbb is available and jump when Zbb is |
| 54 | * not available. | 54 | * not available. |
| 55 | */ | 55 | */ |
| 56 | asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, | 56 | asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, |
| 57 | RISCV_ISA_EXT_ZBB, 1) | 57 | RISCV_ISA_EXT_ZBB, 1) |
| 58 | : | 58 | : |
| 59 | : | 59 | : |
| @@ -170,7 +170,7 @@ do_csum_with_alignment(const unsigned char *buff, int len) · 110 unmodified lines | |||
| 170 | * support, so nop when Zbb is available and jump when Zbb is | 170 | * support, so nop when Zbb is available and jump when Zbb is |
| 171 | * not available. | 171 | * not available. |
| 172 | */ | 172 | */ |
| 173 | asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, | 173 | asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, |
| 174 | RISCV_ISA_EXT_ZBB, 1) | 174 | RISCV_ISA_EXT_ZBB, 1) |
| 175 | : | 175 | : |
| 176 | : | 176 | : |
| @@ -178,7 +178,7 @@ do_csum_with_alignment(const unsigned char *buff, int len) · 1 unmodified line | |||
| 178 | : no_zbb); | 178 | : no_zbb); |
| 179 | 179 | ||
| 180 | #ifdef CONFIG_32BIT | 180 | #ifdef CONFIG_32BIT |
| 181 | asm_volatile_goto(".option push \n\ | 181 | asm_goto_output(".option push \n\ |
| 182 | .option arch,+zbb \n\ | 182 | .option arch,+zbb \n\ |
| 183 | rori %[fold_temp], %[csum], 16 \n\ | 183 | rori %[fold_temp], %[csum], 16 \n\ |
| 184 | andi %[offset], %[offset], 1 \n\ | 184 | andi %[offset], %[offset], 1 \n\ |
| @@ -193,7 +193,7 @@ do_csum_with_alignment(const unsigned char *buff, int len) · 8 unmodified lines | |||
| 193 | 193 | ||
| 194 | return (unsigned short)csum; | 194 | return (unsigned short)csum; |
| 195 | #else /* !CONFIG_32BIT */ | 195 | #else /* !CONFIG_32BIT */ |
| 196 | asm_volatile_goto(".option push \n\ | 196 | asm_goto_output(".option push \n\ |
| 197 | .option arch,+zbb \n\ | 197 | .option arch,+zbb \n\ |
| 198 | rori %[fold_temp], %[csum], 32 \n\ | 198 | rori %[fold_temp], %[csum], 32 \n\ |
| 199 | add %[csum], %[fold_temp], %[csum] \n\ | 199 | add %[csum], %[fold_temp], %[csum] \n\ |
| @@ -257,7 +257,7 @@ do_csum_no_alignment(const unsigned char *buff, int len) · 57 unmodified lines | |||
| 257 | * support, so nop when Zbb is available and jump when Zbb is | 257 | * support, so nop when Zbb is available and jump when Zbb is |
| 258 | * not available. | 258 | * not available. |
| 259 | */ | 259 | */ |
| 260 | asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, | 260 | asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, |
| 261 | RISCV_ISA_EXT_ZBB, 1) | 261 | RISCV_ISA_EXT_ZBB, 1) |
| 262 | : | 262 | : |
| 263 | : | 263 | : |
| @@ -125,6 +125,26 @@ pte_t *huge_pte_offset(struct mm_struct *mm, · 124 unmodified lines | |||
| 125 | return pte; | 125 | return pte; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | unsigned long hugetlb_mask_last_page(struct hstate *h) | ||
| 129 | { | ||
| 130 | unsigned long hp_size = huge_page_size(h); | ||
| 131 | |||
| 132 | switch (hp_size) { | ||
| 133 | #ifndef __PAGETABLE_PMD_FOLDED | ||
| 134 | case PUD_SIZE: | ||
| 135 | return P4D_SIZE - PUD_SIZE; | ||
| 136 | #endif | ||
| 137 | case PMD_SIZE: | ||
| 138 | return PUD_SIZE - PMD_SIZE; | ||
| 139 | case napot_cont_size(NAPOT_CONT64KB_ORDER): | ||
| 140 | return PMD_SIZE - napot_cont_size(NAPOT_CONT64KB_ORDER); | ||
| 141 | default: | ||
| 142 | break; | ||
| 143 | } | ||
| 144 | |||
| 145 | return 0UL; | ||
| 146 | } | ||
| 147 | |||
| 128 | static pte_t get_clear_contig(struct mm_struct *mm, | 148 | static pte_t get_clear_contig(struct mm_struct *mm, |
| 129 | unsigned long addr, | 149 | unsigned long addr, |
| 130 | pte_t *ptep, | 150 | pte_t *ptep, |
| @@ -177,13 +197,36 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) · 46 unmodified lines | |||
| 177 | return entry; | 197 | return entry; |
| 178 | } | 198 | } |
| 179 | 199 | ||
| 200 | static void clear_flush(struct mm_struct *mm, | ||
| 201 | unsigned long addr, | ||
| 202 | pte_t *ptep, | ||
| 203 | unsigned long pgsize, | ||
| 204 | unsigned long ncontig) | ||
| 205 | { | ||
| 206 | struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0); | ||
| 207 | unsigned long i, saddr = addr; | ||
| 208 | |||
| 209 | for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) | ||
| 210 | ptep_get_and_clear(mm, addr, ptep); | ||
| 211 | |||
| 212 | flush_tlb_range(&vma, saddr, addr); | ||
| 213 | } | ||
| 214 | |||
| 215 | /* | ||
| 216 | * When dealing with NAPOT mappings, the privileged specification indicates that | ||
| 217 | * "if an update needs to be made, the OS generally should first mark all of the | ||
| 218 | * PTEs invalid, then issue SFENCE.VMA instruction(s) covering all 4 KiB regions | ||
| 219 | * within the range, [...] then update the PTE(s), as described in Section | ||
| 220 | * 4.2.1.". That's the equivalent of the Break-Before-Make approach used by | ||
| 221 | * arm64. | ||
| 222 | */ | ||
| 180 | void set_huge_pte_at(struct mm_struct *mm, | 223 | void set_huge_pte_at(struct mm_struct *mm, |
| 181 | unsigned long addr, | 224 | unsigned long addr, |
| 182 | pte_t *ptep, | 225 | pte_t *ptep, |
| 183 | pte_t pte, | 226 | pte_t pte, |
| 184 | unsigned long sz) | 227 | unsigned long sz) |
| 185 | { | 228 | { |
| 186 | unsigned long hugepage_shift; | 229 | unsigned long hugepage_shift, pgsize; |
| 187 | int i, pte_num; | 230 | int i, pte_num; |
| 188 | 231 | ||
| 189 | if (sz >= PGDIR_SIZE) | 232 | if (sz >= PGDIR_SIZE) |
| @@ -198,7 +241,22 @@ void set_huge_pte_at(struct mm_struct *mm, · 8 unmodified lines | |||
| 198 | hugepage_shift = PAGE_SHIFT; | 241 | hugepage_shift = PAGE_SHIFT; |
| 199 | 242 | ||
| 200 | pte_num = sz >> hugepage_shift; | 243 | pte_num = sz >> hugepage_shift; |
| 201 | for (i = 0; i < pte_num; i++, ptep++, addr += (1 << hugepage_shift)) | 244 | pgsize = 1 << hugepage_shift; |
| 245 | |||
| 246 | if (!pte_present(pte)) { | ||
| 247 | for (i = 0; i < pte_num; i++, ptep++, addr += pgsize) | ||
| 248 | set_ptes(mm, addr, ptep, pte, 1); | ||
| 249 | return; | ||
| 250 | } | ||
| 251 | |||
| 252 | if (!pte_napot(pte)) { | ||
| 253 | set_ptes(mm, addr, ptep, pte, 1); | ||
| 254 | return; | ||
| 255 | } | ||
| 256 | |||
| 257 | clear_flush(mm, addr, ptep, pgsize, pte_num); | ||
| 258 | |||
| 259 | for (i = 0; i < pte_num; i++, ptep++, addr += pgsize) | ||
| 202 | set_pte_at(mm, addr, ptep, pte); | 260 | set_pte_at(mm, addr, ptep, pte); |
| 203 | } | 261 | } |
| 204 | 262 | ||
| @@ -306,7 +364,7 @@ void huge_pte_clear(struct mm_struct *mm, · 101 unmodified lines | |||
| 306 | pte_clear(mm, addr, ptep); | 364 | pte_clear(mm, addr, ptep); |
| 307 | } | 365 | } |
| 308 | 366 | ||
| 309 | static __init bool is_napot_size(unsigned long size) | 367 | static bool is_napot_size(unsigned long size) |
| 310 | { | 368 | { |
| 311 | unsigned long order; | 369 | unsigned long order; |
| 312 | 370 | ||
| @@ -334,7 +392,7 @@ arch_initcall(napot_hugetlbpages_init); · 21 unmodified lines | |||
| 334 | 392 | ||
| 335 | #else | 393 | #else |
| 336 | 394 | ||
| 337 | static __init bool is_napot_size(unsigned long size) | 395 | static bool is_napot_size(unsigned long size) |
| 338 | { | 396 | { |
| 339 | return false; | 397 | return false; |
| 340 | } | 398 | } |
| @@ -351,7 +409,7 @@ int pmd_huge(pmd_t pmd) · 10 unmodified lines | |||
| 351 | return pmd_leaf(pmd); | 409 | return pmd_leaf(pmd); |
| 352 | } | 410 | } |
| 353 | 411 | ||
| 354 | bool __init arch_hugetlb_valid_size(unsigned long size) | 412 | static bool __hugetlb_valid_size(unsigned long size) |
| 355 | { | 413 | { |
| 356 | if (size == HPAGE_SIZE) | 414 | if (size == HPAGE_SIZE) |
| 357 | return true; | 415 | return true; |
| @@ -363,6 +421,16 @@ bool __init arch_hugetlb_valid_size(unsigned long size) · 5 unmodified lines | |||
| 363 | return false; | 421 | return false; |
| 364 | } | 422 | } |
| 365 | 423 | ||
| 424 | bool __init arch_hugetlb_valid_size(unsigned long size) | ||
| 425 | { | ||
| 426 | return __hugetlb_valid_size(size); | ||
| 427 | } | ||
| 428 | |||
| 429 | bool arch_hugetlb_migration_supported(struct hstate *h) | ||
| 430 | { | ||
| 431 | return __hugetlb_valid_size(huge_page_size(h)); | ||
| 432 | } | ||
| 433 | |||
| 366 | #ifdef CONFIG_CONTIG_ALLOC | 434 | #ifdef CONFIG_CONTIG_ALLOC |
| 367 | static __init int gigantic_pages_init(void) | 435 | static __init int gigantic_pages_init(void) |
| 368 | { | 436 | { |
| @@ -1385,6 +1385,10 @@ void __init misc_mem_init(void) · 1384 unmodified lines | |||
| 1385 | early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); | 1385 | early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); |
| 1386 | arch_numa_init(); | 1386 | arch_numa_init(); |
| 1387 | sparse_init(); | 1387 | sparse_init(); |
| 1388 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | ||
| 1389 | /* The entire VMEMMAP region has been populated. Flush TLB for this region */ | ||
| 1390 | local_flush_tlb_kernel_range(VMEMMAP_START, VMEMMAP_END); | ||
| 1391 | #endif | ||
| 1388 | zone_sizes_init(); | 1392 | zone_sizes_init(); |
| 1389 | arch_reserve_crashkernel(); | 1393 | arch_reserve_crashkernel(); |
| 1390 | memblock_dump_all(); | 1394 | memblock_dump_all(); |
| @@ -66,9 +66,10 @@ static inline void local_flush_tlb_range_asid(unsigned long start, · 65 unmodified lines | |||
| 66 | local_flush_tlb_range_threshold_asid(start, size, stride, asid); | 66 | local_flush_tlb_range_threshold_asid(start, size, stride, asid); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | /* Flush a range of kernel pages without broadcasting */ | ||
| 69 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | 70 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) |
| 70 | { | 71 | { |
| 71 | local_flush_tlb_range_asid(start, end, PAGE_SIZE, FLUSH_TLB_NO_ASID); | 72 | local_flush_tlb_range_asid(start, end - start, PAGE_SIZE, FLUSH_TLB_NO_ASID); |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | static void __ipi_flush_tlb_all(void *info) | 75 | static void __ipi_flush_tlb_all(void *info) |
| @@ -233,4 +234,5 @@ void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch) · 158 unmodified lines | |||
| 233 | { | 234 | { |
| 234 | __flush_tlb_range(&batch->cpumask, FLUSH_TLB_NO_ASID, 0, | 235 | __flush_tlb_range(&batch->cpumask, FLUSH_TLB_NO_ASID, 0, |
| 235 | FLUSH_TLB_MAX_SIZE, PAGE_SIZE); | 236 | FLUSH_TLB_MAX_SIZE, PAGE_SIZE); |
| 237 | cpumask_clear(&batch->cpumask); | ||
| 236 | } | 238 | } |
| @@ -795,6 +795,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, · 794 unmodified lines | |||
| 795 | struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; | 795 | struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; |
| 796 | struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; | 796 | struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; |
| 797 | struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; | 797 | struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; |
| 798 | bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT; | ||
| 798 | void *orig_call = func_addr; | 799 | void *orig_call = func_addr; |
| 799 | bool save_ret; | 800 | bool save_ret; |
| 800 | u32 insn; | 801 | u32 insn; |
| @@ -878,7 +879,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, · 77 unmodified lines | |||
| 878 | 879 | ||
| 879 | stack_size = round_up(stack_size, 16); | 880 | stack_size = round_up(stack_size, 16); |
| 880 | 881 | ||
| 881 | if (func_addr) { | 882 | if (!is_struct_ops) { |
| 882 | /* For the trampoline called from function entry, | 883 | /* For the trampoline called from function entry, |
| 883 | * the frame of traced function and the frame of | 884 | * the frame of traced function and the frame of |
| 884 | * trampoline need to be considered. | 885 | * trampoline need to be considered. |
| @@ -998,7 +999,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, · 113 unmodified lines | |||
| 998 | 999 | ||
| 999 | emit_ld(RV_REG_S1, -sreg_off, RV_REG_FP, ctx); | 1000 | emit_ld(RV_REG_S1, -sreg_off, RV_REG_FP, ctx); |
| 1000 | 1001 | ||
| 1001 | if (func_addr) { | 1002 | if (!is_struct_ops) { |
| 1002 | /* trampoline called from function entry */ | 1003 | /* trampoline called from function entry */ |
| 1003 | emit_ld(RV_REG_T0, stack_size - 8, RV_REG_SP, ctx); | 1004 | emit_ld(RV_REG_T0, stack_size - 8, RV_REG_SP, ctx); |
| 1004 | emit_ld(RV_REG_FP, stack_size - 16, RV_REG_SP, ctx); | 1005 | emit_ld(RV_REG_FP, stack_size - 16, RV_REG_SP, ctx); |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | |||
| 25 | */ | 25 | */ |
| 26 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 26 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 27 | { | 27 | { |
| 28 | asm_volatile_goto("0: brcl 0,%l[label]\n" | 28 | asm goto("0: brcl 0,%l[label]\n" |
| 29 | ".pushsection __jump_table,\"aw\"\n" | 29 | ".pushsection __jump_table,\"aw\"\n" |
| 30 | ".balign 8\n" | 30 | ".balign 8\n" |
| 31 | ".long 0b-.,%l[label]-.\n" | 31 | ".long 0b-.,%l[label]-.\n" |
| @@ -39,7 +39,7 @@ label: · 7 unmodified lines | |||
| 39 | 39 | ||
| 40 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) | 40 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) |
| 41 | { | 41 | { |
| 42 | asm_volatile_goto("0: brcl 15,%l[label]\n" | 42 | asm goto("0: brcl 15,%l[label]\n" |
| 43 | ".pushsection __jump_table,\"aw\"\n" | 43 | ".pushsection __jump_table,\"aw\"\n" |
| 44 | ".balign 8\n" | 44 | ".balign 8\n" |
| 45 | ".long 0b-.,%l[label]-.\n" | 45 | ".long 0b-.,%l[label]-.\n" |
| @@ -676,8 +676,12 @@ static int handle_pqap(struct kvm_vcpu *vcpu) · 675 unmodified lines | |||
| 676 | if (vcpu->kvm->arch.crypto.pqap_hook) { | 676 | if (vcpu->kvm->arch.crypto.pqap_hook) { |
| 677 | pqap_hook = *vcpu->kvm->arch.crypto.pqap_hook; | 677 | pqap_hook = *vcpu->kvm->arch.crypto.pqap_hook; |
| 678 | ret = pqap_hook(vcpu); | 678 | ret = pqap_hook(vcpu); |
| 679 | if (!ret && vcpu->run->s.regs.gprs[1] & 0x00ff0000) | 679 | if (!ret) { |
| 680 | kvm_s390_set_psw_cc(vcpu, 3); | 680 | if (vcpu->run->s.regs.gprs[1] & 0x00ff0000) |
| 681 | kvm_s390_set_psw_cc(vcpu, 3); | ||
| 682 | else | ||
| 683 | kvm_s390_set_psw_cc(vcpu, 0); | ||
| 684 | } | ||
| 681 | up_read(&vcpu->kvm->arch.crypto.pqap_hook_rwsem); | 685 | up_read(&vcpu->kvm->arch.crypto.pqap_hook_rwsem); |
| 682 | return ret; | 686 | return ret; |
| 683 | } | 687 | } |
| @@ -1235,7 +1235,6 @@ static int acquire_gmap_shadow(struct kvm_vcpu *vcpu, · 1234 unmodified lines | |||
| 1235 | gmap = gmap_shadow(vcpu->arch.gmap, asce, edat); | 1235 | gmap = gmap_shadow(vcpu->arch.gmap, asce, edat); |
| 1236 | if (IS_ERR(gmap)) | 1236 | if (IS_ERR(gmap)) |
| 1237 | return PTR_ERR(gmap); | 1237 | return PTR_ERR(gmap); |
| 1238 | gmap->private = vcpu->kvm; | ||
| 1239 | vcpu->kvm->stat.gmap_shadow_create++; | 1238 | vcpu->kvm->stat.gmap_shadow_create++; |
| 1240 | WRITE_ONCE(vsie_page->gmap, gmap); | 1239 | WRITE_ONCE(vsie_page->gmap, gmap); |
| 1241 | return 0; | 1240 | return 0; |
| @@ -1691,6 +1691,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce, · 1690 unmodified lines | |||
| 1691 | return ERR_PTR(-ENOMEM); | 1691 | return ERR_PTR(-ENOMEM); |
| 1692 | new->mm = parent->mm; | 1692 | new->mm = parent->mm; |
| 1693 | new->parent = gmap_get(parent); | 1693 | new->parent = gmap_get(parent); |
| 1694 | new->private = parent->private; | ||
| 1694 | new->orig_asce = asce; | 1695 | new->orig_asce = asce; |
| 1695 | new->edat_level = edat_level; | 1696 | new->edat_level = edat_level; |
| 1696 | new->initialized = false; | 1697 | new->initialized = false; |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 11 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 12 | { | 12 | { |
| 13 | asm_volatile_goto("1:\n\t" | 13 | asm goto("1:\n\t" |
| 14 | "nop\n\t" | 14 | "nop\n\t" |
| 15 | "nop\n\t" | 15 | "nop\n\t" |
| 16 | ".pushsection __jump_table, \"aw\"\n\t" | 16 | ".pushsection __jump_table, \"aw\"\n\t" |
| @@ -26,7 +26,7 @@ l_yes: · 9 unmodified lines | |||
| 26 | 26 | ||
| 27 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) | 27 | static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) |
| 28 | { | 28 | { |
| 29 | asm_volatile_goto("1:\n\t" | 29 | asm goto("1:\n\t" |
| 30 | "b %l[l_yes]\n\t" | 30 | "b %l[l_yes]\n\t" |
| 31 | "nop\n\t" | 31 | "nop\n\t" |
| 32 | ".pushsection __jump_table, \"aw\"\n\t" | 32 | ".pushsection __jump_table, \"aw\"\n\t" |
| @@ -115,7 +115,9 @@ archprepare: · 114 unmodified lines | |||
| 115 | $(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h | 115 | $(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h |
| 116 | 116 | ||
| 117 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static | 117 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static |
| 118 | LINK-$(CONFIG_LD_SCRIPT_DYN) += $(call cc-option, -no-pie) | 118 | ifdef CONFIG_LD_SCRIPT_DYN |
| 119 | LINK-$(call gcc-min-version, 60100)$(CONFIG_CC_IS_CLANG) += -no-pie | ||
| 120 | endif | ||
| 119 | LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib | 121 | LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib |
| 120 | 122 | ||
| 121 | CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ | 123 | CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ |
| @@ -75,7 +75,7 @@ extern void setup_clear_cpu_cap(unsigned int bit); · 74 unmodified lines | |||
| 75 | */ | 75 | */ |
| 76 | static __always_inline bool _static_cpu_has(u16 bit) | 76 | static __always_inline bool _static_cpu_has(u16 bit) |
| 77 | { | 77 | { |
| 78 | asm_volatile_goto("1: jmp 6f\n" | 78 | asm goto("1: jmp 6f\n" |
| 79 | "2:\n" | 79 | "2:\n" |
| 80 | ".skip -(((5f-4f) - (2b-1b)) > 0) * " | 80 | ".skip -(((5f-4f) - (2b-1b)) > 0) * " |
| 81 | "((5f-4f) - (2b-1b)),0x90\n" | 81 | "((5f-4f) - (2b-1b)),0x90\n" |
| @@ -379,7 +379,7 @@ config X86_CMOV · 378 unmodified lines | |||
| 379 | config X86_MINIMUM_CPU_FAMILY | 379 | config X86_MINIMUM_CPU_FAMILY |
| 380 | int | 380 | int |
| 381 | default "64" if X86_64 | 381 | default "64" if X86_64 |
| 382 | default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8) | 382 | default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCORE2 || MK7 || MK8) |
| 383 | default "5" if X86_32 && X86_CMPXCHG64 | 383 | default "5" if X86_32 && X86_CMPXCHG64 |
| 384 | default "4" | 384 | default "4" |
| 385 | 385 | ||
| @@ -112,13 +112,13 @@ ifeq ($(CONFIG_X86_32),y) · 111 unmodified lines | |||
| 112 | # temporary until string.h is fixed | 112 | # temporary until string.h is fixed |
| 113 | KBUILD_CFLAGS += -ffreestanding | 113 | KBUILD_CFLAGS += -ffreestanding |
| 114 | 114 | ||
| 115 | ifeq ($(CONFIG_STACKPROTECTOR),y) | 115 | ifeq ($(CONFIG_STACKPROTECTOR),y) |
| 116 | ifeq ($(CONFIG_SMP),y) | 116 | ifeq ($(CONFIG_SMP),y) |
| 117 | KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard | 117 | KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard |
| 118 | else | 118 | else |
| 119 | KBUILD_CFLAGS += -mstack-protector-guard=global | 119 | KBUILD_CFLAGS += -mstack-protector-guard=global |
| 120 | endif | 120 | endif |
| 121 | endif | 121 | endif |
| 122 | else | 122 | else |
| 123 | BITS := 64 | 123 | BITS := 64 |
| 124 | UTS_MACHINE := x86_64 | 124 | UTS_MACHINE := x86_64 |
| @@ -106,8 +106,7 @@ extra_header_fields: · 105 unmodified lines | |||
| 106 | .word 0 # MinorSubsystemVersion | 106 | .word 0 # MinorSubsystemVersion |
| 107 | .long 0 # Win32VersionValue | 107 | .long 0 # Win32VersionValue |
| 108 | 108 | ||
| 109 | .long setup_size + ZO__end + pecompat_vsize | 109 | .long setup_size + ZO__end # SizeOfImage |
| 110 | # SizeOfImage | ||
| 111 | 110 | ||
| 112 | .long salign # SizeOfHeaders | 111 | .long salign # SizeOfHeaders |
| 113 | .long 0 # CheckSum | 112 | .long 0 # CheckSum |
| @@ -143,7 +142,7 @@ section_table: · 29 unmodified lines | |||
| 143 | .ascii ".setup" | 142 | .ascii ".setup" |
| 144 | .byte 0 | 143 | .byte 0 |
| 145 | .byte 0 | 144 | .byte 0 |
| 146 | .long setup_size - salign # VirtualSize | 145 | .long pecompat_fstart - salign # VirtualSize |
| 147 | .long salign # VirtualAddress | 146 | .long salign # VirtualAddress |
| 148 | .long pecompat_fstart - salign # SizeOfRawData | 147 | .long pecompat_fstart - salign # SizeOfRawData |
| 149 | .long salign # PointerToRawData | 148 | .long salign # PointerToRawData |
| @@ -156,8 +155,8 @@ section_table: · 6 unmodified lines | |||
| 156 | #ifdef CONFIG_EFI_MIXED | 155 | #ifdef CONFIG_EFI_MIXED |
| 157 | .asciz ".compat" | 156 | .asciz ".compat" |
| 158 | 157 | ||
| 159 | .long 8 # VirtualSize | 158 | .long pecompat_fsize # VirtualSize |
| 160 | .long setup_size + ZO__end # VirtualAddress | 159 | .long pecompat_fstart # VirtualAddress |
| 161 | .long pecompat_fsize # SizeOfRawData | 160 | .long pecompat_fsize # SizeOfRawData |
| 162 | .long pecompat_fstart # PointerToRawData | 161 | .long pecompat_fstart # PointerToRawData |
| 163 | 162 | ||
| @@ -172,17 +171,16 @@ section_table: · 8 unmodified lines | |||
| 172 | * modes this image supports. | 171 | * modes this image supports. |
| 173 | */ | 172 | */ |
| 174 | .pushsection ".pecompat", "a", @progbits | 173 | .pushsection ".pecompat", "a", @progbits |
| 175 | .balign falign | 174 | .balign salign |
| 176 | .set pecompat_vsize, salign | ||
| 177 | .globl pecompat_fstart | 175 | .globl pecompat_fstart |
| 178 | pecompat_fstart: | 176 | pecompat_fstart: |
| 179 | .byte 0x1 # Version | 177 | .byte 0x1 # Version |
| 180 | .byte 8 # Size | 178 | .byte 8 # Size |
| 181 | .word IMAGE_FILE_MACHINE_I386 # PE machine type | 179 | .word IMAGE_FILE_MACHINE_I386 # PE machine type |
| 182 | .long setup_size + ZO_efi32_pe_entry # Entrypoint | 180 | .long setup_size + ZO_efi32_pe_entry # Entrypoint |
| 181 | .byte 0x0 # Sentinel | ||
| 183 | .popsection | 182 | .popsection |
| 184 | #else | 183 | #else |
| 185 | .set pecompat_vsize, 0 | ||
| 186 | .set pecompat_fstart, setup_size | 184 | .set pecompat_fstart, setup_size |
| 187 | #endif | 185 | #endif |
| 188 | .ascii ".text" | 186 | .ascii ".text" |
| @@ -24,6 +24,9 @@ SECTIONS · 23 unmodified lines | |||
| 24 | .text : { *(.text .text.*) } | 24 | .text : { *(.text .text.*) } |
| 25 | .text32 : { *(.text32) } | 25 | .text32 : { *(.text32) } |
| 26 | 26 | ||
| 27 | .pecompat : { *(.pecompat) } | ||
| 28 | PROVIDE(pecompat_fsize = setup_size - pecompat_fstart); | ||
| 29 | |||
| 27 | . = ALIGN(16); | 30 | . = ALIGN(16); |
| 28 | .rodata : { *(.rodata*) } | 31 | .rodata : { *(.rodata*) } |
| 29 | 32 | ||
| @@ -36,9 +39,6 @@ SECTIONS · 6 unmodified lines | |||
| 36 | . = ALIGN(16); | 39 | . = ALIGN(16); |
| 37 | .data : { *(.data*) } | 40 | .data : { *(.data*) } |
| 38 | 41 | ||
| 39 | .pecompat : { *(.pecompat) } | ||
| 40 | PROVIDE(pecompat_fsize = setup_size - pecompat_fstart); | ||
| 41 | |||
| 42 | .signature : { | 42 | .signature : { |
| 43 | setup_sig = .; | 43 | setup_sig = .; |
| 44 | LONG(0x5a5aaa55) | 44 | LONG(0x5a5aaa55) |
| @@ -10,13 +10,14 @@ enum cc_vendor { · 9 unmodified lines | |||
| 10 | CC_VENDOR_INTEL, | 10 | CC_VENDOR_INTEL, |
| 11 | }; | 11 | }; |
| 12 | 12 | ||
| 13 | extern enum cc_vendor cc_vendor; | ||
| 14 | |||
| 15 | #ifdef CONFIG_ARCH_HAS_CC_PLATFORM | 13 | #ifdef CONFIG_ARCH_HAS_CC_PLATFORM |
| 14 | extern enum cc_vendor cc_vendor; | ||
| 16 | void cc_set_mask(u64 mask); | 15 | void cc_set_mask(u64 mask); |
| 17 | u64 cc_mkenc(u64 val); | 16 | u64 cc_mkenc(u64 val); |
| 18 | u64 cc_mkdec(u64 val); | 17 | u64 cc_mkdec(u64 val); |
| 19 | #else | 18 | #else |
| 19 | #define cc_vendor (CC_VENDOR_NONE) | ||
| 20 | |||
| 20 | static inline u64 cc_mkenc(u64 val) | 21 | static inline u64 cc_mkenc(u64 val) |
| 21 | { | 22 | { |
| 22 | return val; | 23 | return val; |
| @@ -168,7 +168,7 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); · 167 unmodified lines | |||
| 168 | */ | 168 | */ |
| 169 | static __always_inline bool _static_cpu_has(u16 bit) | 169 | static __always_inline bool _static_cpu_has(u16 bit) |
| 170 | { | 170 | { |
| 171 | asm_volatile_goto( | 171 | asm goto( |
| 172 | ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]") | 172 | ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]") |
| 173 | ".pushsection .altinstr_aux,\"ax\"\n" | 173 | ".pushsection .altinstr_aux,\"ax\"\n" |
| 174 | "6:\n" | 174 | "6:\n" |
| @@ -81,10 +81,8 @@ · 80 unmodified lines | |||
| 81 | #define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ | 81 | #define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ |
| 82 | #define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ | 82 | #define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ |
| 83 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ | 83 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ |
| 84 | |||
| 85 | /* CPU types for specific tunings: */ | ||
| 86 | #define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ | 84 | #define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ |
| 87 | /* FREE, was #define X86_FEATURE_K7 ( 3*32+ 5) "" Athlon */ | 85 | #define X86_FEATURE_ZEN5 ( 3*32+ 5) /* "" CPU based on Zen5 microarchitecture */ |
| 88 | #define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ | 86 | #define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ |
| 89 | #define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ | 87 | #define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ |
| 90 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ | 88 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ |
| @@ -162,6 +162,8 @@ · 161 unmodified lines | |||
| 162 | #define INTEL_FAM6_ATOM_CRESTMONT_X 0xAF /* Sierra Forest */ | 162 | #define INTEL_FAM6_ATOM_CRESTMONT_X 0xAF /* Sierra Forest */ |
| 163 | #define INTEL_FAM6_ATOM_CRESTMONT 0xB6 /* Grand Ridge */ | 163 | #define INTEL_FAM6_ATOM_CRESTMONT 0xB6 /* Grand Ridge */ |
| 164 | 164 | ||
| 165 | #define INTEL_FAM6_ATOM_DARKMONT_X 0xDD /* Clearwater Forest */ | ||
| 166 | |||
| 165 | /* Xeon Phi */ | 167 | /* Xeon Phi */ |
| 166 | 168 | ||
| 167 | #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ | 169 | #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 25 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) |
| 26 | { | 26 | { |
| 27 | asm_volatile_goto("1:" | 27 | asm goto("1:" |
| 28 | "jmp %l[l_yes] # objtool NOPs this \n\t" | 28 | "jmp %l[l_yes] # objtool NOPs this \n\t" |
| 29 | JUMP_TABLE_ENTRY | 29 | JUMP_TABLE_ENTRY |
| 30 | : : "i" (key), "i" (2 | branch) : : l_yes); | 30 | : : "i" (key), "i" (2 | branch) : : l_yes); |
| @@ -38,7 +38,7 @@ l_yes: · 7 unmodified lines | |||
| 38 | 38 | ||
| 39 | static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) | 39 | static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) |
| 40 | { | 40 | { |
| 41 | asm_volatile_goto("1:" | 41 | asm goto("1:" |
| 42 | ".byte " __stringify(BYTES_NOP5) "\n\t" | 42 | ".byte " __stringify(BYTES_NOP5) "\n\t" |
| 43 | JUMP_TABLE_ENTRY | 43 | JUMP_TABLE_ENTRY |
| 44 | : : "i" (key), "i" (branch) : : l_yes); | 44 | : : "i" (key), "i" (branch) : : l_yes); |
| @@ -52,7 +52,7 @@ l_yes: · 7 unmodified lines | |||
| 52 | 52 | ||
| 53 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) | 53 | static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) |
| 54 | { | 54 | { |
| 55 | asm_volatile_goto("1:" | 55 | asm goto("1:" |
| 56 | "jmp %l[l_yes]\n\t" | 56 | "jmp %l[l_yes]\n\t" |
| 57 | JUMP_TABLE_ENTRY | 57 | JUMP_TABLE_ENTRY |
| 58 | : : "i" (key), "i" (branch) : : l_yes); | 58 | : : "i" (key), "i" (branch) : : l_yes); |
| @@ -64,6 +64,7 @@ static inline bool kmsan_virt_addr_valid(void *addr) · 63 unmodified lines | |||
| 64 | { | 64 | { |
| 65 | unsigned long x = (unsigned long)addr; | 65 | unsigned long x = (unsigned long)addr; |
| 66 | unsigned long y = x - __START_KERNEL_map; | 66 | unsigned long y = x - __START_KERNEL_map; |
| 67 | bool ret; | ||
| 67 | 68 | ||
| 68 | /* use the carry flag to determine if x was < __START_KERNEL_map */ | 69 | /* use the carry flag to determine if x was < __START_KERNEL_map */ |
| 69 | if (unlikely(x > y)) { | 70 | if (unlikely(x > y)) { |
| @@ -79,7 +80,21 @@ static inline bool kmsan_virt_addr_valid(void *addr) · 9 unmodified lines | |||
| 79 | return false; | 80 | return false; |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | return pfn_valid(x >> PAGE_SHIFT); | 83 | /* |
| 84 | * pfn_valid() relies on RCU, and may call into the scheduler on exiting | ||
| 85 | * the critical section. However, this would result in recursion with | ||
| 86 | * KMSAN. Therefore, disable preemption here, and re-enable preemption | ||
| 87 | * below while suppressing reschedules to avoid recursion. | ||
| 88 | * | ||
| 89 | * Note, this sacrifices occasionally breaking scheduling guarantees. | ||
| 90 | * Although, a kernel compiled with KMSAN has already given up on any | ||
| 91 | * performance guarantees due to being heavily instrumented. | ||
| 92 | */ | ||
| 93 | preempt_disable(); | ||
| 94 | ret = pfn_valid(x >> PAGE_SHIFT); | ||
| 95 | preempt_enable_no_resched(); | ||
| 96 | |||
| 97 | return ret; | ||
| 83 | } | 98 | } |
| 84 | 99 | ||
| 85 | #endif /* !MODULE */ | 100 | #endif /* !MODULE */ |
| @@ -1145,6 +1145,8 @@ struct kvm_hv { · 1144 unmodified lines | |||
| 1145 | unsigned int synic_auto_eoi_used; | 1145 | unsigned int synic_auto_eoi_used; |
| 1146 | 1146 | ||
| 1147 | struct kvm_hv_syndbg hv_syndbg; | 1147 | struct kvm_hv_syndbg hv_syndbg; |
| 1148 | |||
| 1149 | bool xsaves_xsavec_checked; | ||
| 1148 | }; | 1150 | }; |
| 1149 | #endif | 1151 | #endif |
| 1150 | 1152 | ||
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \ | 13 | #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \ |
| 14 | ({ \ | 14 | ({ \ |
| 15 | bool c = false; \ | 15 | bool c = false; \ |
| 16 | asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ | 16 | asm goto (fullop "; j" #cc " %l[cc_label]" \ |
| 17 | : : [var] "m" (_var), ## __VA_ARGS__ \ | 17 | : : [var] "m" (_var), ## __VA_ARGS__ \ |
| 18 | : clobbers : cc_label); \ | 18 | : clobbers : cc_label); \ |
| 19 | if (0) { \ | 19 | if (0) { \ |
| @@ -205,7 +205,7 @@ static inline void clwb(volatile void *__p) · 204 unmodified lines | |||
| 205 | #ifdef CONFIG_X86_USER_SHADOW_STACK | 205 | #ifdef CONFIG_X86_USER_SHADOW_STACK |
| 206 | static inline int write_user_shstk_64(u64 __user *addr, u64 val) | 206 | static inline int write_user_shstk_64(u64 __user *addr, u64 val) |
| 207 | { | 207 | { |
| 208 | asm_volatile_goto("1: wrussq %[val], (%[addr])\n" | 208 | asm goto("1: wrussq %[val], (%[addr])\n" |
| 209 | _ASM_EXTABLE(1b, %l[fail]) | 209 | _ASM_EXTABLE(1b, %l[fail]) |
| 210 | :: [addr] "r" (addr), [val] "r" (val) | 210 | :: [addr] "r" (addr), [val] "r" (val) |
| 211 | :: fail); | 211 | :: fail); |
| @@ -58,12 +58,29 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); · 57 unmodified lines | |||
| 58 | ,,regs->di,,regs->si,,regs->dx \ | 58 | ,,regs->di,,regs->si,,regs->dx \ |
| 59 | ,,regs->r10,,regs->r8,,regs->r9) \ | 59 | ,,regs->r10,,regs->r8,,regs->r9) \ |
| 60 | 60 | ||
| 61 | |||
| 62 | /* SYSCALL_PT_ARGS is Adapted from s390x */ | ||
| 63 | #define SYSCALL_PT_ARG6(m, t1, t2, t3, t4, t5, t6) \ | ||
| 64 | SYSCALL_PT_ARG5(m, t1, t2, t3, t4, t5), m(t6, (regs->bp)) | ||
| 65 | #define SYSCALL_PT_ARG5(m, t1, t2, t3, t4, t5) \ | ||
| 66 | SYSCALL_PT_ARG4(m, t1, t2, t3, t4), m(t5, (regs->di)) | ||
| 67 | #define SYSCALL_PT_ARG4(m, t1, t2, t3, t4) \ | ||
| 68 | SYSCALL_PT_ARG3(m, t1, t2, t3), m(t4, (regs->si)) | ||
| 69 | #define SYSCALL_PT_ARG3(m, t1, t2, t3) \ | ||
| 70 | SYSCALL_PT_ARG2(m, t1, t2), m(t3, (regs->dx)) | ||
| 71 | #define SYSCALL_PT_ARG2(m, t1, t2) \ | ||
| 72 | SYSCALL_PT_ARG1(m, t1), m(t2, (regs->cx)) | ||
| 73 | #define SYSCALL_PT_ARG1(m, t1) m(t1, (regs->bx)) | ||
| 74 | #define SYSCALL_PT_ARGS(x, ...) SYSCALL_PT_ARG##x(__VA_ARGS__) | ||
| 75 | |||
| 76 | #define __SC_COMPAT_CAST(t, a) \ | ||
| 77 | (__typeof(__builtin_choose_expr(__TYPE_IS_L(t), 0, 0U))) \ | ||
| 78 | (unsigned int)a | ||
| 79 | |||
| 61 | /* Mapping of registers to parameters for syscalls on i386 */ | 80 | /* Mapping of registers to parameters for syscalls on i386 */ |
| 62 | #define SC_IA32_REGS_TO_ARGS(x, ...) \ | 81 | #define SC_IA32_REGS_TO_ARGS(x, ...) \ |
| 63 | __MAP(x,__SC_ARGS \ | 82 | SYSCALL_PT_ARGS(x, __SC_COMPAT_CAST, \ |
| 64 | ,,(unsigned int)regs->bx,,(unsigned int)regs->cx \ | 83 | __MAP(x, __SC_TYPE, __VA_ARGS__)) \ |
| 65 | ,,(unsigned int)regs->dx,,(unsigned int)regs->si \ | ||
| 66 | ,,(unsigned int)regs->di,,(unsigned int)regs->bp) | ||
| 67 | 84 | ||
| 68 | #define __SYS_STUB0(abi, name) \ | 85 | #define __SYS_STUB0(abi, name) \ |
| 69 | long __##abi##_##name(const struct pt_regs *regs); \ | 86 | long __##abi##_##name(const struct pt_regs *regs); \ |
| @@ -133,7 +133,7 @@ extern int __get_user_bad(void); · 132 unmodified lines | |||
| 133 | 133 | ||
| 134 | #ifdef CONFIG_X86_32 | 134 | #ifdef CONFIG_X86_32 |
| 135 | #define __put_user_goto_u64(x, addr, label) \ | 135 | #define __put_user_goto_u64(x, addr, label) \ |
| 136 | asm_volatile_goto("\n" \ | 136 | asm goto("\n" \ |
| 137 | "1: movl %%eax,0(%1)\n" \ | 137 | "1: movl %%eax,0(%1)\n" \ |
| 138 | "2: movl %%edx,4(%1)\n" \ | 138 | "2: movl %%edx,4(%1)\n" \ |
| 139 | _ASM_EXTABLE_UA(1b, %l2) \ | 139 | _ASM_EXTABLE_UA(1b, %l2) \ |
| @@ -295,7 +295,7 @@ do { \ · 155 unmodified lines | |||
| 295 | } while (0) | 295 | } while (0) |
| 296 | 296 | ||
| 297 | #define __get_user_asm(x, addr, itype, ltype, label) \ | 297 | #define __get_user_asm(x, addr, itype, ltype, label) \ |
| 298 | asm_volatile_goto("\n" \ | 298 | asm_goto_output("\n" \ |
| 299 | "1: mov"itype" %[umem],%[output]\n" \ | 299 | "1: mov"itype" %[umem],%[output]\n" \ |
| 300 | _ASM_EXTABLE_UA(1b, %l2) \ | 300 | _ASM_EXTABLE_UA(1b, %l2) \ |
| 301 | : [output] ltype(x) \ | 301 | : [output] ltype(x) \ |
| @@ -375,7 +375,7 @@ do { \ · 73 unmodified lines | |||
| 375 | __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ | 375 | __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ |
| 376 | __typeof__(*(_ptr)) __old = *_old; \ | 376 | __typeof__(*(_ptr)) __old = *_old; \ |
| 377 | __typeof__(*(_ptr)) __new = (_new); \ | 377 | __typeof__(*(_ptr)) __new = (_new); \ |
| 378 | asm_volatile_goto("\n" \ | 378 | asm_goto_output("\n" \ |
| 379 | "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ | 379 | "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ |
| 380 | _ASM_EXTABLE_UA(1b, %l[label]) \ | 380 | _ASM_EXTABLE_UA(1b, %l[label]) \ |
| 381 | : CC_OUT(z) (success), \ | 381 | : CC_OUT(z) (success), \ |
| @@ -394,7 +394,7 @@ do { \ · 12 unmodified lines | |||
| 394 | __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ | 394 | __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ |
| 395 | __typeof__(*(_ptr)) __old = *_old; \ | 395 | __typeof__(*(_ptr)) __old = *_old; \ |
| 396 | __typeof__(*(_ptr)) __new = (_new); \ | 396 | __typeof__(*(_ptr)) __new = (_new); \ |
| 397 | asm_volatile_goto("\n" \ | 397 | asm_goto_output("\n" \ |
| 398 | "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ | 398 | "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ |
| 399 | _ASM_EXTABLE_UA(1b, %l[label]) \ | 399 | _ASM_EXTABLE_UA(1b, %l[label]) \ |
| 400 | : CC_OUT(z) (success), \ | 400 | : CC_OUT(z) (success), \ |
| @@ -477,7 +477,7 @@ struct __large_struct { unsigned long buf[100]; }; · 76 unmodified lines | |||
| 477 | * aliasing issues. | 477 | * aliasing issues. |
| 478 | */ | 478 | */ |
| 479 | #define __put_user_goto(x, addr, itype, ltype, label) \ | 479 | #define __put_user_goto(x, addr, itype, ltype, label) \ |
| 480 | asm_volatile_goto("\n" \ | 480 | asm goto("\n" \ |
| 481 | "1: mov"itype" %0,%1\n" \ | 481 | "1: mov"itype" %0,%1\n" \ |
| 482 | _ASM_EXTABLE_UA(1b, %l2) \ | 482 | _ASM_EXTABLE_UA(1b, %l2) \ |
| 483 | : : ltype(x), "m" (__m(addr)) \ | 483 | : : ltype(x), "m" (__m(addr)) \ |
| @@ -403,7 +403,7 @@ noinstr void BUG_func(void) · 402 unmodified lines | |||
| 403 | { | 403 | { |
| 404 | BUG(); | 404 | BUG(); |
| 405 | } | 405 | } |
| 406 | EXPORT_SYMBOL_GPL(BUG_func); | 406 | EXPORT_SYMBOL(BUG_func); |
| 407 | 407 | ||
| 408 | #define CALL_RIP_REL_OPCODE 0xff | 408 | #define CALL_RIP_REL_OPCODE 0xff |
| 409 | #define CALL_RIP_REL_MODRM 0x15 | 409 | #define CALL_RIP_REL_MODRM 0x15 |
| @@ -538,7 +538,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) · 537 unmodified lines | |||
| 538 | 538 | ||
| 539 | /* Figure out Zen generations: */ | 539 | /* Figure out Zen generations: */ |
| 540 | switch (c->x86) { | 540 | switch (c->x86) { |
| 541 | case 0x17: { | 541 | case 0x17: |
| 542 | switch (c->x86_model) { | 542 | switch (c->x86_model) { |
| 543 | case 0x00 ... 0x2f: | 543 | case 0x00 ... 0x2f: |
| 544 | case 0x50 ... 0x5f: | 544 | case 0x50 ... 0x5f: |
| @@ -554,8 +554,8 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) · 9 unmodified lines | |||
| 554 | goto warn; | 554 | goto warn; |
| 555 | } | 555 | } |
| 556 | break; | 556 | break; |
| 557 | } | 557 | |
| 558 | case 0x19: { | 558 | case 0x19: |
| 559 | switch (c->x86_model) { | 559 | switch (c->x86_model) { |
| 560 | case 0x00 ... 0x0f: | 560 | case 0x00 ... 0x0f: |
| 561 | case 0x20 ... 0x5f: | 561 | case 0x20 ... 0x5f: |
| @@ -569,7 +569,20 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) · 7 unmodified lines | |||
| 569 | goto warn; | 569 | goto warn; |
| 570 | } | 570 | } |
| 571 | break; | 571 | break; |
| 572 | } | 572 | |
| 573 | case 0x1a: | ||
| 574 | switch (c->x86_model) { | ||
| 575 | case 0x00 ... 0x0f: | ||
| 576 | case 0x20 ... 0x2f: | ||
| 577 | case 0x40 ... 0x4f: | ||
| 578 | case 0x70 ... 0x7f: | ||
| 579 | setup_force_cpu_cap(X86_FEATURE_ZEN5); | ||
| 580 | break; | ||
| 581 | default: | ||
| 582 | goto warn; | ||
| 583 | } | ||
| 584 | break; | ||
| 585 | |||
| 573 | default: | 586 | default: |
| 574 | break; | 587 | break; |
| 575 | } | 588 | } |
| @@ -1039,6 +1052,11 @@ static void init_amd_zen4(struct cpuinfo_x86 *c) · 463 unmodified lines | |||
| 1039 | msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT); | 1052 | msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT); |
| 1040 | } | 1053 | } |
| 1041 | 1054 | ||
| 1055 | static void init_amd_zen5(struct cpuinfo_x86 *c) | ||
| 1056 | { | ||
| 1057 | init_amd_zen_common(); | ||
| 1058 | } | ||
| 1059 | |||
| 1042 | static void init_amd(struct cpuinfo_x86 *c) | 1060 | static void init_amd(struct cpuinfo_x86 *c) |
| 1043 | { | 1061 | { |
| 1044 | u64 vm_cr; | 1062 | u64 vm_cr; |
| @@ -1084,6 +1102,8 @@ static void init_amd(struct cpuinfo_x86 *c) · 39 unmodified lines | |||
| 1084 | init_amd_zen3(c); | 1102 | init_amd_zen3(c); |
| 1085 | else if (boot_cpu_has(X86_FEATURE_ZEN4)) | 1103 | else if (boot_cpu_has(X86_FEATURE_ZEN4)) |
| 1086 | init_amd_zen4(c); | 1104 | init_amd_zen4(c); |
| 1105 | else if (boot_cpu_has(X86_FEATURE_ZEN5)) | ||
| 1106 | init_amd_zen5(c); | ||
| 1087 | 1107 | ||
| 1088 | /* | 1108 | /* |
| 1089 | * Enable workaround for FXSAVE leak on CPUs | 1109 | * Enable workaround for FXSAVE leak on CPUs |
| @@ -274,12 +274,13 @@ static int __restore_fpregs_from_user(void __user *buf, u64 ufeatures, · 273 unmodified lines | |||
| 274 | * Attempt to restore the FPU registers directly from user memory. | 274 | * Attempt to restore the FPU registers directly from user memory. |
| 275 | * Pagefaults are handled and any errors returned are fatal. | 275 | * Pagefaults are handled and any errors returned are fatal. |
| 276 | */ | 276 | */ |
| 277 | static bool restore_fpregs_from_user(void __user *buf, u64 xrestore, | 277 | static bool restore_fpregs_from_user(void __user *buf, u64 xrestore, bool fx_only) |
| 278 | bool fx_only, unsigned int size) | ||
| 279 | { | 278 | { |
| 280 | struct fpu *fpu = ¤t->thread.fpu; | 279 | struct fpu *fpu = ¤t->thread.fpu; |
| 281 | int ret; | 280 | int ret; |
| 282 | 281 | ||
| 282 | /* Restore enabled features only. */ | ||
| 283 | xrestore &= fpu->fpstate->user_xfeatures; | ||
| 283 | retry: | 284 | retry: |
| 284 | fpregs_lock(); | 285 | fpregs_lock(); |
| 285 | /* Ensure that XFD is up to date */ | 286 | /* Ensure that XFD is up to date */ |
| @@ -309,7 +310,7 @@ retry: · 23 unmodified lines | |||
| 309 | if (ret != X86_TRAP_PF) | 310 | if (ret != X86_TRAP_PF) |
| 310 | return false; | 311 | return false; |
| 311 | 312 | ||
| 312 | if (!fault_in_readable(buf, size)) | 313 | if (!fault_in_readable(buf, fpu->fpstate->user_size)) |
| 313 | goto retry; | 314 | goto retry; |
| 314 | return false; | 315 | return false; |
| 315 | } | 316 | } |
| @@ -339,7 +340,6 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx, · 23 unmodified lines | |||
| 339 | struct user_i387_ia32_struct env; | 340 | struct user_i387_ia32_struct env; |
| 340 | bool success, fx_only = false; | 341 | bool success, fx_only = false; |
| 341 | union fpregs_state *fpregs; | 342 | union fpregs_state *fpregs; |
| 342 | unsigned int state_size; | ||
| 343 | u64 user_xfeatures = 0; | 343 | u64 user_xfeatures = 0; |
| 344 | 344 | ||
| 345 | if (use_xsave()) { | 345 | if (use_xsave()) { |
| @@ -349,17 +349,14 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx, · 3 unmodified lines | |||
| 349 | return false; | 349 | return false; |
| 350 | 350 | ||
| 351 | fx_only = !fx_sw_user.magic1; | 351 | fx_only = !fx_sw_user.magic1; |
| 352 | state_size = fx_sw_user.xstate_size; | ||
| 353 | user_xfeatures = fx_sw_user.xfeatures; | 352 | user_xfeatures = fx_sw_user.xfeatures; |
| 354 | } else { | 353 | } else { |
| 355 | user_xfeatures = XFEATURE_MASK_FPSSE; | 354 | user_xfeatures = XFEATURE_MASK_FPSSE; |
| 356 | state_size = fpu->fpstate->user_size; | ||
| 357 | } | 355 | } |
| 358 | 356 | ||
| 359 | if (likely(!ia32_fxstate)) { | 357 | if (likely(!ia32_fxstate)) { |
| 360 | /* Restore the FPU registers directly from user memory. */ | 358 | /* Restore the FPU registers directly from user memory. */ |
| 361 | return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only, | 359 | return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only); |
| 362 | state_size); | ||
| 363 | } | 360 | } |
| 364 | 361 | ||
| 365 | /* | 362 | /* |
| @@ -434,7 +434,8 @@ static void __init sev_map_percpu_data(void) · 433 unmodified lines | |||
| 434 | { | 434 | { |
| 435 | int cpu; | 435 | int cpu; |
| 436 | 436 | ||
| 437 | if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) | 437 | if (cc_vendor != CC_VENDOR_AMD || |
| 438 | !cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) | ||
| 438 | return; | 439 | return; |
| 439 | 440 | ||
| 440 | for_each_possible_cpu(cpu) { | 441 | for_each_possible_cpu(cpu) { |
| @@ -1322,6 +1322,56 @@ static bool hv_check_msr_access(struct kvm_vcpu_hv *hv_vcpu, u32 msr) · 1321 unmodified lines | |||
| 1322 | return false; | 1322 | return false; |
| 1323 | } | 1323 | } |
| 1324 | 1324 | ||
| 1325 | #define KVM_HV_WIN2016_GUEST_ID 0x1040a00003839 | ||
| 1326 | #define KVM_HV_WIN2016_GUEST_ID_MASK (~GENMASK_ULL(23, 16)) /* mask out the service version */ | ||
| 1327 | |||
| 1328 | /* | ||
| 1329 | * Hyper-V enabled Windows Server 2016 SMP VMs fail to boot in !XSAVES && XSAVEC | ||
| 1330 | * configuration. | ||
| 1331 | * Such configuration can result from, for example, AMD Erratum 1386 workaround. | ||
| 1332 | * | ||
| 1333 | * Print a notice so users aren't left wondering what's suddenly gone wrong. | ||
| 1334 | */ | ||
| 1335 | static void __kvm_hv_xsaves_xsavec_maybe_warn(struct kvm_vcpu *vcpu) | ||
| 1336 | { | ||
| 1337 | struct kvm *kvm = vcpu->kvm; | ||
| 1338 | struct kvm_hv *hv = to_kvm_hv(kvm); | ||
| 1339 | |||
| 1340 | /* Check again under the hv_lock. */ | ||
| 1341 | if (hv->xsaves_xsavec_checked) | ||
| 1342 | return; | ||
| 1343 | |||
| 1344 | if ((hv->hv_guest_os_id & KVM_HV_WIN2016_GUEST_ID_MASK) != | ||
| 1345 | KVM_HV_WIN2016_GUEST_ID) | ||
| 1346 | return; | ||
| 1347 | |||
| 1348 | hv->xsaves_xsavec_checked = true; | ||
| 1349 | |||
| 1350 | /* UP configurations aren't affected */ | ||
| 1351 | if (atomic_read(&kvm->online_vcpus) < 2) | ||
| 1352 | return; | ||
| 1353 | |||
| 1354 | if (guest_cpuid_has(vcpu, X86_FEATURE_XSAVES) || | ||
| 1355 | !guest_cpuid_has(vcpu, X86_FEATURE_XSAVEC)) | ||
| 1356 | return; | ||
| 1357 | |||
| 1358 | pr_notice_ratelimited("Booting SMP Windows KVM VM with !XSAVES && XSAVEC. " | ||
| 1359 | "If it fails to boot try disabling XSAVEC in the VM config.\n"); | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | void kvm_hv_xsaves_xsavec_maybe_warn(struct kvm_vcpu *vcpu) | ||
| 1363 | { | ||
| 1364 | struct kvm_hv *hv = to_kvm_hv(vcpu->kvm); | ||
| 1365 | |||
| 1366 | if (!vcpu->arch.hyperv_enabled || | ||
| 1367 | hv->xsaves_xsavec_checked) | ||
| 1368 | return; | ||
| 1369 | |||
| 1370 | mutex_lock(&hv->hv_lock); | ||
| 1371 | __kvm_hv_xsaves_xsavec_maybe_warn(vcpu); | ||
| 1372 | mutex_unlock(&hv->hv_lock); | ||
| 1373 | } | ||
| 1374 | |||
| 1325 | static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data, | 1375 | static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data, |
| 1326 | bool host) | 1376 | bool host) |
| 1327 | { | 1377 | { |
| @@ -182,6 +182,8 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm, · 181 unmodified lines | |||
| 182 | struct pvclock_vcpu_time_info *hv_clock); | 182 | struct pvclock_vcpu_time_info *hv_clock); |
| 183 | void kvm_hv_request_tsc_page_update(struct kvm *kvm); | 183 | void kvm_hv_request_tsc_page_update(struct kvm *kvm); |
| 184 | 184 | ||
| 185 | void kvm_hv_xsaves_xsavec_maybe_warn(struct kvm_vcpu *vcpu); | ||
| 186 | |||
| 185 | void kvm_hv_init_vm(struct kvm *kvm); | 187 | void kvm_hv_init_vm(struct kvm *kvm); |
| 186 | void kvm_hv_destroy_vm(struct kvm *kvm); | 188 | void kvm_hv_destroy_vm(struct kvm *kvm); |
| 187 | int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu); | 189 | int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu); |
| @@ -267,6 +269,7 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu); · 79 unmodified lines | |||
| 267 | static inline void kvm_hv_setup_tsc_page(struct kvm *kvm, | 269 | static inline void kvm_hv_setup_tsc_page(struct kvm *kvm, |
| 268 | struct pvclock_vcpu_time_info *hv_clock) {} | 270 | struct pvclock_vcpu_time_info *hv_clock) {} |
| 269 | static inline void kvm_hv_request_tsc_page_update(struct kvm *kvm) {} | 271 | static inline void kvm_hv_request_tsc_page_update(struct kvm *kvm) {} |
| 272 | static inline void kvm_hv_xsaves_xsavec_maybe_warn(struct kvm_vcpu *vcpu) {} | ||
| 270 | static inline void kvm_hv_init_vm(struct kvm *kvm) {} | 273 | static inline void kvm_hv_init_vm(struct kvm *kvm) {} |
| 271 | static inline void kvm_hv_destroy_vm(struct kvm *kvm) {} | 274 | static inline void kvm_hv_destroy_vm(struct kvm *kvm) {} |
| 272 | static inline int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu) | 275 | static inline int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu) |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | #define svm_asm(insn, clobber...) \ | 9 | #define svm_asm(insn, clobber...) \ |
| 10 | do { \ | 10 | do { \ |
| 11 | asm_volatile_goto("1: " __stringify(insn) "\n\t" \ | 11 | asm goto("1: " __stringify(insn) "\n\t" \ |
| 12 | _ASM_EXTABLE(1b, %l[fault]) \ | 12 | _ASM_EXTABLE(1b, %l[fault]) \ |
| 13 | ::: clobber : fault); \ | 13 | ::: clobber : fault); \ |
| 14 | return; \ | 14 | return; \ |
| @@ -18,7 +18,7 @@ fault: \ · 3 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define svm_asm1(insn, op1, clobber...) \ | 19 | #define svm_asm1(insn, op1, clobber...) \ |
| 20 | do { \ | 20 | do { \ |
| 21 | asm_volatile_goto("1: " __stringify(insn) " %0\n\t" \ | 21 | asm goto("1: " __stringify(insn) " %0\n\t" \ |
| 22 | _ASM_EXTABLE(1b, %l[fault]) \ | 22 | _ASM_EXTABLE(1b, %l[fault]) \ |
| 23 | :: op1 : clobber : fault); \ | 23 | :: op1 : clobber : fault); \ |
| 24 | return; \ | 24 | return; \ |
| @@ -28,7 +28,7 @@ fault: \ · 3 unmodified lines | |||
| 28 | 28 | ||
| 29 | #define svm_asm2(insn, op1, op2, clobber...) \ | 29 | #define svm_asm2(insn, op1, op2, clobber...) \ |
| 30 | do { \ | 30 | do { \ |
| 31 | asm_volatile_goto("1: " __stringify(insn) " %1, %0\n\t" \ | 31 | asm goto("1: " __stringify(insn) " %1, %0\n\t" \ |
| 32 | _ASM_EXTABLE(1b, %l[fault]) \ | 32 | _ASM_EXTABLE(1b, %l[fault]) \ |
| 33 | :: op1, op2 : clobber : fault); \ | 33 | :: op1, op2 : clobber : fault); \ |
| 34 | return; \ | 34 | return; \ |
| @@ -738,7 +738,7 @@ static int vmx_set_guest_uret_msr(struct vcpu_vmx *vmx, · 737 unmodified lines | |||
| 738 | */ | 738 | */ |
| 739 | static int kvm_cpu_vmxoff(void) | 739 | static int kvm_cpu_vmxoff(void) |
| 740 | { | 740 | { |
| 741 | asm_volatile_goto("1: vmxoff\n\t" | 741 | asm goto("1: vmxoff\n\t" |
| 742 | _ASM_EXTABLE(1b, %l[fault]) | 742 | _ASM_EXTABLE(1b, %l[fault]) |
| 743 | ::: "cc", "memory" : fault); | 743 | ::: "cc", "memory" : fault); |
| 744 | 744 | ||
| @@ -2784,7 +2784,7 @@ static int kvm_cpu_vmxon(u64 vmxon_pointer) · 2039 unmodified lines | |||
| 2784 | 2784 | ||
| 2785 | cr4_set_bits(X86_CR4_VMXE); | 2785 | cr4_set_bits(X86_CR4_VMXE); |
| 2786 | 2786 | ||
| 2787 | asm_volatile_goto("1: vmxon %[vmxon_pointer]\n\t" | 2787 | asm goto("1: vmxon %[vmxon_pointer]\n\t" |
| 2788 | _ASM_EXTABLE(1b, %l[fault]) | 2788 | _ASM_EXTABLE(1b, %l[fault]) |
| 2789 | : : [vmxon_pointer] "m"(vmxon_pointer) | 2789 | : : [vmxon_pointer] "m"(vmxon_pointer) |
| 2790 | : : fault); | 2790 | : : fault); |
| @@ -94,7 +94,7 @@ static __always_inline unsigned long __vmcs_readl(unsigned long field) · 93 unmodified lines | |||
| 94 | 94 | ||
| 95 | #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT | 95 | #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT |
| 96 | 96 | ||
| 97 | asm_volatile_goto("1: vmread %[field], %[output]\n\t" | 97 | asm_goto_output("1: vmread %[field], %[output]\n\t" |
| 98 | "jna %l[do_fail]\n\t" | 98 | "jna %l[do_fail]\n\t" |
| 99 | 99 | ||
| 100 | _ASM_EXTABLE(1b, %l[do_exception]) | 100 | _ASM_EXTABLE(1b, %l[do_exception]) |
| @@ -188,7 +188,7 @@ static __always_inline unsigned long vmcs_readl(unsigned long field) · 87 unmodified lines | |||
| 188 | 188 | ||
| 189 | #define vmx_asm1(insn, op1, error_args...) \ | 189 | #define vmx_asm1(insn, op1, error_args...) \ |
| 190 | do { \ | 190 | do { \ |
| 191 | asm_volatile_goto("1: " __stringify(insn) " %0\n\t" \ | 191 | asm goto("1: " __stringify(insn) " %0\n\t" \ |
| 192 | ".byte 0x2e\n\t" /* branch not taken hint */ \ | 192 | ".byte 0x2e\n\t" /* branch not taken hint */ \ |
| 193 | "jna %l[error]\n\t" \ | 193 | "jna %l[error]\n\t" \ |
| 194 | _ASM_EXTABLE(1b, %l[fault]) \ | 194 | _ASM_EXTABLE(1b, %l[fault]) \ |
| @@ -205,7 +205,7 @@ fault: \ · 10 unmodified lines | |||
| 205 | 205 | ||
| 206 | #define vmx_asm2(insn, op1, op2, error_args...) \ | 206 | #define vmx_asm2(insn, op1, op2, error_args...) \ |
| 207 | do { \ | 207 | do { \ |
| 208 | asm_volatile_goto("1: " __stringify(insn) " %1, %0\n\t" \ | 208 | asm goto("1: " __stringify(insn) " %1, %0\n\t" \ |
| 209 | ".byte 0x2e\n\t" /* branch not taken hint */ \ | 209 | ".byte 0x2e\n\t" /* branch not taken hint */ \ |
| 210 | "jna %l[error]\n\t" \ | 210 | "jna %l[error]\n\t" \ |
| 211 | _ASM_EXTABLE(1b, %l[fault]) \ | 211 | _ASM_EXTABLE(1b, %l[fault]) \ |
| @@ -1782,6 +1782,10 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 1781 unmodified lines | |||
| 1782 | if ((efer ^ old_efer) & KVM_MMU_EFER_ROLE_BITS) | 1782 | if ((efer ^ old_efer) & KVM_MMU_EFER_ROLE_BITS) |
| 1783 | kvm_mmu_reset_context(vcpu); | 1783 | kvm_mmu_reset_context(vcpu); |
| 1784 | 1784 | ||
| 1785 | if (!static_cpu_has(X86_FEATURE_XSAVES) && | ||
| 1786 | (efer & EFER_SVME)) | ||
| 1787 | kvm_hv_xsaves_xsavec_maybe_warn(vcpu); | ||
| 1788 | |||
| 1785 | return 0; | 1789 | return 0; |
| 1786 | } | 1790 | } |
| 1787 | 1791 | ||
| @@ -7016,6 +7020,9 @@ set_identity_unlock: · 5228 unmodified lines | |||
| 7016 | r = -EEXIST; | 7020 | r = -EEXIST; |
| 7017 | if (kvm->arch.vpit) | 7021 | if (kvm->arch.vpit) |
| 7018 | goto create_pit_unlock; | 7022 | goto create_pit_unlock; |
| 7023 | r = -ENOENT; | ||
| 7024 | if (!pic_in_kernel(kvm)) | ||
| 7025 | goto create_pit_unlock; | ||
| 7019 | r = -ENOMEM; | 7026 | r = -ENOMEM; |
| 7020 | kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags); | 7027 | kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags); |
| 7021 | if (kvm->arch.vpit) | 7028 | if (kvm->arch.vpit) |
| @@ -163,23 +163,23 @@ SYM_CODE_END(__get_user_8_handle_exception) · 162 unmodified lines | |||
| 163 | #endif | 163 | #endif |
| 164 | 164 | ||
| 165 | /* get_user */ | 165 | /* get_user */ |
| 166 | _ASM_EXTABLE(1b, __get_user_handle_exception) | 166 | _ASM_EXTABLE_UA(1b, __get_user_handle_exception) |
| 167 | _ASM_EXTABLE(2b, __get_user_handle_exception) | 167 | _ASM_EXTABLE_UA(2b, __get_user_handle_exception) |
| 168 | _ASM_EXTABLE(3b, __get_user_handle_exception) | 168 | _ASM_EXTABLE_UA(3b, __get_user_handle_exception) |
| 169 | #ifdef CONFIG_X86_64 | 169 | #ifdef CONFIG_X86_64 |
| 170 | _ASM_EXTABLE(4b, __get_user_handle_exception) | 170 | _ASM_EXTABLE_UA(4b, __get_user_handle_exception) |
| 171 | #else | 171 | #else |
| 172 | _ASM_EXTABLE(4b, __get_user_8_handle_exception) | 172 | _ASM_EXTABLE_UA(4b, __get_user_8_handle_exception) |
| 173 | _ASM_EXTABLE(5b, __get_user_8_handle_exception) | 173 | _ASM_EXTABLE_UA(5b, __get_user_8_handle_exception) |
| 174 | #endif | 174 | #endif |
| 175 | 175 | ||
| 176 | /* __get_user */ | 176 | /* __get_user */ |
| 177 | _ASM_EXTABLE(6b, __get_user_handle_exception) | 177 | _ASM_EXTABLE_UA(6b, __get_user_handle_exception) |
| 178 | _ASM_EXTABLE(7b, __get_user_handle_exception) | 178 | _ASM_EXTABLE_UA(7b, __get_user_handle_exception) |
| 179 | _ASM_EXTABLE(8b, __get_user_handle_exception) | 179 | _ASM_EXTABLE_UA(8b, __get_user_handle_exception) |
| 180 | #ifdef CONFIG_X86_64 | 180 | #ifdef CONFIG_X86_64 |
| 181 | _ASM_EXTABLE(9b, __get_user_handle_exception) | 181 | _ASM_EXTABLE_UA(9b, __get_user_handle_exception) |
| 182 | #else | 182 | #else |
| 183 | _ASM_EXTABLE(9b, __get_user_8_handle_exception) | 183 | _ASM_EXTABLE_UA(9b, __get_user_8_handle_exception) |
| 184 | _ASM_EXTABLE(10b, __get_user_8_handle_exception) | 184 | _ASM_EXTABLE_UA(10b, __get_user_8_handle_exception) |
| 185 | #endif | 185 | #endif |
| @@ -133,15 +133,15 @@ SYM_CODE_START_LOCAL(__put_user_handle_exception) · 132 unmodified lines | |||
| 133 | RET | 133 | RET |
| 134 | SYM_CODE_END(__put_user_handle_exception) | 134 | SYM_CODE_END(__put_user_handle_exception) |
| 135 | 135 | ||
| 136 | _ASM_EXTABLE(1b, __put_user_handle_exception) | 136 | _ASM_EXTABLE_UA(1b, __put_user_handle_exception) |
| 137 | _ASM_EXTABLE(2b, __put_user_handle_exception) | 137 | _ASM_EXTABLE_UA(2b, __put_user_handle_exception) |
| 138 | _ASM_EXTABLE(3b, __put_user_handle_exception) | 138 | _ASM_EXTABLE_UA(3b, __put_user_handle_exception) |
| 139 | _ASM_EXTABLE(4b, __put_user_handle_exception) | 139 | _ASM_EXTABLE_UA(4b, __put_user_handle_exception) |
| 140 | _ASM_EXTABLE(5b, __put_user_handle_exception) | 140 | _ASM_EXTABLE_UA(5b, __put_user_handle_exception) |
| 141 | _ASM_EXTABLE(6b, __put_user_handle_exception) | 141 | _ASM_EXTABLE_UA(6b, __put_user_handle_exception) |
| 142 | _ASM_EXTABLE(7b, __put_user_handle_exception) | 142 | _ASM_EXTABLE_UA(7b, __put_user_handle_exception) |
| 143 | _ASM_EXTABLE(9b, __put_user_handle_exception) | 143 | _ASM_EXTABLE_UA(9b, __put_user_handle_exception) |
| 144 | #ifdef CONFIG_X86_32 | 144 | #ifdef CONFIG_X86_32 |
| 145 | _ASM_EXTABLE(8b, __put_user_handle_exception) | 145 | _ASM_EXTABLE_UA(8b, __put_user_handle_exception) |
| 146 | _ASM_EXTABLE(10b, __put_user_handle_exception) | 146 | _ASM_EXTABLE_UA(10b, __put_user_handle_exception) |
| 147 | #endif | 147 | #endif |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | static __always_inline bool arch_static_branch(struct static_key *key, | 13 | static __always_inline bool arch_static_branch(struct static_key *key, |
| 14 | bool branch) | 14 | bool branch) |
| 15 | { | 15 | { |
| 16 | asm_volatile_goto("1:\n\t" | 16 | asm goto("1:\n\t" |
| 17 | "_nop\n\t" | 17 | "_nop\n\t" |
| 18 | ".pushsection __jump_table, \"aw\"\n\t" | 18 | ".pushsection __jump_table, \"aw\"\n\t" |
| 19 | ".word 1b, %l[l_yes], %c0\n\t" | 19 | ".word 1b, %l[l_yes], %c0\n\t" |
| @@ -38,7 +38,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, · 18 unmodified lines | |||
| 38 | * make it reachable and wrap both into a no-transform block | 38 | * make it reachable and wrap both into a no-transform block |
| 39 | * to avoid any assembler interference with this. | 39 | * to avoid any assembler interference with this. |
| 40 | */ | 40 | */ |
| 41 | asm_volatile_goto("1:\n\t" | 41 | asm goto("1:\n\t" |
| 42 | ".begin no-transform\n\t" | 42 | ".begin no-transform\n\t" |
| 43 | "_j %l[l_yes]\n\t" | 43 | "_j %l[l_yes]\n\t" |
| 44 | "2:\n\t" | 44 | "2:\n\t" |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #include "blk-pm.h" | 49 | #include "blk-pm.h" |
| 50 | #include "blk-cgroup.h" | 50 | #include "blk-cgroup.h" |
| 51 | #include "blk-throttle.h" | 51 | #include "blk-throttle.h" |
| 52 | #include "blk-ioprio.h" | ||
| 52 | 53 | ||
| 53 | struct dentry *blk_debugfs_root; | 54 | struct dentry *blk_debugfs_root; |
| 54 | 55 | ||
| @@ -833,6 +834,14 @@ end_io: · 778 unmodified lines | |||
| 833 | } | 834 | } |
| 834 | EXPORT_SYMBOL(submit_bio_noacct); | 835 | EXPORT_SYMBOL(submit_bio_noacct); |
| 835 | 836 | ||
| 837 | static void bio_set_ioprio(struct bio *bio) | ||
| 838 | { | ||
| 839 | /* Nobody set ioprio so far? Initialize it based on task's nice value */ | ||
| 840 | if (IOPRIO_PRIO_CLASS(bio->bi_ioprio) == IOPRIO_CLASS_NONE) | ||
| 841 | bio->bi_ioprio = get_current_ioprio(); | ||
| 842 | blkcg_set_ioprio(bio); | ||
| 843 | } | ||
| 844 | |||
| 836 | /** | 845 | /** |
| 837 | * submit_bio - submit a bio to the block device layer for I/O | 846 | * submit_bio - submit a bio to the block device layer for I/O |
| 838 | * @bio: The &struct bio which describes the I/O | 847 | * @bio: The &struct bio which describes the I/O |
| @@ -855,6 +864,7 @@ void submit_bio(struct bio *bio) · 16 unmodified lines | |||
| 855 | count_vm_events(PGPGOUT, bio_sectors(bio)); | 864 | count_vm_events(PGPGOUT, bio_sectors(bio)); |
| 856 | } | 865 | } |
| 857 | 866 | ||
| 867 | bio_set_ioprio(bio); | ||
| 858 | submit_bio_noacct(bio); | 868 | submit_bio_noacct(bio); |
| 859 | } | 869 | } |
| 860 | EXPORT_SYMBOL(submit_bio); | 870 | EXPORT_SYMBOL(submit_bio); |
| @@ -1353,6 +1353,13 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now) · 1352 unmodified lines | |||
| 1353 | 1353 | ||
| 1354 | lockdep_assert_held(&iocg->waitq.lock); | 1354 | lockdep_assert_held(&iocg->waitq.lock); |
| 1355 | 1355 | ||
| 1356 | /* | ||
| 1357 | * If the delay is set by another CPU, we may be in the past. No need to | ||
| 1358 | * change anything if so. This avoids decay calculation underflow. | ||
| 1359 | */ | ||
| 1360 | if (time_before64(now->now, iocg->delay_at)) | ||
| 1361 | return false; | ||
| 1362 | |||
| 1356 | /* calculate the current delay in effect - 1/2 every second */ | 1363 | /* calculate the current delay in effect - 1/2 every second */ |
| 1357 | tdelta = now->now - iocg->delay_at; | 1364 | tdelta = now->now - iocg->delay_at; |
| 1358 | if (iocg->delay) | 1365 | if (iocg->delay) |
| @@ -205,12 +205,19 @@ static int bio_copy_user_iov(struct request *rq, struct rq_map_data *map_data, · 204 unmodified lines | |||
| 205 | /* | 205 | /* |
| 206 | * success | 206 | * success |
| 207 | */ | 207 | */ |
| 208 | if ((iov_iter_rw(iter) == WRITE && | 208 | if (iov_iter_rw(iter) == WRITE && |
| 209 | (!map_data || !map_data->null_mapped)) || | 209 | (!map_data || !map_data->null_mapped)) { |
| 210 | (map_data && map_data->from_user)) { | ||
| 211 | ret = bio_copy_from_iter(bio, iter); | 210 | ret = bio_copy_from_iter(bio, iter); |
| 212 | if (ret) | 211 | if (ret) |
| 213 | goto cleanup; | 212 | goto cleanup; |
| 213 | } else if (map_data && map_data->from_user) { | ||
| 214 | struct iov_iter iter2 = *iter; | ||
| 215 | |||
| 216 | /* This is the copy-in part of SG_DXFER_TO_FROM_DEV. */ | ||
| 217 | iter2.data_source = ITER_SOURCE; | ||
| 218 | ret = bio_copy_from_iter(bio, &iter2); | ||
| 219 | if (ret) | ||
| 220 | goto cleanup; | ||
| 214 | } else { | 221 | } else { |
| 215 | if (bmd->is_our_pages) | 222 | if (bmd->is_our_pages) |
| 216 | zero_fill_bio(bio); | 223 | zero_fill_bio(bio); |
| @@ -40,7 +40,6 @@ · 39 unmodified lines | |||
| 40 | #include "blk-stat.h" | 40 | #include "blk-stat.h" |
| 41 | #include "blk-mq-sched.h" | 41 | #include "blk-mq-sched.h" |
| 42 | #include "blk-rq-qos.h" | 42 | #include "blk-rq-qos.h" |
| 43 | #include "blk-ioprio.h" | ||
| 44 | 43 | ||
| 45 | static DEFINE_PER_CPU(struct llist_head, blk_cpu_done); | 44 | static DEFINE_PER_CPU(struct llist_head, blk_cpu_done); |
| 46 | static DEFINE_PER_CPU(call_single_data_t, blk_cpu_csd); | 45 | static DEFINE_PER_CPU(call_single_data_t, blk_cpu_csd); |
| @@ -2944,14 +2943,6 @@ static bool blk_mq_use_cached_rq(struct request *rq, struct blk_plug *plug, · 2897 unmodified lines | |||
| 2944 | return true; | 2943 | return true; |
| 2945 | } | 2944 | } |
| 2946 | 2945 | ||
| 2947 | static void bio_set_ioprio(struct bio *bio) | ||
| 2948 | { | ||
| 2949 | /* Nobody set ioprio so far? Initialize it based on task's nice value */ | ||
| 2950 | if (IOPRIO_PRIO_CLASS(bio->bi_ioprio) == IOPRIO_CLASS_NONE) | ||
| 2951 | bio->bi_ioprio = get_current_ioprio(); | ||
| 2952 | blkcg_set_ioprio(bio); | ||
| 2953 | } | ||
| 2954 | |||
| 2955 | /** | 2946 | /** |
| 2956 | * blk_mq_submit_bio - Create and send a request to block device. | 2947 | * blk_mq_submit_bio - Create and send a request to block device. |
| 2957 | * @bio: Bio pointer. | 2948 | * @bio: Bio pointer. |
| @@ -2976,7 +2967,6 @@ void blk_mq_submit_bio(struct bio *bio) · 18 unmodified lines | |||
| 2976 | blk_status_t ret; | 2967 | blk_status_t ret; |
| 2977 | 2968 | ||
| 2978 | bio = blk_queue_bounce(bio, q); | 2969 | bio = blk_queue_bounce(bio, q); |
| 2979 | bio_set_ioprio(bio); | ||
| 2980 | 2970 | ||
| 2981 | if (plug) { | 2971 | if (plug) { |
| 2982 | rq = rq_list_peek(&plug->cached_rq); | 2972 | rq = rq_list_peek(&plug->cached_rq); |
| @@ -163,9 +163,9 @@ static void wb_timestamp(struct rq_wb *rwb, unsigned long *var) · 162 unmodified lines | |||
| 163 | */ | 163 | */ |
| 164 | static bool wb_recent_wait(struct rq_wb *rwb) | 164 | static bool wb_recent_wait(struct rq_wb *rwb) |
| 165 | { | 165 | { |
| 166 | struct bdi_writeback *wb = &rwb->rqos.disk->bdi->wb; | 166 | struct backing_dev_info *bdi = rwb->rqos.disk->bdi; |
| 167 | 167 | ||
| 168 | return time_before(jiffies, wb->dirty_sleep + HZ); | 168 | return time_before(jiffies, bdi->last_bdp_sleep + HZ); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static inline struct rq_wait *get_rq_wait(struct rq_wb *rwb, | 171 | static inline struct rq_wait *get_rq_wait(struct rq_wb *rwb, |
| @@ -20,8 +20,6 @@ static int blkpg_do_ioctl(struct block_device *bdev, · 19 unmodified lines | |||
| 20 | struct blkpg_partition p; | 20 | struct blkpg_partition p; |
| 21 | sector_t start, length; | 21 | sector_t start, length; |
| 22 | 22 | ||
| 23 | if (disk->flags & GENHD_FL_NO_PART) | ||
| 24 | return -EINVAL; | ||
| 25 | if (!capable(CAP_SYS_ADMIN)) | 23 | if (!capable(CAP_SYS_ADMIN)) |
| 26 | return -EACCES; | 24 | return -EACCES; |
| 27 | if (copy_from_user(&p, upart, sizeof(struct blkpg_partition))) | 25 | if (copy_from_user(&p, upart, sizeof(struct blkpg_partition))) |
| @@ -439,6 +439,11 @@ int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, · 438 unmodified lines | |||
| 439 | goto out; | 439 | goto out; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | if (disk->flags & GENHD_FL_NO_PART) { | ||
| 443 | ret = -EINVAL; | ||
| 444 | goto out; | ||
| 445 | } | ||
| 446 | |||
| 442 | if (partition_overlaps(disk, start, length, -1)) { | 447 | if (partition_overlaps(disk, start, length, -1)) { |
| 443 | ret = -EBUSY; | 448 | ret = -EBUSY; |
| 444 | goto out; | 449 | goto out; |
| @@ -91,13 +91,13 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg, · 90 unmodified lines | |||
| 91 | if (!(msg->msg_flags & MSG_MORE)) { | 91 | if (!(msg->msg_flags & MSG_MORE)) { |
| 92 | err = hash_alloc_result(sk, ctx); | 92 | err = hash_alloc_result(sk, ctx); |
| 93 | if (err) | 93 | if (err) |
| 94 | goto unlock_free; | 94 | goto unlock_free_result; |
| 95 | ahash_request_set_crypt(&ctx->req, NULL, | 95 | ahash_request_set_crypt(&ctx->req, NULL, |
| 96 | ctx->result, 0); | 96 | ctx->result, 0); |
| 97 | err = crypto_wait_req(crypto_ahash_final(&ctx->req), | 97 | err = crypto_wait_req(crypto_ahash_final(&ctx->req), |
| 98 | &ctx->wait); | 98 | &ctx->wait); |
| 99 | if (err) | 99 | if (err) |
| 100 | goto unlock_free; | 100 | goto unlock_free_result; |
| 101 | } | 101 | } |
| 102 | goto done_more; | 102 | goto done_more; |
| 103 | } | 103 | } |
| @@ -170,6 +170,7 @@ unlock: · 66 unmodified lines | |||
| 170 | 170 | ||
| 171 | unlock_free: | 171 | unlock_free: |
| 172 | af_alg_free_sg(&ctx->sgl); | 172 | af_alg_free_sg(&ctx->sgl); |
| 173 | unlock_free_result: | ||
| 173 | hash_free_result(sk, ctx); | 174 | hash_free_result(sk, ctx); |
| 174 | ctx->more = false; | 175 | ctx->more = false; |
| 175 | goto unlock; | 176 | goto unlock; |
| @@ -148,6 +148,9 @@ static int crypto_cbc_create(struct crypto_template *tmpl, struct rtattr **tb) · 147 unmodified lines | |||
| 148 | if (!is_power_of_2(inst->alg.co.base.cra_blocksize)) | 148 | if (!is_power_of_2(inst->alg.co.base.cra_blocksize)) |
| 149 | goto out_free_inst; | 149 | goto out_free_inst; |
| 150 | 150 | ||
| 151 | if (inst->alg.co.statesize) | ||
| 152 | goto out_free_inst; | ||
| 153 | |||
| 151 | inst->alg.encrypt = crypto_cbc_encrypt; | 154 | inst->alg.encrypt = crypto_cbc_encrypt; |
| 152 | inst->alg.decrypt = crypto_cbc_decrypt; | 155 | inst->alg.decrypt = crypto_cbc_decrypt; |
| 153 | 156 | ||
| @@ -102,7 +102,7 @@ static int reset_pending_show(struct seq_file *s, void *v) · 101 unmodified lines | |||
| 102 | { | 102 | { |
| 103 | struct ivpu_device *vdev = seq_to_ivpu(s); | 103 | struct ivpu_device *vdev = seq_to_ivpu(s); |
| 104 | 104 | ||
| 105 | seq_printf(s, "%d\n", atomic_read(&vdev->pm->in_reset)); | 105 | seq_printf(s, "%d\n", atomic_read(&vdev->pm->reset_pending)); |
| 106 | return 0; | 106 | return 0; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| @@ -130,7 +130,9 @@ dvfs_mode_fops_write(struct file *file, const char __user *user_buf, size_t size · 21 unmodified lines | |||
| 130 | 130 | ||
| 131 | fw->dvfs_mode = dvfs_mode; | 131 | fw->dvfs_mode = dvfs_mode; |
| 132 | 132 | ||
| 133 | ivpu_pm_schedule_recovery(vdev); | 133 | ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); |
| 134 | if (ret) | ||
| 135 | return ret; | ||
| 134 | 136 | ||
| 135 | return size; | 137 | return size; |
| 136 | } | 138 | } |
| @@ -190,7 +192,10 @@ fw_profiling_freq_fops_write(struct file *file, const char __user *user_buf, · 53 unmodified lines | |||
| 190 | return ret; | 192 | return ret; |
| 191 | 193 | ||
| 192 | ivpu_hw_profiling_freq_drive(vdev, enable); | 194 | ivpu_hw_profiling_freq_drive(vdev, enable); |
| 193 | ivpu_pm_schedule_recovery(vdev); | 195 | |
| 196 | ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); | ||
| 197 | if (ret) | ||
| 198 | return ret; | ||
| 194 | 199 | ||
| 195 | return size; | 200 | return size; |
| 196 | } | 201 | } |
| @@ -301,11 +306,18 @@ static ssize_t · 104 unmodified lines | |||
| 301 | ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) | 306 | ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) |
| 302 | { | 307 | { |
| 303 | struct ivpu_device *vdev = file->private_data; | 308 | struct ivpu_device *vdev = file->private_data; |
| 309 | int ret; | ||
| 304 | 310 | ||
| 305 | if (!size) | 311 | if (!size) |
| 306 | return -EINVAL; | 312 | return -EINVAL; |
| 307 | 313 | ||
| 308 | ivpu_pm_schedule_recovery(vdev); | 314 | ret = ivpu_rpm_get(vdev); |
| 315 | if (ret) | ||
| 316 | return ret; | ||
| 317 | |||
| 318 | ivpu_pm_trigger_recovery(vdev, "debugfs"); | ||
| 319 | flush_work(&vdev->pm->recovery_work); | ||
| 320 | ivpu_rpm_put(vdev); | ||
| 309 | return size; | 321 | return size; |
| 310 | } | 322 | } |
| 311 | 323 | ||
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/firmware.h> | 6 | #include <linux/firmware.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
| 9 | #include <linux/pm_runtime.h> | ||
| 9 | 10 | ||
| 10 | #include <drm/drm_accel.h> | 11 | #include <drm/drm_accel.h> |
| 11 | #include <drm/drm_file.h> | 12 | #include <drm/drm_file.h> |
| @@ -17,6 +18,7 @@ · 5 unmodified lines | |||
| 17 | #include "ivpu_debugfs.h" | 18 | #include "ivpu_debugfs.h" |
| 18 | #include "ivpu_drv.h" | 19 | #include "ivpu_drv.h" |
| 19 | #include "ivpu_fw.h" | 20 | #include "ivpu_fw.h" |
| 21 | #include "ivpu_fw_log.h" | ||
| 20 | #include "ivpu_gem.h" | 22 | #include "ivpu_gem.h" |
| 21 | #include "ivpu_hw.h" | 23 | #include "ivpu_hw.h" |
| 22 | #include "ivpu_ipc.h" | 24 | #include "ivpu_ipc.h" |
| @@ -65,22 +67,20 @@ struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv) · 42 unmodified lines | |||
| 65 | return file_priv; | 67 | return file_priv; |
| 66 | } | 68 | } |
| 67 | 69 | ||
| 68 | struct ivpu_file_priv *ivpu_file_priv_get_by_ctx_id(struct ivpu_device *vdev, unsigned long id) | 70 | static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv) |
| 69 | { | 71 | { |
| 70 | struct ivpu_file_priv *file_priv; | 72 | mutex_lock(&file_priv->lock); |
| 71 | 73 | if (file_priv->bound) { | |
| 72 | xa_lock_irq(&vdev->context_xa); | 74 | ivpu_dbg(vdev, FILE, "file_priv unbind: ctx %u\n", file_priv->ctx.id); |
| 73 | file_priv = xa_load(&vdev->context_xa, id); | 75 | |
| 74 | /* file_priv may still be in context_xa during file_priv_release() */ | 76 | ivpu_cmdq_release_all_locked(file_priv); |
| 75 | if (file_priv && !kref_get_unless_zero(&file_priv->ref)) | 77 | ivpu_jsm_context_release(vdev, file_priv->ctx.id); |
| 76 | file_priv = NULL; | 78 | ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx); |
| 77 | xa_unlock_irq(&vdev->context_xa); | 79 | ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); |
| 78 | 80 | file_priv->bound = false; | |
| 79 | if (file_priv) | 81 | drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id)); |
| 80 | ivpu_dbg(vdev, KREF, "file_priv get by id: ctx %u refcount %u\n", | 82 | } |
| 81 | file_priv->ctx.id, kref_read(&file_priv->ref)); | 83 | mutex_unlock(&file_priv->lock); |
| 82 | |||
| 83 | return file_priv; | ||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static void file_priv_release(struct kref *ref) | 86 | static void file_priv_release(struct kref *ref) |
| @@ -88,13 +88,15 @@ static void file_priv_release(struct kref *ref) · 1 unmodified line | |||
| 88 | struct ivpu_file_priv *file_priv = container_of(ref, struct ivpu_file_priv, ref); | 88 | struct ivpu_file_priv *file_priv = container_of(ref, struct ivpu_file_priv, ref); |
| 89 | struct ivpu_device *vdev = file_priv->vdev; | 89 | struct ivpu_device *vdev = file_priv->vdev; |
| 90 | 90 | ||
| 91 | ivpu_dbg(vdev, FILE, "file_priv release: ctx %u\n", file_priv->ctx.id); | 91 | ivpu_dbg(vdev, FILE, "file_priv release: ctx %u bound %d\n", |
| 92 | file_priv->ctx.id, (bool)file_priv->bound); | ||
| 93 | |||
| 94 | pm_runtime_get_sync(vdev->drm.dev); | ||
| 95 | mutex_lock(&vdev->context_list_lock); | ||
| 96 | file_priv_unbind(vdev, file_priv); | ||
| 97 | mutex_unlock(&vdev->context_list_lock); | ||
| 98 | pm_runtime_put_autosuspend(vdev->drm.dev); | ||
| 92 | 99 | ||
| 93 | ivpu_cmdq_release_all(file_priv); | ||
| 94 | ivpu_jsm_context_release(vdev, file_priv->ctx.id); | ||
| 95 | ivpu_bo_remove_all_bos_from_context(vdev, &file_priv->ctx); | ||
| 96 | ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); | ||
| 97 | drm_WARN_ON(&vdev->drm, xa_erase_irq(&vdev->context_xa, file_priv->ctx.id) != file_priv); | ||
| 98 | mutex_destroy(&file_priv->lock); | 100 | mutex_destroy(&file_priv->lock); |
| 99 | kfree(file_priv); | 101 | kfree(file_priv); |
| 100 | } | 102 | } |
| @@ -176,9 +178,6 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f · 75 unmodified lines | |||
| 176 | case DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS: | 178 | case DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS: |
| 177 | args->value = vdev->hw->ranges.user.start; | 179 | args->value = vdev->hw->ranges.user.start; |
| 178 | break; | 180 | break; |
| 179 | case DRM_IVPU_PARAM_CONTEXT_PRIORITY: | ||
| 180 | args->value = file_priv->priority; | ||
| 181 | break; | ||
| 182 | case DRM_IVPU_PARAM_CONTEXT_ID: | 181 | case DRM_IVPU_PARAM_CONTEXT_ID: |
| 183 | args->value = file_priv->ctx.id; | 182 | args->value = file_priv->ctx.id; |
| 184 | break; | 183 | break; |
| @@ -218,17 +217,10 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f · 33 unmodified lines | |||
| 218 | 217 | ||
| 219 | static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | 218 | static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file) |
| 220 | { | 219 | { |
| 221 | struct ivpu_file_priv *file_priv = file->driver_priv; | ||
| 222 | struct drm_ivpu_param *args = data; | 220 | struct drm_ivpu_param *args = data; |
| 223 | int ret = 0; | 221 | int ret = 0; |
| 224 | 222 | ||
| 225 | switch (args->param) { | 223 | switch (args->param) { |
| 226 | case DRM_IVPU_PARAM_CONTEXT_PRIORITY: | ||
| 227 | if (args->value <= DRM_IVPU_CONTEXT_PRIORITY_REALTIME) | ||
| 228 | file_priv->priority = args->value; | ||
| 229 | else | ||
| 230 | ret = -EINVAL; | ||
| 231 | break; | ||
| 232 | default: | 224 | default: |
| 233 | ret = -EINVAL; | 225 | ret = -EINVAL; |
| 234 | } | 226 | } |
| @@ -241,50 +233,53 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) · 6 unmodified lines | |||
| 241 | struct ivpu_device *vdev = to_ivpu_device(dev); | 233 | struct ivpu_device *vdev = to_ivpu_device(dev); |
| 242 | struct ivpu_file_priv *file_priv; | 234 | struct ivpu_file_priv *file_priv; |
| 243 | u32 ctx_id; | 235 | u32 ctx_id; |
| 244 | void *old; | 236 | int idx, ret; |
| 245 | int ret; | ||
| 246 | 237 | ||
| 247 | ret = xa_alloc_irq(&vdev->context_xa, &ctx_id, NULL, vdev->context_xa_limit, GFP_KERNEL); | 238 | if (!drm_dev_enter(dev, &idx)) |
| 248 | if (ret) { | 239 | return -ENODEV; |
| 249 | ivpu_err(vdev, "Failed to allocate context id: %d\n", ret); | ||
| 250 | return ret; | ||
| 251 | } | ||
| 252 | 240 | ||
| 253 | file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); | 241 | file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); |
| 254 | if (!file_priv) { | 242 | if (!file_priv) { |
| 255 | ret = -ENOMEM; | 243 | ret = -ENOMEM; |
| 256 | goto err_xa_erase; | 244 | goto err_dev_exit; |
| 257 | } | 245 | } |
| 258 | 246 | ||
| 259 | file_priv->vdev = vdev; | 247 | file_priv->vdev = vdev; |
| 260 | file_priv->priority = DRM_IVPU_CONTEXT_PRIORITY_NORMAL; | 248 | file_priv->bound = true; |
| 261 | kref_init(&file_priv->ref); | 249 | kref_init(&file_priv->ref); |
| 262 | mutex_init(&file_priv->lock); | 250 | mutex_init(&file_priv->lock); |
| 263 | 251 | ||
| 252 | mutex_lock(&vdev->context_list_lock); | ||
| 253 | |||
| 254 | ret = xa_alloc_irq(&vdev->context_xa, &ctx_id, file_priv, | ||
| 255 | vdev->context_xa_limit, GFP_KERNEL); | ||
| 256 | if (ret) { | ||
| 257 | ivpu_err(vdev, "Failed to allocate context id: %d\n", ret); | ||
| 258 | goto err_unlock; | ||
| 259 | } | ||
| 260 | |||
| 264 | ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); | 261 | ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); |
| 265 | if (ret) | 262 | if (ret) |
| 266 | goto err_mutex_destroy; | 263 | goto err_xa_erase; |
| 267 | 264 | ||
| 268 | old = xa_store_irq(&vdev->context_xa, ctx_id, file_priv, GFP_KERNEL); | 265 | mutex_unlock(&vdev->context_list_lock); |
| 269 | if (xa_is_err(old)) { | 266 | drm_dev_exit(idx); |
| 270 | ret = xa_err(old); | 267 | |
| 271 | ivpu_err(vdev, "Failed to store context %u: %d\n", ctx_id, ret); | 268 | file->driver_priv = file_priv; |
| 272 | goto err_ctx_fini; | ||
| 273 | } | ||
| 274 | 269 | ||
| 275 | ivpu_dbg(vdev, FILE, "file_priv create: ctx %u process %s pid %d\n", | 270 | ivpu_dbg(vdev, FILE, "file_priv create: ctx %u process %s pid %d\n", |
| 276 | ctx_id, current->comm, task_pid_nr(current)); | 271 | ctx_id, current->comm, task_pid_nr(current)); |
| 277 | 272 | ||
| 278 | file->driver_priv = file_priv; | ||
| 279 | return 0; | 273 | return 0; |
| 280 | 274 | ||
| 281 | err_ctx_fini: | ||
| 282 | ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); | ||
| 283 | err_mutex_destroy: | ||
| 284 | mutex_destroy(&file_priv->lock); | ||
| 285 | kfree(file_priv); | ||
| 286 | err_xa_erase: | 275 | err_xa_erase: |
| 287 | xa_erase_irq(&vdev->context_xa, ctx_id); | 276 | xa_erase_irq(&vdev->context_xa, ctx_id); |
| 277 | err_unlock: | ||
| 278 | mutex_unlock(&vdev->context_list_lock); | ||
| 279 | mutex_destroy(&file_priv->lock); | ||
| 280 | kfree(file_priv); | ||
| 281 | err_dev_exit: | ||
| 282 | drm_dev_exit(idx); | ||
| 288 | return ret; | 283 | return ret; |
| 289 | } | 284 | } |
| 290 | 285 | ||
| @@ -340,8 +335,6 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev) · 49 unmodified lines | |||
| 340 | 335 | ||
| 341 | if (!ret) | 336 | if (!ret) |
| 342 | ivpu_dbg(vdev, PM, "VPU ready message received successfully\n"); | 337 | ivpu_dbg(vdev, PM, "VPU ready message received successfully\n"); |
| 343 | else | ||
| 344 | ivpu_hw_diagnose_failure(vdev); | ||
| 345 | 338 | ||
| 346 | return ret; | 339 | return ret; |
| 347 | } | 340 | } |
| @@ -369,6 +362,9 @@ int ivpu_boot(struct ivpu_device *vdev) · 21 unmodified lines | |||
| 369 | ret = ivpu_wait_for_ready(vdev); | 362 | ret = ivpu_wait_for_ready(vdev); |
| 370 | if (ret) { | 363 | if (ret) { |
| 371 | ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); | 364 | ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); |
| 365 | ivpu_hw_diagnose_failure(vdev); | ||
| 366 | ivpu_mmu_evtq_dump(vdev); | ||
| 367 | ivpu_fw_log_dump(vdev); | ||
| 372 | return ret; | 368 | return ret; |
| 373 | } | 369 | } |
| 374 | 370 | ||
| @@ -484,9 +480,8 @@ static int ivpu_pci_init(struct ivpu_device *vdev) · 109 unmodified lines | |||
| 484 | /* Clear any pending errors */ | 480 | /* Clear any pending errors */ |
| 485 | pcie_capability_clear_word(pdev, PCI_EXP_DEVSTA, 0x3f); | 481 | pcie_capability_clear_word(pdev, PCI_EXP_DEVSTA, 0x3f); |
| 486 | 482 | ||
| 487 | /* VPU 37XX does not require 10m D3hot delay */ | 483 | /* NPU does not require 10m D3hot delay */ |
| 488 | if (ivpu_hw_gen(vdev) == IVPU_HW_37XX) | 484 | pdev->d3hot_delay = 0; |
| 489 | pdev->d3hot_delay = 0; | ||
| 490 | 485 | ||
| 491 | ret = pcim_enable_device(pdev); | 486 | ret = pcim_enable_device(pdev); |
| 492 | if (ret) { | 487 | if (ret) { |
| @@ -540,6 +535,10 @@ static int ivpu_dev_init(struct ivpu_device *vdev) · 47 unmodified lines | |||
| 540 | lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); | 535 | lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); |
| 541 | INIT_LIST_HEAD(&vdev->bo_list); | 536 | INIT_LIST_HEAD(&vdev->bo_list); |
| 542 | 537 | ||
| 538 | ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); | ||
| 539 | if (ret) | ||
| 540 | goto err_xa_destroy; | ||
| 541 | |||
| 543 | ret = drmm_mutex_init(&vdev->drm, &vdev->bo_list_lock); | 542 | ret = drmm_mutex_init(&vdev->drm, &vdev->bo_list_lock); |
| 544 | if (ret) | 543 | if (ret) |
| 545 | goto err_xa_destroy; | 544 | goto err_xa_destroy; |
| @@ -611,14 +610,30 @@ err_xa_destroy: · 65 unmodified lines | |||
| 611 | return ret; | 610 | return ret; |
| 612 | } | 611 | } |
| 613 | 612 | ||
| 613 | static void ivpu_bo_unbind_all_user_contexts(struct ivpu_device *vdev) | ||
| 614 | { | ||
| 615 | struct ivpu_file_priv *file_priv; | ||
| 616 | unsigned long ctx_id; | ||
| 617 | |||
| 618 | mutex_lock(&vdev->context_list_lock); | ||
| 619 | |||
| 620 | xa_for_each(&vdev->context_xa, ctx_id, file_priv) | ||
| 621 | file_priv_unbind(vdev, file_priv); | ||
| 622 | |||
| 623 | mutex_unlock(&vdev->context_list_lock); | ||
| 624 | } | ||
| 625 | |||
| 614 | static void ivpu_dev_fini(struct ivpu_device *vdev) | 626 | static void ivpu_dev_fini(struct ivpu_device *vdev) |
| 615 | { | 627 | { |
| 616 | ivpu_pm_disable(vdev); | 628 | ivpu_pm_disable(vdev); |
| 617 | ivpu_shutdown(vdev); | 629 | ivpu_shutdown(vdev); |
| 618 | if (IVPU_WA(d3hot_after_power_off)) | 630 | if (IVPU_WA(d3hot_after_power_off)) |
| 619 | pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); | 631 | pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); |
| 632 | |||
| 633 | ivpu_jobs_abort_all(vdev); | ||
| 620 | ivpu_job_done_consumer_fini(vdev); | 634 | ivpu_job_done_consumer_fini(vdev); |
| 621 | ivpu_pm_cancel_recovery(vdev); | 635 | ivpu_pm_cancel_recovery(vdev); |
| 636 | ivpu_bo_unbind_all_user_contexts(vdev); | ||
| 622 | 637 | ||
| 623 | ivpu_ipc_fini(vdev); | 638 | ivpu_ipc_fini(vdev); |
| 624 | ivpu_fw_fini(vdev); | 639 | ivpu_fw_fini(vdev); |
| @@ -56,6 +56,7 @@ · 55 unmodified lines | |||
| 56 | #define IVPU_DBG_JSM BIT(10) | 56 | #define IVPU_DBG_JSM BIT(10) |
| 57 | #define IVPU_DBG_KREF BIT(11) | 57 | #define IVPU_DBG_KREF BIT(11) |
| 58 | #define IVPU_DBG_RPM BIT(12) | 58 | #define IVPU_DBG_RPM BIT(12) |
| 59 | #define IVPU_DBG_MMU_MAP BIT(13) | ||
| 59 | 60 | ||
| 60 | #define ivpu_err(vdev, fmt, ...) \ | 61 | #define ivpu_err(vdev, fmt, ...) \ |
| 61 | drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) | 62 | drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) |
| @@ -114,6 +115,7 @@ struct ivpu_device { · 52 unmodified lines | |||
| 114 | 115 | ||
| 115 | struct ivpu_mmu_context gctx; | 116 | struct ivpu_mmu_context gctx; |
| 116 | struct ivpu_mmu_context rctx; | 117 | struct ivpu_mmu_context rctx; |
| 118 | struct mutex context_list_lock; /* Protects user context addition/removal */ | ||
| 117 | struct xarray context_xa; | 119 | struct xarray context_xa; |
| 118 | struct xa_limit context_xa_limit; | 120 | struct xa_limit context_xa_limit; |
| 119 | 121 | ||
| @@ -145,8 +147,8 @@ struct ivpu_file_priv { · 25 unmodified lines | |||
| 145 | struct mutex lock; /* Protects cmdq */ | 147 | struct mutex lock; /* Protects cmdq */ |
| 146 | struct ivpu_cmdq *cmdq[IVPU_NUM_ENGINES]; | 148 | struct ivpu_cmdq *cmdq[IVPU_NUM_ENGINES]; |
| 147 | struct ivpu_mmu_context ctx; | 149 | struct ivpu_mmu_context ctx; |
| 148 | u32 priority; | ||
| 149 | bool has_mmu_faults; | 150 | bool has_mmu_faults; |
| 151 | bool bound; | ||
| 150 | }; | 152 | }; |
| 151 | 153 | ||
| 152 | extern int ivpu_dbg_mask; | 154 | extern int ivpu_dbg_mask; |
| @@ -162,7 +164,6 @@ extern bool ivpu_disable_mmu_cont_pages; · 9 unmodified lines | |||
| 162 | extern int ivpu_test_mode; | 164 | extern int ivpu_test_mode; |
| 163 | 165 | ||
| 164 | struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); | 166 | struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); |
| 165 | struct ivpu_file_priv *ivpu_file_priv_get_by_ctx_id(struct ivpu_device *vdev, unsigned long id); | ||
| 166 | void ivpu_file_priv_put(struct ivpu_file_priv **link); | 167 | void ivpu_file_priv_put(struct ivpu_file_priv **link); |
| 167 | 168 | ||
| 168 | int ivpu_boot(struct ivpu_device *vdev); | 169 | int ivpu_boot(struct ivpu_device *vdev); |
| @@ -222,7 +222,6 @@ ivpu_fw_init_wa(struct ivpu_device *vdev) · 221 unmodified lines | |||
| 222 | const struct vpu_firmware_header *fw_hdr = (const void *)vdev->fw->file->data; | 222 | const struct vpu_firmware_header *fw_hdr = (const void *)vdev->fw->file->data; |
| 223 | 223 | ||
| 224 | if (IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, BOOT, 3, 17) || | 224 | if (IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, BOOT, 3, 17) || |
| 225 | (ivpu_hw_gen(vdev) > IVPU_HW_37XX) || | ||
| 226 | (ivpu_test_mode & IVPU_TEST_MODE_D0I3_MSG_DISABLE)) | 225 | (ivpu_test_mode & IVPU_TEST_MODE_D0I3_MSG_DISABLE)) |
| 227 | vdev->wa.disable_d0i3_msg = true; | 226 | vdev->wa.disable_d0i3_msg = true; |
| 228 | 227 | ||
| @@ -24,14 +24,11 @@ static const struct drm_gem_object_funcs ivpu_gem_funcs; · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, const char *action) | 25 | static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, const char *action) |
| 26 | { | 26 | { |
| 27 | if (bo->ctx) | 27 | ivpu_dbg(vdev, BO, |
| 28 | ivpu_dbg(vdev, BO, "%6s: size %zu has_pages %d dma_mapped %d handle %u ctx %d vpu_addr 0x%llx mmu_mapped %d\n", | 28 | "%6s: bo %8p vpu_addr %9llx size %8zu ctx %d has_pages %d dma_mapped %d mmu_mapped %d wc %d imported %d\n", |
| 29 | action, ivpu_bo_size(bo), (bool)bo->base.pages, (bool)bo->base.sgt, | 29 | action, bo, bo->vpu_addr, ivpu_bo_size(bo), bo->ctx ? bo->ctx->id : 0, |
| 30 | bo->handle, bo->ctx->id, bo->vpu_addr, bo->mmu_mapped); | 30 | (bool)bo->base.pages, (bool)bo->base.sgt, bo->mmu_mapped, bo->base.map_wc, |
| 31 | else | 31 | (bool)bo->base.base.import_attach); |
| 32 | ivpu_dbg(vdev, BO, "%6s: size %zu has_pages %d dma_mapped %d handle %u (not added to context)\n", | ||
| 33 | action, ivpu_bo_size(bo), (bool)bo->base.pages, (bool)bo->base.sgt, | ||
| 34 | bo->handle); | ||
| 35 | } | 32 | } |
| 36 | 33 | ||
| 37 | /* | 34 | /* |
| @@ -49,12 +46,7 @@ int __must_check ivpu_bo_pin(struct ivpu_bo *bo) · 11 unmodified lines | |||
| 49 | mutex_lock(&bo->lock); | 46 | mutex_lock(&bo->lock); |
| 50 | 47 | ||
| 51 | ivpu_dbg_bo(vdev, bo, "pin"); | 48 | ivpu_dbg_bo(vdev, bo, "pin"); |
| 52 | 49 | drm_WARN_ON(&vdev->drm, !bo->ctx); | |
| 53 | if (!bo->ctx) { | ||
| 54 | ivpu_err(vdev, "vpu_addr not allocated for BO %d\n", bo->handle); | ||
| 55 | ret = -EINVAL; | ||
| 56 | goto unlock; | ||
| 57 | } | ||
| 58 | 50 | ||
| 59 | if (!bo->mmu_mapped) { | 51 | if (!bo->mmu_mapped) { |
| 60 | struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(&bo->base); | 52 | struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(&bo->base); |
| @@ -85,7 +77,10 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, · 24 unmodified lines | |||
| 85 | const struct ivpu_addr_range *range) | 77 | const struct ivpu_addr_range *range) |
| 86 | { | 78 | { |
| 87 | struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); | 79 | struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); |
| 88 | int ret; | 80 | int idx, ret; |
| 81 | |||
| 82 | if (!drm_dev_enter(&vdev->drm, &idx)) | ||
| 83 | return -ENODEV; | ||
| 89 | 84 | ||
| 90 | mutex_lock(&bo->lock); | 85 | mutex_lock(&bo->lock); |
| 91 | 86 | ||
| @@ -101,6 +96,8 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, · 9 unmodified lines | |||
| 101 | 96 | ||
| 102 | mutex_unlock(&bo->lock); | 97 | mutex_unlock(&bo->lock); |
| 103 | 98 | ||
| 99 | drm_dev_exit(idx); | ||
| 100 | |||
| 104 | return ret; | 101 | return ret; |
| 105 | } | 102 | } |
| 106 | 103 | ||
| @@ -108,11 +105,7 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) · 1 unmodified line | |||
| 108 | { | 105 | { |
| 109 | struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); | 106 | struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); |
| 110 | 107 | ||
| 111 | lockdep_assert_held(&bo->lock); | 108 | lockdep_assert(lockdep_is_held(&bo->lock) || !kref_read(&bo->base.base.refcount)); |
| 112 | |||
| 113 | ivpu_dbg_bo(vdev, bo, "unbind"); | ||
| 114 | |||
| 115 | /* TODO: dma_unmap */ | ||
| 116 | 109 | ||
| 117 | if (bo->mmu_mapped) { | 110 | if (bo->mmu_mapped) { |
| 118 | drm_WARN_ON(&vdev->drm, !bo->ctx); | 111 | drm_WARN_ON(&vdev->drm, !bo->ctx); |
| @@ -124,19 +117,23 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) · 5 unmodified lines | |||
| 124 | 117 | ||
| 125 | if (bo->ctx) { | 118 | if (bo->ctx) { |
| 126 | ivpu_mmu_context_remove_node(bo->ctx, &bo->mm_node); | 119 | ivpu_mmu_context_remove_node(bo->ctx, &bo->mm_node); |
| 127 | bo->vpu_addr = 0; | ||
| 128 | bo->ctx = NULL; | 120 | bo->ctx = NULL; |
| 129 | } | 121 | } |
| 130 | } | ||
| 131 | 122 | ||
| 132 | static void ivpu_bo_unbind(struct ivpu_bo *bo) | 123 | if (bo->base.base.import_attach) |
| 133 | { | 124 | return; |
| 134 | mutex_lock(&bo->lock); | 125 | |
| 135 | ivpu_bo_unbind_locked(bo); | 126 | dma_resv_lock(bo->base.base.resv, NULL); |
| 136 | mutex_unlock(&bo->lock); | 127 | if (bo->base.sgt) { |
| 128 | dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); | ||
| 129 | sg_free_table(bo->base.sgt); | ||
| 130 | kfree(bo->base.sgt); | ||
| 131 | bo->base.sgt = NULL; | ||
| 132 | } | ||
| 133 | dma_resv_unlock(bo->base.base.resv); | ||
| 137 | } | 134 | } |
| 138 | 135 | ||
| 139 | void ivpu_bo_remove_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) | 136 | void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) |
| 140 | { | 137 | { |
| 141 | struct ivpu_bo *bo; | 138 | struct ivpu_bo *bo; |
| 142 | 139 | ||
| @@ -146,8 +143,10 @@ void ivpu_bo_remove_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_m · 3 unmodified lines | |||
| 146 | mutex_lock(&vdev->bo_list_lock); | 143 | mutex_lock(&vdev->bo_list_lock); |
| 147 | list_for_each_entry(bo, &vdev->bo_list, bo_list_node) { | 144 | list_for_each_entry(bo, &vdev->bo_list, bo_list_node) { |
| 148 | mutex_lock(&bo->lock); | 145 | mutex_lock(&bo->lock); |
| 149 | if (bo->ctx == ctx) | 146 | if (bo->ctx == ctx) { |
| 147 | ivpu_dbg_bo(vdev, bo, "unbind"); | ||
| 150 | ivpu_bo_unbind_locked(bo); | 148 | ivpu_bo_unbind_locked(bo); |
| 149 | } | ||
| 151 | mutex_unlock(&bo->lock); | 150 | mutex_unlock(&bo->lock); |
| 152 | } | 151 | } |
| 153 | mutex_unlock(&vdev->bo_list_lock); | 152 | mutex_unlock(&vdev->bo_list_lock); |
| @@ -199,9 +198,6 @@ ivpu_bo_create(struct ivpu_device *vdev, u64 size, u32 flags) · 45 unmodified lines | |||
| 199 | list_add_tail(&bo->bo_list_node, &vdev->bo_list); | 198 | list_add_tail(&bo->bo_list_node, &vdev->bo_list); |
| 200 | mutex_unlock(&vdev->bo_list_lock); | 199 | mutex_unlock(&vdev->bo_list_lock); |
| 201 | 200 | ||
| 202 | ivpu_dbg(vdev, BO, "create: vpu_addr 0x%llx size %zu flags 0x%x\n", | ||
| 203 | bo->vpu_addr, bo->base.base.size, flags); | ||
| 204 | |||
| 205 | return bo; | 201 | return bo; |
| 206 | } | 202 | } |
| 207 | 203 | ||
| @@ -212,6 +208,12 @@ static int ivpu_bo_open(struct drm_gem_object *obj, struct drm_file *file) · 4 unmodified lines | |||
| 212 | struct ivpu_bo *bo = to_ivpu_bo(obj); | 208 | struct ivpu_bo *bo = to_ivpu_bo(obj); |
| 213 | struct ivpu_addr_range *range; | 209 | struct ivpu_addr_range *range; |
| 214 | 210 | ||
| 211 | if (bo->ctx) { | ||
| 212 | ivpu_warn(vdev, "Can't add BO to ctx %u: already in ctx %u\n", | ||
| 213 | file_priv->ctx.id, bo->ctx->id); | ||
| 214 | return -EALREADY; | ||
| 215 | } | ||
| 216 | |||
| 215 | if (bo->flags & DRM_IVPU_BO_SHAVE_MEM) | 217 | if (bo->flags & DRM_IVPU_BO_SHAVE_MEM) |
| 216 | range = &vdev->hw->ranges.shave; | 218 | range = &vdev->hw->ranges.shave; |
| 217 | else if (bo->flags & DRM_IVPU_BO_DMA_MEM) | 219 | else if (bo->flags & DRM_IVPU_BO_DMA_MEM) |
| @@ -227,62 +229,24 @@ static void ivpu_bo_free(struct drm_gem_object *obj) · 9 unmodified lines | |||
| 227 | struct ivpu_device *vdev = to_ivpu_device(obj->dev); | 229 | struct ivpu_device *vdev = to_ivpu_device(obj->dev); |
| 228 | struct ivpu_bo *bo = to_ivpu_bo(obj); | 230 | struct ivpu_bo *bo = to_ivpu_bo(obj); |
| 229 | 231 | ||
| 232 | ivpu_dbg_bo(vdev, bo, "free"); | ||
| 233 | |||
| 230 | mutex_lock(&vdev->bo_list_lock); | 234 | mutex_lock(&vdev->bo_list_lock); |
| 231 | list_del(&bo->bo_list_node); | 235 | list_del(&bo->bo_list_node); |
| 232 | mutex_unlock(&vdev->bo_list_lock); | 236 | mutex_unlock(&vdev->bo_list_lock); |
| 233 | 237 | ||
| 234 | drm_WARN_ON(&vdev->drm, !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ)); | 238 | drm_WARN_ON(&vdev->drm, !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ)); |
| 235 | 239 | ||
| 236 | ivpu_dbg_bo(vdev, bo, "free"); | 240 | ivpu_bo_unbind_locked(bo); |
| 237 | |||
| 238 | ivpu_bo_unbind(bo); | ||
| 239 | mutex_destroy(&bo->lock); | 241 | mutex_destroy(&bo->lock); |
| 240 | 242 | ||
| 241 | drm_WARN_ON(obj->dev, bo->base.pages_use_count > 1); | 243 | drm_WARN_ON(obj->dev, bo->base.pages_use_count > 1); |
| 242 | drm_gem_shmem_free(&bo->base); | 244 | drm_gem_shmem_free(&bo->base); |
| 243 | } | 245 | } |
| 244 | 246 | ||
| 245 | static const struct dma_buf_ops ivpu_bo_dmabuf_ops = { | ||
| 246 | .cache_sgt_mapping = true, | ||
| 247 | .attach = drm_gem_map_attach, | ||
| 248 | .detach = drm_gem_map_detach, | ||
| 249 | .map_dma_buf = drm_gem_map_dma_buf, | ||
| 250 | .unmap_dma_buf = drm_gem_unmap_dma_buf, | ||
| 251 | .release = drm_gem_dmabuf_release, | ||
| 252 | .mmap = drm_gem_dmabuf_mmap, | ||
| 253 | .vmap = drm_gem_dmabuf_vmap, | ||
| 254 | .vunmap = drm_gem_dmabuf_vunmap, | ||
| 255 | }; | ||
| 256 | |||
| 257 | static struct dma_buf *ivpu_bo_export(struct drm_gem_object *obj, int flags) | ||
| 258 | { | ||
| 259 | struct drm_device *dev = obj->dev; | ||
| 260 | struct dma_buf_export_info exp_info = { | ||
| 261 | .exp_name = KBUILD_MODNAME, | ||
| 262 | .owner = dev->driver->fops->owner, | ||
| 263 | .ops = &ivpu_bo_dmabuf_ops, | ||
| 264 | .size = obj->size, | ||
| 265 | .flags = flags, | ||
| 266 | .priv = obj, | ||
| 267 | .resv = obj->resv, | ||
| 268 | }; | ||
| 269 | void *sgt; | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Make sure that pages are allocated and dma-mapped before exporting the bo. | ||
| 273 | * DMA-mapping is required if the bo will be imported to the same device. | ||
| 274 | */ | ||
| 275 | sgt = drm_gem_shmem_get_pages_sgt(to_drm_gem_shmem_obj(obj)); | ||
| 276 | if (IS_ERR(sgt)) | ||
| 277 | return sgt; | ||
| 278 | |||
| 279 | return drm_gem_dmabuf_export(dev, &exp_info); | ||
| 280 | } | ||
| 281 | |||
| 282 | static const struct drm_gem_object_funcs ivpu_gem_funcs = { | 247 | static const struct drm_gem_object_funcs ivpu_gem_funcs = { |
| 283 | .free = ivpu_bo_free, | 248 | .free = ivpu_bo_free, |
| 284 | .open = ivpu_bo_open, | 249 | .open = ivpu_bo_open, |
| 285 | .export = ivpu_bo_export, | ||
| 286 | .print_info = drm_gem_shmem_object_print_info, | 250 | .print_info = drm_gem_shmem_object_print_info, |
| 287 | .pin = drm_gem_shmem_object_pin, | 251 | .pin = drm_gem_shmem_object_pin, |
| 288 | .unpin = drm_gem_shmem_object_unpin, | 252 | .unpin = drm_gem_shmem_object_unpin, |
| @@ -315,11 +279,9 @@ int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fi · 26 unmodified lines | |||
| 315 | return PTR_ERR(bo); | 279 | return PTR_ERR(bo); |
| 316 | } | 280 | } |
| 317 | 281 | ||
| 318 | ret = drm_gem_handle_create(file, &bo->base.base, &bo->handle); | 282 | ret = drm_gem_handle_create(file, &bo->base.base, &args->handle); |
| 319 | if (!ret) { | 283 | if (!ret) |
| 320 | args->vpu_addr = bo->vpu_addr; | 284 | args->vpu_addr = bo->vpu_addr; |
| 321 | args->handle = bo->handle; | ||
| 322 | } | ||
| 323 | 285 | ||
| 324 | drm_gem_object_put(&bo->base.base); | 286 | drm_gem_object_put(&bo->base.base); |
| 325 | 287 | ||
| @@ -361,7 +323,9 @@ ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 fla · 35 unmodified lines | |||
| 361 | if (ret) | 323 | if (ret) |
| 362 | goto err_put; | 324 | goto err_put; |
| 363 | 325 | ||
| 326 | dma_resv_lock(bo->base.base.resv, NULL); | ||
| 364 | ret = drm_gem_shmem_vmap(&bo->base, &map); | 327 | ret = drm_gem_shmem_vmap(&bo->base, &map); |
| 328 | dma_resv_unlock(bo->base.base.resv); | ||
| 365 | if (ret) | 329 | if (ret) |
| 366 | goto err_put; | 330 | goto err_put; |
| 367 | 331 | ||
| @@ -376,7 +340,10 @@ void ivpu_bo_free_internal(struct ivpu_bo *bo) · 8 unmodified lines | |||
| 376 | { | 340 | { |
| 377 | struct iosys_map map = IOSYS_MAP_INIT_VADDR(bo->base.vaddr); | 341 | struct iosys_map map = IOSYS_MAP_INIT_VADDR(bo->base.vaddr); |
| 378 | 342 | ||
| 343 | dma_resv_lock(bo->base.base.resv, NULL); | ||
| 379 | drm_gem_shmem_vunmap(&bo->base, &map); | 344 | drm_gem_shmem_vunmap(&bo->base, &map); |
| 345 | dma_resv_unlock(bo->base.base.resv); | ||
| 346 | |||
| 380 | drm_gem_object_put(&bo->base.base); | 347 | drm_gem_object_put(&bo->base.base); |
| 381 | } | 348 | } |
| 382 | 349 | ||
| @@ -432,19 +399,11 @@ int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file · 49 unmodified lines | |||
| 432 | 399 | ||
| 433 | static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) | 400 | static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) |
| 434 | { | 401 | { |
| 435 | unsigned long dma_refcount = 0; | ||
| 436 | |||
| 437 | mutex_lock(&bo->lock); | 402 | mutex_lock(&bo->lock); |
| 438 | 403 | ||
| 439 | if (bo->base.base.dma_buf && bo->base.base.dma_buf->file) | 404 | drm_printf(p, "%-9p %-3u 0x%-12llx %-10lu 0x%-8x %-4u", |
| 440 | dma_refcount = atomic_long_read(&bo->base.base.dma_buf->file->f_count); | 405 | bo, bo->ctx->id, bo->vpu_addr, bo->base.base.size, |
| 441 | 406 | bo->flags, kref_read(&bo->base.base.refcount)); | |
| 442 | drm_printf(p, "%-3u %-6d 0x%-12llx %-10lu 0x%-8x %-4u %-8lu", | ||
| 443 | bo->ctx->id, bo->handle, bo->vpu_addr, bo->base.base.size, | ||
| 444 | bo->flags, kref_read(&bo->base.base.refcount), dma_refcount); | ||
| 445 | |||
| 446 | if (bo->base.base.import_attach) | ||
| 447 | drm_printf(p, " imported"); | ||
| 448 | 407 | ||
| 449 | if (bo->base.pages) | 408 | if (bo->base.pages) |
| 450 | drm_printf(p, " has_pages"); | 409 | drm_printf(p, " has_pages"); |
| @@ -452,6 +411,9 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) · 1 unmodified line | |||
| 452 | if (bo->mmu_mapped) | 411 | if (bo->mmu_mapped) |
| 453 | drm_printf(p, " mmu_mapped"); | 412 | drm_printf(p, " mmu_mapped"); |
| 454 | 413 | ||
| 414 | if (bo->base.base.import_attach) | ||
| 415 | drm_printf(p, " imported"); | ||
| 416 | |||
| 455 | drm_printf(p, "\n"); | 417 | drm_printf(p, "\n"); |
| 456 | 418 | ||
| 457 | mutex_unlock(&bo->lock); | 419 | mutex_unlock(&bo->lock); |
| @@ -462,8 +424,8 @@ void ivpu_bo_list(struct drm_device *dev, struct drm_printer *p) · 4 unmodified lines | |||
| 462 | struct ivpu_device *vdev = to_ivpu_device(dev); | 424 | struct ivpu_device *vdev = to_ivpu_device(dev); |
| 463 | struct ivpu_bo *bo; | 425 | struct ivpu_bo *bo; |
| 464 | 426 | ||
| 465 | drm_printf(p, "%-3s %-6s %-14s %-10s %-10s %-4s %-8s %s\n", | 427 | drm_printf(p, "%-9s %-3s %-14s %-10s %-10s %-4s %s\n", |
| 466 | "ctx", "handle", "vpu_addr", "size", "flags", "refs", "dma_refs", "attribs"); | 428 | "bo", "ctx", "vpu_addr", "size", "flags", "refs", "attribs"); |
| 467 | 429 | ||
| 468 | mutex_lock(&vdev->bo_list_lock); | 430 | mutex_lock(&vdev->bo_list_lock); |
| 469 | list_for_each_entry(bo, &vdev->bo_list, bo_list_node) | 431 | list_for_each_entry(bo, &vdev->bo_list, bo_list_node) |
| @@ -19,14 +19,13 @@ struct ivpu_bo { · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | struct mutex lock; /* Protects: ctx, mmu_mapped, vpu_addr */ | 20 | struct mutex lock; /* Protects: ctx, mmu_mapped, vpu_addr */ |
| 21 | u64 vpu_addr; | 21 | u64 vpu_addr; |
| 22 | u32 handle; | ||
| 23 | u32 flags; | 22 | u32 flags; |
| 24 | u32 job_status; /* Valid only for command buffer */ | 23 | u32 job_status; /* Valid only for command buffer */ |
| 25 | bool mmu_mapped; | 24 | bool mmu_mapped; |
| 26 | }; | 25 | }; |
| 27 | 26 | ||
| 28 | int ivpu_bo_pin(struct ivpu_bo *bo); | 27 | int ivpu_bo_pin(struct ivpu_bo *bo); |
| 29 | void ivpu_bo_remove_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); | 28 | void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); |
| 30 | 29 | ||
| 31 | struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size); | 30 | struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size); |
| 32 | struct ivpu_bo *ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 flags); | 31 | struct ivpu_bo *ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 flags); |
| @@ -525,7 +525,7 @@ static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev) · 524 unmodified lines | |||
| 525 | u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES); | 525 | u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES); |
| 526 | 526 | ||
| 527 | val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val); | 527 | val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val); |
| 528 | val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val); | 528 | val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val); |
| 529 | val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val); | 529 | val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val); |
| 530 | 530 | ||
| 531 | REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val); | 531 | REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val); |
| @@ -875,24 +875,18 @@ static void ivpu_hw_37xx_irq_disable(struct ivpu_device *vdev) · 343 unmodified lines | |||
| 875 | 875 | ||
| 876 | static void ivpu_hw_37xx_irq_wdt_nce_handler(struct ivpu_device *vdev) | 876 | static void ivpu_hw_37xx_irq_wdt_nce_handler(struct ivpu_device *vdev) |
| 877 | { | 877 | { |
| 878 | ivpu_err_ratelimited(vdev, "WDT NCE irq\n"); | 878 | ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ"); |
| 879 | |||
| 880 | ivpu_pm_schedule_recovery(vdev); | ||
| 881 | } | 879 | } |
| 882 | 880 | ||
| 883 | static void ivpu_hw_37xx_irq_wdt_mss_handler(struct ivpu_device *vdev) | 881 | static void ivpu_hw_37xx_irq_wdt_mss_handler(struct ivpu_device *vdev) |
| 884 | { | 882 | { |
| 885 | ivpu_err_ratelimited(vdev, "WDT MSS irq\n"); | ||
| 886 | |||
| 887 | ivpu_hw_wdt_disable(vdev); | 883 | ivpu_hw_wdt_disable(vdev); |
| 888 | ivpu_pm_schedule_recovery(vdev); | 884 | ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ"); |
| 889 | } | 885 | } |
| 890 | 886 | ||
| 891 | static void ivpu_hw_37xx_irq_noc_firewall_handler(struct ivpu_device *vdev) | 887 | static void ivpu_hw_37xx_irq_noc_firewall_handler(struct ivpu_device *vdev) |
| 892 | { | 888 | { |
| 893 | ivpu_err_ratelimited(vdev, "NOC Firewall irq\n"); | 889 | ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); |
| 894 | |||
| 895 | ivpu_pm_schedule_recovery(vdev); | ||
| 896 | } | 890 | } |
| 897 | 891 | ||
| 898 | /* Handler for IRQs from VPU core (irqV) */ | 892 | /* Handler for IRQs from VPU core (irqV) */ |
| @@ -970,7 +964,7 @@ static bool ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq) · 71 unmodified lines | |||
| 970 | REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, status); | 964 | REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, status); |
| 971 | 965 | ||
| 972 | if (schedule_recovery) | 966 | if (schedule_recovery) |
| 973 | ivpu_pm_schedule_recovery(vdev); | 967 | ivpu_pm_trigger_recovery(vdev, "Buttress IRQ"); |
| 974 | 968 | ||
| 975 | return true; | 969 | return true; |
| 976 | } | 970 | } |
| @@ -530,7 +530,7 @@ static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev) · 529 unmodified lines | |||
| 530 | u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES); | 530 | u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES); |
| 531 | 531 | ||
| 532 | val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val); | 532 | val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val); |
| 533 | val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val); | 533 | val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val); |
| 534 | val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val); | 534 | val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val); |
| 535 | 535 | ||
| 536 | REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val); | 536 | REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val); |
| @@ -704,7 +704,6 @@ static int ivpu_hw_40xx_info_init(struct ivpu_device *vdev) · 167 unmodified lines | |||
| 704 | { | 704 | { |
| 705 | struct ivpu_hw_info *hw = vdev->hw; | 705 | struct ivpu_hw_info *hw = vdev->hw; |
| 706 | u32 tile_disable; | 706 | u32 tile_disable; |
| 707 | u32 tile_enable; | ||
| 708 | u32 fuse; | 707 | u32 fuse; |
| 709 | 708 | ||
| 710 | fuse = REGB_RD32(VPU_40XX_BUTTRESS_TILE_FUSE); | 709 | fuse = REGB_RD32(VPU_40XX_BUTTRESS_TILE_FUSE); |
| @@ -725,10 +724,6 @@ static int ivpu_hw_40xx_info_init(struct ivpu_device *vdev) · 14 unmodified lines | |||
| 725 | else | 724 | else |
| 726 | ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", TILE_MAX_NUM); | 725 | ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", TILE_MAX_NUM); |
| 727 | 726 | ||
| 728 | tile_enable = (~tile_disable) & TILE_MAX_MASK; | ||
| 729 | |||
| 730 | hw->sku = REG_SET_FLD_NUM(SKU, HW_ID, LNL_HW_ID, hw->sku); | ||
| 731 | hw->sku = REG_SET_FLD_NUM(SKU, TILE, tile_enable, hw->sku); | ||
| 732 | hw->tile_fuse = tile_disable; | 727 | hw->tile_fuse = tile_disable; |
| 733 | hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT; | 728 | hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT; |
| 734 | 729 | ||
| @@ -746,7 +741,7 @@ static int ivpu_hw_40xx_info_init(struct ivpu_device *vdev) · 11 unmodified lines | |||
| 746 | return 0; | 741 | return 0; |
| 747 | } | 742 | } |
| 748 | 743 | ||
| 749 | static int ivpu_hw_40xx_reset(struct ivpu_device *vdev) | 744 | static int ivpu_hw_40xx_ip_reset(struct ivpu_device *vdev) |
| 750 | { | 745 | { |
| 751 | int ret; | 746 | int ret; |
| 752 | u32 val; | 747 | u32 val; |
| @@ -768,6 +763,23 @@ static int ivpu_hw_40xx_reset(struct ivpu_device *vdev) · 15 unmodified lines | |||
| 768 | return ret; | 763 | return ret; |
| 769 | } | 764 | } |
| 770 | 765 | ||
| 766 | static int ivpu_hw_40xx_reset(struct ivpu_device *vdev) | ||
| 767 | { | ||
| 768 | int ret = 0; | ||
| 769 | |||
| 770 | if (ivpu_hw_40xx_ip_reset(vdev)) { | ||
| 771 | ivpu_err(vdev, "Failed to reset VPU IP\n"); | ||
| 772 | ret = -EIO; | ||
| 773 | } | ||
| 774 | |||
| 775 | if (ivpu_pll_disable(vdev)) { | ||
| 776 | ivpu_err(vdev, "Failed to disable PLL\n"); | ||
| 777 | ret = -EIO; | ||
| 778 | } | ||
| 779 | |||
| 780 | return ret; | ||
| 781 | } | ||
| 782 | |||
| 771 | static int ivpu_hw_40xx_d0i3_enable(struct ivpu_device *vdev) | 783 | static int ivpu_hw_40xx_d0i3_enable(struct ivpu_device *vdev) |
| 772 | { | 784 | { |
| 773 | int ret; | 785 | int ret; |
| @@ -913,7 +925,7 @@ static int ivpu_hw_40xx_power_down(struct ivpu_device *vdev) · 139 unmodified lines | |||
| 913 | 925 | ||
| 914 | ivpu_hw_40xx_save_d0i3_entry_timestamp(vdev); | 926 | ivpu_hw_40xx_save_d0i3_entry_timestamp(vdev); |
| 915 | 927 | ||
| 916 | if (!ivpu_hw_40xx_is_idle(vdev) && ivpu_hw_40xx_reset(vdev)) | 928 | if (!ivpu_hw_40xx_is_idle(vdev) && ivpu_hw_40xx_ip_reset(vdev)) |
| 917 | ivpu_warn(vdev, "Failed to reset the VPU\n"); | 929 | ivpu_warn(vdev, "Failed to reset the VPU\n"); |
| 918 | 930 | ||
| 919 | if (ivpu_pll_disable(vdev)) { | 931 | if (ivpu_pll_disable(vdev)) { |
| @@ -1032,18 +1044,18 @@ static void ivpu_hw_40xx_irq_disable(struct ivpu_device *vdev) · 112 unmodified lines | |||
| 1032 | static void ivpu_hw_40xx_irq_wdt_nce_handler(struct ivpu_device *vdev) | 1044 | static void ivpu_hw_40xx_irq_wdt_nce_handler(struct ivpu_device *vdev) |
| 1033 | { | 1045 | { |
| 1034 | /* TODO: For LNN hang consider engine reset instead of full recovery */ | 1046 | /* TODO: For LNN hang consider engine reset instead of full recovery */ |
| 1035 | ivpu_pm_schedule_recovery(vdev); | 1047 | ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ"); |
| 1036 | } | 1048 | } |
| 1037 | 1049 | ||
| 1038 | static void ivpu_hw_40xx_irq_wdt_mss_handler(struct ivpu_device *vdev) | 1050 | static void ivpu_hw_40xx_irq_wdt_mss_handler(struct ivpu_device *vdev) |
| 1039 | { | 1051 | { |
| 1040 | ivpu_hw_wdt_disable(vdev); | 1052 | ivpu_hw_wdt_disable(vdev); |
| 1041 | ivpu_pm_schedule_recovery(vdev); | 1053 | ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ"); |
| 1042 | } | 1054 | } |
| 1043 | 1055 | ||
| 1044 | static void ivpu_hw_40xx_irq_noc_firewall_handler(struct ivpu_device *vdev) | 1056 | static void ivpu_hw_40xx_irq_noc_firewall_handler(struct ivpu_device *vdev) |
| 1045 | { | 1057 | { |
| 1046 | ivpu_pm_schedule_recovery(vdev); | 1058 | ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); |
| 1047 | } | 1059 | } |
| 1048 | 1060 | ||
| 1049 | /* Handler for IRQs from VPU core (irqV) */ | 1061 | /* Handler for IRQs from VPU core (irqV) */ |
| @@ -1137,7 +1149,7 @@ static bool ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq) · 87 unmodified lines | |||
| 1137 | REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status); | 1149 | REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status); |
| 1138 | 1150 | ||
| 1139 | if (schedule_recovery) | 1151 | if (schedule_recovery) |
| 1140 | ivpu_pm_schedule_recovery(vdev); | 1152 | ivpu_pm_trigger_recovery(vdev, "Buttress IRQ"); |
| 1141 | 1153 | ||
| 1142 | return true; | 1154 | return true; |
| 1143 | } | 1155 | } |
| @@ -343,10 +343,8 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r · 342 unmodified lines | |||
| 343 | hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, | 343 | hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, |
| 344 | &hb_resp, VPU_IPC_CHAN_ASYNC_CMD, | 344 | &hb_resp, VPU_IPC_CHAN_ASYNC_CMD, |
| 345 | vdev->timeout.jsm); | 345 | vdev->timeout.jsm); |
| 346 | if (hb_ret == -ETIMEDOUT) { | 346 | if (hb_ret == -ETIMEDOUT) |
| 347 | ivpu_hw_diagnose_failure(vdev); | 347 | ivpu_pm_trigger_recovery(vdev, "IPC timeout"); |
| 348 | ivpu_pm_schedule_recovery(vdev); | ||
| 349 | } | ||
| 350 | 348 | ||
| 351 | return ret; | 349 | return ret; |
| 352 | } | 350 | } |
| @@ -112,22 +112,20 @@ static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engin · 111 unmodified lines | |||
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | void ivpu_cmdq_release_all(struct ivpu_file_priv *file_priv) | 115 | void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) |
| 116 | { | 116 | { |
| 117 | int i; | 117 | int i; |
| 118 | 118 | ||
| 119 | mutex_lock(&file_priv->lock); | 119 | lockdep_assert_held(&file_priv->lock); |
| 120 | 120 | ||
| 121 | for (i = 0; i < IVPU_NUM_ENGINES; i++) | 121 | for (i = 0; i < IVPU_NUM_ENGINES; i++) |
| 122 | ivpu_cmdq_release_locked(file_priv, i); | 122 | ivpu_cmdq_release_locked(file_priv, i); |
| 123 | |||
| 124 | mutex_unlock(&file_priv->lock); | ||
| 125 | } | 123 | } |
| 126 | 124 | ||
| 127 | /* | 125 | /* |
| 128 | * Mark the doorbell as unregistered and reset job queue pointers. | 126 | * Mark the doorbell as unregistered and reset job queue pointers. |
| 129 | * This function needs to be called when the VPU hardware is restarted | 127 | * This function needs to be called when the VPU hardware is restarted |
| 130 | * and FW looses job queue state. The next time job queue is used it | 128 | * and FW loses job queue state. The next time job queue is used it |
| 131 | * will be registered again. | 129 | * will be registered again. |
| 132 | */ | 130 | */ |
| 133 | static void ivpu_cmdq_reset_locked(struct ivpu_file_priv *file_priv, u16 engine) | 131 | static void ivpu_cmdq_reset_locked(struct ivpu_file_priv *file_priv, u16 engine) |
| @@ -161,15 +159,13 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) · 27 unmodified lines | |||
| 161 | struct ivpu_file_priv *file_priv; | 159 | struct ivpu_file_priv *file_priv; |
| 162 | unsigned long ctx_id; | 160 | unsigned long ctx_id; |
| 163 | 161 | ||
| 164 | xa_for_each(&vdev->context_xa, ctx_id, file_priv) { | 162 | mutex_lock(&vdev->context_list_lock); |
| 165 | file_priv = ivpu_file_priv_get_by_ctx_id(vdev, ctx_id); | ||
| 166 | if (!file_priv) | ||
| 167 | continue; | ||
| 168 | 163 | ||
| 164 | xa_for_each(&vdev->context_xa, ctx_id, file_priv) | ||
| 169 | ivpu_cmdq_reset_all(file_priv); | 165 | ivpu_cmdq_reset_all(file_priv); |
| 170 | 166 | ||
| 171 | ivpu_file_priv_put(&file_priv); | 167 | mutex_unlock(&vdev->context_list_lock); |
| 172 | } | 168 | |
| 173 | } | 169 | } |
| 174 | 170 | ||
| 175 | static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) | 171 | static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) |
| @@ -243,60 +239,32 @@ static struct dma_fence *ivpu_fence_create(struct ivpu_device *vdev) · 67 unmodified lines | |||
| 243 | return &fence->base; | 239 | return &fence->base; |
| 244 | } | 240 | } |
| 245 | 241 | ||
| 246 | static void job_get(struct ivpu_job *job, struct ivpu_job **link) | 242 | static void ivpu_job_destroy(struct ivpu_job *job) |
| 247 | { | 243 | { |
| 248 | struct ivpu_device *vdev = job->vdev; | 244 | struct ivpu_device *vdev = job->vdev; |
| 249 | |||
| 250 | kref_get(&job->ref); | ||
| 251 | *link = job; | ||
| 252 | |||
| 253 | ivpu_dbg(vdev, KREF, "Job get: id %u refcount %u\n", job->job_id, kref_read(&job->ref)); | ||
| 254 | } | ||
| 255 | |||
| 256 | static void job_release(struct kref *ref) | ||
| 257 | { | ||
| 258 | struct ivpu_job *job = container_of(ref, struct ivpu_job, ref); | ||
| 259 | struct ivpu_device *vdev = job->vdev; | ||
| 260 | u32 i; | 245 | u32 i; |
| 261 | 246 | ||
| 247 | ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d", | ||
| 248 | job->job_id, job->file_priv->ctx.id, job->engine_idx); | ||
| 249 | |||
| 262 | for (i = 0; i < job->bo_count; i++) | 250 | for (i = 0; i < job->bo_count; i++) |
| 263 | if (job->bos[i]) | 251 | if (job->bos[i]) |
| 264 | drm_gem_object_put(&job->bos[i]->base.base); | 252 | drm_gem_object_put(&job->bos[i]->base.base); |
| 265 | 253 | ||
| 266 | dma_fence_put(job->done_fence); | 254 | dma_fence_put(job->done_fence); |
| 267 | ivpu_file_priv_put(&job->file_priv); | 255 | ivpu_file_priv_put(&job->file_priv); |
| 268 | |||
| 269 | ivpu_dbg(vdev, KREF, "Job released: id %u\n", job->job_id); | ||
| 270 | kfree(job); | 256 | kfree(job); |
| 271 | |||
| 272 | /* Allow the VPU to get suspended, must be called after ivpu_file_priv_put() */ | ||
| 273 | ivpu_rpm_put(vdev); | ||
| 274 | } | ||
| 275 | |||
| 276 | static void job_put(struct ivpu_job *job) | ||
| 277 | { | ||
| 278 | struct ivpu_device *vdev = job->vdev; | ||
| 279 | |||
| 280 | ivpu_dbg(vdev, KREF, "Job put: id %u refcount %u\n", job->job_id, kref_read(&job->ref)); | ||
| 281 | kref_put(&job->ref, job_release); | ||
| 282 | } | 257 | } |
| 283 | 258 | ||
| 284 | static struct ivpu_job * | 259 | static struct ivpu_job * |
| 285 | ivpu_create_job(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) | 260 | ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) |
| 286 | { | 261 | { |
| 287 | struct ivpu_device *vdev = file_priv->vdev; | 262 | struct ivpu_device *vdev = file_priv->vdev; |
| 288 | struct ivpu_job *job; | 263 | struct ivpu_job *job; |
| 289 | int ret; | ||
| 290 | |||
| 291 | ret = ivpu_rpm_get(vdev); | ||
| 292 | if (ret < 0) | ||
| 293 | return NULL; | ||
| 294 | 264 | ||
| 295 | job = kzalloc(struct_size(job, bos, bo_count), GFP_KERNEL); | 265 | job = kzalloc(struct_size(job, bos, bo_count), GFP_KERNEL); |
| 296 | if (!job) | 266 | if (!job) |
| 297 | goto err_rpm_put; | 267 | return NULL; |
| 298 | |||
| 299 | kref_init(&job->ref); | ||
| 300 | 268 | ||
| 301 | job->vdev = vdev; | 269 | job->vdev = vdev; |
| 302 | job->engine_idx = engine_idx; | 270 | job->engine_idx = engine_idx; |
| @@ -310,17 +278,14 @@ ivpu_create_job(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) · 7 unmodified lines | |||
| 310 | job->file_priv = ivpu_file_priv_get(file_priv); | 278 | job->file_priv = ivpu_file_priv_get(file_priv); |
| 311 | 279 | ||
| 312 | ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx); | 280 | ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx); |
| 313 | |||
| 314 | return job; | 281 | return job; |
| 315 | 282 | ||
| 316 | err_free_job: | 283 | err_free_job: |
| 317 | kfree(job); | 284 | kfree(job); |
| 318 | err_rpm_put: | ||
| 319 | ivpu_rpm_put(vdev); | ||
| 320 | return NULL; | 285 | return NULL; |
| 321 | } | 286 | } |
| 322 | 287 | ||
| 323 | static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status) | 288 | static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job_status) |
| 324 | { | 289 | { |
| 325 | struct ivpu_job *job; | 290 | struct ivpu_job *job; |
| 326 | 291 | ||
| @@ -329,7 +294,7 @@ static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status) · 2 unmodified lines | |||
| 329 | return -ENOENT; | 294 | return -ENOENT; |
| 330 | 295 | ||
| 331 | if (job->file_priv->has_mmu_faults) | 296 | if (job->file_priv->has_mmu_faults) |
| 332 | job_status = VPU_JSM_STATUS_ABORTED; | 297 | job_status = DRM_IVPU_JOB_STATUS_ABORTED; |
| 333 | 298 | ||
| 334 | job->bos[CMD_BUF_IDX]->job_status = job_status; | 299 | job->bos[CMD_BUF_IDX]->job_status = job_status; |
| 335 | dma_fence_signal(job->done_fence); | 300 | dma_fence_signal(job->done_fence); |
| @@ -337,9 +302,10 @@ static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status) · 1 unmodified line | |||
| 337 | ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", | 302 | ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", |
| 338 | job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); | 303 | job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); |
| 339 | 304 | ||
| 305 | ivpu_job_destroy(job); | ||
| 340 | ivpu_stop_job_timeout_detection(vdev); | 306 | ivpu_stop_job_timeout_detection(vdev); |
| 341 | 307 | ||
| 342 | job_put(job); | 308 | ivpu_rpm_put(vdev); |
| 343 | return 0; | 309 | return 0; |
| 344 | } | 310 | } |
| 345 | 311 | ||
| @@ -349,10 +315,10 @@ void ivpu_jobs_abort_all(struct ivpu_device *vdev) · 3 unmodified lines | |||
| 349 | unsigned long id; | 315 | unsigned long id; |
| 350 | 316 | ||
| 351 | xa_for_each(&vdev->submitted_jobs_xa, id, job) | 317 | xa_for_each(&vdev->submitted_jobs_xa, id, job) |
| 352 | ivpu_job_done(vdev, id, VPU_JSM_STATUS_ABORTED); | 318 | ivpu_job_signal_and_destroy(vdev, id, DRM_IVPU_JOB_STATUS_ABORTED); |
| 353 | } | 319 | } |
| 354 | 320 | ||
| 355 | static int ivpu_direct_job_submission(struct ivpu_job *job) | 321 | static int ivpu_job_submit(struct ivpu_job *job) |
| 356 | { | 322 | { |
| 357 | struct ivpu_file_priv *file_priv = job->file_priv; | 323 | struct ivpu_file_priv *file_priv = job->file_priv; |
| 358 | struct ivpu_device *vdev = job->vdev; | 324 | struct ivpu_device *vdev = job->vdev; |
| @@ -360,53 +326,65 @@ static int ivpu_direct_job_submission(struct ivpu_job *job) · 1 unmodified line | |||
| 360 | struct ivpu_cmdq *cmdq; | 326 | struct ivpu_cmdq *cmdq; |
| 361 | int ret; | 327 | int ret; |
| 362 | 328 | ||
| 329 | ret = ivpu_rpm_get(vdev); | ||
| 330 | if (ret < 0) | ||
| 331 | return ret; | ||
| 332 | |||
| 363 | mutex_lock(&file_priv->lock); | 333 | mutex_lock(&file_priv->lock); |
| 364 | 334 | ||
| 365 | cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx); | 335 | cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx); |
| 366 | if (!cmdq) { | 336 | if (!cmdq) { |
| 367 | ivpu_warn(vdev, "Failed get job queue, ctx %d engine %d\n", | 337 | ivpu_warn_ratelimited(vdev, "Failed get job queue, ctx %d engine %d\n", |
| 368 | file_priv->ctx.id, job->engine_idx); | 338 | file_priv->ctx.id, job->engine_idx); |
| 369 | ret = -EINVAL; | 339 | ret = -EINVAL; |
| 370 | goto err_unlock; | 340 | goto err_unlock_file_priv; |
| 371 | } | 341 | } |
| 372 | 342 | ||
| 373 | job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); | 343 | job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); |
| 374 | job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK; | 344 | job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK; |
| 375 | 345 | ||
| 376 | job_get(job, &job); | 346 | xa_lock(&vdev->submitted_jobs_xa); |
| 377 | ret = xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL); | 347 | ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL); |
| 378 | if (ret) { | 348 | if (ret) { |
| 379 | ivpu_warn_ratelimited(vdev, "Failed to allocate job id: %d\n", ret); | 349 | ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", |
| 380 | goto err_job_put; | 350 | file_priv->ctx.id); |
| 351 | ret = -EBUSY; | ||
| 352 | goto err_unlock_submitted_jobs_xa; | ||
| 381 | } | 353 | } |
| 382 | 354 | ||
| 383 | ret = ivpu_cmdq_push_job(cmdq, job); | 355 | ret = ivpu_cmdq_push_job(cmdq, job); |
| 384 | if (ret) | 356 | if (ret) |
| 385 | goto err_xa_erase; | 357 | goto err_erase_xa; |
| 386 | 358 | ||
| 387 | ivpu_start_job_timeout_detection(vdev); | 359 | ivpu_start_job_timeout_detection(vdev); |
| 388 | 360 | ||
| 389 | ivpu_dbg(vdev, JOB, "Job submitted: id %3u addr 0x%llx ctx %2d engine %d next %d\n", | 361 | if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_HW)) { |
| 390 | job->job_id, job->cmd_buf_vpu_addr, file_priv->ctx.id, | ||
| 391 | job->engine_idx, cmdq->jobq->header.tail); | ||
| 392 | |||
| 393 | if (ivpu_test_mode & IVPU_TEST_MODE_NULL_HW) { | ||
| 394 | ivpu_job_done(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS); | ||
| 395 | cmdq->jobq->header.head = cmdq->jobq->header.tail; | 362 | cmdq->jobq->header.head = cmdq->jobq->header.tail; |
| 396 | wmb(); /* Flush WC buffer for jobq header */ | 363 | wmb(); /* Flush WC buffer for jobq header */ |
| 397 | } else { | 364 | } else { |
| 398 | ivpu_cmdq_ring_db(vdev, cmdq); | 365 | ivpu_cmdq_ring_db(vdev, cmdq); |
| 399 | } | 366 | } |
| 400 | 367 | ||
| 368 | ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d addr 0x%llx next %d\n", | ||
| 369 | job->job_id, file_priv->ctx.id, job->engine_idx, | ||
| 370 | job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); | ||
| 371 | |||
| 372 | xa_unlock(&vdev->submitted_jobs_xa); | ||
| 373 | |||
| 401 | mutex_unlock(&file_priv->lock); | 374 | mutex_unlock(&file_priv->lock); |
| 375 | |||
| 376 | if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_HW)) | ||
| 377 | ivpu_job_signal_and_destroy(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS); | ||
| 378 | |||
| 402 | return 0; | 379 | return 0; |
| 403 | 380 | ||
| 404 | err_xa_erase: | 381 | err_erase_xa: |
| 405 | xa_erase(&vdev->submitted_jobs_xa, job->job_id); | 382 | __xa_erase(&vdev->submitted_jobs_xa, job->job_id); |
| 406 | err_job_put: | 383 | err_unlock_submitted_jobs_xa: |
| 407 | job_put(job); | 384 | xa_unlock(&vdev->submitted_jobs_xa); |
| 408 | err_unlock: | 385 | err_unlock_file_priv: |
| 409 | mutex_unlock(&file_priv->lock); | 386 | mutex_unlock(&file_priv->lock); |
| 387 | ivpu_rpm_put(vdev); | ||
| 410 | return ret; | 388 | return ret; |
| 411 | } | 389 | } |
| 412 | 390 | ||
| @@ -488,6 +466,9 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 75 unmodified lines | |||
| 488 | if (params->engine > DRM_IVPU_ENGINE_COPY) | 466 | if (params->engine > DRM_IVPU_ENGINE_COPY) |
| 489 | return -EINVAL; | 467 | return -EINVAL; |
| 490 | 468 | ||
| 469 | if (params->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) | ||
| 470 | return -EINVAL; | ||
| 471 | |||
| 491 | if (params->buffer_count == 0 || params->buffer_count > JOB_MAX_BUFFER_COUNT) | 472 | if (params->buffer_count == 0 || params->buffer_count > JOB_MAX_BUFFER_COUNT) |
| 492 | return -EINVAL; | 473 | return -EINVAL; |
| 493 | 474 | ||
| @@ -509,44 +490,49 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 15 unmodified lines | |||
| 509 | params->buffer_count * sizeof(u32)); | 490 | params->buffer_count * sizeof(u32)); |
| 510 | if (ret) { | 491 | if (ret) { |
| 511 | ret = -EFAULT; | 492 | ret = -EFAULT; |
| 512 | goto free_handles; | 493 | goto err_free_handles; |
| 513 | } | 494 | } |
| 514 | 495 | ||
| 515 | if (!drm_dev_enter(&vdev->drm, &idx)) { | 496 | if (!drm_dev_enter(&vdev->drm, &idx)) { |
| 516 | ret = -ENODEV; | 497 | ret = -ENODEV; |
| 517 | goto free_handles; | 498 | goto err_free_handles; |
| 518 | } | 499 | } |
| 519 | 500 | ||
| 520 | ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", | 501 | ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", |
| 521 | file_priv->ctx.id, params->buffer_count); | 502 | file_priv->ctx.id, params->buffer_count); |
| 522 | 503 | ||
| 523 | job = ivpu_create_job(file_priv, params->engine, params->buffer_count); | 504 | job = ivpu_job_create(file_priv, params->engine, params->buffer_count); |
| 524 | if (!job) { | 505 | if (!job) { |
| 525 | ivpu_err(vdev, "Failed to create job\n"); | 506 | ivpu_err(vdev, "Failed to create job\n"); |
| 526 | ret = -ENOMEM; | 507 | ret = -ENOMEM; |
| 527 | goto dev_exit; | 508 | goto err_exit_dev; |
| 528 | } | 509 | } |
| 529 | 510 | ||
| 530 | ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count, | 511 | ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count, |
| 531 | params->commands_offset); | 512 | params->commands_offset); |
| 532 | if (ret) { | 513 | if (ret) { |
| 533 | ivpu_err(vdev, "Failed to prepare job, ret %d\n", ret); | 514 | ivpu_err(vdev, "Failed to prepare job: %d\n", ret); |
| 534 | goto job_put; | 515 | goto err_destroy_job; |
| 535 | } | 516 | } |
| 536 | 517 | ||
| 537 | ret = ivpu_direct_job_submission(job); | 518 | down_read(&vdev->pm->reset_lock); |
| 538 | if (ret) { | 519 | ret = ivpu_job_submit(job); |
| 539 | dma_fence_signal(job->done_fence); | 520 | up_read(&vdev->pm->reset_lock); |
| 540 | ivpu_err(vdev, "Failed to submit job to the HW, ret %d\n", ret); | 521 | if (ret) |
| 541 | } | 522 | goto err_signal_fence; |
| 542 | 523 | ||
| 543 | job_put: | ||
| 544 | job_put(job); | ||
| 545 | dev_exit: | ||
| 546 | drm_dev_exit(idx); | 524 | drm_dev_exit(idx); |
| 547 | free_handles: | ||
| 548 | kfree(buf_handles); | 525 | kfree(buf_handles); |
| 526 | return ret; | ||
| 549 | 527 | ||
| 528 | err_signal_fence: | ||
| 529 | dma_fence_signal(job->done_fence); | ||
| 530 | err_destroy_job: | ||
| 531 | ivpu_job_destroy(job); | ||
| 532 | err_exit_dev: | ||
| 533 | drm_dev_exit(idx); | ||
| 534 | err_free_handles: | ||
| 535 | kfree(buf_handles); | ||
| 550 | return ret; | 536 | return ret; |
| 551 | } | 537 | } |
| 552 | 538 | ||
| @@ -568,7 +554,7 @@ ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr, · 15 unmodified lines | |||
| 568 | } | 554 | } |
| 569 | 555 | ||
| 570 | payload = (struct vpu_ipc_msg_payload_job_done *)&jsm_msg->payload; | 556 | payload = (struct vpu_ipc_msg_payload_job_done *)&jsm_msg->payload; |
| 571 | ret = ivpu_job_done(vdev, payload->job_id, payload->job_status); | 557 | ret = ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status); |
| 572 | if (!ret && !xa_empty(&vdev->submitted_jobs_xa)) | 558 | if (!ret && !xa_empty(&vdev->submitted_jobs_xa)) |
| 573 | ivpu_start_job_timeout_detection(vdev); | 559 | ivpu_start_job_timeout_detection(vdev); |
| 574 | } | 560 | } |
| @@ -43,7 +43,6 @@ struct ivpu_cmdq { · 42 unmodified lines | |||
| 43 | will update the job status | 43 | will update the job status |
| 44 | */ | 44 | */ |
| 45 | struct ivpu_job { | 45 | struct ivpu_job { |
| 46 | struct kref ref; | ||
| 47 | struct ivpu_device *vdev; | 46 | struct ivpu_device *vdev; |
| 48 | struct ivpu_file_priv *file_priv; | 47 | struct ivpu_file_priv *file_priv; |
| 49 | struct dma_fence *done_fence; | 48 | struct dma_fence *done_fence; |
| @@ -56,7 +55,7 @@ struct ivpu_job { · 6 unmodified lines | |||
| 56 | 55 | ||
| 57 | int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file); | 56 | int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file); |
| 58 | 57 | ||
| 59 | void ivpu_cmdq_release_all(struct ivpu_file_priv *file_priv); | 58 | void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv); |
| 60 | void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev); | 59 | void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev); |
| 61 | 60 | ||
| 62 | void ivpu_job_done_consumer_init(struct ivpu_device *vdev); | 61 | void ivpu_job_done_consumer_init(struct ivpu_device *vdev); |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | #include <linux/highmem.h> | 7 | #include <linux/highmem.h> |
| 8 | 8 | ||
| 9 | #include "ivpu_drv.h" | 9 | #include "ivpu_drv.h" |
| 10 | #include "ivpu_hw.h" | ||
| 10 | #include "ivpu_hw_reg_io.h" | 11 | #include "ivpu_hw_reg_io.h" |
| 11 | #include "ivpu_mmu.h" | 12 | #include "ivpu_mmu.h" |
| 12 | #include "ivpu_mmu_context.h" | 13 | #include "ivpu_mmu_context.h" |
| @@ -71,10 +72,10 @@ · 58 unmodified lines | |||
| 71 | 72 | ||
| 72 | #define IVPU_MMU_Q_COUNT_LOG2 4 /* 16 entries */ | 73 | #define IVPU_MMU_Q_COUNT_LOG2 4 /* 16 entries */ |
| 73 | #define IVPU_MMU_Q_COUNT ((u32)1 << IVPU_MMU_Q_COUNT_LOG2) | 74 | #define IVPU_MMU_Q_COUNT ((u32)1 << IVPU_MMU_Q_COUNT_LOG2) |
| 74 | #define IVPU_MMU_Q_WRAP_BIT (IVPU_MMU_Q_COUNT << 1) | 75 | #define IVPU_MMU_Q_WRAP_MASK GENMASK(IVPU_MMU_Q_COUNT_LOG2, 0) |
| 75 | #define IVPU_MMU_Q_WRAP_MASK (IVPU_MMU_Q_WRAP_BIT - 1) | 76 | #define IVPU_MMU_Q_IDX_MASK (IVPU_MMU_Q_COUNT - 1) |
| 76 | #define IVPU_MMU_Q_IDX_MASK (IVPU_MMU_Q_COUNT - 1) | ||
| 77 | #define IVPU_MMU_Q_IDX(val) ((val) & IVPU_MMU_Q_IDX_MASK) | 77 | #define IVPU_MMU_Q_IDX(val) ((val) & IVPU_MMU_Q_IDX_MASK) |
| 78 | #define IVPU_MMU_Q_WRP(val) ((val) & IVPU_MMU_Q_COUNT) | ||
| 78 | 79 | ||
| 79 | #define IVPU_MMU_CMDQ_CMD_SIZE 16 | 80 | #define IVPU_MMU_CMDQ_CMD_SIZE 16 |
| 80 | #define IVPU_MMU_CMDQ_SIZE (IVPU_MMU_Q_COUNT * IVPU_MMU_CMDQ_CMD_SIZE) | 81 | #define IVPU_MMU_CMDQ_SIZE (IVPU_MMU_Q_COUNT * IVPU_MMU_CMDQ_CMD_SIZE) |
| @@ -474,20 +475,32 @@ static int ivpu_mmu_cmdq_wait_for_cons(struct ivpu_device *vdev) · 393 unmodified lines | |||
| 474 | return 0; | 475 | return 0; |
| 475 | } | 476 | } |
| 476 | 477 | ||
| 478 | static bool ivpu_mmu_queue_is_full(struct ivpu_mmu_queue *q) | ||
| 479 | { | ||
| 480 | return ((IVPU_MMU_Q_IDX(q->prod) == IVPU_MMU_Q_IDX(q->cons)) && | ||
| 481 | (IVPU_MMU_Q_WRP(q->prod) != IVPU_MMU_Q_WRP(q->cons))); | ||
| 482 | } | ||
| 483 | |||
| 484 | static bool ivpu_mmu_queue_is_empty(struct ivpu_mmu_queue *q) | ||
| 485 | { | ||
| 486 | return ((IVPU_MMU_Q_IDX(q->prod) == IVPU_MMU_Q_IDX(q->cons)) && | ||
| 487 | (IVPU_MMU_Q_WRP(q->prod) == IVPU_MMU_Q_WRP(q->cons))); | ||
| 488 | } | ||
| 489 | |||
| 477 | static int ivpu_mmu_cmdq_cmd_write(struct ivpu_device *vdev, const char *name, u64 data0, u64 data1) | 490 | static int ivpu_mmu_cmdq_cmd_write(struct ivpu_device *vdev, const char *name, u64 data0, u64 data1) |
| 478 | { | 491 | { |
| 479 | struct ivpu_mmu_queue *q = &vdev->mmu->cmdq; | 492 | struct ivpu_mmu_queue *cmdq = &vdev->mmu->cmdq; |
| 480 | u64 *queue_buffer = q->base; | 493 | u64 *queue_buffer = cmdq->base; |
| 481 | int idx = IVPU_MMU_Q_IDX(q->prod) * (IVPU_MMU_CMDQ_CMD_SIZE / sizeof(*queue_buffer)); | 494 | int idx = IVPU_MMU_Q_IDX(cmdq->prod) * (IVPU_MMU_CMDQ_CMD_SIZE / sizeof(*queue_buffer)); |
| 482 | 495 | ||
| 483 | if (!CIRC_SPACE(IVPU_MMU_Q_IDX(q->prod), IVPU_MMU_Q_IDX(q->cons), IVPU_MMU_Q_COUNT)) { | 496 | if (ivpu_mmu_queue_is_full(cmdq)) { |
| 484 | ivpu_err(vdev, "Failed to write MMU CMD %s\n", name); | 497 | ivpu_err(vdev, "Failed to write MMU CMD %s\n", name); |
| 485 | return -EBUSY; | 498 | return -EBUSY; |
| 486 | } | 499 | } |
| 487 | 500 | ||
| 488 | queue_buffer[idx] = data0; | 501 | queue_buffer[idx] = data0; |
| 489 | queue_buffer[idx + 1] = data1; | 502 | queue_buffer[idx + 1] = data1; |
| 490 | q->prod = (q->prod + 1) & IVPU_MMU_Q_WRAP_MASK; | 503 | cmdq->prod = (cmdq->prod + 1) & IVPU_MMU_Q_WRAP_MASK; |
| 491 | 504 | ||
| 492 | ivpu_dbg(vdev, MMU, "CMD write: %s data: 0x%llx 0x%llx\n", name, data0, data1); | 505 | ivpu_dbg(vdev, MMU, "CMD write: %s data: 0x%llx 0x%llx\n", name, data0, data1); |
| 493 | 506 | ||
| @@ -518,6 +531,7 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev) · 24 unmodified lines | |||
| 518 | 531 | ||
| 519 | ivpu_err(vdev, "Timed out waiting for MMU consumer: %d, error: %s\n", ret, | 532 | ivpu_err(vdev, "Timed out waiting for MMU consumer: %d, error: %s\n", ret, |
| 520 | ivpu_mmu_cmdq_err_to_str(err)); | 533 | ivpu_mmu_cmdq_err_to_str(err)); |
| 534 | ivpu_hw_diagnose_failure(vdev); | ||
| 521 | } | 535 | } |
| 522 | 536 | ||
| 523 | return ret; | 537 | return ret; |
| @@ -558,7 +572,6 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev) · 34 unmodified lines | |||
| 558 | mmu->cmdq.cons = 0; | 572 | mmu->cmdq.cons = 0; |
| 559 | 573 | ||
| 560 | memset(mmu->evtq.base, 0, IVPU_MMU_EVTQ_SIZE); | 574 | memset(mmu->evtq.base, 0, IVPU_MMU_EVTQ_SIZE); |
| 561 | clflush_cache_range(mmu->evtq.base, IVPU_MMU_EVTQ_SIZE); | ||
| 562 | mmu->evtq.prod = 0; | 575 | mmu->evtq.prod = 0; |
| 563 | mmu->evtq.cons = 0; | 576 | mmu->evtq.cons = 0; |
| 564 | 577 | ||
| @@ -872,20 +885,15 @@ static u32 *ivpu_mmu_get_event(struct ivpu_device *vdev) · 307 unmodified lines | |||
| 872 | u32 *evt = evtq->base + (idx * IVPU_MMU_EVTQ_CMD_SIZE); | 885 | u32 *evt = evtq->base + (idx * IVPU_MMU_EVTQ_CMD_SIZE); |
| 873 | 886 | ||
| 874 | evtq->prod = REGV_RD32(IVPU_MMU_REG_EVTQ_PROD_SEC); | 887 | evtq->prod = REGV_RD32(IVPU_MMU_REG_EVTQ_PROD_SEC); |
| 875 | if (!CIRC_CNT(IVPU_MMU_Q_IDX(evtq->prod), IVPU_MMU_Q_IDX(evtq->cons), IVPU_MMU_Q_COUNT)) | 888 | if (ivpu_mmu_queue_is_empty(evtq)) |
| 876 | return NULL; | 889 | return NULL; |
| 877 | 890 | ||
| 878 | clflush_cache_range(evt, IVPU_MMU_EVTQ_CMD_SIZE); | ||
| 879 | |||
| 880 | evtq->cons = (evtq->cons + 1) & IVPU_MMU_Q_WRAP_MASK; | 891 | evtq->cons = (evtq->cons + 1) & IVPU_MMU_Q_WRAP_MASK; |
| 881 | REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, evtq->cons); | ||
| 882 | |||
| 883 | return evt; | 892 | return evt; |
| 884 | } | 893 | } |
| 885 | 894 | ||
| 886 | void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) | 895 | void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) |
| 887 | { | 896 | { |
| 888 | bool schedule_recovery = false; | ||
| 889 | u32 *event; | 897 | u32 *event; |
| 890 | u32 ssid; | 898 | u32 ssid; |
| 891 | 899 | ||
| @@ -895,14 +903,22 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) · 3 unmodified lines | |||
| 895 | ivpu_mmu_dump_event(vdev, event); | 903 | ivpu_mmu_dump_event(vdev, event); |
| 896 | 904 | ||
| 897 | ssid = FIELD_GET(IVPU_MMU_EVT_SSID_MASK, event[0]); | 905 | ssid = FIELD_GET(IVPU_MMU_EVT_SSID_MASK, event[0]); |
| 898 | if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) | 906 | if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) { |
| 899 | schedule_recovery = true; | 907 | ivpu_pm_trigger_recovery(vdev, "MMU event"); |
| 900 | else | 908 | return; |
| 901 | ivpu_mmu_user_context_mark_invalid(vdev, ssid); | 909 | } |
| 910 | |||
| 911 | ivpu_mmu_user_context_mark_invalid(vdev, ssid); | ||
| 912 | REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons); | ||
| 902 | } | 913 | } |
| 914 | } | ||
| 903 | 915 | ||
| 904 | if (schedule_recovery) | 916 | void ivpu_mmu_evtq_dump(struct ivpu_device *vdev) |
| 905 | ivpu_pm_schedule_recovery(vdev); | 917 | { |
| 918 | u32 *event; | ||
| 919 | |||
| 920 | while ((event = ivpu_mmu_get_event(vdev)) != NULL) | ||
| 921 | ivpu_mmu_dump_event(vdev, event); | ||
| 906 | } | 922 | } |
| 907 | 923 | ||
| 908 | void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev) | 924 | void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev) |
| @@ -46,5 +46,6 @@ int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid); · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev); | 47 | void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev); |
| 48 | void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev); | 48 | void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev); |
| 49 | void ivpu_mmu_evtq_dump(struct ivpu_device *vdev); | ||
| 49 | 50 | ||
| 50 | #endif /* __IVPU_MMU_H__ */ | 51 | #endif /* __IVPU_MMU_H__ */ |
| @@ -355,6 +355,9 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, · 354 unmodified lines | |||
| 355 | dma_addr_t dma_addr = sg_dma_address(sg) - sg->offset; | 355 | dma_addr_t dma_addr = sg_dma_address(sg) - sg->offset; |
| 356 | size_t size = sg_dma_len(sg) + sg->offset; | 356 | size_t size = sg_dma_len(sg) + sg->offset; |
| 357 | 357 | ||
| 358 | ivpu_dbg(vdev, MMU_MAP, "Map ctx: %u dma_addr: 0x%llx vpu_addr: 0x%llx size: %lu\n", | ||
| 359 | ctx->id, dma_addr, vpu_addr, size); | ||
| 360 | |||
| 358 | ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); | 361 | ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); |
| 359 | if (ret) { | 362 | if (ret) { |
| 360 | ivpu_err(vdev, "Failed to map context pages\n"); | 363 | ivpu_err(vdev, "Failed to map context pages\n"); |
| @@ -366,6 +369,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, · 5 unmodified lines | |||
| 366 | 369 | ||
| 367 | /* Ensure page table modifications are flushed from wc buffers to memory */ | 370 | /* Ensure page table modifications are flushed from wc buffers to memory */ |
| 368 | wmb(); | 371 | wmb(); |
| 372 | |||
| 369 | mutex_unlock(&ctx->lock); | 373 | mutex_unlock(&ctx->lock); |
| 370 | 374 | ||
| 371 | ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); | 375 | ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); |
| @@ -388,14 +392,19 @@ ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ct · 16 unmodified lines | |||
| 388 | mutex_lock(&ctx->lock); | 392 | mutex_lock(&ctx->lock); |
| 389 | 393 | ||
| 390 | for_each_sgtable_dma_sg(sgt, sg, i) { | 394 | for_each_sgtable_dma_sg(sgt, sg, i) { |
| 395 | dma_addr_t dma_addr = sg_dma_address(sg) - sg->offset; | ||
| 391 | size_t size = sg_dma_len(sg) + sg->offset; | 396 | size_t size = sg_dma_len(sg) + sg->offset; |
| 392 | 397 | ||
| 398 | ivpu_dbg(vdev, MMU_MAP, "Unmap ctx: %u dma_addr: 0x%llx vpu_addr: 0x%llx size: %lu\n", | ||
| 399 | ctx->id, dma_addr, vpu_addr, size); | ||
| 400 | |||
| 393 | ivpu_mmu_context_unmap_pages(ctx, vpu_addr, size); | 401 | ivpu_mmu_context_unmap_pages(ctx, vpu_addr, size); |
| 394 | vpu_addr += size; | 402 | vpu_addr += size; |
| 395 | } | 403 | } |
| 396 | 404 | ||
| 397 | /* Ensure page table modifications are flushed from wc buffers to memory */ | 405 | /* Ensure page table modifications are flushed from wc buffers to memory */ |
| 398 | wmb(); | 406 | wmb(); |
| 407 | |||
| 399 | mutex_unlock(&ctx->lock); | 408 | mutex_unlock(&ctx->lock); |
| 400 | 409 | ||
| 401 | ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); | 410 | ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include "ivpu_drv.h" | 13 | #include "ivpu_drv.h" |
| 14 | #include "ivpu_hw.h" | 14 | #include "ivpu_hw.h" |
| 15 | #include "ivpu_fw.h" | 15 | #include "ivpu_fw.h" |
| 16 | #include "ivpu_fw_log.h" | ||
| 16 | #include "ivpu_ipc.h" | 17 | #include "ivpu_ipc.h" |
| 17 | #include "ivpu_job.h" | 18 | #include "ivpu_job.h" |
| 18 | #include "ivpu_jsm_msg.h" | 19 | #include "ivpu_jsm_msg.h" |
| @@ -111,6 +112,14 @@ static void ivpu_pm_recovery_work(struct work_struct *work) · 92 unmodified lines | |||
| 111 | char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL}; | 112 | char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL}; |
| 112 | int ret; | 113 | int ret; |
| 113 | 114 | ||
| 115 | ivpu_err(vdev, "Recovering the VPU (reset #%d)\n", atomic_read(&vdev->pm->reset_counter)); | ||
| 116 | |||
| 117 | ret = pm_runtime_resume_and_get(vdev->drm.dev); | ||
| 118 | if (ret) | ||
| 119 | ivpu_err(vdev, "Failed to resume VPU: %d\n", ret); | ||
| 120 | |||
| 121 | ivpu_fw_log_dump(vdev); | ||
| 122 | |||
| 114 | retry: | 123 | retry: |
| 115 | ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); | 124 | ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); |
| 116 | if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) { | 125 | if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) { |
| @@ -122,11 +131,13 @@ retry: · 5 unmodified lines | |||
| 122 | ivpu_err(vdev, "Failed to reset VPU: %d\n", ret); | 131 | ivpu_err(vdev, "Failed to reset VPU: %d\n", ret); |
| 123 | 132 | ||
| 124 | kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt); | 133 | kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt); |
| 134 | pm_runtime_mark_last_busy(vdev->drm.dev); | ||
| 135 | pm_runtime_put_autosuspend(vdev->drm.dev); | ||
| 125 | } | 136 | } |
| 126 | 137 | ||
| 127 | void ivpu_pm_schedule_recovery(struct ivpu_device *vdev) | 138 | void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason) |
| 128 | { | 139 | { |
| 129 | struct ivpu_pm_info *pm = vdev->pm; | 140 | ivpu_err(vdev, "Recovery triggered by %s\n", reason); |
| 130 | 141 | ||
| 131 | if (ivpu_disable_recovery) { | 142 | if (ivpu_disable_recovery) { |
| 132 | ivpu_err(vdev, "Recovery not available when disable_recovery param is set\n"); | 143 | ivpu_err(vdev, "Recovery not available when disable_recovery param is set\n"); |
| @@ -138,10 +149,11 @@ void ivpu_pm_schedule_recovery(struct ivpu_device *vdev) · 5 unmodified lines | |||
| 138 | return; | 149 | return; |
| 139 | } | 150 | } |
| 140 | 151 | ||
| 141 | /* Schedule recovery if it's not in progress */ | 152 | /* Trigger recovery if it's not in progress */ |
| 142 | if (atomic_cmpxchg(&pm->in_reset, 0, 1) == 0) { | 153 | if (atomic_cmpxchg(&vdev->pm->reset_pending, 0, 1) == 0) { |
| 143 | ivpu_hw_irq_disable(vdev); | 154 | ivpu_hw_diagnose_failure(vdev); |
| 144 | queue_work(system_long_wq, &pm->recovery_work); | 155 | ivpu_hw_irq_disable(vdev); /* Disable IRQ early to protect from IRQ storm */ |
| 156 | queue_work(system_long_wq, &vdev->pm->recovery_work); | ||
| 145 | } | 157 | } |
| 146 | } | 158 | } |
| 147 | 159 | ||
| @@ -149,12 +161,8 @@ static void ivpu_job_timeout_work(struct work_struct *work) · 1 unmodified line | |||
| 149 | { | 161 | { |
| 150 | struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, job_timeout_work.work); | 162 | struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, job_timeout_work.work); |
| 151 | struct ivpu_device *vdev = pm->vdev; | 163 | struct ivpu_device *vdev = pm->vdev; |
| 152 | unsigned long timeout_ms = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr; | ||
| 153 | 164 | ||
| 154 | ivpu_err(vdev, "TDR detected, timeout %lu ms", timeout_ms); | 165 | ivpu_pm_trigger_recovery(vdev, "TDR"); |
| 155 | ivpu_hw_diagnose_failure(vdev); | ||
| 156 | |||
| 157 | ivpu_pm_schedule_recovery(vdev); | ||
| 158 | } | 166 | } |
| 159 | 167 | ||
| 160 | void ivpu_start_job_timeout_detection(struct ivpu_device *vdev) | 168 | void ivpu_start_job_timeout_detection(struct ivpu_device *vdev) |
| @@ -227,6 +235,9 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) · 66 unmodified lines | |||
| 227 | bool hw_is_idle = true; | 235 | bool hw_is_idle = true; |
| 228 | int ret; | 236 | int ret; |
| 229 | 237 | ||
| 238 | drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa)); | ||
| 239 | drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work)); | ||
| 240 | |||
| 230 | ivpu_dbg(vdev, PM, "Runtime suspend..\n"); | 241 | ivpu_dbg(vdev, PM, "Runtime suspend..\n"); |
| 231 | 242 | ||
| 232 | if (!ivpu_hw_is_idle(vdev) && vdev->pm->suspend_reschedule_counter) { | 243 | if (!ivpu_hw_is_idle(vdev) && vdev->pm->suspend_reschedule_counter) { |
| @@ -247,7 +258,8 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) · 14 unmodified lines | |||
| 247 | ivpu_err(vdev, "Failed to set suspend VPU: %d\n", ret); | 258 | ivpu_err(vdev, "Failed to set suspend VPU: %d\n", ret); |
| 248 | 259 | ||
| 249 | if (!hw_is_idle) { | 260 | if (!hw_is_idle) { |
| 250 | ivpu_warn(vdev, "VPU failed to enter idle, force suspended.\n"); | 261 | ivpu_err(vdev, "VPU failed to enter idle, force suspended.\n"); |
| 262 | ivpu_fw_log_dump(vdev); | ||
| 251 | ivpu_pm_prepare_cold_boot(vdev); | 263 | ivpu_pm_prepare_cold_boot(vdev); |
| 252 | } else { | 264 | } else { |
| 253 | ivpu_pm_prepare_warm_boot(vdev); | 265 | ivpu_pm_prepare_warm_boot(vdev); |
| @@ -308,11 +320,12 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev) · 54 unmodified lines | |||
| 308 | { | 320 | { |
| 309 | struct ivpu_device *vdev = pci_get_drvdata(pdev); | 321 | struct ivpu_device *vdev = pci_get_drvdata(pdev); |
| 310 | 322 | ||
| 311 | pm_runtime_get_sync(vdev->drm.dev); | ||
| 312 | |||
| 313 | ivpu_dbg(vdev, PM, "Pre-reset..\n"); | 323 | ivpu_dbg(vdev, PM, "Pre-reset..\n"); |
| 314 | atomic_inc(&vdev->pm->reset_counter); | 324 | atomic_inc(&vdev->pm->reset_counter); |
| 315 | atomic_set(&vdev->pm->in_reset, 1); | 325 | atomic_set(&vdev->pm->reset_pending, 1); |
| 326 | |||
| 327 | pm_runtime_get_sync(vdev->drm.dev); | ||
| 328 | down_write(&vdev->pm->reset_lock); | ||
| 316 | ivpu_prepare_for_reset(vdev); | 329 | ivpu_prepare_for_reset(vdev); |
| 317 | ivpu_hw_reset(vdev); | 330 | ivpu_hw_reset(vdev); |
| 318 | ivpu_pm_prepare_cold_boot(vdev); | 331 | ivpu_pm_prepare_cold_boot(vdev); |
| @@ -329,9 +342,11 @@ void ivpu_pm_reset_done_cb(struct pci_dev *pdev) · 10 unmodified lines | |||
| 329 | ret = ivpu_resume(vdev); | 342 | ret = ivpu_resume(vdev); |
| 330 | if (ret) | 343 | if (ret) |
| 331 | ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret); | 344 | ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret); |
| 332 | atomic_set(&vdev->pm->in_reset, 0); | 345 | up_write(&vdev->pm->reset_lock); |
| 346 | atomic_set(&vdev->pm->reset_pending, 0); | ||
| 333 | ivpu_dbg(vdev, PM, "Post-reset done.\n"); | 347 | ivpu_dbg(vdev, PM, "Post-reset done.\n"); |
| 334 | 348 | ||
| 349 | pm_runtime_mark_last_busy(vdev->drm.dev); | ||
| 335 | pm_runtime_put_autosuspend(vdev->drm.dev); | 350 | pm_runtime_put_autosuspend(vdev->drm.dev); |
| 336 | } | 351 | } |
| 337 | 352 | ||
| @@ -344,7 +359,10 @@ void ivpu_pm_init(struct ivpu_device *vdev) · 6 unmodified lines | |||
| 344 | pm->vdev = vdev; | 359 | pm->vdev = vdev; |
| 345 | pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT; | 360 | pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT; |
| 346 | 361 | ||
| 347 | atomic_set(&pm->in_reset, 0); | 362 | init_rwsem(&pm->reset_lock); |
| 363 | atomic_set(&pm->reset_pending, 0); | ||
| 364 | atomic_set(&pm->reset_counter, 0); | ||
| 365 | |||
| 348 | INIT_WORK(&pm->recovery_work, ivpu_pm_recovery_work); | 366 | INIT_WORK(&pm->recovery_work, ivpu_pm_recovery_work); |
| 349 | INIT_DELAYED_WORK(&pm->job_timeout_work, ivpu_job_timeout_work); | 367 | INIT_DELAYED_WORK(&pm->job_timeout_work, ivpu_job_timeout_work); |
| 350 | 368 | ||
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #ifndef __IVPU_PM_H__ | 6 | #ifndef __IVPU_PM_H__ |
| 7 | #define __IVPU_PM_H__ | 7 | #define __IVPU_PM_H__ |
| 8 | 8 | ||
| 9 | #include <linux/rwsem.h> | ||
| 9 | #include <linux/types.h> | 10 | #include <linux/types.h> |
| 10 | 11 | ||
| 11 | struct ivpu_device; | 12 | struct ivpu_device; |
| @@ -14,8 +15,9 @@ struct ivpu_pm_info { · 2 unmodified lines | |||
| 14 | struct ivpu_device *vdev; | 15 | struct ivpu_device *vdev; |
| 15 | struct delayed_work job_timeout_work; | 16 | struct delayed_work job_timeout_work; |
| 16 | struct work_struct recovery_work; | 17 | struct work_struct recovery_work; |
| 17 | atomic_t in_reset; | 18 | struct rw_semaphore reset_lock; |
| 18 | atomic_t reset_counter; | 19 | atomic_t reset_counter; |
| 20 | atomic_t reset_pending; | ||
| 19 | bool is_warmboot; | 21 | bool is_warmboot; |
| 20 | u32 suspend_reschedule_counter; | 22 | u32 suspend_reschedule_counter; |
| 21 | }; | 23 | }; |
| @@ -37,7 +39,7 @@ int __must_check ivpu_rpm_get(struct ivpu_device *vdev); · 15 unmodified lines | |||
| 37 | int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev); | 39 | int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev); |
| 38 | void ivpu_rpm_put(struct ivpu_device *vdev); | 40 | void ivpu_rpm_put(struct ivpu_device *vdev); |
| 39 | 41 | ||
| 40 | void ivpu_pm_schedule_recovery(struct ivpu_device *vdev); | 42 | void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason); |
| 41 | void ivpu_start_job_timeout_detection(struct ivpu_device *vdev); | 43 | void ivpu_start_job_timeout_detection(struct ivpu_device *vdev); |
| 42 | void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev); | 44 | void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev); |
| 43 | 45 | ||
| @@ -680,32 +680,6 @@ static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata, · 679 unmodified lines | |||
| 680 | static DECLARE_RWSEM(cxl_cper_rw_sem); | 680 | static DECLARE_RWSEM(cxl_cper_rw_sem); |
| 681 | static cxl_cper_callback cper_callback; | 681 | static cxl_cper_callback cper_callback; |
| 682 | 682 | ||
| 683 | /* CXL Event record UUIDs are formatted as GUIDs and reported in section type */ | ||
| 684 | |||
| 685 | /* | ||
| 686 | * General Media Event Record | ||
| 687 | * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 | ||
| 688 | */ | ||
| 689 | #define CPER_SEC_CXL_GEN_MEDIA_GUID \ | ||
| 690 | GUID_INIT(0xfbcd0a77, 0xc260, 0x417f, \ | ||
| 691 | 0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6) | ||
| 692 | |||
| 693 | /* | ||
| 694 | * DRAM Event Record | ||
| 695 | * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44 | ||
| 696 | */ | ||
| 697 | #define CPER_SEC_CXL_DRAM_GUID \ | ||
| 698 | GUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, \ | ||
| 699 | 0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24) | ||
| 700 | |||
| 701 | /* | ||
| 702 | * Memory Module Event Record | ||
| 703 | * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45 | ||
| 704 | */ | ||
| 705 | #define CPER_SEC_CXL_MEM_MODULE_GUID \ | ||
| 706 | GUID_INIT(0xfe927475, 0xdd59, 0x4339, \ | ||
| 707 | 0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74) | ||
| 708 | |||
| 709 | static void cxl_cper_post_event(enum cxl_event_type event_type, | 683 | static void cxl_cper_post_event(enum cxl_event_type event_type, |
| 710 | struct cxl_cper_event_rec *rec) | 684 | struct cxl_cper_event_rec *rec) |
| 711 | { | 685 | { |
| @@ -478,6 +478,16 @@ binder_enqueue_thread_work_ilocked(struct binder_thread *thread, · 477 unmodified lines | |||
| 478 | { | 478 | { |
| 479 | WARN_ON(!list_empty(&thread->waiting_thread_node)); | 479 | WARN_ON(!list_empty(&thread->waiting_thread_node)); |
| 480 | binder_enqueue_work_ilocked(work, &thread->todo); | 480 | binder_enqueue_work_ilocked(work, &thread->todo); |
| 481 | |||
| 482 | /* (e)poll-based threads require an explicit wakeup signal when | ||
| 483 | * queuing their own work; they rely on these events to consume | ||
| 484 | * messages without I/O block. Without it, threads risk waiting | ||
| 485 | * indefinitely without handling the work. | ||
| 486 | */ | ||
| 487 | if (thread->looper & BINDER_LOOPER_STATE_POLL && | ||
| 488 | thread->pid == current->pid && !thread->process_todo) | ||
| 489 | wake_up_interruptible_sync(&thread->wait); | ||
| 490 | |||
| 481 | thread->process_todo = true; | 491 | thread->process_todo = true; |
| 482 | } | 492 | } |
| 483 | 493 | ||
| @@ -48,6 +48,7 @@ enum { · 47 unmodified lines | |||
| 48 | enum board_ids { | 48 | enum board_ids { |
| 49 | /* board IDs by feature in alphabetical order */ | 49 | /* board IDs by feature in alphabetical order */ |
| 50 | board_ahci, | 50 | board_ahci, |
| 51 | board_ahci_43bit_dma, | ||
| 51 | board_ahci_ign_iferr, | 52 | board_ahci_ign_iferr, |
| 52 | board_ahci_low_power, | 53 | board_ahci_low_power, |
| 53 | board_ahci_no_debounce_delay, | 54 | board_ahci_no_debounce_delay, |
| @@ -128,6 +129,13 @@ static const struct ata_port_info ahci_port_info[] = { · 74 unmodified lines | |||
| 128 | .udma_mask = ATA_UDMA6, | 129 | .udma_mask = ATA_UDMA6, |
| 129 | .port_ops = &ahci_ops, | 130 | .port_ops = &ahci_ops, |
| 130 | }, | 131 | }, |
| 132 | [board_ahci_43bit_dma] = { | ||
| 133 | AHCI_HFLAGS (AHCI_HFLAG_43BIT_ONLY), | ||
| 134 | .flags = AHCI_FLAG_COMMON, | ||
| 135 | .pio_mask = ATA_PIO4, | ||
| 136 | .udma_mask = ATA_UDMA6, | ||
| 137 | .port_ops = &ahci_ops, | ||
| 138 | }, | ||
| 131 | [board_ahci_ign_iferr] = { | 139 | [board_ahci_ign_iferr] = { |
| 132 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), | 140 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), |
| 133 | .flags = AHCI_FLAG_COMMON, | 141 | .flags = AHCI_FLAG_COMMON, |
| @@ -597,14 +605,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { · 463 unmodified lines | |||
| 597 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 605 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
| 598 | { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */ | 606 | { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */ |
| 599 | 607 | ||
| 600 | /* Asmedia */ | 608 | /* ASMedia */ |
| 601 | { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ | 609 | { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci_43bit_dma }, /* ASM1060 */ |
| 602 | { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ | 610 | { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci_43bit_dma }, /* ASM1060 */ |
| 603 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ | 611 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci_43bit_dma }, /* ASM1061 */ |
| 604 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | 612 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci_43bit_dma }, /* ASM1061/1062 */ |
| 605 | { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */ | 613 | { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci_43bit_dma }, /* ASM1061R */ |
| 606 | { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */ | 614 | { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci_43bit_dma }, /* ASM1062R */ |
| 607 | { PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci }, /* ASM1062+JMB575 */ | 615 | { PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci_43bit_dma }, /* ASM1062+JMB575 */ |
| 608 | { PCI_VDEVICE(ASMEDIA, 0x1062), board_ahci }, /* ASM1062A */ | 616 | { PCI_VDEVICE(ASMEDIA, 0x1062), board_ahci }, /* ASM1062A */ |
| 609 | { PCI_VDEVICE(ASMEDIA, 0x1064), board_ahci }, /* ASM1064 */ | 617 | { PCI_VDEVICE(ASMEDIA, 0x1064), board_ahci }, /* ASM1064 */ |
| 610 | { PCI_VDEVICE(ASMEDIA, 0x1164), board_ahci }, /* ASM1164 */ | 618 | { PCI_VDEVICE(ASMEDIA, 0x1164), board_ahci }, /* ASM1164 */ |
| @@ -663,6 +671,11 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets"); · 52 unmodified lines | |||
| 663 | static void ahci_pci_save_initial_config(struct pci_dev *pdev, | 671 | static void ahci_pci_save_initial_config(struct pci_dev *pdev, |
| 664 | struct ahci_host_priv *hpriv) | 672 | struct ahci_host_priv *hpriv) |
| 665 | { | 673 | { |
| 674 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) { | ||
| 675 | dev_info(&pdev->dev, "ASM1166 has only six ports\n"); | ||
| 676 | hpriv->saved_port_map = 0x3f; | ||
| 677 | } | ||
| 678 | |||
| 666 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { | 679 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { |
| 667 | dev_info(&pdev->dev, "JMB361 has only one port\n"); | 680 | dev_info(&pdev->dev, "JMB361 has only one port\n"); |
| 668 | hpriv->saved_port_map = 1; | 681 | hpriv->saved_port_map = 1; |
| @@ -949,11 +962,20 @@ static int ahci_pci_device_resume(struct device *dev) · 280 unmodified lines | |||
| 949 | 962 | ||
| 950 | #endif /* CONFIG_PM */ | 963 | #endif /* CONFIG_PM */ |
| 951 | 964 | ||
| 952 | static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) | 965 | static int ahci_configure_dma_masks(struct pci_dev *pdev, |
| 966 | struct ahci_host_priv *hpriv) | ||
| 953 | { | 967 | { |
| 954 | const int dma_bits = using_dac ? 64 : 32; | 968 | int dma_bits; |
| 955 | int rc; | 969 | int rc; |
| 956 | 970 | ||
| 971 | if (hpriv->cap & HOST_CAP_64) { | ||
| 972 | dma_bits = 64; | ||
| 973 | if (hpriv->flags & AHCI_HFLAG_43BIT_ONLY) | ||
| 974 | dma_bits = 43; | ||
| 975 | } else { | ||
| 976 | dma_bits = 32; | ||
| 977 | } | ||
| 978 | |||
| 957 | /* | 979 | /* |
| 958 | * If the device fixup already set the dma_mask to some non-standard | 980 | * If the device fixup already set the dma_mask to some non-standard |
| 959 | * value, don't extend it here. This happens on STA2X11, for example. | 981 | * value, don't extend it here. This happens on STA2X11, for example. |
| @@ -1926,7 +1948,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 966 unmodified lines | |||
| 1926 | ahci_gtf_filter_workaround(host); | 1948 | ahci_gtf_filter_workaround(host); |
| 1927 | 1949 | ||
| 1928 | /* initialize adapter */ | 1950 | /* initialize adapter */ |
| 1929 | rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); | 1951 | rc = ahci_configure_dma_masks(pdev, hpriv); |
| 1930 | if (rc) | 1952 | if (rc) |
| 1931 | return rc; | 1953 | return rc; |
| 1932 | 1954 | ||
| @@ -247,6 +247,7 @@ enum { · 246 unmodified lines | |||
| 247 | AHCI_HFLAG_SUSPEND_PHYS = BIT(26), /* handle PHYs during | 247 | AHCI_HFLAG_SUSPEND_PHYS = BIT(26), /* handle PHYs during |
| 248 | suspend/resume */ | 248 | suspend/resume */ |
| 249 | AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */ | 249 | AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */ |
| 250 | AHCI_HFLAG_43BIT_ONLY = BIT(29), /* 43bit DMA addr limit */ | ||
| 250 | 251 | ||
| 251 | /* ap->flags bits */ | 252 | /* ap->flags bits */ |
| 252 | 253 | ||
| @@ -784,7 +784,7 @@ bool sata_lpm_ignore_phy_events(struct ata_link *link) · 783 unmodified lines | |||
| 784 | EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); | 784 | EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); |
| 785 | 785 | ||
| 786 | static const char *ata_lpm_policy_names[] = { | 786 | static const char *ata_lpm_policy_names[] = { |
| 787 | [ATA_LPM_UNKNOWN] = "max_performance", | 787 | [ATA_LPM_UNKNOWN] = "keep_firmware_settings", |
| 788 | [ATA_LPM_MAX_POWER] = "max_performance", | 788 | [ATA_LPM_MAX_POWER] = "max_performance", |
| 789 | [ATA_LPM_MED_POWER] = "medium_power", | 789 | [ATA_LPM_MED_POWER] = "medium_power", |
| 790 | [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", | 790 | [ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm", |
| @@ -2930,6 +2930,8 @@ open_card_ubr0(struct idt77252_dev *card) · 2929 unmodified lines | |||
| 2930 | vc->scq = alloc_scq(card, vc->class); | 2930 | vc->scq = alloc_scq(card, vc->class); |
| 2931 | if (!vc->scq) { | 2931 | if (!vc->scq) { |
| 2932 | printk("%s: can't get SCQ.\n", card->name); | 2932 | printk("%s: can't get SCQ.\n", card->name); |
| 2933 | kfree(card->vcs[0]); | ||
| 2934 | card->vcs[0] = NULL; | ||
| 2933 | return -ENOMEM; | 2935 | return -ENOMEM; |
| 2934 | } | 2936 | } |
| 2935 | 2937 | ||
| @@ -333,6 +333,7 @@ aoeblk_gdalloc(void *vp) · 332 unmodified lines | |||
| 333 | struct gendisk *gd; | 333 | struct gendisk *gd; |
| 334 | mempool_t *mp; | 334 | mempool_t *mp; |
| 335 | struct blk_mq_tag_set *set; | 335 | struct blk_mq_tag_set *set; |
| 336 | sector_t ssize; | ||
| 336 | ulong flags; | 337 | ulong flags; |
| 337 | int late = 0; | 338 | int late = 0; |
| 338 | int err; | 339 | int err; |
| @@ -396,7 +397,7 @@ aoeblk_gdalloc(void *vp) · 57 unmodified lines | |||
| 396 | gd->minors = AOE_PARTITIONS; | 397 | gd->minors = AOE_PARTITIONS; |
| 397 | gd->fops = &aoe_bdops; | 398 | gd->fops = &aoe_bdops; |
| 398 | gd->private_data = d; | 399 | gd->private_data = d; |
| 399 | set_capacity(gd, d->ssize); | 400 | ssize = d->ssize; |
| 400 | snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", | 401 | snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", |
| 401 | d->aoemajor, d->aoeminor); | 402 | d->aoemajor, d->aoeminor); |
| 402 | 403 | ||
| @@ -405,6 +406,8 @@ aoeblk_gdalloc(void *vp) · 2 unmodified lines | |||
| 405 | 406 | ||
| 406 | spin_unlock_irqrestore(&d->lock, flags); | 407 | spin_unlock_irqrestore(&d->lock, flags); |
| 407 | 408 | ||
| 409 | set_capacity(gd, ssize); | ||
| 410 | |||
| 408 | err = device_add_disk(NULL, gd, aoe_attr_groups); | 411 | err = device_add_disk(NULL, gd, aoe_attr_groups); |
| 409 | if (err) | 412 | if (err) |
| 410 | goto out_disk_cleanup; | 413 | goto out_disk_cleanup; |
| @@ -3452,14 +3452,15 @@ static bool rbd_lock_add_request(struct rbd_img_request *img_req) · 3451 unmodified lines | |||
| 3452 | static void rbd_lock_del_request(struct rbd_img_request *img_req) | 3452 | static void rbd_lock_del_request(struct rbd_img_request *img_req) |
| 3453 | { | 3453 | { |
| 3454 | struct rbd_device *rbd_dev = img_req->rbd_dev; | 3454 | struct rbd_device *rbd_dev = img_req->rbd_dev; |
| 3455 | bool need_wakeup; | 3455 | bool need_wakeup = false; |
| 3456 | 3456 | ||
| 3457 | lockdep_assert_held(&rbd_dev->lock_rwsem); | 3457 | lockdep_assert_held(&rbd_dev->lock_rwsem); |
| 3458 | spin_lock(&rbd_dev->lock_lists_lock); | 3458 | spin_lock(&rbd_dev->lock_lists_lock); |
| 3459 | rbd_assert(!list_empty(&img_req->lock_item)); | 3459 | if (!list_empty(&img_req->lock_item)) { |
| 3460 | list_del_init(&img_req->lock_item); | 3460 | list_del_init(&img_req->lock_item); |
| 3461 | need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && | 3461 | need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && |
| 3462 | list_empty(&rbd_dev->running_list)); | 3462 | list_empty(&rbd_dev->running_list)); |
| 3463 | } | ||
| 3463 | spin_unlock(&rbd_dev->lock_lists_lock); | 3464 | spin_unlock(&rbd_dev->lock_lists_lock); |
| 3464 | if (need_wakeup) | 3465 | if (need_wakeup) |
| 3465 | complete(&rbd_dev->releasing_wait); | 3466 | complete(&rbd_dev->releasing_wait); |
| @@ -3842,14 +3843,19 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) · 376 unmodified lines | |||
| 3842 | return; | 3843 | return; |
| 3843 | } | 3844 | } |
| 3844 | 3845 | ||
| 3845 | list_for_each_entry(img_req, &rbd_dev->acquiring_list, lock_item) { | 3846 | while (!list_empty(&rbd_dev->acquiring_list)) { |
| 3847 | img_req = list_first_entry(&rbd_dev->acquiring_list, | ||
| 3848 | struct rbd_img_request, lock_item); | ||
| 3846 | mutex_lock(&img_req->state_mutex); | 3849 | mutex_lock(&img_req->state_mutex); |
| 3847 | rbd_assert(img_req->state == RBD_IMG_EXCLUSIVE_LOCK); | 3850 | rbd_assert(img_req->state == RBD_IMG_EXCLUSIVE_LOCK); |
| 3851 | if (!result) | ||
| 3852 | list_move_tail(&img_req->lock_item, | ||
| 3853 | &rbd_dev->running_list); | ||
| 3854 | else | ||
| 3855 | list_del_init(&img_req->lock_item); | ||
| 3848 | rbd_img_schedule(img_req, result); | 3856 | rbd_img_schedule(img_req, result); |
| 3849 | mutex_unlock(&img_req->state_mutex); | 3857 | mutex_unlock(&img_req->state_mutex); |
| 3850 | } | 3858 | } |
| 3851 | |||
| 3852 | list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); | ||
| 3853 | } | 3859 | } |
| 3854 | 3860 | ||
| 3855 | static bool locker_equal(const struct ceph_locker *lhs, | 3861 | static bool locker_equal(const struct ceph_locker *lhs, |
| @@ -5326,7 +5332,7 @@ static void rbd_dev_release(struct device *dev) · 1470 unmodified lines | |||
| 5326 | 5332 | ||
| 5327 | if (need_put) { | 5333 | if (need_put) { |
| 5328 | destroy_workqueue(rbd_dev->task_wq); | 5334 | destroy_workqueue(rbd_dev->task_wq); |
| 5329 | ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); | 5335 | ida_free(&rbd_dev_id_ida, rbd_dev->dev_id); |
| 5330 | } | 5336 | } |
| 5331 | 5337 | ||
| 5332 | rbd_dev_free(rbd_dev); | 5338 | rbd_dev_free(rbd_dev); |
| @@ -5402,9 +5408,9 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, · 69 unmodified lines | |||
| 5402 | return NULL; | 5408 | return NULL; |
| 5403 | 5409 | ||
| 5404 | /* get an id and fill in device name */ | 5410 | /* get an id and fill in device name */ |
| 5405 | rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, | 5411 | rbd_dev->dev_id = ida_alloc_max(&rbd_dev_id_ida, |
| 5406 | minor_to_rbd_dev_id(1 << MINORBITS), | 5412 | minor_to_rbd_dev_id(1 << MINORBITS) - 1, |
| 5407 | GFP_KERNEL); | 5413 | GFP_KERNEL); |
| 5408 | if (rbd_dev->dev_id < 0) | 5414 | if (rbd_dev->dev_id < 0) |
| 5409 | goto fail_rbd_dev; | 5415 | goto fail_rbd_dev; |
| 5410 | 5416 | ||
| @@ -5425,7 +5431,7 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, · 14 unmodified lines | |||
| 5425 | return rbd_dev; | 5431 | return rbd_dev; |
| 5426 | 5432 | ||
| 5427 | fail_dev_id: | 5433 | fail_dev_id: |
| 5428 | ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); | 5434 | ida_free(&rbd_dev_id_ida, rbd_dev->dev_id); |
| 5429 | fail_rbd_dev: | 5435 | fail_rbd_dev: |
| 5430 | rbd_dev_free(rbd_dev); | 5436 | rbd_dev_free(rbd_dev); |
| 5431 | return NULL; | 5437 | return NULL; |
| @@ -1593,14 +1593,15 @@ static int virtblk_freeze(struct virtio_device *vdev) · 1592 unmodified lines | |||
| 1593 | { | 1593 | { |
| 1594 | struct virtio_blk *vblk = vdev->priv; | 1594 | struct virtio_blk *vblk = vdev->priv; |
| 1595 | 1595 | ||
| 1596 | /* Ensure no requests in virtqueues before deleting vqs. */ | ||
| 1597 | blk_mq_freeze_queue(vblk->disk->queue); | ||
| 1598 | |||
| 1596 | /* Ensure we don't receive any more interrupts */ | 1599 | /* Ensure we don't receive any more interrupts */ |
| 1597 | virtio_reset_device(vdev); | 1600 | virtio_reset_device(vdev); |
| 1598 | 1601 | ||
| 1599 | /* Make sure no work handler is accessing the device. */ | 1602 | /* Make sure no work handler is accessing the device. */ |
| 1600 | flush_work(&vblk->config_work); | 1603 | flush_work(&vblk->config_work); |
| 1601 | 1604 | ||
| 1602 | blk_mq_quiesce_queue(vblk->disk->queue); | ||
| 1603 | |||
| 1604 | vdev->config->del_vqs(vdev); | 1605 | vdev->config->del_vqs(vdev); |
| 1605 | kfree(vblk->vqs); | 1606 | kfree(vblk->vqs); |
| 1606 | 1607 | ||
| @@ -1618,7 +1619,7 @@ static int virtblk_restore(struct virtio_device *vdev) · 11 unmodified lines | |||
| 1618 | 1619 | ||
| 1619 | virtio_device_ready(vdev); | 1620 | virtio_device_ready(vdev); |
| 1620 | 1621 | ||
| 1621 | blk_mq_unquiesce_queue(vblk->disk->queue); | 1622 | blk_mq_unfreeze_queue(vblk->disk->queue); |
| 1622 | return 0; | 1623 | return 0; |
| 1623 | } | 1624 | } |
| 1624 | #endif | 1625 | #endif |
| @@ -1232,14 +1232,13 @@ static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy) · 1231 unmodified lines | |||
| 1232 | max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | 1232 | max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); |
| 1233 | min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | 1233 | min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); |
| 1234 | 1234 | ||
| 1235 | WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); | ||
| 1236 | WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); | ||
| 1237 | |||
| 1235 | max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, | 1238 | max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, |
| 1236 | cpudata->max_limit_perf); | 1239 | cpudata->max_limit_perf); |
| 1237 | min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, | 1240 | min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, |
| 1238 | cpudata->max_limit_perf); | 1241 | cpudata->max_limit_perf); |
| 1239 | |||
| 1240 | WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); | ||
| 1241 | WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); | ||
| 1242 | |||
| 1243 | value = READ_ONCE(cpudata->cppc_req_cached); | 1242 | value = READ_ONCE(cpudata->cppc_req_cached); |
| 1244 | 1243 | ||
| 1245 | if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) | 1244 | if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) |
| @@ -529,6 +529,30 @@ static int intel_pstate_cppc_get_scaling(int cpu) · 528 unmodified lines | |||
| 529 | } | 529 | } |
| 530 | #endif /* CONFIG_ACPI_CPPC_LIB */ | 530 | #endif /* CONFIG_ACPI_CPPC_LIB */ |
| 531 | 531 | ||
| 532 | static int intel_pstate_freq_to_hwp_rel(struct cpudata *cpu, int freq, | ||
| 533 | unsigned int relation) | ||
| 534 | { | ||
| 535 | if (freq == cpu->pstate.turbo_freq) | ||
| 536 | return cpu->pstate.turbo_pstate; | ||
| 537 | |||
| 538 | if (freq == cpu->pstate.max_freq) | ||
| 539 | return cpu->pstate.max_pstate; | ||
| 540 | |||
| 541 | switch (relation) { | ||
| 542 | case CPUFREQ_RELATION_H: | ||
| 543 | return freq / cpu->pstate.scaling; | ||
| 544 | case CPUFREQ_RELATION_C: | ||
| 545 | return DIV_ROUND_CLOSEST(freq, cpu->pstate.scaling); | ||
| 546 | } | ||
| 547 | |||
| 548 | return DIV_ROUND_UP(freq, cpu->pstate.scaling); | ||
| 549 | } | ||
| 550 | |||
| 551 | static int intel_pstate_freq_to_hwp(struct cpudata *cpu, int freq) | ||
| 552 | { | ||
| 553 | return intel_pstate_freq_to_hwp_rel(cpu, freq, CPUFREQ_RELATION_L); | ||
| 554 | } | ||
| 555 | |||
| 532 | /** | 556 | /** |
| 533 | * intel_pstate_hybrid_hwp_adjust - Calibrate HWP performance levels. | 557 | * intel_pstate_hybrid_hwp_adjust - Calibrate HWP performance levels. |
| 534 | * @cpu: Target CPU. | 558 | * @cpu: Target CPU. |
| @@ -546,6 +570,7 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu) · 11 unmodified lines | |||
| 546 | int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling; | 570 | int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling; |
| 547 | int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu); | 571 | int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu); |
| 548 | int scaling = cpu->pstate.scaling; | 572 | int scaling = cpu->pstate.scaling; |
| 573 | int freq; | ||
| 549 | 574 | ||
| 550 | pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys); | 575 | pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys); |
| 551 | pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo); | 576 | pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo); |
| @@ -559,16 +584,16 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu) · 7 unmodified lines | |||
| 559 | cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling, | 584 | cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling, |
| 560 | perf_ctl_scaling); | 585 | perf_ctl_scaling); |
| 561 | 586 | ||
| 562 | cpu->pstate.max_pstate_physical = | 587 | freq = perf_ctl_max_phys * perf_ctl_scaling; |
| 563 | DIV_ROUND_UP(perf_ctl_max_phys * perf_ctl_scaling, | 588 | cpu->pstate.max_pstate_physical = intel_pstate_freq_to_hwp(cpu, freq); |
| 564 | scaling); | ||
| 565 | 589 | ||
| 566 | cpu->pstate.min_freq = cpu->pstate.min_pstate * perf_ctl_scaling; | 590 | freq = cpu->pstate.min_pstate * perf_ctl_scaling; |
| 591 | cpu->pstate.min_freq = freq; | ||
| 567 | /* | 592 | /* |
| 568 | * Cast the min P-state value retrieved via pstate_funcs.get_min() to | 593 | * Cast the min P-state value retrieved via pstate_funcs.get_min() to |
| 569 | * the effective range of HWP performance levels. | 594 | * the effective range of HWP performance levels. |
| 570 | */ | 595 | */ |
| 571 | cpu->pstate.min_pstate = DIV_ROUND_UP(cpu->pstate.min_freq, scaling); | 596 | cpu->pstate.min_pstate = intel_pstate_freq_to_hwp(cpu, freq); |
| 572 | } | 597 | } |
| 573 | 598 | ||
| 574 | static inline void update_turbo_state(void) | 599 | static inline void update_turbo_state(void) |
| @@ -2528,13 +2553,12 @@ static void intel_pstate_update_perf_limits(struct cpudata *cpu, · 1953 unmodified lines | |||
| 2528 | * abstract values to represent performance rather than pure ratios. | 2553 | * abstract values to represent performance rather than pure ratios. |
| 2529 | */ | 2554 | */ |
| 2530 | if (hwp_active && cpu->pstate.scaling != perf_ctl_scaling) { | 2555 | if (hwp_active && cpu->pstate.scaling != perf_ctl_scaling) { |
| 2531 | int scaling = cpu->pstate.scaling; | ||
| 2532 | int freq; | 2556 | int freq; |
| 2533 | 2557 | ||
| 2534 | freq = max_policy_perf * perf_ctl_scaling; | 2558 | freq = max_policy_perf * perf_ctl_scaling; |
| 2535 | max_policy_perf = DIV_ROUND_UP(freq, scaling); | 2559 | max_policy_perf = intel_pstate_freq_to_hwp(cpu, freq); |
| 2536 | freq = min_policy_perf * perf_ctl_scaling; | 2560 | freq = min_policy_perf * perf_ctl_scaling; |
| 2537 | min_policy_perf = DIV_ROUND_UP(freq, scaling); | 2561 | min_policy_perf = intel_pstate_freq_to_hwp(cpu, freq); |
| 2538 | } | 2562 | } |
| 2539 | 2563 | ||
| 2540 | pr_debug("cpu:%d min_policy_perf:%d max_policy_perf:%d\n", | 2564 | pr_debug("cpu:%d min_policy_perf:%d max_policy_perf:%d\n", |
| @@ -2908,18 +2932,7 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy, · 367 unmodified lines | |||
| 2908 | 2932 | ||
| 2909 | cpufreq_freq_transition_begin(policy, &freqs); | 2933 | cpufreq_freq_transition_begin(policy, &freqs); |
| 2910 | 2934 | ||
| 2911 | switch (relation) { | 2935 | target_pstate = intel_pstate_freq_to_hwp_rel(cpu, freqs.new, relation); |
| 2912 | case CPUFREQ_RELATION_L: | ||
| 2913 | target_pstate = DIV_ROUND_UP(freqs.new, cpu->pstate.scaling); | ||
| 2914 | break; | ||
| 2915 | case CPUFREQ_RELATION_H: | ||
| 2916 | target_pstate = freqs.new / cpu->pstate.scaling; | ||
| 2917 | break; | ||
| 2918 | default: | ||
| 2919 | target_pstate = DIV_ROUND_CLOSEST(freqs.new, cpu->pstate.scaling); | ||
| 2920 | break; | ||
| 2921 | } | ||
| 2922 | |||
| 2923 | target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, false); | 2936 | target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, false); |
| 2924 | 2937 | ||
| 2925 | freqs.new = target_pstate * cpu->pstate.scaling; | 2938 | freqs.new = target_pstate * cpu->pstate.scaling; |
| @@ -2937,7 +2950,7 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy, · 11 unmodified lines | |||
| 2937 | 2950 | ||
| 2938 | update_turbo_state(); | 2951 | update_turbo_state(); |
| 2939 | 2952 | ||
| 2940 | target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling); | 2953 | target_pstate = intel_pstate_freq_to_hwp(cpu, target_freq); |
| 2941 | 2954 | ||
| 2942 | target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, true); | 2955 | target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, true); |
| 2943 | 2956 | ||
| @@ -4545,6 +4545,7 @@ struct caam_hash_alg { · 4544 unmodified lines | |||
| 4545 | struct list_head entry; | 4545 | struct list_head entry; |
| 4546 | struct device *dev; | 4546 | struct device *dev; |
| 4547 | int alg_type; | 4547 | int alg_type; |
| 4548 | bool is_hmac; | ||
| 4548 | struct ahash_alg ahash_alg; | 4549 | struct ahash_alg ahash_alg; |
| 4549 | }; | 4550 | }; |
| 4550 | 4551 | ||
| @@ -4571,7 +4572,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) · 20 unmodified lines | |||
| 4571 | 4572 | ||
| 4572 | ctx->dev = caam_hash->dev; | 4573 | ctx->dev = caam_hash->dev; |
| 4573 | 4574 | ||
| 4574 | if (alg->setkey) { | 4575 | if (caam_hash->is_hmac) { |
| 4575 | ctx->adata.key_dma = dma_map_single_attrs(ctx->dev, ctx->key, | 4576 | ctx->adata.key_dma = dma_map_single_attrs(ctx->dev, ctx->key, |
| 4576 | ARRAY_SIZE(ctx->key), | 4577 | ARRAY_SIZE(ctx->key), |
| 4577 | DMA_TO_DEVICE, | 4578 | DMA_TO_DEVICE, |
| @@ -4611,7 +4612,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) · 33 unmodified lines | |||
| 4611 | * For keyed hash algorithms shared descriptors | 4612 | * For keyed hash algorithms shared descriptors |
| 4612 | * will be created later in setkey() callback | 4613 | * will be created later in setkey() callback |
| 4613 | */ | 4614 | */ |
| 4614 | return alg->setkey ? 0 : ahash_set_sh_desc(ahash); | 4615 | return caam_hash->is_hmac ? 0 : ahash_set_sh_desc(ahash); |
| 4615 | } | 4616 | } |
| 4616 | 4617 | ||
| 4617 | static void caam_hash_cra_exit(struct crypto_tfm *tfm) | 4618 | static void caam_hash_cra_exit(struct crypto_tfm *tfm) |
| @@ -4646,12 +4647,14 @@ static struct caam_hash_alg *caam_hash_alloc(struct device *dev, · 28 unmodified lines | |||
| 4646 | template->hmac_name); | 4647 | template->hmac_name); |
| 4647 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", | 4648 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", |
| 4648 | template->hmac_driver_name); | 4649 | template->hmac_driver_name); |
| 4650 | t_alg->is_hmac = true; | ||
| 4649 | } else { | 4651 | } else { |
| 4650 | snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", | 4652 | snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", |
| 4651 | template->name); | 4653 | template->name); |
| 4652 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", | 4654 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", |
| 4653 | template->driver_name); | 4655 | template->driver_name); |
| 4654 | t_alg->ahash_alg.setkey = NULL; | 4656 | t_alg->ahash_alg.setkey = NULL; |
| 4657 | t_alg->is_hmac = false; | ||
| 4655 | } | 4658 | } |
| 4656 | alg->cra_module = THIS_MODULE; | 4659 | alg->cra_module = THIS_MODULE; |
| 4657 | alg->cra_init = caam_hash_cra_init; | 4660 | alg->cra_init = caam_hash_cra_init; |
| @@ -1753,6 +1753,7 @@ static struct caam_hash_template driver_hash[] = { · 1752 unmodified lines | |||
| 1753 | struct caam_hash_alg { | 1753 | struct caam_hash_alg { |
| 1754 | struct list_head entry; | 1754 | struct list_head entry; |
| 1755 | int alg_type; | 1755 | int alg_type; |
| 1756 | bool is_hmac; | ||
| 1756 | struct ahash_engine_alg ahash_alg; | 1757 | struct ahash_engine_alg ahash_alg; |
| 1757 | }; | 1758 | }; |
| 1758 | 1759 | ||
| @@ -1804,7 +1805,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) · 45 unmodified lines | |||
| 1804 | } else { | 1805 | } else { |
| 1805 | if (priv->era >= 6) { | 1806 | if (priv->era >= 6) { |
| 1806 | ctx->dir = DMA_BIDIRECTIONAL; | 1807 | ctx->dir = DMA_BIDIRECTIONAL; |
| 1807 | ctx->key_dir = alg->setkey ? DMA_TO_DEVICE : DMA_NONE; | 1808 | ctx->key_dir = caam_hash->is_hmac ? DMA_TO_DEVICE : DMA_NONE; |
| 1808 | } else { | 1809 | } else { |
| 1809 | ctx->dir = DMA_TO_DEVICE; | 1810 | ctx->dir = DMA_TO_DEVICE; |
| 1810 | ctx->key_dir = DMA_NONE; | 1811 | ctx->key_dir = DMA_NONE; |
| @@ -1862,7 +1863,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) · 51 unmodified lines | |||
| 1862 | * For keyed hash algorithms shared descriptors | 1863 | * For keyed hash algorithms shared descriptors |
| 1863 | * will be created later in setkey() callback | 1864 | * will be created later in setkey() callback |
| 1864 | */ | 1865 | */ |
| 1865 | return alg->setkey ? 0 : ahash_set_sh_desc(ahash); | 1866 | return caam_hash->is_hmac ? 0 : ahash_set_sh_desc(ahash); |
| 1866 | } | 1867 | } |
| 1867 | 1868 | ||
| 1868 | static void caam_hash_cra_exit(struct crypto_tfm *tfm) | 1869 | static void caam_hash_cra_exit(struct crypto_tfm *tfm) |
| @@ -1915,12 +1916,14 @@ caam_hash_alloc(struct caam_hash_template *template, · 46 unmodified lines | |||
| 1915 | template->hmac_name); | 1916 | template->hmac_name); |
| 1916 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", | 1917 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", |
| 1917 | template->hmac_driver_name); | 1918 | template->hmac_driver_name); |
| 1919 | t_alg->is_hmac = true; | ||
| 1918 | } else { | 1920 | } else { |
| 1919 | snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", | 1921 | snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", |
| 1920 | template->name); | 1922 | template->name); |
| 1921 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", | 1923 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", |
| 1922 | template->driver_name); | 1924 | template->driver_name); |
| 1923 | halg->setkey = NULL; | 1925 | halg->setkey = NULL; |
| 1926 | t_alg->is_hmac = false; | ||
| 1924 | } | 1927 | } |
| 1925 | alg->cra_module = THIS_MODULE; | 1928 | alg->cra_module = THIS_MODULE; |
| 1926 | alg->cra_init = caam_hash_cra_init; | 1929 | alg->cra_init = caam_hash_cra_init; |
| @@ -534,10 +534,16 @@ EXPORT_SYMBOL_GPL(sev_platform_init); · 533 unmodified lines | |||
| 534 | 534 | ||
| 535 | static int __sev_platform_shutdown_locked(int *error) | 535 | static int __sev_platform_shutdown_locked(int *error) |
| 536 | { | 536 | { |
| 537 | struct sev_device *sev = psp_master->sev_data; | 537 | struct psp_device *psp = psp_master; |
| 538 | struct sev_device *sev; | ||
| 538 | int ret; | 539 | int ret; |
| 539 | 540 | ||
| 540 | if (!sev || sev->state == SEV_STATE_UNINIT) | 541 | if (!psp || !psp->sev_data) |
| 542 | return 0; | ||
| 543 | |||
| 544 | sev = psp->sev_data; | ||
| 545 | |||
| 546 | if (sev->state == SEV_STATE_UNINIT) | ||
| 541 | return 0; | 547 | return 0; |
| 542 | 548 | ||
| 543 | ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error); | 549 | ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error); |
| @@ -463,6 +463,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id) · 462 unmodified lines | |||
| 463 | hw_data->fw_name = ADF_402XX_FW; | 463 | hw_data->fw_name = ADF_402XX_FW; |
| 464 | hw_data->fw_mmp_name = ADF_402XX_MMP; | 464 | hw_data->fw_mmp_name = ADF_402XX_MMP; |
| 465 | hw_data->uof_get_name = uof_get_name_402xx; | 465 | hw_data->uof_get_name = uof_get_name_402xx; |
| 466 | hw_data->get_ena_thd_mask = get_ena_thd_mask; | ||
| 466 | break; | 467 | break; |
| 467 | case ADF_401XX_PCI_DEVICE_ID: | 468 | case ADF_401XX_PCI_DEVICE_ID: |
| 468 | hw_data->fw_name = ADF_4XXX_FW; | 469 | hw_data->fw_name = ADF_4XXX_FW; |
| @@ -525,7 +525,7 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size) · 524 unmodified lines | |||
| 525 | struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); | 525 | struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); |
| 526 | struct cxl_region_params *p = &cxlr->params; | 526 | struct cxl_region_params *p = &cxlr->params; |
| 527 | struct resource *res; | 527 | struct resource *res; |
| 528 | u32 remainder = 0; | 528 | u64 remainder = 0; |
| 529 | 529 | ||
| 530 | lockdep_assert_held_write(&cxl_region_rwsem); | 530 | lockdep_assert_held_write(&cxl_region_rwsem); |
| 531 | 531 | ||
| @@ -545,7 +545,7 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size) · 13 unmodified lines | |||
| 545 | (cxlr->mode == CXL_DECODER_PMEM && uuid_is_null(&p->uuid))) | 545 | (cxlr->mode == CXL_DECODER_PMEM && uuid_is_null(&p->uuid))) |
| 546 | return -ENXIO; | 546 | return -ENXIO; |
| 547 | 547 | ||
| 548 | div_u64_rem(size, SZ_256M * p->interleave_ways, &remainder); | 548 | div64_u64_rem(size, (u64)SZ_256M * p->interleave_ways, &remainder); |
| 549 | if (remainder) | 549 | if (remainder) |
| 550 | return -EINVAL; | 550 | return -EINVAL; |
| 551 | 551 | ||
| @@ -338,7 +338,7 @@ TRACE_EVENT(cxl_general_media, · 337 unmodified lines | |||
| 338 | 338 | ||
| 339 | TP_fast_assign( | 339 | TP_fast_assign( |
| 340 | CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr); | 340 | CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr); |
| 341 | memcpy(&__entry->hdr_uuid, &CXL_EVENT_GEN_MEDIA_UUID, sizeof(uuid_t)); | 341 | __entry->hdr_uuid = CXL_EVENT_GEN_MEDIA_UUID; |
| 342 | 342 | ||
| 343 | /* General Media */ | 343 | /* General Media */ |
| 344 | __entry->dpa = le64_to_cpu(rec->phys_addr); | 344 | __entry->dpa = le64_to_cpu(rec->phys_addr); |
| @@ -425,7 +425,7 @@ TRACE_EVENT(cxl_dram, · 80 unmodified lines | |||
| 425 | 425 | ||
| 426 | TP_fast_assign( | 426 | TP_fast_assign( |
| 427 | CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr); | 427 | CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr); |
| 428 | memcpy(&__entry->hdr_uuid, &CXL_EVENT_DRAM_UUID, sizeof(uuid_t)); | 428 | __entry->hdr_uuid = CXL_EVENT_DRAM_UUID; |
| 429 | 429 | ||
| 430 | /* DRAM */ | 430 | /* DRAM */ |
| 431 | __entry->dpa = le64_to_cpu(rec->phys_addr); | 431 | __entry->dpa = le64_to_cpu(rec->phys_addr); |
| @@ -573,7 +573,7 @@ TRACE_EVENT(cxl_memory_module, · 141 unmodified lines | |||
| 573 | 573 | ||
| 574 | TP_fast_assign( | 574 | TP_fast_assign( |
| 575 | CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr); | 575 | CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr); |
| 576 | memcpy(&__entry->hdr_uuid, &CXL_EVENT_MEM_MODULE_UUID, sizeof(uuid_t)); | 576 | __entry->hdr_uuid = CXL_EVENT_MEM_MODULE_UUID; |
| 577 | 577 | ||
| 578 | /* Memory Module Event */ | 578 | /* Memory Module Event */ |
| 579 | __entry->event_type = rec->event_type; | 579 | __entry->event_type = rec->event_type; |
| @@ -382,7 +382,7 @@ static int cxl_pci_mbox_send(struct cxl_memdev_state *mds, · 381 unmodified lines | |||
| 382 | return rc; | 382 | return rc; |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds) | 385 | static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail) |
| 386 | { | 386 | { |
| 387 | struct cxl_dev_state *cxlds = &mds->cxlds; | 387 | struct cxl_dev_state *cxlds = &mds->cxlds; |
| 388 | const int cap = readl(cxlds->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET); | 388 | const int cap = readl(cxlds->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET); |
| @@ -441,7 +441,7 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds) · 52 unmodified lines | |||
| 441 | INIT_DELAYED_WORK(&mds->security.poll_dwork, cxl_mbox_sanitize_work); | 441 | INIT_DELAYED_WORK(&mds->security.poll_dwork, cxl_mbox_sanitize_work); |
| 442 | 442 | ||
| 443 | /* background command interrupts are optional */ | 443 | /* background command interrupts are optional */ |
| 444 | if (!(cap & CXLDEV_MBOX_CAP_BG_CMD_IRQ)) | 444 | if (!(cap & CXLDEV_MBOX_CAP_BG_CMD_IRQ) || !irq_avail) |
| 445 | return 0; | 445 | return 0; |
| 446 | 446 | ||
| 447 | msgnum = FIELD_GET(CXLDEV_MBOX_CAP_IRQ_MSGNUM_MASK, cap); | 447 | msgnum = FIELD_GET(CXLDEV_MBOX_CAP_IRQ_MSGNUM_MASK, cap); |
| @@ -588,7 +588,7 @@ static int cxl_mem_alloc_event_buf(struct cxl_memdev_state *mds) · 140 unmodified lines | |||
| 588 | return devm_add_action_or_reset(mds->cxlds.dev, free_event_buf, buf); | 588 | return devm_add_action_or_reset(mds->cxlds.dev, free_event_buf, buf); |
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | static int cxl_alloc_irq_vectors(struct pci_dev *pdev) | 591 | static bool cxl_alloc_irq_vectors(struct pci_dev *pdev) |
| 592 | { | 592 | { |
| 593 | int nvecs; | 593 | int nvecs; |
| 594 | 594 | ||
| @@ -605,9 +605,9 @@ static int cxl_alloc_irq_vectors(struct pci_dev *pdev) · 10 unmodified lines | |||
| 605 | PCI_IRQ_MSIX | PCI_IRQ_MSI); | 605 | PCI_IRQ_MSIX | PCI_IRQ_MSI); |
| 606 | if (nvecs < 1) { | 606 | if (nvecs < 1) { |
| 607 | dev_dbg(&pdev->dev, "Failed to alloc irq vectors: %d\n", nvecs); | 607 | dev_dbg(&pdev->dev, "Failed to alloc irq vectors: %d\n", nvecs); |
| 608 | return -ENXIO; | 608 | return false; |
| 609 | } | 609 | } |
| 610 | return 0; | 610 | return true; |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | static irqreturn_t cxl_event_thread(int irq, void *id) | 613 | static irqreturn_t cxl_event_thread(int irq, void *id) |
| @@ -743,7 +743,7 @@ static bool cxl_event_int_is_fw(u8 setting) · 129 unmodified lines | |||
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | static int cxl_event_config(struct pci_host_bridge *host_bridge, | 745 | static int cxl_event_config(struct pci_host_bridge *host_bridge, |
| 746 | struct cxl_memdev_state *mds) | 746 | struct cxl_memdev_state *mds, bool irq_avail) |
| 747 | { | 747 | { |
| 748 | struct cxl_event_interrupt_policy policy; | 748 | struct cxl_event_interrupt_policy policy; |
| 749 | int rc; | 749 | int rc; |
| @@ -755,6 +755,11 @@ static int cxl_event_config(struct pci_host_bridge *host_bridge, · 5 unmodified lines | |||
| 755 | if (!host_bridge->native_cxl_error) | 755 | if (!host_bridge->native_cxl_error) |
| 756 | return 0; | 756 | return 0; |
| 757 | 757 | ||
| 758 | if (!irq_avail) { | ||
| 759 | dev_info(mds->cxlds.dev, "No interrupt support, disable event processing.\n"); | ||
| 760 | return 0; | ||
| 761 | } | ||
| 762 | |||
| 758 | rc = cxl_mem_alloc_event_buf(mds); | 763 | rc = cxl_mem_alloc_event_buf(mds); |
| 759 | if (rc) | 764 | if (rc) |
| 760 | return rc; | 765 | return rc; |
| @@ -789,6 +794,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 28 unmodified lines | |||
| 789 | struct cxl_register_map map; | 794 | struct cxl_register_map map; |
| 790 | struct cxl_memdev *cxlmd; | 795 | struct cxl_memdev *cxlmd; |
| 791 | int i, rc, pmu_count; | 796 | int i, rc, pmu_count; |
| 797 | bool irq_avail; | ||
| 792 | 798 | ||
| 793 | /* | 799 | /* |
| 794 | * Double check the anonymous union trickery in struct cxl_regs | 800 | * Double check the anonymous union trickery in struct cxl_regs |
| @@ -846,11 +852,9 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 51 unmodified lines | |||
| 846 | else | 852 | else |
| 847 | dev_warn(&pdev->dev, "Media not active (%d)\n", rc); | 853 | dev_warn(&pdev->dev, "Media not active (%d)\n", rc); |
| 848 | 854 | ||
| 849 | rc = cxl_alloc_irq_vectors(pdev); | 855 | irq_avail = cxl_alloc_irq_vectors(pdev); |
| 850 | if (rc) | ||
| 851 | return rc; | ||
| 852 | 856 | ||
| 853 | rc = cxl_pci_setup_mailbox(mds); | 857 | rc = cxl_pci_setup_mailbox(mds, irq_avail); |
| 854 | if (rc) | 858 | if (rc) |
| 855 | return rc; | 859 | return rc; |
| 856 | 860 | ||
| @@ -909,7 +913,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 52 unmodified lines | |||
| 909 | } | 913 | } |
| 910 | } | 914 | } |
| 911 | 915 | ||
| 912 | rc = cxl_event_config(host_bridge, mds); | 916 | rc = cxl_event_config(host_bridge, mds, irq_avail); |
| 913 | if (rc) | 917 | if (rc) |
| 914 | return rc; | 918 | return rc; |
| 915 | 919 | ||
| @@ -168,10 +168,7 @@ static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf) · 167 unmodified lines | |||
| 168 | if (vmf->pgoff > buffer->pagecount) | 168 | if (vmf->pgoff > buffer->pagecount) |
| 169 | return VM_FAULT_SIGBUS; | 169 | return VM_FAULT_SIGBUS; |
| 170 | 170 | ||
| 171 | vmf->page = buffer->pages[vmf->pgoff]; | 171 | return vmf_insert_pfn(vma, vmf->address, page_to_pfn(buffer->pages[vmf->pgoff])); |
| 172 | get_page(vmf->page); | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | 172 | } |
| 176 | 173 | ||
| 177 | static const struct vm_operations_struct dma_heap_vm_ops = { | 174 | static const struct vm_operations_struct dma_heap_vm_ops = { |
| @@ -185,6 +182,8 @@ static int cma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) · 7 unmodified lines | |||
| 185 | if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) | 182 | if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) |
| 186 | return -EINVAL; | 183 | return -EINVAL; |
| 187 | 184 | ||
| 185 | vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); | ||
| 186 | |||
| 188 | vma->vm_ops = &dma_heap_vm_ops; | 187 | vma->vm_ops = &dma_heap_vm_ops; |
| 189 | vma->vm_private_data = buffer; | 188 | vma->vm_private_data = buffer; |
| 190 | 189 | ||
| @@ -222,8 +222,14 @@ struct atdma_sg { · 221 unmodified lines | |||
| 222 | * @vd: pointer to the virtual dma descriptor. | 222 | * @vd: pointer to the virtual dma descriptor. |
| 223 | * @atchan: pointer to the atmel dma channel. | 223 | * @atchan: pointer to the atmel dma channel. |
| 224 | * @total_len: total transaction byte count | 224 | * @total_len: total transaction byte count |
| 225 | * @sg_len: number of sg entries. | 225 | * @sglen: number of sg entries. |
| 226 | * @sg: array of sgs. | 226 | * @sg: array of sgs. |
| 227 | * @boundary: number of transfers to perform before the automatic address increment operation | ||
| 228 | * @dst_hole: value to add to the destination address when the boundary has been reached | ||
| 229 | * @src_hole: value to add to the source address when the boundary has been reached | ||
| 230 | * @memset_buffer: buffer used for the memset operation | ||
| 231 | * @memset_paddr: physical address of the buffer used for the memset operation | ||
| 232 | * @memset_vaddr: virtual address of the buffer used for the memset operation | ||
| 227 | */ | 233 | */ |
| 228 | struct at_desc { | 234 | struct at_desc { |
| 229 | struct virt_dma_desc vd; | 235 | struct virt_dma_desc vd; |
| @@ -245,7 +251,10 @@ struct at_desc { · 15 unmodified lines | |||
| 245 | /*-- Channels --------------------------------------------------------*/ | 251 | /*-- Channels --------------------------------------------------------*/ |
| 246 | 252 | ||
| 247 | /** | 253 | /** |
| 248 | * atc_status - information bits stored in channel status flag | 254 | * enum atc_status - information bits stored in channel status flag |
| 255 | * | ||
| 256 | * @ATC_IS_PAUSED: If channel is pauses | ||
| 257 | * @ATC_IS_CYCLIC: If channel is cyclic | ||
| 249 | * | 258 | * |
| 250 | * Manipulated with atomic operations. | 259 | * Manipulated with atomic operations. |
| 251 | */ | 260 | */ |
| @@ -282,7 +291,6 @@ struct at_dma_chan { · 30 unmodified lines | |||
| 282 | u32 save_cfg; | 291 | u32 save_cfg; |
| 283 | u32 save_dscr; | 292 | u32 save_dscr; |
| 284 | struct dma_slave_config dma_sconfig; | 293 | struct dma_slave_config dma_sconfig; |
| 285 | bool cyclic; | ||
| 286 | struct at_desc *desc; | 294 | struct at_desc *desc; |
| 287 | }; | 295 | }; |
| 288 | 296 | ||
| @@ -328,12 +336,12 @@ static inline u8 convert_buswidth(enum dma_slave_buswidth addr_width) · 39 unmodified lines | |||
| 328 | /** | 336 | /** |
| 329 | * struct at_dma - internal representation of an Atmel HDMA Controller | 337 | * struct at_dma - internal representation of an Atmel HDMA Controller |
| 330 | * @dma_device: dmaengine dma_device object members | 338 | * @dma_device: dmaengine dma_device object members |
| 331 | * @atdma_devtype: identifier of DMA controller compatibility | 339 | * @regs: memory mapped register base |
| 332 | * @ch_regs: memory mapped register base | ||
| 333 | * @clk: dma controller clock | 340 | * @clk: dma controller clock |
| 334 | * @save_imr: interrupt mask register that is saved on suspend/resume cycle | 341 | * @save_imr: interrupt mask register that is saved on suspend/resume cycle |
| 335 | * @all_chan_mask: all channels availlable in a mask | 342 | * @all_chan_mask: all channels availlable in a mask |
| 336 | * @lli_pool: hw lli table | 343 | * @lli_pool: hw lli table |
| 344 | * @memset_pool: hw memset pool | ||
| 337 | * @chan: channels table to store at_dma_chan structures | 345 | * @chan: channels table to store at_dma_chan structures |
| 338 | */ | 346 | */ |
| 339 | struct at_dma { | 347 | struct at_dma { |
| @@ -626,6 +634,9 @@ static inline u32 atc_calc_bytes_left(u32 current_len, u32 ctrla) · 286 unmodified lines | |||
| 626 | 634 | ||
| 627 | /** | 635 | /** |
| 628 | * atc_get_llis_residue - Get residue for a hardware linked list transfer | 636 | * atc_get_llis_residue - Get residue for a hardware linked list transfer |
| 637 | * @atchan: pointer to an atmel hdmac channel. | ||
| 638 | * @desc: pointer to the descriptor for which the residue is calculated. | ||
| 639 | * @residue: residue to be set to dma_tx_state. | ||
| 629 | * | 640 | * |
| 630 | * Calculate the residue by removing the length of the Linked List Item (LLI) | 641 | * Calculate the residue by removing the length of the Linked List Item (LLI) |
| 631 | * already transferred from the total length. To get the current LLI we can use | 642 | * already transferred from the total length. To get the current LLI we can use |
| @@ -661,10 +672,8 @@ static inline u32 atc_calc_bytes_left(u32 current_len, u32 ctrla) · 29 unmodified lines | |||
| 661 | * two DSCR values are different, we read again the CTRLA then the DSCR till two | 672 | * two DSCR values are different, we read again the CTRLA then the DSCR till two |
| 662 | * consecutive read values from DSCR are equal or till the maximum trials is | 673 | * consecutive read values from DSCR are equal or till the maximum trials is |
| 663 | * reach. This algorithm is very unlikely not to find a stable value for DSCR. | 674 | * reach. This algorithm is very unlikely not to find a stable value for DSCR. |
| 664 | * @atchan: pointer to an atmel hdmac channel. | 675 | * |
| 665 | * @desc: pointer to the descriptor for which the residue is calculated. | 676 | * Returns: %0 on success, -errno otherwise. |
| 666 | * @residue: residue to be set to dma_tx_state. | ||
| 667 | * Returns 0 on success, -errno otherwise. | ||
| 668 | */ | 677 | */ |
| 669 | static int atc_get_llis_residue(struct at_dma_chan *atchan, | 678 | static int atc_get_llis_residue(struct at_dma_chan *atchan, |
| 670 | struct at_desc *desc, u32 *residue) | 679 | struct at_desc *desc, u32 *residue) |
| @@ -731,7 +740,8 @@ static int atc_get_llis_residue(struct at_dma_chan *atchan, · 60 unmodified lines | |||
| 731 | * @chan: DMA channel | 740 | * @chan: DMA channel |
| 732 | * @cookie: transaction identifier to check status of | 741 | * @cookie: transaction identifier to check status of |
| 733 | * @residue: residue to be updated. | 742 | * @residue: residue to be updated. |
| 734 | * Return 0 on success, -errono otherwise. | 743 | * |
| 744 | * Return: %0 on success, -errno otherwise. | ||
| 735 | */ | 745 | */ |
| 736 | static int atc_get_residue(struct dma_chan *chan, dma_cookie_t cookie, | 746 | static int atc_get_residue(struct dma_chan *chan, dma_cookie_t cookie, |
| 737 | u32 *residue) | 747 | u32 *residue) |
| @@ -1710,7 +1720,7 @@ static void atc_issue_pending(struct dma_chan *chan) · 972 unmodified lines | |||
| 1710 | * atc_alloc_chan_resources - allocate resources for DMA channel | 1720 | * atc_alloc_chan_resources - allocate resources for DMA channel |
| 1711 | * @chan: allocate descriptor resources for this channel | 1721 | * @chan: allocate descriptor resources for this channel |
| 1712 | * | 1722 | * |
| 1713 | * return - the number of allocated descriptors | 1723 | * Return: the number of allocated descriptors |
| 1714 | */ | 1724 | */ |
| 1715 | static int atc_alloc_chan_resources(struct dma_chan *chan) | 1725 | static int atc_alloc_chan_resources(struct dma_chan *chan) |
| 1716 | { | 1726 | { |
| @@ -38,15 +38,17 @@ static int dpaa2_qdma_alloc_chan_resources(struct dma_chan *chan) · 37 unmodified lines | |||
| 38 | if (!dpaa2_chan->fd_pool) | 38 | if (!dpaa2_chan->fd_pool) |
| 39 | goto err; | 39 | goto err; |
| 40 | 40 | ||
| 41 | dpaa2_chan->fl_pool = dma_pool_create("fl_pool", dev, | 41 | dpaa2_chan->fl_pool = |
| 42 | sizeof(struct dpaa2_fl_entry), | 42 | dma_pool_create("fl_pool", dev, |
| 43 | sizeof(struct dpaa2_fl_entry), 0); | 43 | sizeof(struct dpaa2_fl_entry) * 3, |
| 44 | sizeof(struct dpaa2_fl_entry), 0); | ||
| 45 | |||
| 44 | if (!dpaa2_chan->fl_pool) | 46 | if (!dpaa2_chan->fl_pool) |
| 45 | goto err_fd; | 47 | goto err_fd; |
| 46 | 48 | ||
| 47 | dpaa2_chan->sdd_pool = | 49 | dpaa2_chan->sdd_pool = |
| 48 | dma_pool_create("sdd_pool", dev, | 50 | dma_pool_create("sdd_pool", dev, |
| 49 | sizeof(struct dpaa2_qdma_sd_d), | 51 | sizeof(struct dpaa2_qdma_sd_d) * 2, |
| 50 | sizeof(struct dpaa2_qdma_sd_d), 0); | 52 | sizeof(struct dpaa2_qdma_sd_d), 0); |
| 51 | if (!dpaa2_chan->sdd_pool) | 53 | if (!dpaa2_chan->sdd_pool) |
| 52 | goto err_fl; | 54 | goto err_fl; |
| @@ -514,11 +514,11 @@ static struct fsl_qdma_queue · 513 unmodified lines | |||
| 514 | queue_temp = queue_head + i + (j * queue_num); | 514 | queue_temp = queue_head + i + (j * queue_num); |
| 515 | 515 | ||
| 516 | queue_temp->cq = | 516 | queue_temp->cq = |
| 517 | dma_alloc_coherent(&pdev->dev, | 517 | dmam_alloc_coherent(&pdev->dev, |
| 518 | sizeof(struct fsl_qdma_format) * | 518 | sizeof(struct fsl_qdma_format) * |
| 519 | queue_size[i], | 519 | queue_size[i], |
| 520 | &queue_temp->bus_addr, | 520 | &queue_temp->bus_addr, |
| 521 | GFP_KERNEL); | 521 | GFP_KERNEL); |
| 522 | if (!queue_temp->cq) | 522 | if (!queue_temp->cq) |
| 523 | return NULL; | 523 | return NULL; |
| 524 | queue_temp->block_base = fsl_qdma->block_base + | 524 | queue_temp->block_base = fsl_qdma->block_base + |
| @@ -563,15 +563,14 @@ static struct fsl_qdma_queue · 38 unmodified lines | |||
| 563 | /* | 563 | /* |
| 564 | * Buffer for queue command | 564 | * Buffer for queue command |
| 565 | */ | 565 | */ |
| 566 | status_head->cq = dma_alloc_coherent(&pdev->dev, | 566 | status_head->cq = dmam_alloc_coherent(&pdev->dev, |
| 567 | sizeof(struct fsl_qdma_format) * | 567 | sizeof(struct fsl_qdma_format) * |
| 568 | status_size, | 568 | status_size, |
| 569 | &status_head->bus_addr, | 569 | &status_head->bus_addr, |
| 570 | GFP_KERNEL); | 570 | GFP_KERNEL); |
| 571 | if (!status_head->cq) { | 571 | if (!status_head->cq) |
| 572 | devm_kfree(&pdev->dev, status_head); | ||
| 573 | return NULL; | 572 | return NULL; |
| 574 | } | 573 | |
| 575 | status_head->n_cq = status_size; | 574 | status_head->n_cq = status_size; |
| 576 | status_head->virt_head = status_head->cq; | 575 | status_head->virt_head = status_head->cq; |
| 577 | status_head->virt_tail = status_head->cq; | 576 | status_head->virt_tail = status_head->cq; |
| @@ -1268,8 +1267,6 @@ static void fsl_qdma_cleanup_vchan(struct dma_device *dmadev) · 690 unmodified lines | |||
| 1268 | 1267 | ||
| 1269 | static void fsl_qdma_remove(struct platform_device *pdev) | 1268 | static void fsl_qdma_remove(struct platform_device *pdev) |
| 1270 | { | 1269 | { |
| 1271 | int i; | ||
| 1272 | struct fsl_qdma_queue *status; | ||
| 1273 | struct device_node *np = pdev->dev.of_node; | 1270 | struct device_node *np = pdev->dev.of_node; |
| 1274 | struct fsl_qdma_engine *fsl_qdma = platform_get_drvdata(pdev); | 1271 | struct fsl_qdma_engine *fsl_qdma = platform_get_drvdata(pdev); |
| 1275 | 1272 | ||
| @@ -1277,12 +1274,6 @@ static void fsl_qdma_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 1277 | fsl_qdma_cleanup_vchan(&fsl_qdma->dma_dev); | 1274 | fsl_qdma_cleanup_vchan(&fsl_qdma->dma_dev); |
| 1278 | of_dma_controller_free(np); | 1275 | of_dma_controller_free(np); |
| 1279 | dma_async_device_unregister(&fsl_qdma->dma_dev); | 1276 | dma_async_device_unregister(&fsl_qdma->dma_dev); |
| 1280 | |||
| 1281 | for (i = 0; i < fsl_qdma->block_number; i++) { | ||
| 1282 | status = fsl_qdma->status[i]; | ||
| 1283 | dma_free_coherent(&pdev->dev, sizeof(struct fsl_qdma_format) * | ||
| 1284 | status->n_cq, status->cq, status->bus_addr); | ||
| 1285 | } | ||
| 1286 | } | 1277 | } |
| 1287 | 1278 | ||
| 1288 | static const struct of_device_id fsl_qdma_dt_ids[] = { | 1279 | static const struct of_device_id fsl_qdma_dt_ids[] = { |
| @@ -2404,6 +2404,11 @@ static int edma_probe(struct platform_device *pdev) · 2403 unmodified lines | |||
| 2404 | if (irq > 0) { | 2404 | if (irq > 0) { |
| 2405 | irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", | 2405 | irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", |
| 2406 | dev_name(dev)); | 2406 | dev_name(dev)); |
| 2407 | if (!irq_name) { | ||
| 2408 | ret = -ENOMEM; | ||
| 2409 | goto err_disable_pm; | ||
| 2410 | } | ||
| 2411 | |||
| 2407 | ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, | 2412 | ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, |
| 2408 | ecc); | 2413 | ecc); |
| 2409 | if (ret) { | 2414 | if (ret) { |
| @@ -2420,6 +2425,11 @@ static int edma_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 2420 | if (irq > 0) { | 2425 | if (irq > 0) { |
| 2421 | irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", | 2426 | irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", |
| 2422 | dev_name(dev)); | 2427 | dev_name(dev)); |
| 2428 | if (!irq_name) { | ||
| 2429 | ret = -ENOMEM; | ||
| 2430 | goto err_disable_pm; | ||
| 2431 | } | ||
| 2432 | |||
| 2423 | ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, | 2433 | ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, |
| 2424 | ecc); | 2434 | ecc); |
| 2425 | if (ret) { | 2435 | if (ret) { |
| @@ -3968,6 +3968,7 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc, · 3967 unmodified lines | |||
| 3968 | { | 3968 | { |
| 3969 | struct udma_chan *uc = to_udma_chan(&vc->chan); | 3969 | struct udma_chan *uc = to_udma_chan(&vc->chan); |
| 3970 | struct udma_desc *d; | 3970 | struct udma_desc *d; |
| 3971 | u8 status; | ||
| 3971 | 3972 | ||
| 3972 | if (!vd) | 3973 | if (!vd) |
| 3973 | return; | 3974 | return; |
| @@ -3977,12 +3978,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc, · 3 unmodified lines | |||
| 3977 | if (d->metadata_size) | 3978 | if (d->metadata_size) |
| 3978 | udma_fetch_epib(uc, d); | 3979 | udma_fetch_epib(uc, d); |
| 3979 | 3980 | ||
| 3980 | /* Provide residue information for the client */ | ||
| 3981 | if (result) { | 3981 | if (result) { |
| 3982 | void *desc_vaddr = udma_curr_cppi5_desc_vaddr(d, d->desc_idx); | 3982 | void *desc_vaddr = udma_curr_cppi5_desc_vaddr(d, d->desc_idx); |
| 3983 | 3983 | ||
| 3984 | if (cppi5_desc_get_type(desc_vaddr) == | 3984 | if (cppi5_desc_get_type(desc_vaddr) == |
| 3985 | CPPI5_INFO0_DESC_TYPE_VAL_HOST) { | 3985 | CPPI5_INFO0_DESC_TYPE_VAL_HOST) { |
| 3986 | /* Provide residue information for the client */ | ||
| 3986 | result->residue = d->residue - | 3987 | result->residue = d->residue - |
| 3987 | cppi5_hdesc_get_pktlen(desc_vaddr); | 3988 | cppi5_hdesc_get_pktlen(desc_vaddr); |
| 3988 | if (result->residue) | 3989 | if (result->residue) |
| @@ -3991,7 +3992,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc, · 2 unmodified lines | |||
| 3991 | result->result = DMA_TRANS_NOERROR; | 3992 | result->result = DMA_TRANS_NOERROR; |
| 3992 | } else { | 3993 | } else { |
| 3993 | result->residue = 0; | 3994 | result->residue = 0; |
| 3994 | result->result = DMA_TRANS_NOERROR; | 3995 | /* Propagate TR Response errors to the client */ |
| 3996 | status = d->hwdesc[0].tr_resp_base->status; | ||
| 3997 | if (status) | ||
| 3998 | result->result = DMA_TRANS_ABORTED; | ||
| 3999 | else | ||
| 4000 | result->result = DMA_TRANS_NOERROR; | ||
| 3995 | } | 4001 | } |
| 3996 | } | 4002 | } |
| 3997 | } | 4003 | } |
| @@ -29,8 +29,6 @@ static u32 dpll_pin_xa_id; · 28 unmodified lines | |||
| 29 | WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) | 29 | WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) |
| 30 | #define ASSERT_DPLL_NOT_REGISTERED(d) \ | 30 | #define ASSERT_DPLL_NOT_REGISTERED(d) \ |
| 31 | WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) | 31 | WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) |
| 32 | #define ASSERT_PIN_REGISTERED(p) \ | ||
| 33 | WARN_ON_ONCE(!xa_get_mark(&dpll_pin_xa, (p)->id, DPLL_REGISTERED)) | ||
| 34 | 32 | ||
| 35 | struct dpll_device_registration { | 33 | struct dpll_device_registration { |
| 36 | struct list_head list; | 34 | struct list_head list; |
| @@ -425,6 +423,53 @@ void dpll_device_unregister(struct dpll_device *dpll, · 388 unmodified lines | |||
| 425 | } | 423 | } |
| 426 | EXPORT_SYMBOL_GPL(dpll_device_unregister); | 424 | EXPORT_SYMBOL_GPL(dpll_device_unregister); |
| 427 | 425 | ||
| 426 | static void dpll_pin_prop_free(struct dpll_pin_properties *prop) | ||
| 427 | { | ||
| 428 | kfree(prop->package_label); | ||
| 429 | kfree(prop->panel_label); | ||
| 430 | kfree(prop->board_label); | ||
| 431 | kfree(prop->freq_supported); | ||
| 432 | } | ||
| 433 | |||
| 434 | static int dpll_pin_prop_dup(const struct dpll_pin_properties *src, | ||
| 435 | struct dpll_pin_properties *dst) | ||
| 436 | { | ||
| 437 | memcpy(dst, src, sizeof(*dst)); | ||
| 438 | if (src->freq_supported && src->freq_supported_num) { | ||
| 439 | size_t freq_size = src->freq_supported_num * | ||
| 440 | sizeof(*src->freq_supported); | ||
| 441 | dst->freq_supported = kmemdup(src->freq_supported, | ||
| 442 | freq_size, GFP_KERNEL); | ||
| 443 | if (!src->freq_supported) | ||
| 444 | return -ENOMEM; | ||
| 445 | } | ||
| 446 | if (src->board_label) { | ||
| 447 | dst->board_label = kstrdup(src->board_label, GFP_KERNEL); | ||
| 448 | if (!dst->board_label) | ||
| 449 | goto err_board_label; | ||
| 450 | } | ||
| 451 | if (src->panel_label) { | ||
| 452 | dst->panel_label = kstrdup(src->panel_label, GFP_KERNEL); | ||
| 453 | if (!dst->panel_label) | ||
| 454 | goto err_panel_label; | ||
| 455 | } | ||
| 456 | if (src->package_label) { | ||
| 457 | dst->package_label = kstrdup(src->package_label, GFP_KERNEL); | ||
| 458 | if (!dst->package_label) | ||
| 459 | goto err_package_label; | ||
| 460 | } | ||
| 461 | |||
| 462 | return 0; | ||
| 463 | |||
| 464 | err_package_label: | ||
| 465 | kfree(dst->panel_label); | ||
| 466 | err_panel_label: | ||
| 467 | kfree(dst->board_label); | ||
| 468 | err_board_label: | ||
| 469 | kfree(dst->freq_supported); | ||
| 470 | return -ENOMEM; | ||
| 471 | } | ||
| 472 | |||
| 428 | static struct dpll_pin * | 473 | static struct dpll_pin * |
| 429 | dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, | 474 | dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, |
| 430 | const struct dpll_pin_properties *prop) | 475 | const struct dpll_pin_properties *prop) |
| @@ -441,20 +486,24 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, · 10 unmodified lines | |||
| 441 | if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX || | 486 | if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX || |
| 442 | prop->type > DPLL_PIN_TYPE_MAX)) { | 487 | prop->type > DPLL_PIN_TYPE_MAX)) { |
| 443 | ret = -EINVAL; | 488 | ret = -EINVAL; |
| 444 | goto err; | 489 | goto err_pin_prop; |
| 445 | } | 490 | } |
| 446 | pin->prop = prop; | 491 | ret = dpll_pin_prop_dup(prop, &pin->prop); |
| 492 | if (ret) | ||
| 493 | goto err_pin_prop; | ||
| 447 | refcount_set(&pin->refcount, 1); | 494 | refcount_set(&pin->refcount, 1); |
| 448 | xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC); | 495 | xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC); |
| 449 | xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC); | 496 | xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC); |
| 450 | ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b, | 497 | ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b, |
| 451 | &dpll_pin_xa_id, GFP_KERNEL); | 498 | &dpll_pin_xa_id, GFP_KERNEL); |
| 452 | if (ret) | 499 | if (ret) |
| 453 | goto err; | 500 | goto err_xa_alloc; |
| 454 | return pin; | 501 | return pin; |
| 455 | err: | 502 | err_xa_alloc: |
| 456 | xa_destroy(&pin->dpll_refs); | 503 | xa_destroy(&pin->dpll_refs); |
| 457 | xa_destroy(&pin->parent_refs); | 504 | xa_destroy(&pin->parent_refs); |
| 505 | dpll_pin_prop_free(&pin->prop); | ||
| 506 | err_pin_prop: | ||
| 458 | kfree(pin); | 507 | kfree(pin); |
| 459 | return ERR_PTR(ret); | 508 | return ERR_PTR(ret); |
| 460 | } | 509 | } |
| @@ -514,6 +563,7 @@ void dpll_pin_put(struct dpll_pin *pin) · 53 unmodified lines | |||
| 514 | xa_destroy(&pin->dpll_refs); | 563 | xa_destroy(&pin->dpll_refs); |
| 515 | xa_destroy(&pin->parent_refs); | 564 | xa_destroy(&pin->parent_refs); |
| 516 | xa_erase(&dpll_pin_xa, pin->id); | 565 | xa_erase(&dpll_pin_xa, pin->id); |
| 566 | dpll_pin_prop_free(&pin->prop); | ||
| 517 | kfree(pin); | 567 | kfree(pin); |
| 518 | } | 568 | } |
| 519 | mutex_unlock(&dpll_lock); | 569 | mutex_unlock(&dpll_lock); |
| @@ -564,8 +614,6 @@ dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, · 44 unmodified lines | |||
| 564 | WARN_ON(!ops->state_on_dpll_get) || | 614 | WARN_ON(!ops->state_on_dpll_get) || |
| 565 | WARN_ON(!ops->direction_get)) | 615 | WARN_ON(!ops->direction_get)) |
| 566 | return -EINVAL; | 616 | return -EINVAL; |
| 567 | if (ASSERT_DPLL_REGISTERED(dpll)) | ||
| 568 | return -EINVAL; | ||
| 569 | 617 | ||
| 570 | mutex_lock(&dpll_lock); | 618 | mutex_lock(&dpll_lock); |
| 571 | if (WARN_ON(!(dpll->module == pin->module && | 619 | if (WARN_ON(!(dpll->module == pin->module && |
| @@ -636,15 +684,13 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, · 64 unmodified lines | |||
| 636 | unsigned long i, stop; | 684 | unsigned long i, stop; |
| 637 | int ret; | 685 | int ret; |
| 638 | 686 | ||
| 639 | if (WARN_ON(parent->prop->type != DPLL_PIN_TYPE_MUX)) | 687 | if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX)) |
| 640 | return -EINVAL; | 688 | return -EINVAL; |
| 641 | 689 | ||
| 642 | if (WARN_ON(!ops) || | 690 | if (WARN_ON(!ops) || |
| 643 | WARN_ON(!ops->state_on_pin_get) || | 691 | WARN_ON(!ops->state_on_pin_get) || |
| 644 | WARN_ON(!ops->direction_get)) | 692 | WARN_ON(!ops->direction_get)) |
| 645 | return -EINVAL; | 693 | return -EINVAL; |
| 646 | if (ASSERT_PIN_REGISTERED(parent)) | ||
| 647 | return -EINVAL; | ||
| 648 | 694 | ||
| 649 | mutex_lock(&dpll_lock); | 695 | mutex_lock(&dpll_lock); |
| 650 | ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv); | 696 | ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv); |
| @@ -44,7 +44,7 @@ struct dpll_device { · 43 unmodified lines | |||
| 44 | * @module: module of creator | 44 | * @module: module of creator |
| 45 | * @dpll_refs: hold referencees to dplls pin was registered with | 45 | * @dpll_refs: hold referencees to dplls pin was registered with |
| 46 | * @parent_refs: hold references to parent pins pin was registered with | 46 | * @parent_refs: hold references to parent pins pin was registered with |
| 47 | * @prop: pointer to pin properties given by registerer | 47 | * @prop: pin properties copied from the registerer |
| 48 | * @rclk_dev_name: holds name of device when pin can recover clock from it | 48 | * @rclk_dev_name: holds name of device when pin can recover clock from it |
| 49 | * @refcount: refcount | 49 | * @refcount: refcount |
| 50 | **/ | 50 | **/ |
| @@ -55,7 +55,7 @@ struct dpll_pin { · 4 unmodified lines | |||
| 55 | struct module *module; | 55 | struct module *module; |
| 56 | struct xarray dpll_refs; | 56 | struct xarray dpll_refs; |
| 57 | struct xarray parent_refs; | 57 | struct xarray parent_refs; |
| 58 | const struct dpll_pin_properties *prop; | 58 | struct dpll_pin_properties prop; |
| 59 | refcount_t refcount; | 59 | refcount_t refcount; |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| @@ -303,17 +303,17 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin, · 302 unmodified lines | |||
| 303 | if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq, | 303 | if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq, |
| 304 | DPLL_A_PIN_PAD)) | 304 | DPLL_A_PIN_PAD)) |
| 305 | return -EMSGSIZE; | 305 | return -EMSGSIZE; |
| 306 | for (fs = 0; fs < pin->prop->freq_supported_num; fs++) { | 306 | for (fs = 0; fs < pin->prop.freq_supported_num; fs++) { |
| 307 | nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED); | 307 | nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED); |
| 308 | if (!nest) | 308 | if (!nest) |
| 309 | return -EMSGSIZE; | 309 | return -EMSGSIZE; |
| 310 | freq = pin->prop->freq_supported[fs].min; | 310 | freq = pin->prop.freq_supported[fs].min; |
| 311 | if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq), | 311 | if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq), |
| 312 | &freq, DPLL_A_PIN_PAD)) { | 312 | &freq, DPLL_A_PIN_PAD)) { |
| 313 | nla_nest_cancel(msg, nest); | 313 | nla_nest_cancel(msg, nest); |
| 314 | return -EMSGSIZE; | 314 | return -EMSGSIZE; |
| 315 | } | 315 | } |
| 316 | freq = pin->prop->freq_supported[fs].max; | 316 | freq = pin->prop.freq_supported[fs].max; |
| 317 | if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq), | 317 | if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq), |
| 318 | &freq, DPLL_A_PIN_PAD)) { | 318 | &freq, DPLL_A_PIN_PAD)) { |
| 319 | nla_nest_cancel(msg, nest); | 319 | nla_nest_cancel(msg, nest); |
| @@ -329,9 +329,9 @@ static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq) · 9 unmodified lines | |||
| 329 | { | 329 | { |
| 330 | int fs; | 330 | int fs; |
| 331 | 331 | ||
| 332 | for (fs = 0; fs < pin->prop->freq_supported_num; fs++) | 332 | for (fs = 0; fs < pin->prop.freq_supported_num; fs++) |
| 333 | if (freq >= pin->prop->freq_supported[fs].min && | 333 | if (freq >= pin->prop.freq_supported[fs].min && |
| 334 | freq <= pin->prop->freq_supported[fs].max) | 334 | freq <= pin->prop.freq_supported[fs].max) |
| 335 | return true; | 335 | return true; |
| 336 | return false; | 336 | return false; |
| 337 | } | 337 | } |
| @@ -421,7 +421,7 @@ static int · 83 unmodified lines | |||
| 421 | dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin, | 421 | dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin, |
| 422 | struct netlink_ext_ack *extack) | 422 | struct netlink_ext_ack *extack) |
| 423 | { | 423 | { |
| 424 | const struct dpll_pin_properties *prop = pin->prop; | 424 | const struct dpll_pin_properties *prop = &pin->prop; |
| 425 | struct dpll_pin_ref *ref; | 425 | struct dpll_pin_ref *ref; |
| 426 | int ret; | 426 | int ret; |
| 427 | 427 | ||
| @@ -553,6 +553,24 @@ __dpll_device_change_ntf(struct dpll_device *dpll) · 125 unmodified lines | |||
| 553 | return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll); | 553 | return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll); |
| 554 | } | 554 | } |
| 555 | 555 | ||
| 556 | static bool dpll_pin_available(struct dpll_pin *pin) | ||
| 557 | { | ||
| 558 | struct dpll_pin_ref *par_ref; | ||
| 559 | unsigned long i; | ||
| 560 | |||
| 561 | if (!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED)) | ||
| 562 | return false; | ||
| 563 | xa_for_each(&pin->parent_refs, i, par_ref) | ||
| 564 | if (xa_get_mark(&dpll_pin_xa, par_ref->pin->id, | ||
| 565 | DPLL_REGISTERED)) | ||
| 566 | return true; | ||
| 567 | xa_for_each(&pin->dpll_refs, i, par_ref) | ||
| 568 | if (xa_get_mark(&dpll_device_xa, par_ref->dpll->id, | ||
| 569 | DPLL_REGISTERED)) | ||
| 570 | return true; | ||
| 571 | return false; | ||
| 572 | } | ||
| 573 | |||
| 556 | /** | 574 | /** |
| 557 | * dpll_device_change_ntf - notify that the dpll device has been changed | 575 | * dpll_device_change_ntf - notify that the dpll device has been changed |
| 558 | * @dpll: registered dpll pointer | 576 | * @dpll: registered dpll pointer |
| @@ -579,7 +597,7 @@ dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin) · 20 unmodified lines | |||
| 579 | int ret = -ENOMEM; | 597 | int ret = -ENOMEM; |
| 580 | void *hdr; | 598 | void *hdr; |
| 581 | 599 | ||
| 582 | if (WARN_ON(!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED))) | 600 | if (!dpll_pin_available(pin)) |
| 583 | return -ENODEV; | 601 | return -ENODEV; |
| 584 | 602 | ||
| 585 | msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 603 | msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); |
| @@ -717,7 +735,7 @@ dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx, · 131 unmodified lines | |||
| 717 | int ret; | 735 | int ret; |
| 718 | 736 | ||
| 719 | if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & | 737 | if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & |
| 720 | pin->prop->capabilities)) { | 738 | pin->prop.capabilities)) { |
| 721 | NL_SET_ERR_MSG(extack, "state changing is not allowed"); | 739 | NL_SET_ERR_MSG(extack, "state changing is not allowed"); |
| 722 | return -EOPNOTSUPP; | 740 | return -EOPNOTSUPP; |
| 723 | } | 741 | } |
| @@ -753,7 +771,7 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, · 29 unmodified lines | |||
| 753 | int ret; | 771 | int ret; |
| 754 | 772 | ||
| 755 | if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & | 773 | if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & |
| 756 | pin->prop->capabilities)) { | 774 | pin->prop.capabilities)) { |
| 757 | NL_SET_ERR_MSG(extack, "state changing is not allowed"); | 775 | NL_SET_ERR_MSG(extack, "state changing is not allowed"); |
| 758 | return -EOPNOTSUPP; | 776 | return -EOPNOTSUPP; |
| 759 | } | 777 | } |
| @@ -780,7 +798,7 @@ dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin, · 20 unmodified lines | |||
| 780 | int ret; | 798 | int ret; |
| 781 | 799 | ||
| 782 | if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE & | 800 | if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE & |
| 783 | pin->prop->capabilities)) { | 801 | pin->prop.capabilities)) { |
| 784 | NL_SET_ERR_MSG(extack, "prio changing is not allowed"); | 802 | NL_SET_ERR_MSG(extack, "prio changing is not allowed"); |
| 785 | return -EOPNOTSUPP; | 803 | return -EOPNOTSUPP; |
| 786 | } | 804 | } |
| @@ -808,7 +826,7 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll, · 21 unmodified lines | |||
| 808 | int ret; | 826 | int ret; |
| 809 | 827 | ||
| 810 | if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE & | 828 | if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE & |
| 811 | pin->prop->capabilities)) { | 829 | pin->prop.capabilities)) { |
| 812 | NL_SET_ERR_MSG(extack, "direction changing is not allowed"); | 830 | NL_SET_ERR_MSG(extack, "direction changing is not allowed"); |
| 813 | return -EOPNOTSUPP; | 831 | return -EOPNOTSUPP; |
| 814 | } | 832 | } |
| @@ -838,8 +856,8 @@ dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr, · 23 unmodified lines | |||
| 838 | int ret; | 856 | int ret; |
| 839 | 857 | ||
| 840 | phase_adj = nla_get_s32(phase_adj_attr); | 858 | phase_adj = nla_get_s32(phase_adj_attr); |
| 841 | if (phase_adj > pin->prop->phase_range.max || | 859 | if (phase_adj > pin->prop.phase_range.max || |
| 842 | phase_adj < pin->prop->phase_range.min) { | 860 | phase_adj < pin->prop.phase_range.min) { |
| 843 | NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr, | 861 | NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr, |
| 844 | "phase adjust value not supported"); | 862 | "phase adjust value not supported"); |
| 845 | return -EINVAL; | 863 | return -EINVAL; |
| @@ -1023,7 +1041,7 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr, · 177 unmodified lines | |||
| 1023 | unsigned long i; | 1041 | unsigned long i; |
| 1024 | 1042 | ||
| 1025 | xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) { | 1043 | xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) { |
| 1026 | prop = pin->prop; | 1044 | prop = &pin->prop; |
| 1027 | cid_match = clock_id ? pin->clock_id == clock_id : true; | 1045 | cid_match = clock_id ? pin->clock_id == clock_id : true; |
| 1028 | mod_match = mod_name_attr && module_name(pin->module) ? | 1046 | mod_match = mod_name_attr && module_name(pin->module) ? |
| 1029 | !nla_strcmp(mod_name_attr, | 1047 | !nla_strcmp(mod_name_attr, |
| @@ -1130,6 +1148,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info) · 100 unmodified lines | |||
| 1130 | } | 1148 | } |
| 1131 | pin = dpll_pin_find_from_nlattr(info); | 1149 | pin = dpll_pin_find_from_nlattr(info); |
| 1132 | if (!IS_ERR(pin)) { | 1150 | if (!IS_ERR(pin)) { |
| 1151 | if (!dpll_pin_available(pin)) { | ||
| 1152 | nlmsg_free(msg); | ||
| 1153 | return -ENODEV; | ||
| 1154 | } | ||
| 1133 | ret = dpll_msg_add_pin_handle(msg, pin); | 1155 | ret = dpll_msg_add_pin_handle(msg, pin); |
| 1134 | if (ret) { | 1156 | if (ret) { |
| 1135 | nlmsg_free(msg); | 1157 | nlmsg_free(msg); |
| @@ -1179,6 +1201,8 @@ int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) · 43 unmodified lines | |||
| 1179 | 1201 | ||
| 1180 | xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED, | 1202 | xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED, |
| 1181 | ctx->idx) { | 1203 | ctx->idx) { |
| 1204 | if (!dpll_pin_available(pin)) | ||
| 1205 | continue; | ||
| 1182 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, | 1206 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, |
| 1183 | cb->nlh->nlmsg_seq, | 1207 | cb->nlh->nlmsg_seq, |
| 1184 | &dpll_nl_family, NLM_F_MULTI, | 1208 | &dpll_nl_family, NLM_F_MULTI, |
| @@ -1441,7 +1465,8 @@ int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb, · 256 unmodified lines | |||
| 1441 | } | 1465 | } |
| 1442 | info->user_ptr[0] = xa_load(&dpll_pin_xa, | 1466 | info->user_ptr[0] = xa_load(&dpll_pin_xa, |
| 1443 | nla_get_u32(info->attrs[DPLL_A_PIN_ID])); | 1467 | nla_get_u32(info->attrs[DPLL_A_PIN_ID])); |
| 1444 | if (!info->user_ptr[0]) { | 1468 | if (!info->user_ptr[0] || |
| 1469 | !dpll_pin_available(info->user_ptr[0])) { | ||
| 1445 | NL_SET_ERR_MSG(info->extack, "pin not found"); | 1470 | NL_SET_ERR_MSG(info->extack, "pin not found"); |
| 1446 | ret = -ENODEV; | 1471 | ret = -ENODEV; |
| 1447 | goto unlock_dev; | 1472 | goto unlock_dev; |
| @@ -429,7 +429,23 @@ static void bm_work(struct work_struct *work) · 428 unmodified lines | |||
| 429 | */ | 429 | */ |
| 430 | card->bm_generation = generation; | 430 | card->bm_generation = generation; |
| 431 | 431 | ||
| 432 | if (root_device == NULL) { | 432 | if (card->gap_count == 0) { |
| 433 | /* | ||
| 434 | * If self IDs have inconsistent gap counts, do a | ||
| 435 | * bus reset ASAP. The config rom read might never | ||
| 436 | * complete, so don't wait for it. However, still | ||
| 437 | * send a PHY configuration packet prior to the | ||
| 438 | * bus reset. The PHY configuration packet might | ||
| 439 | * fail, but 1394-2008 8.4.5.2 explicitly permits | ||
| 440 | * it in this case, so it should be safe to try. | ||
| 441 | */ | ||
| 442 | new_root_id = local_id; | ||
| 443 | /* | ||
| 444 | * We must always send a bus reset if the gap count | ||
| 445 | * is inconsistent, so bypass the 5-reset limit. | ||
| 446 | */ | ||
| 447 | card->bm_retries = 0; | ||
| 448 | } else if (root_device == NULL) { | ||
| 433 | /* | 449 | /* |
| 434 | * Either link_on is false, or we failed to read the | 450 | * Either link_on is false, or we failed to read the |
| 435 | * config rom. In either case, pick another root. | 451 | * config rom. In either case, pick another root. |
| @@ -118,10 +118,9 @@ static int textual_leaf_to_string(const u32 *block, char *buf, size_t size) · 117 unmodified lines | |||
| 118 | * @buf: where to put the string | 118 | * @buf: where to put the string |
| 119 | * @size: size of @buf, in bytes | 119 | * @size: size of @buf, in bytes |
| 120 | * | 120 | * |
| 121 | * The string is taken from a minimal ASCII text descriptor leaf after | 121 | * The string is taken from a minimal ASCII text descriptor leaf just after the entry with the |
| 122 | * the immediate entry with @key. The string is zero-terminated. | 122 | * @key. The string is zero-terminated. An overlong string is silently truncated such that it |
| 123 | * An overlong string is silently truncated such that it and the | 123 | * and the zero byte fit into @size. |
| 124 | * zero byte fit into @size. | ||
| 125 | * | 124 | * |
| 126 | * Returns strlen(buf) or a negative error code. | 125 | * Returns strlen(buf) or a negative error code. |
| 127 | */ | 126 | */ |
| @@ -368,8 +367,17 @@ static ssize_t show_text_leaf(struct device *dev, · 240 unmodified lines | |||
| 368 | for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) { | 367 | for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) { |
| 369 | int result = fw_csr_string(directories[i], attr->key, buf, bufsize); | 368 | int result = fw_csr_string(directories[i], attr->key, buf, bufsize); |
| 370 | // Detected. | 369 | // Detected. |
| 371 | if (result >= 0) | 370 | if (result >= 0) { |
| 372 | ret = result; | 371 | ret = result; |
| 372 | } else if (i == 0 && attr->key == CSR_VENDOR) { | ||
| 373 | // Sony DVMC-DA1 has configuration ROM such that the descriptor leaf entry | ||
| 374 | // in the root directory follows to the directory entry for vendor ID | ||
| 375 | // instead of the immediate value for vendor ID. | ||
| 376 | result = fw_csr_string(directories[i], CSR_DIRECTORY | attr->key, buf, | ||
| 377 | bufsize); | ||
| 378 | if (result >= 0) | ||
| 379 | ret = result; | ||
| 380 | } | ||
| 373 | } | 381 | } |
| 374 | 382 | ||
| 375 | if (ret >= 0) { | 383 | if (ret >= 0) { |
| @@ -107,12 +107,12 @@ struct ffa_drv_info { · 106 unmodified lines | |||
| 107 | struct work_struct notif_pcpu_work; | 107 | struct work_struct notif_pcpu_work; |
| 108 | struct work_struct irq_work; | 108 | struct work_struct irq_work; |
| 109 | struct xarray partition_info; | 109 | struct xarray partition_info; |
| 110 | unsigned int partition_count; | ||
| 111 | DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS)); | 110 | DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS)); |
| 112 | struct mutex notify_lock; /* lock to protect notifier hashtable */ | 111 | struct mutex notify_lock; /* lock to protect notifier hashtable */ |
| 113 | }; | 112 | }; |
| 114 | 113 | ||
| 115 | static struct ffa_drv_info *drv_info; | 114 | static struct ffa_drv_info *drv_info; |
| 115 | static void ffa_partitions_cleanup(void); | ||
| 116 | 116 | ||
| 117 | /* | 117 | /* |
| 118 | * The driver must be able to support all the versions from the earliest | 118 | * The driver must be able to support all the versions from the earliest |
| @@ -733,6 +733,11 @@ static void __do_sched_recv_cb(u16 part_id, u16 vcpu, bool is_per_vcpu) · 614 unmodified lines | |||
| 733 | void *cb_data; | 733 | void *cb_data; |
| 734 | 734 | ||
| 735 | partition = xa_load(&drv_info->partition_info, part_id); | 735 | partition = xa_load(&drv_info->partition_info, part_id); |
| 736 | if (!partition) { | ||
| 737 | pr_err("%s: Invalid partition ID 0x%x\n", __func__, part_id); | ||
| 738 | return; | ||
| 739 | } | ||
| 740 | |||
| 736 | read_lock(&partition->rw_lock); | 741 | read_lock(&partition->rw_lock); |
| 737 | callback = partition->callback; | 742 | callback = partition->callback; |
| 738 | cb_data = partition->cb_data; | 743 | cb_data = partition->cb_data; |
| @@ -915,6 +920,11 @@ static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback, · 176 unmodified lines | |||
| 915 | return -EOPNOTSUPP; | 920 | return -EOPNOTSUPP; |
| 916 | 921 | ||
| 917 | partition = xa_load(&drv_info->partition_info, part_id); | 922 | partition = xa_load(&drv_info->partition_info, part_id); |
| 923 | if (!partition) { | ||
| 924 | pr_err("%s: Invalid partition ID 0x%x\n", __func__, part_id); | ||
| 925 | return -EINVAL; | ||
| 926 | } | ||
| 927 | |||
| 918 | write_lock(&partition->rw_lock); | 928 | write_lock(&partition->rw_lock); |
| 919 | 929 | ||
| 920 | cb_valid = !!partition->callback; | 930 | cb_valid = !!partition->callback; |
| @@ -1186,9 +1196,9 @@ void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid) · 265 unmodified lines | |||
| 1186 | kfree(pbuf); | 1196 | kfree(pbuf); |
| 1187 | } | 1197 | } |
| 1188 | 1198 | ||
| 1189 | static void ffa_setup_partitions(void) | 1199 | static int ffa_setup_partitions(void) |
| 1190 | { | 1200 | { |
| 1191 | int count, idx; | 1201 | int count, idx, ret; |
| 1192 | uuid_t uuid; | 1202 | uuid_t uuid; |
| 1193 | struct ffa_device *ffa_dev; | 1203 | struct ffa_device *ffa_dev; |
| 1194 | struct ffa_dev_part_info *info; | 1204 | struct ffa_dev_part_info *info; |
| @@ -1197,7 +1207,7 @@ static void ffa_setup_partitions(void) · 2 unmodified lines | |||
| 1197 | count = ffa_partition_probe(&uuid_null, &pbuf); | 1207 | count = ffa_partition_probe(&uuid_null, &pbuf); |
| 1198 | if (count <= 0) { | 1208 | if (count <= 0) { |
| 1199 | pr_info("%s: No partitions found, error %d\n", __func__, count); | 1209 | pr_info("%s: No partitions found, error %d\n", __func__, count); |
| 1200 | return; | 1210 | return -EINVAL; |
| 1201 | } | 1211 | } |
| 1202 | 1212 | ||
| 1203 | xa_init(&drv_info->partition_info); | 1213 | xa_init(&drv_info->partition_info); |
| @@ -1226,40 +1236,53 @@ static void ffa_setup_partitions(void) · 22 unmodified lines | |||
| 1226 | ffa_device_unregister(ffa_dev); | 1236 | ffa_device_unregister(ffa_dev); |
| 1227 | continue; | 1237 | continue; |
| 1228 | } | 1238 | } |
| 1229 | xa_store(&drv_info->partition_info, tpbuf->id, info, GFP_KERNEL); | 1239 | rwlock_init(&info->rw_lock); |
| 1240 | ret = xa_insert(&drv_info->partition_info, tpbuf->id, | ||
| 1241 | info, GFP_KERNEL); | ||
| 1242 | if (ret) { | ||
| 1243 | pr_err("%s: failed to save partition ID 0x%x - ret:%d\n", | ||
| 1244 | __func__, tpbuf->id, ret); | ||
| 1245 | ffa_device_unregister(ffa_dev); | ||
| 1246 | kfree(info); | ||
| 1247 | } | ||
| 1230 | } | 1248 | } |
| 1231 | drv_info->partition_count = count; | ||
| 1232 | 1249 | ||
| 1233 | kfree(pbuf); | 1250 | kfree(pbuf); |
| 1234 | 1251 | ||
| 1235 | /* Allocate for the host */ | 1252 | /* Allocate for the host */ |
| 1236 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1253 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
| 1237 | if (!info) | 1254 | if (!info) { |
| 1238 | return; | 1255 | pr_err("%s: failed to alloc Host partition ID 0x%x. Abort.\n", |
| 1239 | xa_store(&drv_info->partition_info, drv_info->vm_id, info, GFP_KERNEL); | 1256 | __func__, drv_info->vm_id); |
| 1240 | drv_info->partition_count++; | 1257 | /* Already registered devices are freed on bus_exit */ |
| 1258 | ffa_partitions_cleanup(); | ||
| 1259 | return -ENOMEM; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | rwlock_init(&info->rw_lock); | ||
| 1263 | ret = xa_insert(&drv_info->partition_info, drv_info->vm_id, | ||
| 1264 | info, GFP_KERNEL); | ||
| 1265 | if (ret) { | ||
| 1266 | pr_err("%s: failed to save Host partition ID 0x%x - ret:%d. Abort.\n", | ||
| 1267 | __func__, drv_info->vm_id, ret); | ||
| 1268 | kfree(info); | ||
| 1269 | /* Already registered devices are freed on bus_exit */ | ||
| 1270 | ffa_partitions_cleanup(); | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | return ret; | ||
| 1241 | } | 1274 | } |
| 1242 | 1275 | ||
| 1243 | static void ffa_partitions_cleanup(void) | 1276 | static void ffa_partitions_cleanup(void) |
| 1244 | { | 1277 | { |
| 1245 | struct ffa_dev_part_info **info; | 1278 | struct ffa_dev_part_info *info; |
| 1246 | int idx, count = drv_info->partition_count; | 1279 | unsigned long idx; |
| 1247 | |||
| 1248 | if (!count) | ||
| 1249 | return; | ||
| 1250 | |||
| 1251 | info = kcalloc(count, sizeof(*info), GFP_KERNEL); | ||
| 1252 | if (!info) | ||
| 1253 | return; | ||
| 1254 | |||
| 1255 | xa_extract(&drv_info->partition_info, (void **)info, 0, VM_ID_MASK, | ||
| 1256 | count, XA_PRESENT); | ||
| 1257 | 1280 | ||
| 1258 | for (idx = 0; idx < count; idx++) | 1281 | xa_for_each(&drv_info->partition_info, idx, info) { |
| 1259 | kfree(info[idx]); | 1282 | xa_erase(&drv_info->partition_info, idx); |
| 1260 | kfree(info); | 1283 | kfree(info); |
| 1284 | } | ||
| 1261 | 1285 | ||
| 1262 | drv_info->partition_count = 0; | ||
| 1263 | xa_destroy(&drv_info->partition_info); | 1286 | xa_destroy(&drv_info->partition_info); |
| 1264 | } | 1287 | } |
| 1265 | 1288 | ||
| @@ -1508,7 +1531,11 @@ static int __init ffa_init(void) · 242 unmodified lines | |||
| 1508 | 1531 | ||
| 1509 | ffa_notifications_setup(); | 1532 | ffa_notifications_setup(); |
| 1510 | 1533 | ||
| 1511 | ffa_setup_partitions(); | 1534 | ret = ffa_setup_partitions(); |
| 1535 | if (ret) { | ||
| 1536 | pr_err("failed to setup partitions\n"); | ||
| 1537 | goto cleanup_notifs; | ||
| 1538 | } | ||
| 1512 | 1539 | ||
| 1513 | ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle, | 1540 | ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle, |
| 1514 | drv_info, true); | 1541 | drv_info, true); |
| @@ -1516,6 +1543,9 @@ static int __init ffa_init(void) · 1 unmodified line | |||
| 1516 | pr_info("Failed to register driver sched callback %d\n", ret); | 1543 | pr_info("Failed to register driver sched callback %d\n", ret); |
| 1517 | 1544 | ||
| 1518 | return 0; | 1545 | return 0; |
| 1546 | |||
| 1547 | cleanup_notifs: | ||
| 1548 | ffa_notifications_cleanup(); | ||
| 1519 | free_pages: | 1549 | free_pages: |
| 1520 | if (drv_info->tx_buffer) | 1550 | if (drv_info->tx_buffer) |
| 1521 | free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); | 1551 | free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); |
| @@ -1535,7 +1565,6 @@ static void __exit ffa_exit(void) · 13 unmodified lines | |||
| 1535 | ffa_rxtx_unmap(drv_info->vm_id); | 1565 | ffa_rxtx_unmap(drv_info->vm_id); |
| 1536 | free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); | 1566 | free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); |
| 1537 | free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); | 1567 | free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); |
| 1538 | xa_destroy(&drv_info->partition_info); | ||
| 1539 | kfree(drv_info); | 1568 | kfree(drv_info); |
| 1540 | arm_ffa_bus_exit(); | 1569 | arm_ffa_bus_exit(); |
| 1541 | } | 1570 | } |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include "notify.h" | 13 | #include "notify.h" |
| 14 | 14 | ||
| 15 | /* Updated only after ALL the mandatory features for that version are merged */ | 15 | /* Updated only after ALL the mandatory features for that version are merged */ |
| 16 | #define SCMI_PROTOCOL_SUPPORTED_VERSION 0x20001 | 16 | #define SCMI_PROTOCOL_SUPPORTED_VERSION 0x20000 |
| 17 | 17 | ||
| 18 | enum scmi_clock_protocol_cmd { | 18 | enum scmi_clock_protocol_cmd { |
| 19 | CLOCK_ATTRIBUTES = 0x3, | 19 | CLOCK_ATTRIBUTES = 0x3, |
| @@ -954,8 +954,7 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph) · 934 unmodified lines | |||
| 954 | scmi_clock_describe_rates_get(ph, clkid, clk); | 954 | scmi_clock_describe_rates_get(ph, clkid, clk); |
| 955 | } | 955 | } |
| 956 | 956 | ||
| 957 | if (PROTOCOL_REV_MAJOR(version) >= 0x2 && | 957 | if (PROTOCOL_REV_MAJOR(version) >= 0x3) { |
| 958 | PROTOCOL_REV_MINOR(version) >= 0x1) { | ||
| 959 | cinfo->clock_config_set = scmi_clock_config_set_v2; | 958 | cinfo->clock_config_set = scmi_clock_config_set_v2; |
| 960 | cinfo->clock_config_get = scmi_clock_config_get_v2; | 959 | cinfo->clock_config_get = scmi_clock_config_get_v2; |
| 961 | } else { | 960 | } else { |
| @@ -314,6 +314,7 @@ void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, · 313 unmodified lines | |||
| 314 | void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem); | 314 | void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem); |
| 315 | bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, | 315 | bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, |
| 316 | struct scmi_xfer *xfer); | 316 | struct scmi_xfer *xfer); |
| 317 | bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); | ||
| 317 | 318 | ||
| 318 | /* declarations for message passing transports */ | 319 | /* declarations for message passing transports */ |
| 319 | struct scmi_msg_payld; | 320 | struct scmi_msg_payld; |
| @@ -45,6 +45,20 @@ static void rx_callback(struct mbox_client *cl, void *m) · 44 unmodified lines | |||
| 45 | { | 45 | { |
| 46 | struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl); | 46 | struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl); |
| 47 | 47 | ||
| 48 | /* | ||
| 49 | * An A2P IRQ is NOT valid when received while the platform still has | ||
| 50 | * the ownership of the channel, because the platform at first releases | ||
| 51 | * the SMT channel and then sends the completion interrupt. | ||
| 52 | * | ||
| 53 | * This addresses a possible race condition in which a spurious IRQ from | ||
| 54 | * a previous timed-out reply which arrived late could be wrongly | ||
| 55 | * associated with the next pending transaction. | ||
| 56 | */ | ||
| 57 | if (cl->knows_txdone && !shmem_channel_free(smbox->shmem)) { | ||
| 58 | dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n"); | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | |||
| 48 | scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); | 62 | scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); |
| 49 | } | 63 | } |
| 50 | 64 | ||
| @@ -350,8 +350,8 @@ process_response_opp(struct scmi_opp *opp, unsigned int loop_idx, · 349 unmodified lines | |||
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static inline void | 352 | static inline void |
| 353 | process_response_opp_v4(struct perf_dom_info *dom, struct scmi_opp *opp, | 353 | process_response_opp_v4(struct device *dev, struct perf_dom_info *dom, |
| 354 | unsigned int loop_idx, | 354 | struct scmi_opp *opp, unsigned int loop_idx, |
| 355 | const struct scmi_msg_resp_perf_describe_levels_v4 *r) | 355 | const struct scmi_msg_resp_perf_describe_levels_v4 *r) |
| 356 | { | 356 | { |
| 357 | opp->perf = le32_to_cpu(r->opp[loop_idx].perf_val); | 357 | opp->perf = le32_to_cpu(r->opp[loop_idx].perf_val); |
| @@ -362,10 +362,23 @@ process_response_opp_v4(struct perf_dom_info *dom, struct scmi_opp *opp, · 4 unmodified lines | |||
| 362 | /* Note that PERF v4 reports always five 32-bit words */ | 362 | /* Note that PERF v4 reports always five 32-bit words */ |
| 363 | opp->indicative_freq = le32_to_cpu(r->opp[loop_idx].indicative_freq); | 363 | opp->indicative_freq = le32_to_cpu(r->opp[loop_idx].indicative_freq); |
| 364 | if (dom->level_indexing_mode) { | 364 | if (dom->level_indexing_mode) { |
| 365 | int ret; | ||
| 366 | |||
| 365 | opp->level_index = le32_to_cpu(r->opp[loop_idx].level_index); | 367 | opp->level_index = le32_to_cpu(r->opp[loop_idx].level_index); |
| 366 | 368 | ||
| 367 | xa_store(&dom->opps_by_idx, opp->level_index, opp, GFP_KERNEL); | 369 | ret = xa_insert(&dom->opps_by_idx, opp->level_index, opp, |
| 368 | xa_store(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL); | 370 | GFP_KERNEL); |
| 371 | if (ret) | ||
| 372 | dev_warn(dev, | ||
| 373 | "Failed to add opps_by_idx at %d - ret:%d\n", | ||
| 374 | opp->level_index, ret); | ||
| 375 | |||
| 376 | ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL); | ||
| 377 | if (ret) | ||
| 378 | dev_warn(dev, | ||
| 379 | "Failed to add opps_by_lvl at %d - ret:%d\n", | ||
| 380 | opp->perf, ret); | ||
| 381 | |||
| 369 | hash_add(dom->opps_by_freq, &opp->hash, opp->indicative_freq); | 382 | hash_add(dom->opps_by_freq, &opp->hash, opp->indicative_freq); |
| 370 | } | 383 | } |
| 371 | } | 384 | } |
| @@ -382,7 +395,7 @@ iter_perf_levels_process_response(const struct scmi_protocol_handle *ph, · 10 unmodified lines | |||
| 382 | if (PROTOCOL_REV_MAJOR(p->version) <= 0x3) | 395 | if (PROTOCOL_REV_MAJOR(p->version) <= 0x3) |
| 383 | process_response_opp(opp, st->loop_idx, response); | 396 | process_response_opp(opp, st->loop_idx, response); |
| 384 | else | 397 | else |
| 385 | process_response_opp_v4(p->perf_dom, opp, st->loop_idx, | 398 | process_response_opp_v4(ph->dev, p->perf_dom, opp, st->loop_idx, |
| 386 | response); | 399 | response); |
| 387 | p->perf_dom->opp_count++; | 400 | p->perf_dom->opp_count++; |
| 388 | 401 | ||
| @@ -1111,7 +1111,6 @@ static int scmi_raw_mode_setup(struct scmi_raw_mode_info *raw, · 1110 unmodified lines | |||
| 1111 | int i; | 1111 | int i; |
| 1112 | 1112 | ||
| 1113 | for (i = 0; i < num_chans; i++) { | 1113 | for (i = 0; i < num_chans; i++) { |
| 1114 | void *xret; | ||
| 1115 | struct scmi_raw_queue *q; | 1114 | struct scmi_raw_queue *q; |
| 1116 | 1115 | ||
| 1117 | q = scmi_raw_queue_init(raw); | 1116 | q = scmi_raw_queue_init(raw); |
| @@ -1120,13 +1119,12 @@ static int scmi_raw_mode_setup(struct scmi_raw_mode_info *raw, · 2 unmodified lines | |||
| 1120 | goto err_xa; | 1119 | goto err_xa; |
| 1121 | } | 1120 | } |
| 1122 | 1121 | ||
| 1123 | xret = xa_store(&raw->chans_q, channels[i], q, | 1122 | ret = xa_insert(&raw->chans_q, channels[i], q, |
| 1124 | GFP_KERNEL); | 1123 | GFP_KERNEL); |
| 1125 | if (xa_err(xret)) { | 1124 | if (ret) { |
| 1126 | dev_err(dev, | 1125 | dev_err(dev, |
| 1127 | "Fail to allocate Raw queue 0x%02X\n", | 1126 | "Fail to allocate Raw queue 0x%02X\n", |
| 1128 | channels[i]); | 1127 | channels[i]); |
| 1129 | ret = xa_err(xret); | ||
| 1130 | goto err_xa; | 1128 | goto err_xa; |
| 1131 | } | 1129 | } |
| 1132 | } | 1130 | } |
| @@ -1322,6 +1320,12 @@ void scmi_raw_message_report(void *r, struct scmi_xfer *xfer, · 189 unmodified lines | |||
| 1322 | dev = raw->handle->dev; | 1320 | dev = raw->handle->dev; |
| 1323 | q = scmi_raw_queue_select(raw, idx, | 1321 | q = scmi_raw_queue_select(raw, idx, |
| 1324 | SCMI_XFER_IS_CHAN_SET(xfer) ? chan_id : 0); | 1322 | SCMI_XFER_IS_CHAN_SET(xfer) ? chan_id : 0); |
| 1323 | if (!q) { | ||
| 1324 | dev_warn(dev, | ||
| 1325 | "RAW[%d] - NO queue for chan 0x%X. Dropping report.\n", | ||
| 1326 | idx, chan_id); | ||
| 1327 | return; | ||
| 1328 | } | ||
| 1325 | 1329 | ||
| 1326 | /* | 1330 | /* |
| 1327 | * Grab the msg_q_lock upfront to avoid a possible race between | 1331 | * Grab the msg_q_lock upfront to avoid a possible race between |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <linux/processor.h> | 10 | #include <linux/processor.h> |
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | 12 | ||
| 13 | #include <asm-generic/bug.h> | 13 | #include <linux/bug.h> |
| 14 | 14 | ||
| 15 | #include "common.h" | 15 | #include "common.h" |
| 16 | 16 | ||
| @@ -122,3 +122,9 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, · 105 unmodified lines | |||
| 122 | (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR | | 122 | (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR | |
| 123 | SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); | 123 | SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); |
| 124 | } | 124 | } |
| 125 | |||
| 126 | bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem) | ||
| 127 | { | ||
| 128 | return (ioread32(&shmem->channel_status) & | ||
| 129 | SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); | ||
| 130 | } | ||
| @@ -107,7 +107,7 @@ static int __init arm_enable_runtime_services(void) · 106 unmodified lines | |||
| 107 | efi_memory_desc_t *md; | 107 | efi_memory_desc_t *md; |
| 108 | 108 | ||
| 109 | for_each_efi_memory_desc(md) { | 109 | for_each_efi_memory_desc(md) { |
| 110 | int md_size = md->num_pages << EFI_PAGE_SHIFT; | 110 | u64 md_size = md->num_pages << EFI_PAGE_SHIFT; |
| 111 | struct resource *res; | 111 | struct resource *res; |
| 112 | 112 | ||
| 113 | if (!(md->attribute & EFI_MEMORY_SP)) | 113 | if (!(md->attribute & EFI_MEMORY_SP)) |
| @@ -523,6 +523,17 @@ static void cper_print_tstamp(const char *pfx, · 522 unmodified lines | |||
| 523 | } | 523 | } |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | struct ignore_section { | ||
| 527 | guid_t guid; | ||
| 528 | const char *name; | ||
| 529 | }; | ||
| 530 | |||
| 531 | static const struct ignore_section ignore_sections[] = { | ||
| 532 | { .guid = CPER_SEC_CXL_GEN_MEDIA_GUID, .name = "CXL General Media Event" }, | ||
| 533 | { .guid = CPER_SEC_CXL_DRAM_GUID, .name = "CXL DRAM Event" }, | ||
| 534 | { .guid = CPER_SEC_CXL_MEM_MODULE_GUID, .name = "CXL Memory Module Event" }, | ||
| 535 | }; | ||
| 536 | |||
| 526 | static void | 537 | static void |
| 527 | cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata, | 538 | cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata, |
| 528 | int sec_no) | 539 | int sec_no) |
| @@ -543,6 +554,14 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata · 14 unmodified lines | |||
| 543 | printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text); | 554 | printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text); |
| 544 | 555 | ||
| 545 | snprintf(newpfx, sizeof(newpfx), "%s ", pfx); | 556 | snprintf(newpfx, sizeof(newpfx), "%s ", pfx); |
| 557 | |||
| 558 | for (int i = 0; i < ARRAY_SIZE(ignore_sections); i++) { | ||
| 559 | if (guid_equal(sec_type, &ignore_sections[i].guid)) { | ||
| 560 | printk("%ssection_type: %s\n", newpfx, ignore_sections[i].name); | ||
| 561 | return; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | |||
| 546 | if (guid_equal(sec_type, &CPER_SEC_PROC_GENERIC)) { | 565 | if (guid_equal(sec_type, &CPER_SEC_PROC_GENERIC)) { |
| 547 | struct cper_sec_proc_generic *proc_err = acpi_hest_get_payload(gdata); | 566 | struct cper_sec_proc_generic *proc_err = acpi_hest_get_payload(gdata); |
| 548 | 567 | ||
| @@ -143,15 +143,6 @@ static __init int is_usable_memory(efi_memory_desc_t *md) · 142 unmodified lines | |||
| 143 | case EFI_BOOT_SERVICES_DATA: | 143 | case EFI_BOOT_SERVICES_DATA: |
| 144 | case EFI_CONVENTIONAL_MEMORY: | 144 | case EFI_CONVENTIONAL_MEMORY: |
| 145 | case EFI_PERSISTENT_MEMORY: | 145 | case EFI_PERSISTENT_MEMORY: |
| 146 | /* | ||
| 147 | * Special purpose memory is 'soft reserved', which means it | ||
| 148 | * is set aside initially, but can be hotplugged back in or | ||
| 149 | * be assigned to the dax driver after boot. | ||
| 150 | */ | ||
| 151 | if (efi_soft_reserve_enabled() && | ||
| 152 | (md->attribute & EFI_MEMORY_SP)) | ||
| 153 | return false; | ||
| 154 | |||
| 155 | /* | 146 | /* |
| 156 | * According to the spec, these regions are no longer reserved | 147 | * According to the spec, these regions are no longer reserved |
| 157 | * after calling ExitBootServices(). However, we can only use | 148 | * after calling ExitBootServices(). However, we can only use |
| @@ -196,6 +187,16 @@ static __init void reserve_regions(void) · 38 unmodified lines | |||
| 196 | size = npages << PAGE_SHIFT; | 187 | size = npages << PAGE_SHIFT; |
| 197 | 188 | ||
| 198 | if (is_memory(md)) { | 189 | if (is_memory(md)) { |
| 190 | /* | ||
| 191 | * Special purpose memory is 'soft reserved', which | ||
| 192 | * means it is set aside initially. Don't add a memblock | ||
| 193 | * for it now so that it can be hotplugged back in or | ||
| 194 | * be assigned to the dax driver after boot. | ||
| 195 | */ | ||
| 196 | if (efi_soft_reserve_enabled() && | ||
| 197 | (md->attribute & EFI_MEMORY_SP)) | ||
| 198 | continue; | ||
| 199 | |||
| 199 | early_init_dt_add_memory_arch(paddr, size); | 200 | early_init_dt_add_memory_arch(paddr, size); |
| 200 | 201 | ||
| 201 | if (!is_usable_memory(md)) | 202 | if (!is_usable_memory(md)) |
| @@ -28,7 +28,7 @@ cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \ · 27 unmodified lines | |||
| 28 | -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \ | 28 | -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \ |
| 29 | -DEFI_HAVE_STRCMP -fno-builtin -fpic \ | 29 | -DEFI_HAVE_STRCMP -fno-builtin -fpic \ |
| 30 | $(call cc-option,-mno-single-pic-base) | 30 | $(call cc-option,-mno-single-pic-base) |
| 31 | cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE | 31 | cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE -mno-relax |
| 32 | cflags-$(CONFIG_LOONGARCH) += -fpie | 32 | cflags-$(CONFIG_LOONGARCH) += -fpie |
| 33 | 33 | ||
| 34 | cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt | 34 | cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt |
| @@ -143,7 +143,7 @@ STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS · 108 unmodified lines | |||
| 143 | # exist. | 143 | # exist. |
| 144 | STUBCOPY_FLAGS-$(CONFIG_RISCV) += --prefix-alloc-sections=.init \ | 144 | STUBCOPY_FLAGS-$(CONFIG_RISCV) += --prefix-alloc-sections=.init \ |
| 145 | --prefix-symbols=__efistub_ | 145 | --prefix-symbols=__efistub_ |
| 146 | STUBCOPY_RELOC-$(CONFIG_RISCV) := R_RISCV_HI20 | 146 | STUBCOPY_RELOC-$(CONFIG_RISCV) := -E R_RISCV_HI20\|R_RISCV_$(BITS)\|R_RISCV_RELAX |
| 147 | 147 | ||
| 148 | # For LoongArch, keep all the symbols in .init section and make sure that no | 148 | # For LoongArch, keep all the symbols in .init section and make sure that no |
| 149 | # absolute symbols references exist. | 149 | # absolute symbols references exist. |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | * @max: the address that the last allocated memory page shall not | 14 | * @max: the address that the last allocated memory page shall not |
| 15 | * exceed | 15 | * exceed |
| 16 | * @align: minimum alignment of the base of the allocation | 16 | * @align: minimum alignment of the base of the allocation |
| 17 | * @memory_type: the type of memory to allocate | ||
| 17 | * | 18 | * |
| 18 | * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according | 19 | * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according |
| 19 | * to @align, which should be >= EFI_ALLOC_ALIGN. The last allocated page will | 20 | * to @align, which should be >= EFI_ALLOC_ALIGN. The last allocated page will |
| @@ -956,7 +956,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out); · 955 unmodified lines | |||
| 956 | 956 | ||
| 957 | efi_status_t efi_random_alloc(unsigned long size, unsigned long align, | 957 | efi_status_t efi_random_alloc(unsigned long size, unsigned long align, |
| 958 | unsigned long *addr, unsigned long random_seed, | 958 | unsigned long *addr, unsigned long random_seed, |
| 959 | int memory_type, unsigned long alloc_limit); | 959 | int memory_type, unsigned long alloc_min, |
| 960 | unsigned long alloc_max); | ||
| 960 | 961 | ||
| 961 | efi_status_t efi_random_get_seed(void); | 962 | efi_status_t efi_random_get_seed(void); |
| 962 | 963 | ||
| @@ -119,7 +119,7 @@ efi_status_t efi_kaslr_relocate_kernel(unsigned long *image_addr, · 118 unmodified lines | |||
| 119 | */ | 119 | */ |
| 120 | status = efi_random_alloc(*reserve_size, min_kimg_align, | 120 | status = efi_random_alloc(*reserve_size, min_kimg_align, |
| 121 | reserve_addr, phys_seed, | 121 | reserve_addr, phys_seed, |
| 122 | EFI_LOADER_CODE, EFI_ALLOC_LIMIT); | 122 | EFI_LOADER_CODE, 0, EFI_ALLOC_LIMIT); |
| 123 | if (status != EFI_SUCCESS) | 123 | if (status != EFI_SUCCESS) |
| 124 | efi_warn("efi_random_alloc() failed: 0x%lx\n", status); | 124 | efi_warn("efi_random_alloc() failed: 0x%lx\n", status); |
| 125 | } else { | 125 | } else { |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | static unsigned long get_entry_num_slots(efi_memory_desc_t *md, | 17 | static unsigned long get_entry_num_slots(efi_memory_desc_t *md, |
| 18 | unsigned long size, | 18 | unsigned long size, |
| 19 | unsigned long align_shift, | 19 | unsigned long align_shift, |
| 20 | u64 alloc_limit) | 20 | u64 alloc_min, u64 alloc_max) |
| 21 | { | 21 | { |
| 22 | unsigned long align = 1UL << align_shift; | 22 | unsigned long align = 1UL << align_shift; |
| 23 | u64 first_slot, last_slot, region_end; | 23 | u64 first_slot, last_slot, region_end; |
| @@ -30,11 +30,11 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, · 6 unmodified lines | |||
| 30 | return 0; | 30 | return 0; |
| 31 | 31 | ||
| 32 | region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1, | 32 | region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1, |
| 33 | alloc_limit); | 33 | alloc_max); |
| 34 | if (region_end < size) | 34 | if (region_end < size) |
| 35 | return 0; | 35 | return 0; |
| 36 | 36 | ||
| 37 | first_slot = round_up(md->phys_addr, align); | 37 | first_slot = round_up(max(md->phys_addr, alloc_min), align); |
| 38 | last_slot = round_down(region_end - size + 1, align); | 38 | last_slot = round_down(region_end - size + 1, align); |
| 39 | 39 | ||
| 40 | if (first_slot > last_slot) | 40 | if (first_slot > last_slot) |
| @@ -56,7 +56,8 @@ efi_status_t efi_random_alloc(unsigned long size, · 15 unmodified lines | |||
| 56 | unsigned long *addr, | 56 | unsigned long *addr, |
| 57 | unsigned long random_seed, | 57 | unsigned long random_seed, |
| 58 | int memory_type, | 58 | int memory_type, |
| 59 | unsigned long alloc_limit) | 59 | unsigned long alloc_min, |
| 60 | unsigned long alloc_max) | ||
| 60 | { | 61 | { |
| 61 | unsigned long total_slots = 0, target_slot; | 62 | unsigned long total_slots = 0, target_slot; |
| 62 | unsigned long total_mirrored_slots = 0; | 63 | unsigned long total_mirrored_slots = 0; |
| @@ -78,7 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size, · 15 unmodified lines | |||
| 78 | efi_memory_desc_t *md = (void *)map->map + map_offset; | 79 | efi_memory_desc_t *md = (void *)map->map + map_offset; |
| 79 | unsigned long slots; | 80 | unsigned long slots; |
| 80 | 81 | ||
| 81 | slots = get_entry_num_slots(md, size, ilog2(align), alloc_limit); | 82 | slots = get_entry_num_slots(md, size, ilog2(align), alloc_min, |
| 83 | alloc_max); | ||
| 82 | MD_NUM_SLOTS(md) = slots; | 84 | MD_NUM_SLOTS(md) = slots; |
| 83 | total_slots += slots; | 85 | total_slots += slots; |
| 84 | if (md->attribute & EFI_MEMORY_MORE_RELIABLE) | 86 | if (md->attribute & EFI_MEMORY_MORE_RELIABLE) |
| @@ -223,8 +223,8 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params) · 222 unmodified lines | |||
| 223 | } | 223 | } |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | void efi_adjust_memory_range_protection(unsigned long start, | 226 | efi_status_t efi_adjust_memory_range_protection(unsigned long start, |
| 227 | unsigned long size) | 227 | unsigned long size) |
| 228 | { | 228 | { |
| 229 | efi_status_t status; | 229 | efi_status_t status; |
| 230 | efi_gcd_memory_space_desc_t desc; | 230 | efi_gcd_memory_space_desc_t desc; |
| @@ -236,13 +236,17 @@ void efi_adjust_memory_range_protection(unsigned long start, · 5 unmodified lines | |||
| 236 | rounded_end = roundup(start + size, EFI_PAGE_SIZE); | 236 | rounded_end = roundup(start + size, EFI_PAGE_SIZE); |
| 237 | 237 | ||
| 238 | if (memattr != NULL) { | 238 | if (memattr != NULL) { |
| 239 | efi_call_proto(memattr, clear_memory_attributes, rounded_start, | 239 | status = efi_call_proto(memattr, clear_memory_attributes, |
| 240 | rounded_end - rounded_start, EFI_MEMORY_XP); | 240 | rounded_start, |
| 241 | return; | 241 | rounded_end - rounded_start, |
| 242 | EFI_MEMORY_XP); | ||
| 243 | if (status != EFI_SUCCESS) | ||
| 244 | efi_warn("Failed to clear EFI_MEMORY_XP attribute\n"); | ||
| 245 | return status; | ||
| 242 | } | 246 | } |
| 243 | 247 | ||
| 244 | if (efi_dxe_table == NULL) | 248 | if (efi_dxe_table == NULL) |
| 245 | return; | 249 | return EFI_SUCCESS; |
| 246 | 250 | ||
| 247 | /* | 251 | /* |
| 248 | * Don't modify memory region attributes, they are | 252 | * Don't modify memory region attributes, they are |
| @@ -255,7 +259,7 @@ void efi_adjust_memory_range_protection(unsigned long start, · 6 unmodified lines | |||
| 255 | status = efi_dxe_call(get_memory_space_descriptor, start, &desc); | 259 | status = efi_dxe_call(get_memory_space_descriptor, start, &desc); |
| 256 | 260 | ||
| 257 | if (status != EFI_SUCCESS) | 261 | if (status != EFI_SUCCESS) |
| 258 | return; | 262 | break; |
| 259 | 263 | ||
| 260 | next = desc.base_address + desc.length; | 264 | next = desc.base_address + desc.length; |
| 261 | 265 | ||
| @@ -280,8 +284,10 @@ void efi_adjust_memory_range_protection(unsigned long start, · 18 unmodified lines | |||
| 280 | unprotect_start, | 284 | unprotect_start, |
| 281 | unprotect_start + unprotect_size, | 285 | unprotect_start + unprotect_size, |
| 282 | status); | 286 | status); |
| 287 | break; | ||
| 283 | } | 288 | } |
| 284 | } | 289 | } |
| 290 | return EFI_SUCCESS; | ||
| 285 | } | 291 | } |
| 286 | 292 | ||
| 287 | static void setup_unaccepted_memory(void) | 293 | static void setup_unaccepted_memory(void) |
| @@ -793,6 +799,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry) · 505 unmodified lines | |||
| 793 | 799 | ||
| 794 | status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr, | 800 | status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr, |
| 795 | seed[0], EFI_LOADER_CODE, | 801 | seed[0], EFI_LOADER_CODE, |
| 802 | LOAD_PHYSICAL_ADDR, | ||
| 796 | EFI_X86_KERNEL_ALLOC_LIMIT); | 803 | EFI_X86_KERNEL_ALLOC_LIMIT); |
| 797 | if (status != EFI_SUCCESS) | 804 | if (status != EFI_SUCCESS) |
| 798 | return status; | 805 | return status; |
| @@ -805,9 +812,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry) · 6 unmodified lines | |||
| 805 | 812 | ||
| 806 | *kernel_entry = addr + entry; | 813 | *kernel_entry = addr + entry; |
| 807 | 814 | ||
| 808 | efi_adjust_memory_range_protection(addr, kernel_total_size); | 815 | return efi_adjust_memory_range_protection(addr, kernel_total_size); |
| 809 | |||
| 810 | return EFI_SUCCESS; | ||
| 811 | } | 816 | } |
| 812 | 817 | ||
| 813 | static void __noreturn enter_kernel(unsigned long kernel_addr, | 818 | static void __noreturn enter_kernel(unsigned long kernel_addr, |
| @@ -5,8 +5,8 @@ · 4 unmodified lines | |||
| 5 | extern void trampoline_32bit_src(void *, bool); | 5 | extern void trampoline_32bit_src(void *, bool); |
| 6 | extern const u16 trampoline_ljmp_imm_offset; | 6 | extern const u16 trampoline_ljmp_imm_offset; |
| 7 | 7 | ||
| 8 | void efi_adjust_memory_range_protection(unsigned long start, | 8 | efi_status_t efi_adjust_memory_range_protection(unsigned long start, |
| 9 | unsigned long size); | 9 | unsigned long size); |
| 10 | 10 | ||
| 11 | #ifdef CONFIG_X86_64 | 11 | #ifdef CONFIG_X86_64 |
| 12 | efi_status_t efi_setup_5level_paging(void); | 12 | efi_status_t efi_setup_5level_paging(void); |
| @@ -119,7 +119,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) · 118 unmodified lines | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | status = efi_random_alloc(alloc_size, min_kimg_align, &image_base, | 121 | status = efi_random_alloc(alloc_size, min_kimg_align, &image_base, |
| 122 | seed, EFI_LOADER_CODE, EFI_ALLOC_LIMIT); | 122 | seed, EFI_LOADER_CODE, 0, EFI_ALLOC_LIMIT); |
| 123 | if (status != EFI_SUCCESS) { | 123 | if (status != EFI_SUCCESS) { |
| 124 | efi_err("Failed to allocate memory\n"); | 124 | efi_err("Failed to allocate memory\n"); |
| 125 | goto free_cmdline; | 125 | goto free_cmdline; |
| @@ -85,7 +85,7 @@ static int __init riscv_enable_runtime_services(void) · 84 unmodified lines | |||
| 85 | efi_memory_desc_t *md; | 85 | efi_memory_desc_t *md; |
| 86 | 86 | ||
| 87 | for_each_efi_memory_desc(md) { | 87 | for_each_efi_memory_desc(md) { |
| 88 | int md_size = md->num_pages << EFI_PAGE_SHIFT; | 88 | u64 md_size = md->num_pages << EFI_PAGE_SHIFT; |
| 89 | struct resource *res; | 89 | struct resource *res; |
| 90 | 90 | ||
| 91 | if (!(md->attribute & EFI_MEMORY_SP)) | 91 | if (!(md->attribute & EFI_MEMORY_SP)) |
| @@ -128,4 +128,4 @@ unlock_mutex: · 127 unmodified lines | |||
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | /* must execute after PCI subsystem for EFI quirks */ | 130 | /* must execute after PCI subsystem for EFI quirks */ |
| 131 | subsys_initcall_sync(sysfb_init); | 131 | device_initcall(sysfb_init); |
| @@ -325,20 +325,27 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type) · 324 unmodified lines | |||
| 325 | switch (flow_type) { | 325 | switch (flow_type) { |
| 326 | case IRQ_TYPE_LEVEL_HIGH: | 326 | case IRQ_TYPE_LEVEL_HIGH: |
| 327 | sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1); | 327 | sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1); |
| 328 | sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1); | ||
| 328 | break; | 329 | break; |
| 329 | case IRQ_TYPE_LEVEL_LOW: | 330 | case IRQ_TYPE_LEVEL_LOW: |
| 330 | sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0); | 331 | sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0); |
| 332 | sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1); | ||
| 331 | break; | 333 | break; |
| 332 | case IRQ_TYPE_EDGE_RISING: | 334 | case IRQ_TYPE_EDGE_RISING: |
| 333 | case IRQ_TYPE_EDGE_FALLING: | 335 | case IRQ_TYPE_EDGE_FALLING: |
| 334 | case IRQ_TYPE_EDGE_BOTH: | 336 | case IRQ_TYPE_EDGE_BOTH: |
| 335 | state = sprd_eic_get(chip, offset); | 337 | state = sprd_eic_get(chip, offset); |
| 336 | if (state) | 338 | if (state) { |
| 337 | sprd_eic_update(chip, offset, | 339 | sprd_eic_update(chip, offset, |
| 338 | SPRD_EIC_DBNC_IEV, 0); | 340 | SPRD_EIC_DBNC_IEV, 0); |
| 339 | else | 341 | sprd_eic_update(chip, offset, |
| 342 | SPRD_EIC_DBNC_IC, 1); | ||
| 343 | } else { | ||
| 340 | sprd_eic_update(chip, offset, | 344 | sprd_eic_update(chip, offset, |
| 341 | SPRD_EIC_DBNC_IEV, 1); | 345 | SPRD_EIC_DBNC_IEV, 1); |
| 346 | sprd_eic_update(chip, offset, | ||
| 347 | SPRD_EIC_DBNC_IC, 1); | ||
| 348 | } | ||
| 342 | break; | 349 | break; |
| 343 | default: | 350 | default: |
| 344 | return -ENOTSUPP; | 351 | return -ENOTSUPP; |
| @@ -350,20 +357,27 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type) · 5 unmodified lines | |||
| 350 | switch (flow_type) { | 357 | switch (flow_type) { |
| 351 | case IRQ_TYPE_LEVEL_HIGH: | 358 | case IRQ_TYPE_LEVEL_HIGH: |
| 352 | sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0); | 359 | sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0); |
| 360 | sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1); | ||
| 353 | break; | 361 | break; |
| 354 | case IRQ_TYPE_LEVEL_LOW: | 362 | case IRQ_TYPE_LEVEL_LOW: |
| 355 | sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1); | 363 | sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1); |
| 364 | sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1); | ||
| 356 | break; | 365 | break; |
| 357 | case IRQ_TYPE_EDGE_RISING: | 366 | case IRQ_TYPE_EDGE_RISING: |
| 358 | case IRQ_TYPE_EDGE_FALLING: | 367 | case IRQ_TYPE_EDGE_FALLING: |
| 359 | case IRQ_TYPE_EDGE_BOTH: | 368 | case IRQ_TYPE_EDGE_BOTH: |
| 360 | state = sprd_eic_get(chip, offset); | 369 | state = sprd_eic_get(chip, offset); |
| 361 | if (state) | 370 | if (state) { |
| 362 | sprd_eic_update(chip, offset, | 371 | sprd_eic_update(chip, offset, |
| 363 | SPRD_EIC_LATCH_INTPOL, 0); | 372 | SPRD_EIC_LATCH_INTPOL, 0); |
| 364 | else | 373 | sprd_eic_update(chip, offset, |
| 374 | SPRD_EIC_LATCH_INTCLR, 1); | ||
| 375 | } else { | ||
| 365 | sprd_eic_update(chip, offset, | 376 | sprd_eic_update(chip, offset, |
| 366 | SPRD_EIC_LATCH_INTPOL, 1); | 377 | SPRD_EIC_LATCH_INTPOL, 1); |
| 378 | sprd_eic_update(chip, offset, | ||
| 379 | SPRD_EIC_LATCH_INTCLR, 1); | ||
| 380 | } | ||
| 367 | break; | 381 | break; |
| 368 | default: | 382 | default: |
| 369 | return -ENOTSUPP; | 383 | return -ENOTSUPP; |
| @@ -377,29 +391,34 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type) · 7 unmodified lines | |||
| 377 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); | 391 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); |
| 378 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); | 392 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); |
| 379 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); | 393 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); |
| 394 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); | ||
| 380 | irq_set_handler_locked(data, handle_edge_irq); | 395 | irq_set_handler_locked(data, handle_edge_irq); |
| 381 | break; | 396 | break; |
| 382 | case IRQ_TYPE_EDGE_FALLING: | 397 | case IRQ_TYPE_EDGE_FALLING: |
| 383 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); | 398 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); |
| 384 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); | 399 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); |
| 385 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); | 400 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); |
| 401 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); | ||
| 386 | irq_set_handler_locked(data, handle_edge_irq); | 402 | irq_set_handler_locked(data, handle_edge_irq); |
| 387 | break; | 403 | break; |
| 388 | case IRQ_TYPE_EDGE_BOTH: | 404 | case IRQ_TYPE_EDGE_BOTH: |
| 389 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); | 405 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); |
| 390 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1); | 406 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1); |
| 407 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); | ||
| 391 | irq_set_handler_locked(data, handle_edge_irq); | 408 | irq_set_handler_locked(data, handle_edge_irq); |
| 392 | break; | 409 | break; |
| 393 | case IRQ_TYPE_LEVEL_HIGH: | 410 | case IRQ_TYPE_LEVEL_HIGH: |
| 394 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); | 411 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); |
| 395 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); | 412 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); |
| 396 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); | 413 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); |
| 414 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); | ||
| 397 | irq_set_handler_locked(data, handle_level_irq); | 415 | irq_set_handler_locked(data, handle_level_irq); |
| 398 | break; | 416 | break; |
| 399 | case IRQ_TYPE_LEVEL_LOW: | 417 | case IRQ_TYPE_LEVEL_LOW: |
| 400 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); | 418 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); |
| 401 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); | 419 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); |
| 402 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); | 420 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); |
| 421 | sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); | ||
| 403 | irq_set_handler_locked(data, handle_level_irq); | 422 | irq_set_handler_locked(data, handle_level_irq); |
| 404 | break; | 423 | break; |
| 405 | default: | 424 | default: |
| @@ -412,29 +431,34 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type) · 6 unmodified lines | |||
| 412 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); | 431 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); |
| 413 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); | 432 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); |
| 414 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); | 433 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); |
| 434 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); | ||
| 415 | irq_set_handler_locked(data, handle_edge_irq); | 435 | irq_set_handler_locked(data, handle_edge_irq); |
| 416 | break; | 436 | break; |
| 417 | case IRQ_TYPE_EDGE_FALLING: | 437 | case IRQ_TYPE_EDGE_FALLING: |
| 418 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); | 438 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); |
| 419 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); | 439 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); |
| 420 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); | 440 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); |
| 441 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); | ||
| 421 | irq_set_handler_locked(data, handle_edge_irq); | 442 | irq_set_handler_locked(data, handle_edge_irq); |
| 422 | break; | 443 | break; |
| 423 | case IRQ_TYPE_EDGE_BOTH: | 444 | case IRQ_TYPE_EDGE_BOTH: |
| 424 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); | 445 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); |
| 425 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1); | 446 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1); |
| 447 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); | ||
| 426 | irq_set_handler_locked(data, handle_edge_irq); | 448 | irq_set_handler_locked(data, handle_edge_irq); |
| 427 | break; | 449 | break; |
| 428 | case IRQ_TYPE_LEVEL_HIGH: | 450 | case IRQ_TYPE_LEVEL_HIGH: |
| 429 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); | 451 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); |
| 430 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); | 452 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); |
| 431 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); | 453 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); |
| 454 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); | ||
| 432 | irq_set_handler_locked(data, handle_level_irq); | 455 | irq_set_handler_locked(data, handle_level_irq); |
| 433 | break; | 456 | break; |
| 434 | case IRQ_TYPE_LEVEL_LOW: | 457 | case IRQ_TYPE_LEVEL_LOW: |
| 435 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); | 458 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); |
| 436 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); | 459 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); |
| 437 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); | 460 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); |
| 461 | sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); | ||
| 438 | irq_set_handler_locked(data, handle_level_irq); | 462 | irq_set_handler_locked(data, handle_level_irq); |
| 439 | break; | 463 | break; |
| 440 | default: | 464 | default: |
| @@ -1651,6 +1651,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { · 1650 unmodified lines | |||
| 1651 | .ignore_interrupt = "INT33FC:00@3", | 1651 | .ignore_interrupt = "INT33FC:00@3", |
| 1652 | }, | 1652 | }, |
| 1653 | }, | 1653 | }, |
| 1654 | { | ||
| 1655 | /* | ||
| 1656 | * Spurious wakeups from TP_ATTN# pin | ||
| 1657 | * Found in BIOS 0.35 | ||
| 1658 | * https://gitlab.freedesktop.org/drm/amd/-/issues/3073 | ||
| 1659 | */ | ||
| 1660 | .matches = { | ||
| 1661 | DMI_MATCH(DMI_SYS_VENDOR, "GPD"), | ||
| 1662 | DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"), | ||
| 1663 | }, | ||
| 1664 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { | ||
| 1665 | .ignore_wake = "PNP0C50:00@8", | ||
| 1666 | }, | ||
| 1667 | }, | ||
| 1654 | {} /* Terminating entry */ | 1668 | {} /* Terminating entry */ |
| 1655 | }; | 1669 | }; |
| 1656 | 1670 | ||
| @@ -1010,15 +1010,15 @@ err_remove_of_chip: · 1009 unmodified lines | |||
| 1010 | err_free_gpiochip_mask: | 1010 | err_free_gpiochip_mask: |
| 1011 | gpiochip_remove_pin_ranges(gc); | 1011 | gpiochip_remove_pin_ranges(gc); |
| 1012 | gpiochip_free_valid_mask(gc); | 1012 | gpiochip_free_valid_mask(gc); |
| 1013 | err_remove_from_list: | ||
| 1014 | spin_lock_irqsave(&gpio_lock, flags); | ||
| 1015 | list_del(&gdev->list); | ||
| 1016 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
| 1013 | if (gdev->dev.release) { | 1017 | if (gdev->dev.release) { |
| 1014 | /* release() has been registered by gpiochip_setup_dev() */ | 1018 | /* release() has been registered by gpiochip_setup_dev() */ |
| 1015 | gpio_device_put(gdev); | 1019 | gpio_device_put(gdev); |
| 1016 | goto err_print_message; | 1020 | goto err_print_message; |
| 1017 | } | 1021 | } |
| 1018 | err_remove_from_list: | ||
| 1019 | spin_lock_irqsave(&gpio_lock, flags); | ||
| 1020 | list_del(&gdev->list); | ||
| 1021 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
| 1022 | err_free_label: | 1022 | err_free_label: |
| 1023 | kfree_const(gdev->label); | 1023 | kfree_const(gdev->label); |
| 1024 | err_free_descs: | 1024 | err_free_descs: |
| @@ -1078,6 +1078,8 @@ struct amdgpu_device { · 1077 unmodified lines | |||
| 1078 | bool in_s3; | 1078 | bool in_s3; |
| 1079 | bool in_s4; | 1079 | bool in_s4; |
| 1080 | bool in_s0ix; | 1080 | bool in_s0ix; |
| 1081 | /* indicate amdgpu suspension status */ | ||
| 1082 | bool suspend_complete; | ||
| 1081 | 1083 | ||
| 1082 | enum pp_mp1_state mp1_state; | 1084 | enum pp_mp1_state mp1_state; |
| 1083 | struct amdgpu_doorbell_index doorbell_index; | 1085 | struct amdgpu_doorbell_index doorbell_index; |
| @@ -141,11 +141,31 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work) · 140 unmodified lines | |||
| 141 | static const struct drm_client_funcs kfd_client_funcs = { | 141 | static const struct drm_client_funcs kfd_client_funcs = { |
| 142 | .unregister = drm_client_release, | 142 | .unregister = drm_client_release, |
| 143 | }; | 143 | }; |
| 144 | |||
| 145 | int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev) | ||
| 146 | { | ||
| 147 | int ret; | ||
| 148 | |||
| 149 | if (!adev->kfd.init_complete) | ||
| 150 | return 0; | ||
| 151 | |||
| 152 | ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", | ||
| 153 | &kfd_client_funcs); | ||
| 154 | if (ret) { | ||
| 155 | dev_err(adev->dev, "Failed to init DRM client: %d\n", | ||
| 156 | ret); | ||
| 157 | return ret; | ||
| 158 | } | ||
| 159 | |||
| 160 | drm_client_register(&adev->kfd.client); | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 144 | void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | 165 | void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) |
| 145 | { | 166 | { |
| 146 | int i; | 167 | int i; |
| 147 | int last_valid_bit; | 168 | int last_valid_bit; |
| 148 | int ret; | ||
| 149 | 169 | ||
| 150 | amdgpu_amdkfd_gpuvm_init_mem_limits(); | 170 | amdgpu_amdkfd_gpuvm_init_mem_limits(); |
| 151 | 171 | ||
| @@ -164,12 +184,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) · 12 unmodified lines | |||
| 164 | .enable_mes = adev->enable_mes, | 184 | .enable_mes = adev->enable_mes, |
| 165 | }; | 185 | }; |
| 166 | 186 | ||
| 167 | ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", &kfd_client_funcs); | ||
| 168 | if (ret) { | ||
| 169 | dev_err(adev->dev, "Failed to init DRM client: %d\n", ret); | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | |||
| 173 | /* this is going to have a few of the MSBs set that we need to | 187 | /* this is going to have a few of the MSBs set that we need to |
| 174 | * clear | 188 | * clear |
| 175 | */ | 189 | */ |
| @@ -208,10 +222,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) · 32 unmodified lines | |||
| 208 | 222 | ||
| 209 | adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev, | 223 | adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev, |
| 210 | &gpu_resources); | 224 | &gpu_resources); |
| 211 | if (adev->kfd.init_complete) | ||
| 212 | drm_client_register(&adev->kfd.client); | ||
| 213 | else | ||
| 214 | drm_client_release(&adev->kfd.client); | ||
| 215 | 225 | ||
| 216 | amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size; | 226 | amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size; |
| 217 | 227 | ||
| @@ -182,6 +182,8 @@ int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev, · 181 unmodified lines | |||
| 182 | struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context, | 182 | struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context, |
| 183 | struct mm_struct *mm, | 183 | struct mm_struct *mm, |
| 184 | struct svm_range_bo *svm_bo); | 184 | struct svm_range_bo *svm_bo); |
| 185 | |||
| 186 | int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev); | ||
| 185 | #if defined(CONFIG_DEBUG_FS) | 187 | #if defined(CONFIG_DEBUG_FS) |
| 186 | int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data); | 188 | int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data); |
| 187 | #endif | 189 | #endif |
| @@ -301,7 +303,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev, · 113 unmodified lines | |||
| 301 | struct kgd_mem *mem, void *drm_priv); | 303 | struct kgd_mem *mem, void *drm_priv); |
| 302 | int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( | 304 | int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( |
| 303 | struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); | 305 | struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); |
| 304 | void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); | 306 | int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); |
| 305 | int amdgpu_amdkfd_gpuvm_sync_memory( | 307 | int amdgpu_amdkfd_gpuvm_sync_memory( |
| 306 | struct amdgpu_device *adev, struct kgd_mem *mem, bool intr); | 308 | struct amdgpu_device *adev, struct kgd_mem *mem, bool intr); |
| 307 | int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem, | 309 | int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem, |
| @@ -290,7 +290,7 @@ static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool sus · 289 unmodified lines | |||
| 290 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 290 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
| 291 | struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; | 291 | struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; |
| 292 | 292 | ||
| 293 | if (!(ring && drm_sched_wqueue_ready(&ring->sched))) | 293 | if (!amdgpu_ring_sched_ready(ring)) |
| 294 | continue; | 294 | continue; |
| 295 | 295 | ||
| 296 | /* stop secheduler and drain ring. */ | 296 | /* stop secheduler and drain ring. */ |
| @@ -2085,21 +2085,35 @@ out: · 2084 unmodified lines | |||
| 2085 | return ret; | 2085 | return ret; |
| 2086 | } | 2086 | } |
| 2087 | 2087 | ||
| 2088 | void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) | 2088 | int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) |
| 2089 | { | 2089 | { |
| 2090 | struct kfd_mem_attachment *entry; | 2090 | struct kfd_mem_attachment *entry; |
| 2091 | struct amdgpu_vm *vm; | 2091 | struct amdgpu_vm *vm; |
| 2092 | int ret; | ||
| 2092 | 2093 | ||
| 2093 | vm = drm_priv_to_vm(drm_priv); | 2094 | vm = drm_priv_to_vm(drm_priv); |
| 2094 | 2095 | ||
| 2095 | mutex_lock(&mem->lock); | 2096 | mutex_lock(&mem->lock); |
| 2096 | 2097 | ||
| 2098 | ret = amdgpu_bo_reserve(mem->bo, true); | ||
| 2099 | if (ret) | ||
| 2100 | goto out; | ||
| 2101 | |||
| 2097 | list_for_each_entry(entry, &mem->attachments, list) { | 2102 | list_for_each_entry(entry, &mem->attachments, list) { |
| 2098 | if (entry->bo_va->base.vm == vm) | 2103 | if (entry->bo_va->base.vm != vm) |
| 2099 | kfd_mem_dmaunmap_attachment(mem, entry); | 2104 | continue; |
| 2105 | if (entry->bo_va->base.bo->tbo.ttm && | ||
| 2106 | !entry->bo_va->base.bo->tbo.ttm->sg) | ||
| 2107 | continue; | ||
| 2108 | |||
| 2109 | kfd_mem_dmaunmap_attachment(mem, entry); | ||
| 2100 | } | 2110 | } |
| 2101 | 2111 | ||
| 2112 | amdgpu_bo_unreserve(mem->bo); | ||
| 2113 | out: | ||
| 2102 | mutex_unlock(&mem->lock); | 2114 | mutex_unlock(&mem->lock); |
| 2115 | |||
| 2116 | return ret; | ||
| 2103 | } | 2117 | } |
| 2104 | 2118 | ||
| 2105 | int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( | 2119 | int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( |
| @@ -1678,7 +1678,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) · 1677 unmodified lines | |||
| 1678 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | 1678 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { |
| 1679 | struct amdgpu_ring *ring = adev->rings[i]; | 1679 | struct amdgpu_ring *ring = adev->rings[i]; |
| 1680 | 1680 | ||
| 1681 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 1681 | if (!amdgpu_ring_sched_ready(ring)) |
| 1682 | continue; | 1682 | continue; |
| 1683 | drm_sched_wqueue_stop(&ring->sched); | 1683 | drm_sched_wqueue_stop(&ring->sched); |
| 1684 | } | 1684 | } |
| @@ -1694,7 +1694,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) · 9 unmodified lines | |||
| 1694 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | 1694 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { |
| 1695 | struct amdgpu_ring *ring = adev->rings[i]; | 1695 | struct amdgpu_ring *ring = adev->rings[i]; |
| 1696 | 1696 | ||
| 1697 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 1697 | if (!amdgpu_ring_sched_ready(ring)) |
| 1698 | continue; | 1698 | continue; |
| 1699 | drm_sched_wqueue_start(&ring->sched); | 1699 | drm_sched_wqueue_start(&ring->sched); |
| 1700 | } | 1700 | } |
| @@ -1916,8 +1916,8 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) · 215 unmodified lines | |||
| 1916 | 1916 | ||
| 1917 | ring = adev->rings[val]; | 1917 | ring = adev->rings[val]; |
| 1918 | 1918 | ||
| 1919 | if (!ring || !ring->funcs->preempt_ib || | 1919 | if (!amdgpu_ring_sched_ready(ring) || |
| 1920 | !drm_sched_wqueue_ready(&ring->sched)) | 1920 | !ring->funcs->preempt_ib) |
| 1921 | return -EINVAL; | 1921 | return -EINVAL; |
| 1922 | 1922 | ||
| 1923 | /* the last preemption failed */ | 1923 | /* the last preemption failed */ |
| @@ -4121,23 +4121,13 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 4120 unmodified lines | |||
| 4121 | } | 4121 | } |
| 4122 | } | 4122 | } |
| 4123 | } else { | 4123 | } else { |
| 4124 | switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { | 4124 | tmp = amdgpu_reset_method; |
| 4125 | case IP_VERSION(13, 0, 0): | 4125 | /* It should do a default reset when loading or reloading the driver, |
| 4126 | case IP_VERSION(13, 0, 7): | 4126 | * regardless of the module parameter reset_method. |
| 4127 | case IP_VERSION(13, 0, 10): | 4127 | */ |
| 4128 | r = psp_gpu_reset(adev); | 4128 | amdgpu_reset_method = AMD_RESET_METHOD_NONE; |
| 4129 | break; | 4129 | r = amdgpu_asic_reset(adev); |
| 4130 | default: | 4130 | amdgpu_reset_method = tmp; |
| 4131 | tmp = amdgpu_reset_method; | ||
| 4132 | /* It should do a default reset when loading or reloading the driver, | ||
| 4133 | * regardless of the module parameter reset_method. | ||
| 4134 | */ | ||
| 4135 | amdgpu_reset_method = AMD_RESET_METHOD_NONE; | ||
| 4136 | r = amdgpu_asic_reset(adev); | ||
| 4137 | amdgpu_reset_method = tmp; | ||
| 4138 | break; | ||
| 4139 | } | ||
| 4140 | |||
| 4141 | if (r) { | 4131 | if (r) { |
| 4142 | dev_err(adev->dev, "asic reset on init failed\n"); | 4132 | dev_err(adev->dev, "asic reset on init failed\n"); |
| 4143 | goto failed; | 4133 | goto failed; |
| @@ -5031,7 +5021,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev) · 887 unmodified lines | |||
| 5031 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 5021 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 5032 | struct amdgpu_ring *ring = adev->rings[i]; | 5022 | struct amdgpu_ring *ring = adev->rings[i]; |
| 5033 | 5023 | ||
| 5034 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 5024 | if (!amdgpu_ring_sched_ready(ring)) |
| 5035 | continue; | 5025 | continue; |
| 5036 | 5026 | ||
| 5037 | spin_lock(&ring->sched.job_list_lock); | 5027 | spin_lock(&ring->sched.job_list_lock); |
| @@ -5170,7 +5160,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, · 132 unmodified lines | |||
| 5170 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 5160 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 5171 | struct amdgpu_ring *ring = adev->rings[i]; | 5161 | struct amdgpu_ring *ring = adev->rings[i]; |
| 5172 | 5162 | ||
| 5173 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 5163 | if (!amdgpu_ring_sched_ready(ring)) |
| 5174 | continue; | 5164 | continue; |
| 5175 | 5165 | ||
| 5176 | /* Clear job fence from fence drv to avoid force_completion | 5166 | /* Clear job fence from fence drv to avoid force_completion |
| @@ -5637,7 +5627,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 460 unmodified lines | |||
| 5637 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 5627 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 5638 | struct amdgpu_ring *ring = tmp_adev->rings[i]; | 5628 | struct amdgpu_ring *ring = tmp_adev->rings[i]; |
| 5639 | 5629 | ||
| 5640 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 5630 | if (!amdgpu_ring_sched_ready(ring)) |
| 5641 | continue; | 5631 | continue; |
| 5642 | 5632 | ||
| 5643 | drm_sched_stop(&ring->sched, job ? &job->base : NULL); | 5633 | drm_sched_stop(&ring->sched, job ? &job->base : NULL); |
| @@ -5706,7 +5696,7 @@ skip_hw_reset: · 62 unmodified lines | |||
| 5706 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 5696 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 5707 | struct amdgpu_ring *ring = tmp_adev->rings[i]; | 5697 | struct amdgpu_ring *ring = tmp_adev->rings[i]; |
| 5708 | 5698 | ||
| 5709 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 5699 | if (!amdgpu_ring_sched_ready(ring)) |
| 5710 | continue; | 5700 | continue; |
| 5711 | 5701 | ||
| 5712 | drm_sched_start(&ring->sched, true); | 5702 | drm_sched_start(&ring->sched, true); |
| @@ -6061,7 +6051,7 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta · 348 unmodified lines | |||
| 6061 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 6051 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 6062 | struct amdgpu_ring *ring = adev->rings[i]; | 6052 | struct amdgpu_ring *ring = adev->rings[i]; |
| 6063 | 6053 | ||
| 6064 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 6054 | if (!amdgpu_ring_sched_ready(ring)) |
| 6065 | continue; | 6055 | continue; |
| 6066 | 6056 | ||
| 6067 | drm_sched_stop(&ring->sched, NULL); | 6057 | drm_sched_stop(&ring->sched, NULL); |
| @@ -6189,7 +6179,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev) · 121 unmodified lines | |||
| 6189 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 6179 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 6190 | struct amdgpu_ring *ring = adev->rings[i]; | 6180 | struct amdgpu_ring *ring = adev->rings[i]; |
| 6191 | 6181 | ||
| 6192 | if (!ring || !drm_sched_wqueue_ready(&ring->sched)) | 6182 | if (!amdgpu_ring_sched_ready(ring)) |
| 6193 | continue; | 6183 | continue; |
| 6194 | 6184 | ||
| 6195 | drm_sched_start(&ring->sched, true); | 6185 | drm_sched_start(&ring->sched, true); |
| @@ -2255,6 +2255,10 @@ retry_init: · 2254 unmodified lines | |||
| 2255 | if (ret) | 2255 | if (ret) |
| 2256 | goto err_pci; | 2256 | goto err_pci; |
| 2257 | 2257 | ||
| 2258 | ret = amdgpu_amdkfd_drm_client_create(adev); | ||
| 2259 | if (ret) | ||
| 2260 | goto err_pci; | ||
| 2261 | |||
| 2258 | /* | 2262 | /* |
| 2259 | * 1. don't init fbdev on hw without DCE | 2263 | * 1. don't init fbdev on hw without DCE |
| 2260 | * 2. don't init fbdev if there are no connectors | 2264 | * 2. don't init fbdev if there are no connectors |
| @@ -2472,6 +2476,7 @@ static int amdgpu_pmops_suspend(struct device *dev) · 211 unmodified lines | |||
| 2472 | struct drm_device *drm_dev = dev_get_drvdata(dev); | 2476 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 2473 | struct amdgpu_device *adev = drm_to_adev(drm_dev); | 2477 | struct amdgpu_device *adev = drm_to_adev(drm_dev); |
| 2474 | 2478 | ||
| 2479 | adev->suspend_complete = false; | ||
| 2475 | if (amdgpu_acpi_is_s0ix_active(adev)) | 2480 | if (amdgpu_acpi_is_s0ix_active(adev)) |
| 2476 | adev->in_s0ix = true; | 2481 | adev->in_s0ix = true; |
| 2477 | else if (amdgpu_acpi_is_s3_active(adev)) | 2482 | else if (amdgpu_acpi_is_s3_active(adev)) |
| @@ -2486,6 +2491,7 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev) · 8 unmodified lines | |||
| 2486 | struct drm_device *drm_dev = dev_get_drvdata(dev); | 2491 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 2487 | struct amdgpu_device *adev = drm_to_adev(drm_dev); | 2492 | struct amdgpu_device *adev = drm_to_adev(drm_dev); |
| 2488 | 2493 | ||
| 2494 | adev->suspend_complete = true; | ||
| 2489 | if (amdgpu_acpi_should_gpu_reset(adev)) | 2495 | if (amdgpu_acpi_should_gpu_reset(adev)) |
| 2490 | return amdgpu_asic_reset(adev); | 2496 | return amdgpu_asic_reset(adev); |
| 2491 | 2497 | ||
| @@ -121,6 +121,7 @@ int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev) · 120 unmodified lines | |||
| 121 | struct amdgpu_bo_param bp; | 121 | struct amdgpu_bo_param bp; |
| 122 | dma_addr_t dma_addr; | 122 | dma_addr_t dma_addr; |
| 123 | struct page *p; | 123 | struct page *p; |
| 124 | unsigned long x; | ||
| 124 | int ret; | 125 | int ret; |
| 125 | 126 | ||
| 126 | if (adev->gart.bo != NULL) | 127 | if (adev->gart.bo != NULL) |
| @@ -130,6 +131,10 @@ int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev) · 3 unmodified lines | |||
| 130 | if (!p) | 131 | if (!p) |
| 131 | return -ENOMEM; | 132 | return -ENOMEM; |
| 132 | 133 | ||
| 134 | /* assign pages to this device */ | ||
| 135 | for (x = 0; x < (1UL << order); x++) | ||
| 136 | p[x].mapping = adev->mman.bdev.dev_mapping; | ||
| 137 | |||
| 133 | /* If the hardware does not support UTCL2 snooping of the CPU caches | 138 | /* If the hardware does not support UTCL2 snooping of the CPU caches |
| 134 | * then set_memory_wc() could be used as a workaround to mark the pages | 139 | * then set_memory_wc() could be used as a workaround to mark the pages |
| 135 | * as write combine memory. | 140 | * as write combine memory. |
| @@ -223,6 +228,7 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev) · 87 unmodified lines | |||
| 223 | unsigned int order = get_order(adev->gart.table_size); | 228 | unsigned int order = get_order(adev->gart.table_size); |
| 224 | struct sg_table *sg = adev->gart.bo->tbo.sg; | 229 | struct sg_table *sg = adev->gart.bo->tbo.sg; |
| 225 | struct page *p; | 230 | struct page *p; |
| 231 | unsigned long x; | ||
| 226 | int ret; | 232 | int ret; |
| 227 | 233 | ||
| 228 | ret = amdgpu_bo_reserve(adev->gart.bo, false); | 234 | ret = amdgpu_bo_reserve(adev->gart.bo, false); |
| @@ -234,6 +240,8 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev) · 5 unmodified lines | |||
| 234 | sg_free_table(sg); | 240 | sg_free_table(sg); |
| 235 | kfree(sg); | 241 | kfree(sg); |
| 236 | p = virt_to_page(adev->gart.ptr); | 242 | p = virt_to_page(adev->gart.ptr); |
| 243 | for (x = 0; x < (1UL << order); x++) | ||
| 244 | p[x].mapping = NULL; | ||
| 237 | __free_pages(p, order); | 245 | __free_pages(p, order); |
| 238 | 246 | ||
| 239 | adev->gart.ptr = NULL; | 247 | adev->gart.ptr = NULL; |
| @@ -362,7 +362,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size · 361 unmodified lines | |||
| 362 | } | 362 | } |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | if (copy_to_user((char *)buf, context->mem_context.shared_buf, shared_buf_len)) | 365 | if (copy_to_user((char *)&buf[copy_pos], context->mem_context.shared_buf, shared_buf_len)) |
| 366 | ret = -EFAULT; | 366 | ret = -EFAULT; |
| 367 | 367 | ||
| 368 | err_free_shared_buf: | 368 | err_free_shared_buf: |
| @@ -635,6 +635,7 @@ int amdgpu_ring_test_helper(struct amdgpu_ring *ring) · 634 unmodified lines | |||
| 635 | ring->name); | 635 | ring->name); |
| 636 | 636 | ||
| 637 | ring->sched.ready = !r; | 637 | ring->sched.ready = !r; |
| 638 | |||
| 638 | return r; | 639 | return r; |
| 639 | } | 640 | } |
| 640 | 641 | ||
| @@ -717,3 +718,14 @@ void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring) · 76 unmodified lines | |||
| 717 | if (ring->is_sw_ring) | 718 | if (ring->is_sw_ring) |
| 718 | amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE); | 719 | amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE); |
| 719 | } | 720 | } |
| 721 | |||
| 722 | bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring) | ||
| 723 | { | ||
| 724 | if (!ring) | ||
| 725 | return false; | ||
| 726 | |||
| 727 | if (ring->no_scheduler || !drm_sched_wqueue_ready(&ring->sched)) | ||
| 728 | return false; | ||
| 729 | |||
| 730 | return true; | ||
| 731 | } | ||
| @@ -450,5 +450,5 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 449 unmodified lines | |||
| 450 | int amdgpu_ib_pool_init(struct amdgpu_device *adev); | 450 | int amdgpu_ib_pool_init(struct amdgpu_device *adev); |
| 451 | void amdgpu_ib_pool_fini(struct amdgpu_device *adev); | 451 | void amdgpu_ib_pool_fini(struct amdgpu_device *adev); |
| 452 | int amdgpu_ib_ring_tests(struct amdgpu_device *adev); | 452 | int amdgpu_ib_ring_tests(struct amdgpu_device *adev); |
| 453 | 453 | bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring); | |
| 454 | #endif | 454 | #endif |
| @@ -221,8 +221,23 @@ static struct attribute *amdgpu_vram_mgr_attributes[] = { · 220 unmodified lines | |||
| 221 | NULL | 221 | NULL |
| 222 | }; | 222 | }; |
| 223 | 223 | ||
| 224 | static umode_t amdgpu_vram_attrs_is_visible(struct kobject *kobj, | ||
| 225 | struct attribute *attr, int i) | ||
| 226 | { | ||
| 227 | struct device *dev = kobj_to_dev(kobj); | ||
| 228 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
| 229 | struct amdgpu_device *adev = drm_to_adev(ddev); | ||
| 230 | |||
| 231 | if (attr == &dev_attr_mem_info_vram_vendor.attr && | ||
| 232 | !adev->gmc.vram_vendor) | ||
| 233 | return 0; | ||
| 234 | |||
| 235 | return attr->mode; | ||
| 236 | } | ||
| 237 | |||
| 224 | const struct attribute_group amdgpu_vram_mgr_attr_group = { | 238 | const struct attribute_group amdgpu_vram_mgr_attr_group = { |
| 225 | .attrs = amdgpu_vram_mgr_attributes | 239 | .attrs = amdgpu_vram_mgr_attributes, |
| 240 | .is_visible = amdgpu_vram_attrs_is_visible | ||
| 226 | }; | 241 | }; |
| 227 | 242 | ||
| 228 | /** | 243 | /** |
| @@ -204,6 +204,12 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev, · 203 unmodified lines | |||
| 204 | tmp = RREG32(mmIH_RB_CNTL); | 204 | tmp = RREG32(mmIH_RB_CNTL); |
| 205 | tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; | 205 | tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; |
| 206 | WREG32(mmIH_RB_CNTL, tmp); | 206 | WREG32(mmIH_RB_CNTL, tmp); |
| 207 | |||
| 208 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 209 | * can be detected. | ||
| 210 | */ | ||
| 211 | tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; | ||
| 212 | WREG32(mmIH_RB_CNTL, tmp); | ||
| 207 | } | 213 | } |
| 208 | return (wptr & ih->ptr_mask); | 214 | return (wptr & ih->ptr_mask); |
| 209 | } | 215 | } |
| @@ -216,6 +216,11 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev, · 215 unmodified lines | |||
| 216 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 216 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 217 | WREG32(mmIH_RB_CNTL, tmp); | 217 | WREG32(mmIH_RB_CNTL, tmp); |
| 218 | 218 | ||
| 219 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 220 | * can be detected. | ||
| 221 | */ | ||
| 222 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 223 | WREG32(mmIH_RB_CNTL, tmp); | ||
| 219 | 224 | ||
| 220 | out: | 225 | out: |
| 221 | return (wptr & ih->ptr_mask); | 226 | return (wptr & ih->ptr_mask); |
| @@ -4027,8 +4027,6 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) · 4026 unmodified lines | |||
| 4027 | err = 0; | 4027 | err = 0; |
| 4028 | adev->gfx.mec2_fw = NULL; | 4028 | adev->gfx.mec2_fw = NULL; |
| 4029 | } | 4029 | } |
| 4030 | amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2); | ||
| 4031 | amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT); | ||
| 4032 | 4030 | ||
| 4033 | gfx_v10_0_check_fw_write_wait(adev); | 4031 | gfx_v10_0_check_fw_write_wait(adev); |
| 4034 | out: | 4032 | out: |
| @@ -6589,7 +6587,7 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_device *adev, void *m, · 2554 unmodified lines | |||
| 6589 | #ifdef __BIG_ENDIAN | 6587 | #ifdef __BIG_ENDIAN |
| 6590 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1); | 6588 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1); |
| 6591 | #endif | 6589 | #endif |
| 6592 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); | 6590 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); |
| 6593 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, | 6591 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, |
| 6594 | prop->allow_tunneling); | 6592 | prop->allow_tunneling); |
| 6595 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); | 6593 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); |
| @@ -107,23 +107,6 @@ static const struct soc15_reg_golden golden_settings_gc_11_0_1[] = · 106 unmodified lines | |||
| 107 | SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xfcffffff, 0x0000000a) | 107 | SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xfcffffff, 0x0000000a) |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | static const struct soc15_reg_golden golden_settings_gc_11_5_0[] = { | ||
| 111 | SOC15_REG_GOLDEN_VALUE(GC, 0, regDB_DEBUG5, 0xffffffff, 0x00000800), | ||
| 112 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x0c1807ff, 0x00000242), | ||
| 113 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500), | ||
| 114 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3), | ||
| 115 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3), | ||
| 116 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL, 0xffffffff, 0xf37fff3f), | ||
| 117 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL3, 0xfffffffb, 0x00f40188), | ||
| 118 | SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x80009007), | ||
| 119 | SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_CL_ENHANCE, 0xf1ffffff, 0x00880007), | ||
| 120 | SOC15_REG_GOLDEN_VALUE(GC, 0, regPC_CONFIG_CNTL_1, 0xffffffff, 0x00010000), | ||
| 121 | SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL_AUX, 0xf7f7ffff, 0x01030000), | ||
| 122 | SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL2, 0x007f0000, 0x00000000), | ||
| 123 | SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xffcfffff, 0x0000200a), | ||
| 124 | SOC15_REG_GOLDEN_VALUE(GC, 0, regUTCL1_CTRL_2, 0xffffffff, 0x0000048f) | ||
| 125 | }; | ||
| 126 | |||
| 127 | #define DEFAULT_SH_MEM_CONFIG \ | 110 | #define DEFAULT_SH_MEM_CONFIG \ |
| 128 | ((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \ | 111 | ((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \ |
| 129 | (SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \ | 112 | (SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \ |
| @@ -304,11 +287,6 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev) · 174 unmodified lines | |||
| 304 | golden_settings_gc_11_0_1, | 287 | golden_settings_gc_11_0_1, |
| 305 | (const u32)ARRAY_SIZE(golden_settings_gc_11_0_1)); | 288 | (const u32)ARRAY_SIZE(golden_settings_gc_11_0_1)); |
| 306 | break; | 289 | break; |
| 307 | case IP_VERSION(11, 5, 0): | ||
| 308 | soc15_program_register_sequence(adev, | ||
| 309 | golden_settings_gc_11_5_0, | ||
| 310 | (const u32)ARRAY_SIZE(golden_settings_gc_11_5_0)); | ||
| 311 | break; | ||
| 312 | default: | 290 | default: |
| 313 | break; | 291 | break; |
| 314 | } | 292 | } |
| @@ -3846,7 +3824,7 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m, · 3531 unmodified lines | |||
| 3846 | (order_base_2(prop->queue_size / 4) - 1)); | 3824 | (order_base_2(prop->queue_size / 4) - 1)); |
| 3847 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE, | 3825 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE, |
| 3848 | (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1)); | 3826 | (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1)); |
| 3849 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); | 3827 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); |
| 3850 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, | 3828 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, |
| 3851 | prop->allow_tunneling); | 3829 | prop->allow_tunneling); |
| 3852 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); | 3830 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); |
| @@ -3034,6 +3034,14 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev) · 3033 unmodified lines | |||
| 3034 | 3034 | ||
| 3035 | gfx_v9_0_cp_gfx_enable(adev, true); | 3035 | gfx_v9_0_cp_gfx_enable(adev, true); |
| 3036 | 3036 | ||
| 3037 | /* Now only limit the quirk on the APU gfx9 series and already | ||
| 3038 | * confirmed that the APU gfx10/gfx11 needn't such update. | ||
| 3039 | */ | ||
| 3040 | if (adev->flags & AMD_IS_APU && | ||
| 3041 | adev->in_s3 && !adev->suspend_complete) { | ||
| 3042 | DRM_INFO(" Will skip the CSB packet resubmit\n"); | ||
| 3043 | return 0; | ||
| 3044 | } | ||
| 3037 | r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3); | 3045 | r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3); |
| 3038 | if (r) { | 3046 | if (r) { |
| 3039 | DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); | 3047 | DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); |
| @@ -915,8 +915,8 @@ static int gmc_v6_0_hw_init(void *handle) · 914 unmodified lines | |||
| 915 | 915 | ||
| 916 | if (amdgpu_emu_mode == 1) | 916 | if (amdgpu_emu_mode == 1) |
| 917 | return amdgpu_gmc_vram_checking(adev); | 917 | return amdgpu_gmc_vram_checking(adev); |
| 918 | else | 918 | |
| 919 | return r; | 919 | return 0; |
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | static int gmc_v6_0_hw_fini(void *handle) | 922 | static int gmc_v6_0_hw_fini(void *handle) |
| @@ -1099,8 +1099,8 @@ static int gmc_v7_0_hw_init(void *handle) · 1098 unmodified lines | |||
| 1099 | 1099 | ||
| 1100 | if (amdgpu_emu_mode == 1) | 1100 | if (amdgpu_emu_mode == 1) |
| 1101 | return amdgpu_gmc_vram_checking(adev); | 1101 | return amdgpu_gmc_vram_checking(adev); |
| 1102 | else | 1102 | |
| 1103 | return r; | 1103 | return 0; |
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | static int gmc_v7_0_hw_fini(void *handle) | 1106 | static int gmc_v7_0_hw_fini(void *handle) |
| @@ -1219,8 +1219,8 @@ static int gmc_v8_0_hw_init(void *handle) · 1218 unmodified lines | |||
| 1219 | 1219 | ||
| 1220 | if (amdgpu_emu_mode == 1) | 1220 | if (amdgpu_emu_mode == 1) |
| 1221 | return amdgpu_gmc_vram_checking(adev); | 1221 | return amdgpu_gmc_vram_checking(adev); |
| 1222 | else | 1222 | |
| 1223 | return r; | 1223 | return 0; |
| 1224 | } | 1224 | } |
| 1225 | 1225 | ||
| 1226 | static int gmc_v8_0_hw_fini(void *handle) | 1226 | static int gmc_v8_0_hw_fini(void *handle) |
| @@ -1947,13 +1947,6 @@ static int gmc_v9_0_init_mem_ranges(struct amdgpu_device *adev) · 1946 unmodified lines | |||
| 1947 | 1947 | ||
| 1948 | static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev) | 1948 | static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev) |
| 1949 | { | 1949 | { |
| 1950 | static const u32 regBIF_BIOS_SCRATCH_4 = 0x50; | ||
| 1951 | u32 vram_info; | ||
| 1952 | |||
| 1953 | if (!amdgpu_sriov_vf(adev)) { | ||
| 1954 | vram_info = RREG32(regBIF_BIOS_SCRATCH_4); | ||
| 1955 | adev->gmc.vram_vendor = vram_info & 0xF; | ||
| 1956 | } | ||
| 1957 | adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; | 1950 | adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; |
| 1958 | adev->gmc.vram_width = 128 * 64; | 1951 | adev->gmc.vram_width = 128 * 64; |
| 1959 | } | 1952 | } |
| @@ -2340,8 +2333,8 @@ static int gmc_v9_0_hw_init(void *handle) · 380 unmodified lines | |||
| 2340 | 2333 | ||
| 2341 | if (amdgpu_emu_mode == 1) | 2334 | if (amdgpu_emu_mode == 1) |
| 2342 | return amdgpu_gmc_vram_checking(adev); | 2335 | return amdgpu_gmc_vram_checking(adev); |
| 2343 | else | 2336 | |
| 2344 | return r; | 2337 | return 0; |
| 2345 | } | 2338 | } |
| 2346 | 2339 | ||
| 2347 | /** | 2340 | /** |
| @@ -215,6 +215,11 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev, · 214 unmodified lines | |||
| 215 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 215 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 216 | WREG32(mmIH_RB_CNTL, tmp); | 216 | WREG32(mmIH_RB_CNTL, tmp); |
| 217 | 217 | ||
| 218 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 219 | * can be detected. | ||
| 220 | */ | ||
| 221 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 222 | WREG32(mmIH_RB_CNTL, tmp); | ||
| 218 | 223 | ||
| 219 | out: | 224 | out: |
| 220 | return (wptr & ih->ptr_mask); | 225 | return (wptr & ih->ptr_mask); |
| @@ -418,6 +418,12 @@ static u32 ih_v6_0_get_wptr(struct amdgpu_device *adev, · 417 unmodified lines | |||
| 418 | tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl); | 418 | tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl); |
| 419 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 419 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 420 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | 420 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); |
| 421 | |||
| 422 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 423 | * can be detected. | ||
| 424 | */ | ||
| 425 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 426 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | ||
| 421 | out: | 427 | out: |
| 422 | return (wptr & ih->ptr_mask); | 428 | return (wptr & ih->ptr_mask); |
| 423 | } | 429 | } |
| @@ -418,6 +418,13 @@ static u32 ih_v6_1_get_wptr(struct amdgpu_device *adev, · 417 unmodified lines | |||
| 418 | tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl); | 418 | tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl); |
| 419 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 419 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 420 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | 420 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); |
| 421 | |||
| 422 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 423 | * can be detected. | ||
| 424 | */ | ||
| 425 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 426 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | ||
| 427 | |||
| 421 | out: | 428 | out: |
| 422 | return (wptr & ih->ptr_mask); | 429 | return (wptr & ih->ptr_mask); |
| 423 | } | 430 | } |
| @@ -674,14 +674,6 @@ static int jpeg_v4_0_set_powergating_state(void *handle, · 673 unmodified lines | |||
| 674 | return ret; | 674 | return ret; |
| 675 | } | 675 | } |
| 676 | 676 | ||
| 677 | static int jpeg_v4_0_set_interrupt_state(struct amdgpu_device *adev, | ||
| 678 | struct amdgpu_irq_src *source, | ||
| 679 | unsigned type, | ||
| 680 | enum amdgpu_interrupt_state state) | ||
| 681 | { | ||
| 682 | return 0; | ||
| 683 | } | ||
| 684 | |||
| 685 | static int jpeg_v4_0_set_ras_interrupt_state(struct amdgpu_device *adev, | 677 | static int jpeg_v4_0_set_ras_interrupt_state(struct amdgpu_device *adev, |
| 686 | struct amdgpu_irq_src *source, | 678 | struct amdgpu_irq_src *source, |
| 687 | unsigned int type, | 679 | unsigned int type, |
| @@ -765,7 +757,6 @@ static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev) · 77 unmodified lines | |||
| 765 | } | 757 | } |
| 766 | 758 | ||
| 767 | static const struct amdgpu_irq_src_funcs jpeg_v4_0_irq_funcs = { | 759 | static const struct amdgpu_irq_src_funcs jpeg_v4_0_irq_funcs = { |
| 768 | .set = jpeg_v4_0_set_interrupt_state, | ||
| 769 | .process = jpeg_v4_0_process_interrupt, | 760 | .process = jpeg_v4_0_process_interrupt, |
| 770 | }; | 761 | }; |
| 771 | 762 | ||
| @@ -181,7 +181,6 @@ static int jpeg_v4_0_5_hw_fini(void *handle) · 180 unmodified lines | |||
| 181 | RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS)) | 181 | RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS)) |
| 182 | jpeg_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE); | 182 | jpeg_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE); |
| 183 | } | 183 | } |
| 184 | amdgpu_irq_put(adev, &adev->jpeg.inst->irq, 0); | ||
| 185 | 184 | ||
| 186 | return 0; | 185 | return 0; |
| 187 | } | 186 | } |
| @@ -516,14 +515,6 @@ static int jpeg_v4_0_5_set_powergating_state(void *handle, · 328 unmodified lines | |||
| 516 | return ret; | 515 | return ret; |
| 517 | } | 516 | } |
| 518 | 517 | ||
| 519 | static int jpeg_v4_0_5_set_interrupt_state(struct amdgpu_device *adev, | ||
| 520 | struct amdgpu_irq_src *source, | ||
| 521 | unsigned type, | ||
| 522 | enum amdgpu_interrupt_state state) | ||
| 523 | { | ||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev, | 518 | static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev, |
| 528 | struct amdgpu_irq_src *source, | 519 | struct amdgpu_irq_src *source, |
| 529 | struct amdgpu_iv_entry *entry) | 520 | struct amdgpu_iv_entry *entry) |
| @@ -603,7 +594,6 @@ static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev) · 73 unmodified lines | |||
| 603 | } | 594 | } |
| 604 | 595 | ||
| 605 | static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = { | 596 | static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = { |
| 606 | .set = jpeg_v4_0_5_set_interrupt_state, | ||
| 607 | .process = jpeg_v4_0_5_process_interrupt, | 597 | .process = jpeg_v4_0_5_process_interrupt, |
| 608 | }; | 598 | }; |
| 609 | 599 | ||
| @@ -442,6 +442,12 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev, · 441 unmodified lines | |||
| 442 | tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl); | 442 | tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl); |
| 443 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 443 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 444 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | 444 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); |
| 445 | |||
| 446 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 447 | * can be detected. | ||
| 448 | */ | ||
| 449 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 450 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | ||
| 445 | out: | 451 | out: |
| 446 | return (wptr & ih->ptr_mask); | 452 | return (wptr & ih->ptr_mask); |
| 447 | } | 453 | } |
| @@ -431,6 +431,12 @@ static void nbio_v7_9_init_registers(struct amdgpu_device *adev) · 430 unmodified lines | |||
| 431 | u32 inst_mask; | 431 | u32 inst_mask; |
| 432 | int i; | 432 | int i; |
| 433 | 433 | ||
| 434 | if (amdgpu_sriov_vf(adev)) | ||
| 435 | adev->rmmio_remap.reg_offset = | ||
| 436 | SOC15_REG_OFFSET( | ||
| 437 | NBIO, 0, | ||
| 438 | regBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) | ||
| 439 | << 2; | ||
| 434 | WREG32_SOC15(NBIO, 0, regXCC_DOORBELL_FENCE, | 440 | WREG32_SOC15(NBIO, 0, regXCC_DOORBELL_FENCE, |
| 435 | 0xff & ~(adev->gfx.xcc_mask)); | 441 | 0xff & ~(adev->gfx.xcc_mask)); |
| 436 | 442 | ||
| @@ -119,6 +119,12 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev, · 118 unmodified lines | |||
| 119 | tmp = RREG32(IH_RB_CNTL); | 119 | tmp = RREG32(IH_RB_CNTL); |
| 120 | tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; | 120 | tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; |
| 121 | WREG32(IH_RB_CNTL, tmp); | 121 | WREG32(IH_RB_CNTL, tmp); |
| 122 | |||
| 123 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 124 | * can be detected. | ||
| 125 | */ | ||
| 126 | tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; | ||
| 127 | WREG32(IH_RB_CNTL, tmp); | ||
| 122 | } | 128 | } |
| 123 | return (wptr & ih->ptr_mask); | 129 | return (wptr & ih->ptr_mask); |
| 124 | } | 130 | } |
| @@ -1298,10 +1298,32 @@ static int soc15_common_suspend(void *handle) · 1297 unmodified lines | |||
| 1298 | return soc15_common_hw_fini(adev); | 1298 | return soc15_common_hw_fini(adev); |
| 1299 | } | 1299 | } |
| 1300 | 1300 | ||
| 1301 | static bool soc15_need_reset_on_resume(struct amdgpu_device *adev) | ||
| 1302 | { | ||
| 1303 | u32 sol_reg; | ||
| 1304 | |||
| 1305 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | ||
| 1306 | |||
| 1307 | /* Will reset for the following suspend abort cases. | ||
| 1308 | * 1) Only reset limit on APU side, dGPU hasn't checked yet. | ||
| 1309 | * 2) S3 suspend abort and TOS already launched. | ||
| 1310 | */ | ||
| 1311 | if (adev->flags & AMD_IS_APU && adev->in_s3 && | ||
| 1312 | !adev->suspend_complete && | ||
| 1313 | sol_reg) | ||
| 1314 | return true; | ||
| 1315 | |||
| 1316 | return false; | ||
| 1317 | } | ||
| 1318 | |||
| 1301 | static int soc15_common_resume(void *handle) | 1319 | static int soc15_common_resume(void *handle) |
| 1302 | { | 1320 | { |
| 1303 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1321 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1304 | 1322 | ||
| 1323 | if (soc15_need_reset_on_resume(adev)) { | ||
| 1324 | dev_info(adev->dev, "S3 suspend abort case, let's reset ASIC.\n"); | ||
| 1325 | soc15_asic_reset(adev); | ||
| 1326 | } | ||
| 1305 | return soc15_common_hw_init(adev); | 1327 | return soc15_common_hw_init(adev); |
| 1306 | } | 1328 | } |
| 1307 | 1329 | ||
| @@ -219,6 +219,12 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev, · 218 unmodified lines | |||
| 219 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 219 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 220 | WREG32(mmIH_RB_CNTL, tmp); | 220 | WREG32(mmIH_RB_CNTL, tmp); |
| 221 | 221 | ||
| 222 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 223 | * can be detected. | ||
| 224 | */ | ||
| 225 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 226 | WREG32(mmIH_RB_CNTL, tmp); | ||
| 227 | |||
| 222 | out: | 228 | out: |
| 223 | return (wptr & ih->ptr_mask); | 229 | return (wptr & ih->ptr_mask); |
| 224 | } | 230 | } |
| @@ -2017,22 +2017,6 @@ static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_sta · 2016 unmodified lines | |||
| 2017 | return ret; | 2017 | return ret; |
| 2018 | } | 2018 | } |
| 2019 | 2019 | ||
| 2020 | /** | ||
| 2021 | * vcn_v4_0_set_interrupt_state - set VCN block interrupt state | ||
| 2022 | * | ||
| 2023 | * @adev: amdgpu_device pointer | ||
| 2024 | * @source: interrupt sources | ||
| 2025 | * @type: interrupt types | ||
| 2026 | * @state: interrupt states | ||
| 2027 | * | ||
| 2028 | * Set VCN block interrupt state | ||
| 2029 | */ | ||
| 2030 | static int vcn_v4_0_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, | ||
| 2031 | unsigned type, enum amdgpu_interrupt_state state) | ||
| 2032 | { | ||
| 2033 | return 0; | ||
| 2034 | } | ||
| 2035 | |||
| 2036 | /** | 2020 | /** |
| 2037 | * vcn_v4_0_set_ras_interrupt_state - set VCN block RAS interrupt state | 2021 | * vcn_v4_0_set_ras_interrupt_state - set VCN block RAS interrupt state |
| 2038 | * | 2022 | * |
| @@ -2097,7 +2081,6 @@ static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_ · 58 unmodified lines | |||
| 2097 | } | 2081 | } |
| 2098 | 2082 | ||
| 2099 | static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = { | 2083 | static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = { |
| 2100 | .set = vcn_v4_0_set_interrupt_state, | ||
| 2101 | .process = vcn_v4_0_process_interrupt, | 2084 | .process = vcn_v4_0_process_interrupt, |
| 2102 | }; | 2085 | }; |
| 2103 | 2086 | ||
| @@ -269,8 +269,6 @@ static int vcn_v4_0_5_hw_fini(void *handle) · 268 unmodified lines | |||
| 269 | vcn_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE); | 269 | vcn_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE); |
| 270 | } | 270 | } |
| 271 | } | 271 | } |
| 272 | |||
| 273 | amdgpu_irq_put(adev, &adev->vcn.inst[i].irq, 0); | ||
| 274 | } | 272 | } |
| 275 | 273 | ||
| 276 | return 0; | 274 | return 0; |
| @@ -1668,22 +1666,6 @@ static int vcn_v4_0_5_set_powergating_state(void *handle, enum amd_powergating_s · 1391 unmodified lines | |||
| 1668 | return ret; | 1666 | return ret; |
| 1669 | } | 1667 | } |
| 1670 | 1668 | ||
| 1671 | /** | ||
| 1672 | * vcn_v4_0_5_set_interrupt_state - set VCN block interrupt state | ||
| 1673 | * | ||
| 1674 | * @adev: amdgpu_device pointer | ||
| 1675 | * @source: interrupt sources | ||
| 1676 | * @type: interrupt types | ||
| 1677 | * @state: interrupt states | ||
| 1678 | * | ||
| 1679 | * Set VCN block interrupt state | ||
| 1680 | */ | ||
| 1681 | static int vcn_v4_0_5_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, | ||
| 1682 | unsigned type, enum amdgpu_interrupt_state state) | ||
| 1683 | { | ||
| 1684 | return 0; | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | /** | 1669 | /** |
| 1688 | * vcn_v4_0_5_process_interrupt - process VCN block interrupt | 1670 | * vcn_v4_0_5_process_interrupt - process VCN block interrupt |
| 1689 | * | 1671 | * |
| @@ -1726,7 +1708,6 @@ static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgp · 36 unmodified lines | |||
| 1726 | } | 1708 | } |
| 1727 | 1709 | ||
| 1728 | static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = { | 1710 | static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = { |
| 1729 | .set = vcn_v4_0_5_set_interrupt_state, | ||
| 1730 | .process = vcn_v4_0_5_process_interrupt, | 1711 | .process = vcn_v4_0_5_process_interrupt, |
| 1731 | }; | 1712 | }; |
| 1732 | 1713 | ||
| @@ -373,6 +373,12 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, · 372 unmodified lines | |||
| 373 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 373 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 374 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | 374 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); |
| 375 | 375 | ||
| 376 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 377 | * can be detected. | ||
| 378 | */ | ||
| 379 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 380 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | ||
| 381 | |||
| 376 | out: | 382 | out: |
| 377 | return (wptr & ih->ptr_mask); | 383 | return (wptr & ih->ptr_mask); |
| 378 | } | 384 | } |
| @@ -421,6 +421,12 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev, · 420 unmodified lines | |||
| 421 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 421 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
| 422 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | 422 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); |
| 423 | 423 | ||
| 424 | /* Unset the CLEAR_OVERFLOW bit immediately so new overflows | ||
| 425 | * can be detected. | ||
| 426 | */ | ||
| 427 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); | ||
| 428 | WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); | ||
| 429 | |||
| 424 | out: | 430 | out: |
| 425 | return (wptr & ih->ptr_mask); | 431 | return (wptr & ih->ptr_mask); |
| 426 | } | 432 | } |
| @@ -674,7 +674,7 @@ static const uint32_t cwsr_trap_gfx9_hex[] = { · 673 unmodified lines | |||
| 674 | 0x86ea6a6a, 0x8f6e837a, | 674 | 0x86ea6a6a, 0x8f6e837a, |
| 675 | 0xb96ee0c2, 0xbf800002, | 675 | 0xb96ee0c2, 0xbf800002, |
| 676 | 0xb97a0002, 0xbf8a0000, | 676 | 0xb97a0002, 0xbf8a0000, |
| 677 | 0xbe801f6c, 0xbf810000, | 677 | 0xbe801f6c, 0xbf9b0000, |
| 678 | }; | 678 | }; |
| 679 | 679 | ||
| 680 | static const uint32_t cwsr_trap_nv1x_hex[] = { | 680 | static const uint32_t cwsr_trap_nv1x_hex[] = { |
| @@ -1091,7 +1091,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = { · 410 unmodified lines | |||
| 1091 | 0xb9eef807, 0x876dff6d, | 1091 | 0xb9eef807, 0x876dff6d, |
| 1092 | 0x0000ffff, 0x87fe7e7e, | 1092 | 0x0000ffff, 0x87fe7e7e, |
| 1093 | 0x87ea6a6a, 0xb9faf802, | 1093 | 0x87ea6a6a, 0xb9faf802, |
| 1094 | 0xbe80226c, 0xbf810000, | 1094 | 0xbe80226c, 0xbf9b0000, |
| 1095 | 0xbf9f0000, 0xbf9f0000, | 1095 | 0xbf9f0000, 0xbf9f0000, |
| 1096 | 0xbf9f0000, 0xbf9f0000, | 1096 | 0xbf9f0000, 0xbf9f0000, |
| 1097 | 0xbf9f0000, 0x00000000, | 1097 | 0xbf9f0000, 0x00000000, |
| @@ -1574,7 +1574,7 @@ static const uint32_t cwsr_trap_arcturus_hex[] = { · 476 unmodified lines | |||
| 1574 | 0x86ea6a6a, 0x8f6e837a, | 1574 | 0x86ea6a6a, 0x8f6e837a, |
| 1575 | 0xb96ee0c2, 0xbf800002, | 1575 | 0xb96ee0c2, 0xbf800002, |
| 1576 | 0xb97a0002, 0xbf8a0000, | 1576 | 0xb97a0002, 0xbf8a0000, |
| 1577 | 0xbe801f6c, 0xbf810000, | 1577 | 0xbe801f6c, 0xbf9b0000, |
| 1578 | }; | 1578 | }; |
| 1579 | 1579 | ||
| 1580 | static const uint32_t cwsr_trap_aldebaran_hex[] = { | 1580 | static const uint32_t cwsr_trap_aldebaran_hex[] = { |
| @@ -2065,7 +2065,7 @@ static const uint32_t cwsr_trap_aldebaran_hex[] = { · 484 unmodified lines | |||
| 2065 | 0x86ea6a6a, 0x8f6e837a, | 2065 | 0x86ea6a6a, 0x8f6e837a, |
| 2066 | 0xb96ee0c2, 0xbf800002, | 2066 | 0xb96ee0c2, 0xbf800002, |
| 2067 | 0xb97a0002, 0xbf8a0000, | 2067 | 0xb97a0002, 0xbf8a0000, |
| 2068 | 0xbe801f6c, 0xbf810000, | 2068 | 0xbe801f6c, 0xbf9b0000, |
| 2069 | }; | 2069 | }; |
| 2070 | 2070 | ||
| 2071 | static const uint32_t cwsr_trap_gfx10_hex[] = { | 2071 | static const uint32_t cwsr_trap_gfx10_hex[] = { |
| @@ -2500,7 +2500,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = { · 428 unmodified lines | |||
| 2500 | 0x876dff6d, 0x0000ffff, | 2500 | 0x876dff6d, 0x0000ffff, |
| 2501 | 0x87fe7e7e, 0x87ea6a6a, | 2501 | 0x87fe7e7e, 0x87ea6a6a, |
| 2502 | 0xb9faf802, 0xbe80226c, | 2502 | 0xb9faf802, 0xbe80226c, |
| 2503 | 0xbf810000, 0xbf9f0000, | 2503 | 0xbf9b0000, 0xbf9f0000, |
| 2504 | 0xbf9f0000, 0xbf9f0000, | 2504 | 0xbf9f0000, 0xbf9f0000, |
| 2505 | 0xbf9f0000, 0xbf9f0000, | 2505 | 0xbf9f0000, 0xbf9f0000, |
| 2506 | }; | 2506 | }; |
| @@ -2944,7 +2944,7 @@ static const uint32_t cwsr_trap_gfx11_hex[] = { · 437 unmodified lines | |||
| 2944 | 0xb8eef802, 0xbf0d866e, | 2944 | 0xb8eef802, 0xbf0d866e, |
| 2945 | 0xbfa20002, 0xb97af802, | 2945 | 0xbfa20002, 0xb97af802, |
| 2946 | 0xbe80486c, 0xb97af802, | 2946 | 0xbe80486c, 0xb97af802, |
| 2947 | 0xbe804a6c, 0xbfb00000, | 2947 | 0xbe804a6c, 0xbfb10000, |
| 2948 | 0xbf9f0000, 0xbf9f0000, | 2948 | 0xbf9f0000, 0xbf9f0000, |
| 2949 | 0xbf9f0000, 0xbf9f0000, | 2949 | 0xbf9f0000, 0xbf9f0000, |
| 2950 | 0xbf9f0000, 0x00000000, | 2950 | 0xbf9f0000, 0x00000000, |
| @@ -3436,5 +3436,5 @@ static const uint32_t cwsr_trap_gfx9_4_3_hex[] = { · 485 unmodified lines | |||
| 3436 | 0x86ea6a6a, 0x8f6e837a, | 3436 | 0x86ea6a6a, 0x8f6e837a, |
| 3437 | 0xb96ee0c2, 0xbf800002, | 3437 | 0xb96ee0c2, 0xbf800002, |
| 3438 | 0xb97a0002, 0xbf8a0000, | 3438 | 0xb97a0002, 0xbf8a0000, |
| 3439 | 0xbe801f6c, 0xbf810000, | 3439 | 0xbe801f6c, 0xbf9b0000, |
| 3440 | }; | 3440 | }; |
| @@ -1104,7 +1104,7 @@ L_RETURN_WITHOUT_PRIV: · 1103 unmodified lines | |||
| 1104 | s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution | 1104 | s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution |
| 1105 | 1105 | ||
| 1106 | L_END_PGM: | 1106 | L_END_PGM: |
| 1107 | s_endpgm | 1107 | s_endpgm_saved |
| 1108 | end | 1108 | end |
| 1109 | 1109 | ||
| 1110 | function write_hwreg_to_mem(s, s_rsrc, s_mem_offset) | 1110 | function write_hwreg_to_mem(s, s_rsrc, s_mem_offset) |
| @@ -921,7 +921,7 @@ L_RESTORE: · 920 unmodified lines | |||
| 921 | /* the END */ | 921 | /* the END */ |
| 922 | /**************************************************************************/ | 922 | /**************************************************************************/ |
| 923 | L_END_PGM: | 923 | L_END_PGM: |
| 924 | s_endpgm | 924 | s_endpgm_saved |
| 925 | 925 | ||
| 926 | end | 926 | end |
| 927 | 927 | ||
| @@ -1442,7 +1442,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, · 1441 unmodified lines | |||
| 1442 | kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT); | 1442 | kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT); |
| 1443 | 1443 | ||
| 1444 | /* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */ | 1444 | /* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */ |
| 1445 | amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv); | 1445 | err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv); |
| 1446 | if (err) | ||
| 1447 | goto sync_memory_failed; | ||
| 1446 | } | 1448 | } |
| 1447 | 1449 | ||
| 1448 | mutex_unlock(&p->mutex); | 1450 | mutex_unlock(&p->mutex); |
| @@ -574,7 +574,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange, · 573 unmodified lines | |||
| 574 | pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms, prange->start, | 574 | pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms, prange->start, |
| 575 | prange->last); | 575 | prange->last); |
| 576 | 576 | ||
| 577 | addr = prange->start << PAGE_SHIFT; | 577 | addr = migrate->start; |
| 578 | 578 | ||
| 579 | src = (uint64_t *)(scratch + npages); | 579 | src = (uint64_t *)(scratch + npages); |
| 580 | dst = scratch; | 580 | dst = scratch; |
| @@ -170,6 +170,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd, · 169 unmodified lines | |||
| 170 | m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; | 170 | m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; |
| 171 | m->cp_hqd_pq_control |= | 171 | m->cp_hqd_pq_control |= |
| 172 | ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1; | 172 | ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1; |
| 173 | m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK; | ||
| 173 | pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); | 174 | pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); |
| 174 | 175 | ||
| 175 | m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); | 176 | m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); |
| @@ -224,6 +224,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd, · 223 unmodified lines | |||
| 224 | m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; | 224 | m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; |
| 225 | m->cp_hqd_pq_control |= | 225 | m->cp_hqd_pq_control |= |
| 226 | ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1; | 226 | ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1; |
| 227 | m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK; | ||
| 227 | pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); | 228 | pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); |
| 228 | 229 | ||
| 229 | m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); | 230 | m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); |
| @@ -1488,10 +1488,15 @@ void kfd_dec_compute_active(struct kfd_node *dev); · 1487 unmodified lines | |||
| 1488 | 1488 | ||
| 1489 | /* Cgroup Support */ | 1489 | /* Cgroup Support */ |
| 1490 | /* Check with device cgroup if @kfd device is accessible */ | 1490 | /* Check with device cgroup if @kfd device is accessible */ |
| 1491 | static inline int kfd_devcgroup_check_permission(struct kfd_node *kfd) | 1491 | static inline int kfd_devcgroup_check_permission(struct kfd_node *node) |
| 1492 | { | 1492 | { |
| 1493 | #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) | 1493 | #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) |
| 1494 | struct drm_device *ddev = adev_to_drm(kfd->adev); | 1494 | struct drm_device *ddev; |
| 1495 | |||
| 1496 | if (node->xcp) | ||
| 1497 | ddev = node->xcp->ddev; | ||
| 1498 | else | ||
| 1499 | ddev = adev_to_drm(node->adev); | ||
| 1495 | 1500 | ||
| 1496 | return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR, | 1501 | return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR, |
| 1497 | ddev->render->index, | 1502 | ddev->render->index, |
| @@ -272,6 +272,7 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, · 271 unmodified lines | |||
| 272 | { | 272 | { |
| 273 | u32 v_blank_start, v_blank_end, h_position, v_position; | 273 | u32 v_blank_start, v_blank_end, h_position, v_position; |
| 274 | struct amdgpu_crtc *acrtc = NULL; | 274 | struct amdgpu_crtc *acrtc = NULL; |
| 275 | struct dc *dc = adev->dm.dc; | ||
| 275 | 276 | ||
| 276 | if ((crtc < 0) || (crtc >= adev->mode_info.num_crtc)) | 277 | if ((crtc < 0) || (crtc >= adev->mode_info.num_crtc)) |
| 277 | return -EINVAL; | 278 | return -EINVAL; |
| @@ -284,6 +285,9 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, · 6 unmodified lines | |||
| 284 | return 0; | 285 | return 0; |
| 285 | } | 286 | } |
| 286 | 287 | ||
| 288 | if (dc && dc->caps.ips_support && dc->idle_optimizations_allowed) | ||
| 289 | dc_allow_idle_optimizations(dc, false); | ||
| 290 | |||
| 287 | /* | 291 | /* |
| 288 | * TODO rework base driver to use values directly. | 292 | * TODO rework base driver to use values directly. |
| 289 | * for now parse it back into reg-format | 293 | * for now parse it back into reg-format |
| @@ -1715,7 +1719,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 1425 unmodified lines | |||
| 1715 | init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0]; | 1719 | init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0]; |
| 1716 | init_data.clk_reg_offsets = adev->reg_offset[CLK_HWIP][0]; | 1720 | init_data.clk_reg_offsets = adev->reg_offset[CLK_HWIP][0]; |
| 1717 | 1721 | ||
| 1718 | init_data.flags.disable_ips = DMUB_IPS_DISABLE_ALL; | 1722 | if (amdgpu_dc_debug_mask & DC_DISABLE_IPS) |
| 1723 | init_data.flags.disable_ips = DMUB_IPS_DISABLE_ALL; | ||
| 1724 | |||
| 1725 | init_data.flags.disable_ips_in_vpb = 1; | ||
| 1719 | 1726 | ||
| 1720 | /* Enable DWB for tested platforms only */ | 1727 | /* Enable DWB for tested platforms only */ |
| 1721 | if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0)) | 1728 | if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0)) |
| @@ -8976,16 +8983,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 7254 unmodified lines | |||
| 8976 | 8983 | ||
| 8977 | trace_amdgpu_dm_atomic_commit_tail_begin(state); | 8984 | trace_amdgpu_dm_atomic_commit_tail_begin(state); |
| 8978 | 8985 | ||
| 8979 | if (dm->dc->caps.ips_support) { | 8986 | if (dm->dc->caps.ips_support && dm->dc->idle_optimizations_allowed) |
| 8980 | for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { | 8987 | dc_allow_idle_optimizations(dm->dc, false); |
| 8981 | if (new_con_state->crtc && | ||
| 8982 | new_con_state->crtc->state->active && | ||
| 8983 | drm_atomic_crtc_needs_modeset(new_con_state->crtc->state)) { | ||
| 8984 | dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false); | ||
| 8985 | break; | ||
| 8986 | } | ||
| 8987 | } | ||
| 8988 | } | ||
| 8989 | 8988 | ||
| 8990 | drm_atomic_helper_update_legacy_modeset_state(dev, state); | 8989 | drm_atomic_helper_update_legacy_modeset_state(dev, state); |
| 8991 | drm_dp_mst_atomic_wait_for_dependencies(state); | 8990 | drm_dp_mst_atomic_wait_for_dependencies(state); |
| @@ -9188,6 +9187,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 196 unmodified lines | |||
| 9188 | * To fix this, DC should permit updating only stream properties. | 9187 | * To fix this, DC should permit updating only stream properties. |
| 9189 | */ | 9188 | */ |
| 9190 | dummy_updates = kzalloc(sizeof(struct dc_surface_update) * MAX_SURFACES, GFP_ATOMIC); | 9189 | dummy_updates = kzalloc(sizeof(struct dc_surface_update) * MAX_SURFACES, GFP_ATOMIC); |
| 9190 | if (!dummy_updates) { | ||
| 9191 | DRM_ERROR("Failed to allocate memory for dummy_updates.\n"); | ||
| 9192 | continue; | ||
| 9193 | } | ||
| 9191 | for (j = 0; j < status->plane_count; j++) | 9194 | for (j = 0; j < status->plane_count; j++) |
| 9192 | dummy_updates[j].surface = status->plane_states[0]; | 9195 | dummy_updates[j].surface = status->plane_states[0]; |
| 9193 | 9196 | ||
| @@ -10728,11 +10731,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 1534 unmodified lines | |||
| 10728 | goto fail; | 10731 | goto fail; |
| 10729 | } | 10732 | } |
| 10730 | 10733 | ||
| 10731 | ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars); | 10734 | if (dc_resource_is_dsc_encoding_supported(dc)) { |
| 10732 | if (ret) { | 10735 | ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars); |
| 10733 | DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); | 10736 | if (ret) { |
| 10734 | ret = -EINVAL; | 10737 | DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); |
| 10735 | goto fail; | 10738 | ret = -EINVAL; |
| 10739 | goto fail; | ||
| 10740 | } | ||
| 10736 | } | 10741 | } |
| 10737 | 10742 | ||
| 10738 | ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars); | 10743 | ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars); |
| @@ -711,7 +711,7 @@ static inline int dm_irq_state(struct amdgpu_device *adev, · 710 unmodified lines | |||
| 711 | { | 711 | { |
| 712 | bool st; | 712 | bool st; |
| 713 | enum dc_irq_source irq_source; | 713 | enum dc_irq_source irq_source; |
| 714 | 714 | struct dc *dc = adev->dm.dc; | |
| 715 | struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc_id]; | 715 | struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc_id]; |
| 716 | 716 | ||
| 717 | if (!acrtc) { | 717 | if (!acrtc) { |
| @@ -729,6 +729,9 @@ static inline int dm_irq_state(struct amdgpu_device *adev, · 11 unmodified lines | |||
| 729 | 729 | ||
| 730 | st = (state == AMDGPU_IRQ_STATE_ENABLE); | 730 | st = (state == AMDGPU_IRQ_STATE_ENABLE); |
| 731 | 731 | ||
| 732 | if (dc && dc->caps.ips_support && dc->idle_optimizations_allowed) | ||
| 733 | dc_allow_idle_optimizations(dc, false); | ||
| 734 | |||
| 732 | dc_interrupt_set(adev->dm.dc, irq_source, st); | 735 | dc_interrupt_set(adev->dm.dc, irq_source, st); |
| 733 | return 0; | 736 | return 0; |
| 734 | } | 737 | } |
| @@ -437,32 +437,32 @@ static struct wm_table ddr5_wm_table = { · 436 unmodified lines | |||
| 437 | .wm_inst = WM_A, | 437 | .wm_inst = WM_A, |
| 438 | .wm_type = WM_TYPE_PSTATE_CHG, | 438 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 439 | .pstate_latency_us = 11.72, | 439 | .pstate_latency_us = 11.72, |
| 440 | .sr_exit_time_us = 14.0, | 440 | .sr_exit_time_us = 28.0, |
| 441 | .sr_enter_plus_exit_time_us = 16.0, | 441 | .sr_enter_plus_exit_time_us = 30.0, |
| 442 | .valid = true, | 442 | .valid = true, |
| 443 | }, | 443 | }, |
| 444 | { | 444 | { |
| 445 | .wm_inst = WM_B, | 445 | .wm_inst = WM_B, |
| 446 | .wm_type = WM_TYPE_PSTATE_CHG, | 446 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 447 | .pstate_latency_us = 11.72, | 447 | .pstate_latency_us = 11.72, |
| 448 | .sr_exit_time_us = 14.0, | 448 | .sr_exit_time_us = 28.0, |
| 449 | .sr_enter_plus_exit_time_us = 16.0, | 449 | .sr_enter_plus_exit_time_us = 30.0, |
| 450 | .valid = true, | 450 | .valid = true, |
| 451 | }, | 451 | }, |
| 452 | { | 452 | { |
| 453 | .wm_inst = WM_C, | 453 | .wm_inst = WM_C, |
| 454 | .wm_type = WM_TYPE_PSTATE_CHG, | 454 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 455 | .pstate_latency_us = 11.72, | 455 | .pstate_latency_us = 11.72, |
| 456 | .sr_exit_time_us = 14.0, | 456 | .sr_exit_time_us = 28.0, |
| 457 | .sr_enter_plus_exit_time_us = 16.0, | 457 | .sr_enter_plus_exit_time_us = 30.0, |
| 458 | .valid = true, | 458 | .valid = true, |
| 459 | }, | 459 | }, |
| 460 | { | 460 | { |
| 461 | .wm_inst = WM_D, | 461 | .wm_inst = WM_D, |
| 462 | .wm_type = WM_TYPE_PSTATE_CHG, | 462 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 463 | .pstate_latency_us = 11.72, | 463 | .pstate_latency_us = 11.72, |
| 464 | .sr_exit_time_us = 14.0, | 464 | .sr_exit_time_us = 28.0, |
| 465 | .sr_enter_plus_exit_time_us = 16.0, | 465 | .sr_enter_plus_exit_time_us = 30.0, |
| 466 | .valid = true, | 466 | .valid = true, |
| 467 | }, | 467 | }, |
| 468 | } | 468 | } |
| @@ -474,32 +474,32 @@ static struct wm_table lpddr5_wm_table = { · 5 unmodified lines | |||
| 474 | .wm_inst = WM_A, | 474 | .wm_inst = WM_A, |
| 475 | .wm_type = WM_TYPE_PSTATE_CHG, | 475 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 476 | .pstate_latency_us = 11.65333, | 476 | .pstate_latency_us = 11.65333, |
| 477 | .sr_exit_time_us = 14.0, | 477 | .sr_exit_time_us = 28.0, |
| 478 | .sr_enter_plus_exit_time_us = 16.0, | 478 | .sr_enter_plus_exit_time_us = 30.0, |
| 479 | .valid = true, | 479 | .valid = true, |
| 480 | }, | 480 | }, |
| 481 | { | 481 | { |
| 482 | .wm_inst = WM_B, | 482 | .wm_inst = WM_B, |
| 483 | .wm_type = WM_TYPE_PSTATE_CHG, | 483 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 484 | .pstate_latency_us = 11.65333, | 484 | .pstate_latency_us = 11.65333, |
| 485 | .sr_exit_time_us = 14.0, | 485 | .sr_exit_time_us = 28.0, |
| 486 | .sr_enter_plus_exit_time_us = 16.0, | 486 | .sr_enter_plus_exit_time_us = 30.0, |
| 487 | .valid = true, | 487 | .valid = true, |
| 488 | }, | 488 | }, |
| 489 | { | 489 | { |
| 490 | .wm_inst = WM_C, | 490 | .wm_inst = WM_C, |
| 491 | .wm_type = WM_TYPE_PSTATE_CHG, | 491 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 492 | .pstate_latency_us = 11.65333, | 492 | .pstate_latency_us = 11.65333, |
| 493 | .sr_exit_time_us = 14.0, | 493 | .sr_exit_time_us = 28.0, |
| 494 | .sr_enter_plus_exit_time_us = 16.0, | 494 | .sr_enter_plus_exit_time_us = 30.0, |
| 495 | .valid = true, | 495 | .valid = true, |
| 496 | }, | 496 | }, |
| 497 | { | 497 | { |
| 498 | .wm_inst = WM_D, | 498 | .wm_inst = WM_D, |
| 499 | .wm_type = WM_TYPE_PSTATE_CHG, | 499 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 500 | .pstate_latency_us = 11.65333, | 500 | .pstate_latency_us = 11.65333, |
| 501 | .sr_exit_time_us = 14.0, | 501 | .sr_exit_time_us = 28.0, |
| 502 | .sr_enter_plus_exit_time_us = 16.0, | 502 | .sr_enter_plus_exit_time_us = 30.0, |
| 503 | .valid = true, | 503 | .valid = true, |
| 504 | }, | 504 | }, |
| 505 | } | 505 | } |
| @@ -3817,7 +3817,9 @@ static void commit_planes_for_stream(struct dc *dc, · 3816 unmodified lines | |||
| 3817 | * programming has completed (we turn on phantom OTG in order | 3817 | * programming has completed (we turn on phantom OTG in order |
| 3818 | * to complete the plane disable for phantom pipes). | 3818 | * to complete the plane disable for phantom pipes). |
| 3819 | */ | 3819 | */ |
| 3820 | dc->hwss.apply_ctx_to_hw(dc, context); | 3820 | |
| 3821 | if (dc->hwss.disable_phantom_streams) | ||
| 3822 | dc->hwss.disable_phantom_streams(dc, context); | ||
| 3821 | } | 3823 | } |
| 3822 | 3824 | ||
| 3823 | if (update_type != UPDATE_TYPE_FAST) | 3825 | if (update_type != UPDATE_TYPE_FAST) |
| @@ -291,11 +291,14 @@ void dc_state_destruct(struct dc_state *state) · 290 unmodified lines | |||
| 291 | dc_stream_release(state->phantom_streams[i]); | 291 | dc_stream_release(state->phantom_streams[i]); |
| 292 | state->phantom_streams[i] = NULL; | 292 | state->phantom_streams[i] = NULL; |
| 293 | } | 293 | } |
| 294 | state->phantom_stream_count = 0; | ||
| 294 | 295 | ||
| 295 | for (i = 0; i < state->phantom_plane_count; i++) { | 296 | for (i = 0; i < state->phantom_plane_count; i++) { |
| 296 | dc_plane_state_release(state->phantom_planes[i]); | 297 | dc_plane_state_release(state->phantom_planes[i]); |
| 297 | state->phantom_planes[i] = NULL; | 298 | state->phantom_planes[i] = NULL; |
| 298 | } | 299 | } |
| 300 | state->phantom_plane_count = 0; | ||
| 301 | |||
| 299 | state->stream_mask = 0; | 302 | state->stream_mask = 0; |
| 300 | memset(&state->res_ctx, 0, sizeof(state->res_ctx)); | 303 | memset(&state->res_ctx, 0, sizeof(state->res_ctx)); |
| 301 | memset(&state->pp_display_cfg, 0, sizeof(state->pp_display_cfg)); | 304 | memset(&state->pp_display_cfg, 0, sizeof(state->pp_display_cfg)); |
| @@ -434,6 +434,7 @@ struct dc_config { · 433 unmodified lines | |||
| 434 | bool EnableMinDispClkODM; | 434 | bool EnableMinDispClkODM; |
| 435 | bool enable_auto_dpm_test_logs; | 435 | bool enable_auto_dpm_test_logs; |
| 436 | unsigned int disable_ips; | 436 | unsigned int disable_ips; |
| 437 | unsigned int disable_ips_in_vpb; | ||
| 437 | }; | 438 | }; |
| 438 | 439 | ||
| 439 | enum visual_confirm { | 440 | enum visual_confirm { |
| @@ -1034,6 +1034,7 @@ enum replay_FW_Message_type { · 1033 unmodified lines | |||
| 1034 | Replay_Msg_Not_Support = -1, | 1034 | Replay_Msg_Not_Support = -1, |
| 1035 | Replay_Set_Timing_Sync_Supported, | 1035 | Replay_Set_Timing_Sync_Supported, |
| 1036 | Replay_Set_Residency_Frameupdate_Timer, | 1036 | Replay_Set_Residency_Frameupdate_Timer, |
| 1037 | Replay_Set_Pseudo_VTotal, | ||
| 1037 | }; | 1038 | }; |
| 1038 | 1039 | ||
| 1039 | union replay_error_status { | 1040 | union replay_error_status { |
| @@ -1089,6 +1090,10 @@ struct replay_settings { · 49 unmodified lines | |||
| 1089 | uint16_t coasting_vtotal_table[PR_COASTING_TYPE_NUM]; | 1090 | uint16_t coasting_vtotal_table[PR_COASTING_TYPE_NUM]; |
| 1090 | /* Maximum link off frame count */ | 1091 | /* Maximum link off frame count */ |
| 1091 | enum replay_link_off_frame_count_level link_off_frame_count_level; | 1092 | enum replay_link_off_frame_count_level link_off_frame_count_level; |
| 1093 | /* Replay pseudo vtotal for abm + ips on full screen video which can improve ips residency */ | ||
| 1094 | uint16_t abm_with_ips_on_full_screen_video_pseudo_vtotal; | ||
| 1095 | /* Replay last pseudo vtotal set to DMUB */ | ||
| 1096 | uint16_t last_pseudo_vtotal; | ||
| 1092 | }; | 1097 | }; |
| 1093 | 1098 | ||
| 1094 | /* To split out "global" and "per-panel" config settings. | 1099 | /* To split out "global" and "per-panel" config settings. |
| @@ -203,12 +203,12 @@ void dcn32_link_encoder_construct( · 202 unmodified lines | |||
| 203 | enc10->base.hpd_source = init_data->hpd_source; | 203 | enc10->base.hpd_source = init_data->hpd_source; |
| 204 | enc10->base.connector = init_data->connector; | 204 | enc10->base.connector = init_data->connector; |
| 205 | 205 | ||
| 206 | if (enc10->base.connector.id == CONNECTOR_ID_USBC) | ||
| 207 | enc10->base.features.flags.bits.DP_IS_USB_C = 1; | ||
| 208 | 206 | ||
| 209 | enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; | 207 | enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; |
| 210 | 208 | ||
| 211 | enc10->base.features = *enc_features; | 209 | enc10->base.features = *enc_features; |
| 210 | if (enc10->base.connector.id == CONNECTOR_ID_USBC) | ||
| 211 | enc10->base.features.flags.bits.DP_IS_USB_C = 1; | ||
| 212 | 212 | ||
| 213 | enc10->base.transmitter = init_data->transmitter; | 213 | enc10->base.transmitter = init_data->transmitter; |
| 214 | 214 | ||
| @@ -184,8 +184,6 @@ void dcn35_link_encoder_construct( · 183 unmodified lines | |||
| 184 | enc10->base.hpd_source = init_data->hpd_source; | 184 | enc10->base.hpd_source = init_data->hpd_source; |
| 185 | enc10->base.connector = init_data->connector; | 185 | enc10->base.connector = init_data->connector; |
| 186 | 186 | ||
| 187 | if (enc10->base.connector.id == CONNECTOR_ID_USBC) | ||
| 188 | enc10->base.features.flags.bits.DP_IS_USB_C = 1; | ||
| 189 | 187 | ||
| 190 | enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; | 188 | enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; |
| 191 | 189 | ||
| @@ -240,6 +238,8 @@ void dcn35_link_encoder_construct( · 48 unmodified lines | |||
| 240 | } | 238 | } |
| 241 | 239 | ||
| 242 | enc10->base.features.flags.bits.HDMI_6GB_EN = 1; | 240 | enc10->base.features.flags.bits.HDMI_6GB_EN = 1; |
| 241 | if (enc10->base.connector.id == CONNECTOR_ID_USBC) | ||
| 242 | enc10->base.features.flags.bits.DP_IS_USB_C = 1; | ||
| 243 | 243 | ||
| 244 | if (bp_funcs->get_connector_speed_cap_info) | 244 | if (bp_funcs->get_connector_speed_cap_info) |
| 245 | result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios, | 245 | result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios, |
| @@ -72,11 +72,11 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) · 71 unmodified lines | |||
| 72 | CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) | 72 | CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) |
| 73 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags) | 73 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags) |
| 74 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags) | 74 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags) |
| 75 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) | 75 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) $(frame_warn_flag) |
| 76 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags) | 76 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags) |
| 77 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) | 77 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) $(frame_warn_flag) |
| 78 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags) | 78 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags) |
| 79 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) | 79 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) $(frame_warn_flag) |
| 80 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags) | 80 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags) |
| 81 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(frame_warn_flag) | 81 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(frame_warn_flag) |
| 82 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) | 82 | CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) |
| @@ -1112,7 +1112,7 @@ struct pipe_slice_table { · 1111 unmodified lines | |||
| 1112 | struct pipe_ctx *pri_pipe; | 1112 | struct pipe_ctx *pri_pipe; |
| 1113 | struct dc_plane_state *plane; | 1113 | struct dc_plane_state *plane; |
| 1114 | int slice_count; | 1114 | int slice_count; |
| 1115 | } mpc_combines[MAX_SURFACES]; | 1115 | } mpc_combines[MAX_PLANES]; |
| 1116 | int mpc_combine_count; | 1116 | int mpc_combine_count; |
| 1117 | }; | 1117 | }; |
| 1118 | 1118 | ||
| @@ -1288,7 +1288,7 @@ static bool update_pipes_with_split_flags(struct dc *dc, struct dc_state *contex · 169 unmodified lines | |||
| 1288 | return updated; | 1288 | return updated; |
| 1289 | } | 1289 | } |
| 1290 | 1290 | ||
| 1291 | static bool should_allow_odm_power_optimization(struct dc *dc, | 1291 | static bool should_apply_odm_power_optimization(struct dc *dc, |
| 1292 | struct dc_state *context, struct vba_vars_st *v, int *split, | 1292 | struct dc_state *context, struct vba_vars_st *v, int *split, |
| 1293 | bool *merge) | 1293 | bool *merge) |
| 1294 | { | 1294 | { |
| @@ -1392,9 +1392,12 @@ static void try_odm_power_optimization_and_revalidate( · 97 unmodified lines | |||
| 1392 | { | 1392 | { |
| 1393 | int i; | 1393 | int i; |
| 1394 | unsigned int new_vlevel; | 1394 | unsigned int new_vlevel; |
| 1395 | unsigned int cur_policy[MAX_PIPES]; | ||
| 1395 | 1396 | ||
| 1396 | for (i = 0; i < pipe_cnt; i++) | 1397 | for (i = 0; i < pipe_cnt; i++) { |
| 1398 | cur_policy[i] = pipes[i].pipe.dest.odm_combine_policy; | ||
| 1397 | pipes[i].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; | 1399 | pipes[i].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; |
| 1400 | } | ||
| 1398 | 1401 | ||
| 1399 | new_vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); | 1402 | new_vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); |
| 1400 | 1403 | ||
| @@ -1403,6 +1406,9 @@ static void try_odm_power_optimization_and_revalidate( · 2 unmodified lines | |||
| 1403 | memset(merge, 0, MAX_PIPES * sizeof(bool)); | 1406 | memset(merge, 0, MAX_PIPES * sizeof(bool)); |
| 1404 | *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, new_vlevel, split, merge); | 1407 | *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, new_vlevel, split, merge); |
| 1405 | context->bw_ctx.dml.vba.VoltageLevel = *vlevel; | 1408 | context->bw_ctx.dml.vba.VoltageLevel = *vlevel; |
| 1409 | } else { | ||
| 1410 | for (i = 0; i < pipe_cnt; i++) | ||
| 1411 | pipes[i].pipe.dest.odm_combine_policy = cur_policy[i]; | ||
| 1406 | } | 1412 | } |
| 1407 | } | 1413 | } |
| 1408 | 1414 | ||
| @@ -1580,7 +1586,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, · 171 unmodified lines | |||
| 1580 | } | 1586 | } |
| 1581 | } | 1587 | } |
| 1582 | 1588 | ||
| 1583 | if (should_allow_odm_power_optimization(dc, context, vba, split, merge)) | 1589 | if (should_apply_odm_power_optimization(dc, context, vba, split, merge)) |
| 1584 | try_odm_power_optimization_and_revalidate( | 1590 | try_odm_power_optimization_and_revalidate( |
| 1585 | dc, context, pipes, split, merge, vlevel, *pipe_cnt); | 1591 | dc, context, pipes, split, merge, vlevel, *pipe_cnt); |
| 1586 | 1592 | ||
| @@ -2209,7 +2215,8 @@ bool dcn32_internal_validate_bw(struct dc *dc, · 622 unmodified lines | |||
| 2209 | int i; | 2215 | int i; |
| 2210 | 2216 | ||
| 2211 | pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); | 2217 | pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); |
| 2212 | dcn32_update_dml_pipes_odm_policy_based_on_context(dc, context, pipes); | 2218 | if (!dc->config.enable_windowed_mpo_odm) |
| 2219 | dcn32_update_dml_pipes_odm_policy_based_on_context(dc, context, pipes); | ||
| 2213 | 2220 | ||
| 2214 | /* repopulate_pipes = 1 means the pipes were either split or merged. In this case | 2221 | /* repopulate_pipes = 1 means the pipes were either split or merged. In this case |
| 2215 | * we have to re-calculate the DET allocation and run through DML once more to | 2222 | * we have to re-calculate the DET allocation and run through DML once more to |
| @@ -2753,7 +2760,7 @@ static int build_synthetic_soc_states(bool disable_dc_mode_overwrite, struct clk · 537 unmodified lines | |||
| 2753 | struct _vcs_dpi_voltage_scaling_st entry = {0}; | 2760 | struct _vcs_dpi_voltage_scaling_st entry = {0}; |
| 2754 | struct clk_limit_table_entry max_clk_data = {0}; | 2761 | struct clk_limit_table_entry max_clk_data = {0}; |
| 2755 | 2762 | ||
| 2756 | unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299; | 2763 | unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599; |
| 2757 | 2764 | ||
| 2758 | static const unsigned int num_dcfclk_stas = 5; | 2765 | static const unsigned int num_dcfclk_stas = 5; |
| 2759 | unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564}; | 2766 | unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564}; |
| @@ -164,8 +164,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { · 163 unmodified lines | |||
| 164 | }, | 164 | }, |
| 165 | }, | 165 | }, |
| 166 | .num_states = 5, | 166 | .num_states = 5, |
| 167 | .sr_exit_time_us = 14.0, | 167 | .sr_exit_time_us = 28.0, |
| 168 | .sr_enter_plus_exit_time_us = 16.0, | 168 | .sr_enter_plus_exit_time_us = 30.0, |
| 169 | .sr_exit_z8_time_us = 210.0, | 169 | .sr_exit_z8_time_us = 210.0, |
| 170 | .sr_enter_plus_exit_z8_time_us = 320.0, | 170 | .sr_enter_plus_exit_z8_time_us = 320.0, |
| 171 | .fclk_change_latency_us = 24.0, | 171 | .fclk_change_latency_us = 24.0, |
| @@ -341,9 +341,6 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, · 340 unmodified lines | |||
| 341 | break; | 341 | break; |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | if (dml2->config.bbox_overrides.clks_table.num_states) | ||
| 345 | p->in_states->num_states = dml2->config.bbox_overrides.clks_table.num_states; | ||
| 346 | |||
| 347 | /* Override from passed values, if available */ | 344 | /* Override from passed values, if available */ |
| 348 | for (i = 0; i < p->in_states->num_states; i++) { | 345 | for (i = 0; i < p->in_states->num_states; i++) { |
| 349 | if (dml2->config.bbox_overrides.sr_exit_latency_us) { | 346 | if (dml2->config.bbox_overrides.sr_exit_latency_us) { |
| @@ -400,6 +397,7 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, · 50 unmodified lines | |||
| 400 | } | 397 | } |
| 401 | /* Copy clocks tables entries, if available */ | 398 | /* Copy clocks tables entries, if available */ |
| 402 | if (dml2->config.bbox_overrides.clks_table.num_states) { | 399 | if (dml2->config.bbox_overrides.clks_table.num_states) { |
| 400 | p->in_states->num_states = dml2->config.bbox_overrides.clks_table.num_states; | ||
| 403 | 401 | ||
| 404 | for (i = 0; i < dml2->config.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels; i++) { | 402 | for (i = 0; i < dml2->config.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels; i++) { |
| 405 | p->in_states->state_array[i].dcfclk_mhz = dml2->config.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz; | 403 | p->in_states->state_array[i].dcfclk_mhz = dml2->config.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz; |
| @@ -793,35 +791,28 @@ static void populate_dml_surface_cfg_from_plane_state(enum dml_project_id dml2_p · 387 unmodified lines | |||
| 793 | } | 791 | } |
| 794 | } | 792 | } |
| 795 | 793 | ||
| 796 | /*TODO no support for mpc combine, need rework - should calculate scaling params based on plane+stream*/ | 794 | static struct scaler_data get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc_state *context) |
| 797 | static struct scaler_data get_scaler_data_for_plane(const struct dc_plane_state *in, const struct dc_state *context) | ||
| 798 | { | 795 | { |
| 799 | int i; | 796 | int i; |
| 800 | struct scaler_data data = { 0 }; | 797 | struct pipe_ctx *temp_pipe = &context->res_ctx.temp_pipe; |
| 798 | |||
| 799 | memset(temp_pipe, 0, sizeof(struct pipe_ctx)); | ||
| 801 | 800 | ||
| 802 | for (i = 0; i < MAX_PIPES; i++) { | 801 | for (i = 0; i < MAX_PIPES; i++) { |
| 803 | const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | 802 | const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; |
| 804 | 803 | ||
| 805 | if (pipe->plane_state == in && !pipe->prev_odm_pipe) { | 804 | if (pipe->plane_state == in && !pipe->prev_odm_pipe) { |
| 806 | const struct pipe_ctx *next_pipe = pipe->next_odm_pipe; | 805 | temp_pipe->stream = pipe->stream; |
| 807 | 806 | temp_pipe->plane_state = pipe->plane_state; | |
| 808 | data = context->res_ctx.pipe_ctx[i].plane_res.scl_data; | 807 | temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps; |
| 809 | while (next_pipe) { | 808 | |
| 810 | data.h_active += next_pipe->plane_res.scl_data.h_active; | 809 | resource_build_scaling_params(temp_pipe); |
| 811 | data.recout.width += next_pipe->plane_res.scl_data.recout.width; | ||
| 812 | if (in->rotation == ROTATION_ANGLE_0 || in->rotation == ROTATION_ANGLE_180) { | ||
| 813 | data.viewport.width += next_pipe->plane_res.scl_data.viewport.width; | ||
| 814 | } else { | ||
| 815 | data.viewport.height += next_pipe->plane_res.scl_data.viewport.height; | ||
| 816 | } | ||
| 817 | next_pipe = next_pipe->next_odm_pipe; | ||
| 818 | } | ||
| 819 | break; | 810 | break; |
| 820 | } | 811 | } |
| 821 | } | 812 | } |
| 822 | 813 | ||
| 823 | ASSERT(i < MAX_PIPES); | 814 | ASSERT(i < MAX_PIPES); |
| 824 | return data; | 815 | return temp_pipe->plane_res.scl_data; |
| 825 | } | 816 | } |
| 826 | 817 | ||
| 827 | static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_stream_state *in) | 818 | static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_stream_state *in) |
| @@ -866,7 +857,7 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned · 38 unmodified lines | |||
| 866 | out->ScalerEnabled[location] = false; | 857 | out->ScalerEnabled[location] = false; |
| 867 | } | 858 | } |
| 868 | 859 | ||
| 869 | static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_plane_state *in, const struct dc_state *context) | 860 | static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_plane_state *in, struct dc_state *context) |
| 870 | { | 861 | { |
| 871 | const struct scaler_data scaler_data = get_scaler_data_for_plane(in, context); | 862 | const struct scaler_data scaler_data = get_scaler_data_for_plane(in, context); |
| 872 | 863 | ||
| @@ -1183,9 +1183,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 1182 unmodified lines | |||
| 1183 | dto_params.timing = &pipe_ctx->stream->timing; | 1183 | dto_params.timing = &pipe_ctx->stream->timing; |
| 1184 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | 1184 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; |
| 1185 | if (dccg) { | 1185 | if (dccg) { |
| 1186 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | ||
| 1187 | dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); | 1186 | dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); |
| 1188 | dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); | 1187 | dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); |
| 1188 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | ||
| 1189 | } | 1189 | } |
| 1190 | } else if (dccg && dccg->funcs->disable_symclk_se) { | 1190 | } else if (dccg && dccg->funcs->disable_symclk_se) { |
| 1191 | dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, | 1191 | dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, |
| @@ -1476,7 +1476,7 @@ static enum dc_status dce110_enable_stream_timing( · 284 unmodified lines | |||
| 1476 | return DC_OK; | 1476 | return DC_OK; |
| 1477 | } | 1477 | } |
| 1478 | 1478 | ||
| 1479 | static enum dc_status apply_single_controller_ctx_to_hw( | 1479 | enum dc_status dce110_apply_single_controller_ctx_to_hw( |
| 1480 | struct pipe_ctx *pipe_ctx, | 1480 | struct pipe_ctx *pipe_ctx, |
| 1481 | struct dc_state *context, | 1481 | struct dc_state *context, |
| 1482 | struct dc *dc) | 1482 | struct dc *dc) |
| @@ -2302,7 +2302,7 @@ enum dc_status dce110_apply_ctx_to_hw( · 819 unmodified lines | |||
| 2302 | if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) | 2302 | if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) |
| 2303 | continue; | 2303 | continue; |
| 2304 | 2304 | ||
| 2305 | status = apply_single_controller_ctx_to_hw( | 2305 | status = dce110_apply_single_controller_ctx_to_hw( |
| 2306 | pipe_ctx, | 2306 | pipe_ctx, |
| 2307 | context, | 2307 | context, |
| 2308 | dc); | 2308 | dc); |
| @@ -39,6 +39,10 @@ enum dc_status dce110_apply_ctx_to_hw( · 38 unmodified lines | |||
| 39 | struct dc *dc, | 39 | struct dc *dc, |
| 40 | struct dc_state *context); | 40 | struct dc_state *context); |
| 41 | 41 | ||
| 42 | enum dc_status dce110_apply_single_controller_ctx_to_hw( | ||
| 43 | struct pipe_ctx *pipe_ctx, | ||
| 44 | struct dc_state *context, | ||
| 45 | struct dc *dc); | ||
| 42 | 46 | ||
| 43 | void dce110_enable_stream(struct pipe_ctx *pipe_ctx); | 47 | void dce110_enable_stream(struct pipe_ctx *pipe_ctx); |
| 44 | 48 | ||
| @@ -2561,7 +2561,7 @@ void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx) · 2560 unmodified lines | |||
| 2561 | tg->funcs->setup_vertical_interrupt2(tg, start_line); | 2561 | tg->funcs->setup_vertical_interrupt2(tg, start_line); |
| 2562 | } | 2562 | } |
| 2563 | 2563 | ||
| 2564 | static void dcn20_reset_back_end_for_pipe( | 2564 | void dcn20_reset_back_end_for_pipe( |
| 2565 | struct dc *dc, | 2565 | struct dc *dc, |
| 2566 | struct pipe_ctx *pipe_ctx, | 2566 | struct pipe_ctx *pipe_ctx, |
| 2567 | struct dc_state *context) | 2567 | struct dc_state *context) |
| @@ -2790,18 +2790,17 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 222 unmodified lines | |||
| 2790 | } | 2790 | } |
| 2791 | 2791 | ||
| 2792 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { | 2792 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { |
| 2793 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | ||
| 2794 | dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst); | ||
| 2795 | |||
| 2796 | phyd32clk = get_phyd32clk_src(link); | ||
| 2797 | dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk); | ||
| 2798 | |||
| 2799 | dto_params.otg_inst = tg->inst; | 2793 | dto_params.otg_inst = tg->inst; |
| 2800 | dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; | 2794 | dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; |
| 2801 | dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); | 2795 | dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); |
| 2802 | dto_params.timing = &pipe_ctx->stream->timing; | 2796 | dto_params.timing = &pipe_ctx->stream->timing; |
| 2803 | dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); | 2797 | dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); |
| 2804 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | 2798 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); |
| 2799 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | ||
| 2800 | dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst); | ||
| 2801 | |||
| 2802 | phyd32clk = get_phyd32clk_src(link); | ||
| 2803 | dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk); | ||
| 2805 | } else { | 2804 | } else { |
| 2806 | if (dccg->funcs->enable_symclk_se) | 2805 | if (dccg->funcs->enable_symclk_se) |
| 2807 | dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst, | 2806 | dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst, |
| @@ -84,6 +84,10 @@ enum dc_status dcn20_enable_stream_timing( · 83 unmodified lines | |||
| 84 | void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx); | 84 | void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx); |
| 85 | void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx); | 85 | void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx); |
| 86 | void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx); | 86 | void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx); |
| 87 | void dcn20_reset_back_end_for_pipe( | ||
| 88 | struct dc *dc, | ||
| 89 | struct pipe_ctx *pipe_ctx, | ||
| 90 | struct dc_state *context); | ||
| 87 | void dcn20_init_blank( | 91 | void dcn20_init_blank( |
| 88 | struct dc *dc, | 92 | struct dc *dc, |
| 89 | struct timing_generator *tg); | 93 | struct timing_generator *tg); |
| @@ -206,28 +206,32 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) · 205 unmodified lines | |||
| 206 | void dcn21_set_pipe(struct pipe_ctx *pipe_ctx) | 206 | void dcn21_set_pipe(struct pipe_ctx *pipe_ctx) |
| 207 | { | 207 | { |
| 208 | struct abm *abm = pipe_ctx->stream_res.abm; | 208 | struct abm *abm = pipe_ctx->stream_res.abm; |
| 209 | uint32_t otg_inst = pipe_ctx->stream_res.tg->inst; | 209 | struct timing_generator *tg = pipe_ctx->stream_res.tg; |
| 210 | struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; | 210 | struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; |
| 211 | struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu; | 211 | struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu; |
| 212 | uint32_t otg_inst; | ||
| 213 | |||
| 214 | if (!abm && !tg && !panel_cntl) | ||
| 215 | return; | ||
| 216 | |||
| 217 | otg_inst = tg->inst; | ||
| 212 | 218 | ||
| 213 | if (dmcu) { | 219 | if (dmcu) { |
| 214 | dce110_set_pipe(pipe_ctx); | 220 | dce110_set_pipe(pipe_ctx); |
| 215 | return; | 221 | return; |
| 216 | } | 222 | } |
| 217 | 223 | ||
| 218 | if (abm && panel_cntl) { | 224 | if (abm->funcs && abm->funcs->set_pipe_ex) { |
| 219 | if (abm->funcs && abm->funcs->set_pipe_ex) { | 225 | abm->funcs->set_pipe_ex(abm, |
| 220 | abm->funcs->set_pipe_ex(abm, | ||
| 221 | otg_inst, | 226 | otg_inst, |
| 222 | SET_ABM_PIPE_NORMAL, | 227 | SET_ABM_PIPE_NORMAL, |
| 223 | panel_cntl->inst, | 228 | panel_cntl->inst, |
| 224 | panel_cntl->pwrseq_inst); | 229 | panel_cntl->pwrseq_inst); |
| 225 | } else { | 230 | } else { |
| 226 | dmub_abm_set_pipe(abm, otg_inst, | 231 | dmub_abm_set_pipe(abm, otg_inst, |
| 227 | SET_ABM_PIPE_NORMAL, | 232 | SET_ABM_PIPE_NORMAL, |
| 228 | panel_cntl->inst, | 233 | panel_cntl->inst, |
| 229 | panel_cntl->pwrseq_inst); | 234 | panel_cntl->pwrseq_inst); |
| 230 | } | ||
| 231 | } | 235 | } |
| 232 | } | 236 | } |
| 233 | 237 | ||
| @@ -237,34 +241,35 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, · 3 unmodified lines | |||
| 237 | { | 241 | { |
| 238 | struct dc_context *dc = pipe_ctx->stream->ctx; | 242 | struct dc_context *dc = pipe_ctx->stream->ctx; |
| 239 | struct abm *abm = pipe_ctx->stream_res.abm; | 243 | struct abm *abm = pipe_ctx->stream_res.abm; |
| 244 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | ||
| 240 | struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; | 245 | struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; |
| 246 | uint32_t otg_inst; | ||
| 247 | |||
| 248 | if (!abm && !tg && !panel_cntl) | ||
| 249 | return false; | ||
| 250 | |||
| 251 | otg_inst = tg->inst; | ||
| 241 | 252 | ||
| 242 | if (dc->dc->res_pool->dmcu) { | 253 | if (dc->dc->res_pool->dmcu) { |
| 243 | dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp); | 254 | dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp); |
| 244 | return true; | 255 | return true; |
| 245 | } | 256 | } |
| 246 | 257 | ||
| 247 | if (abm != NULL) { | 258 | if (abm->funcs && abm->funcs->set_pipe_ex) { |
| 248 | uint32_t otg_inst = pipe_ctx->stream_res.tg->inst; | 259 | abm->funcs->set_pipe_ex(abm, |
| 249 | 260 | otg_inst, | |
| 250 | if (abm && panel_cntl) { | 261 | SET_ABM_PIPE_NORMAL, |
| 251 | if (abm->funcs && abm->funcs->set_pipe_ex) { | 262 | panel_cntl->inst, |
| 252 | abm->funcs->set_pipe_ex(abm, | 263 | panel_cntl->pwrseq_inst); |
| 253 | otg_inst, | 264 | } else { |
| 254 | SET_ABM_PIPE_NORMAL, | 265 | dmub_abm_set_pipe(abm, |
| 255 | panel_cntl->inst, | 266 | otg_inst, |
| 256 | panel_cntl->pwrseq_inst); | 267 | SET_ABM_PIPE_NORMAL, |
| 257 | } else { | 268 | panel_cntl->inst, |
| 258 | dmub_abm_set_pipe(abm, | 269 | panel_cntl->pwrseq_inst); |
| 259 | otg_inst, | ||
| 260 | SET_ABM_PIPE_NORMAL, | ||
| 261 | panel_cntl->inst, | ||
| 262 | panel_cntl->pwrseq_inst); | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | 270 | } |
| 266 | 271 | ||
| 267 | if (abm && abm->funcs && abm->funcs->set_backlight_level_pwm) | 272 | if (abm->funcs && abm->funcs->set_backlight_level_pwm) |
| 268 | abm->funcs->set_backlight_level_pwm(abm, backlight_pwm_u16_16, | 273 | abm->funcs->set_backlight_level_pwm(abm, backlight_pwm_u16_16, |
| 269 | frame_ramp, 0, panel_cntl->inst); | 274 | frame_ramp, 0, panel_cntl->inst); |
| 270 | else | 275 | else |
| @@ -1474,9 +1474,44 @@ void dcn32_update_dsc_pg(struct dc *dc, · 1473 unmodified lines | |||
| 1474 | } | 1474 | } |
| 1475 | } | 1475 | } |
| 1476 | 1476 | ||
| 1477 | void dcn32_disable_phantom_streams(struct dc *dc, struct dc_state *context) | ||
| 1478 | { | ||
| 1479 | struct dce_hwseq *hws = dc->hwseq; | ||
| 1480 | int i; | ||
| 1481 | |||
| 1482 | for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) { | ||
| 1483 | struct pipe_ctx *pipe_ctx_old = | ||
| 1484 | &dc->current_state->res_ctx.pipe_ctx[i]; | ||
| 1485 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
| 1486 | |||
| 1487 | if (!pipe_ctx_old->stream) | ||
| 1488 | continue; | ||
| 1489 | |||
| 1490 | if (dc_state_get_pipe_subvp_type(dc->current_state, pipe_ctx_old) != SUBVP_PHANTOM) | ||
| 1491 | continue; | ||
| 1492 | |||
| 1493 | if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe) | ||
| 1494 | continue; | ||
| 1495 | |||
| 1496 | if (!pipe_ctx->stream || pipe_need_reprogram(pipe_ctx_old, pipe_ctx) || | ||
| 1497 | (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM)) { | ||
| 1498 | struct clock_source *old_clk = pipe_ctx_old->clock_source; | ||
| 1499 | |||
| 1500 | if (hws->funcs.reset_back_end_for_pipe) | ||
| 1501 | hws->funcs.reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); | ||
| 1502 | if (hws->funcs.enable_stream_gating) | ||
| 1503 | hws->funcs.enable_stream_gating(dc, pipe_ctx_old); | ||
| 1504 | if (old_clk) | ||
| 1505 | old_clk->funcs->cs_power_down(old_clk); | ||
| 1506 | } | ||
| 1507 | } | ||
| 1508 | } | ||
| 1509 | |||
| 1477 | void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context) | 1510 | void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context) |
| 1478 | { | 1511 | { |
| 1479 | unsigned int i; | 1512 | unsigned int i; |
| 1513 | enum dc_status status = DC_OK; | ||
| 1514 | struct dce_hwseq *hws = dc->hwseq; | ||
| 1480 | 1515 | ||
| 1481 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 1516 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 1482 | struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | 1517 | struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; |
| @@ -1497,16 +1532,39 @@ void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context) · 14 unmodified lines | |||
| 1497 | } | 1532 | } |
| 1498 | } | 1533 | } |
| 1499 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 1534 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 1500 | struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; | 1535 | struct pipe_ctx *pipe_ctx_old = |
| 1501 | 1536 | &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 1502 | if (new_pipe->stream && dc_state_get_pipe_subvp_type(context, new_pipe) == SUBVP_PHANTOM) { | 1537 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
| 1503 | // If old context or new context has phantom pipes, apply | 1538 | |
| 1504 | // the phantom timings now. We can't change the phantom | 1539 | if (pipe_ctx->stream == NULL) |
| 1505 | // pipe configuration safely without driver acquiring | 1540 | continue; |
| 1506 | // the DMCUB lock first. | 1541 | |
| 1507 | dc->hwss.apply_ctx_to_hw(dc, context); | 1542 | if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) |
| 1508 | break; | 1543 | continue; |
| 1544 | |||
| 1545 | if (pipe_ctx->stream == pipe_ctx_old->stream && | ||
| 1546 | pipe_ctx->stream->link->link_state_valid) { | ||
| 1547 | continue; | ||
| 1509 | } | 1548 | } |
| 1549 | |||
| 1550 | if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) | ||
| 1551 | continue; | ||
| 1552 | |||
| 1553 | if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) | ||
| 1554 | continue; | ||
| 1555 | |||
| 1556 | if (hws->funcs.apply_single_controller_ctx_to_hw) | ||
| 1557 | status = hws->funcs.apply_single_controller_ctx_to_hw( | ||
| 1558 | pipe_ctx, | ||
| 1559 | context, | ||
| 1560 | dc); | ||
| 1561 | |||
| 1562 | ASSERT(status == DC_OK); | ||
| 1563 | |||
| 1564 | #ifdef CONFIG_DRM_AMD_DC_FP | ||
| 1565 | if (hws->funcs.resync_fifo_dccg_dio) | ||
| 1566 | hws->funcs.resync_fifo_dccg_dio(hws, dc, context); | ||
| 1567 | #endif | ||
| 1510 | } | 1568 | } |
| 1511 | } | 1569 | } |
| 1512 | 1570 | ||
| @@ -111,6 +111,8 @@ void dcn32_update_dsc_pg(struct dc *dc, · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context); | 112 | void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context); |
| 113 | 113 | ||
| 114 | void dcn32_disable_phantom_streams(struct dc *dc, struct dc_state *context); | ||
| 115 | |||
| 114 | void dcn32_init_blank( | 116 | void dcn32_init_blank( |
| 115 | struct dc *dc, | 117 | struct dc *dc, |
| 116 | struct timing_generator *tg); | 118 | struct timing_generator *tg); |
| @@ -109,6 +109,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { · 108 unmodified lines | |||
| 109 | .get_dcc_en_bits = dcn10_get_dcc_en_bits, | 109 | .get_dcc_en_bits = dcn10_get_dcc_en_bits, |
| 110 | .commit_subvp_config = dcn32_commit_subvp_config, | 110 | .commit_subvp_config = dcn32_commit_subvp_config, |
| 111 | .enable_phantom_streams = dcn32_enable_phantom_streams, | 111 | .enable_phantom_streams = dcn32_enable_phantom_streams, |
| 112 | .disable_phantom_streams = dcn32_disable_phantom_streams, | ||
| 112 | .subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock, | 113 | .subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock, |
| 113 | .update_visual_confirm_color = dcn10_update_visual_confirm_color, | 114 | .update_visual_confirm_color = dcn10_update_visual_confirm_color, |
| 114 | .subvp_pipe_control_lock_fast = dcn32_subvp_pipe_control_lock_fast, | 115 | .subvp_pipe_control_lock_fast = dcn32_subvp_pipe_control_lock_fast, |
| @@ -159,6 +160,8 @@ static const struct hwseq_private_funcs dcn32_private_funcs = { · 44 unmodified lines | |||
| 159 | .set_pixels_per_cycle = dcn32_set_pixels_per_cycle, | 160 | .set_pixels_per_cycle = dcn32_set_pixels_per_cycle, |
| 160 | .resync_fifo_dccg_dio = dcn32_resync_fifo_dccg_dio, | 161 | .resync_fifo_dccg_dio = dcn32_resync_fifo_dccg_dio, |
| 161 | .is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy, | 162 | .is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy, |
| 163 | .apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw, | ||
| 164 | .reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe, | ||
| 162 | }; | 165 | }; |
| 163 | 166 | ||
| 164 | void dcn32_hw_sequencer_init_functions(struct dc *dc) | 167 | void dcn32_hw_sequencer_init_functions(struct dc *dc) |
| @@ -680,7 +680,7 @@ void dcn35_power_down_on_boot(struct dc *dc) · 679 unmodified lines | |||
| 680 | bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable) | 680 | bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable) |
| 681 | { | 681 | { |
| 682 | struct dc_link *edp_links[MAX_NUM_EDP]; | 682 | struct dc_link *edp_links[MAX_NUM_EDP]; |
| 683 | int edp_num; | 683 | int i, edp_num; |
| 684 | if (dc->debug.dmcub_emulation) | 684 | if (dc->debug.dmcub_emulation) |
| 685 | return true; | 685 | return true; |
| 686 | 686 | ||
| @@ -688,6 +688,13 @@ bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable) · 1 unmodified line | |||
| 688 | dc_get_edp_links(dc, edp_links, &edp_num); | 688 | dc_get_edp_links(dc, edp_links, &edp_num); |
| 689 | if (edp_num == 0 || edp_num > 1) | 689 | if (edp_num == 0 || edp_num > 1) |
| 690 | return false; | 690 | return false; |
| 691 | |||
| 692 | for (i = 0; i < dc->current_state->stream_count; ++i) { | ||
| 693 | struct dc_stream_state *stream = dc->current_state->streams[i]; | ||
| 694 | |||
| 695 | if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal)) | ||
| 696 | return false; | ||
| 697 | } | ||
| 691 | } | 698 | } |
| 692 | 699 | ||
| 693 | // TODO: review other cases when idle optimization is allowed | 700 | // TODO: review other cases when idle optimization is allowed |
| @@ -379,6 +379,7 @@ struct hw_sequencer_funcs { · 378 unmodified lines | |||
| 379 | struct dc_cursor_attributes *cursor_attr); | 379 | struct dc_cursor_attributes *cursor_attr); |
| 380 | void (*commit_subvp_config)(struct dc *dc, struct dc_state *context); | 380 | void (*commit_subvp_config)(struct dc *dc, struct dc_state *context); |
| 381 | void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context); | 381 | void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context); |
| 382 | void (*disable_phantom_streams)(struct dc *dc, struct dc_state *context); | ||
| 382 | void (*subvp_pipe_control_lock)(struct dc *dc, | 383 | void (*subvp_pipe_control_lock)(struct dc *dc, |
| 383 | struct dc_state *context, | 384 | struct dc_state *context, |
| 384 | bool lock, | 385 | bool lock, |
| @@ -165,8 +165,15 @@ struct hwseq_private_funcs { · 164 unmodified lines | |||
| 165 | void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx); | 165 | void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx); |
| 166 | void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc, | 166 | void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc, |
| 167 | struct dc_state *context); | 167 | struct dc_state *context); |
| 168 | enum dc_status (*apply_single_controller_ctx_to_hw)( | ||
| 169 | struct pipe_ctx *pipe_ctx, | ||
| 170 | struct dc_state *context, | ||
| 171 | struct dc *dc); | ||
| 168 | bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx); | 172 | bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx); |
| 169 | #endif | 173 | #endif |
| 174 | void (*reset_back_end_for_pipe)(struct dc *dc, | ||
| 175 | struct pipe_ctx *pipe_ctx, | ||
| 176 | struct dc_state *context); | ||
| 170 | }; | 177 | }; |
| 171 | 178 | ||
| 172 | struct dce_hwseq { | 179 | struct dce_hwseq { |
| @@ -469,6 +469,8 @@ struct resource_context { · 468 unmodified lines | |||
| 469 | unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS]; | 469 | unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS]; |
| 470 | int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS]; | 470 | int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS]; |
| 471 | bool is_mpc_3dlut_acquired[MAX_PIPES]; | 471 | bool is_mpc_3dlut_acquired[MAX_PIPES]; |
| 472 | /* solely used for build scalar data in dml2 */ | ||
| 473 | struct pipe_ctx temp_pipe; | ||
| 472 | }; | 474 | }; |
| 473 | 475 | ||
| 474 | struct dce_bw_output { | 476 | struct dce_bw_output { |
| @@ -427,22 +427,18 @@ struct pipe_ctx *resource_get_primary_dpp_pipe(const struct pipe_ctx *dpp_pipe); · 426 unmodified lines | |||
| 427 | int resource_get_mpc_slice_index(const struct pipe_ctx *dpp_pipe); | 427 | int resource_get_mpc_slice_index(const struct pipe_ctx *dpp_pipe); |
| 428 | 428 | ||
| 429 | /* | 429 | /* |
| 430 | * Get number of MPC "cuts" of the plane associated with the pipe. MPC slice | 430 | * Get the number of MPC slices associated with the pipe. |
| 431 | * count is equal to MPC splits + 1. For example if a plane is cut 3 times, it | 431 | * The function returns 0 if the pipe is not associated with an MPC combine |
| 432 | * will have 4 pieces of slice. | 432 | * pipe topology. |
| 433 | * return - 0 if pipe is not used for a plane with MPCC combine. otherwise | ||
| 434 | * the number of MPC "cuts" for the plane. | ||
| 435 | */ | 433 | */ |
| 436 | int resource_get_mpc_slice_count(const struct pipe_ctx *opp_head); | 434 | int resource_get_mpc_slice_count(const struct pipe_ctx *pipe); |
| 437 | 435 | ||
| 438 | /* | 436 | /* |
| 439 | * Get number of ODM "cuts" of the timing associated with the pipe. ODM slice | 437 | * Get the number of ODM slices associated with the pipe. |
| 440 | * count is equal to ODM splits + 1. For example if a timing is cut 3 times, it | 438 | * The function returns 0 if the pipe is not associated with an ODM combine |
| 441 | * will have 4 pieces of slice. | 439 | * pipe topology. |
| 442 | * return - 0 if pipe is not used for ODM combine. otherwise | ||
| 443 | * the number of ODM "cuts" for the timing. | ||
| 444 | */ | 440 | */ |
| 445 | int resource_get_odm_slice_count(const struct pipe_ctx *otg_master); | 441 | int resource_get_odm_slice_count(const struct pipe_ctx *pipe); |
| 446 | 442 | ||
| 447 | /* Get the ODM slice index counting from 0 from left most slice */ | 443 | /* Get the ODM slice index counting from 0 from left most slice */ |
| 448 | int resource_get_odm_slice_index(const struct pipe_ctx *opp_head); | 444 | int resource_get_odm_slice_index(const struct pipe_ctx *opp_head); |
| @@ -196,7 +196,7 @@ static int get_host_router_total_dp_tunnel_bw(const struct dc *dc, uint8_t hr_in · 195 unmodified lines | |||
| 196 | struct dc_link *link_dpia_primary, *link_dpia_secondary; | 196 | struct dc_link *link_dpia_primary, *link_dpia_secondary; |
| 197 | int total_bw = 0; | 197 | int total_bw = 0; |
| 198 | 198 | ||
| 199 | for (uint8_t i = 0; i < MAX_PIPES * 2; ++i) { | 199 | for (uint8_t i = 0; i < (MAX_PIPES * 2) - 1; ++i) { |
| 200 | 200 | ||
| 201 | if (!dc->links[i] || dc->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) | 201 | if (!dc->links[i] || dc->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) |
| 202 | continue; | 202 | continue; |
| @@ -205,7 +205,7 @@ enum dc_status core_link_read_dpcd( · 204 unmodified lines | |||
| 205 | uint32_t extended_size; | 205 | uint32_t extended_size; |
| 206 | /* size of the remaining partitioned address space */ | 206 | /* size of the remaining partitioned address space */ |
| 207 | uint32_t size_left_to_read; | 207 | uint32_t size_left_to_read; |
| 208 | enum dc_status status; | 208 | enum dc_status status = DC_ERROR_UNEXPECTED; |
| 209 | /* size of the next partition to be read from */ | 209 | /* size of the next partition to be read from */ |
| 210 | uint32_t partition_size; | 210 | uint32_t partition_size; |
| 211 | uint32_t data_index = 0; | 211 | uint32_t data_index = 0; |
| @@ -234,7 +234,7 @@ enum dc_status core_link_write_dpcd( · 22 unmodified lines | |||
| 234 | { | 234 | { |
| 235 | uint32_t partition_size; | 235 | uint32_t partition_size; |
| 236 | uint32_t data_index = 0; | 236 | uint32_t data_index = 0; |
| 237 | enum dc_status status; | 237 | enum dc_status status = DC_ERROR_UNEXPECTED; |
| 238 | 238 | ||
| 239 | while (size) { | 239 | while (size) { |
| 240 | partition_size = dpcd_get_next_partition_size(address, size); | 240 | partition_size = dpcd_get_next_partition_size(address, size); |
| @@ -999,7 +999,7 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id · 998 unmodified lines | |||
| 999 | vpg = dcn301_vpg_create(ctx, vpg_inst); | 999 | vpg = dcn301_vpg_create(ctx, vpg_inst); |
| 1000 | afmt = dcn301_afmt_create(ctx, afmt_inst); | 1000 | afmt = dcn301_afmt_create(ctx, afmt_inst); |
| 1001 | 1001 | ||
| 1002 | if (!enc1 || !vpg || !afmt) { | 1002 | if (!enc1 || !vpg || !afmt || eng_id >= ARRAY_SIZE(stream_enc_regs)) { |
| 1003 | kfree(enc1); | 1003 | kfree(enc1); |
| 1004 | kfree(vpg); | 1004 | kfree(vpg); |
| 1005 | kfree(afmt); | 1005 | kfree(afmt); |
| @@ -1829,7 +1829,21 @@ int dcn32_populate_dml_pipes_from_context( · 1828 unmodified lines | |||
| 1829 | dcn32_zero_pipe_dcc_fraction(pipes, pipe_cnt); | 1829 | dcn32_zero_pipe_dcc_fraction(pipes, pipe_cnt); |
| 1830 | DC_FP_END(); | 1830 | DC_FP_END(); |
| 1831 | pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; | 1831 | pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; |
| 1832 | pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; | 1832 | if (dc->config.enable_windowed_mpo_odm && |
| 1833 | dc->debug.enable_single_display_2to1_odm_policy) { | ||
| 1834 | switch (resource_get_odm_slice_count(pipe)) { | ||
| 1835 | case 2: | ||
| 1836 | pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; | ||
| 1837 | break; | ||
| 1838 | case 4: | ||
| 1839 | pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_4to1; | ||
| 1840 | break; | ||
| 1841 | default: | ||
| 1842 | pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; | ||
| 1843 | } | ||
| 1844 | } else { | ||
| 1845 | pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; | ||
| 1846 | } | ||
| 1833 | pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet | 1847 | pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet |
| 1834 | pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; | 1848 | pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; |
| 1835 | pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19; | 1849 | pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19; |
| @@ -780,8 +780,8 @@ static const struct dc_debug_options debug_defaults_drv = { · 779 unmodified lines | |||
| 780 | .disable_z10 = false, | 780 | .disable_z10 = false, |
| 781 | .ignore_pg = true, | 781 | .ignore_pg = true, |
| 782 | .psp_disabled_wa = true, | 782 | .psp_disabled_wa = true, |
| 783 | .ips2_eval_delay_us = 200, | 783 | .ips2_eval_delay_us = 1650, |
| 784 | .ips2_entry_delay_us = 400, | 784 | .ips2_entry_delay_us = 800, |
| 785 | .static_screen_wait_frames = 2, | 785 | .static_screen_wait_frames = 2, |
| 786 | }; | 786 | }; |
| 787 | 787 | ||
| @@ -2130,6 +2130,7 @@ static bool dcn35_resource_construct( · 1342 unmodified lines | |||
| 2130 | dc->dml2_options.dcn_pipe_count = pool->base.pipe_count; | 2130 | dc->dml2_options.dcn_pipe_count = pool->base.pipe_count; |
| 2131 | dc->dml2_options.use_native_pstate_optimization = true; | 2131 | dc->dml2_options.use_native_pstate_optimization = true; |
| 2132 | dc->dml2_options.use_native_soc_bb_construction = true; | 2132 | dc->dml2_options.use_native_soc_bb_construction = true; |
| 2133 | dc->dml2_options.minimize_dispclk_using_odm = false; | ||
| 2133 | if (dc->config.EnableMinDispClkODM) | 2134 | if (dc->config.EnableMinDispClkODM) |
| 2134 | dc->dml2_options.minimize_dispclk_using_odm = true; | 2135 | dc->dml2_options.minimize_dispclk_using_odm = true; |
| 2135 | dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm; | 2136 | dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm; |
| @@ -2832,6 +2832,7 @@ struct dmub_rb_cmd_psr_set_power_opt { · 2831 unmodified lines | |||
| 2832 | #define REPLAY_RESIDENCY_MODE_MASK (0x1 << REPLAY_RESIDENCY_MODE_SHIFT) | 2832 | #define REPLAY_RESIDENCY_MODE_MASK (0x1 << REPLAY_RESIDENCY_MODE_SHIFT) |
| 2833 | # define REPLAY_RESIDENCY_MODE_PHY (0x0 << REPLAY_RESIDENCY_MODE_SHIFT) | 2833 | # define REPLAY_RESIDENCY_MODE_PHY (0x0 << REPLAY_RESIDENCY_MODE_SHIFT) |
| 2834 | # define REPLAY_RESIDENCY_MODE_ALPM (0x1 << REPLAY_RESIDENCY_MODE_SHIFT) | 2834 | # define REPLAY_RESIDENCY_MODE_ALPM (0x1 << REPLAY_RESIDENCY_MODE_SHIFT) |
| 2835 | # define REPLAY_RESIDENCY_MODE_IPS 0x10 | ||
| 2835 | 2836 | ||
| 2836 | #define REPLAY_RESIDENCY_ENABLE_MASK (0x1 << REPLAY_RESIDENCY_ENABLE_SHIFT) | 2837 | #define REPLAY_RESIDENCY_ENABLE_MASK (0x1 << REPLAY_RESIDENCY_ENABLE_SHIFT) |
| 2837 | # define REPLAY_RESIDENCY_DISABLE (0x0 << REPLAY_RESIDENCY_ENABLE_SHIFT) | 2838 | # define REPLAY_RESIDENCY_DISABLE (0x0 << REPLAY_RESIDENCY_ENABLE_SHIFT) |
| @@ -2894,6 +2895,10 @@ enum dmub_cmd_replay_type { · 56 unmodified lines | |||
| 2894 | * Set Residency Frameupdate Timer. | 2895 | * Set Residency Frameupdate Timer. |
| 2895 | */ | 2896 | */ |
| 2896 | DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER = 6, | 2897 | DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER = 6, |
| 2898 | /** | ||
| 2899 | * Set pseudo vtotal | ||
| 2900 | */ | ||
| 2901 | DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL = 7, | ||
| 2897 | }; | 2902 | }; |
| 2898 | 2903 | ||
| 2899 | /** | 2904 | /** |
| @@ -3076,6 +3081,26 @@ struct dmub_cmd_replay_set_timing_sync_data { · 176 unmodified lines | |||
| 3076 | uint8_t pad[2]; | 3081 | uint8_t pad[2]; |
| 3077 | }; | 3082 | }; |
| 3078 | 3083 | ||
| 3084 | /** | ||
| 3085 | * Data passed from driver to FW in a DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL command. | ||
| 3086 | */ | ||
| 3087 | struct dmub_cmd_replay_set_pseudo_vtotal { | ||
| 3088 | /** | ||
| 3089 | * Panel Instance. | ||
| 3090 | * Panel isntance to identify which replay_state to use | ||
| 3091 | * Currently the support is only for 0 or 1 | ||
| 3092 | */ | ||
| 3093 | uint8_t panel_inst; | ||
| 3094 | /** | ||
| 3095 | * Source Vtotal that Replay + IPS + ABM full screen video src vtotal | ||
| 3096 | */ | ||
| 3097 | uint16_t vtotal; | ||
| 3098 | /** | ||
| 3099 | * Explicit padding to 4 byte boundary. | ||
| 3100 | */ | ||
| 3101 | uint8_t pad; | ||
| 3102 | }; | ||
| 3103 | |||
| 3079 | /** | 3104 | /** |
| 3080 | * Definition of a DMUB_CMD__SET_REPLAY_POWER_OPT command. | 3105 | * Definition of a DMUB_CMD__SET_REPLAY_POWER_OPT command. |
| 3081 | */ | 3106 | */ |
| @@ -3156,6 +3181,20 @@ struct dmub_rb_cmd_replay_set_timing_sync { · 74 unmodified lines | |||
| 3156 | struct dmub_cmd_replay_set_timing_sync_data replay_set_timing_sync_data; | 3181 | struct dmub_cmd_replay_set_timing_sync_data replay_set_timing_sync_data; |
| 3157 | }; | 3182 | }; |
| 3158 | 3183 | ||
| 3184 | /** | ||
| 3185 | * Definition of a DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL command. | ||
| 3186 | */ | ||
| 3187 | struct dmub_rb_cmd_replay_set_pseudo_vtotal { | ||
| 3188 | /** | ||
| 3189 | * Command header. | ||
| 3190 | */ | ||
| 3191 | struct dmub_cmd_header header; | ||
| 3192 | /** | ||
| 3193 | * Definition of DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL command. | ||
| 3194 | */ | ||
| 3195 | struct dmub_cmd_replay_set_pseudo_vtotal data; | ||
| 3196 | }; | ||
| 3197 | |||
| 3159 | /** | 3198 | /** |
| 3160 | * Data passed from driver to FW in DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER command. | 3199 | * Data passed from driver to FW in DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER command. |
| 3161 | */ | 3200 | */ |
| @@ -3207,6 +3246,10 @@ union dmub_replay_cmd_set { · 45 unmodified lines | |||
| 3207 | * Definition of DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER command data. | 3246 | * Definition of DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER command data. |
| 3208 | */ | 3247 | */ |
| 3209 | struct dmub_cmd_replay_frameupdate_timer_data timer_data; | 3248 | struct dmub_cmd_replay_frameupdate_timer_data timer_data; |
| 3249 | /** | ||
| 3250 | * Definition of DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL command data. | ||
| 3251 | */ | ||
| 3252 | struct dmub_cmd_replay_set_pseudo_vtotal pseudo_vtotal_data; | ||
| 3210 | }; | 3253 | }; |
| 3211 | 3254 | ||
| 3212 | /** | 3255 | /** |
| @@ -4358,6 +4401,10 @@ union dmub_rb_cmd { · 1145 unmodified lines | |||
| 4358 | * Definition of a DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER command. | 4401 | * Definition of a DMUB_CMD__REPLAY_SET_RESIDENCY_FRAMEUPDATE_TIMER command. |
| 4359 | */ | 4402 | */ |
| 4360 | struct dmub_rb_cmd_replay_set_frameupdate_timer replay_set_frameupdate_timer; | 4403 | struct dmub_rb_cmd_replay_set_frameupdate_timer replay_set_frameupdate_timer; |
| 4404 | /** | ||
| 4405 | * Definition of a DMUB_CMD__REPLAY_SET_PSEUDO_VTOTAL command. | ||
| 4406 | */ | ||
| 4407 | struct dmub_rb_cmd_replay_set_pseudo_vtotal replay_set_pseudo_vtotal; | ||
| 4361 | }; | 4408 | }; |
| 4362 | 4409 | ||
| 4363 | /** | 4410 | /** |
| @@ -980,6 +980,11 @@ void set_replay_coasting_vtotal(struct dc_link *link, · 979 unmodified lines | |||
| 980 | link->replay_settings.coasting_vtotal_table[type] = vtotal; | 980 | link->replay_settings.coasting_vtotal_table[type] = vtotal; |
| 981 | } | 981 | } |
| 982 | 982 | ||
| 983 | void set_replay_ips_full_screen_video_src_vtotal(struct dc_link *link, uint16_t vtotal) | ||
| 984 | { | ||
| 985 | link->replay_settings.abm_with_ips_on_full_screen_video_pseudo_vtotal = vtotal; | ||
| 986 | } | ||
| 987 | |||
| 983 | void calculate_replay_link_off_frame_count(struct dc_link *link, | 988 | void calculate_replay_link_off_frame_count(struct dc_link *link, |
| 984 | uint16_t vtotal, uint16_t htotal) | 989 | uint16_t vtotal, uint16_t htotal) |
| 985 | { | 990 | { |
| @@ -57,6 +57,7 @@ void init_replay_config(struct dc_link *link, struct replay_config *pr_config); · 56 unmodified lines | |||
| 57 | void set_replay_coasting_vtotal(struct dc_link *link, | 57 | void set_replay_coasting_vtotal(struct dc_link *link, |
| 58 | enum replay_coasting_vtotal_type type, | 58 | enum replay_coasting_vtotal_type type, |
| 59 | uint16_t vtotal); | 59 | uint16_t vtotal); |
| 60 | void set_replay_ips_full_screen_video_src_vtotal(struct dc_link *link, uint16_t vtotal); | ||
| 60 | void calculate_replay_link_off_frame_count(struct dc_link *link, | 61 | void calculate_replay_link_off_frame_count(struct dc_link *link, |
| 61 | uint16_t vtotal, uint16_t htotal); | 62 | uint16_t vtotal, uint16_t htotal); |
| 62 | 63 | ||
| @@ -258,6 +258,7 @@ enum DC_DEBUG_MASK { · 257 unmodified lines | |||
| 258 | DC_ENABLE_DML2 = 0x100, | 258 | DC_ENABLE_DML2 = 0x100, |
| 259 | DC_DISABLE_PSR_SU = 0x200, | 259 | DC_DISABLE_PSR_SU = 0x200, |
| 260 | DC_DISABLE_REPLAY = 0x400, | 260 | DC_DISABLE_REPLAY = 0x400, |
| 261 | DC_DISABLE_IPS = 0x800, | ||
| 261 | }; | 262 | }; |
| 262 | 263 | ||
| 263 | enum amd_dpm_forced_level; | 264 | enum amd_dpm_forced_level; |
| @@ -138,7 +138,7 @@ static inline size_t amdgpu_reginst_size(uint16_t num_inst, size_t inst_size, · 137 unmodified lines | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | #define amdgpu_asic_get_reg_state_supported(adev) \ | 140 | #define amdgpu_asic_get_reg_state_supported(adev) \ |
| 141 | ((adev)->asic_funcs->get_reg_state ? 1 : 0) | 141 | (((adev)->asic_funcs && (adev)->asic_funcs->get_reg_state) ? 1 : 0) |
| 142 | 142 | ||
| 143 | #define amdgpu_asic_get_reg_state(adev, state, buf, size) \ | 143 | #define amdgpu_asic_get_reg_state(adev, state, buf, size) \ |
| 144 | ((adev)->asic_funcs->get_reg_state ? \ | 144 | ((adev)->asic_funcs->get_reg_state ? \ |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
| 26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
| 27 | #include <linux/power_supply.h> | ||
| 27 | #include <linux/reboot.h> | 28 | #include <linux/reboot.h> |
| 28 | 29 | ||
| 29 | #include "amdgpu.h" | 30 | #include "amdgpu.h" |
| @@ -733,7 +734,7 @@ static int smu_early_init(void *handle) · 703 unmodified lines | |||
| 733 | smu->adev = adev; | 734 | smu->adev = adev; |
| 734 | smu->pm_enabled = !!amdgpu_dpm; | 735 | smu->pm_enabled = !!amdgpu_dpm; |
| 735 | smu->is_apu = false; | 736 | smu->is_apu = false; |
| 736 | smu->smu_baco.state = SMU_BACO_STATE_NONE; | 737 | smu->smu_baco.state = SMU_BACO_STATE_EXIT; |
| 737 | smu->smu_baco.platform_support = false; | 738 | smu->smu_baco.platform_support = false; |
| 738 | smu->user_dpm_profile.fan_mode = -1; | 739 | smu->user_dpm_profile.fan_mode = -1; |
| 739 | 740 | ||
| @@ -817,16 +818,8 @@ static int smu_late_init(void *handle) · 77 unmodified lines | |||
| 817 | * handle the switch automatically. Driver involvement | 818 | * handle the switch automatically. Driver involvement |
| 818 | * is unnecessary. | 819 | * is unnecessary. |
| 819 | */ | 820 | */ |
| 820 | if (!smu->dc_controlled_by_gpio) { | 821 | adev->pm.ac_power = power_supply_is_system_supplied() > 0; |
| 821 | ret = smu_set_power_source(smu, | 822 | smu_set_ac_dc(smu); |
| 822 | adev->pm.ac_power ? SMU_POWER_SOURCE_AC : | ||
| 823 | SMU_POWER_SOURCE_DC); | ||
| 824 | if (ret) { | ||
| 825 | dev_err(adev->dev, "Failed to switch to %s mode!\n", | ||
| 826 | adev->pm.ac_power ? "AC" : "DC"); | ||
| 827 | return ret; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | 823 | ||
| 831 | if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 1)) || | 824 | if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 1)) || |
| 832 | (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 3))) | 825 | (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 3))) |
| @@ -1961,31 +1954,10 @@ static int smu_smc_hw_cleanup(struct smu_context *smu) · 1128 unmodified lines | |||
| 1961 | return 0; | 1954 | return 0; |
| 1962 | } | 1955 | } |
| 1963 | 1956 | ||
| 1964 | static int smu_reset_mp1_state(struct smu_context *smu) | ||
| 1965 | { | ||
| 1966 | struct amdgpu_device *adev = smu->adev; | ||
| 1967 | int ret = 0; | ||
| 1968 | |||
| 1969 | if ((!adev->in_runpm) && (!adev->in_suspend) && | ||
| 1970 | (!amdgpu_in_reset(adev))) | ||
| 1971 | switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { | ||
| 1972 | case IP_VERSION(13, 0, 0): | ||
| 1973 | case IP_VERSION(13, 0, 7): | ||
| 1974 | case IP_VERSION(13, 0, 10): | ||
| 1975 | ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD); | ||
| 1976 | break; | ||
| 1977 | default: | ||
| 1978 | break; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | return ret; | ||
| 1982 | } | ||
| 1983 | |||
| 1984 | static int smu_hw_fini(void *handle) | 1957 | static int smu_hw_fini(void *handle) |
| 1985 | { | 1958 | { |
| 1986 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1959 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1987 | struct smu_context *smu = adev->powerplay.pp_handle; | 1960 | struct smu_context *smu = adev->powerplay.pp_handle; |
| 1988 | int ret; | ||
| 1989 | 1961 | ||
| 1990 | if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) | 1962 | if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) |
| 1991 | return 0; | 1963 | return 0; |
| @@ -2003,15 +1975,7 @@ static int smu_hw_fini(void *handle) · 11 unmodified lines | |||
| 2003 | 1975 | ||
| 2004 | adev->pm.dpm_enabled = false; | 1976 | adev->pm.dpm_enabled = false; |
| 2005 | 1977 | ||
| 2006 | ret = smu_smc_hw_cleanup(smu); | 1978 | return smu_smc_hw_cleanup(smu); |
| 2007 | if (ret) | ||
| 2008 | return ret; | ||
| 2009 | |||
| 2010 | ret = smu_reset_mp1_state(smu); | ||
| 2011 | if (ret) | ||
| 2012 | return ret; | ||
| 2013 | |||
| 2014 | return 0; | ||
| 2015 | } | 1979 | } |
| 2016 | 1980 | ||
| 2017 | static void smu_late_fini(void *handle) | 1981 | static void smu_late_fini(void *handle) |
| @@ -2710,6 +2674,7 @@ int smu_get_power_limit(void *handle, · 692 unmodified lines | |||
| 2710 | case SMU_PPT_LIMIT_CURRENT: | 2674 | case SMU_PPT_LIMIT_CURRENT: |
| 2711 | switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { | 2675 | switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { |
| 2712 | case IP_VERSION(13, 0, 2): | 2676 | case IP_VERSION(13, 0, 2): |
| 2677 | case IP_VERSION(13, 0, 6): | ||
| 2713 | case IP_VERSION(11, 0, 7): | 2678 | case IP_VERSION(11, 0, 7): |
| 2714 | case IP_VERSION(11, 0, 11): | 2679 | case IP_VERSION(11, 0, 11): |
| 2715 | case IP_VERSION(11, 0, 12): | 2680 | case IP_VERSION(11, 0, 12): |
| @@ -424,7 +424,6 @@ enum smu_reset_mode { · 423 unmodified lines | |||
| 424 | enum smu_baco_state { | 424 | enum smu_baco_state { |
| 425 | SMU_BACO_STATE_ENTER = 0, | 425 | SMU_BACO_STATE_ENTER = 0, |
| 426 | SMU_BACO_STATE_EXIT, | 426 | SMU_BACO_STATE_EXIT, |
| 427 | SMU_BACO_STATE_NONE, | ||
| 428 | }; | 427 | }; |
| 429 | 428 | ||
| 430 | struct smu_baco_context { | 429 | struct smu_baco_context { |
| @@ -1442,10 +1442,12 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev, · 1441 unmodified lines | |||
| 1442 | case 0x3: | 1442 | case 0x3: |
| 1443 | dev_dbg(adev->dev, "Switched to AC mode!\n"); | 1443 | dev_dbg(adev->dev, "Switched to AC mode!\n"); |
| 1444 | schedule_work(&smu->interrupt_work); | 1444 | schedule_work(&smu->interrupt_work); |
| 1445 | adev->pm.ac_power = true; | ||
| 1445 | break; | 1446 | break; |
| 1446 | case 0x4: | 1447 | case 0x4: |
| 1447 | dev_dbg(adev->dev, "Switched to DC mode!\n"); | 1448 | dev_dbg(adev->dev, "Switched to DC mode!\n"); |
| 1448 | schedule_work(&smu->interrupt_work); | 1449 | schedule_work(&smu->interrupt_work); |
| 1450 | adev->pm.ac_power = false; | ||
| 1449 | break; | 1451 | break; |
| 1450 | case 0x7: | 1452 | case 0x7: |
| 1451 | /* | 1453 | /* |
| @@ -1379,10 +1379,12 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev, · 1378 unmodified lines | |||
| 1379 | case 0x3: | 1379 | case 0x3: |
| 1380 | dev_dbg(adev->dev, "Switched to AC mode!\n"); | 1380 | dev_dbg(adev->dev, "Switched to AC mode!\n"); |
| 1381 | smu_v13_0_ack_ac_dc_interrupt(smu); | 1381 | smu_v13_0_ack_ac_dc_interrupt(smu); |
| 1382 | adev->pm.ac_power = true; | ||
| 1382 | break; | 1383 | break; |
| 1383 | case 0x4: | 1384 | case 0x4: |
| 1384 | dev_dbg(adev->dev, "Switched to DC mode!\n"); | 1385 | dev_dbg(adev->dev, "Switched to DC mode!\n"); |
| 1385 | smu_v13_0_ack_ac_dc_interrupt(smu); | 1386 | smu_v13_0_ack_ac_dc_interrupt(smu); |
| 1387 | adev->pm.ac_power = false; | ||
| 1386 | break; | 1388 | break; |
| 1387 | case 0x7: | 1389 | case 0x7: |
| 1388 | /* | 1390 | /* |
| @@ -2357,6 +2357,7 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu, · 2356 unmodified lines | |||
| 2357 | PPTable_t *pptable = table_context->driver_pptable; | 2357 | PPTable_t *pptable = table_context->driver_pptable; |
| 2358 | SkuTable_t *skutable = &pptable->SkuTable; | 2358 | SkuTable_t *skutable = &pptable->SkuTable; |
| 2359 | uint32_t power_limit, od_percent_upper, od_percent_lower; | 2359 | uint32_t power_limit, od_percent_upper, od_percent_lower; |
| 2360 | uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; | ||
| 2360 | 2361 | ||
| 2361 | if (smu_v13_0_get_current_power_limit(smu, &power_limit)) | 2362 | if (smu_v13_0_get_current_power_limit(smu, &power_limit)) |
| 2362 | power_limit = smu->adev->pm.ac_power ? | 2363 | power_limit = smu->adev->pm.ac_power ? |
| @@ -2380,7 +2381,7 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu, · 17 unmodified lines | |||
| 2380 | od_percent_upper, od_percent_lower, power_limit); | 2381 | od_percent_upper, od_percent_lower, power_limit); |
| 2381 | 2382 | ||
| 2382 | if (max_power_limit) { | 2383 | if (max_power_limit) { |
| 2383 | *max_power_limit = power_limit * (100 + od_percent_upper); | 2384 | *max_power_limit = msg_limit * (100 + od_percent_upper); |
| 2384 | *max_power_limit /= 100; | 2385 | *max_power_limit /= 100; |
| 2385 | } | 2386 | } |
| 2386 | 2387 | ||
| @@ -2747,13 +2748,7 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu, · 360 unmodified lines | |||
| 2747 | 2748 | ||
| 2748 | switch (mp1_state) { | 2749 | switch (mp1_state) { |
| 2749 | case PP_MP1_STATE_UNLOAD: | 2750 | case PP_MP1_STATE_UNLOAD: |
| 2750 | ret = smu_cmn_send_smc_msg_with_param(smu, | 2751 | ret = smu_cmn_set_mp1_state(smu, mp1_state); |
| 2751 | SMU_MSG_PrepareMp1ForUnload, | ||
| 2752 | 0x55, NULL); | ||
| 2753 | |||
| 2754 | if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) | ||
| 2755 | ret = smu_v13_0_disable_pmfw_state(smu); | ||
| 2756 | |||
| 2757 | break; | 2752 | break; |
| 2758 | default: | 2753 | default: |
| 2759 | /* Ignore others */ | 2754 | /* Ignore others */ |
| @@ -2949,7 +2944,7 @@ static bool smu_v13_0_0_wbrf_support_check(struct smu_context *smu) · 189 unmodified lines | |||
| 2949 | { | 2944 | { |
| 2950 | struct amdgpu_device *adev = smu->adev; | 2945 | struct amdgpu_device *adev = smu->adev; |
| 2951 | 2946 | ||
| 2952 | switch (adev->ip_versions[MP1_HWIP][0]) { | 2947 | switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { |
| 2953 | case IP_VERSION(13, 0, 0): | 2948 | case IP_VERSION(13, 0, 0): |
| 2954 | return smu->smc_fw_version >= 0x004e6300; | 2949 | return smu->smc_fw_version >= 0x004e6300; |
| 2955 | case IP_VERSION(13, 0, 10): | 2950 | case IP_VERSION(13, 0, 10): |
| @@ -2959,6 +2954,55 @@ static bool smu_v13_0_0_wbrf_support_check(struct smu_context *smu) · 3 unmodified lines | |||
| 2959 | } | 2954 | } |
| 2960 | } | 2955 | } |
| 2961 | 2956 | ||
| 2957 | static int smu_v13_0_0_set_power_limit(struct smu_context *smu, | ||
| 2958 | enum smu_ppt_limit_type limit_type, | ||
| 2959 | uint32_t limit) | ||
| 2960 | { | ||
| 2961 | PPTable_t *pptable = smu->smu_table.driver_pptable; | ||
| 2962 | SkuTable_t *skutable = &pptable->SkuTable; | ||
| 2963 | uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; | ||
| 2964 | struct smu_table_context *table_context = &smu->smu_table; | ||
| 2965 | OverDriveTableExternal_t *od_table = | ||
| 2966 | (OverDriveTableExternal_t *)table_context->overdrive_table; | ||
| 2967 | int ret = 0; | ||
| 2968 | |||
| 2969 | if (limit_type != SMU_DEFAULT_PPT_LIMIT) | ||
| 2970 | return -EINVAL; | ||
| 2971 | |||
| 2972 | if (limit <= msg_limit) { | ||
| 2973 | if (smu->current_power_limit > msg_limit) { | ||
| 2974 | od_table->OverDriveTable.Ppt = 0; | ||
| 2975 | od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT; | ||
| 2976 | |||
| 2977 | ret = smu_v13_0_0_upload_overdrive_table(smu, od_table); | ||
| 2978 | if (ret) { | ||
| 2979 | dev_err(smu->adev->dev, "Failed to upload overdrive table!\n"); | ||
| 2980 | return ret; | ||
| 2981 | } | ||
| 2982 | } | ||
| 2983 | return smu_v13_0_set_power_limit(smu, limit_type, limit); | ||
| 2984 | } else if (smu->od_enabled) { | ||
| 2985 | ret = smu_v13_0_set_power_limit(smu, limit_type, msg_limit); | ||
| 2986 | if (ret) | ||
| 2987 | return ret; | ||
| 2988 | |||
| 2989 | od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100; | ||
| 2990 | od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT; | ||
| 2991 | |||
| 2992 | ret = smu_v13_0_0_upload_overdrive_table(smu, od_table); | ||
| 2993 | if (ret) { | ||
| 2994 | dev_err(smu->adev->dev, "Failed to upload overdrive table!\n"); | ||
| 2995 | return ret; | ||
| 2996 | } | ||
| 2997 | |||
| 2998 | smu->current_power_limit = limit; | ||
| 2999 | } else { | ||
| 3000 | return -EINVAL; | ||
| 3001 | } | ||
| 3002 | |||
| 3003 | return 0; | ||
| 3004 | } | ||
| 3005 | |||
| 2962 | static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { | 3006 | static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { |
| 2963 | .get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask, | 3007 | .get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask, |
| 2964 | .set_default_dpm_table = smu_v13_0_0_set_default_dpm_table, | 3008 | .set_default_dpm_table = smu_v13_0_0_set_default_dpm_table, |
| @@ -3013,7 +3057,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { · 48 unmodified lines | |||
| 3013 | .set_fan_control_mode = smu_v13_0_set_fan_control_mode, | 3057 | .set_fan_control_mode = smu_v13_0_set_fan_control_mode, |
| 3014 | .enable_mgpu_fan_boost = smu_v13_0_0_enable_mgpu_fan_boost, | 3058 | .enable_mgpu_fan_boost = smu_v13_0_0_enable_mgpu_fan_boost, |
| 3015 | .get_power_limit = smu_v13_0_0_get_power_limit, | 3059 | .get_power_limit = smu_v13_0_0_get_power_limit, |
| 3016 | .set_power_limit = smu_v13_0_set_power_limit, | 3060 | .set_power_limit = smu_v13_0_0_set_power_limit, |
| 3017 | .set_power_source = smu_v13_0_set_power_source, | 3061 | .set_power_source = smu_v13_0_set_power_source, |
| 3018 | .get_power_profile_mode = smu_v13_0_0_get_power_profile_mode, | 3062 | .get_power_profile_mode = smu_v13_0_0_get_power_profile_mode, |
| 3019 | .set_power_profile_mode = smu_v13_0_0_set_power_profile_mode, | 3063 | .set_power_profile_mode = smu_v13_0_0_set_power_profile_mode, |
| @@ -160,8 +160,8 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU · 159 unmodified lines | |||
| 160 | MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), | 160 | MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), |
| 161 | MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 1), | 161 | MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 1), |
| 162 | MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 1), | 162 | MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 1), |
| 163 | MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxClk, 0), | 163 | MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxClk, 1), |
| 164 | MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 0), | 164 | MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), |
| 165 | MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareForDriverUnload, 0), | 165 | MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareForDriverUnload, 0), |
| 166 | MSG_MAP(GetCTFLimit, PPSMC_MSG_GetCTFLimit, 0), | 166 | MSG_MAP(GetCTFLimit, PPSMC_MSG_GetCTFLimit, 0), |
| 167 | MSG_MAP(GetThermalLimit, PPSMC_MSG_ReadThrottlerLimit, 0), | 167 | MSG_MAP(GetThermalLimit, PPSMC_MSG_ReadThrottlerLimit, 0), |
| @@ -2321,6 +2321,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, · 2320 unmodified lines | |||
| 2321 | PPTable_t *pptable = table_context->driver_pptable; | 2321 | PPTable_t *pptable = table_context->driver_pptable; |
| 2322 | SkuTable_t *skutable = &pptable->SkuTable; | 2322 | SkuTable_t *skutable = &pptable->SkuTable; |
| 2323 | uint32_t power_limit, od_percent_upper, od_percent_lower; | 2323 | uint32_t power_limit, od_percent_upper, od_percent_lower; |
| 2324 | uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; | ||
| 2324 | 2325 | ||
| 2325 | if (smu_v13_0_get_current_power_limit(smu, &power_limit)) | 2326 | if (smu_v13_0_get_current_power_limit(smu, &power_limit)) |
| 2326 | power_limit = smu->adev->pm.ac_power ? | 2327 | power_limit = smu->adev->pm.ac_power ? |
| @@ -2344,7 +2345,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, · 17 unmodified lines | |||
| 2344 | od_percent_upper, od_percent_lower, power_limit); | 2345 | od_percent_upper, od_percent_lower, power_limit); |
| 2345 | 2346 | ||
| 2346 | if (max_power_limit) { | 2347 | if (max_power_limit) { |
| 2347 | *max_power_limit = power_limit * (100 + od_percent_upper); | 2348 | *max_power_limit = msg_limit * (100 + od_percent_upper); |
| 2348 | *max_power_limit /= 100; | 2349 | *max_power_limit /= 100; |
| 2349 | } | 2350 | } |
| 2350 | 2351 | ||
| @@ -2504,13 +2505,7 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu, · 153 unmodified lines | |||
| 2504 | 2505 | ||
| 2505 | switch (mp1_state) { | 2506 | switch (mp1_state) { |
| 2506 | case PP_MP1_STATE_UNLOAD: | 2507 | case PP_MP1_STATE_UNLOAD: |
| 2507 | ret = smu_cmn_send_smc_msg_with_param(smu, | 2508 | ret = smu_cmn_set_mp1_state(smu, mp1_state); |
| 2508 | SMU_MSG_PrepareMp1ForUnload, | ||
| 2509 | 0x55, NULL); | ||
| 2510 | |||
| 2511 | if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) | ||
| 2512 | ret = smu_v13_0_disable_pmfw_state(smu); | ||
| 2513 | |||
| 2514 | break; | 2509 | break; |
| 2515 | default: | 2510 | default: |
| 2516 | /* Ignore others */ | 2511 | /* Ignore others */ |
| @@ -2545,6 +2540,55 @@ static bool smu_v13_0_7_wbrf_support_check(struct smu_context *smu) · 28 unmodified lines | |||
| 2545 | return smu->smc_fw_version > 0x00524600; | 2540 | return smu->smc_fw_version > 0x00524600; |
| 2546 | } | 2541 | } |
| 2547 | 2542 | ||
| 2543 | static int smu_v13_0_7_set_power_limit(struct smu_context *smu, | ||
| 2544 | enum smu_ppt_limit_type limit_type, | ||
| 2545 | uint32_t limit) | ||
| 2546 | { | ||
| 2547 | PPTable_t *pptable = smu->smu_table.driver_pptable; | ||
| 2548 | SkuTable_t *skutable = &pptable->SkuTable; | ||
| 2549 | uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; | ||
| 2550 | struct smu_table_context *table_context = &smu->smu_table; | ||
| 2551 | OverDriveTableExternal_t *od_table = | ||
| 2552 | (OverDriveTableExternal_t *)table_context->overdrive_table; | ||
| 2553 | int ret = 0; | ||
| 2554 | |||
| 2555 | if (limit_type != SMU_DEFAULT_PPT_LIMIT) | ||
| 2556 | return -EINVAL; | ||
| 2557 | |||
| 2558 | if (limit <= msg_limit) { | ||
| 2559 | if (smu->current_power_limit > msg_limit) { | ||
| 2560 | od_table->OverDriveTable.Ppt = 0; | ||
| 2561 | od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT; | ||
| 2562 | |||
| 2563 | ret = smu_v13_0_7_upload_overdrive_table(smu, od_table); | ||
| 2564 | if (ret) { | ||
| 2565 | dev_err(smu->adev->dev, "Failed to upload overdrive table!\n"); | ||
| 2566 | return ret; | ||
| 2567 | } | ||
| 2568 | } | ||
| 2569 | return smu_v13_0_set_power_limit(smu, limit_type, limit); | ||
| 2570 | } else if (smu->od_enabled) { | ||
| 2571 | ret = smu_v13_0_set_power_limit(smu, limit_type, msg_limit); | ||
| 2572 | if (ret) | ||
| 2573 | return ret; | ||
| 2574 | |||
| 2575 | od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100; | ||
| 2576 | od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT; | ||
| 2577 | |||
| 2578 | ret = smu_v13_0_7_upload_overdrive_table(smu, od_table); | ||
| 2579 | if (ret) { | ||
| 2580 | dev_err(smu->adev->dev, "Failed to upload overdrive table!\n"); | ||
| 2581 | return ret; | ||
| 2582 | } | ||
| 2583 | |||
| 2584 | smu->current_power_limit = limit; | ||
| 2585 | } else { | ||
| 2586 | return -EINVAL; | ||
| 2587 | } | ||
| 2588 | |||
| 2589 | return 0; | ||
| 2590 | } | ||
| 2591 | |||
| 2548 | static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { | 2592 | static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { |
| 2549 | .get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask, | 2593 | .get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask, |
| 2550 | .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table, | 2594 | .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table, |
| @@ -2596,7 +2640,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { · 45 unmodified lines | |||
| 2596 | .set_fan_control_mode = smu_v13_0_set_fan_control_mode, | 2640 | .set_fan_control_mode = smu_v13_0_set_fan_control_mode, |
| 2597 | .enable_mgpu_fan_boost = smu_v13_0_7_enable_mgpu_fan_boost, | 2641 | .enable_mgpu_fan_boost = smu_v13_0_7_enable_mgpu_fan_boost, |
| 2598 | .get_power_limit = smu_v13_0_7_get_power_limit, | 2642 | .get_power_limit = smu_v13_0_7_get_power_limit, |
| 2599 | .set_power_limit = smu_v13_0_set_power_limit, | 2643 | .set_power_limit = smu_v13_0_7_set_power_limit, |
| 2600 | .set_power_source = smu_v13_0_set_power_source, | 2644 | .set_power_source = smu_v13_0_set_power_source, |
| 2601 | .get_power_profile_mode = smu_v13_0_7_get_power_profile_mode, | 2645 | .get_power_profile_mode = smu_v13_0_7_get_power_profile_mode, |
| 2602 | .set_power_profile_mode = smu_v13_0_7_set_power_profile_mode, | 2646 | .set_power_profile_mode = smu_v13_0_7_set_power_profile_mode, |
| @@ -1762,6 +1762,7 @@ static ssize_t anx7625_aux_transfer(struct drm_dp_aux *aux, · 1761 unmodified lines | |||
| 1762 | u8 request = msg->request & ~DP_AUX_I2C_MOT; | 1762 | u8 request = msg->request & ~DP_AUX_I2C_MOT; |
| 1763 | int ret = 0; | 1763 | int ret = 0; |
| 1764 | 1764 | ||
| 1765 | mutex_lock(&ctx->aux_lock); | ||
| 1765 | pm_runtime_get_sync(dev); | 1766 | pm_runtime_get_sync(dev); |
| 1766 | msg->reply = 0; | 1767 | msg->reply = 0; |
| 1767 | switch (request) { | 1768 | switch (request) { |
| @@ -1778,6 +1779,7 @@ static ssize_t anx7625_aux_transfer(struct drm_dp_aux *aux, · 10 unmodified lines | |||
| 1778 | msg->size, msg->buffer); | 1779 | msg->size, msg->buffer); |
| 1779 | pm_runtime_mark_last_busy(dev); | 1780 | pm_runtime_mark_last_busy(dev); |
| 1780 | pm_runtime_put_autosuspend(dev); | 1781 | pm_runtime_put_autosuspend(dev); |
| 1782 | mutex_unlock(&ctx->aux_lock); | ||
| 1781 | 1783 | ||
| 1782 | return ret; | 1784 | return ret; |
| 1783 | } | 1785 | } |
| @@ -2474,7 +2476,9 @@ static void anx7625_bridge_atomic_disable(struct drm_bridge *bridge, · 690 unmodified lines | |||
| 2474 | ctx->connector = NULL; | 2476 | ctx->connector = NULL; |
| 2475 | anx7625_dp_stop(ctx); | 2477 | anx7625_dp_stop(ctx); |
| 2476 | 2478 | ||
| 2477 | pm_runtime_put_sync(dev); | 2479 | mutex_lock(&ctx->aux_lock); |
| 2480 | pm_runtime_put_sync_suspend(dev); | ||
| 2481 | mutex_unlock(&ctx->aux_lock); | ||
| 2478 | } | 2482 | } |
| 2479 | 2483 | ||
| 2480 | static enum drm_connector_status | 2484 | static enum drm_connector_status |
| @@ -2668,6 +2672,7 @@ static int anx7625_i2c_probe(struct i2c_client *client) · 187 unmodified lines | |||
| 2668 | 2672 | ||
| 2669 | mutex_init(&platform->lock); | 2673 | mutex_init(&platform->lock); |
| 2670 | mutex_init(&platform->hdcp_wq_lock); | 2674 | mutex_init(&platform->hdcp_wq_lock); |
| 2675 | mutex_init(&platform->aux_lock); | ||
| 2671 | 2676 | ||
| 2672 | INIT_DELAYED_WORK(&platform->hdcp_work, hdcp_check_work_func); | 2677 | INIT_DELAYED_WORK(&platform->hdcp_work, hdcp_check_work_func); |
| 2673 | platform->hdcp_workqueue = create_workqueue("hdcp workqueue"); | 2678 | platform->hdcp_workqueue = create_workqueue("hdcp workqueue"); |
| @@ -475,6 +475,8 @@ struct anx7625_data { · 474 unmodified lines | |||
| 475 | struct workqueue_struct *hdcp_workqueue; | 475 | struct workqueue_struct *hdcp_workqueue; |
| 476 | /* Lock for hdcp work queue */ | 476 | /* Lock for hdcp work queue */ |
| 477 | struct mutex hdcp_wq_lock; | 477 | struct mutex hdcp_wq_lock; |
| 478 | /* Lock for aux transfer and disable */ | ||
| 479 | struct mutex aux_lock; | ||
| 478 | char edid_block; | 480 | char edid_block; |
| 479 | struct display_timing dt; | 481 | struct display_timing dt; |
| 480 | u8 display_timing_valid; | 482 | u8 display_timing_valid; |
| @@ -107,6 +107,7 @@ struct ps8640 { · 106 unmodified lines | |||
| 107 | struct device_link *link; | 107 | struct device_link *link; |
| 108 | bool pre_enabled; | 108 | bool pre_enabled; |
| 109 | bool need_post_hpd_delay; | 109 | bool need_post_hpd_delay; |
| 110 | struct mutex aux_lock; | ||
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | static const struct regmap_config ps8640_regmap_config[] = { | 113 | static const struct regmap_config ps8640_regmap_config[] = { |
| @@ -345,11 +346,20 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux, · 232 unmodified lines | |||
| 345 | struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; | 346 | struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; |
| 346 | int ret; | 347 | int ret; |
| 347 | 348 | ||
| 349 | mutex_lock(&ps_bridge->aux_lock); | ||
| 348 | pm_runtime_get_sync(dev); | 350 | pm_runtime_get_sync(dev); |
| 351 | ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000); | ||
| 352 | if (ret) { | ||
| 353 | pm_runtime_put_sync_suspend(dev); | ||
| 354 | goto exit; | ||
| 355 | } | ||
| 349 | ret = ps8640_aux_transfer_msg(aux, msg); | 356 | ret = ps8640_aux_transfer_msg(aux, msg); |
| 350 | pm_runtime_mark_last_busy(dev); | 357 | pm_runtime_mark_last_busy(dev); |
| 351 | pm_runtime_put_autosuspend(dev); | 358 | pm_runtime_put_autosuspend(dev); |
| 352 | 359 | ||
| 360 | exit: | ||
| 361 | mutex_unlock(&ps_bridge->aux_lock); | ||
| 362 | |||
| 353 | return ret; | 363 | return ret; |
| 354 | } | 364 | } |
| 355 | 365 | ||
| @@ -470,7 +480,18 @@ static void ps8640_atomic_post_disable(struct drm_bridge *bridge, · 114 unmodified lines | |||
| 470 | ps_bridge->pre_enabled = false; | 480 | ps_bridge->pre_enabled = false; |
| 471 | 481 | ||
| 472 | ps8640_bridge_vdo_control(ps_bridge, DISABLE); | 482 | ps8640_bridge_vdo_control(ps_bridge, DISABLE); |
| 483 | |||
| 484 | /* | ||
| 485 | * The bridge seems to expect everything to be power cycled at the | ||
| 486 | * disable process, so grab a lock here to make sure | ||
| 487 | * ps8640_aux_transfer() is not holding a runtime PM reference and | ||
| 488 | * preventing the bridge from suspend. | ||
| 489 | */ | ||
| 490 | mutex_lock(&ps_bridge->aux_lock); | ||
| 491 | |||
| 473 | pm_runtime_put_sync_suspend(&ps_bridge->page[PAGE0_DP_CNTL]->dev); | 492 | pm_runtime_put_sync_suspend(&ps_bridge->page[PAGE0_DP_CNTL]->dev); |
| 493 | |||
| 494 | mutex_unlock(&ps_bridge->aux_lock); | ||
| 474 | } | 495 | } |
| 475 | 496 | ||
| 476 | static int ps8640_bridge_attach(struct drm_bridge *bridge, | 497 | static int ps8640_bridge_attach(struct drm_bridge *bridge, |
| @@ -619,6 +640,8 @@ static int ps8640_probe(struct i2c_client *client) · 142 unmodified lines | |||
| 619 | if (!ps_bridge) | 640 | if (!ps_bridge) |
| 620 | return -ENOMEM; | 641 | return -ENOMEM; |
| 621 | 642 | ||
| 643 | mutex_init(&ps_bridge->aux_lock); | ||
| 644 | |||
| 622 | ps_bridge->supplies[0].supply = "vdd12"; | 645 | ps_bridge->supplies[0].supply = "vdd12"; |
| 623 | ps_bridge->supplies[1].supply = "vdd33"; | 646 | ps_bridge->supplies[1].supply = "vdd33"; |
| 624 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), | 647 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), |
| @@ -969,10 +969,6 @@ static int samsung_dsim_init_link(struct samsung_dsim *dsi) · 968 unmodified lines | |||
| 969 | reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); | 969 | reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); |
| 970 | reg &= ~DSIM_STOP_STATE_CNT_MASK; | 970 | reg &= ~DSIM_STOP_STATE_CNT_MASK; |
| 971 | reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]); | 971 | reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]); |
| 972 | |||
| 973 | if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) | ||
| 974 | reg |= DSIM_FORCE_STOP_STATE; | ||
| 975 | |||
| 976 | samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); | 972 | samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); |
| 977 | 973 | ||
| 978 | reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff); | 974 | reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff); |
| @@ -1431,18 +1427,6 @@ static void samsung_dsim_disable_irq(struct samsung_dsim *dsi) · 452 unmodified lines | |||
| 1431 | disable_irq(dsi->irq); | 1427 | disable_irq(dsi->irq); |
| 1432 | } | 1428 | } |
| 1433 | 1429 | ||
| 1434 | static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool enable) | ||
| 1435 | { | ||
| 1436 | u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); | ||
| 1437 | |||
| 1438 | if (enable) | ||
| 1439 | reg |= DSIM_FORCE_STOP_STATE; | ||
| 1440 | else | ||
| 1441 | reg &= ~DSIM_FORCE_STOP_STATE; | ||
| 1442 | |||
| 1443 | samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); | ||
| 1444 | } | ||
| 1445 | |||
| 1446 | static int samsung_dsim_init(struct samsung_dsim *dsi) | 1430 | static int samsung_dsim_init(struct samsung_dsim *dsi) |
| 1447 | { | 1431 | { |
| 1448 | const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; | 1432 | const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; |
| @@ -1492,9 +1476,6 @@ static void samsung_dsim_atomic_pre_enable(struct drm_bridge *bridge, · 43 unmodified lines | |||
| 1492 | ret = samsung_dsim_init(dsi); | 1476 | ret = samsung_dsim_init(dsi); |
| 1493 | if (ret) | 1477 | if (ret) |
| 1494 | return; | 1478 | return; |
| 1495 | |||
| 1496 | samsung_dsim_set_display_mode(dsi); | ||
| 1497 | samsung_dsim_set_display_enable(dsi, true); | ||
| 1498 | } | 1479 | } |
| 1499 | } | 1480 | } |
| 1500 | 1481 | ||
| @@ -1503,12 +1484,8 @@ static void samsung_dsim_atomic_enable(struct drm_bridge *bridge, · 2 unmodified lines | |||
| 1503 | { | 1484 | { |
| 1504 | struct samsung_dsim *dsi = bridge_to_dsi(bridge); | 1485 | struct samsung_dsim *dsi = bridge_to_dsi(bridge); |
| 1505 | 1486 | ||
| 1506 | if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) { | 1487 | samsung_dsim_set_display_mode(dsi); |
| 1507 | samsung_dsim_set_display_mode(dsi); | 1488 | samsung_dsim_set_display_enable(dsi, true); |
| 1508 | samsung_dsim_set_display_enable(dsi, true); | ||
| 1509 | } else { | ||
| 1510 | samsung_dsim_set_stop_state(dsi, false); | ||
| 1511 | } | ||
| 1512 | 1489 | ||
| 1513 | dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; | 1490 | dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; |
| 1514 | } | 1491 | } |
| @@ -1521,9 +1498,6 @@ static void samsung_dsim_atomic_disable(struct drm_bridge *bridge, · 6 unmodified lines | |||
| 1521 | if (!(dsi->state & DSIM_STATE_ENABLED)) | 1498 | if (!(dsi->state & DSIM_STATE_ENABLED)) |
| 1522 | return; | 1499 | return; |
| 1523 | 1500 | ||
| 1524 | if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) | ||
| 1525 | samsung_dsim_set_stop_state(dsi, true); | ||
| 1526 | |||
| 1527 | dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; | 1501 | dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; |
| 1528 | } | 1502 | } |
| 1529 | 1503 | ||
| @@ -1828,8 +1802,6 @@ static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host, · 298 unmodified lines | |||
| 1828 | if (ret) | 1802 | if (ret) |
| 1829 | return ret; | 1803 | return ret; |
| 1830 | 1804 | ||
| 1831 | samsung_dsim_set_stop_state(dsi, false); | ||
| 1832 | |||
| 1833 | ret = mipi_dsi_create_packet(&xfer.packet, msg); | 1805 | ret = mipi_dsi_create_packet(&xfer.packet, msg); |
| 1834 | if (ret < 0) | 1806 | if (ret < 0) |
| 1835 | return ret; | 1807 | return ret; |
| @@ -1080,6 +1080,26 @@ static int sii902x_init(struct sii902x *sii902x) · 1079 unmodified lines | |||
| 1080 | return ret; | 1080 | return ret; |
| 1081 | } | 1081 | } |
| 1082 | 1082 | ||
| 1083 | ret = sii902x_audio_codec_init(sii902x, dev); | ||
| 1084 | if (ret) | ||
| 1085 | return ret; | ||
| 1086 | |||
| 1087 | i2c_set_clientdata(sii902x->i2c, sii902x); | ||
| 1088 | |||
| 1089 | sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev, | ||
| 1090 | 1, 0, I2C_MUX_GATE, | ||
| 1091 | sii902x_i2c_bypass_select, | ||
| 1092 | sii902x_i2c_bypass_deselect); | ||
| 1093 | if (!sii902x->i2cmux) { | ||
| 1094 | ret = -ENOMEM; | ||
| 1095 | goto err_unreg_audio; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | sii902x->i2cmux->priv = sii902x; | ||
| 1099 | ret = i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); | ||
| 1100 | if (ret) | ||
| 1101 | goto err_unreg_audio; | ||
| 1102 | |||
| 1083 | sii902x->bridge.funcs = &sii902x_bridge_funcs; | 1103 | sii902x->bridge.funcs = &sii902x_bridge_funcs; |
| 1084 | sii902x->bridge.of_node = dev->of_node; | 1104 | sii902x->bridge.of_node = dev->of_node; |
| 1085 | sii902x->bridge.timings = &default_sii902x_timings; | 1105 | sii902x->bridge.timings = &default_sii902x_timings; |
| @@ -1090,19 +1110,13 @@ static int sii902x_init(struct sii902x *sii902x) · 4 unmodified lines | |||
| 1090 | 1110 | ||
| 1091 | drm_bridge_add(&sii902x->bridge); | 1111 | drm_bridge_add(&sii902x->bridge); |
| 1092 | 1112 | ||
| 1093 | sii902x_audio_codec_init(sii902x, dev); | 1113 | return 0; |
| 1094 | |||
| 1095 | i2c_set_clientdata(sii902x->i2c, sii902x); | ||
| 1096 | 1114 | ||
| 1097 | sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev, | 1115 | err_unreg_audio: |
| 1098 | 1, 0, I2C_MUX_GATE, | 1116 | if (!PTR_ERR_OR_ZERO(sii902x->audio.pdev)) |
| 1099 | sii902x_i2c_bypass_select, | 1117 | platform_device_unregister(sii902x->audio.pdev); |
| 1100 | sii902x_i2c_bypass_deselect); | ||
| 1101 | if (!sii902x->i2cmux) | ||
| 1102 | return -ENOMEM; | ||
| 1103 | 1118 | ||
| 1104 | sii902x->i2cmux->priv = sii902x; | 1119 | return ret; |
| 1105 | return i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); | ||
| 1106 | } | 1120 | } |
| 1107 | 1121 | ||
| 1108 | static int sii902x_probe(struct i2c_client *client) | 1122 | static int sii902x_probe(struct i2c_client *client) |
| @@ -1170,12 +1184,14 @@ static int sii902x_probe(struct i2c_client *client) · 61 unmodified lines | |||
| 1170 | } | 1184 | } |
| 1171 | 1185 | ||
| 1172 | static void sii902x_remove(struct i2c_client *client) | 1186 | static void sii902x_remove(struct i2c_client *client) |
| 1173 | |||
| 1174 | { | 1187 | { |
| 1175 | struct sii902x *sii902x = i2c_get_clientdata(client); | 1188 | struct sii902x *sii902x = i2c_get_clientdata(client); |
| 1176 | 1189 | ||
| 1177 | i2c_mux_del_adapters(sii902x->i2cmux); | ||
| 1178 | drm_bridge_remove(&sii902x->bridge); | 1190 | drm_bridge_remove(&sii902x->bridge); |
| 1191 | i2c_mux_del_adapters(sii902x->i2cmux); | ||
| 1192 | |||
| 1193 | if (!PTR_ERR_OR_ZERO(sii902x->audio.pdev)) | ||
| 1194 | platform_device_unregister(sii902x->audio.pdev); | ||
| 1179 | } | 1195 | } |
| 1180 | 1196 | ||
| 1181 | static const struct of_device_id sii902x_dt_ids[] = { | 1197 | static const struct of_device_id sii902x_dt_ids[] = { |
| @@ -5491,6 +5491,7 @@ EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc); · 5490 unmodified lines | |||
| 5491 | * - 0 if the new state is valid | 5491 | * - 0 if the new state is valid |
| 5492 | * - %-ENOSPC, if the new state is invalid, because of BW limitation | 5492 | * - %-ENOSPC, if the new state is invalid, because of BW limitation |
| 5493 | * @failing_port is set to: | 5493 | * @failing_port is set to: |
| 5494 | * | ||
| 5494 | * - The non-root port where a BW limit check failed | 5495 | * - The non-root port where a BW limit check failed |
| 5495 | * with all the ports downstream of @failing_port passing | 5496 | * with all the ports downstream of @failing_port passing |
| 5496 | * the BW limit check. | 5497 | * the BW limit check. |
| @@ -5499,6 +5500,7 @@ EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc); · 2 unmodified lines | |||
| 5499 | * - %NULL if the BW limit check failed at the root port | 5500 | * - %NULL if the BW limit check failed at the root port |
| 5500 | * with all the ports downstream of the root port passing | 5501 | * with all the ports downstream of the root port passing |
| 5501 | * the BW limit check. | 5502 | * the BW limit check. |
| 5503 | * | ||
| 5502 | * - %-EINVAL, if the new state is invalid, because the root port has | 5504 | * - %-EINVAL, if the new state is invalid, because the root port has |
| 5503 | * too many payloads. | 5505 | * too many payloads. |
| 5504 | */ | 5506 | */ |
| @@ -319,9 +319,9 @@ static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win, · 318 unmodified lines | |||
| 319 | static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, | 319 | static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, |
| 320 | struct drm_framebuffer *fb) | 320 | struct drm_framebuffer *fb) |
| 321 | { | 321 | { |
| 322 | struct exynos_drm_plane plane = ctx->planes[win]; | 322 | struct exynos_drm_plane *plane = &ctx->planes[win]; |
| 323 | struct exynos_drm_plane_state *state = | 323 | struct exynos_drm_plane_state *state = |
| 324 | to_exynos_plane_state(plane.base.state); | 324 | to_exynos_plane_state(plane->base.state); |
| 325 | unsigned int alpha = state->base.alpha; | 325 | unsigned int alpha = state->base.alpha; |
| 326 | unsigned int pixel_alpha; | 326 | unsigned int pixel_alpha; |
| 327 | unsigned long val; | 327 | unsigned long val; |
| @@ -480,7 +480,7 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) · 479 unmodified lines | |||
| 480 | struct fimd_context *ctx = crtc->ctx; | 480 | struct fimd_context *ctx = crtc->ctx; |
| 481 | struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; | 481 | struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; |
| 482 | const struct fimd_driver_data *driver_data = ctx->driver_data; | 482 | const struct fimd_driver_data *driver_data = ctx->driver_data; |
| 483 | void *timing_base = ctx->regs + driver_data->timing_base; | 483 | void __iomem *timing_base = ctx->regs + driver_data->timing_base; |
| 484 | u32 val; | 484 | u32 val; |
| 485 | 485 | ||
| 486 | if (ctx->suspended) | 486 | if (ctx->suspended) |
| @@ -661,9 +661,9 @@ static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win, · 174 unmodified lines | |||
| 661 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, | 661 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, |
| 662 | struct drm_framebuffer *fb, int width) | 662 | struct drm_framebuffer *fb, int width) |
| 663 | { | 663 | { |
| 664 | struct exynos_drm_plane plane = ctx->planes[win]; | 664 | struct exynos_drm_plane *plane = &ctx->planes[win]; |
| 665 | struct exynos_drm_plane_state *state = | 665 | struct exynos_drm_plane_state *state = |
| 666 | to_exynos_plane_state(plane.base.state); | 666 | to_exynos_plane_state(plane->base.state); |
| 667 | uint32_t pixel_format = fb->format->format; | 667 | uint32_t pixel_format = fb->format->format; |
| 668 | unsigned int alpha = state->base.alpha; | 668 | unsigned int alpha = state->base.alpha; |
| 669 | u32 val = WINCONx_ENWIN; | 669 | u32 val = WINCONx_ENWIN; |
| @@ -1341,7 +1341,7 @@ static int __maybe_unused gsc_runtime_resume(struct device *dev) · 1340 unmodified lines | |||
| 1341 | for (i = 0; i < ctx->num_clocks; i++) { | 1341 | for (i = 0; i < ctx->num_clocks; i++) { |
| 1342 | ret = clk_prepare_enable(ctx->clocks[i]); | 1342 | ret = clk_prepare_enable(ctx->clocks[i]); |
| 1343 | if (ret) { | 1343 | if (ret) { |
| 1344 | while (--i > 0) | 1344 | while (--i >= 0) |
| 1345 | clk_disable_unprepare(ctx->clocks[i]); | 1345 | clk_disable_unprepare(ctx->clocks[i]); |
| 1346 | return ret; | 1346 | return ret; |
| 1347 | } | 1347 | } |
| @@ -140,7 +140,7 @@ config DRM_I915_GVT_KVMGT · 139 unmodified lines | |||
| 140 | 140 | ||
| 141 | Note that this driver only supports newer device from Broadwell on. | 141 | Note that this driver only supports newer device from Broadwell on. |
| 142 | For further information and setup guide, you can visit: | 142 | For further information and setup guide, you can visit: |
| 143 | http://01.org/igvt-g. | 143 | https://github.com/intel/gvt-linux/wiki. |
| 144 | 144 | ||
| 145 | If in doubt, say "N". | 145 | If in doubt, say "N". |
| 146 | 146 | ||
| @@ -17,7 +17,6 @@ subdir-ccflags-y += $(call cc-option, -Wunused-const-variable) · 16 unmodified lines | |||
| 17 | subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned) | 17 | subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned) |
| 18 | subdir-ccflags-y += $(call cc-option, -Wformat-overflow) | 18 | subdir-ccflags-y += $(call cc-option, -Wformat-overflow) |
| 19 | subdir-ccflags-y += $(call cc-option, -Wformat-truncation) | 19 | subdir-ccflags-y += $(call cc-option, -Wformat-truncation) |
| 20 | subdir-ccflags-y += $(call cc-option, -Wstringop-overflow) | ||
| 21 | subdir-ccflags-y += $(call cc-option, -Wstringop-truncation) | 20 | subdir-ccflags-y += $(call cc-option, -Wstringop-truncation) |
| 22 | # The following turn off the warnings enabled by -Wextra | 21 | # The following turn off the warnings enabled by -Wextra |
| 23 | ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) | 22 | ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) |
| @@ -1155,6 +1155,7 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) · 1154 unmodified lines | |||
| 1155 | } | 1155 | } |
| 1156 | 1156 | ||
| 1157 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); | 1157 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); |
| 1158 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); | ||
| 1158 | 1159 | ||
| 1159 | /* ensure all panel commands dispatched before enabling transcoder */ | 1160 | /* ensure all panel commands dispatched before enabling transcoder */ |
| 1160 | wait_for_cmds_dispatched_to_panel(encoder); | 1161 | wait_for_cmds_dispatched_to_panel(encoder); |
| @@ -1255,8 +1256,6 @@ static void gen11_dsi_enable(struct intel_atomic_state *state, · 94 unmodified lines | |||
| 1255 | /* step6d: enable dsi transcoder */ | 1256 | /* step6d: enable dsi transcoder */ |
| 1256 | gen11_dsi_enable_transcoder(encoder); | 1257 | gen11_dsi_enable_transcoder(encoder); |
| 1257 | 1258 | ||
| 1258 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); | ||
| 1259 | |||
| 1260 | /* step7: enable backlight */ | 1259 | /* step7: enable backlight */ |
| 1261 | intel_backlight_enable(crtc_state, conn_state); | 1260 | intel_backlight_enable(crtc_state, conn_state); |
| 1262 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); | 1261 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); |
| @@ -1525,8 +1525,18 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, · 1524 unmodified lines | |||
| 1525 | * can rely on frontbuffer tracking. | 1525 | * can rely on frontbuffer tracking. |
| 1526 | */ | 1526 | */ |
| 1527 | mask = EDP_PSR_DEBUG_MASK_MEMUP | | 1527 | mask = EDP_PSR_DEBUG_MASK_MEMUP | |
| 1528 | EDP_PSR_DEBUG_MASK_HPD | | 1528 | EDP_PSR_DEBUG_MASK_HPD; |
| 1529 | EDP_PSR_DEBUG_MASK_LPSP; | 1529 | |
| 1530 | /* | ||
| 1531 | * For some unknown reason on HSW non-ULT (or at least on | ||
| 1532 | * Dell Latitude E6540) external displays start to flicker | ||
| 1533 | * when PSR is enabled on the eDP. SR/PC6 residency is much | ||
| 1534 | * higher than should be possible with an external display. | ||
| 1535 | * As a workaround leave LPSP unmasked to prevent PSR entry | ||
| 1536 | * when external displays are active. | ||
| 1537 | */ | ||
| 1538 | if (DISPLAY_VER(dev_priv) >= 8 || IS_HASWELL_ULT(dev_priv)) | ||
| 1539 | mask |= EDP_PSR_DEBUG_MASK_LPSP; | ||
| 1530 | 1540 | ||
| 1531 | if (DISPLAY_VER(dev_priv) < 20) | 1541 | if (DISPLAY_VER(dev_priv) < 20) |
| 1532 | mask |= EDP_PSR_DEBUG_MASK_MAX_SLEEP; | 1542 | mask |= EDP_PSR_DEBUG_MASK_MAX_SLEEP; |
| @@ -2849,8 +2849,7 @@ static int handle_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset, · 2848 unmodified lines | |||
| 2849 | for (i = start; i < end; i += 4) { | 2849 | for (i = start; i < end; i += 4) { |
| 2850 | p = intel_gvt_find_mmio_info(gvt, i); | 2850 | p = intel_gvt_find_mmio_info(gvt, i); |
| 2851 | if (p) { | 2851 | if (p) { |
| 2852 | WARN(1, "dup mmio definition offset %x\n", | 2852 | WARN(1, "dup mmio definition offset %x\n", i); |
| 2853 | info->offset); | ||
| 2854 | 2853 | ||
| 2855 | /* We return -EEXIST here to make GVT-g load fail. | 2854 | /* We return -EEXIST here to make GVT-g load fail. |
| 2856 | * So duplicated MMIO can be found as soon as | 2855 | * So duplicated MMIO can be found as soon as |
| @@ -41,7 +41,7 @@ · 40 unmodified lines | |||
| 41 | * To virtualize GPU resources GVT-g driver depends on hypervisor technology | 41 | * To virtualize GPU resources GVT-g driver depends on hypervisor technology |
| 42 | * e.g KVM/VFIO/mdev, Xen, etc. to provide resource access trapping capability | 42 | * e.g KVM/VFIO/mdev, Xen, etc. to provide resource access trapping capability |
| 43 | * and be virtualized within GVT-g device module. More architectural design | 43 | * and be virtualized within GVT-g device module. More architectural design |
| 44 | * doc is available on https://01.org/group/2230/documentation-list. | 44 | * doc is available on https://github.com/intel/gvt-linux/wiki. |
| 45 | */ | 45 | */ |
| 46 | 46 | ||
| 47 | static LIST_HEAD(intel_gvt_devices); | 47 | static LIST_HEAD(intel_gvt_devices); |
| @@ -144,10 +144,6 @@ enum dpu_enc_rc_states { · 143 unmodified lines | |||
| 144 | * to track crtc in the disable() hook which is called | 144 | * to track crtc in the disable() hook which is called |
| 145 | * _after_ encoder_mask is cleared. | 145 | * _after_ encoder_mask is cleared. |
| 146 | * @connector: If a mode is set, cached pointer to the active connector | 146 | * @connector: If a mode is set, cached pointer to the active connector |
| 147 | * @crtc_kickoff_cb: Callback into CRTC that will flush & start | ||
| 148 | * all CTL paths | ||
| 149 | * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb | ||
| 150 | * @debugfs_root: Debug file system root file node | ||
| 151 | * @enc_lock: Lock around physical encoder | 147 | * @enc_lock: Lock around physical encoder |
| 152 | * create/destroy/enable/disable | 148 | * create/destroy/enable/disable |
| 153 | * @frame_busy_mask: Bitmask tracking which phys_enc we are still | 149 | * @frame_busy_mask: Bitmask tracking which phys_enc we are still |
| @@ -2072,7 +2068,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) · 1918 unmodified lines | |||
| 2072 | } | 2068 | } |
| 2073 | 2069 | ||
| 2074 | /* reset the merge 3D HW block */ | 2070 | /* reset the merge 3D HW block */ |
| 2075 | if (phys_enc->hw_pp->merge_3d) { | 2071 | if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { |
| 2076 | phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, | 2072 | phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, |
| 2077 | BLEND_3D_NONE); | 2073 | BLEND_3D_NONE); |
| 2078 | if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d) | 2074 | if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d) |
| @@ -2103,7 +2099,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) · 24 unmodified lines | |||
| 2103 | if (phys_enc->hw_wb) | 2099 | if (phys_enc->hw_wb) |
| 2104 | intf_cfg.wb = phys_enc->hw_wb->idx; | 2100 | intf_cfg.wb = phys_enc->hw_wb->idx; |
| 2105 | 2101 | ||
| 2106 | if (phys_enc->hw_pp->merge_3d) | 2102 | if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) |
| 2107 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; | 2103 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; |
| 2108 | 2104 | ||
| 2109 | if (ctl->ops.reset_intf_cfg) | 2105 | if (ctl->ops.reset_intf_cfg) |
| @@ -29,7 +29,6 @@ static inline bool reserved_by_other(uint32_t *res_map, int idx, · 28 unmodified lines | |||
| 29 | /** | 29 | /** |
| 30 | * struct dpu_rm_requirements - Reservation requirements parameter bundle | 30 | * struct dpu_rm_requirements - Reservation requirements parameter bundle |
| 31 | * @topology: selected topology for the display | 31 | * @topology: selected topology for the display |
| 32 | * @hw_res: Hardware resources required as reported by the encoders | ||
| 33 | */ | 32 | */ |
| 34 | struct dpu_rm_requirements { | 33 | struct dpu_rm_requirements { |
| 35 | struct msm_display_topology topology; | 34 | struct msm_display_topology topology; |
| @@ -204,6 +203,8 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) · 168 unmodified lines | |||
| 204 | * _dpu_rm_get_lm_peer - get the id of a mixer which is a peer of the primary | 203 | * _dpu_rm_get_lm_peer - get the id of a mixer which is a peer of the primary |
| 205 | * @rm: dpu resource manager handle | 204 | * @rm: dpu resource manager handle |
| 206 | * @primary_idx: index of primary mixer in rm->mixer_blks[] | 205 | * @primary_idx: index of primary mixer in rm->mixer_blks[] |
| 206 | * | ||
| 207 | * Returns: lm peer mixed id on success or %-EINVAL on error | ||
| 207 | */ | 208 | */ |
| 208 | static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx) | 209 | static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx) |
| 209 | { | 210 | { |
| @@ -135,11 +135,6 @@ static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl) · 134 unmodified lines | |||
| 135 | tbd = dp_link_get_test_bits_depth(ctrl->link, | 135 | tbd = dp_link_get_test_bits_depth(ctrl->link, |
| 136 | ctrl->panel->dp_mode.bpp); | 136 | ctrl->panel->dp_mode.bpp); |
| 137 | 137 | ||
| 138 | if (tbd == DP_TEST_BIT_DEPTH_UNKNOWN) { | ||
| 139 | pr_debug("BIT_DEPTH not set. Configure default\n"); | ||
| 140 | tbd = DP_TEST_BIT_DEPTH_8; | ||
| 141 | } | ||
| 142 | |||
| 143 | config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT; | 138 | config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT; |
| 144 | 139 | ||
| 145 | /* Num of Lanes */ | 140 | /* Num of Lanes */ |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include <drm/drm_print.h> | 8 | #include <drm/drm_print.h> |
| 9 | 9 | ||
| 10 | #include "dp_reg.h" | ||
| 10 | #include "dp_link.h" | 11 | #include "dp_link.h" |
| 11 | #include "dp_panel.h" | 12 | #include "dp_panel.h" |
| 12 | 13 | ||
| @@ -1082,7 +1083,7 @@ int dp_link_process_request(struct dp_link *dp_link) · 1069 unmodified lines | |||
| 1082 | 1083 | ||
| 1083 | int dp_link_get_colorimetry_config(struct dp_link *dp_link) | 1084 | int dp_link_get_colorimetry_config(struct dp_link *dp_link) |
| 1084 | { | 1085 | { |
| 1085 | u32 cc; | 1086 | u32 cc = DP_MISC0_COLORIMERY_CFG_LEGACY_RGB; |
| 1086 | struct dp_link_private *link; | 1087 | struct dp_link_private *link; |
| 1087 | 1088 | ||
| 1088 | if (!dp_link) { | 1089 | if (!dp_link) { |
| @@ -1096,10 +1097,11 @@ int dp_link_get_colorimetry_config(struct dp_link *dp_link) · 7 unmodified lines | |||
| 1096 | * Unless a video pattern CTS test is ongoing, use RGB_VESA | 1097 | * Unless a video pattern CTS test is ongoing, use RGB_VESA |
| 1097 | * Only RGB_VESA and RGB_CEA supported for now | 1098 | * Only RGB_VESA and RGB_CEA supported for now |
| 1098 | */ | 1099 | */ |
| 1099 | if (dp_link_is_video_pattern_requested(link)) | 1100 | if (dp_link_is_video_pattern_requested(link)) { |
| 1100 | cc = link->dp_link.test_video.test_dyn_range; | 1101 | if (link->dp_link.test_video.test_dyn_range & |
| 1101 | else | 1102 | DP_TEST_DYNAMIC_RANGE_CEA) |
| 1102 | cc = DP_TEST_DYNAMIC_RANGE_VESA; | 1103 | cc = DP_MISC0_COLORIMERY_CFG_CEA_RGB; |
| 1104 | } | ||
| 1103 | 1105 | ||
| 1104 | return cc; | 1106 | return cc; |
| 1105 | } | 1107 | } |
| @@ -1179,6 +1181,9 @@ void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link) · 73 unmodified lines | |||
| 1179 | u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp) | 1181 | u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp) |
| 1180 | { | 1182 | { |
| 1181 | u32 tbd; | 1183 | u32 tbd; |
| 1184 | struct dp_link_private *link; | ||
| 1185 | |||
| 1186 | link = container_of(dp_link, struct dp_link_private, dp_link); | ||
| 1182 | 1187 | ||
| 1183 | /* | 1188 | /* |
| 1184 | * Few simplistic rules and assumptions made here: | 1189 | * Few simplistic rules and assumptions made here: |
| @@ -1196,12 +1201,13 @@ u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp) · 11 unmodified lines | |||
| 1196 | tbd = DP_TEST_BIT_DEPTH_10; | 1201 | tbd = DP_TEST_BIT_DEPTH_10; |
| 1197 | break; | 1202 | break; |
| 1198 | default: | 1203 | default: |
| 1199 | tbd = DP_TEST_BIT_DEPTH_UNKNOWN; | 1204 | drm_dbg_dp(link->drm_dev, "bpp=%d not supported, use bpc=8\n", |
| 1205 | bpp); | ||
| 1206 | tbd = DP_TEST_BIT_DEPTH_8; | ||
| 1200 | break; | 1207 | break; |
| 1201 | } | 1208 | } |
| 1202 | 1209 | ||
| 1203 | if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN) | 1210 | tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT); |
| 1204 | tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT); | ||
| 1205 | 1211 | ||
| 1206 | return tbd; | 1212 | return tbd; |
| 1207 | } | 1213 | } |
| @@ -143,6 +143,9 @@ · 142 unmodified lines | |||
| 143 | #define DP_MISC0_COLORIMETRY_CFG_SHIFT (0x00000001) | 143 | #define DP_MISC0_COLORIMETRY_CFG_SHIFT (0x00000001) |
| 144 | #define DP_MISC0_TEST_BITS_DEPTH_SHIFT (0x00000005) | 144 | #define DP_MISC0_TEST_BITS_DEPTH_SHIFT (0x00000005) |
| 145 | 145 | ||
| 146 | #define DP_MISC0_COLORIMERY_CFG_LEGACY_RGB (0) | ||
| 147 | #define DP_MISC0_COLORIMERY_CFG_CEA_RGB (0x04) | ||
| 148 | |||
| 146 | #define REG_DP_VALID_BOUNDARY (0x00000030) | 149 | #define REG_DP_VALID_BOUNDARY (0x00000030) |
| 147 | #define REG_DP_VALID_BOUNDARY_2 (0x00000034) | 150 | #define REG_DP_VALID_BOUNDARY_2 (0x00000034) |
| 148 | 151 | ||
| @@ -562,6 +562,7 @@ static const struct msm_mdss_data sdm670_data = { · 561 unmodified lines | |||
| 562 | .ubwc_enc_version = UBWC_2_0, | 562 | .ubwc_enc_version = UBWC_2_0, |
| 563 | .ubwc_dec_version = UBWC_2_0, | 563 | .ubwc_dec_version = UBWC_2_0, |
| 564 | .highest_bank_bit = 1, | 564 | .highest_bank_bit = 1, |
| 565 | .reg_bus_bw = 76800, | ||
| 565 | }; | 566 | }; |
| 566 | 567 | ||
| 567 | static const struct msm_mdss_data sdm845_data = { | 568 | static const struct msm_mdss_data sdm845_data = { |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | |||
| 9 | #define GSP_PAGE_SIZE BIT(GSP_PAGE_SHIFT) | 9 | #define GSP_PAGE_SIZE BIT(GSP_PAGE_SHIFT) |
| 10 | 10 | ||
| 11 | struct nvkm_gsp_mem { | 11 | struct nvkm_gsp_mem { |
| 12 | u32 size; | 12 | size_t size; |
| 13 | void *data; | 13 | void *data; |
| 14 | dma_addr_t addr; | 14 | dma_addr_t addr; |
| 15 | }; | 15 | }; |
| @@ -62,7 +62,7 @@ nouveau_fence_signal(struct nouveau_fence *fence) · 61 unmodified lines | |||
| 62 | if (test_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags)) { | 62 | if (test_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags)) { |
| 63 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 63 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
| 64 | 64 | ||
| 65 | if (atomic_dec_and_test(&fctx->notify_ref)) | 65 | if (!--fctx->notify_ref) |
| 66 | drop = 1; | 66 | drop = 1; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| @@ -103,7 +103,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error) · 34 unmodified lines | |||
| 103 | void | 103 | void |
| 104 | nouveau_fence_context_del(struct nouveau_fence_chan *fctx) | 104 | nouveau_fence_context_del(struct nouveau_fence_chan *fctx) |
| 105 | { | 105 | { |
| 106 | cancel_work_sync(&fctx->allow_block_work); | 106 | cancel_work_sync(&fctx->uevent_work); |
| 107 | nouveau_fence_context_kill(fctx, 0); | 107 | nouveau_fence_context_kill(fctx, 0); |
| 108 | nvif_event_dtor(&fctx->event); | 108 | nvif_event_dtor(&fctx->event); |
| 109 | fctx->dead = 1; | 109 | fctx->dead = 1; |
| @@ -146,12 +146,13 @@ nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fc · 36 unmodified lines | |||
| 146 | return drop; | 146 | return drop; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static int | 149 | static void |
| 150 | nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc) | 150 | nouveau_fence_uevent_work(struct work_struct *work) |
| 151 | { | 151 | { |
| 152 | struct nouveau_fence_chan *fctx = container_of(event, typeof(*fctx), event); | 152 | struct nouveau_fence_chan *fctx = container_of(work, struct nouveau_fence_chan, |
| 153 | uevent_work); | ||
| 153 | unsigned long flags; | 154 | unsigned long flags; |
| 154 | int ret = NVIF_EVENT_KEEP; | 155 | int drop = 0; |
| 155 | 156 | ||
| 156 | spin_lock_irqsave(&fctx->lock, flags); | 157 | spin_lock_irqsave(&fctx->lock, flags); |
| 157 | if (!list_empty(&fctx->pending)) { | 158 | if (!list_empty(&fctx->pending)) { |
| @@ -161,23 +162,20 @@ nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc · 3 unmodified lines | |||
| 161 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 162 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
| 162 | chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); | 163 | chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); |
| 163 | if (nouveau_fence_update(chan, fctx)) | 164 | if (nouveau_fence_update(chan, fctx)) |
| 164 | ret = NVIF_EVENT_DROP; | 165 | drop = 1; |
| 165 | } | 166 | } |
| 166 | spin_unlock_irqrestore(&fctx->lock, flags); | 167 | if (drop) |
| 168 | nvif_event_block(&fctx->event); | ||
| 167 | 169 | ||
| 168 | return ret; | 170 | spin_unlock_irqrestore(&fctx->lock, flags); |
| 169 | } | 171 | } |
| 170 | 172 | ||
| 171 | static void | 173 | static int |
| 172 | nouveau_fence_work_allow_block(struct work_struct *work) | 174 | nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc) |
| 173 | { | 175 | { |
| 174 | struct nouveau_fence_chan *fctx = container_of(work, struct nouveau_fence_chan, | 176 | struct nouveau_fence_chan *fctx = container_of(event, typeof(*fctx), event); |
| 175 | allow_block_work); | 177 | schedule_work(&fctx->uevent_work); |
| 176 | 178 | return NVIF_EVENT_KEEP; | |
| 177 | if (atomic_read(&fctx->notify_ref) == 0) | ||
| 178 | nvif_event_block(&fctx->event); | ||
| 179 | else | ||
| 180 | nvif_event_allow(&fctx->event); | ||
| 181 | } | 179 | } |
| 182 | 180 | ||
| 183 | void | 181 | void |
| @@ -191,7 +189,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha · 7 unmodified lines | |||
| 191 | } args; | 189 | } args; |
| 192 | int ret; | 190 | int ret; |
| 193 | 191 | ||
| 194 | INIT_WORK(&fctx->allow_block_work, nouveau_fence_work_allow_block); | 192 | INIT_WORK(&fctx->uevent_work, nouveau_fence_uevent_work); |
| 195 | INIT_LIST_HEAD(&fctx->flip); | 193 | INIT_LIST_HEAD(&fctx->flip); |
| 196 | INIT_LIST_HEAD(&fctx->pending); | 194 | INIT_LIST_HEAD(&fctx->pending); |
| 197 | spin_lock_init(&fctx->lock); | 195 | spin_lock_init(&fctx->lock); |
| @@ -535,19 +533,15 @@ static bool nouveau_fence_enable_signaling(struct dma_fence *f) · 337 unmodified lines | |||
| 535 | struct nouveau_fence *fence = from_fence(f); | 533 | struct nouveau_fence *fence = from_fence(f); |
| 536 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 534 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
| 537 | bool ret; | 535 | bool ret; |
| 538 | bool do_work; | ||
| 539 | 536 | ||
| 540 | if (atomic_inc_return(&fctx->notify_ref) == 0) | 537 | if (!fctx->notify_ref++) |
| 541 | do_work = true; | 538 | nvif_event_allow(&fctx->event); |
| 542 | 539 | ||
| 543 | ret = nouveau_fence_no_signaling(f); | 540 | ret = nouveau_fence_no_signaling(f); |
| 544 | if (ret) | 541 | if (ret) |
| 545 | set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags); | 542 | set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags); |
| 546 | else if (atomic_dec_and_test(&fctx->notify_ref)) | 543 | else if (!--fctx->notify_ref) |
| 547 | do_work = true; | 544 | nvif_event_block(&fctx->event); |
| 548 | |||
| 549 | if (do_work) | ||
| 550 | schedule_work(&fctx->allow_block_work); | ||
| 551 | 545 | ||
| 552 | return ret; | 546 | return ret; |
| 553 | } | 547 | } |
| @@ -3,7 +3,6 @@ · 2 unmodified lines | |||
| 3 | #define __NOUVEAU_FENCE_H__ | 3 | #define __NOUVEAU_FENCE_H__ |
| 4 | 4 | ||
| 5 | #include <linux/dma-fence.h> | 5 | #include <linux/dma-fence.h> |
| 6 | #include <linux/workqueue.h> | ||
| 7 | #include <nvif/event.h> | 6 | #include <nvif/event.h> |
| 8 | 7 | ||
| 9 | struct nouveau_drm; | 8 | struct nouveau_drm; |
| @@ -45,10 +44,9 @@ struct nouveau_fence_chan { · 35 unmodified lines | |||
| 45 | u32 context; | 44 | u32 context; |
| 46 | char name[32]; | 45 | char name[32]; |
| 47 | 46 | ||
| 47 | struct work_struct uevent_work; | ||
| 48 | struct nvif_event event; | 48 | struct nvif_event event; |
| 49 | struct work_struct allow_block_work; | 49 | int notify_ref, dead, killed; |
| 50 | atomic_t notify_ref; | ||
| 51 | int dead, killed; | ||
| 52 | }; | 50 | }; |
| 53 | 51 | ||
| 54 | struct nouveau_fence_priv { | 52 | struct nouveau_fence_priv { |
| @@ -997,6 +997,32 @@ r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) · 996 unmodified lines | |||
| 997 | return 0; | 997 | return 0; |
| 998 | } | 998 | } |
| 999 | 999 | ||
| 1000 | static void | ||
| 1001 | nvkm_gsp_mem_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_mem *mem) | ||
| 1002 | { | ||
| 1003 | if (mem->data) { | ||
| 1004 | /* | ||
| 1005 | * Poison the buffer to catch any unexpected access from | ||
| 1006 | * GSP-RM if the buffer was prematurely freed. | ||
| 1007 | */ | ||
| 1008 | memset(mem->data, 0xFF, mem->size); | ||
| 1009 | |||
| 1010 | dma_free_coherent(gsp->subdev.device->dev, mem->size, mem->data, mem->addr); | ||
| 1011 | memset(mem, 0, sizeof(*mem)); | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | static int | ||
| 1016 | nvkm_gsp_mem_ctor(struct nvkm_gsp *gsp, size_t size, struct nvkm_gsp_mem *mem) | ||
| 1017 | { | ||
| 1018 | mem->size = size; | ||
| 1019 | mem->data = dma_alloc_coherent(gsp->subdev.device->dev, size, &mem->addr, GFP_KERNEL); | ||
| 1020 | if (WARN_ON(!mem->data)) | ||
| 1021 | return -ENOMEM; | ||
| 1022 | |||
| 1023 | return 0; | ||
| 1024 | } | ||
| 1025 | |||
| 1000 | static int | 1026 | static int |
| 1001 | r535_gsp_postinit(struct nvkm_gsp *gsp) | 1027 | r535_gsp_postinit(struct nvkm_gsp *gsp) |
| 1002 | { | 1028 | { |
| @@ -1024,6 +1050,13 @@ r535_gsp_postinit(struct nvkm_gsp *gsp) · 21 unmodified lines | |||
| 1024 | 1050 | ||
| 1025 | nvkm_inth_allow(&gsp->subdev.inth); | 1051 | nvkm_inth_allow(&gsp->subdev.inth); |
| 1026 | nvkm_wr32(device, 0x110004, 0x00000040); | 1052 | nvkm_wr32(device, 0x110004, 0x00000040); |
| 1053 | |||
| 1054 | /* Release the DMA buffers that were needed only for boot and init */ | ||
| 1055 | nvkm_gsp_mem_dtor(gsp, &gsp->boot.fw); | ||
| 1056 | nvkm_gsp_mem_dtor(gsp, &gsp->libos); | ||
| 1057 | nvkm_gsp_mem_dtor(gsp, &gsp->rmargs); | ||
| 1058 | nvkm_gsp_mem_dtor(gsp, &gsp->wpr_meta); | ||
| 1059 | |||
| 1027 | return ret; | 1060 | return ret; |
| 1028 | } | 1061 | } |
| 1029 | 1062 | ||
| @@ -1078,7 +1111,6 @@ r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp) · 48 unmodified lines | |||
| 1078 | if (IS_ERR(rpc)) | 1111 | if (IS_ERR(rpc)) |
| 1079 | return PTR_ERR(rpc); | 1112 | return PTR_ERR(rpc); |
| 1080 | 1113 | ||
| 1081 | rpc->size = sizeof(*rpc); | ||
| 1082 | rpc->numEntries = NV_GSP_REG_NUM_ENTRIES; | 1114 | rpc->numEntries = NV_GSP_REG_NUM_ENTRIES; |
| 1083 | 1115 | ||
| 1084 | str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]); | 1116 | str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]); |
| @@ -1094,6 +1126,7 @@ r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp) · 9 unmodified lines | |||
| 1094 | strings += name_len; | 1126 | strings += name_len; |
| 1095 | str_offset += name_len; | 1127 | str_offset += name_len; |
| 1096 | } | 1128 | } |
| 1129 | rpc->size = str_offset; | ||
| 1097 | 1130 | ||
| 1098 | return nvkm_gsp_rpc_wr(gsp, rpc, false); | 1131 | return nvkm_gsp_rpc_wr(gsp, rpc, false); |
| 1099 | } | 1132 | } |
| @@ -1532,27 +1565,6 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc) · 432 unmodified lines | |||
| 1532 | return 0; | 1565 | return 0; |
| 1533 | } | 1566 | } |
| 1534 | 1567 | ||
| 1535 | static void | ||
| 1536 | nvkm_gsp_mem_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_mem *mem) | ||
| 1537 | { | ||
| 1538 | if (mem->data) { | ||
| 1539 | dma_free_coherent(gsp->subdev.device->dev, mem->size, mem->data, mem->addr); | ||
| 1540 | mem->data = NULL; | ||
| 1541 | } | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | static int | ||
| 1545 | nvkm_gsp_mem_ctor(struct nvkm_gsp *gsp, u32 size, struct nvkm_gsp_mem *mem) | ||
| 1546 | { | ||
| 1547 | mem->size = size; | ||
| 1548 | mem->data = dma_alloc_coherent(gsp->subdev.device->dev, size, &mem->addr, GFP_KERNEL); | ||
| 1549 | if (WARN_ON(!mem->data)) | ||
| 1550 | return -ENOMEM; | ||
| 1551 | |||
| 1552 | return 0; | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | |||
| 1556 | static int | 1568 | static int |
| 1557 | r535_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) | 1569 | r535_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) |
| 1558 | { | 1570 | { |
| @@ -1938,20 +1950,20 @@ nvkm_gsp_radix3_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_radix3 *rx3) · 379 unmodified lines | |||
| 1938 | * See kgspCreateRadix3_IMPL | 1950 | * See kgspCreateRadix3_IMPL |
| 1939 | */ | 1951 | */ |
| 1940 | static int | 1952 | static int |
| 1941 | nvkm_gsp_radix3_sg(struct nvkm_device *device, struct sg_table *sgt, u64 size, | 1953 | nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, |
| 1942 | struct nvkm_gsp_radix3 *rx3) | 1954 | struct nvkm_gsp_radix3 *rx3) |
| 1943 | { | 1955 | { |
| 1944 | u64 addr; | 1956 | u64 addr; |
| 1945 | 1957 | ||
| 1946 | for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) { | 1958 | for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) { |
| 1947 | u64 *ptes; | 1959 | u64 *ptes; |
| 1948 | int idx; | 1960 | size_t bufsize; |
| 1961 | int ret, idx; | ||
| 1949 | 1962 | ||
| 1950 | rx3->mem[i].size = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE); | 1963 | bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE); |
| 1951 | rx3->mem[i].data = dma_alloc_coherent(device->dev, rx3->mem[i].size, | 1964 | ret = nvkm_gsp_mem_ctor(gsp, bufsize, &rx3->mem[i]); |
| 1952 | &rx3->mem[i].addr, GFP_KERNEL); | 1965 | if (ret) |
| 1953 | if (WARN_ON(!rx3->mem[i].data)) | 1966 | return ret; |
| 1954 | return -ENOMEM; | ||
| 1955 | 1967 | ||
| 1956 | ptes = rx3->mem[i].data; | 1968 | ptes = rx3->mem[i].data; |
| 1957 | if (i == 2) { | 1969 | if (i == 2) { |
| @@ -1991,7 +2003,7 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) · 33 unmodified lines | |||
| 1991 | if (ret) | 2003 | if (ret) |
| 1992 | return ret; | 2004 | return ret; |
| 1993 | 2005 | ||
| 1994 | ret = nvkm_gsp_radix3_sg(gsp->subdev.device, &gsp->sr.sgt, len, &gsp->sr.radix3); | 2006 | ret = nvkm_gsp_radix3_sg(gsp, &gsp->sr.sgt, len, &gsp->sr.radix3); |
| 1995 | if (ret) | 2007 | if (ret) |
| 1996 | return ret; | 2008 | return ret; |
| 1997 | 2009 | ||
| @@ -2150,6 +2162,11 @@ r535_gsp_dtor(struct nvkm_gsp *gsp) · 152 unmodified lines | |||
| 2150 | mutex_destroy(&gsp->cmdq.mutex); | 2162 | mutex_destroy(&gsp->cmdq.mutex); |
| 2151 | 2163 | ||
| 2152 | r535_gsp_dtor_fws(gsp); | 2164 | r535_gsp_dtor_fws(gsp); |
| 2165 | |||
| 2166 | nvkm_gsp_mem_dtor(gsp, &gsp->shm.mem); | ||
| 2167 | nvkm_gsp_mem_dtor(gsp, &gsp->loginit); | ||
| 2168 | nvkm_gsp_mem_dtor(gsp, &gsp->logintr); | ||
| 2169 | nvkm_gsp_mem_dtor(gsp, &gsp->logrm); | ||
| 2153 | } | 2170 | } |
| 2154 | 2171 | ||
| 2155 | int | 2172 | int |
| @@ -2194,7 +2211,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) · 38 unmodified lines | |||
| 2194 | memcpy(gsp->sig.data, data, size); | 2211 | memcpy(gsp->sig.data, data, size); |
| 2195 | 2212 | ||
| 2196 | /* Build radix3 page table for ELF image. */ | 2213 | /* Build radix3 page table for ELF image. */ |
| 2197 | ret = nvkm_gsp_radix3_sg(device, &gsp->fw.mem.sgt, gsp->fw.len, &gsp->radix3); | 2214 | ret = nvkm_gsp_radix3_sg(gsp, &gsp->fw.mem.sgt, gsp->fw.len, &gsp->radix3); |
| 2198 | if (ret) | 2215 | if (ret) |
| 2199 | return ret; | 2216 | return ret; |
| 2200 | 2217 | ||
| @@ -539,6 +539,8 @@ config DRM_PANEL_RAYDIUM_RM692E5 · 538 unmodified lines | |||
| 539 | depends on OF | 539 | depends on OF |
| 540 | depends on DRM_MIPI_DSI | 540 | depends on DRM_MIPI_DSI |
| 541 | depends on BACKLIGHT_CLASS_DEVICE | 541 | depends on BACKLIGHT_CLASS_DEVICE |
| 542 | select DRM_DISPLAY_DP_HELPER | ||
| 543 | select DRM_DISPLAY_HELPER | ||
| 542 | help | 544 | help |
| 543 | Say Y here if you want to enable support for Raydium RM692E5-based | 545 | Say Y here if you want to enable support for Raydium RM692E5-based |
| 544 | display panels, such as the one found in the Fairphone 5 smartphone. | 546 | display panels, such as the one found in the Fairphone 5 smartphone. |
| @@ -309,7 +309,7 @@ static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al02_desc = { · 308 unmodified lines | |||
| 309 | .off_func = s6d7aa0_lsl080al02_off, | 309 | .off_func = s6d7aa0_lsl080al02_off, |
| 310 | .drm_mode = &s6d7aa0_lsl080al02_mode, | 310 | .drm_mode = &s6d7aa0_lsl080al02_mode, |
| 311 | .mode_flags = MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_NO_HFP, | 311 | .mode_flags = MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_NO_HFP, |
| 312 | .bus_flags = DRM_BUS_FLAG_DE_HIGH, | 312 | .bus_flags = 0, |
| 313 | 313 | ||
| 314 | .has_backlight = false, | 314 | .has_backlight = false, |
| 315 | .use_passwd3 = false, | 315 | .use_passwd3 = false, |
| @@ -3948,6 +3948,7 @@ static const struct panel_desc tianma_tm070jdhg30 = { · 3947 unmodified lines | |||
| 3948 | }, | 3948 | }, |
| 3949 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, | 3949 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, |
| 3950 | .connector_type = DRM_MODE_CONNECTOR_LVDS, | 3950 | .connector_type = DRM_MODE_CONNECTOR_LVDS, |
| 3951 | .bus_flags = DRM_BUS_FLAG_DE_HIGH, | ||
| 3951 | }; | 3952 | }; |
| 3952 | 3953 | ||
| 3953 | static const struct panel_desc tianma_tm070jvhg33 = { | 3954 | static const struct panel_desc tianma_tm070jvhg33 = { |
| @@ -3960,6 +3961,7 @@ static const struct panel_desc tianma_tm070jvhg33 = { · 6 unmodified lines | |||
| 3960 | }, | 3961 | }, |
| 3961 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, | 3962 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, |
| 3962 | .connector_type = DRM_MODE_CONNECTOR_LVDS, | 3963 | .connector_type = DRM_MODE_CONNECTOR_LVDS, |
| 3964 | .bus_flags = DRM_BUS_FLAG_DE_HIGH, | ||
| 3963 | }; | 3965 | }; |
| 3964 | 3966 | ||
| 3965 | static const struct display_timing tianma_tm070rvhg71_timing = { | 3967 | static const struct display_timing tianma_tm070rvhg71_timing = { |
| @@ -1184,14 +1184,16 @@ static void drm_sched_run_job_work(struct work_struct *w) · 1183 unmodified lines | |||
| 1184 | if (READ_ONCE(sched->pause_submit)) | 1184 | if (READ_ONCE(sched->pause_submit)) |
| 1185 | return; | 1185 | return; |
| 1186 | 1186 | ||
| 1187 | /* Find entity with a ready job */ | ||
| 1187 | entity = drm_sched_select_entity(sched); | 1188 | entity = drm_sched_select_entity(sched); |
| 1188 | if (!entity) | 1189 | if (!entity) |
| 1189 | return; | 1190 | return; /* No more work */ |
| 1190 | 1191 | ||
| 1191 | sched_job = drm_sched_entity_pop_job(entity); | 1192 | sched_job = drm_sched_entity_pop_job(entity); |
| 1192 | if (!sched_job) { | 1193 | if (!sched_job) { |
| 1193 | complete_all(&entity->entity_idle); | 1194 | complete_all(&entity->entity_idle); |
| 1194 | return; /* No more work */ | 1195 | drm_sched_run_job_queue(sched); |
| 1196 | return; | ||
| 1195 | } | 1197 | } |
| 1196 | 1198 | ||
| 1197 | s_fence = sched_job->s_fence; | 1199 | s_fence = sched_job->s_fence; |
| @@ -960,7 +960,8 @@ int host1x_client_iommu_attach(struct host1x_client *client) · 959 unmodified lines | |||
| 960 | * not the shared IOMMU domain, don't try to attach it to a different | 960 | * not the shared IOMMU domain, don't try to attach it to a different |
| 961 | * domain. This allows using the IOMMU-backed DMA API. | 961 | * domain. This allows using the IOMMU-backed DMA API. |
| 962 | */ | 962 | */ |
| 963 | if (domain && domain != tegra->domain) | 963 | if (domain && domain->type != IOMMU_DOMAIN_IDENTITY && |
| 964 | domain != tegra->domain) | ||
| 964 | return 0; | 965 | return 0; |
| 965 | 966 | ||
| 966 | if (tegra->domain) { | 967 | if (tegra->domain) { |
| @@ -188,13 +188,13 @@ out: · 187 unmodified lines | |||
| 188 | 188 | ||
| 189 | static void drm_test_mm_debug(struct kunit *test) | 189 | static void drm_test_mm_debug(struct kunit *test) |
| 190 | { | 190 | { |
| 191 | struct drm_printer p = drm_debug_printer(test->name); | ||
| 191 | struct drm_mm mm; | 192 | struct drm_mm mm; |
| 192 | struct drm_mm_node nodes[2]; | 193 | struct drm_mm_node nodes[2]; |
| 193 | 194 | ||
| 194 | /* Create a small drm_mm with a couple of nodes and a few holes, and | 195 | /* Create a small drm_mm with a couple of nodes and a few holes, and |
| 195 | * check that the debug iterator doesn't explode over a trivial drm_mm. | 196 | * check that the debug iterator doesn't explode over a trivial drm_mm. |
| 196 | */ | 197 | */ |
| 197 | |||
| 198 | drm_mm_init(&mm, 0, 4096); | 198 | drm_mm_init(&mm, 0, 4096); |
| 199 | 199 | ||
| 200 | memset(nodes, 0, sizeof(nodes)); | 200 | memset(nodes, 0, sizeof(nodes)); |
| @@ -209,6 +209,9 @@ static void drm_test_mm_debug(struct kunit *test) · 8 unmodified lines | |||
| 209 | KUNIT_ASSERT_FALSE_MSG(test, drm_mm_reserve_node(&mm, &nodes[1]), | 209 | KUNIT_ASSERT_FALSE_MSG(test, drm_mm_reserve_node(&mm, &nodes[1]), |
| 210 | "failed to reserve node[0] {start=%lld, size=%lld)\n", | 210 | "failed to reserve node[0] {start=%lld, size=%lld)\n", |
| 211 | nodes[0].start, nodes[0].size); | 211 | nodes[0].start, nodes[0].size); |
| 212 | |||
| 213 | drm_mm_print(&mm, &p); | ||
| 214 | KUNIT_SUCCEED(test); | ||
| 212 | } | 215 | } |
| 213 | 216 | ||
| 214 | static bool expect_insert(struct kunit *test, struct drm_mm *mm, | 217 | static bool expect_insert(struct kunit *test, struct drm_mm *mm, |
| @@ -95,11 +95,17 @@ static int ttm_global_init(void) · 94 unmodified lines | |||
| 95 | ttm_pool_mgr_init(num_pages); | 95 | ttm_pool_mgr_init(num_pages); |
| 96 | ttm_tt_mgr_init(num_pages, num_dma32); | 96 | ttm_tt_mgr_init(num_pages, num_dma32); |
| 97 | 97 | ||
| 98 | glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); | 98 | glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32 | |
| 99 | __GFP_NOWARN); | ||
| 99 | 100 | ||
| 101 | /* Retry without GFP_DMA32 for platforms DMA32 is not available */ | ||
| 100 | if (unlikely(glob->dummy_read_page == NULL)) { | 102 | if (unlikely(glob->dummy_read_page == NULL)) { |
| 101 | ret = -ENOMEM; | 103 | glob->dummy_read_page = alloc_page(__GFP_ZERO); |
| 102 | goto out; | 104 | if (unlikely(glob->dummy_read_page == NULL)) { |
| 105 | ret = -ENOMEM; | ||
| 106 | goto out; | ||
| 107 | } | ||
| 108 | pr_warn("Using GFP_DMA32 fallback for dummy_read_page\n"); | ||
| 103 | } | 109 | } |
| 104 | 110 | ||
| 105 | INIT_LIST_HEAD(&glob->device_list); | 111 | INIT_LIST_HEAD(&glob->device_list); |
| @@ -195,7 +201,7 @@ int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *func · 89 unmodified lines | |||
| 195 | bool use_dma_alloc, bool use_dma32) | 201 | bool use_dma_alloc, bool use_dma32) |
| 196 | { | 202 | { |
| 197 | struct ttm_global *glob = &ttm_glob; | 203 | struct ttm_global *glob = &ttm_glob; |
| 198 | int ret; | 204 | int ret, nid; |
| 199 | 205 | ||
| 200 | if (WARN_ON(vma_manager == NULL)) | 206 | if (WARN_ON(vma_manager == NULL)) |
| 201 | return -EINVAL; | 207 | return -EINVAL; |
| @@ -215,7 +221,12 @@ int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *func · 13 unmodified lines | |||
| 215 | 221 | ||
| 216 | ttm_sys_man_init(bdev); | 222 | ttm_sys_man_init(bdev); |
| 217 | 223 | ||
| 218 | ttm_pool_init(&bdev->pool, dev, dev_to_node(dev), use_dma_alloc, use_dma32); | 224 | if (dev) |
| 225 | nid = dev_to_node(dev); | ||
| 226 | else | ||
| 227 | nid = NUMA_NO_NODE; | ||
| 228 | |||
| 229 | ttm_pool_init(&bdev->pool, dev, nid, use_dma_alloc, use_dma32); | ||
| 219 | 230 | ||
| 220 | bdev->vma_manager = vma_manager; | 231 | bdev->vma_manager = vma_manager; |
| 221 | spin_lock_init(&bdev->lru_lock); | 232 | spin_lock_init(&bdev->lru_lock); |
| @@ -147,6 +147,13 @@ v3d_job_allocate(void **container, size_t size) · 146 unmodified lines | |||
| 147 | return 0; | 147 | return 0; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static void | ||
| 151 | v3d_job_deallocate(void **container) | ||
| 152 | { | ||
| 153 | kfree(*container); | ||
| 154 | *container = NULL; | ||
| 155 | } | ||
| 156 | |||
| 150 | static int | 157 | static int |
| 151 | v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, | 158 | v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, |
| 152 | struct v3d_job *job, void (*free)(struct kref *ref), | 159 | struct v3d_job *job, void (*free)(struct kref *ref), |
| @@ -273,8 +280,10 @@ v3d_setup_csd_jobs_and_bos(struct drm_file *file_priv, · 120 unmodified lines | |||
| 273 | 280 | ||
| 274 | ret = v3d_job_init(v3d, file_priv, &(*job)->base, | 281 | ret = v3d_job_init(v3d, file_priv, &(*job)->base, |
| 275 | v3d_job_free, args->in_sync, se, V3D_CSD); | 282 | v3d_job_free, args->in_sync, se, V3D_CSD); |
| 276 | if (ret) | 283 | if (ret) { |
| 284 | v3d_job_deallocate((void *)job); | ||
| 277 | return ret; | 285 | return ret; |
| 286 | } | ||
| 278 | 287 | ||
| 279 | ret = v3d_job_allocate((void *)clean_job, sizeof(**clean_job)); | 288 | ret = v3d_job_allocate((void *)clean_job, sizeof(**clean_job)); |
| 280 | if (ret) | 289 | if (ret) |
| @@ -282,8 +291,10 @@ v3d_setup_csd_jobs_and_bos(struct drm_file *file_priv, · 1 unmodified line | |||
| 282 | 291 | ||
| 283 | ret = v3d_job_init(v3d, file_priv, *clean_job, | 292 | ret = v3d_job_init(v3d, file_priv, *clean_job, |
| 284 | v3d_job_free, 0, NULL, V3D_CACHE_CLEAN); | 293 | v3d_job_free, 0, NULL, V3D_CACHE_CLEAN); |
| 285 | if (ret) | 294 | if (ret) { |
| 295 | v3d_job_deallocate((void *)clean_job); | ||
| 286 | return ret; | 296 | return ret; |
| 297 | } | ||
| 287 | 298 | ||
| 288 | (*job)->args = *args; | 299 | (*job)->args = *args; |
| 289 | 300 | ||
| @@ -860,8 +871,10 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 570 unmodified lines | |||
| 860 | 871 | ||
| 861 | ret = v3d_job_init(v3d, file_priv, &render->base, | 872 | ret = v3d_job_init(v3d, file_priv, &render->base, |
| 862 | v3d_render_job_free, args->in_sync_rcl, &se, V3D_RENDER); | 873 | v3d_render_job_free, args->in_sync_rcl, &se, V3D_RENDER); |
| 863 | if (ret) | 874 | if (ret) { |
| 875 | v3d_job_deallocate((void *)&render); | ||
| 864 | goto fail; | 876 | goto fail; |
| 877 | } | ||
| 865 | 878 | ||
| 866 | render->start = args->rcl_start; | 879 | render->start = args->rcl_start; |
| 867 | render->end = args->rcl_end; | 880 | render->end = args->rcl_end; |
| @@ -874,8 +887,10 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 6 unmodified lines | |||
| 874 | 887 | ||
| 875 | ret = v3d_job_init(v3d, file_priv, &bin->base, | 888 | ret = v3d_job_init(v3d, file_priv, &bin->base, |
| 876 | v3d_job_free, args->in_sync_bcl, &se, V3D_BIN); | 889 | v3d_job_free, args->in_sync_bcl, &se, V3D_BIN); |
| 877 | if (ret) | 890 | if (ret) { |
| 891 | v3d_job_deallocate((void *)&bin); | ||
| 878 | goto fail; | 892 | goto fail; |
| 893 | } | ||
| 879 | 894 | ||
| 880 | bin->start = args->bcl_start; | 895 | bin->start = args->bcl_start; |
| 881 | bin->end = args->bcl_end; | 896 | bin->end = args->bcl_end; |
| @@ -892,8 +907,10 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 10 unmodified lines | |||
| 892 | 907 | ||
| 893 | ret = v3d_job_init(v3d, file_priv, clean_job, | 908 | ret = v3d_job_init(v3d, file_priv, clean_job, |
| 894 | v3d_job_free, 0, NULL, V3D_CACHE_CLEAN); | 909 | v3d_job_free, 0, NULL, V3D_CACHE_CLEAN); |
| 895 | if (ret) | 910 | if (ret) { |
| 911 | v3d_job_deallocate((void *)&clean_job); | ||
| 896 | goto fail; | 912 | goto fail; |
| 913 | } | ||
| 897 | 914 | ||
| 898 | last_job = clean_job; | 915 | last_job = clean_job; |
| 899 | } else { | 916 | } else { |
| @@ -1015,8 +1032,10 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, · 115 unmodified lines | |||
| 1015 | 1032 | ||
| 1016 | ret = v3d_job_init(v3d, file_priv, &job->base, | 1033 | ret = v3d_job_init(v3d, file_priv, &job->base, |
| 1017 | v3d_job_free, args->in_sync, &se, V3D_TFU); | 1034 | v3d_job_free, args->in_sync, &se, V3D_TFU); |
| 1018 | if (ret) | 1035 | if (ret) { |
| 1036 | v3d_job_deallocate((void *)&job); | ||
| 1019 | goto fail; | 1037 | goto fail; |
| 1038 | } | ||
| 1020 | 1039 | ||
| 1021 | job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles), | 1040 | job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles), |
| 1022 | sizeof(*job->base.bo), GFP_KERNEL); | 1041 | sizeof(*job->base.bo), GFP_KERNEL); |
| @@ -1233,8 +1252,10 @@ v3d_submit_cpu_ioctl(struct drm_device *dev, void *data, · 210 unmodified lines | |||
| 1233 | 1252 | ||
| 1234 | ret = v3d_job_init(v3d, file_priv, &cpu_job->base, | 1253 | ret = v3d_job_init(v3d, file_priv, &cpu_job->base, |
| 1235 | v3d_job_free, 0, &se, V3D_CPU); | 1254 | v3d_job_free, 0, &se, V3D_CPU); |
| 1236 | if (ret) | 1255 | if (ret) { |
| 1256 | v3d_job_deallocate((void *)&cpu_job); | ||
| 1237 | goto fail; | 1257 | goto fail; |
| 1258 | } | ||
| 1238 | 1259 | ||
| 1239 | clean_job = cpu_job->indirect_csd.clean_job; | 1260 | clean_job = cpu_job->indirect_csd.clean_job; |
| 1240 | csd_job = cpu_job->indirect_csd.job; | 1261 | csd_job = cpu_job->indirect_csd.job; |
| @@ -94,6 +94,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev) · 93 unmodified lines | |||
| 94 | goto err_free; | 94 | goto err_free; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | dma_set_max_seg_size(dev->dev, dma_max_mapping_size(dev->dev) ?: UINT_MAX); | ||
| 97 | ret = virtio_gpu_init(vdev, dev); | 98 | ret = virtio_gpu_init(vdev, dev); |
| 98 | if (ret) | 99 | if (ret) |
| 99 | goto err_free; | 100 | goto err_free; |
| @@ -50,8 +50,8 @@ · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN (GUC_HXG_REQUEST_MSG_MIN_LEN + 3u) | 51 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN (GUC_HXG_REQUEST_MSG_MIN_LEN + 3u) |
| 52 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ GUC_HXG_REQUEST_MSG_0_DATA0 | 52 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ GUC_HXG_REQUEST_MSG_0_DATA0 |
| 53 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY (0xffff << 16) | 53 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY (0xffffu << 16) |
| 54 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN (0xffff << 0) | 54 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN (0xffffu << 0) |
| 55 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32 GUC_HXG_REQUEST_MSG_n_DATAn | 55 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32 GUC_HXG_REQUEST_MSG_n_DATAn |
| 56 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64 GUC_HXG_REQUEST_MSG_n_DATAn | 56 | #define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64 GUC_HXG_REQUEST_MSG_n_DATAn |
| 57 | 57 | ||
| @@ -242,8 +242,8 @@ struct slpc_shared_data { · 241 unmodified lines | |||
| 242 | (HOST2GUC_PC_SLPC_REQUEST_REQUEST_MSG_MIN_LEN + \ | 242 | (HOST2GUC_PC_SLPC_REQUEST_REQUEST_MSG_MIN_LEN + \ |
| 243 | HOST2GUC_PC_SLPC_EVENT_MAX_INPUT_ARGS) | 243 | HOST2GUC_PC_SLPC_EVENT_MAX_INPUT_ARGS) |
| 244 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_0_MBZ GUC_HXG_REQUEST_MSG_0_DATA0 | 244 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_0_MBZ GUC_HXG_REQUEST_MSG_0_DATA0 |
| 245 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ID (0xff << 8) | 245 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ID (0xffu << 8) |
| 246 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ARGC (0xff << 0) | 246 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ARGC (0xffu << 0) |
| 247 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_N_EVENT_DATA_N GUC_HXG_REQUEST_MSG_n_DATAn | 247 | #define HOST2GUC_PC_SLPC_REQUEST_MSG_N_EVENT_DATA_N GUC_HXG_REQUEST_MSG_n_DATAn |
| 248 | 248 | ||
| 249 | #endif | 249 | #endif |
| @@ -82,11 +82,11 @@ static_assert(sizeof(struct guc_ct_buffer_desc) == 64); · 81 unmodified lines | |||
| 82 | #define GUC_CTB_HDR_LEN 1u | 82 | #define GUC_CTB_HDR_LEN 1u |
| 83 | #define GUC_CTB_MSG_MIN_LEN GUC_CTB_HDR_LEN | 83 | #define GUC_CTB_MSG_MIN_LEN GUC_CTB_HDR_LEN |
| 84 | #define GUC_CTB_MSG_MAX_LEN 256u | 84 | #define GUC_CTB_MSG_MAX_LEN 256u |
| 85 | #define GUC_CTB_MSG_0_FENCE (0xffff << 16) | 85 | #define GUC_CTB_MSG_0_FENCE (0xffffu << 16) |
| 86 | #define GUC_CTB_MSG_0_FORMAT (0xf << 12) | 86 | #define GUC_CTB_MSG_0_FORMAT (0xfu << 12) |
| 87 | #define GUC_CTB_FORMAT_HXG 0u | 87 | #define GUC_CTB_FORMAT_HXG 0u |
| 88 | #define GUC_CTB_MSG_0_RESERVED (0xf << 8) | 88 | #define GUC_CTB_MSG_0_RESERVED (0xfu << 8) |
| 89 | #define GUC_CTB_MSG_0_NUM_DWORDS (0xff << 0) | 89 | #define GUC_CTB_MSG_0_NUM_DWORDS (0xffu << 0) |
| 90 | 90 | ||
| 91 | /** | 91 | /** |
| 92 | * DOC: CTB HXG Message | 92 | * DOC: CTB HXG Message |
| @@ -31,9 +31,9 @@ · 30 unmodified lines | |||
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | #define GUC_KLV_LEN_MIN 1u | 33 | #define GUC_KLV_LEN_MIN 1u |
| 34 | #define GUC_KLV_0_KEY (0xffff << 16) | 34 | #define GUC_KLV_0_KEY (0xffffu << 16) |
| 35 | #define GUC_KLV_0_LEN (0xffff << 0) | 35 | #define GUC_KLV_0_LEN (0xffffu << 0) |
| 36 | #define GUC_KLV_n_VALUE (0xffffffff << 0) | 36 | #define GUC_KLV_n_VALUE (0xffffffffu << 0) |
| 37 | 37 | ||
| 38 | /** | 38 | /** |
| 39 | * DOC: GuC Self Config KLVs | 39 | * DOC: GuC Self Config KLVs |
| @@ -40,18 +40,18 @@ · 39 unmodified lines | |||
| 40 | */ | 40 | */ |
| 41 | 41 | ||
| 42 | #define GUC_HXG_MSG_MIN_LEN 1u | 42 | #define GUC_HXG_MSG_MIN_LEN 1u |
| 43 | #define GUC_HXG_MSG_0_ORIGIN (0x1 << 31) | 43 | #define GUC_HXG_MSG_0_ORIGIN (0x1u << 31) |
| 44 | #define GUC_HXG_ORIGIN_HOST 0u | 44 | #define GUC_HXG_ORIGIN_HOST 0u |
| 45 | #define GUC_HXG_ORIGIN_GUC 1u | 45 | #define GUC_HXG_ORIGIN_GUC 1u |
| 46 | #define GUC_HXG_MSG_0_TYPE (0x7 << 28) | 46 | #define GUC_HXG_MSG_0_TYPE (0x7u << 28) |
| 47 | #define GUC_HXG_TYPE_REQUEST 0u | 47 | #define GUC_HXG_TYPE_REQUEST 0u |
| 48 | #define GUC_HXG_TYPE_EVENT 1u | 48 | #define GUC_HXG_TYPE_EVENT 1u |
| 49 | #define GUC_HXG_TYPE_NO_RESPONSE_BUSY 3u | 49 | #define GUC_HXG_TYPE_NO_RESPONSE_BUSY 3u |
| 50 | #define GUC_HXG_TYPE_NO_RESPONSE_RETRY 5u | 50 | #define GUC_HXG_TYPE_NO_RESPONSE_RETRY 5u |
| 51 | #define GUC_HXG_TYPE_RESPONSE_FAILURE 6u | 51 | #define GUC_HXG_TYPE_RESPONSE_FAILURE 6u |
| 52 | #define GUC_HXG_TYPE_RESPONSE_SUCCESS 7u | 52 | #define GUC_HXG_TYPE_RESPONSE_SUCCESS 7u |
| 53 | #define GUC_HXG_MSG_0_AUX (0xfffffff << 0) | 53 | #define GUC_HXG_MSG_0_AUX (0xfffffffu << 0) |
| 54 | #define GUC_HXG_MSG_n_PAYLOAD (0xffffffff << 0) | 54 | #define GUC_HXG_MSG_n_PAYLOAD (0xffffffffu << 0) |
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | * DOC: HXG Request | 57 | * DOC: HXG Request |
| @@ -85,8 +85,8 @@ · 27 unmodified lines | |||
| 85 | */ | 85 | */ |
| 86 | 86 | ||
| 87 | #define GUC_HXG_REQUEST_MSG_MIN_LEN GUC_HXG_MSG_MIN_LEN | 87 | #define GUC_HXG_REQUEST_MSG_MIN_LEN GUC_HXG_MSG_MIN_LEN |
| 88 | #define GUC_HXG_REQUEST_MSG_0_DATA0 (0xfff << 16) | 88 | #define GUC_HXG_REQUEST_MSG_0_DATA0 (0xfffu << 16) |
| 89 | #define GUC_HXG_REQUEST_MSG_0_ACTION (0xffff << 0) | 89 | #define GUC_HXG_REQUEST_MSG_0_ACTION (0xffffu << 0) |
| 90 | #define GUC_HXG_REQUEST_MSG_n_DATAn GUC_HXG_MSG_n_PAYLOAD | 90 | #define GUC_HXG_REQUEST_MSG_n_DATAn GUC_HXG_MSG_n_PAYLOAD |
| 91 | 91 | ||
| 92 | /** | 92 | /** |
| @@ -117,8 +117,8 @@ · 24 unmodified lines | |||
| 117 | */ | 117 | */ |
| 118 | 118 | ||
| 119 | #define GUC_HXG_EVENT_MSG_MIN_LEN GUC_HXG_MSG_MIN_LEN | 119 | #define GUC_HXG_EVENT_MSG_MIN_LEN GUC_HXG_MSG_MIN_LEN |
| 120 | #define GUC_HXG_EVENT_MSG_0_DATA0 (0xfff << 16) | 120 | #define GUC_HXG_EVENT_MSG_0_DATA0 (0xfffu << 16) |
| 121 | #define GUC_HXG_EVENT_MSG_0_ACTION (0xffff << 0) | 121 | #define GUC_HXG_EVENT_MSG_0_ACTION (0xffffu << 0) |
| 122 | #define GUC_HXG_EVENT_MSG_n_DATAn GUC_HXG_MSG_n_PAYLOAD | 122 | #define GUC_HXG_EVENT_MSG_n_DATAn GUC_HXG_MSG_n_PAYLOAD |
| 123 | 123 | ||
| 124 | /** | 124 | /** |
| @@ -188,8 +188,8 @@ · 63 unmodified lines | |||
| 188 | */ | 188 | */ |
| 189 | 189 | ||
| 190 | #define GUC_HXG_FAILURE_MSG_LEN GUC_HXG_MSG_MIN_LEN | 190 | #define GUC_HXG_FAILURE_MSG_LEN GUC_HXG_MSG_MIN_LEN |
| 191 | #define GUC_HXG_FAILURE_MSG_0_HINT (0xfff << 16) | 191 | #define GUC_HXG_FAILURE_MSG_0_HINT (0xfffu << 16) |
| 192 | #define GUC_HXG_FAILURE_MSG_0_ERROR (0xffff << 0) | 192 | #define GUC_HXG_FAILURE_MSG_0_ERROR (0xffffu << 0) |
| 193 | 193 | ||
| 194 | /** | 194 | /** |
| 195 | * DOC: HXG Response | 195 | * DOC: HXG Response |
| @@ -35,12 +35,10 @@ static inline int i915_gem_object_read_from_page(struct xe_bo *bo, · 34 unmodified lines | |||
| 35 | u32 ofs, u64 *ptr, u32 size) | 35 | u32 ofs, u64 *ptr, u32 size) |
| 36 | { | 36 | { |
| 37 | struct ttm_bo_kmap_obj map; | 37 | struct ttm_bo_kmap_obj map; |
| 38 | void *virtual; | 38 | void *src; |
| 39 | bool is_iomem; | 39 | bool is_iomem; |
| 40 | int ret; | 40 | int ret; |
| 41 | 41 | ||
| 42 | XE_WARN_ON(size != 8); | ||
| 43 | |||
| 44 | ret = xe_bo_lock(bo, true); | 42 | ret = xe_bo_lock(bo, true); |
| 45 | if (ret) | 43 | if (ret) |
| 46 | return ret; | 44 | return ret; |
| @@ -50,11 +48,12 @@ static inline int i915_gem_object_read_from_page(struct xe_bo *bo, · 3 unmodified lines | |||
| 50 | goto out_unlock; | 48 | goto out_unlock; |
| 51 | 49 | ||
| 52 | ofs &= ~PAGE_MASK; | 50 | ofs &= ~PAGE_MASK; |
| 53 | virtual = ttm_kmap_obj_virtual(&map, &is_iomem); | 51 | src = ttm_kmap_obj_virtual(&map, &is_iomem); |
| 52 | src += ofs; | ||
| 54 | if (is_iomem) | 53 | if (is_iomem) |
| 55 | *ptr = readq((void __iomem *)(virtual + ofs)); | 54 | memcpy_fromio(ptr, (void __iomem *)src, size); |
| 56 | else | 55 | else |
| 57 | *ptr = *(u64 *)(virtual + ofs); | 56 | memcpy(ptr, src, size); |
| 58 | 57 | ||
| 59 | ttm_bo_kunmap(&map); | 58 | ttm_bo_kunmap(&map); |
| 60 | out_unlock: | 59 | out_unlock: |
| @@ -74,9 +74,6 @@ static const struct platform_test_case cases[] = { · 73 unmodified lines | |||
| 74 | SUBPLATFORM_CASE(DG2, G11, B1), | 74 | SUBPLATFORM_CASE(DG2, G11, B1), |
| 75 | SUBPLATFORM_CASE(DG2, G12, A0), | 75 | SUBPLATFORM_CASE(DG2, G12, A0), |
| 76 | SUBPLATFORM_CASE(DG2, G12, A1), | 76 | SUBPLATFORM_CASE(DG2, G12, A1), |
| 77 | PLATFORM_CASE(PVC, B0), | ||
| 78 | PLATFORM_CASE(PVC, B1), | ||
| 79 | PLATFORM_CASE(PVC, C0), | ||
| 80 | GMDID_CASE(METEORLAKE, 1270, A0, 1300, A0), | 77 | GMDID_CASE(METEORLAKE, 1270, A0, 1300, A0), |
| 81 | GMDID_CASE(METEORLAKE, 1271, A0, 1300, A0), | 78 | GMDID_CASE(METEORLAKE, 1271, A0, 1300, A0), |
| 82 | GMDID_CASE(LUNARLAKE, 2004, A0, 2000, A0), | 79 | GMDID_CASE(LUNARLAKE, 2004, A0, 2000, A0), |
| @@ -613,7 +613,7 @@ void xe_device_wmb(struct xe_device *xe) · 612 unmodified lines | |||
| 613 | u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size) | 613 | u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size) |
| 614 | { | 614 | { |
| 615 | return xe_device_has_flat_ccs(xe) ? | 615 | return xe_device_has_flat_ccs(xe) ? |
| 616 | DIV_ROUND_UP(size, NUM_BYTES_PER_CCS_BYTE(xe)) : 0; | 616 | DIV_ROUND_UP_ULL(size, NUM_BYTES_PER_CCS_BYTE(xe)) : 0; |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | bool xe_device_mem_access_ongoing(struct xe_device *xe) | 619 | bool xe_device_mem_access_ongoing(struct xe_device *xe) |
| @@ -134,8 +134,6 @@ static void xe_display_fini_nommio(struct drm_device *dev, void *dummy) · 133 unmodified lines | |||
| 134 | 134 | ||
| 135 | int xe_display_init_nommio(struct xe_device *xe) | 135 | int xe_display_init_nommio(struct xe_device *xe) |
| 136 | { | 136 | { |
| 137 | int err; | ||
| 138 | |||
| 139 | if (!xe->info.enable_display) | 137 | if (!xe->info.enable_display) |
| 140 | return 0; | 138 | return 0; |
| 141 | 139 | ||
| @@ -145,10 +143,6 @@ int xe_display_init_nommio(struct xe_device *xe) · 3 unmodified lines | |||
| 145 | /* This must be called before any calls to HAS_PCH_* */ | 143 | /* This must be called before any calls to HAS_PCH_* */ |
| 146 | intel_detect_pch(xe); | 144 | intel_detect_pch(xe); |
| 147 | 145 | ||
| 148 | err = intel_power_domains_init(xe); | ||
| 149 | if (err) | ||
| 150 | return err; | ||
| 151 | |||
| 152 | return drmm_add_action_or_reset(&xe->drm, xe_display_fini_nommio, xe); | 146 | return drmm_add_action_or_reset(&xe->drm, xe_display_fini_nommio, xe); |
| 153 | } | 147 | } |
| 154 | 148 | ||
| @@ -175,7 +175,7 @@ static int xe_dma_buf_begin_cpu_access(struct dma_buf *dma_buf, · 174 unmodified lines | |||
| 175 | return 0; | 175 | return 0; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | const struct dma_buf_ops xe_dmabuf_ops = { | 178 | static const struct dma_buf_ops xe_dmabuf_ops = { |
| 179 | .attach = xe_dma_buf_attach, | 179 | .attach = xe_dma_buf_attach, |
| 180 | .detach = xe_dma_buf_detach, | 180 | .detach = xe_dma_buf_detach, |
| 181 | .pin = xe_dma_buf_pin, | 181 | .pin = xe_dma_buf_pin, |
| @@ -111,7 +111,7 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 110 unmodified lines | |||
| 111 | u64 addresses[XE_HW_ENGINE_MAX_INSTANCE]; | 111 | u64 addresses[XE_HW_ENGINE_MAX_INSTANCE]; |
| 112 | struct drm_gpuvm_exec vm_exec = {.extra.fn = xe_exec_fn}; | 112 | struct drm_gpuvm_exec vm_exec = {.extra.fn = xe_exec_fn}; |
| 113 | struct drm_exec *exec = &vm_exec.exec; | 113 | struct drm_exec *exec = &vm_exec.exec; |
| 114 | u32 i, num_syncs = 0; | 114 | u32 i, num_syncs = 0, num_ufence = 0; |
| 115 | struct xe_sched_job *job; | 115 | struct xe_sched_job *job; |
| 116 | struct dma_fence *rebind_fence; | 116 | struct dma_fence *rebind_fence; |
| 117 | struct xe_vm *vm; | 117 | struct xe_vm *vm; |
| @@ -157,6 +157,14 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 39 unmodified lines | |||
| 157 | SYNC_PARSE_FLAG_LR_MODE : 0)); | 157 | SYNC_PARSE_FLAG_LR_MODE : 0)); |
| 158 | if (err) | 158 | if (err) |
| 159 | goto err_syncs; | 159 | goto err_syncs; |
| 160 | |||
| 161 | if (xe_sync_is_ufence(&syncs[i])) | ||
| 162 | num_ufence++; | ||
| 163 | } | ||
| 164 | |||
| 165 | if (XE_IOCTL_DBG(xe, num_ufence > 1)) { | ||
| 166 | err = -EINVAL; | ||
| 167 | goto err_syncs; | ||
| 160 | } | 168 | } |
| 161 | 169 | ||
| 162 | if (xe_exec_queue_is_parallel(q)) { | 170 | if (xe_exec_queue_is_parallel(q)) { |
| @@ -926,20 +926,24 @@ void xe_exec_queue_last_fence_put_unlocked(struct xe_exec_queue *q) · 925 unmodified lines | |||
| 926 | * @q: The exec queue | 926 | * @q: The exec queue |
| 927 | * @vm: The VM the engine does a bind or exec for | 927 | * @vm: The VM the engine does a bind or exec for |
| 928 | * | 928 | * |
| 929 | * Get last fence, does not take a ref | 929 | * Get last fence, takes a ref |
| 930 | * | 930 | * |
| 931 | * Returns: last fence if not signaled, dma fence stub if signaled | 931 | * Returns: last fence if not signaled, dma fence stub if signaled |
| 932 | */ | 932 | */ |
| 933 | struct dma_fence *xe_exec_queue_last_fence_get(struct xe_exec_queue *q, | 933 | struct dma_fence *xe_exec_queue_last_fence_get(struct xe_exec_queue *q, |
| 934 | struct xe_vm *vm) | 934 | struct xe_vm *vm) |
| 935 | { | 935 | { |
| 936 | struct dma_fence *fence; | ||
| 937 | |||
| 936 | xe_exec_queue_last_fence_lockdep_assert(q, vm); | 938 | xe_exec_queue_last_fence_lockdep_assert(q, vm); |
| 937 | 939 | ||
| 938 | if (q->last_fence && | 940 | if (q->last_fence && |
| 939 | test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &q->last_fence->flags)) | 941 | test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &q->last_fence->flags)) |
| 940 | xe_exec_queue_last_fence_put(q, vm); | 942 | xe_exec_queue_last_fence_put(q, vm); |
| 941 | 943 | ||
| 942 | return q->last_fence ? q->last_fence : dma_fence_get_stub(); | 944 | fence = q->last_fence ? q->last_fence : dma_fence_get_stub(); |
| 945 | dma_fence_get(fence); | ||
| 946 | return fence; | ||
| 943 | } | 947 | } |
| 944 | 948 | ||
| 945 | /** | 949 | /** |
| @@ -437,7 +437,10 @@ static int all_fw_domain_init(struct xe_gt *gt) · 436 unmodified lines | |||
| 437 | * USM has its only SA pool to non-block behind user operations | 437 | * USM has its only SA pool to non-block behind user operations |
| 438 | */ | 438 | */ |
| 439 | if (gt_to_xe(gt)->info.has_usm) { | 439 | if (gt_to_xe(gt)->info.has_usm) { |
| 440 | gt->usm.bb_pool = xe_sa_bo_manager_init(gt_to_tile(gt), SZ_1M, 16); | 440 | struct xe_device *xe = gt_to_xe(gt); |
| 441 | |||
| 442 | gt->usm.bb_pool = xe_sa_bo_manager_init(gt_to_tile(gt), | ||
| 443 | IS_DGFX(xe) ? SZ_1M : SZ_512K, 16); | ||
| 441 | if (IS_ERR(gt->usm.bb_pool)) { | 444 | if (IS_ERR(gt->usm.bb_pool)) { |
| 442 | err = PTR_ERR(gt->usm.bb_pool); | 445 | err = PTR_ERR(gt->usm.bb_pool); |
| 443 | goto err_force_wake; | 446 | goto err_force_wake; |
| @@ -480,7 +480,7 @@ static bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, · 479 unmodified lines | |||
| 480 | * to synchronize with external clients (e.g., firmware), so a semaphore | 480 | * to synchronize with external clients (e.g., firmware), so a semaphore |
| 481 | * register will also need to be taken. | 481 | * register will also need to be taken. |
| 482 | */ | 482 | */ |
| 483 | static void mcr_lock(struct xe_gt *gt) | 483 | static void mcr_lock(struct xe_gt *gt) __acquires(>->mcr_lock) |
| 484 | { | 484 | { |
| 485 | struct xe_device *xe = gt_to_xe(gt); | 485 | struct xe_device *xe = gt_to_xe(gt); |
| 486 | int ret = 0; | 486 | int ret = 0; |
| @@ -500,7 +500,7 @@ static void mcr_lock(struct xe_gt *gt) · 13 unmodified lines | |||
| 500 | drm_WARN_ON_ONCE(&xe->drm, ret == -ETIMEDOUT); | 500 | drm_WARN_ON_ONCE(&xe->drm, ret == -ETIMEDOUT); |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | static void mcr_unlock(struct xe_gt *gt) | 503 | static void mcr_unlock(struct xe_gt *gt) __releases(>->mcr_lock) |
| 504 | { | 504 | { |
| 505 | /* Release hardware semaphore - this is done by writing 1 to the register */ | 505 | /* Release hardware semaphore - this is done by writing 1 to the register */ |
| 506 | if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) | 506 | if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) |
| @@ -165,7 +165,8 @@ retry_userptr: · 164 unmodified lines | |||
| 165 | goto unlock_vm; | 165 | goto unlock_vm; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | if (!xe_vma_is_userptr(vma) || !xe_vma_userptr_check_repin(vma)) { | 168 | if (!xe_vma_is_userptr(vma) || |
| 169 | !xe_vma_userptr_check_repin(to_userptr_vma(vma))) { | ||
| 169 | downgrade_write(&vm->lock); | 170 | downgrade_write(&vm->lock); |
| 170 | write_locked = false; | 171 | write_locked = false; |
| 171 | } | 172 | } |
| @@ -181,11 +182,13 @@ retry_userptr: · 9 unmodified lines | |||
| 181 | /* TODO: Validate fault */ | 182 | /* TODO: Validate fault */ |
| 182 | 183 | ||
| 183 | if (xe_vma_is_userptr(vma) && write_locked) { | 184 | if (xe_vma_is_userptr(vma) && write_locked) { |
| 185 | struct xe_userptr_vma *uvma = to_userptr_vma(vma); | ||
| 186 | |||
| 184 | spin_lock(&vm->userptr.invalidated_lock); | 187 | spin_lock(&vm->userptr.invalidated_lock); |
| 185 | list_del_init(&vma->userptr.invalidate_link); | 188 | list_del_init(&uvma->userptr.invalidate_link); |
| 186 | spin_unlock(&vm->userptr.invalidated_lock); | 189 | spin_unlock(&vm->userptr.invalidated_lock); |
| 187 | 190 | ||
| 188 | ret = xe_vma_userptr_pin_pages(vma); | 191 | ret = xe_vma_userptr_pin_pages(uvma); |
| 189 | if (ret) | 192 | if (ret) |
| 190 | goto unlock_vm; | 193 | goto unlock_vm; |
| 191 | 194 | ||
| @@ -220,7 +223,7 @@ retry_userptr: · 28 unmodified lines | |||
| 220 | dma_fence_put(fence); | 223 | dma_fence_put(fence); |
| 221 | 224 | ||
| 222 | if (xe_vma_is_userptr(vma)) | 225 | if (xe_vma_is_userptr(vma)) |
| 223 | ret = xe_vma_userptr_check_repin(vma); | 226 | ret = xe_vma_userptr_check_repin(to_userptr_vma(vma)); |
| 224 | vma->usm.tile_invalidated &= ~BIT(tile->id); | 227 | vma->usm.tile_invalidated &= ~BIT(tile->id); |
| 225 | 228 | ||
| 226 | unlock_dma_resv: | 229 | unlock_dma_resv: |
| @@ -332,7 +335,7 @@ int xe_guc_pagefault_handler(struct xe_guc *guc, u32 *msg, u32 len) · 105 unmodified lines | |||
| 332 | return -EPROTO; | 335 | return -EPROTO; |
| 333 | 336 | ||
| 334 | asid = FIELD_GET(PFD_ASID, msg[1]); | 337 | asid = FIELD_GET(PFD_ASID, msg[1]); |
| 335 | pf_queue = >->usm.pf_queue[asid % NUM_PF_QUEUE]; | 338 | pf_queue = gt->usm.pf_queue + (asid % NUM_PF_QUEUE); |
| 336 | 339 | ||
| 337 | spin_lock_irqsave(&pf_queue->lock, flags); | 340 | spin_lock_irqsave(&pf_queue->lock, flags); |
| 338 | full = pf_queue_full(pf_queue); | 341 | full = pf_queue_full(pf_queue); |
| @@ -963,7 +963,9 @@ void xe_guc_pc_fini(struct xe_guc_pc *pc) · 962 unmodified lines | |||
| 963 | struct xe_device *xe = pc_to_xe(pc); | 963 | struct xe_device *xe = pc_to_xe(pc); |
| 964 | 964 | ||
| 965 | if (xe->info.skip_guc_pc) { | 965 | if (xe->info.skip_guc_pc) { |
| 966 | xe_device_mem_access_get(xe); | ||
| 966 | xe_gt_idle_disable_c6(pc_to_gt(pc)); | 967 | xe_gt_idle_disable_c6(pc_to_gt(pc)); |
| 968 | xe_device_mem_access_put(xe); | ||
| 967 | return; | 969 | return; |
| 968 | } | 970 | } |
| 969 | 971 | ||
| @@ -217,13 +217,13 @@ struct xe_hw_fence *xe_hw_fence_create(struct xe_hw_fence_ctx *ctx, · 216 unmodified lines | |||
| 217 | if (!fence) | 217 | if (!fence) |
| 218 | return ERR_PTR(-ENOMEM); | 218 | return ERR_PTR(-ENOMEM); |
| 219 | 219 | ||
| 220 | dma_fence_init(&fence->dma, &xe_hw_fence_ops, &ctx->irq->lock, | ||
| 221 | ctx->dma_fence_ctx, ctx->next_seqno++); | ||
| 222 | |||
| 223 | fence->ctx = ctx; | 220 | fence->ctx = ctx; |
| 224 | fence->seqno_map = seqno_map; | 221 | fence->seqno_map = seqno_map; |
| 225 | INIT_LIST_HEAD(&fence->irq_link); | 222 | INIT_LIST_HEAD(&fence->irq_link); |
| 226 | 223 | ||
| 224 | dma_fence_init(&fence->dma, &xe_hw_fence_ops, &ctx->irq->lock, | ||
| 225 | ctx->dma_fence_ctx, ctx->next_seqno++); | ||
| 226 | |||
| 227 | trace_xe_hw_fence_create(fence); | 227 | trace_xe_hw_fence_create(fence); |
| 228 | 228 | ||
| 229 | return fence; | 229 | return fence; |
| @@ -419,7 +419,7 @@ static int xe_hwmon_pcode_read_i1(struct xe_gt *gt, u32 *uval) · 418 unmodified lines | |||
| 419 | 419 | ||
| 420 | return xe_pcode_read(gt, PCODE_MBOX(PCODE_POWER_SETUP, | 420 | return xe_pcode_read(gt, PCODE_MBOX(PCODE_POWER_SETUP, |
| 421 | POWER_SETUP_SUBCOMMAND_READ_I1, 0), | 421 | POWER_SETUP_SUBCOMMAND_READ_I1, 0), |
| 422 | uval, 0); | 422 | uval, NULL); |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | static int xe_hwmon_pcode_write_i1(struct xe_gt *gt, u32 uval) | 425 | static int xe_hwmon_pcode_write_i1(struct xe_gt *gt, u32 uval) |
| @@ -21,10 +21,10 @@ · 20 unmodified lines | |||
| 21 | #include "xe_map.h" | 21 | #include "xe_map.h" |
| 22 | #include "xe_vm.h" | 22 | #include "xe_vm.h" |
| 23 | 23 | ||
| 24 | #define CTX_VALID (1 << 0) | 24 | #define LRC_VALID (1 << 0) |
| 25 | #define CTX_PRIVILEGE (1 << 8) | 25 | #define LRC_PRIVILEGE (1 << 8) |
| 26 | #define CTX_ADDRESSING_MODE_SHIFT 3 | 26 | #define LRC_ADDRESSING_MODE_SHIFT 3 |
| 27 | #define LEGACY_64B_CONTEXT 3 | 27 | #define LRC_LEGACY_64B_CONTEXT 3 |
| 28 | 28 | ||
| 29 | #define ENGINE_CLASS_SHIFT 61 | 29 | #define ENGINE_CLASS_SHIFT 61 |
| 30 | #define ENGINE_INSTANCE_SHIFT 48 | 30 | #define ENGINE_INSTANCE_SHIFT 48 |
| @@ -762,15 +762,15 @@ int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe, · 731 unmodified lines | |||
| 762 | (q->usm.acc_notify << ACC_NOTIFY_S) | | 762 | (q->usm.acc_notify << ACC_NOTIFY_S) | |
| 763 | q->usm.acc_trigger); | 763 | q->usm.acc_trigger); |
| 764 | 764 | ||
| 765 | lrc->desc = CTX_VALID; | 765 | lrc->desc = LRC_VALID; |
| 766 | lrc->desc |= LEGACY_64B_CONTEXT << CTX_ADDRESSING_MODE_SHIFT; | 766 | lrc->desc |= LRC_LEGACY_64B_CONTEXT << LRC_ADDRESSING_MODE_SHIFT; |
| 767 | /* TODO: Priority */ | 767 | /* TODO: Priority */ |
| 768 | 768 | ||
| 769 | /* While this appears to have something about privileged batches or | 769 | /* While this appears to have something about privileged batches or |
| 770 | * some such, it really just means PPGTT mode. | 770 | * some such, it really just means PPGTT mode. |
| 771 | */ | 771 | */ |
| 772 | if (vm) | 772 | if (vm) |
| 773 | lrc->desc |= CTX_PRIVILEGE; | 773 | lrc->desc |= LRC_PRIVILEGE; |
| 774 | 774 | ||
| 775 | if (GRAPHICS_VERx100(xe) < 1250) { | 775 | if (GRAPHICS_VERx100(xe) < 1250) { |
| 776 | lrc->desc |= (u64)hwe->instance << ENGINE_INSTANCE_SHIFT; | 776 | lrc->desc |= (u64)hwe->instance << ENGINE_INSTANCE_SHIFT; |
| @@ -170,11 +170,6 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, · 169 unmodified lines | |||
| 170 | if (!IS_DGFX(xe)) { | 170 | if (!IS_DGFX(xe)) { |
| 171 | /* Write out batch too */ | 171 | /* Write out batch too */ |
| 172 | m->batch_base_ofs = NUM_PT_SLOTS * XE_PAGE_SIZE; | 172 | m->batch_base_ofs = NUM_PT_SLOTS * XE_PAGE_SIZE; |
| 173 | if (xe->info.has_usm) { | ||
| 174 | batch = tile->primary_gt->usm.bb_pool->bo; | ||
| 175 | m->usm_batch_base_ofs = m->batch_base_ofs; | ||
| 176 | } | ||
| 177 | |||
| 178 | for (i = 0; i < batch->size; | 173 | for (i = 0; i < batch->size; |
| 179 | i += vm->flags & XE_VM_FLAG_64K ? XE_64K_PAGE_SIZE : | 174 | i += vm->flags & XE_VM_FLAG_64K ? XE_64K_PAGE_SIZE : |
| 180 | XE_PAGE_SIZE) { | 175 | XE_PAGE_SIZE) { |
| @@ -185,6 +180,24 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, · 4 unmodified lines | |||
| 185 | entry); | 180 | entry); |
| 186 | level++; | 181 | level++; |
| 187 | } | 182 | } |
| 183 | if (xe->info.has_usm) { | ||
| 184 | xe_tile_assert(tile, batch->size == SZ_1M); | ||
| 185 | |||
| 186 | batch = tile->primary_gt->usm.bb_pool->bo; | ||
| 187 | m->usm_batch_base_ofs = m->batch_base_ofs + SZ_1M; | ||
| 188 | xe_tile_assert(tile, batch->size == SZ_512K); | ||
| 189 | |||
| 190 | for (i = 0; i < batch->size; | ||
| 191 | i += vm->flags & XE_VM_FLAG_64K ? XE_64K_PAGE_SIZE : | ||
| 192 | XE_PAGE_SIZE) { | ||
| 193 | entry = vm->pt_ops->pte_encode_bo(batch, i, | ||
| 194 | pat_index, 0); | ||
| 195 | |||
| 196 | xe_map_wr(xe, &bo->vmap, map_ofs + level * 8, u64, | ||
| 197 | entry); | ||
| 198 | level++; | ||
| 199 | } | ||
| 200 | } | ||
| 188 | } else { | 201 | } else { |
| 189 | u64 batch_addr = xe_bo_addr(batch, 0, XE_PAGE_SIZE); | 202 | u64 batch_addr = xe_bo_addr(batch, 0, XE_PAGE_SIZE); |
| 190 | 203 | ||
| @@ -472,7 +485,7 @@ static void emit_pte(struct xe_migrate *m, · 281 unmodified lines | |||
| 472 | /* Indirect access needs compression enabled uncached PAT index */ | 485 | /* Indirect access needs compression enabled uncached PAT index */ |
| 473 | if (GRAPHICS_VERx100(xe) >= 2000) | 486 | if (GRAPHICS_VERx100(xe) >= 2000) |
| 474 | pat_index = is_comp_pte ? xe->pat.idx[XE_CACHE_NONE_COMPRESSION] : | 487 | pat_index = is_comp_pte ? xe->pat.idx[XE_CACHE_NONE_COMPRESSION] : |
| 475 | xe->pat.idx[XE_CACHE_NONE]; | 488 | xe->pat.idx[XE_CACHE_WB]; |
| 476 | else | 489 | else |
| 477 | pat_index = xe->pat.idx[XE_CACHE_WB]; | 490 | pat_index = xe->pat.idx[XE_CACHE_WB]; |
| 478 | 491 | ||
| @@ -760,14 +773,14 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m, · 281 unmodified lines | |||
| 760 | if (src_is_vram && xe_migrate_allow_identity(src_L0, &src_it)) | 773 | if (src_is_vram && xe_migrate_allow_identity(src_L0, &src_it)) |
| 761 | xe_res_next(&src_it, src_L0); | 774 | xe_res_next(&src_it, src_L0); |
| 762 | else | 775 | else |
| 763 | emit_pte(m, bb, src_L0_pt, src_is_vram, true, &src_it, src_L0, | 776 | emit_pte(m, bb, src_L0_pt, src_is_vram, copy_system_ccs, |
| 764 | src); | 777 | &src_it, src_L0, src); |
| 765 | 778 | ||
| 766 | if (dst_is_vram && xe_migrate_allow_identity(src_L0, &dst_it)) | 779 | if (dst_is_vram && xe_migrate_allow_identity(src_L0, &dst_it)) |
| 767 | xe_res_next(&dst_it, src_L0); | 780 | xe_res_next(&dst_it, src_L0); |
| 768 | else | 781 | else |
| 769 | emit_pte(m, bb, dst_L0_pt, dst_is_vram, true, &dst_it, src_L0, | 782 | emit_pte(m, bb, dst_L0_pt, dst_is_vram, copy_system_ccs, |
| 770 | dst); | 783 | &dst_it, src_L0, dst); |
| 771 | 784 | ||
| 772 | if (copy_system_ccs) | 785 | if (copy_system_ccs) |
| 773 | emit_pte(m, bb, ccs_pt, false, false, &ccs_it, ccs_size, src); | 786 | emit_pte(m, bb, ccs_pt, false, false, &ccs_it, ccs_size, src); |
| @@ -1009,8 +1022,8 @@ struct dma_fence *xe_migrate_clear(struct xe_migrate *m, · 235 unmodified lines | |||
| 1009 | if (clear_vram && xe_migrate_allow_identity(clear_L0, &src_it)) | 1022 | if (clear_vram && xe_migrate_allow_identity(clear_L0, &src_it)) |
| 1010 | xe_res_next(&src_it, clear_L0); | 1023 | xe_res_next(&src_it, clear_L0); |
| 1011 | else | 1024 | else |
| 1012 | emit_pte(m, bb, clear_L0_pt, clear_vram, true, &src_it, clear_L0, | 1025 | emit_pte(m, bb, clear_L0_pt, clear_vram, clear_system_ccs, |
| 1013 | dst); | 1026 | &src_it, clear_L0, dst); |
| 1014 | 1027 | ||
| 1015 | bb->cs[bb->len++] = MI_BATCH_BUFFER_END; | 1028 | bb->cs[bb->len++] = MI_BATCH_BUFFER_END; |
| 1016 | update_idx = bb->len; | 1029 | update_idx = bb->len; |
| @@ -1204,8 +1217,11 @@ static bool no_in_syncs(struct xe_vm *vm, struct xe_exec_queue *q, · 187 unmodified lines | |||
| 1204 | } | 1217 | } |
| 1205 | if (q) { | 1218 | if (q) { |
| 1206 | fence = xe_exec_queue_last_fence_get(q, vm); | 1219 | fence = xe_exec_queue_last_fence_get(q, vm); |
| 1207 | if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) | 1220 | if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { |
| 1221 | dma_fence_put(fence); | ||
| 1208 | return false; | 1222 | return false; |
| 1223 | } | ||
| 1224 | dma_fence_put(fence); | ||
| 1209 | } | 1225 | } |
| 1210 | 1226 | ||
| 1211 | return true; | 1227 | return true; |
| @@ -272,8 +272,8 @@ int xe_mmio_probe_vram(struct xe_device *xe) · 271 unmodified lines | |||
| 272 | drm_info(&xe->drm, "VRAM[%u, %u]: Actual physical size %pa, usable size exclude stolen %pa, CPU accessible size %pa\n", id, | 272 | drm_info(&xe->drm, "VRAM[%u, %u]: Actual physical size %pa, usable size exclude stolen %pa, CPU accessible size %pa\n", id, |
| 273 | tile->id, &tile->mem.vram.actual_physical_size, &tile->mem.vram.usable_size, &tile->mem.vram.io_size); | 273 | tile->id, &tile->mem.vram.actual_physical_size, &tile->mem.vram.usable_size, &tile->mem.vram.io_size); |
| 274 | drm_info(&xe->drm, "VRAM[%u, %u]: DPA range: [%pa-%llx], io range: [%pa-%llx]\n", id, tile->id, | 274 | drm_info(&xe->drm, "VRAM[%u, %u]: DPA range: [%pa-%llx], io range: [%pa-%llx]\n", id, tile->id, |
| 275 | &tile->mem.vram.dpa_base, tile->mem.vram.dpa_base + tile->mem.vram.actual_physical_size, | 275 | &tile->mem.vram.dpa_base, tile->mem.vram.dpa_base + (u64)tile->mem.vram.actual_physical_size, |
| 276 | &tile->mem.vram.io_start, tile->mem.vram.io_start + tile->mem.vram.io_size); | 276 | &tile->mem.vram.io_start, tile->mem.vram.io_start + (u64)tile->mem.vram.io_size); |
| 277 | 277 | ||
| 278 | /* calculate total size using tile size to get the correct HW sizing */ | 278 | /* calculate total size using tile size to get the correct HW sizing */ |
| 279 | total_size += tile_size; | 279 | total_size += tile_size; |
| @@ -618,8 +618,8 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma, · 617 unmodified lines | |||
| 618 | 618 | ||
| 619 | if (!xe_vma_is_null(vma)) { | 619 | if (!xe_vma_is_null(vma)) { |
| 620 | if (xe_vma_is_userptr(vma)) | 620 | if (xe_vma_is_userptr(vma)) |
| 621 | xe_res_first_sg(vma->userptr.sg, 0, xe_vma_size(vma), | 621 | xe_res_first_sg(to_userptr_vma(vma)->userptr.sg, 0, |
| 622 | &curs); | 622 | xe_vma_size(vma), &curs); |
| 623 | else if (xe_bo_is_vram(bo) || xe_bo_is_stolen(bo)) | 623 | else if (xe_bo_is_vram(bo) || xe_bo_is_stolen(bo)) |
| 624 | xe_res_first(bo->ttm.resource, xe_vma_bo_offset(vma), | 624 | xe_res_first(bo->ttm.resource, xe_vma_bo_offset(vma), |
| 625 | xe_vma_size(vma), &curs); | 625 | xe_vma_size(vma), &curs); |
| @@ -906,17 +906,17 @@ static void xe_vm_dbg_print_entries(struct xe_device *xe, · 280 unmodified lines | |||
| 906 | 906 | ||
| 907 | #ifdef CONFIG_DRM_XE_USERPTR_INVAL_INJECT | 907 | #ifdef CONFIG_DRM_XE_USERPTR_INVAL_INJECT |
| 908 | 908 | ||
| 909 | static int xe_pt_userptr_inject_eagain(struct xe_vma *vma) | 909 | static int xe_pt_userptr_inject_eagain(struct xe_userptr_vma *uvma) |
| 910 | { | 910 | { |
| 911 | u32 divisor = vma->userptr.divisor ? vma->userptr.divisor : 2; | 911 | u32 divisor = uvma->userptr.divisor ? uvma->userptr.divisor : 2; |
| 912 | static u32 count; | 912 | static u32 count; |
| 913 | 913 | ||
| 914 | if (count++ % divisor == divisor - 1) { | 914 | if (count++ % divisor == divisor - 1) { |
| 915 | struct xe_vm *vm = xe_vma_vm(vma); | 915 | struct xe_vm *vm = xe_vma_vm(&uvma->vma); |
| 916 | 916 | ||
| 917 | vma->userptr.divisor = divisor << 1; | 917 | uvma->userptr.divisor = divisor << 1; |
| 918 | spin_lock(&vm->userptr.invalidated_lock); | 918 | spin_lock(&vm->userptr.invalidated_lock); |
| 919 | list_move_tail(&vma->userptr.invalidate_link, | 919 | list_move_tail(&uvma->userptr.invalidate_link, |
| 920 | &vm->userptr.invalidated); | 920 | &vm->userptr.invalidated); |
| 921 | spin_unlock(&vm->userptr.invalidated_lock); | 921 | spin_unlock(&vm->userptr.invalidated_lock); |
| 922 | return true; | 922 | return true; |
| @@ -927,7 +927,7 @@ static int xe_pt_userptr_inject_eagain(struct xe_vma *vma) · 4 unmodified lines | |||
| 927 | 927 | ||
| 928 | #else | 928 | #else |
| 929 | 929 | ||
| 930 | static bool xe_pt_userptr_inject_eagain(struct xe_vma *vma) | 930 | static bool xe_pt_userptr_inject_eagain(struct xe_userptr_vma *uvma) |
| 931 | { | 931 | { |
| 932 | return false; | 932 | return false; |
| 933 | } | 933 | } |
| @@ -1000,9 +1000,9 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update) · 66 unmodified lines | |||
| 1000 | { | 1000 | { |
| 1001 | struct xe_pt_migrate_pt_update *userptr_update = | 1001 | struct xe_pt_migrate_pt_update *userptr_update = |
| 1002 | container_of(pt_update, typeof(*userptr_update), base); | 1002 | container_of(pt_update, typeof(*userptr_update), base); |
| 1003 | struct xe_vma *vma = pt_update->vma; | 1003 | struct xe_userptr_vma *uvma = to_userptr_vma(pt_update->vma); |
| 1004 | unsigned long notifier_seq = vma->userptr.notifier_seq; | 1004 | unsigned long notifier_seq = uvma->userptr.notifier_seq; |
| 1005 | struct xe_vm *vm = xe_vma_vm(vma); | 1005 | struct xe_vm *vm = xe_vma_vm(&uvma->vma); |
| 1006 | int err = xe_pt_vm_dependencies(pt_update->job, | 1006 | int err = xe_pt_vm_dependencies(pt_update->job, |
| 1007 | &vm->rftree[pt_update->tile_id], | 1007 | &vm->rftree[pt_update->tile_id], |
| 1008 | pt_update->start, | 1008 | pt_update->start, |
| @@ -1023,7 +1023,7 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update) · 14 unmodified lines | |||
| 1023 | */ | 1023 | */ |
| 1024 | do { | 1024 | do { |
| 1025 | down_read(&vm->userptr.notifier_lock); | 1025 | down_read(&vm->userptr.notifier_lock); |
| 1026 | if (!mmu_interval_read_retry(&vma->userptr.notifier, | 1026 | if (!mmu_interval_read_retry(&uvma->userptr.notifier, |
| 1027 | notifier_seq)) | 1027 | notifier_seq)) |
| 1028 | break; | 1028 | break; |
| 1029 | 1029 | ||
| @@ -1032,11 +1032,11 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update) · 2 unmodified lines | |||
| 1032 | if (userptr_update->bind) | 1032 | if (userptr_update->bind) |
| 1033 | return -EAGAIN; | 1033 | return -EAGAIN; |
| 1034 | 1034 | ||
| 1035 | notifier_seq = mmu_interval_read_begin(&vma->userptr.notifier); | 1035 | notifier_seq = mmu_interval_read_begin(&uvma->userptr.notifier); |
| 1036 | } while (true); | 1036 | } while (true); |
| 1037 | 1037 | ||
| 1038 | /* Inject errors to test_whether they are handled correctly */ | 1038 | /* Inject errors to test_whether they are handled correctly */ |
| 1039 | if (userptr_update->bind && xe_pt_userptr_inject_eagain(vma)) { | 1039 | if (userptr_update->bind && xe_pt_userptr_inject_eagain(uvma)) { |
| 1040 | up_read(&vm->userptr.notifier_lock); | 1040 | up_read(&vm->userptr.notifier_lock); |
| 1041 | return -EAGAIN; | 1041 | return -EAGAIN; |
| 1042 | } | 1042 | } |
| @@ -1297,7 +1297,7 @@ __xe_pt_bind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queue · 254 unmodified lines | |||
| 1297 | vma->tile_present |= BIT(tile->id); | 1297 | vma->tile_present |= BIT(tile->id); |
| 1298 | 1298 | ||
| 1299 | if (bind_pt_update.locked) { | 1299 | if (bind_pt_update.locked) { |
| 1300 | vma->userptr.initial_bind = true; | 1300 | to_userptr_vma(vma)->userptr.initial_bind = true; |
| 1301 | up_read(&vm->userptr.notifier_lock); | 1301 | up_read(&vm->userptr.notifier_lock); |
| 1302 | xe_bo_put_commit(&deferred); | 1302 | xe_bo_put_commit(&deferred); |
| 1303 | } | 1303 | } |
| @@ -1642,7 +1642,7 @@ __xe_pt_unbind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queu · 338 unmodified lines | |||
| 1642 | 1642 | ||
| 1643 | if (!vma->tile_present) { | 1643 | if (!vma->tile_present) { |
| 1644 | spin_lock(&vm->userptr.invalidated_lock); | 1644 | spin_lock(&vm->userptr.invalidated_lock); |
| 1645 | list_del_init(&vma->userptr.invalidate_link); | 1645 | list_del_init(&to_userptr_vma(vma)->userptr.invalidate_link); |
| 1646 | spin_unlock(&vm->userptr.invalidated_lock); | 1646 | spin_unlock(&vm->userptr.invalidated_lock); |
| 1647 | } | 1647 | } |
| 1648 | up_read(&vm->userptr.notifier_lock); | 1648 | up_read(&vm->userptr.notifier_lock); |
| @@ -459,21 +459,21 @@ static size_t calc_topo_query_size(struct xe_device *xe) · 458 unmodified lines | |||
| 459 | sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss)); | 459 | sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss)); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | static void __user *copy_mask(void __user *ptr, | 462 | static int copy_mask(void __user **ptr, |
| 463 | struct drm_xe_query_topology_mask *topo, | 463 | struct drm_xe_query_topology_mask *topo, |
| 464 | void *mask, size_t mask_size) | 464 | void *mask, size_t mask_size) |
| 465 | { | 465 | { |
| 466 | topo->num_bytes = mask_size; | 466 | topo->num_bytes = mask_size; |
| 467 | 467 | ||
| 468 | if (copy_to_user(ptr, topo, sizeof(*topo))) | 468 | if (copy_to_user(*ptr, topo, sizeof(*topo))) |
| 469 | return ERR_PTR(-EFAULT); | 469 | return -EFAULT; |
| 470 | ptr += sizeof(topo); | 470 | *ptr += sizeof(topo); |
| 471 | 471 | ||
| 472 | if (copy_to_user(ptr, mask, mask_size)) | 472 | if (copy_to_user(*ptr, mask, mask_size)) |
| 473 | return ERR_PTR(-EFAULT); | 473 | return -EFAULT; |
| 474 | ptr += mask_size; | 474 | *ptr += mask_size; |
| 475 | 475 | ||
| 476 | return ptr; | 476 | return 0; |
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | static int query_gt_topology(struct xe_device *xe, | 479 | static int query_gt_topology(struct xe_device *xe, |
| @@ -493,28 +493,28 @@ static int query_gt_topology(struct xe_device *xe, · 13 unmodified lines | |||
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | for_each_gt(gt, xe, id) { | 495 | for_each_gt(gt, xe, id) { |
| 496 | int err; | ||
| 497 | |||
| 496 | topo.gt_id = id; | 498 | topo.gt_id = id; |
| 497 | 499 | ||
| 498 | topo.type = DRM_XE_TOPO_DSS_GEOMETRY; | 500 | topo.type = DRM_XE_TOPO_DSS_GEOMETRY; |
| 499 | query_ptr = copy_mask(query_ptr, &topo, | 501 | err = copy_mask(&query_ptr, &topo, gt->fuse_topo.g_dss_mask, |
| 500 | gt->fuse_topo.g_dss_mask, | 502 | sizeof(gt->fuse_topo.g_dss_mask)); |
| 501 | sizeof(gt->fuse_topo.g_dss_mask)); | 503 | if (err) |
| 502 | if (IS_ERR(query_ptr)) | 504 | return err; |
| 503 | return PTR_ERR(query_ptr); | ||
| 504 | 505 | ||
| 505 | topo.type = DRM_XE_TOPO_DSS_COMPUTE; | 506 | topo.type = DRM_XE_TOPO_DSS_COMPUTE; |
| 506 | query_ptr = copy_mask(query_ptr, &topo, | 507 | err = copy_mask(&query_ptr, &topo, gt->fuse_topo.c_dss_mask, |
| 507 | gt->fuse_topo.c_dss_mask, | 508 | sizeof(gt->fuse_topo.c_dss_mask)); |
| 508 | sizeof(gt->fuse_topo.c_dss_mask)); | 509 | if (err) |
| 509 | if (IS_ERR(query_ptr)) | 510 | return err; |
| 510 | return PTR_ERR(query_ptr); | ||
| 511 | 511 | ||
| 512 | topo.type = DRM_XE_TOPO_EU_PER_DSS; | 512 | topo.type = DRM_XE_TOPO_EU_PER_DSS; |
| 513 | query_ptr = copy_mask(query_ptr, &topo, | 513 | err = copy_mask(&query_ptr, &topo, |
| 514 | gt->fuse_topo.eu_mask_per_dss, | 514 | gt->fuse_topo.eu_mask_per_dss, |
| 515 | sizeof(gt->fuse_topo.eu_mask_per_dss)); | 515 | sizeof(gt->fuse_topo.eu_mask_per_dss)); |
| 516 | if (IS_ERR(query_ptr)) | 516 | if (err) |
| 517 | return PTR_ERR(query_ptr); | 517 | return err; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | return 0; | 520 | return 0; |
| @@ -274,7 +274,6 @@ int xe_sched_job_last_fence_add_dep(struct xe_sched_job *job, struct xe_vm *vm) · 273 unmodified lines | |||
| 274 | struct dma_fence *fence; | 274 | struct dma_fence *fence; |
| 275 | 275 | ||
| 276 | fence = xe_exec_queue_last_fence_get(job->q, vm); | 276 | fence = xe_exec_queue_last_fence_get(job->q, vm); |
| 277 | dma_fence_get(fence); | ||
| 278 | 277 | ||
| 279 | return drm_sched_job_add_dependency(&job->drm, fence); | 278 | return drm_sched_job_add_dependency(&job->drm, fence); |
| 280 | } | 279 | } |
| @@ -307,7 +307,6 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync, · 306 unmodified lines | |||
| 307 | /* Easy case... */ | 307 | /* Easy case... */ |
| 308 | if (!num_in_fence) { | 308 | if (!num_in_fence) { |
| 309 | fence = xe_exec_queue_last_fence_get(q, vm); | 309 | fence = xe_exec_queue_last_fence_get(q, vm); |
| 310 | dma_fence_get(fence); | ||
| 311 | return fence; | 310 | return fence; |
| 312 | } | 311 | } |
| 313 | 312 | ||
| @@ -322,7 +321,6 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync, · 8 unmodified lines | |||
| 322 | } | 321 | } |
| 323 | } | 322 | } |
| 324 | fences[current_fence++] = xe_exec_queue_last_fence_get(q, vm); | 323 | fences[current_fence++] = xe_exec_queue_last_fence_get(q, vm); |
| 325 | dma_fence_get(fences[current_fence - 1]); | ||
| 326 | cf = dma_fence_array_create(num_in_fence, fences, | 324 | cf = dma_fence_array_create(num_in_fence, fences, |
| 327 | vm->composite_fence_ctx, | 325 | vm->composite_fence_ctx, |
| 328 | vm->composite_fence_seqno++, | 326 | vm->composite_fence_seqno++, |
| @@ -33,4 +33,9 @@ struct dma_fence * · 32 unmodified lines | |||
| 33 | xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync, | 33 | xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync, |
| 34 | struct xe_exec_queue *q, struct xe_vm *vm); | 34 | struct xe_exec_queue *q, struct xe_vm *vm); |
| 35 | 35 | ||
| 36 | static inline bool xe_sync_is_ufence(struct xe_sync_entry *sync) | ||
| 37 | { | ||
| 38 | return !!sync->ufence; | ||
| 39 | } | ||
| 40 | |||
| 36 | #endif | 41 | #endif |
| @@ -37,8 +37,6 @@ · 36 unmodified lines | |||
| 37 | #include "generated/xe_wa_oob.h" | 37 | #include "generated/xe_wa_oob.h" |
| 38 | #include "xe_wa.h" | 38 | #include "xe_wa.h" |
| 39 | 39 | ||
| 40 | #define TEST_VM_ASYNC_OPS_ERROR | ||
| 41 | |||
| 42 | static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm) | 40 | static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm) |
| 43 | { | 41 | { |
| 44 | return vm->gpuvm.r_obj; | 42 | return vm->gpuvm.r_obj; |
| @@ -46,7 +44,7 @@ static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm) · 1 unmodified line | |||
| 46 | 44 | ||
| 47 | /** | 45 | /** |
| 48 | * xe_vma_userptr_check_repin() - Advisory check for repin needed | 46 | * xe_vma_userptr_check_repin() - Advisory check for repin needed |
| 49 | * @vma: The userptr vma | 47 | * @uvma: The userptr vma |
| 50 | * | 48 | * |
| 51 | * Check if the userptr vma has been invalidated since last successful | 49 | * Check if the userptr vma has been invalidated since last successful |
| 52 | * repin. The check is advisory only and can the function can be called | 50 | * repin. The check is advisory only and can the function can be called |
| @@ -56,15 +54,17 @@ static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm) · 3 unmodified lines | |||
| 56 | * | 54 | * |
| 57 | * Return: 0 if userptr vma is valid, -EAGAIN otherwise; repin recommended. | 55 | * Return: 0 if userptr vma is valid, -EAGAIN otherwise; repin recommended. |
| 58 | */ | 56 | */ |
| 59 | int xe_vma_userptr_check_repin(struct xe_vma *vma) | 57 | int xe_vma_userptr_check_repin(struct xe_userptr_vma *uvma) |
| 60 | { | 58 | { |
| 61 | return mmu_interval_check_retry(&vma->userptr.notifier, | 59 | return mmu_interval_check_retry(&uvma->userptr.notifier, |
| 62 | vma->userptr.notifier_seq) ? | 60 | uvma->userptr.notifier_seq) ? |
| 63 | -EAGAIN : 0; | 61 | -EAGAIN : 0; |
| 64 | } | 62 | } |
| 65 | 63 | ||
| 66 | int xe_vma_userptr_pin_pages(struct xe_vma *vma) | 64 | int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma) |
| 67 | { | 65 | { |
| 66 | struct xe_userptr *userptr = &uvma->userptr; | ||
| 67 | struct xe_vma *vma = &uvma->vma; | ||
| 68 | struct xe_vm *vm = xe_vma_vm(vma); | 68 | struct xe_vm *vm = xe_vma_vm(vma); |
| 69 | struct xe_device *xe = vm->xe; | 69 | struct xe_device *xe = vm->xe; |
| 70 | const unsigned long num_pages = xe_vma_size(vma) >> PAGE_SHIFT; | 70 | const unsigned long num_pages = xe_vma_size(vma) >> PAGE_SHIFT; |
| @@ -80,30 +80,30 @@ retry: · 9 unmodified lines | |||
| 80 | if (vma->gpuva.flags & XE_VMA_DESTROYED) | 80 | if (vma->gpuva.flags & XE_VMA_DESTROYED) |
| 81 | return 0; | 81 | return 0; |
| 82 | 82 | ||
| 83 | notifier_seq = mmu_interval_read_begin(&vma->userptr.notifier); | 83 | notifier_seq = mmu_interval_read_begin(&userptr->notifier); |
| 84 | if (notifier_seq == vma->userptr.notifier_seq) | 84 | if (notifier_seq == userptr->notifier_seq) |
| 85 | return 0; | 85 | return 0; |
| 86 | 86 | ||
| 87 | pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL); | 87 | pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL); |
| 88 | if (!pages) | 88 | if (!pages) |
| 89 | return -ENOMEM; | 89 | return -ENOMEM; |
| 90 | 90 | ||
| 91 | if (vma->userptr.sg) { | 91 | if (userptr->sg) { |
| 92 | dma_unmap_sgtable(xe->drm.dev, | 92 | dma_unmap_sgtable(xe->drm.dev, |
| 93 | vma->userptr.sg, | 93 | userptr->sg, |
| 94 | read_only ? DMA_TO_DEVICE : | 94 | read_only ? DMA_TO_DEVICE : |
| 95 | DMA_BIDIRECTIONAL, 0); | 95 | DMA_BIDIRECTIONAL, 0); |
| 96 | sg_free_table(vma->userptr.sg); | 96 | sg_free_table(userptr->sg); |
| 97 | vma->userptr.sg = NULL; | 97 | userptr->sg = NULL; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | pinned = ret = 0; | 100 | pinned = ret = 0; |
| 101 | if (in_kthread) { | 101 | if (in_kthread) { |
| 102 | if (!mmget_not_zero(vma->userptr.notifier.mm)) { | 102 | if (!mmget_not_zero(userptr->notifier.mm)) { |
| 103 | ret = -EFAULT; | 103 | ret = -EFAULT; |
| 104 | goto mm_closed; | 104 | goto mm_closed; |
| 105 | } | 105 | } |
| 106 | kthread_use_mm(vma->userptr.notifier.mm); | 106 | kthread_use_mm(userptr->notifier.mm); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | while (pinned < num_pages) { | 109 | while (pinned < num_pages) { |
| @@ -112,43 +112,40 @@ retry: · 2 unmodified lines | |||
| 112 | num_pages - pinned, | 112 | num_pages - pinned, |
| 113 | read_only ? 0 : FOLL_WRITE, | 113 | read_only ? 0 : FOLL_WRITE, |
| 114 | &pages[pinned]); | 114 | &pages[pinned]); |
| 115 | if (ret < 0) { | 115 | if (ret < 0) |
| 116 | if (in_kthread) | ||
| 117 | ret = 0; | ||
| 118 | break; | 116 | break; |
| 119 | } | ||
| 120 | 117 | ||
| 121 | pinned += ret; | 118 | pinned += ret; |
| 122 | ret = 0; | 119 | ret = 0; |
| 123 | } | 120 | } |
| 124 | 121 | ||
| 125 | if (in_kthread) { | 122 | if (in_kthread) { |
| 126 | kthread_unuse_mm(vma->userptr.notifier.mm); | 123 | kthread_unuse_mm(userptr->notifier.mm); |
| 127 | mmput(vma->userptr.notifier.mm); | 124 | mmput(userptr->notifier.mm); |
| 128 | } | 125 | } |
| 129 | mm_closed: | 126 | mm_closed: |
| 130 | if (ret) | 127 | if (ret) |
| 131 | goto out; | 128 | goto out; |
| 132 | 129 | ||
| 133 | ret = sg_alloc_table_from_pages_segment(&vma->userptr.sgt, pages, | 130 | ret = sg_alloc_table_from_pages_segment(&userptr->sgt, pages, |
| 134 | pinned, 0, | 131 | pinned, 0, |
| 135 | (u64)pinned << PAGE_SHIFT, | 132 | (u64)pinned << PAGE_SHIFT, |
| 136 | xe_sg_segment_size(xe->drm.dev), | 133 | xe_sg_segment_size(xe->drm.dev), |
| 137 | GFP_KERNEL); | 134 | GFP_KERNEL); |
| 138 | if (ret) { | 135 | if (ret) { |
| 139 | vma->userptr.sg = NULL; | 136 | userptr->sg = NULL; |
| 140 | goto out; | 137 | goto out; |
| 141 | } | 138 | } |
| 142 | vma->userptr.sg = &vma->userptr.sgt; | 139 | userptr->sg = &userptr->sgt; |
| 143 | 140 | ||
| 144 | ret = dma_map_sgtable(xe->drm.dev, vma->userptr.sg, | 141 | ret = dma_map_sgtable(xe->drm.dev, userptr->sg, |
| 145 | read_only ? DMA_TO_DEVICE : | 142 | read_only ? DMA_TO_DEVICE : |
| 146 | DMA_BIDIRECTIONAL, | 143 | DMA_BIDIRECTIONAL, |
| 147 | DMA_ATTR_SKIP_CPU_SYNC | | 144 | DMA_ATTR_SKIP_CPU_SYNC | |
| 148 | DMA_ATTR_NO_KERNEL_MAPPING); | 145 | DMA_ATTR_NO_KERNEL_MAPPING); |
| 149 | if (ret) { | 146 | if (ret) { |
| 150 | sg_free_table(vma->userptr.sg); | 147 | sg_free_table(userptr->sg); |
| 151 | vma->userptr.sg = NULL; | 148 | userptr->sg = NULL; |
| 152 | goto out; | 149 | goto out; |
| 153 | } | 150 | } |
| 154 | 151 | ||
| @@ -167,8 +164,8 @@ out: · 12 unmodified lines | |||
| 167 | kvfree(pages); | 164 | kvfree(pages); |
| 168 | 165 | ||
| 169 | if (!(ret < 0)) { | 166 | if (!(ret < 0)) { |
| 170 | vma->userptr.notifier_seq = notifier_seq; | 167 | userptr->notifier_seq = notifier_seq; |
| 171 | if (xe_vma_userptr_check_repin(vma) == -EAGAIN) | 168 | if (xe_vma_userptr_check_repin(uvma) == -EAGAIN) |
| 172 | goto retry; | 169 | goto retry; |
| 173 | } | 170 | } |
| 174 | 171 | ||
| @@ -635,7 +632,9 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni, · 460 unmodified lines | |||
| 635 | const struct mmu_notifier_range *range, | 632 | const struct mmu_notifier_range *range, |
| 636 | unsigned long cur_seq) | 633 | unsigned long cur_seq) |
| 637 | { | 634 | { |
| 638 | struct xe_vma *vma = container_of(mni, struct xe_vma, userptr.notifier); | 635 | struct xe_userptr *userptr = container_of(mni, typeof(*userptr), notifier); |
| 636 | struct xe_userptr_vma *uvma = container_of(userptr, typeof(*uvma), userptr); | ||
| 637 | struct xe_vma *vma = &uvma->vma; | ||
| 639 | struct xe_vm *vm = xe_vma_vm(vma); | 638 | struct xe_vm *vm = xe_vma_vm(vma); |
| 640 | struct dma_resv_iter cursor; | 639 | struct dma_resv_iter cursor; |
| 641 | struct dma_fence *fence; | 640 | struct dma_fence *fence; |
| @@ -651,7 +650,7 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni, · 9 unmodified lines | |||
| 651 | mmu_interval_set_seq(mni, cur_seq); | 650 | mmu_interval_set_seq(mni, cur_seq); |
| 652 | 651 | ||
| 653 | /* No need to stop gpu access if the userptr is not yet bound. */ | 652 | /* No need to stop gpu access if the userptr is not yet bound. */ |
| 654 | if (!vma->userptr.initial_bind) { | 653 | if (!userptr->initial_bind) { |
| 655 | up_write(&vm->userptr.notifier_lock); | 654 | up_write(&vm->userptr.notifier_lock); |
| 656 | return true; | 655 | return true; |
| 657 | } | 656 | } |
| @@ -663,7 +662,7 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni, · 5 unmodified lines | |||
| 663 | if (!xe_vm_in_fault_mode(vm) && | 662 | if (!xe_vm_in_fault_mode(vm) && |
| 664 | !(vma->gpuva.flags & XE_VMA_DESTROYED) && vma->tile_present) { | 663 | !(vma->gpuva.flags & XE_VMA_DESTROYED) && vma->tile_present) { |
| 665 | spin_lock(&vm->userptr.invalidated_lock); | 664 | spin_lock(&vm->userptr.invalidated_lock); |
| 666 | list_move_tail(&vma->userptr.invalidate_link, | 665 | list_move_tail(&userptr->invalidate_link, |
| 667 | &vm->userptr.invalidated); | 666 | &vm->userptr.invalidated); |
| 668 | spin_unlock(&vm->userptr.invalidated_lock); | 667 | spin_unlock(&vm->userptr.invalidated_lock); |
| 669 | } | 668 | } |
| @@ -703,7 +702,7 @@ static const struct mmu_interval_notifier_ops vma_userptr_notifier_ops = { · 33 unmodified lines | |||
| 703 | 702 | ||
| 704 | int xe_vm_userptr_pin(struct xe_vm *vm) | 703 | int xe_vm_userptr_pin(struct xe_vm *vm) |
| 705 | { | 704 | { |
| 706 | struct xe_vma *vma, *next; | 705 | struct xe_userptr_vma *uvma, *next; |
| 707 | int err = 0; | 706 | int err = 0; |
| 708 | LIST_HEAD(tmp_evict); | 707 | LIST_HEAD(tmp_evict); |
| 709 | 708 | ||
| @@ -711,22 +710,23 @@ int xe_vm_userptr_pin(struct xe_vm *vm) · 1 unmodified line | |||
| 711 | 710 | ||
| 712 | /* Collect invalidated userptrs */ | 711 | /* Collect invalidated userptrs */ |
| 713 | spin_lock(&vm->userptr.invalidated_lock); | 712 | spin_lock(&vm->userptr.invalidated_lock); |
| 714 | list_for_each_entry_safe(vma, next, &vm->userptr.invalidated, | 713 | list_for_each_entry_safe(uvma, next, &vm->userptr.invalidated, |
| 715 | userptr.invalidate_link) { | 714 | userptr.invalidate_link) { |
| 716 | list_del_init(&vma->userptr.invalidate_link); | 715 | list_del_init(&uvma->userptr.invalidate_link); |
| 717 | list_move_tail(&vma->combined_links.userptr, | 716 | list_move_tail(&uvma->userptr.repin_link, |
| 718 | &vm->userptr.repin_list); | 717 | &vm->userptr.repin_list); |
| 719 | } | 718 | } |
| 720 | spin_unlock(&vm->userptr.invalidated_lock); | 719 | spin_unlock(&vm->userptr.invalidated_lock); |
| 721 | 720 | ||
| 722 | /* Pin and move to temporary list */ | 721 | /* Pin and move to temporary list */ |
| 723 | list_for_each_entry_safe(vma, next, &vm->userptr.repin_list, | 722 | list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list, |
| 724 | combined_links.userptr) { | 723 | userptr.repin_link) { |
| 725 | err = xe_vma_userptr_pin_pages(vma); | 724 | err = xe_vma_userptr_pin_pages(uvma); |
| 726 | if (err < 0) | 725 | if (err < 0) |
| 727 | return err; | 726 | return err; |
| 728 | 727 | ||
| 729 | list_move_tail(&vma->combined_links.userptr, &vm->rebind_list); | 728 | list_del_init(&uvma->userptr.repin_link); |
| 729 | list_move_tail(&uvma->vma.combined_links.rebind, &vm->rebind_list); | ||
| 730 | } | 730 | } |
| 731 | 731 | ||
| 732 | return 0; | 732 | return 0; |
| @@ -782,6 +782,14 @@ struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker) · 49 unmodified lines | |||
| 782 | return fence; | 782 | return fence; |
| 783 | } | 783 | } |
| 784 | 784 | ||
| 785 | static void xe_vma_free(struct xe_vma *vma) | ||
| 786 | { | ||
| 787 | if (xe_vma_is_userptr(vma)) | ||
| 788 | kfree(to_userptr_vma(vma)); | ||
| 789 | else | ||
| 790 | kfree(vma); | ||
| 791 | } | ||
| 792 | |||
| 785 | #define VMA_CREATE_FLAG_READ_ONLY BIT(0) | 793 | #define VMA_CREATE_FLAG_READ_ONLY BIT(0) |
| 786 | #define VMA_CREATE_FLAG_IS_NULL BIT(1) | 794 | #define VMA_CREATE_FLAG_IS_NULL BIT(1) |
| 787 | 795 | ||
| @@ -800,14 +808,26 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, · 12 unmodified lines | |||
| 800 | xe_assert(vm->xe, start < end); | 808 | xe_assert(vm->xe, start < end); |
| 801 | xe_assert(vm->xe, end < vm->size); | 809 | xe_assert(vm->xe, end < vm->size); |
| 802 | 810 | ||
| 803 | if (!bo && !is_null) /* userptr */ | 811 | /* |
| 812 | * Allocate and ensure that the xe_vma_is_userptr() return | ||
| 813 | * matches what was allocated. | ||
| 814 | */ | ||
| 815 | if (!bo && !is_null) { | ||
| 816 | struct xe_userptr_vma *uvma = kzalloc(sizeof(*uvma), GFP_KERNEL); | ||
| 817 | |||
| 818 | if (!uvma) | ||
| 819 | return ERR_PTR(-ENOMEM); | ||
| 820 | |||
| 821 | vma = &uvma->vma; | ||
| 822 | } else { | ||
| 804 | vma = kzalloc(sizeof(*vma), GFP_KERNEL); | 823 | vma = kzalloc(sizeof(*vma), GFP_KERNEL); |
| 805 | else | 824 | if (!vma) |
| 806 | vma = kzalloc(sizeof(*vma) - sizeof(struct xe_userptr), | 825 | return ERR_PTR(-ENOMEM); |
| 807 | GFP_KERNEL); | 826 | |
| 808 | if (!vma) { | 827 | if (is_null) |
| 809 | vma = ERR_PTR(-ENOMEM); | 828 | vma->gpuva.flags |= DRM_GPUVA_SPARSE; |
| 810 | return vma; | 829 | if (bo) |
| 830 | vma->gpuva.gem.obj = &bo->ttm.base; | ||
| 811 | } | 831 | } |
| 812 | 832 | ||
| 813 | INIT_LIST_HEAD(&vma->combined_links.rebind); | 833 | INIT_LIST_HEAD(&vma->combined_links.rebind); |
| @@ -818,8 +838,6 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, · 4 unmodified lines | |||
| 818 | vma->gpuva.va.range = end - start + 1; | 838 | vma->gpuva.va.range = end - start + 1; |
| 819 | if (read_only) | 839 | if (read_only) |
| 820 | vma->gpuva.flags |= XE_VMA_READ_ONLY; | 840 | vma->gpuva.flags |= XE_VMA_READ_ONLY; |
| 821 | if (is_null) | ||
| 822 | vma->gpuva.flags |= DRM_GPUVA_SPARSE; | ||
| 823 | 841 | ||
| 824 | for_each_tile(tile, vm->xe, id) | 842 | for_each_tile(tile, vm->xe, id) |
| 825 | vma->tile_mask |= 0x1 << id; | 843 | vma->tile_mask |= 0x1 << id; |
| @@ -836,35 +854,35 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, · 10 unmodified lines | |||
| 836 | 854 | ||
| 837 | vm_bo = drm_gpuvm_bo_obtain(vma->gpuva.vm, &bo->ttm.base); | 855 | vm_bo = drm_gpuvm_bo_obtain(vma->gpuva.vm, &bo->ttm.base); |
| 838 | if (IS_ERR(vm_bo)) { | 856 | if (IS_ERR(vm_bo)) { |
| 839 | kfree(vma); | 857 | xe_vma_free(vma); |
| 840 | return ERR_CAST(vm_bo); | 858 | return ERR_CAST(vm_bo); |
| 841 | } | 859 | } |
| 842 | 860 | ||
| 843 | drm_gpuvm_bo_extobj_add(vm_bo); | 861 | drm_gpuvm_bo_extobj_add(vm_bo); |
| 844 | drm_gem_object_get(&bo->ttm.base); | 862 | drm_gem_object_get(&bo->ttm.base); |
| 845 | vma->gpuva.gem.obj = &bo->ttm.base; | ||
| 846 | vma->gpuva.gem.offset = bo_offset_or_userptr; | 863 | vma->gpuva.gem.offset = bo_offset_or_userptr; |
| 847 | drm_gpuva_link(&vma->gpuva, vm_bo); | 864 | drm_gpuva_link(&vma->gpuva, vm_bo); |
| 848 | drm_gpuvm_bo_put(vm_bo); | 865 | drm_gpuvm_bo_put(vm_bo); |
| 849 | } else /* userptr or null */ { | 866 | } else /* userptr or null */ { |
| 850 | if (!is_null) { | 867 | if (!is_null) { |
| 868 | struct xe_userptr *userptr = &to_userptr_vma(vma)->userptr; | ||
| 851 | u64 size = end - start + 1; | 869 | u64 size = end - start + 1; |
| 852 | int err; | 870 | int err; |
| 853 | 871 | ||
| 854 | INIT_LIST_HEAD(&vma->userptr.invalidate_link); | 872 | INIT_LIST_HEAD(&userptr->invalidate_link); |
| 873 | INIT_LIST_HEAD(&userptr->repin_link); | ||
| 855 | vma->gpuva.gem.offset = bo_offset_or_userptr; | 874 | vma->gpuva.gem.offset = bo_offset_or_userptr; |
| 856 | 875 | ||
| 857 | err = mmu_interval_notifier_insert(&vma->userptr.notifier, | 876 | err = mmu_interval_notifier_insert(&userptr->notifier, |
| 858 | current->mm, | 877 | current->mm, |
| 859 | xe_vma_userptr(vma), size, | 878 | xe_vma_userptr(vma), size, |
| 860 | &vma_userptr_notifier_ops); | 879 | &vma_userptr_notifier_ops); |
| 861 | if (err) { | 880 | if (err) { |
| 862 | kfree(vma); | 881 | xe_vma_free(vma); |
| 863 | vma = ERR_PTR(err); | 882 | return ERR_PTR(err); |
| 864 | return vma; | ||
| 865 | } | 883 | } |
| 866 | 884 | ||
| 867 | vma->userptr.notifier_seq = LONG_MAX; | 885 | userptr->notifier_seq = LONG_MAX; |
| 868 | } | 886 | } |
| 869 | 887 | ||
| 870 | xe_vm_get(vm); | 888 | xe_vm_get(vm); |
| @@ -880,13 +898,15 @@ static void xe_vma_destroy_late(struct xe_vma *vma) · 9 unmodified lines | |||
| 880 | bool read_only = xe_vma_read_only(vma); | 898 | bool read_only = xe_vma_read_only(vma); |
| 881 | 899 | ||
| 882 | if (xe_vma_is_userptr(vma)) { | 900 | if (xe_vma_is_userptr(vma)) { |
| 883 | if (vma->userptr.sg) { | 901 | struct xe_userptr *userptr = &to_userptr_vma(vma)->userptr; |
| 902 | |||
| 903 | if (userptr->sg) { | ||
| 884 | dma_unmap_sgtable(xe->drm.dev, | 904 | dma_unmap_sgtable(xe->drm.dev, |
| 885 | vma->userptr.sg, | 905 | userptr->sg, |
| 886 | read_only ? DMA_TO_DEVICE : | 906 | read_only ? DMA_TO_DEVICE : |
| 887 | DMA_BIDIRECTIONAL, 0); | 907 | DMA_BIDIRECTIONAL, 0); |
| 888 | sg_free_table(vma->userptr.sg); | 908 | sg_free_table(userptr->sg); |
| 889 | vma->userptr.sg = NULL; | 909 | userptr->sg = NULL; |
| 890 | } | 910 | } |
| 891 | 911 | ||
| 892 | /* | 912 | /* |
| @@ -894,7 +914,7 @@ static void xe_vma_destroy_late(struct xe_vma *vma) · 1 unmodified line | |||
| 894 | * the notifer until we're sure the GPU is not accessing | 914 | * the notifer until we're sure the GPU is not accessing |
| 895 | * them anymore | 915 | * them anymore |
| 896 | */ | 916 | */ |
| 897 | mmu_interval_notifier_remove(&vma->userptr.notifier); | 917 | mmu_interval_notifier_remove(&userptr->notifier); |
| 898 | xe_vm_put(vm); | 918 | xe_vm_put(vm); |
| 899 | } else if (xe_vma_is_null(vma)) { | 919 | } else if (xe_vma_is_null(vma)) { |
| 900 | xe_vm_put(vm); | 920 | xe_vm_put(vm); |
| @@ -902,7 +922,7 @@ static void xe_vma_destroy_late(struct xe_vma *vma) · 1 unmodified line | |||
| 902 | xe_bo_put(xe_vma_bo(vma)); | 922 | xe_bo_put(xe_vma_bo(vma)); |
| 903 | } | 923 | } |
| 904 | 924 | ||
| 905 | kfree(vma); | 925 | xe_vma_free(vma); |
| 906 | } | 926 | } |
| 907 | 927 | ||
| 908 | static void vma_destroy_work_func(struct work_struct *w) | 928 | static void vma_destroy_work_func(struct work_struct *w) |
| @@ -933,7 +953,7 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence) · 24 unmodified lines | |||
| 933 | xe_assert(vm->xe, vma->gpuva.flags & XE_VMA_DESTROYED); | 953 | xe_assert(vm->xe, vma->gpuva.flags & XE_VMA_DESTROYED); |
| 934 | 954 | ||
| 935 | spin_lock(&vm->userptr.invalidated_lock); | 955 | spin_lock(&vm->userptr.invalidated_lock); |
| 936 | list_del(&vma->userptr.invalidate_link); | 956 | list_del(&to_userptr_vma(vma)->userptr.invalidate_link); |
| 937 | spin_unlock(&vm->userptr.invalidated_lock); | 957 | spin_unlock(&vm->userptr.invalidated_lock); |
| 938 | } else if (!xe_vma_is_null(vma)) { | 958 | } else if (!xe_vma_is_null(vma)) { |
| 939 | xe_bo_assert_held(xe_vma_bo(vma)); | 959 | xe_bo_assert_held(xe_vma_bo(vma)); |
| @@ -1855,10 +1875,8 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 915 unmodified lines | |||
| 1855 | mutex_lock(&xef->vm.lock); | 1875 | mutex_lock(&xef->vm.lock); |
| 1856 | err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); | 1876 | err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); |
| 1857 | mutex_unlock(&xef->vm.lock); | 1877 | mutex_unlock(&xef->vm.lock); |
| 1858 | if (err) { | 1878 | if (err) |
| 1859 | xe_vm_close_and_put(vm); | 1879 | goto err_close_and_put; |
| 1860 | return err; | ||
| 1861 | } | ||
| 1862 | 1880 | ||
| 1863 | if (xe->info.has_asid) { | 1881 | if (xe->info.has_asid) { |
| 1864 | mutex_lock(&xe->usm.lock); | 1882 | mutex_lock(&xe->usm.lock); |
| @@ -1866,11 +1884,9 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 1 unmodified line | |||
| 1866 | XA_LIMIT(1, XE_MAX_ASID - 1), | 1884 | XA_LIMIT(1, XE_MAX_ASID - 1), |
| 1867 | &xe->usm.next_asid, GFP_KERNEL); | 1885 | &xe->usm.next_asid, GFP_KERNEL); |
| 1868 | mutex_unlock(&xe->usm.lock); | 1886 | mutex_unlock(&xe->usm.lock); |
| 1869 | if (err < 0) { | 1887 | if (err < 0) |
| 1870 | xe_vm_close_and_put(vm); | 1888 | goto err_free_id; |
| 1871 | return err; | 1889 | |
| 1872 | } | ||
| 1873 | err = 0; | ||
| 1874 | vm->usm.asid = asid; | 1890 | vm->usm.asid = asid; |
| 1875 | } | 1891 | } |
| 1876 | 1892 | ||
| @@ -1888,6 +1904,15 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 11 unmodified lines | |||
| 1888 | #endif | 1904 | #endif |
| 1889 | 1905 | ||
| 1890 | return 0; | 1906 | return 0; |
| 1907 | |||
| 1908 | err_free_id: | ||
| 1909 | mutex_lock(&xef->vm.lock); | ||
| 1910 | xa_erase(&xef->vm.xa, id); | ||
| 1911 | mutex_unlock(&xef->vm.lock); | ||
| 1912 | err_close_and_put: | ||
| 1913 | xe_vm_close_and_put(vm); | ||
| 1914 | |||
| 1915 | return err; | ||
| 1891 | } | 1916 | } |
| 1892 | 1917 | ||
| 1893 | int xe_vm_destroy_ioctl(struct drm_device *dev, void *data, | 1918 | int xe_vm_destroy_ioctl(struct drm_device *dev, void *data, |
| @@ -1954,6 +1979,7 @@ static int xe_vm_prefetch(struct xe_vm *vm, struct xe_vma *vma, · 60 unmodified lines | |||
| 1954 | xe_exec_queue_last_fence_get(wait_exec_queue, vm); | 1979 | xe_exec_queue_last_fence_get(wait_exec_queue, vm); |
| 1955 | 1980 | ||
| 1956 | xe_sync_entry_signal(&syncs[i], NULL, fence); | 1981 | xe_sync_entry_signal(&syncs[i], NULL, fence); |
| 1982 | dma_fence_put(fence); | ||
| 1957 | } | 1983 | } |
| 1958 | } | 1984 | } |
| 1959 | 1985 | ||
| @@ -2034,7 +2060,6 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo, · 74 unmodified lines | |||
| 2034 | struct drm_gem_object *obj = bo ? &bo->ttm.base : NULL; | 2060 | struct drm_gem_object *obj = bo ? &bo->ttm.base : NULL; |
| 2035 | struct drm_gpuva_ops *ops; | 2061 | struct drm_gpuva_ops *ops; |
| 2036 | struct drm_gpuva_op *__op; | 2062 | struct drm_gpuva_op *__op; |
| 2037 | struct xe_vma_op *op; | ||
| 2038 | struct drm_gpuvm_bo *vm_bo; | 2063 | struct drm_gpuvm_bo *vm_bo; |
| 2039 | int err; | 2064 | int err; |
| 2040 | 2065 | ||
| @@ -2081,15 +2106,6 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo, · 40 unmodified lines | |||
| 2081 | if (IS_ERR(ops)) | 2106 | if (IS_ERR(ops)) |
| 2082 | return ops; | 2107 | return ops; |
| 2083 | 2108 | ||
| 2084 | #ifdef TEST_VM_ASYNC_OPS_ERROR | ||
| 2085 | if (operation & FORCE_ASYNC_OP_ERROR) { | ||
| 2086 | op = list_first_entry_or_null(&ops->list, struct xe_vma_op, | ||
| 2087 | base.entry); | ||
| 2088 | if (op) | ||
| 2089 | op->inject_error = true; | ||
| 2090 | } | ||
| 2091 | #endif | ||
| 2092 | |||
| 2093 | drm_gpuva_for_each_op(__op, ops) { | 2109 | drm_gpuva_for_each_op(__op, ops) { |
| 2094 | struct xe_vma_op *op = gpuva_op_to_vma_op(__op); | 2110 | struct xe_vma_op *op = gpuva_op_to_vma_op(__op); |
| 2095 | 2111 | ||
| @@ -2145,7 +2161,7 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op, · 49 unmodified lines | |||
| 2145 | drm_exec_fini(&exec); | 2161 | drm_exec_fini(&exec); |
| 2146 | 2162 | ||
| 2147 | if (xe_vma_is_userptr(vma)) { | 2163 | if (xe_vma_is_userptr(vma)) { |
| 2148 | err = xe_vma_userptr_pin_pages(vma); | 2164 | err = xe_vma_userptr_pin_pages(to_userptr_vma(vma)); |
| 2149 | if (err) { | 2165 | if (err) { |
| 2150 | prep_vma_destroy(vm, vma, false); | 2166 | prep_vma_destroy(vm, vma, false); |
| 2151 | xe_vma_destroy_unlocked(vma); | 2167 | xe_vma_destroy_unlocked(vma); |
| @@ -2169,8 +2185,10 @@ static u64 xe_vma_max_pte_size(struct xe_vma *vma) · 17 unmodified lines | |||
| 2169 | return SZ_1G; | 2185 | return SZ_1G; |
| 2170 | else if (vma->gpuva.flags & XE_VMA_PTE_2M) | 2186 | else if (vma->gpuva.flags & XE_VMA_PTE_2M) |
| 2171 | return SZ_2M; | 2187 | return SZ_2M; |
| 2188 | else if (vma->gpuva.flags & XE_VMA_PTE_4K) | ||
| 2189 | return SZ_4K; | ||
| 2172 | 2190 | ||
| 2173 | return SZ_4K; | 2191 | return SZ_1G; /* Uninitialized, used max size */ |
| 2174 | } | 2192 | } |
| 2175 | 2193 | ||
| 2176 | static u64 xe_vma_set_pte_size(struct xe_vma *vma, u64 size) | 2194 | static u64 xe_vma_set_pte_size(struct xe_vma *vma, u64 size) |
| @@ -2500,13 +2518,25 @@ retry_userptr: · 323 unmodified lines | |||
| 2500 | } | 2518 | } |
| 2501 | drm_exec_fini(&exec); | 2519 | drm_exec_fini(&exec); |
| 2502 | 2520 | ||
| 2503 | if (err == -EAGAIN && xe_vma_is_userptr(vma)) { | 2521 | if (err == -EAGAIN) { |
| 2504 | lockdep_assert_held_write(&vm->lock); | 2522 | lockdep_assert_held_write(&vm->lock); |
| 2505 | err = xe_vma_userptr_pin_pages(vma); | ||
| 2506 | if (!err) | ||
| 2507 | goto retry_userptr; | ||
| 2508 | 2523 | ||
| 2509 | trace_xe_vma_fail(vma); | 2524 | if (op->base.op == DRM_GPUVA_OP_REMAP) { |
| 2525 | if (!op->remap.unmap_done) | ||
| 2526 | vma = gpuva_to_vma(op->base.remap.unmap->va); | ||
| 2527 | else if (op->remap.prev) | ||
| 2528 | vma = op->remap.prev; | ||
| 2529 | else | ||
| 2530 | vma = op->remap.next; | ||
| 2531 | } | ||
| 2532 | |||
| 2533 | if (xe_vma_is_userptr(vma)) { | ||
| 2534 | err = xe_vma_userptr_pin_pages(to_userptr_vma(vma)); | ||
| 2535 | if (!err) | ||
| 2536 | goto retry_userptr; | ||
| 2537 | |||
| 2538 | trace_xe_vma_fail(vma); | ||
| 2539 | } | ||
| 2510 | } | 2540 | } |
| 2511 | 2541 | ||
| 2512 | return err; | 2542 | return err; |
| @@ -2518,13 +2548,6 @@ static int xe_vma_op_execute(struct xe_vm *vm, struct xe_vma_op *op) · 5 unmodified lines | |||
| 2518 | 2548 | ||
| 2519 | lockdep_assert_held_write(&vm->lock); | 2549 | lockdep_assert_held_write(&vm->lock); |
| 2520 | 2550 | ||
| 2521 | #ifdef TEST_VM_ASYNC_OPS_ERROR | ||
| 2522 | if (op->inject_error) { | ||
| 2523 | op->inject_error = false; | ||
| 2524 | return -ENOMEM; | ||
| 2525 | } | ||
| 2526 | #endif | ||
| 2527 | |||
| 2528 | switch (op->base.op) { | 2551 | switch (op->base.op) { |
| 2529 | case DRM_GPUVA_OP_MAP: | 2552 | case DRM_GPUVA_OP_MAP: |
| 2530 | ret = __xe_vma_op_execute(vm, op->map.vma, op); | 2553 | ret = __xe_vma_op_execute(vm, op->map.vma, op); |
| @@ -2639,7 +2662,7 @@ static void vm_bind_ioctl_ops_unwind(struct xe_vm *vm, · 108 unmodified lines | |||
| 2639 | { | 2662 | { |
| 2640 | int i; | 2663 | int i; |
| 2641 | 2664 | ||
| 2642 | for (i = num_ops_list - 1; i; ++i) { | 2665 | for (i = num_ops_list - 1; i >= 0; --i) { |
| 2643 | struct drm_gpuva_ops *__ops = ops[i]; | 2666 | struct drm_gpuva_ops *__ops = ops[i]; |
| 2644 | struct drm_gpuva_op *__op; | 2667 | struct drm_gpuva_op *__op; |
| 2645 | 2668 | ||
| @@ -2684,16 +2707,9 @@ static int vm_bind_ioctl_ops_execute(struct xe_vm *vm, · 38 unmodified lines | |||
| 2684 | return 0; | 2707 | return 0; |
| 2685 | } | 2708 | } |
| 2686 | 2709 | ||
| 2687 | #ifdef TEST_VM_ASYNC_OPS_ERROR | ||
| 2688 | #define SUPPORTED_FLAGS \ | ||
| 2689 | (FORCE_ASYNC_OP_ERROR | DRM_XE_VM_BIND_FLAG_READONLY | \ | ||
| 2690 | DRM_XE_VM_BIND_FLAG_IMMEDIATE | DRM_XE_VM_BIND_FLAG_NULL | 0xffff) | ||
| 2691 | #else | ||
| 2692 | #define SUPPORTED_FLAGS \ | 2710 | #define SUPPORTED_FLAGS \ |
| 2693 | (DRM_XE_VM_BIND_FLAG_READONLY | \ | 2711 | (DRM_XE_VM_BIND_FLAG_READONLY | \ |
| 2694 | DRM_XE_VM_BIND_FLAG_IMMEDIATE | DRM_XE_VM_BIND_FLAG_NULL | \ | 2712 | DRM_XE_VM_BIND_FLAG_IMMEDIATE | DRM_XE_VM_BIND_FLAG_NULL) |
| 2695 | 0xffff) | ||
| 2696 | #endif | ||
| 2697 | #define XE_64K_PAGE_MASK 0xffffull | 2713 | #define XE_64K_PAGE_MASK 0xffffull |
| 2698 | #define ALL_DRM_XE_SYNCS_FLAGS (DRM_XE_SYNCS_FLAG_WAIT_FOR_OP) | 2714 | #define ALL_DRM_XE_SYNCS_FLAGS (DRM_XE_SYNCS_FLAG_WAIT_FOR_OP) |
| 2699 | 2715 | ||
| @@ -2846,7 +2862,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 146 unmodified lines | |||
| 2846 | struct drm_gpuva_ops **ops = NULL; | 2862 | struct drm_gpuva_ops **ops = NULL; |
| 2847 | struct xe_vm *vm; | 2863 | struct xe_vm *vm; |
| 2848 | struct xe_exec_queue *q = NULL; | 2864 | struct xe_exec_queue *q = NULL; |
| 2849 | u32 num_syncs; | 2865 | u32 num_syncs, num_ufence = 0; |
| 2850 | struct xe_sync_entry *syncs = NULL; | 2866 | struct xe_sync_entry *syncs = NULL; |
| 2851 | struct drm_xe_vm_bind_op *bind_ops; | 2867 | struct drm_xe_vm_bind_op *bind_ops; |
| 2852 | LIST_HEAD(ops_list); | 2868 | LIST_HEAD(ops_list); |
| @@ -2983,6 +2999,14 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 130 unmodified lines | |||
| 2983 | SYNC_PARSE_FLAG_DISALLOW_USER_FENCE : 0)); | 2999 | SYNC_PARSE_FLAG_DISALLOW_USER_FENCE : 0)); |
| 2984 | if (err) | 3000 | if (err) |
| 2985 | goto free_syncs; | 3001 | goto free_syncs; |
| 3002 | |||
| 3003 | if (xe_sync_is_ufence(&syncs[num_syncs])) | ||
| 3004 | num_ufence++; | ||
| 3005 | } | ||
| 3006 | |||
| 3007 | if (XE_IOCTL_DBG(xe, num_ufence > 1)) { | ||
| 3008 | err = -EINVAL; | ||
| 3009 | goto free_syncs; | ||
| 2986 | } | 3010 | } |
| 2987 | 3011 | ||
| 2988 | if (!args->num_binds) { | 3012 | if (!args->num_binds) { |
| @@ -3125,8 +3149,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma) · 136 unmodified lines | |||
| 3125 | if (IS_ENABLED(CONFIG_PROVE_LOCKING)) { | 3149 | if (IS_ENABLED(CONFIG_PROVE_LOCKING)) { |
| 3126 | if (xe_vma_is_userptr(vma)) { | 3150 | if (xe_vma_is_userptr(vma)) { |
| 3127 | WARN_ON_ONCE(!mmu_interval_check_retry | 3151 | WARN_ON_ONCE(!mmu_interval_check_retry |
| 3128 | (&vma->userptr.notifier, | 3152 | (&to_userptr_vma(vma)->userptr.notifier, |
| 3129 | vma->userptr.notifier_seq)); | 3153 | to_userptr_vma(vma)->userptr.notifier_seq)); |
| 3130 | WARN_ON_ONCE(!dma_resv_test_signaled(xe_vm_resv(xe_vma_vm(vma)), | 3154 | WARN_ON_ONCE(!dma_resv_test_signaled(xe_vm_resv(xe_vma_vm(vma)), |
| 3131 | DMA_RESV_USAGE_BOOKKEEP)); | 3155 | DMA_RESV_USAGE_BOOKKEEP)); |
| 3132 | 3156 | ||
| @@ -3187,11 +3211,11 @@ int xe_analyze_vm(struct drm_printer *p, struct xe_vm *vm, int gt_id) · 54 unmodified lines | |||
| 3187 | if (is_null) { | 3211 | if (is_null) { |
| 3188 | addr = 0; | 3212 | addr = 0; |
| 3189 | } else if (is_userptr) { | 3213 | } else if (is_userptr) { |
| 3214 | struct sg_table *sg = to_userptr_vma(vma)->userptr.sg; | ||
| 3190 | struct xe_res_cursor cur; | 3215 | struct xe_res_cursor cur; |
| 3191 | 3216 | ||
| 3192 | if (vma->userptr.sg) { | 3217 | if (sg) { |
| 3193 | xe_res_first_sg(vma->userptr.sg, 0, XE_PAGE_SIZE, | 3218 | xe_res_first_sg(sg, 0, XE_PAGE_SIZE, &cur); |
| 3194 | &cur); | ||
| 3195 | addr = xe_res_dma(&cur); | 3219 | addr = xe_res_dma(&cur); |
| 3196 | } else { | 3220 | } else { |
| 3197 | addr = 0; | 3221 | addr = 0; |
| @@ -160,6 +160,18 @@ static inline bool xe_vma_is_userptr(struct xe_vma *vma) · 159 unmodified lines | |||
| 160 | return xe_vma_has_no_bo(vma) && !xe_vma_is_null(vma); | 160 | return xe_vma_has_no_bo(vma) && !xe_vma_is_null(vma); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | /** | ||
| 164 | * to_userptr_vma() - Return a pointer to an embedding userptr vma | ||
| 165 | * @vma: Pointer to the embedded struct xe_vma | ||
| 166 | * | ||
| 167 | * Return: Pointer to the embedding userptr vma | ||
| 168 | */ | ||
| 169 | static inline struct xe_userptr_vma *to_userptr_vma(struct xe_vma *vma) | ||
| 170 | { | ||
| 171 | xe_assert(xe_vma_vm(vma)->xe, xe_vma_is_userptr(vma)); | ||
| 172 | return container_of(vma, struct xe_userptr_vma, vma); | ||
| 173 | } | ||
| 174 | |||
| 163 | u64 xe_vm_pdp4_descriptor(struct xe_vm *vm, struct xe_tile *tile); | 175 | u64 xe_vm_pdp4_descriptor(struct xe_vm *vm, struct xe_tile *tile); |
| 164 | 176 | ||
| 165 | int xe_vm_create_ioctl(struct drm_device *dev, void *data, | 177 | int xe_vm_create_ioctl(struct drm_device *dev, void *data, |
| @@ -224,9 +236,9 @@ static inline void xe_vm_reactivate_rebind(struct xe_vm *vm) · 58 unmodified lines | |||
| 224 | } | 236 | } |
| 225 | } | 237 | } |
| 226 | 238 | ||
| 227 | int xe_vma_userptr_pin_pages(struct xe_vma *vma); | 239 | int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma); |
| 228 | 240 | ||
| 229 | int xe_vma_userptr_check_repin(struct xe_vma *vma); | 241 | int xe_vma_userptr_check_repin(struct xe_userptr_vma *uvma); |
| 230 | 242 | ||
| 231 | bool xe_vm_validate_should_retry(struct drm_exec *exec, int err, ktime_t *end); | 243 | bool xe_vm_validate_should_retry(struct drm_exec *exec, int err, ktime_t *end); |
| 232 | 244 | ||
| @@ -21,9 +21,6 @@ struct xe_bo; · 20 unmodified lines | |||
| 21 | struct xe_sync_entry; | 21 | struct xe_sync_entry; |
| 22 | struct xe_vm; | 22 | struct xe_vm; |
| 23 | 23 | ||
| 24 | #define TEST_VM_ASYNC_OPS_ERROR | ||
| 25 | #define FORCE_ASYNC_OP_ERROR BIT(31) | ||
| 26 | |||
| 27 | #define XE_VMA_READ_ONLY DRM_GPUVA_USERBITS | 24 | #define XE_VMA_READ_ONLY DRM_GPUVA_USERBITS |
| 28 | #define XE_VMA_DESTROYED (DRM_GPUVA_USERBITS << 1) | 25 | #define XE_VMA_DESTROYED (DRM_GPUVA_USERBITS << 1) |
| 29 | #define XE_VMA_ATOMIC_PTE_BIT (DRM_GPUVA_USERBITS << 2) | 26 | #define XE_VMA_ATOMIC_PTE_BIT (DRM_GPUVA_USERBITS << 2) |
| @@ -37,6 +34,8 @@ struct xe_vm; · 7 unmodified lines | |||
| 37 | struct xe_userptr { | 34 | struct xe_userptr { |
| 38 | /** @invalidate_link: Link for the vm::userptr.invalidated list */ | 35 | /** @invalidate_link: Link for the vm::userptr.invalidated list */ |
| 39 | struct list_head invalidate_link; | 36 | struct list_head invalidate_link; |
| 37 | /** @userptr: link into VM repin list if userptr. */ | ||
| 38 | struct list_head repin_link; | ||
| 40 | /** | 39 | /** |
| 41 | * @notifier: MMU notifier for user pointer (invalidation call back) | 40 | * @notifier: MMU notifier for user pointer (invalidation call back) |
| 42 | */ | 41 | */ |
| @@ -68,8 +67,6 @@ struct xe_vma { · 25 unmodified lines | |||
| 68 | * resv. | 67 | * resv. |
| 69 | */ | 68 | */ |
| 70 | union { | 69 | union { |
| 71 | /** @userptr: link into VM repin list if userptr. */ | ||
| 72 | struct list_head userptr; | ||
| 73 | /** @rebind: link into VM if this VMA needs rebinding. */ | 70 | /** @rebind: link into VM if this VMA needs rebinding. */ |
| 74 | struct list_head rebind; | 71 | struct list_head rebind; |
| 75 | /** @destroy: link to contested list when VM is being closed. */ | 72 | /** @destroy: link to contested list when VM is being closed. */ |
| @@ -105,11 +102,15 @@ struct xe_vma { · 29 unmodified lines | |||
| 105 | * @pat_index: The pat index to use when encoding the PTEs for this vma. | 102 | * @pat_index: The pat index to use when encoding the PTEs for this vma. |
| 106 | */ | 103 | */ |
| 107 | u16 pat_index; | 104 | u16 pat_index; |
| 105 | }; | ||
| 108 | 106 | ||
| 109 | /** | 107 | /** |
| 110 | * @userptr: user pointer state, only allocated for VMAs that are | 108 | * struct xe_userptr_vma - A userptr vma subclass |
| 111 | * user pointers | 109 | * @vma: The vma. |
| 112 | */ | 110 | * @userptr: Additional userptr information. |
| 111 | */ | ||
| 112 | struct xe_userptr_vma { | ||
| 113 | struct xe_vma vma; | ||
| 113 | struct xe_userptr userptr; | 114 | struct xe_userptr userptr; |
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| @@ -356,11 +357,6 @@ struct xe_vma_op { · 240 unmodified lines | |||
| 356 | /** @flags: operation flags */ | 357 | /** @flags: operation flags */ |
| 357 | enum xe_vma_op_flags flags; | 358 | enum xe_vma_op_flags flags; |
| 358 | 359 | ||
| 359 | #ifdef TEST_VM_ASYNC_OPS_ERROR | ||
| 360 | /** @inject_error: inject error to test async op error handling */ | ||
| 361 | bool inject_error; | ||
| 362 | #endif | ||
| 363 | |||
| 364 | union { | 360 | union { |
| 365 | /** @map: VMA map operation specific data */ | 361 | /** @map: VMA map operation specific data */ |
| 366 | struct xe_vma_op_map map; | 362 | struct xe_vma_op_map map; |
| @@ -143,6 +143,9 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s · 142 unmodified lines | |||
| 143 | } | 143 | } |
| 144 | EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup); | 144 | EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup); |
| 145 | 145 | ||
| 146 | /* Disables missing prototype warnings */ | ||
| 147 | __bpf_kfunc_start_defs(); | ||
| 148 | |||
| 146 | /** | 149 | /** |
| 147 | * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx | 150 | * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx |
| 148 | * | 151 | * |
| @@ -152,7 +155,7 @@ EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup); · 3 unmodified lines | |||
| 152 | * | 155 | * |
| 153 | * @returns %NULL on error, an %__u8 memory pointer on success | 156 | * @returns %NULL on error, an %__u8 memory pointer on success |
| 154 | */ | 157 | */ |
| 155 | noinline __u8 * | 158 | __bpf_kfunc __u8 * |
| 156 | hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size) | 159 | hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size) |
| 157 | { | 160 | { |
| 158 | struct hid_bpf_ctx_kern *ctx_kern; | 161 | struct hid_bpf_ctx_kern *ctx_kern; |
| @@ -167,6 +170,7 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr · 8 unmodified lines | |||
| 167 | 170 | ||
| 168 | return ctx_kern->data + offset; | 171 | return ctx_kern->data + offset; |
| 169 | } | 172 | } |
| 173 | __bpf_kfunc_end_defs(); | ||
| 170 | 174 | ||
| 171 | /* | 175 | /* |
| 172 | * The following set contains all functions we agree BPF programs | 176 | * The following set contains all functions we agree BPF programs |
| @@ -241,6 +245,42 @@ int hid_bpf_reconnect(struct hid_device *hdev) · 68 unmodified lines | |||
| 241 | return 0; | 245 | return 0; |
| 242 | } | 246 | } |
| 243 | 247 | ||
| 248 | static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct bpf_prog *prog, | ||
| 249 | __u32 flags) | ||
| 250 | { | ||
| 251 | int fd, err, prog_type; | ||
| 252 | |||
| 253 | prog_type = hid_bpf_get_prog_attach_type(prog); | ||
| 254 | if (prog_type < 0) | ||
| 255 | return prog_type; | ||
| 256 | |||
| 257 | if (prog_type >= HID_BPF_PROG_TYPE_MAX) | ||
| 258 | return -EINVAL; | ||
| 259 | |||
| 260 | if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) { | ||
| 261 | err = hid_bpf_allocate_event_data(hdev); | ||
| 262 | if (err) | ||
| 263 | return err; | ||
| 264 | } | ||
| 265 | |||
| 266 | fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags); | ||
| 267 | if (fd < 0) | ||
| 268 | return fd; | ||
| 269 | |||
| 270 | if (prog_type == HID_BPF_PROG_TYPE_RDESC_FIXUP) { | ||
| 271 | err = hid_bpf_reconnect(hdev); | ||
| 272 | if (err) { | ||
| 273 | close_fd(fd); | ||
| 274 | return err; | ||
| 275 | } | ||
| 276 | } | ||
| 277 | |||
| 278 | return fd; | ||
| 279 | } | ||
| 280 | |||
| 281 | /* Disables missing prototype warnings */ | ||
| 282 | __bpf_kfunc_start_defs(); | ||
| 283 | |||
| 244 | /** | 284 | /** |
| 245 | * hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device | 285 | * hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device |
| 246 | * | 286 | * |
| @@ -253,22 +293,17 @@ int hid_bpf_reconnect(struct hid_device *hdev) · 6 unmodified lines | |||
| 253 | * is pinned to the BPF file system). | 293 | * is pinned to the BPF file system). |
| 254 | */ | 294 | */ |
| 255 | /* called from syscall */ | 295 | /* called from syscall */ |
| 256 | noinline int | 296 | __bpf_kfunc int |
| 257 | hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags) | 297 | hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags) |
| 258 | { | 298 | { |
| 259 | struct hid_device *hdev; | 299 | struct hid_device *hdev; |
| 300 | struct bpf_prog *prog; | ||
| 260 | struct device *dev; | 301 | struct device *dev; |
| 261 | int fd, err, prog_type = hid_bpf_get_prog_attach_type(prog_fd); | 302 | int err, fd; |
| 262 | 303 | ||
| 263 | if (!hid_bpf_ops) | 304 | if (!hid_bpf_ops) |
| 264 | return -EINVAL; | 305 | return -EINVAL; |
| 265 | 306 | ||
| 266 | if (prog_type < 0) | ||
| 267 | return prog_type; | ||
| 268 | |||
| 269 | if (prog_type >= HID_BPF_PROG_TYPE_MAX) | ||
| 270 | return -EINVAL; | ||
| 271 | |||
| 272 | if ((flags & ~HID_BPF_FLAG_MASK)) | 307 | if ((flags & ~HID_BPF_FLAG_MASK)) |
| 273 | return -EINVAL; | 308 | return -EINVAL; |
| 274 | 309 | ||
| @@ -278,25 +313,29 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags) · 3 unmodified lines | |||
| 278 | 313 | ||
| 279 | hdev = to_hid_device(dev); | 314 | hdev = to_hid_device(dev); |
| 280 | 315 | ||
| 281 | if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) { | 316 | /* |
| 282 | err = hid_bpf_allocate_event_data(hdev); | 317 | * take a ref on the prog itself, it will be released |
| 283 | if (err) | 318 | * on errors or when it'll be detached |
| 284 | return err; | 319 | */ |
| 320 | prog = bpf_prog_get(prog_fd); | ||
| 321 | if (IS_ERR(prog)) { | ||
| 322 | err = PTR_ERR(prog); | ||
| 323 | goto out_dev_put; | ||
| 285 | } | 324 | } |
| 286 | 325 | ||
| 287 | fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, flags); | 326 | fd = do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags); |
| 288 | if (fd < 0) | 327 | if (fd < 0) { |
| 289 | return fd; | 328 | err = fd; |
| 290 | 329 | goto out_prog_put; | |
| 291 | if (prog_type == HID_BPF_PROG_TYPE_RDESC_FIXUP) { | ||
| 292 | err = hid_bpf_reconnect(hdev); | ||
| 293 | if (err) { | ||
| 294 | close_fd(fd); | ||
| 295 | return err; | ||
| 296 | } | ||
| 297 | } | 330 | } |
| 298 | 331 | ||
| 299 | return fd; | 332 | return fd; |
| 333 | |||
| 334 | out_prog_put: | ||
| 335 | bpf_prog_put(prog); | ||
| 336 | out_dev_put: | ||
| 337 | put_device(dev); | ||
| 338 | return err; | ||
| 300 | } | 339 | } |
| 301 | 340 | ||
| 302 | /** | 341 | /** |
| @@ -306,7 +345,7 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags) · 3 unmodified lines | |||
| 306 | * | 345 | * |
| 307 | * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error. | 346 | * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error. |
| 308 | */ | 347 | */ |
| 309 | noinline struct hid_bpf_ctx * | 348 | __bpf_kfunc struct hid_bpf_ctx * |
| 310 | hid_bpf_allocate_context(unsigned int hid_id) | 349 | hid_bpf_allocate_context(unsigned int hid_id) |
| 311 | { | 350 | { |
| 312 | struct hid_device *hdev; | 351 | struct hid_device *hdev; |
| @@ -323,8 +362,10 @@ hid_bpf_allocate_context(unsigned int hid_id) · 10 unmodified lines | |||
| 323 | hdev = to_hid_device(dev); | 362 | hdev = to_hid_device(dev); |
| 324 | 363 | ||
| 325 | ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL); | 364 | ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL); |
| 326 | if (!ctx_kern) | 365 | if (!ctx_kern) { |
| 366 | put_device(dev); | ||
| 327 | return NULL; | 367 | return NULL; |
| 368 | } | ||
| 328 | 369 | ||
| 329 | ctx_kern->ctx.hid = hdev; | 370 | ctx_kern->ctx.hid = hdev; |
| 330 | 371 | ||
| @@ -337,14 +378,19 @@ hid_bpf_allocate_context(unsigned int hid_id) · 6 unmodified lines | |||
| 337 | * @ctx: the HID-BPF context to release | 378 | * @ctx: the HID-BPF context to release |
| 338 | * | 379 | * |
| 339 | */ | 380 | */ |
| 340 | noinline void | 381 | __bpf_kfunc void |
| 341 | hid_bpf_release_context(struct hid_bpf_ctx *ctx) | 382 | hid_bpf_release_context(struct hid_bpf_ctx *ctx) |
| 342 | { | 383 | { |
| 343 | struct hid_bpf_ctx_kern *ctx_kern; | 384 | struct hid_bpf_ctx_kern *ctx_kern; |
| 385 | struct hid_device *hid; | ||
| 344 | 386 | ||
| 345 | ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); | 387 | ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); |
| 388 | hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */ | ||
| 346 | 389 | ||
| 347 | kfree(ctx_kern); | 390 | kfree(ctx_kern); |
| 391 | |||
| 392 | /* get_device() is called by bus_find_device() */ | ||
| 393 | put_device(&hid->dev); | ||
| 348 | } | 394 | } |
| 349 | 395 | ||
| 350 | /** | 396 | /** |
| @@ -358,7 +404,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx) · 7 unmodified lines | |||
| 358 | * | 404 | * |
| 359 | * @returns %0 on success, a negative error code otherwise. | 405 | * @returns %0 on success, a negative error code otherwise. |
| 360 | */ | 406 | */ |
| 361 | noinline int | 407 | __bpf_kfunc int |
| 362 | hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, | 408 | hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, |
| 363 | enum hid_report_type rtype, enum hid_class_request reqtype) | 409 | enum hid_report_type rtype, enum hid_class_request reqtype) |
| 364 | { | 410 | { |
| @@ -426,6 +472,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, · 61 unmodified lines | |||
| 426 | kfree(dma_data); | 472 | kfree(dma_data); |
| 427 | return ret; | 473 | return ret; |
| 428 | } | 474 | } |
| 475 | __bpf_kfunc_end_defs(); | ||
| 429 | 476 | ||
| 430 | /* our HID-BPF entrypoints */ | 477 | /* our HID-BPF entrypoints */ |
| 431 | BTF_SET8_START(hid_bpf_fmodret_ids) | 478 | BTF_SET8_START(hid_bpf_fmodret_ids) |
| @@ -12,9 +12,9 @@ struct hid_bpf_ctx_kern { · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | int hid_bpf_preload_skel(void); | 13 | int hid_bpf_preload_skel(void); |
| 14 | void hid_bpf_free_links_and_skel(void); | 14 | void hid_bpf_free_links_and_skel(void); |
| 15 | int hid_bpf_get_prog_attach_type(int prog_fd); | 15 | int hid_bpf_get_prog_attach_type(struct bpf_prog *prog); |
| 16 | int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, int prog_fd, | 16 | int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, int prog_fd, |
| 17 | __u32 flags); | 17 | struct bpf_prog *prog, __u32 flags); |
| 18 | void __hid_bpf_destroy_device(struct hid_device *hdev); | 18 | void __hid_bpf_destroy_device(struct hid_device *hdev); |
| 19 | int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, | 19 | int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, |
| 20 | struct hid_bpf_ctx_kern *ctx_kern); | 20 | struct hid_bpf_ctx_kern *ctx_kern); |
| @@ -196,6 +196,7 @@ static void __hid_bpf_do_release_prog(int map_fd, unsigned int idx) · 195 unmodified lines | |||
| 196 | static void hid_bpf_release_progs(struct work_struct *work) | 196 | static void hid_bpf_release_progs(struct work_struct *work) |
| 197 | { | 197 | { |
| 198 | int i, j, n, map_fd = -1; | 198 | int i, j, n, map_fd = -1; |
| 199 | bool hdev_destroyed; | ||
| 199 | 200 | ||
| 200 | if (!jmp_table.map) | 201 | if (!jmp_table.map) |
| 201 | return; | 202 | return; |
| @@ -220,6 +221,12 @@ static void hid_bpf_release_progs(struct work_struct *work) · 18 unmodified lines | |||
| 220 | if (entry->hdev) { | 221 | if (entry->hdev) { |
| 221 | hdev = entry->hdev; | 222 | hdev = entry->hdev; |
| 222 | type = entry->type; | 223 | type = entry->type; |
| 224 | /* | ||
| 225 | * hdev is still valid, even if we are called after hid_destroy_device(): | ||
| 226 | * when hid_bpf_attach() gets called, it takes a ref on the dev through | ||
| 227 | * bus_find_device() | ||
| 228 | */ | ||
| 229 | hdev_destroyed = hdev->bpf.destroyed; | ||
| 223 | 230 | ||
| 224 | hid_bpf_populate_hdev(hdev, type); | 231 | hid_bpf_populate_hdev(hdev, type); |
| 225 | 232 | ||
| @@ -232,12 +239,19 @@ static void hid_bpf_release_progs(struct work_struct *work) · 6 unmodified lines | |||
| 232 | if (test_bit(next->idx, jmp_table.enabled)) | 239 | if (test_bit(next->idx, jmp_table.enabled)) |
| 233 | continue; | 240 | continue; |
| 234 | 241 | ||
| 235 | if (next->hdev == hdev && next->type == type) | 242 | if (next->hdev == hdev && next->type == type) { |
| 243 | /* | ||
| 244 | * clear the hdev reference and decrement the device ref | ||
| 245 | * that was taken during bus_find_device() while calling | ||
| 246 | * hid_bpf_attach() | ||
| 247 | */ | ||
| 236 | next->hdev = NULL; | 248 | next->hdev = NULL; |
| 249 | put_device(&hdev->dev); | ||
| 250 | } | ||
| 237 | } | 251 | } |
| 238 | 252 | ||
| 239 | /* if type was rdesc fixup, reconnect device */ | 253 | /* if type was rdesc fixup and the device is not gone, reconnect device */ |
| 240 | if (type == HID_BPF_PROG_TYPE_RDESC_FIXUP) | 254 | if (type == HID_BPF_PROG_TYPE_RDESC_FIXUP && !hdev_destroyed) |
| 241 | hid_bpf_reconnect(hdev); | 255 | hid_bpf_reconnect(hdev); |
| 242 | } | 256 | } |
| 243 | } | 257 | } |
| @@ -333,15 +347,10 @@ static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog) · 89 unmodified lines | |||
| 333 | return err; | 347 | return err; |
| 334 | } | 348 | } |
| 335 | 349 | ||
| 336 | int hid_bpf_get_prog_attach_type(int prog_fd) | 350 | int hid_bpf_get_prog_attach_type(struct bpf_prog *prog) |
| 337 | { | 351 | { |
| 338 | struct bpf_prog *prog = NULL; | ||
| 339 | int i; | ||
| 340 | int prog_type = HID_BPF_PROG_TYPE_UNDEF; | 352 | int prog_type = HID_BPF_PROG_TYPE_UNDEF; |
| 341 | 353 | int i; | |
| 342 | prog = bpf_prog_get(prog_fd); | ||
| 343 | if (IS_ERR(prog)) | ||
| 344 | return PTR_ERR(prog); | ||
| 345 | 354 | ||
| 346 | for (i = 0; i < HID_BPF_PROG_TYPE_MAX; i++) { | 355 | for (i = 0; i < HID_BPF_PROG_TYPE_MAX; i++) { |
| 347 | if (hid_bpf_btf_ids[i] == prog->aux->attach_btf_id) { | 356 | if (hid_bpf_btf_ids[i] == prog->aux->attach_btf_id) { |
| @@ -350,8 +359,6 @@ int hid_bpf_get_prog_attach_type(int prog_fd) · 2 unmodified lines | |||
| 350 | } | 359 | } |
| 351 | } | 360 | } |
| 352 | 361 | ||
| 353 | bpf_prog_put(prog); | ||
| 354 | |||
| 355 | return prog_type; | 362 | return prog_type; |
| 356 | } | 363 | } |
| 357 | 364 | ||
| @@ -388,19 +395,13 @@ static const struct bpf_link_ops hid_bpf_link_lops = { · 30 unmodified lines | |||
| 388 | /* called from syscall */ | 395 | /* called from syscall */ |
| 389 | noinline int | 396 | noinline int |
| 390 | __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, | 397 | __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, |
| 391 | int prog_fd, __u32 flags) | 398 | int prog_fd, struct bpf_prog *prog, __u32 flags) |
| 392 | { | 399 | { |
| 393 | struct bpf_link_primer link_primer; | 400 | struct bpf_link_primer link_primer; |
| 394 | struct hid_bpf_link *link; | 401 | struct hid_bpf_link *link; |
| 395 | struct bpf_prog *prog = NULL; | ||
| 396 | struct hid_bpf_prog_entry *prog_entry; | 402 | struct hid_bpf_prog_entry *prog_entry; |
| 397 | int cnt, err = -EINVAL, prog_table_idx = -1; | 403 | int cnt, err = -EINVAL, prog_table_idx = -1; |
| 398 | 404 | ||
| 399 | /* take a ref on the prog itself */ | ||
| 400 | prog = bpf_prog_get(prog_fd); | ||
| 401 | if (IS_ERR(prog)) | ||
| 402 | return PTR_ERR(prog); | ||
| 403 | |||
| 404 | mutex_lock(&hid_bpf_attach_lock); | 405 | mutex_lock(&hid_bpf_attach_lock); |
| 405 | 406 | ||
| 406 | link = kzalloc(sizeof(*link), GFP_USER); | 407 | link = kzalloc(sizeof(*link), GFP_USER); |
| @@ -467,7 +468,6 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, · 60 unmodified lines | |||
| 467 | err_unlock: | 468 | err_unlock: |
| 468 | mutex_unlock(&hid_bpf_attach_lock); | 469 | mutex_unlock(&hid_bpf_attach_lock); |
| 469 | 470 | ||
| 470 | bpf_prog_put(prog); | ||
| 471 | kfree(link); | 471 | kfree(link); |
| 472 | 472 | ||
| 473 | return err; | 473 | return err; |
| @@ -298,6 +298,9 @@ · 297 unmodified lines | |||
| 298 | 298 | ||
| 299 | #define USB_VENDOR_ID_CIDC 0x1677 | 299 | #define USB_VENDOR_ID_CIDC 0x1677 |
| 300 | 300 | ||
| 301 | #define I2C_VENDOR_ID_CIRQUE 0x0488 | ||
| 302 | #define I2C_PRODUCT_ID_CIRQUE_1063 0x1063 | ||
| 303 | |||
| 301 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 | 304 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 |
| 302 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 | 305 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 |
| 303 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 | 306 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 |
| @@ -4610,6 +4610,8 @@ static const struct hid_device_id hidpp_devices[] = { · 4609 unmodified lines | |||
| 4610 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) }, | 4610 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) }, |
| 4611 | { /* Logitech G Pro X Superlight Gaming Mouse over USB */ | 4611 | { /* Logitech G Pro X Superlight Gaming Mouse over USB */ |
| 4612 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) }, | 4612 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) }, |
| 4613 | { /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */ | ||
| 4614 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) }, | ||
| 4613 | 4615 | ||
| 4614 | { /* G935 Gaming Headset */ | 4616 | { /* G935 Gaming Headset */ |
| 4615 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87), | 4617 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87), |
| @@ -800,6 +800,8 @@ static inline int thunderstrike_led_create(struct thunderstrike *ts) · 799 unmodified lines | |||
| 800 | 800 | ||
| 801 | led->name = devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, | 801 | led->name = devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, |
| 802 | "thunderstrike%d:blue:led", ts->id); | 802 | "thunderstrike%d:blue:led", ts->id); |
| 803 | if (!led->name) | ||
| 804 | return -ENOMEM; | ||
| 803 | led->max_brightness = 1; | 805 | led->max_brightness = 1; |
| 804 | led->flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN; | 806 | led->flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN; |
| 805 | led->brightness_get = &thunderstrike_led_get_brightness; | 807 | led->brightness_get = &thunderstrike_led_get_brightness; |
| @@ -831,6 +833,8 @@ static inline int thunderstrike_psy_create(struct shield_device *shield_dev) · 25 unmodified lines | |||
| 831 | shield_dev->battery_dev.desc.name = | 833 | shield_dev->battery_dev.desc.name = |
| 832 | devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, | 834 | devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, |
| 833 | "thunderstrike_%d", ts->id); | 835 | "thunderstrike_%d", ts->id); |
| 836 | if (!shield_dev->battery_dev.desc.name) | ||
| 837 | return -ENOMEM; | ||
| 834 | 838 | ||
| 835 | shield_dev->battery_dev.psy = power_supply_register( | 839 | shield_dev->battery_dev.psy = power_supply_register( |
| 836 | &hdev->dev, &shield_dev->battery_dev.desc, &psy_cfg); | 840 | &hdev->dev, &shield_dev->battery_dev.desc, &psy_cfg); |
| @@ -1109,10 +1109,9 @@ static int steam_probe(struct hid_device *hdev, · 1108 unmodified lines | |||
| 1109 | return hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 1109 | return hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
| 1110 | 1110 | ||
| 1111 | steam = devm_kzalloc(&hdev->dev, sizeof(*steam), GFP_KERNEL); | 1111 | steam = devm_kzalloc(&hdev->dev, sizeof(*steam), GFP_KERNEL); |
| 1112 | if (!steam) { | 1112 | if (!steam) |
| 1113 | ret = -ENOMEM; | 1113 | return -ENOMEM; |
| 1114 | goto steam_alloc_fail; | 1114 | |
| 1115 | } | ||
| 1116 | steam->hdev = hdev; | 1115 | steam->hdev = hdev; |
| 1117 | hid_set_drvdata(hdev, steam); | 1116 | hid_set_drvdata(hdev, steam); |
| 1118 | spin_lock_init(&steam->lock); | 1117 | spin_lock_init(&steam->lock); |
| @@ -1129,14 +1128,14 @@ static int steam_probe(struct hid_device *hdev, · 10 unmodified lines | |||
| 1129 | */ | 1128 | */ |
| 1130 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW); | 1129 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW); |
| 1131 | if (ret) | 1130 | if (ret) |
| 1132 | goto hid_hw_start_fail; | 1131 | goto err_cancel_work; |
| 1133 | 1132 | ||
| 1134 | ret = hid_hw_open(hdev); | 1133 | ret = hid_hw_open(hdev); |
| 1135 | if (ret) { | 1134 | if (ret) { |
| 1136 | hid_err(hdev, | 1135 | hid_err(hdev, |
| 1137 | "%s:hid_hw_open\n", | 1136 | "%s:hid_hw_open\n", |
| 1138 | __func__); | 1137 | __func__); |
| 1139 | goto hid_hw_open_fail; | 1138 | goto err_hw_stop; |
| 1140 | } | 1139 | } |
| 1141 | 1140 | ||
| 1142 | if (steam->quirks & STEAM_QUIRK_WIRELESS) { | 1141 | if (steam->quirks & STEAM_QUIRK_WIRELESS) { |
| @@ -1152,36 +1151,37 @@ static int steam_probe(struct hid_device *hdev, · 9 unmodified lines | |||
| 1152 | hid_err(hdev, | 1151 | hid_err(hdev, |
| 1153 | "%s:steam_register failed with error %d\n", | 1152 | "%s:steam_register failed with error %d\n", |
| 1154 | __func__, ret); | 1153 | __func__, ret); |
| 1155 | goto input_register_fail; | 1154 | goto err_hw_close; |
| 1156 | } | 1155 | } |
| 1157 | } | 1156 | } |
| 1158 | 1157 | ||
| 1159 | steam->client_hdev = steam_create_client_hid(hdev); | 1158 | steam->client_hdev = steam_create_client_hid(hdev); |
| 1160 | if (IS_ERR(steam->client_hdev)) { | 1159 | if (IS_ERR(steam->client_hdev)) { |
| 1161 | ret = PTR_ERR(steam->client_hdev); | 1160 | ret = PTR_ERR(steam->client_hdev); |
| 1162 | goto client_hdev_fail; | 1161 | goto err_stream_unregister; |
| 1163 | } | 1162 | } |
| 1164 | steam->client_hdev->driver_data = steam; | 1163 | steam->client_hdev->driver_data = steam; |
| 1165 | 1164 | ||
| 1166 | ret = hid_add_device(steam->client_hdev); | 1165 | ret = hid_add_device(steam->client_hdev); |
| 1167 | if (ret) | 1166 | if (ret) |
| 1168 | goto client_hdev_add_fail; | 1167 | goto err_destroy; |
| 1169 | 1168 | ||
| 1170 | return 0; | 1169 | return 0; |
| 1171 | 1170 | ||
| 1172 | client_hdev_add_fail: | 1171 | err_destroy: |
| 1173 | hid_hw_stop(hdev); | ||
| 1174 | client_hdev_fail: | ||
| 1175 | hid_destroy_device(steam->client_hdev); | 1172 | hid_destroy_device(steam->client_hdev); |
| 1176 | input_register_fail: | 1173 | err_stream_unregister: |
| 1177 | hid_hw_open_fail: | 1174 | if (steam->connected) |
| 1178 | hid_hw_start_fail: | 1175 | steam_unregister(steam); |
| 1176 | err_hw_close: | ||
| 1177 | hid_hw_close(hdev); | ||
| 1178 | err_hw_stop: | ||
| 1179 | hid_hw_stop(hdev); | ||
| 1180 | err_cancel_work: | ||
| 1179 | cancel_work_sync(&steam->work_connect); | 1181 | cancel_work_sync(&steam->work_connect); |
| 1180 | cancel_delayed_work_sync(&steam->mode_switch); | 1182 | cancel_delayed_work_sync(&steam->mode_switch); |
| 1181 | cancel_work_sync(&steam->rumble_work); | 1183 | cancel_work_sync(&steam->rumble_work); |
| 1182 | steam_alloc_fail: | 1184 | |
| 1183 | hid_err(hdev, "%s: failed with error %d\n", | ||
| 1184 | __func__, ret); | ||
| 1185 | return ret; | 1185 | return ret; |
| 1186 | } | 1186 | } |
| 1187 | 1187 | ||
| @@ -357,8 +357,11 @@ static int hidraw_release(struct inode * inode, struct file * file) · 356 unmodified lines | |||
| 357 | down_write(&minors_rwsem); | 357 | down_write(&minors_rwsem); |
| 358 | 358 | ||
| 359 | spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags); | 359 | spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags); |
| 360 | for (int i = list->tail; i < list->head; i++) | 360 | while (list->tail != list->head) { |
| 361 | kfree(list->buffer[i].value); | 361 | kfree(list->buffer[list->tail].value); |
| 362 | list->buffer[list->tail].value = NULL; | ||
| 363 | list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); | ||
| 364 | } | ||
| 362 | list_del(&list->node); | 365 | list_del(&list->node); |
| 363 | spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); | 366 | spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); |
| 364 | kfree(list); | 367 | kfree(list); |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(2) | 49 | #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(2) |
| 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) | 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) |
| 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) | 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) |
| 52 | #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5) | ||
| 52 | 53 | ||
| 53 | /* Command opcodes */ | 54 | /* Command opcodes */ |
| 54 | #define I2C_HID_OPCODE_RESET 0x01 | 55 | #define I2C_HID_OPCODE_RESET 0x01 |
| @@ -131,6 +132,8 @@ static const struct i2c_hid_quirks { · 76 unmodified lines | |||
| 131 | I2C_HID_QUIRK_RESET_ON_RESUME }, | 132 | I2C_HID_QUIRK_RESET_ON_RESUME }, |
| 132 | { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, | 133 | { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, |
| 133 | I2C_HID_QUIRK_BAD_INPUT_SIZE }, | 134 | I2C_HID_QUIRK_BAD_INPUT_SIZE }, |
| 135 | { I2C_VENDOR_ID_CIRQUE, I2C_PRODUCT_ID_CIRQUE_1063, | ||
| 136 | I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND }, | ||
| 134 | /* | 137 | /* |
| 135 | * Sending the wakeup after reset actually break ELAN touchscreen controller | 138 | * Sending the wakeup after reset actually break ELAN touchscreen controller |
| 136 | */ | 139 | */ |
| @@ -956,7 +959,8 @@ static int i2c_hid_core_suspend(struct i2c_hid *ihid, bool force_poweroff) · 819 unmodified lines | |||
| 956 | return ret; | 959 | return ret; |
| 957 | 960 | ||
| 958 | /* Save some power */ | 961 | /* Save some power */ |
| 959 | i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); | 962 | if (!(ihid->quirks & I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND)) |
| 963 | i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); | ||
| 960 | 964 | ||
| 961 | disable_irq(client->irq); | 965 | disable_irq(client->irq); |
| 962 | 966 | ||
| @@ -87,6 +87,7 @@ static int i2c_hid_of_probe(struct i2c_client *client) · 86 unmodified lines | |||
| 87 | if (!ihid_of) | 87 | if (!ihid_of) |
| 88 | return -ENOMEM; | 88 | return -ENOMEM; |
| 89 | 89 | ||
| 90 | ihid_of->client = client; | ||
| 90 | ihid_of->ops.power_up = i2c_hid_of_power_up; | 91 | ihid_of->ops.power_up = i2c_hid_of_power_up; |
| 91 | ihid_of->ops.power_down = i2c_hid_of_power_down; | 92 | ihid_of->ops.power_down = i2c_hid_of_power_down; |
| 92 | 93 | ||
| @@ -195,6 +195,8 @@ struct aspeed_pwm_tacho_data { · 194 unmodified lines | |||
| 195 | u8 fan_tach_ch_source[MAX_ASPEED_FAN_TACH_CHANNELS]; | 195 | u8 fan_tach_ch_source[MAX_ASPEED_FAN_TACH_CHANNELS]; |
| 196 | struct aspeed_cooling_device *cdev[8]; | 196 | struct aspeed_cooling_device *cdev[8]; |
| 197 | const struct attribute_group *groups[3]; | 197 | const struct attribute_group *groups[3]; |
| 198 | /* protects access to shared ASPEED_PTCR_RESULT */ | ||
| 199 | struct mutex tach_lock; | ||
| 198 | }; | 200 | }; |
| 199 | 201 | ||
| 200 | enum type { TYPEM, TYPEN, TYPEO }; | 202 | enum type { TYPEM, TYPEN, TYPEO }; |
| @@ -529,6 +531,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, · 328 unmodified lines | |||
| 529 | u8 fan_tach_ch_source, type, mode, both; | 531 | u8 fan_tach_ch_source, type, mode, both; |
| 530 | int ret; | 532 | int ret; |
| 531 | 533 | ||
| 534 | mutex_lock(&priv->tach_lock); | ||
| 535 | |||
| 532 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); | 536 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); |
| 533 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); | 537 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); |
| 534 | 538 | ||
| @@ -546,6 +550,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, · 11 unmodified lines | |||
| 546 | ASPEED_RPM_STATUS_SLEEP_USEC, | 550 | ASPEED_RPM_STATUS_SLEEP_USEC, |
| 547 | usec); | 551 | usec); |
| 548 | 552 | ||
| 553 | mutex_unlock(&priv->tach_lock); | ||
| 554 | |||
| 549 | /* return -ETIMEDOUT if we didn't get an answer. */ | 555 | /* return -ETIMEDOUT if we didn't get an answer. */ |
| 550 | if (ret) | 556 | if (ret) |
| 551 | return ret; | 557 | return ret; |
| @@ -915,6 +921,7 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev) · 363 unmodified lines | |||
| 915 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 921 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
| 916 | if (!priv) | 922 | if (!priv) |
| 917 | return -ENOMEM; | 923 | return -ENOMEM; |
| 924 | mutex_init(&priv->tach_lock); | ||
| 918 | priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs, | 925 | priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs, |
| 919 | &aspeed_pwm_tacho_regmap_config); | 926 | &aspeed_pwm_tacho_regmap_config); |
| 920 | if (IS_ERR(priv->regmap)) | 927 | if (IS_ERR(priv->regmap)) |
| @@ -41,7 +41,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ | 42 | #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ |
| 43 | #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ | 43 | #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ |
| 44 | #define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ | 44 | #define NUM_REAL_CORES 512 /* Number of Real cores per cpu */ |
| 45 | #define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ | 45 | #define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ |
| 46 | #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ | 46 | #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ |
| 47 | #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) | 47 | #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) |
| @@ -419,7 +419,7 @@ static ssize_t show_temp(struct device *dev, · 371 unmodified lines | |||
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | static int create_core_attrs(struct temp_data *tdata, struct device *dev, | 421 | static int create_core_attrs(struct temp_data *tdata, struct device *dev, |
| 422 | int attr_no) | 422 | int index) |
| 423 | { | 423 | { |
| 424 | int i; | 424 | int i; |
| 425 | static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, | 425 | static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, |
| @@ -431,13 +431,20 @@ static int create_core_attrs(struct temp_data *tdata, struct device *dev, · 5 unmodified lines | |||
| 431 | }; | 431 | }; |
| 432 | 432 | ||
| 433 | for (i = 0; i < tdata->attr_size; i++) { | 433 | for (i = 0; i < tdata->attr_size; i++) { |
| 434 | /* | ||
| 435 | * We map the attr number to core id of the CPU | ||
| 436 | * The attr number is always core id + 2 | ||
| 437 | * The Pkgtemp will always show up as temp1_*, if available | ||
| 438 | */ | ||
| 439 | int attr_no = tdata->is_pkg_data ? 1 : tdata->cpu_core_id + 2; | ||
| 440 | |||
| 434 | snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, | 441 | snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, |
| 435 | "temp%d_%s", attr_no, suffixes[i]); | 442 | "temp%d_%s", attr_no, suffixes[i]); |
| 436 | sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); | 443 | sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); |
| 437 | tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; | 444 | tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; |
| 438 | tdata->sd_attrs[i].dev_attr.attr.mode = 0444; | 445 | tdata->sd_attrs[i].dev_attr.attr.mode = 0444; |
| 439 | tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; | 446 | tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; |
| 440 | tdata->sd_attrs[i].index = attr_no; | 447 | tdata->sd_attrs[i].index = index; |
| 441 | tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr; | 448 | tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr; |
| 442 | } | 449 | } |
| 443 | tdata->attr_group.attrs = tdata->attrs; | 450 | tdata->attr_group.attrs = tdata->attrs; |
| @@ -495,30 +502,25 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, · 51 unmodified lines | |||
| 495 | struct platform_data *pdata = platform_get_drvdata(pdev); | 502 | struct platform_data *pdata = platform_get_drvdata(pdev); |
| 496 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 503 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 497 | u32 eax, edx; | 504 | u32 eax, edx; |
| 498 | int err, index, attr_no; | 505 | int err, index; |
| 499 | 506 | ||
| 500 | if (!housekeeping_cpu(cpu, HK_TYPE_MISC)) | 507 | if (!housekeeping_cpu(cpu, HK_TYPE_MISC)) |
| 501 | return 0; | 508 | return 0; |
| 502 | 509 | ||
| 503 | /* | 510 | /* |
| 504 | * Find attr number for sysfs: | 511 | * Get the index of tdata in pdata->core_data[] |
| 505 | * We map the attr number to core id of the CPU | 512 | * tdata for package: pdata->core_data[1] |
| 506 | * The attr number is always core id + 2 | 513 | * tdata for core: pdata->core_data[2] .. pdata->core_data[NUM_REAL_CORES + 1] |
| 507 | * The Pkgtemp will always show up as temp1_*, if available | ||
| 508 | */ | 514 | */ |
| 509 | if (pkg_flag) { | 515 | if (pkg_flag) { |
| 510 | attr_no = PKG_SYSFS_ATTR_NO; | 516 | index = PKG_SYSFS_ATTR_NO; |
| 511 | } else { | 517 | } else { |
| 512 | index = ida_alloc(&pdata->ida, GFP_KERNEL); | 518 | index = ida_alloc_max(&pdata->ida, NUM_REAL_CORES - 1, GFP_KERNEL); |
| 513 | if (index < 0) | 519 | if (index < 0) |
| 514 | return index; | 520 | return index; |
| 515 | pdata->cpu_map[index] = topology_core_id(cpu); | ||
| 516 | attr_no = index + BASE_SYSFS_ATTR_NO; | ||
| 517 | } | ||
| 518 | 521 | ||
| 519 | if (attr_no > MAX_CORE_DATA - 1) { | 522 | pdata->cpu_map[index] = topology_core_id(cpu); |
| 520 | err = -ERANGE; | 523 | index += BASE_SYSFS_ATTR_NO; |
| 521 | goto ida_free; | ||
| 522 | } | 524 | } |
| 523 | 525 | ||
| 524 | tdata = init_temp_data(cpu, pkg_flag); | 526 | tdata = init_temp_data(cpu, pkg_flag); |
| @@ -544,20 +546,20 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, · 19 unmodified lines | |||
| 544 | if (get_ttarget(tdata, &pdev->dev) >= 0) | 546 | if (get_ttarget(tdata, &pdev->dev) >= 0) |
| 545 | tdata->attr_size++; | 547 | tdata->attr_size++; |
| 546 | 548 | ||
| 547 | pdata->core_data[attr_no] = tdata; | 549 | pdata->core_data[index] = tdata; |
| 548 | 550 | ||
| 549 | /* Create sysfs interfaces */ | 551 | /* Create sysfs interfaces */ |
| 550 | err = create_core_attrs(tdata, pdata->hwmon_dev, attr_no); | 552 | err = create_core_attrs(tdata, pdata->hwmon_dev, index); |
| 551 | if (err) | 553 | if (err) |
| 552 | goto exit_free; | 554 | goto exit_free; |
| 553 | 555 | ||
| 554 | return 0; | 556 | return 0; |
| 555 | exit_free: | 557 | exit_free: |
| 556 | pdata->core_data[attr_no] = NULL; | 558 | pdata->core_data[index] = NULL; |
| 557 | kfree(tdata); | 559 | kfree(tdata); |
| 558 | ida_free: | 560 | ida_free: |
| 559 | if (!pkg_flag) | 561 | if (!pkg_flag) |
| 560 | ida_free(&pdata->ida, index); | 562 | ida_free(&pdata->ida, index - BASE_SYSFS_ATTR_NO); |
| 561 | return err; | 563 | return err; |
| 562 | } | 564 | } |
| 563 | 565 | ||
| @@ -146,7 +146,7 @@ static int waterforce_get_status(struct waterforce_data *priv) · 145 unmodified lines | |||
| 146 | /* Send command for getting status */ | 146 | /* Send command for getting status */ |
| 147 | ret = waterforce_write_expanded(priv, get_status_cmd, GET_STATUS_CMD_LENGTH); | 147 | ret = waterforce_write_expanded(priv, get_status_cmd, GET_STATUS_CMD_LENGTH); |
| 148 | if (ret < 0) | 148 | if (ret < 0) |
| 149 | return ret; | 149 | goto unlock_and_return; |
| 150 | 150 | ||
| 151 | ret = wait_for_completion_interruptible_timeout(&priv->status_report_received, | 151 | ret = wait_for_completion_interruptible_timeout(&priv->status_report_received, |
| 152 | msecs_to_jiffies(STATUS_VALIDITY)); | 152 | msecs_to_jiffies(STATUS_VALIDITY)); |
| @@ -126,6 +126,21 @@ static const struct regulator_desc __maybe_unused mp2975_reg_desc[] = { · 125 unmodified lines | |||
| 126 | 126 | ||
| 127 | #define to_mp2975_data(x) container_of(x, struct mp2975_data, info) | 127 | #define to_mp2975_data(x) container_of(x, struct mp2975_data, info) |
| 128 | 128 | ||
| 129 | static int mp2975_read_byte_data(struct i2c_client *client, int page, int reg) | ||
| 130 | { | ||
| 131 | switch (reg) { | ||
| 132 | case PMBUS_VOUT_MODE: | ||
| 133 | /* | ||
| 134 | * Report direct format as configured by MFR_DC_LOOP_CTRL. | ||
| 135 | * Unlike on MP2971/MP2973 the reported VOUT_MODE isn't automatically | ||
| 136 | * internally updated, but always reads as PB_VOUT_MODE_VID. | ||
| 137 | */ | ||
| 138 | return PB_VOUT_MODE_DIRECT; | ||
| 139 | default: | ||
| 140 | return -ENODATA; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 129 | static int | 144 | static int |
| 130 | mp2975_read_word_helper(struct i2c_client *client, int page, int phase, u8 reg, | 145 | mp2975_read_word_helper(struct i2c_client *client, int page, int phase, u8 reg, |
| 131 | u16 mask) | 146 | u16 mask) |
| @@ -869,6 +884,7 @@ static struct pmbus_driver_info mp2975_info = { · 737 unmodified lines | |||
| 869 | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | | 884 | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
| 870 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT | | 885 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT | |
| 871 | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_PHASE_VIRTUAL, | 886 | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_PHASE_VIRTUAL, |
| 887 | .read_byte_data = mp2975_read_byte_data, | ||
| 872 | .read_word_data = mp2975_read_word_data, | 888 | .read_word_data = mp2975_read_word_data, |
| 873 | #if IS_ENABLED(CONFIG_SENSORS_MP2975_REGULATOR) | 889 | #if IS_ENABLED(CONFIG_SENSORS_MP2975_REGULATOR) |
| 874 | .num_regulators = 1, | 890 | .num_regulators = 1, |
| @@ -294,6 +294,7 @@ static const struct xpad_device { · 293 unmodified lines | |||
| 294 | { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 }, | 294 | { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 }, |
| 295 | { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 }, | 295 | { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 }, |
| 296 | { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 }, | 296 | { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 }, |
| 297 | { 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 }, | ||
| 297 | { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 }, | 298 | { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 }, |
| 298 | { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, | 299 | { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, |
| 299 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 300 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
| @@ -491,6 +492,7 @@ static const struct usb_device_id xpad_table[] = { · 191 unmodified lines | |||
| 491 | XPAD_XBOX360_VENDOR(0x15e4), /* Numark Xbox 360 controllers */ | 492 | XPAD_XBOX360_VENDOR(0x15e4), /* Numark Xbox 360 controllers */ |
| 492 | XPAD_XBOX360_VENDOR(0x162e), /* Joytech Xbox 360 controllers */ | 493 | XPAD_XBOX360_VENDOR(0x162e), /* Joytech Xbox 360 controllers */ |
| 493 | XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ | 494 | XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ |
| 495 | XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */ | ||
| 494 | XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ | 496 | XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ |
| 495 | XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */ | 497 | XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */ |
| 496 | XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */ | 498 | XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */ |
| @@ -811,7 +811,6 @@ static int atkbd_probe(struct atkbd *atkbd) · 810 unmodified lines | |||
| 811 | { | 811 | { |
| 812 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 812 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
| 813 | unsigned char param[2]; | 813 | unsigned char param[2]; |
| 814 | bool skip_getid; | ||
| 815 | 814 | ||
| 816 | /* | 815 | /* |
| 817 | * Some systems, where the bit-twiddling when testing the io-lines of the | 816 | * Some systems, where the bit-twiddling when testing the io-lines of the |
| @@ -825,6 +824,11 @@ static int atkbd_probe(struct atkbd *atkbd) · 7 unmodified lines | |||
| 825 | "keyboard reset failed on %s\n", | 824 | "keyboard reset failed on %s\n", |
| 826 | ps2dev->serio->phys); | 825 | ps2dev->serio->phys); |
| 827 | 826 | ||
| 827 | if (atkbd_skip_getid(atkbd)) { | ||
| 828 | atkbd->id = 0xab83; | ||
| 829 | goto deactivate_kbd; | ||
| 830 | } | ||
| 831 | |||
| 828 | /* | 832 | /* |
| 829 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. | 833 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. |
| 830 | * Some keyboards report different values, but the first byte is always 0xab or | 834 | * Some keyboards report different values, but the first byte is always 0xab or |
| @@ -833,18 +837,17 @@ static int atkbd_probe(struct atkbd *atkbd) · 2 unmodified lines | |||
| 833 | */ | 837 | */ |
| 834 | 838 | ||
| 835 | param[0] = param[1] = 0xa5; /* initialize with invalid values */ | 839 | param[0] = param[1] = 0xa5; /* initialize with invalid values */ |
| 836 | skip_getid = atkbd_skip_getid(atkbd); | 840 | if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { |
| 837 | if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { | ||
| 838 | 841 | ||
| 839 | /* | 842 | /* |
| 840 | * If the get ID command was skipped or failed, we check if we can at least set | 843 | * If the get ID command failed, we check if we can at least set |
| 841 | * the LEDs on the keyboard. This should work on every keyboard out there. | 844 | * the LEDs on the keyboard. This should work on every keyboard out there. |
| 842 | * It also turns the LEDs off, which we want anyway. | 845 | * It also turns the LEDs off, which we want anyway. |
| 843 | */ | 846 | */ |
| 844 | param[0] = 0; | 847 | param[0] = 0; |
| 845 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) | 848 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) |
| 846 | return -1; | 849 | return -1; |
| 847 | atkbd->id = skip_getid ? 0xab83 : 0xabba; | 850 | atkbd->id = 0xabba; |
| 848 | return 0; | 851 | return 0; |
| 849 | } | 852 | } |
| 850 | 853 | ||
| @@ -860,6 +863,7 @@ static int atkbd_probe(struct atkbd *atkbd) · 9 unmodified lines | |||
| 860 | return -1; | 863 | return -1; |
| 861 | } | 864 | } |
| 862 | 865 | ||
| 866 | deactivate_kbd: | ||
| 863 | /* | 867 | /* |
| 864 | * Make sure nothing is coming from the keyboard and disturbs our | 868 | * Make sure nothing is coming from the keyboard and disturbs our |
| 865 | * internal state. | 869 | * internal state. |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) | 19 | * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "linux/usb.h" | ||
| 22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 23 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
| 24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| @@ -193,6 +194,8 @@ enum tp_type { · 168 unmodified lines | |||
| 193 | 194 | ||
| 194 | /* list of device capability bits */ | 195 | /* list of device capability bits */ |
| 195 | #define HAS_INTEGRATED_BUTTON 1 | 196 | #define HAS_INTEGRATED_BUTTON 1 |
| 197 | /* maximum number of supported endpoints (currently trackpad and button) */ | ||
| 198 | #define MAX_ENDPOINTS 2 | ||
| 196 | 199 | ||
| 197 | /* trackpad finger data block size */ | 200 | /* trackpad finger data block size */ |
| 198 | #define FSIZE_TYPE1 (14 * sizeof(__le16)) | 201 | #define FSIZE_TYPE1 (14 * sizeof(__le16)) |
| @@ -891,6 +894,18 @@ static int bcm5974_resume(struct usb_interface *iface) · 692 unmodified lines | |||
| 891 | return error; | 894 | return error; |
| 892 | } | 895 | } |
| 893 | 896 | ||
| 897 | static bool bcm5974_check_endpoints(struct usb_interface *iface, | ||
| 898 | const struct bcm5974_config *cfg) | ||
| 899 | { | ||
| 900 | u8 ep_addr[MAX_ENDPOINTS + 1] = {0}; | ||
| 901 | |||
| 902 | ep_addr[0] = cfg->tp_ep; | ||
| 903 | if (cfg->tp_type == TYPE1) | ||
| 904 | ep_addr[1] = cfg->bt_ep; | ||
| 905 | |||
| 906 | return usb_check_int_endpoints(iface, ep_addr); | ||
| 907 | } | ||
| 908 | |||
| 894 | static int bcm5974_probe(struct usb_interface *iface, | 909 | static int bcm5974_probe(struct usb_interface *iface, |
| 895 | const struct usb_device_id *id) | 910 | const struct usb_device_id *id) |
| 896 | { | 911 | { |
| @@ -903,6 +918,11 @@ static int bcm5974_probe(struct usb_interface *iface, · 6 unmodified lines | |||
| 903 | /* find the product index */ | 918 | /* find the product index */ |
| 904 | cfg = bcm5974_get_config(udev); | 919 | cfg = bcm5974_get_config(udev); |
| 905 | 920 | ||
| 921 | if (!bcm5974_check_endpoints(iface, cfg)) { | ||
| 922 | dev_err(&iface->dev, "Unexpected non-int endpoint\n"); | ||
| 923 | return -ENODEV; | ||
| 924 | } | ||
| 925 | |||
| 906 | /* allocate memory for our device state and initialize it */ | 926 | /* allocate memory for our device state and initialize it */ |
| 907 | dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); | 927 | dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); |
| 908 | input_dev = input_allocate_device(); | 928 | input_dev = input_allocate_device(); |
| @@ -634,6 +634,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { · 633 unmodified lines | |||
| 634 | }, | 634 | }, |
| 635 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) | 635 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) |
| 636 | }, | 636 | }, |
| 637 | { | ||
| 638 | /* Fujitsu Lifebook U728 */ | ||
| 639 | .matches = { | ||
| 640 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
| 641 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U728"), | ||
| 642 | }, | ||
| 643 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) | ||
| 644 | }, | ||
| 637 | { | 645 | { |
| 638 | /* Gigabyte M912 */ | 646 | /* Gigabyte M912 */ |
| 639 | .matches = { | 647 | .matches = { |
| @@ -1208,6 +1216,12 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { · 568 unmodified lines | |||
| 1208 | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | | 1216 | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | |
| 1209 | SERIO_QUIRK_NOPNP) | 1217 | SERIO_QUIRK_NOPNP) |
| 1210 | }, | 1218 | }, |
| 1219 | { | ||
| 1220 | .matches = { | ||
| 1221 | DMI_MATCH(DMI_BOARD_NAME, "NS5x_7xPU"), | ||
| 1222 | }, | ||
| 1223 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) | ||
| 1224 | }, | ||
| 1211 | { | 1225 | { |
| 1212 | .matches = { | 1226 | .matches = { |
| 1213 | DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"), | 1227 | DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"), |
| @@ -884,7 +884,8 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) · 883 unmodified lines | |||
| 884 | } | 884 | } |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) { | 887 | /* Some devices with gpio_int_idx 0 list a third unused GPIO */ |
| 888 | if ((ts->gpio_count == 2 || ts->gpio_count == 3) && ts->gpio_int_idx == 0) { | ||
| 888 | ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; | 889 | ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; |
| 889 | gpio_mapping = acpi_goodix_int_first_gpios; | 890 | gpio_mapping = acpi_goodix_int_first_gpios; |
| 890 | } else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) { | 891 | } else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) { |
| @@ -1799,7 +1799,7 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) · 1798 unmodified lines | |||
| 1799 | * domain. Do not use in new drivers. | 1799 | * domain. Do not use in new drivers. |
| 1800 | */ | 1800 | */ |
| 1801 | if (ops->default_domain) { | 1801 | if (ops->default_domain) { |
| 1802 | if (req_type) | 1802 | if (req_type != ops->default_domain->type) |
| 1803 | return ERR_PTR(-EINVAL); | 1803 | return ERR_PTR(-EINVAL); |
| 1804 | return ops->default_domain; | 1804 | return ops->default_domain; |
| 1805 | } | 1805 | } |
| @@ -1871,10 +1871,18 @@ static int iommu_get_def_domain_type(struct iommu_group *group, · 65 unmodified lines | |||
| 1871 | const struct iommu_ops *ops = dev_iommu_ops(dev); | 1871 | const struct iommu_ops *ops = dev_iommu_ops(dev); |
| 1872 | int type; | 1872 | int type; |
| 1873 | 1873 | ||
| 1874 | if (!ops->def_domain_type) | 1874 | if (ops->default_domain) { |
| 1875 | return cur_type; | 1875 | /* |
| 1876 | 1876 | * Drivers that declare a global static default_domain will | |
| 1877 | type = ops->def_domain_type(dev); | 1877 | * always choose that. |
| 1878 | */ | ||
| 1879 | type = ops->default_domain->type; | ||
| 1880 | } else { | ||
| 1881 | if (ops->def_domain_type) | ||
| 1882 | type = ops->def_domain_type(dev); | ||
| 1883 | else | ||
| 1884 | return cur_type; | ||
| 1885 | } | ||
| 1878 | if (!type || cur_type == type) | 1886 | if (!type || cur_type == type) |
| 1879 | return cur_type; | 1887 | return cur_type; |
| 1880 | if (!cur_type) | 1888 | if (!cur_type) |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | |||
| 22 | #include "dm-ima.h" | 22 | #include "dm-ima.h" |
| 23 | 23 | ||
| 24 | #define DM_RESERVED_MAX_IOS 1024 | 24 | #define DM_RESERVED_MAX_IOS 1024 |
| 25 | #define DM_MAX_TARGETS 1048576 | ||
| 26 | #define DM_MAX_TARGET_PARAMS 1024 | ||
| 25 | 27 | ||
| 26 | struct dm_io; | 28 | struct dm_io; |
| 27 | 29 | ||
| @@ -73,10 +73,8 @@ struct dm_crypt_io { · 72 unmodified lines | |||
| 73 | struct bio *base_bio; | 73 | struct bio *base_bio; |
| 74 | u8 *integrity_metadata; | 74 | u8 *integrity_metadata; |
| 75 | bool integrity_metadata_from_pool:1; | 75 | bool integrity_metadata_from_pool:1; |
| 76 | bool in_tasklet:1; | ||
| 77 | 76 | ||
| 78 | struct work_struct work; | 77 | struct work_struct work; |
| 79 | struct tasklet_struct tasklet; | ||
| 80 | 78 | ||
| 81 | struct convert_context ctx; | 79 | struct convert_context ctx; |
| 82 | 80 | ||
| @@ -1762,7 +1760,6 @@ static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc, · 1679 unmodified lines | |||
| 1762 | io->ctx.r.req = NULL; | 1760 | io->ctx.r.req = NULL; |
| 1763 | io->integrity_metadata = NULL; | 1761 | io->integrity_metadata = NULL; |
| 1764 | io->integrity_metadata_from_pool = false; | 1762 | io->integrity_metadata_from_pool = false; |
| 1765 | io->in_tasklet = false; | ||
| 1766 | atomic_set(&io->io_pending, 0); | 1763 | atomic_set(&io->io_pending, 0); |
| 1767 | } | 1764 | } |
| 1768 | 1765 | ||
| @@ -1771,13 +1768,6 @@ static void crypt_inc_pending(struct dm_crypt_io *io) · 2 unmodified lines | |||
| 1771 | atomic_inc(&io->io_pending); | 1768 | atomic_inc(&io->io_pending); |
| 1772 | } | 1769 | } |
| 1773 | 1770 | ||
| 1774 | static void kcryptd_io_bio_endio(struct work_struct *work) | ||
| 1775 | { | ||
| 1776 | struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); | ||
| 1777 | |||
| 1778 | bio_endio(io->base_bio); | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | /* | 1771 | /* |
| 1782 | * One of the bios was finished. Check for completion of | 1772 | * One of the bios was finished. Check for completion of |
| 1783 | * the whole request and correctly clean up the buffer. | 1773 | * the whole request and correctly clean up the buffer. |
| @@ -1801,20 +1791,6 @@ static void crypt_dec_pending(struct dm_crypt_io *io) · 17 unmodified lines | |||
| 1801 | 1791 | ||
| 1802 | base_bio->bi_status = error; | 1792 | base_bio->bi_status = error; |
| 1803 | 1793 | ||
| 1804 | /* | ||
| 1805 | * If we are running this function from our tasklet, | ||
| 1806 | * we can't call bio_endio() here, because it will call | ||
| 1807 | * clone_endio() from dm.c, which in turn will | ||
| 1808 | * free the current struct dm_crypt_io structure with | ||
| 1809 | * our tasklet. In this case we need to delay bio_endio() | ||
| 1810 | * execution to after the tasklet is done and dequeued. | ||
| 1811 | */ | ||
| 1812 | if (io->in_tasklet) { | ||
| 1813 | INIT_WORK(&io->work, kcryptd_io_bio_endio); | ||
| 1814 | queue_work(cc->io_queue, &io->work); | ||
| 1815 | return; | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | bio_endio(base_bio); | 1794 | bio_endio(base_bio); |
| 1819 | } | 1795 | } |
| 1820 | 1796 | ||
| @@ -2246,11 +2222,6 @@ static void kcryptd_crypt(struct work_struct *work) · 425 unmodified lines | |||
| 2246 | kcryptd_crypt_write_convert(io); | 2222 | kcryptd_crypt_write_convert(io); |
| 2247 | } | 2223 | } |
| 2248 | 2224 | ||
| 2249 | static void kcryptd_crypt_tasklet(unsigned long work) | ||
| 2250 | { | ||
| 2251 | kcryptd_crypt((struct work_struct *)work); | ||
| 2252 | } | ||
| 2253 | |||
| 2254 | static void kcryptd_queue_crypt(struct dm_crypt_io *io) | 2225 | static void kcryptd_queue_crypt(struct dm_crypt_io *io) |
| 2255 | { | 2226 | { |
| 2256 | struct crypt_config *cc = io->cc; | 2227 | struct crypt_config *cc = io->cc; |
| @@ -2262,15 +2233,10 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io) · 5 unmodified lines | |||
| 2262 | * irqs_disabled(): the kernel may run some IO completion from the idle thread, but | 2233 | * irqs_disabled(): the kernel may run some IO completion from the idle thread, but |
| 2263 | * it is being executed with irqs disabled. | 2234 | * it is being executed with irqs disabled. |
| 2264 | */ | 2235 | */ |
| 2265 | if (in_hardirq() || irqs_disabled()) { | 2236 | if (!(in_hardirq() || irqs_disabled())) { |
| 2266 | io->in_tasklet = true; | 2237 | kcryptd_crypt(&io->work); |
| 2267 | tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); | ||
| 2268 | tasklet_schedule(&io->tasklet); | ||
| 2269 | return; | 2238 | return; |
| 2270 | } | 2239 | } |
| 2271 | |||
| 2272 | kcryptd_crypt(&io->work); | ||
| 2273 | return; | ||
| 2274 | } | 2240 | } |
| 2275 | 2241 | ||
| 2276 | INIT_WORK(&io->work, kcryptd_crypt); | 2242 | INIT_WORK(&io->work, kcryptd_crypt); |
| @@ -1941,7 +1941,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern · 1940 unmodified lines | |||
| 1941 | minimum_data_size - sizeof(param_kernel->version))) | 1941 | minimum_data_size - sizeof(param_kernel->version))) |
| 1942 | return -EFAULT; | 1942 | return -EFAULT; |
| 1943 | 1943 | ||
| 1944 | if (param_kernel->data_size < minimum_data_size) { | 1944 | if (unlikely(param_kernel->data_size < minimum_data_size) || |
| 1945 | unlikely(param_kernel->data_size > DM_MAX_TARGETS * DM_MAX_TARGET_PARAMS)) { | ||
| 1945 | DMERR("Invalid data size in the ioctl structure: %u", | 1946 | DMERR("Invalid data size in the ioctl structure: %u", |
| 1946 | param_kernel->data_size); | 1947 | param_kernel->data_size); |
| 1947 | return -EINVAL; | 1948 | return -EINVAL; |
| @@ -66,6 +66,9 @@ struct dm_stats_last_position { · 65 unmodified lines | |||
| 66 | unsigned int last_rw; | 66 | unsigned int last_rw; |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | #define DM_STAT_MAX_ENTRIES 8388608 | ||
| 70 | #define DM_STAT_MAX_HISTOGRAM_ENTRIES 134217728 | ||
| 71 | |||
| 69 | /* | 72 | /* |
| 70 | * A typo on the command line could possibly make the kernel run out of memory | 73 | * A typo on the command line could possibly make the kernel run out of memory |
| 71 | * and crash. To prevent the crash we account all used memory. We fail if we | 74 | * and crash. To prevent the crash we account all used memory. We fail if we |
| @@ -285,6 +288,9 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end, · 213 unmodified lines | |||
| 285 | if (n_entries != (size_t)n_entries || !(size_t)(n_entries + 1)) | 288 | if (n_entries != (size_t)n_entries || !(size_t)(n_entries + 1)) |
| 286 | return -EOVERFLOW; | 289 | return -EOVERFLOW; |
| 287 | 290 | ||
| 291 | if (n_entries > DM_STAT_MAX_ENTRIES) | ||
| 292 | return -EOVERFLOW; | ||
| 293 | |||
| 288 | shared_alloc_size = struct_size(s, stat_shared, n_entries); | 294 | shared_alloc_size = struct_size(s, stat_shared, n_entries); |
| 289 | if ((shared_alloc_size - sizeof(struct dm_stat)) / sizeof(struct dm_stat_shared) != n_entries) | 295 | if ((shared_alloc_size - sizeof(struct dm_stat)) / sizeof(struct dm_stat_shared) != n_entries) |
| 290 | return -EOVERFLOW; | 296 | return -EOVERFLOW; |
| @@ -297,6 +303,9 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end, · 6 unmodified lines | |||
| 297 | if (histogram_alloc_size / (n_histogram_entries + 1) != (size_t)n_entries * sizeof(unsigned long long)) | 303 | if (histogram_alloc_size / (n_histogram_entries + 1) != (size_t)n_entries * sizeof(unsigned long long)) |
| 298 | return -EOVERFLOW; | 304 | return -EOVERFLOW; |
| 299 | 305 | ||
| 306 | if ((n_histogram_entries + 1) * (size_t)n_entries > DM_STAT_MAX_HISTOGRAM_ENTRIES) | ||
| 307 | return -EOVERFLOW; | ||
| 308 | |||
| 300 | if (!check_shared_memory(shared_alloc_size + histogram_alloc_size + | 309 | if (!check_shared_memory(shared_alloc_size + histogram_alloc_size + |
| 301 | num_possible_cpus() * (percpu_alloc_size + histogram_alloc_size))) | 310 | num_possible_cpus() * (percpu_alloc_size + histogram_alloc_size))) |
| 302 | return -ENOMEM; | 311 | return -ENOMEM; |
| @@ -129,7 +129,12 @@ static int alloc_targets(struct dm_table *t, unsigned int num) · 128 unmodified lines | |||
| 129 | int dm_table_create(struct dm_table **result, blk_mode_t mode, | 129 | int dm_table_create(struct dm_table **result, blk_mode_t mode, |
| 130 | unsigned int num_targets, struct mapped_device *md) | 130 | unsigned int num_targets, struct mapped_device *md) |
| 131 | { | 131 | { |
| 132 | struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL); | 132 | struct dm_table *t; |
| 133 | |||
| 134 | if (num_targets > DM_MAX_TARGETS) | ||
| 135 | return -EOVERFLOW; | ||
| 136 | |||
| 137 | t = kzalloc(sizeof(*t), GFP_KERNEL); | ||
| 133 | 138 | ||
| 134 | if (!t) | 139 | if (!t) |
| 135 | return -ENOMEM; | 140 | return -ENOMEM; |
| @@ -144,7 +149,7 @@ int dm_table_create(struct dm_table **result, blk_mode_t mode, · 8 unmodified lines | |||
| 144 | 149 | ||
| 145 | if (!num_targets) { | 150 | if (!num_targets) { |
| 146 | kfree(t); | 151 | kfree(t); |
| 147 | return -ENOMEM; | 152 | return -EOVERFLOW; |
| 148 | } | 153 | } |
| 149 | 154 | ||
| 150 | if (alloc_targets(t, num_targets)) { | 155 | if (alloc_targets(t, num_targets)) { |
| @@ -645,23 +645,6 @@ static void verity_work(struct work_struct *w) · 644 unmodified lines | |||
| 645 | verity_finish_io(io, errno_to_blk_status(verity_verify_io(io))); | 645 | verity_finish_io(io, errno_to_blk_status(verity_verify_io(io))); |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | static void verity_tasklet(unsigned long data) | ||
| 649 | { | ||
| 650 | struct dm_verity_io *io = (struct dm_verity_io *)data; | ||
| 651 | int err; | ||
| 652 | |||
| 653 | io->in_tasklet = true; | ||
| 654 | err = verity_verify_io(io); | ||
| 655 | if (err == -EAGAIN || err == -ENOMEM) { | ||
| 656 | /* fallback to retrying with work-queue */ | ||
| 657 | INIT_WORK(&io->work, verity_work); | ||
| 658 | queue_work(io->v->verify_wq, &io->work); | ||
| 659 | return; | ||
| 660 | } | ||
| 661 | |||
| 662 | verity_finish_io(io, errno_to_blk_status(err)); | ||
| 663 | } | ||
| 664 | |||
| 665 | static void verity_end_io(struct bio *bio) | 648 | static void verity_end_io(struct bio *bio) |
| 666 | { | 649 | { |
| 667 | struct dm_verity_io *io = bio->bi_private; | 650 | struct dm_verity_io *io = bio->bi_private; |
| @@ -674,13 +657,8 @@ static void verity_end_io(struct bio *bio) · 6 unmodified lines | |||
| 674 | return; | 657 | return; |
| 675 | } | 658 | } |
| 676 | 659 | ||
| 677 | if (static_branch_unlikely(&use_tasklet_enabled) && io->v->use_tasklet) { | 660 | INIT_WORK(&io->work, verity_work); |
| 678 | tasklet_init(&io->tasklet, verity_tasklet, (unsigned long)io); | 661 | queue_work(io->v->verify_wq, &io->work); |
| 679 | tasklet_schedule(&io->tasklet); | ||
| 680 | } else { | ||
| 681 | INIT_WORK(&io->work, verity_work); | ||
| 682 | queue_work(io->v->verify_wq, &io->work); | ||
| 683 | } | ||
| 684 | } | 662 | } |
| 685 | 663 | ||
| 686 | /* | 664 | /* |
| @@ -83,7 +83,6 @@ struct dm_verity_io { · 82 unmodified lines | |||
| 83 | struct bvec_iter iter; | 83 | struct bvec_iter iter; |
| 84 | 84 | ||
| 85 | struct work_struct work; | 85 | struct work_struct work; |
| 86 | struct tasklet_struct tasklet; | ||
| 87 | 86 | ||
| 88 | /* | 87 | /* |
| 89 | * Three variably-size fields follow this struct: | 88 | * Three variably-size fields follow this struct: |
| @@ -299,7 +299,7 @@ static int persistent_memory_claim(struct dm_writecache *wc) · 298 unmodified lines | |||
| 299 | long i; | 299 | long i; |
| 300 | 300 | ||
| 301 | wc->memory_map = NULL; | 301 | wc->memory_map = NULL; |
| 302 | pages = kvmalloc_array(p, sizeof(struct page *), GFP_KERNEL); | 302 | pages = vmalloc_array(p, sizeof(struct page *)); |
| 303 | if (!pages) { | 303 | if (!pages) { |
| 304 | r = -ENOMEM; | 304 | r = -ENOMEM; |
| 305 | goto err2; | 305 | goto err2; |
| @@ -330,7 +330,7 @@ static int persistent_memory_claim(struct dm_writecache *wc) · 24 unmodified lines | |||
| 330 | r = -ENOMEM; | 330 | r = -ENOMEM; |
| 331 | goto err3; | 331 | goto err3; |
| 332 | } | 332 | } |
| 333 | kvfree(pages); | 333 | vfree(pages); |
| 334 | wc->memory_vmapped = true; | 334 | wc->memory_vmapped = true; |
| 335 | } | 335 | } |
| 336 | 336 | ||
| @@ -341,7 +341,7 @@ static int persistent_memory_claim(struct dm_writecache *wc) · 4 unmodified lines | |||
| 341 | 341 | ||
| 342 | return 0; | 342 | return 0; |
| 343 | err3: | 343 | err3: |
| 344 | kvfree(pages); | 344 | vfree(pages); |
| 345 | err2: | 345 | err2: |
| 346 | dax_read_unlock(id); | 346 | dax_read_unlock(id); |
| 347 | err1: | 347 | err1: |
| @@ -962,7 +962,7 @@ static int writecache_alloc_entries(struct dm_writecache *wc) · 614 unmodified lines | |||
| 962 | 962 | ||
| 963 | if (wc->entries) | 963 | if (wc->entries) |
| 964 | return 0; | 964 | return 0; |
| 965 | wc->entries = vmalloc(array_size(sizeof(struct wc_entry), wc->n_blocks)); | 965 | wc->entries = vmalloc_array(wc->n_blocks, sizeof(struct wc_entry)); |
| 966 | if (!wc->entries) | 966 | if (!wc->entries) |
| 967 | return -ENOMEM; | 967 | return -ENOMEM; |
| 968 | for (b = 0; b < wc->n_blocks; b++) { | 968 | for (b = 0; b < wc->n_blocks; b++) { |
| @@ -2262,7 +2262,7 @@ static void fix_read_error(struct r1conf *conf, struct r1bio *r1_bio) · 2261 unmodified lines | |||
| 2262 | int sectors = r1_bio->sectors; | 2262 | int sectors = r1_bio->sectors; |
| 2263 | int read_disk = r1_bio->read_disk; | 2263 | int read_disk = r1_bio->read_disk; |
| 2264 | struct mddev *mddev = conf->mddev; | 2264 | struct mddev *mddev = conf->mddev; |
| 2265 | struct md_rdev *rdev = rcu_dereference(conf->mirrors[read_disk].rdev); | 2265 | struct md_rdev *rdev = conf->mirrors[read_disk].rdev; |
| 2266 | 2266 | ||
| 2267 | if (exceed_read_errors(mddev, rdev)) { | 2267 | if (exceed_read_errors(mddev, rdev)) { |
| 2268 | r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED; | 2268 | r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED; |
| @@ -989,7 +989,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, · 988 unmodified lines | |||
| 989 | bool no_previous_buffers = !q_num_bufs; | 989 | bool no_previous_buffers = !q_num_bufs; |
| 990 | int ret = 0; | 990 | int ret = 0; |
| 991 | 991 | ||
| 992 | if (q->num_buffers == q->max_num_buffers) { | 992 | if (q_num_bufs == q->max_num_buffers) { |
| 993 | dprintk(q, 1, "maximum number of buffers already allocated\n"); | 993 | dprintk(q, 1, "maximum number of buffers already allocated\n"); |
| 994 | return -ENOBUFS; | 994 | return -ENOBUFS; |
| 995 | } | 995 | } |
| @@ -671,8 +671,20 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b) · 670 unmodified lines | |||
| 671 | } | 671 | } |
| 672 | EXPORT_SYMBOL(vb2_querybuf); | 672 | EXPORT_SYMBOL(vb2_querybuf); |
| 673 | 673 | ||
| 674 | static void fill_buf_caps(struct vb2_queue *q, u32 *caps) | 674 | static void vb2_set_flags_and_caps(struct vb2_queue *q, u32 memory, |
| 675 | u32 *flags, u32 *caps, u32 *max_num_bufs) | ||
| 675 | { | 676 | { |
| 677 | if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP) { | ||
| 678 | /* | ||
| 679 | * This needs to clear V4L2_MEMORY_FLAG_NON_COHERENT only, | ||
| 680 | * but in order to avoid bugs we zero out all bits. | ||
| 681 | */ | ||
| 682 | *flags = 0; | ||
| 683 | } else { | ||
| 684 | /* Clear all unknown flags. */ | ||
| 685 | *flags &= V4L2_MEMORY_FLAG_NON_COHERENT; | ||
| 686 | } | ||
| 687 | |||
| 676 | *caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; | 688 | *caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; |
| 677 | if (q->io_modes & VB2_MMAP) | 689 | if (q->io_modes & VB2_MMAP) |
| 678 | *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; | 690 | *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; |
| @@ -686,21 +698,9 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps) · 7 unmodified lines | |||
| 686 | *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS; | 698 | *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS; |
| 687 | if (q->supports_requests) | 699 | if (q->supports_requests) |
| 688 | *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; | 700 | *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; |
| 689 | } | 701 | if (max_num_bufs) { |
| 690 | 702 | *max_num_bufs = q->max_num_buffers; | |
| 691 | static void validate_memory_flags(struct vb2_queue *q, | 703 | *caps |= V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS; |
| 692 | int memory, | ||
| 693 | u32 *flags) | ||
| 694 | { | ||
| 695 | if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP) { | ||
| 696 | /* | ||
| 697 | * This needs to clear V4L2_MEMORY_FLAG_NON_COHERENT only, | ||
| 698 | * but in order to avoid bugs we zero out all bits. | ||
| 699 | */ | ||
| 700 | *flags = 0; | ||
| 701 | } else { | ||
| 702 | /* Clear all unknown flags. */ | ||
| 703 | *flags &= V4L2_MEMORY_FLAG_NON_COHERENT; | ||
| 704 | } | 704 | } |
| 705 | } | 705 | } |
| 706 | 706 | ||
| @@ -709,8 +709,8 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) · 2 unmodified lines | |||
| 709 | int ret = vb2_verify_memory_type(q, req->memory, req->type); | 709 | int ret = vb2_verify_memory_type(q, req->memory, req->type); |
| 710 | u32 flags = req->flags; | 710 | u32 flags = req->flags; |
| 711 | 711 | ||
| 712 | fill_buf_caps(q, &req->capabilities); | 712 | vb2_set_flags_and_caps(q, req->memory, &flags, |
| 713 | validate_memory_flags(q, req->memory, &flags); | 713 | &req->capabilities, NULL); |
| 714 | req->flags = flags; | 714 | req->flags = flags; |
| 715 | return ret ? ret : vb2_core_reqbufs(q, req->memory, | 715 | return ret ? ret : vb2_core_reqbufs(q, req->memory, |
| 716 | req->flags, &req->count); | 716 | req->flags, &req->count); |
| @@ -751,11 +751,9 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) · 34 unmodified lines | |||
| 751 | int ret = vb2_verify_memory_type(q, create->memory, f->type); | 751 | int ret = vb2_verify_memory_type(q, create->memory, f->type); |
| 752 | unsigned i; | 752 | unsigned i; |
| 753 | 753 | ||
| 754 | fill_buf_caps(q, &create->capabilities); | ||
| 755 | validate_memory_flags(q, create->memory, &create->flags); | ||
| 756 | create->index = vb2_get_num_buffers(q); | 754 | create->index = vb2_get_num_buffers(q); |
| 757 | create->max_num_buffers = q->max_num_buffers; | 755 | vb2_set_flags_and_caps(q, create->memory, &create->flags, |
| 758 | create->capabilities |= V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS; | 756 | &create->capabilities, &create->max_num_buffers); |
| 759 | if (create->count == 0) | 757 | if (create->count == 0) |
| 760 | return ret != -EBUSY ? ret : 0; | 758 | return ret != -EBUSY ? ret : 0; |
| 761 | 759 | ||
| @@ -1006,8 +1004,8 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv, · 244 unmodified lines | |||
| 1006 | int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); | 1004 | int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); |
| 1007 | u32 flags = p->flags; | 1005 | u32 flags = p->flags; |
| 1008 | 1006 | ||
| 1009 | fill_buf_caps(vdev->queue, &p->capabilities); | 1007 | vb2_set_flags_and_caps(vdev->queue, p->memory, &flags, |
| 1010 | validate_memory_flags(vdev->queue, p->memory, &flags); | 1008 | &p->capabilities, NULL); |
| 1011 | p->flags = flags; | 1009 | p->flags = flags; |
| 1012 | if (res) | 1010 | if (res) |
| 1013 | return res; | 1011 | return res; |
| @@ -1026,12 +1024,11 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv, · 12 unmodified lines | |||
| 1026 | struct v4l2_create_buffers *p) | 1024 | struct v4l2_create_buffers *p) |
| 1027 | { | 1025 | { |
| 1028 | struct video_device *vdev = video_devdata(file); | 1026 | struct video_device *vdev = video_devdata(file); |
| 1029 | int res = vb2_verify_memory_type(vdev->queue, p->memory, | 1027 | int res = vb2_verify_memory_type(vdev->queue, p->memory, p->format.type); |
| 1030 | p->format.type); | ||
| 1031 | 1028 | ||
| 1032 | p->index = vdev->queue->num_buffers; | 1029 | p->index = vb2_get_num_buffers(vdev->queue); |
| 1033 | fill_buf_caps(vdev->queue, &p->capabilities); | 1030 | vb2_set_flags_and_caps(vdev->queue, p->memory, &p->flags, |
| 1034 | validate_memory_flags(vdev->queue, p->memory, &p->flags); | 1031 | &p->capabilities, &p->max_num_buffers); |
| 1035 | /* | 1032 | /* |
| 1036 | * If count == 0, then just check if memory and type are valid. | 1033 | * If count == 0, then just check if memory and type are valid. |
| 1037 | * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. | 1034 | * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. |
| @@ -272,7 +272,7 @@ static const struct wave5_match_data ti_wave521c_data = { · 271 unmodified lines | |||
| 272 | }; | 272 | }; |
| 273 | 273 | ||
| 274 | static const struct of_device_id wave5_dt_ids[] = { | 274 | static const struct of_device_id wave5_dt_ids[] = { |
| 275 | { .compatible = "ti,k3-j721s2-wave521c", .data = &ti_wave521c_data }, | 275 | { .compatible = "ti,j721s2-wave521c", .data = &ti_wave521c_data }, |
| 276 | { /* sentinel */ } | 276 | { /* sentinel */ } |
| 277 | }; | 277 | }; |
| 278 | MODULE_DEVICE_TABLE(of, wave5_dt_ids); | 278 | MODULE_DEVICE_TABLE(of, wave5_dt_ids); |
| @@ -2191,7 +2191,7 @@ static int fastrpc_cb_remove(struct platform_device *pdev) · 2190 unmodified lines | |||
| 2191 | int i; | 2191 | int i; |
| 2192 | 2192 | ||
| 2193 | spin_lock_irqsave(&cctx->lock, flags); | 2193 | spin_lock_irqsave(&cctx->lock, flags); |
| 2194 | for (i = 1; i < FASTRPC_MAX_SESSIONS; i++) { | 2194 | for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) { |
| 2195 | if (cctx->session[i].sid == sess->sid) { | 2195 | if (cctx->session[i].sid == sess->sid) { |
| 2196 | cctx->session[i].valid = false; | 2196 | cctx->session[i].valid = false; |
| 2197 | cctx->sesscount--; | 2197 | cctx->sesscount--; |
| @@ -140,7 +140,6 @@ static int __init open_dice_probe(struct platform_device *pdev) · 139 unmodified lines | |||
| 140 | return -ENOMEM; | 140 | return -ENOMEM; |
| 141 | 141 | ||
| 142 | *drvdata = (struct open_dice_drvdata){ | 142 | *drvdata = (struct open_dice_drvdata){ |
| 143 | .lock = __MUTEX_INITIALIZER(drvdata->lock), | ||
| 144 | .rmem = rmem, | 143 | .rmem = rmem, |
| 145 | .misc = (struct miscdevice){ | 144 | .misc = (struct miscdevice){ |
| 146 | .parent = dev, | 145 | .parent = dev, |
| @@ -150,6 +149,7 @@ static int __init open_dice_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 150 | .mode = 0600, | 149 | .mode = 0600, |
| 151 | }, | 150 | }, |
| 152 | }; | 151 | }; |
| 152 | mutex_init(&drvdata->lock); | ||
| 153 | 153 | ||
| 154 | /* Index overflow check not needed, misc_register() will fail. */ | 154 | /* Index overflow check not needed, misc_register() will fail. */ |
| 155 | snprintf(drvdata->name, sizeof(drvdata->name), DRIVER_NAME"%u", dev_idx++); | 155 | snprintf(drvdata->name, sizeof(drvdata->name), DRIVER_NAME"%u", dev_idx++); |
| @@ -75,11 +75,15 @@ EXPORT_SYMBOL(mmc_gpio_set_cd_irq); · 74 unmodified lines | |||
| 75 | int mmc_gpio_get_ro(struct mmc_host *host) | 75 | int mmc_gpio_get_ro(struct mmc_host *host) |
| 76 | { | 76 | { |
| 77 | struct mmc_gpio *ctx = host->slot.handler_priv; | 77 | struct mmc_gpio *ctx = host->slot.handler_priv; |
| 78 | int cansleep; | ||
| 78 | 79 | ||
| 79 | if (!ctx || !ctx->ro_gpio) | 80 | if (!ctx || !ctx->ro_gpio) |
| 80 | return -ENOSYS; | 81 | return -ENOSYS; |
| 81 | 82 | ||
| 82 | return gpiod_get_value_cansleep(ctx->ro_gpio); | 83 | cansleep = gpiod_cansleep(ctx->ro_gpio); |
| 84 | return cansleep ? | ||
| 85 | gpiod_get_value_cansleep(ctx->ro_gpio) : | ||
| 86 | gpiod_get_value(ctx->ro_gpio); | ||
| 83 | } | 87 | } |
| 84 | EXPORT_SYMBOL(mmc_gpio_get_ro); | 88 | EXPORT_SYMBOL(mmc_gpio_get_ro); |
| 85 | 89 | ||
| @@ -693,6 +693,35 @@ static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc, struct mmc_ios *io · 692 unmodified lines | |||
| 693 | return 0; | 693 | return 0; |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | static void sdhci_pci_o2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd) | ||
| 697 | { | ||
| 698 | struct sdhci_pci_chip *chip; | ||
| 699 | struct sdhci_pci_slot *slot = sdhci_priv(host); | ||
| 700 | u32 scratch_32 = 0; | ||
| 701 | u8 scratch_8 = 0; | ||
| 702 | |||
| 703 | chip = slot->chip; | ||
| 704 | |||
| 705 | if (mode == MMC_POWER_OFF) { | ||
| 706 | /* UnLock WP */ | ||
| 707 | pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); | ||
| 708 | scratch_8 &= 0x7f; | ||
| 709 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); | ||
| 710 | |||
| 711 | /* Set PCR 0x354[16] to switch Clock Source back to OPE Clock */ | ||
| 712 | pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32); | ||
| 713 | scratch_32 &= ~(O2_SD_SEL_DLL); | ||
| 714 | pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, scratch_32); | ||
| 715 | |||
| 716 | /* Lock WP */ | ||
| 717 | pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); | ||
| 718 | scratch_8 |= 0x80; | ||
| 719 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); | ||
| 720 | } | ||
| 721 | |||
| 722 | sdhci_set_power(host, mode, vdd); | ||
| 723 | } | ||
| 724 | |||
| 696 | static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) | 725 | static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) |
| 697 | { | 726 | { |
| 698 | struct sdhci_pci_chip *chip; | 727 | struct sdhci_pci_chip *chip; |
| @@ -1051,6 +1080,7 @@ static const struct sdhci_ops sdhci_pci_o2_ops = { · 352 unmodified lines | |||
| 1051 | .set_bus_width = sdhci_set_bus_width, | 1080 | .set_bus_width = sdhci_set_bus_width, |
| 1052 | .reset = sdhci_reset, | 1081 | .reset = sdhci_reset, |
| 1053 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 1082 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 1083 | .set_power = sdhci_pci_o2_set_power, | ||
| 1054 | }; | 1084 | }; |
| 1055 | 1085 | ||
| 1056 | const struct sdhci_pci_fixes sdhci_o2 = { | 1086 | const struct sdhci_pci_fixes sdhci_o2 = { |
| @@ -2838,8 +2838,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, · 2837 unmodified lines | |||
| 2838 | /* MT753x MAC works in 1G full duplex mode for all up-clocked | 2838 | /* MT753x MAC works in 1G full duplex mode for all up-clocked |
| 2839 | * variants. | 2839 | * variants. |
| 2840 | */ | 2840 | */ |
| 2841 | if (interface == PHY_INTERFACE_MODE_INTERNAL || | 2841 | if (interface == PHY_INTERFACE_MODE_TRGMII || |
| 2842 | interface == PHY_INTERFACE_MODE_TRGMII || | ||
| 2843 | (phy_interface_mode_is_8023z(interface))) { | 2842 | (phy_interface_mode_is_8023z(interface))) { |
| 2844 | speed = SPEED_1000; | 2843 | speed = SPEED_1000; |
| 2845 | duplex = DUPLEX_FULL; | 2844 | duplex = DUPLEX_FULL; |
| @@ -3659,7 +3659,7 @@ static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad, · 3658 unmodified lines | |||
| 3659 | int err; | 3659 | int err; |
| 3660 | 3660 | ||
| 3661 | if (!chip->info->ops->phy_read_c45) | 3661 | if (!chip->info->ops->phy_read_c45) |
| 3662 | return -EOPNOTSUPP; | 3662 | return 0xffff; |
| 3663 | 3663 | ||
| 3664 | mv88e6xxx_reg_lock(chip); | 3664 | mv88e6xxx_reg_lock(chip); |
| 3665 | err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); | 3665 | err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); |
| @@ -2051,12 +2051,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev) · 2050 unmodified lines | |||
| 2051 | priv->info = of_device_get_match_data(priv->dev); | 2051 | priv->info = of_device_get_match_data(priv->dev); |
| 2052 | 2052 | ||
| 2053 | priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", | 2053 | priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", |
| 2054 | GPIOD_ASIS); | 2054 | GPIOD_OUT_HIGH); |
| 2055 | if (IS_ERR(priv->reset_gpio)) | 2055 | if (IS_ERR(priv->reset_gpio)) |
| 2056 | return PTR_ERR(priv->reset_gpio); | 2056 | return PTR_ERR(priv->reset_gpio); |
| 2057 | 2057 | ||
| 2058 | if (priv->reset_gpio) { | 2058 | if (priv->reset_gpio) { |
| 2059 | gpiod_set_value_cansleep(priv->reset_gpio, 1); | ||
| 2060 | /* The active low duration must be greater than 10 ms | 2059 | /* The active low duration must be greater than 10 ms |
| 2061 | * and checkpatch.pl wants 20 ms. | 2060 | * and checkpatch.pl wants 20 ms. |
| 2062 | */ | 2061 | */ |
| @@ -100,4 +100,5 @@ static void __exit ns8390_module_exit(void) · 99 unmodified lines | |||
| 100 | module_init(ns8390_module_init); | 100 | module_init(ns8390_module_init); |
| 101 | module_exit(ns8390_module_exit); | 101 | module_exit(ns8390_module_exit); |
| 102 | #endif /* MODULE */ | 102 | #endif /* MODULE */ |
| 103 | MODULE_DESCRIPTION("National Semiconductor 8390 core driver"); | ||
| 103 | MODULE_LICENSE("GPL"); | 104 | MODULE_LICENSE("GPL"); |
| @@ -102,4 +102,5 @@ static void __exit NS8390p_cleanup_module(void) · 101 unmodified lines | |||
| 102 | 102 | ||
| 103 | module_init(NS8390p_init_module); | 103 | module_init(NS8390p_init_module); |
| 104 | module_exit(NS8390p_cleanup_module); | 104 | module_exit(NS8390p_cleanup_module); |
| 105 | MODULE_DESCRIPTION("National Semiconductor 8390 core for ISA driver"); | ||
| 105 | MODULE_LICENSE("GPL"); | 106 | MODULE_LICENSE("GPL"); |
| @@ -610,4 +610,5 @@ static int init_pcmcia(void) · 609 unmodified lines | |||
| 610 | return 1; | 610 | return 1; |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | MODULE_DESCRIPTION("National Semiconductor 8390 Amiga PCMCIA ethernet driver"); | ||
| 613 | MODULE_LICENSE("GPL"); | 614 | MODULE_LICENSE("GPL"); |
| @@ -270,4 +270,5 @@ static void __exit hydra_cleanup_module(void) · 269 unmodified lines | |||
| 270 | module_init(hydra_init_module); | 270 | module_init(hydra_init_module); |
| 271 | module_exit(hydra_cleanup_module); | 271 | module_exit(hydra_cleanup_module); |
| 272 | 272 | ||
| 273 | MODULE_DESCRIPTION("Zorro-II Hydra 8390 ethernet driver"); | ||
| 273 | MODULE_LICENSE("GPL"); | 274 | MODULE_LICENSE("GPL"); |
| @@ -296,4 +296,5 @@ static void __exit stnic_cleanup(void) · 295 unmodified lines | |||
| 296 | 296 | ||
| 297 | module_init(stnic_probe); | 297 | module_init(stnic_probe); |
| 298 | module_exit(stnic_cleanup); | 298 | module_exit(stnic_cleanup); |
| 299 | MODULE_DESCRIPTION("National Semiconductor DP83902AV ethernet driver"); | ||
| 299 | MODULE_LICENSE("GPL"); | 300 | MODULE_LICENSE("GPL"); |
| @@ -443,4 +443,5 @@ static void __exit zorro8390_cleanup_module(void) · 442 unmodified lines | |||
| 443 | module_init(zorro8390_init_module); | 443 | module_init(zorro8390_init_module); |
| 444 | module_exit(zorro8390_cleanup_module); | 444 | module_exit(zorro8390_cleanup_module); |
| 445 | 445 | ||
| 446 | MODULE_DESCRIPTION("Zorro NS8390-based ethernet driver"); | ||
| 446 | MODULE_LICENSE("GPL"); | 447 | MODULE_LICENSE("GPL"); |
| @@ -63,6 +63,15 @@ static int pdsc_process_notifyq(struct pdsc_qcq *qcq) · 62 unmodified lines | |||
| 63 | return nq_work; | 63 | return nq_work; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static bool pdsc_adminq_inc_if_up(struct pdsc *pdsc) | ||
| 67 | { | ||
| 68 | if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER) || | ||
| 69 | pdsc->state & BIT_ULL(PDSC_S_FW_DEAD)) | ||
| 70 | return false; | ||
| 71 | |||
| 72 | return refcount_inc_not_zero(&pdsc->adminq_refcnt); | ||
| 73 | } | ||
| 74 | |||
| 66 | void pdsc_process_adminq(struct pdsc_qcq *qcq) | 75 | void pdsc_process_adminq(struct pdsc_qcq *qcq) |
| 67 | { | 76 | { |
| 68 | union pds_core_adminq_comp *comp; | 77 | union pds_core_adminq_comp *comp; |
| @@ -75,9 +84,9 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq) · 6 unmodified lines | |||
| 75 | int aq_work = 0; | 84 | int aq_work = 0; |
| 76 | int credits; | 85 | int credits; |
| 77 | 86 | ||
| 78 | /* Don't process AdminQ when shutting down */ | 87 | /* Don't process AdminQ when it's not up */ |
| 79 | if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { | 88 | if (!pdsc_adminq_inc_if_up(pdsc)) { |
| 80 | dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", | 89 | dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", |
| 81 | __func__); | 90 | __func__); |
| 82 | return; | 91 | return; |
| 83 | } | 92 | } |
| @@ -124,6 +133,7 @@ credits: · 40 unmodified lines | |||
| 124 | pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], | 133 | pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], |
| 125 | credits, | 134 | credits, |
| 126 | PDS_CORE_INTR_CRED_REARM); | 135 | PDS_CORE_INTR_CRED_REARM); |
| 136 | refcount_dec(&pdsc->adminq_refcnt); | ||
| 127 | } | 137 | } |
| 128 | 138 | ||
| 129 | void pdsc_work_thread(struct work_struct *work) | 139 | void pdsc_work_thread(struct work_struct *work) |
| @@ -135,18 +145,20 @@ void pdsc_work_thread(struct work_struct *work) · 5 unmodified lines | |||
| 135 | 145 | ||
| 136 | irqreturn_t pdsc_adminq_isr(int irq, void *data) | 146 | irqreturn_t pdsc_adminq_isr(int irq, void *data) |
| 137 | { | 147 | { |
| 138 | struct pdsc_qcq *qcq = data; | 148 | struct pdsc *pdsc = data; |
| 139 | struct pdsc *pdsc = qcq->pdsc; | 149 | struct pdsc_qcq *qcq; |
| 140 | 150 | ||
| 141 | /* Don't process AdminQ when shutting down */ | 151 | /* Don't process AdminQ when it's not up */ |
| 142 | if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { | 152 | if (!pdsc_adminq_inc_if_up(pdsc)) { |
| 143 | dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", | 153 | dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", |
| 144 | __func__); | 154 | __func__); |
| 145 | return IRQ_HANDLED; | 155 | return IRQ_HANDLED; |
| 146 | } | 156 | } |
| 147 | 157 | ||
| 158 | qcq = &pdsc->adminqcq; | ||
| 148 | queue_work(pdsc->wq, &qcq->work); | 159 | queue_work(pdsc->wq, &qcq->work); |
| 149 | pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); | 160 | pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); |
| 161 | refcount_dec(&pdsc->adminq_refcnt); | ||
| 150 | 162 | ||
| 151 | return IRQ_HANDLED; | 163 | return IRQ_HANDLED; |
| 152 | } | 164 | } |
| @@ -179,10 +191,16 @@ static int __pdsc_adminq_post(struct pdsc *pdsc, · 26 unmodified lines | |||
| 179 | 191 | ||
| 180 | /* Check that the FW is running */ | 192 | /* Check that the FW is running */ |
| 181 | if (!pdsc_is_fw_running(pdsc)) { | 193 | if (!pdsc_is_fw_running(pdsc)) { |
| 182 | u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | 194 | if (pdsc->info_regs) { |
| 183 | 195 | u8 fw_status = | |
| 184 | dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", | 196 | ioread8(&pdsc->info_regs->fw_status); |
| 185 | __func__, fw_status); | 197 | |
| 198 | dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", | ||
| 199 | __func__, fw_status); | ||
| 200 | } else { | ||
| 201 | dev_info(pdsc->dev, "%s: post failed - BARs not setup\n", | ||
| 202 | __func__); | ||
| 203 | } | ||
| 186 | ret = -ENXIO; | 204 | ret = -ENXIO; |
| 187 | 205 | ||
| 188 | goto err_out_unlock; | 206 | goto err_out_unlock; |
| @@ -230,6 +248,12 @@ int pdsc_adminq_post(struct pdsc *pdsc, · 41 unmodified lines | |||
| 230 | int err = 0; | 248 | int err = 0; |
| 231 | int index; | 249 | int index; |
| 232 | 250 | ||
| 251 | if (!pdsc_adminq_inc_if_up(pdsc)) { | ||
| 252 | dev_dbg(pdsc->dev, "%s: preventing adminq cmd %u\n", | ||
| 253 | __func__, cmd->opcode); | ||
| 254 | return -ENXIO; | ||
| 255 | } | ||
| 256 | |||
| 233 | wc.qcq = &pdsc->adminqcq; | 257 | wc.qcq = &pdsc->adminqcq; |
| 234 | index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); | 258 | index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); |
| 235 | if (index < 0) { | 259 | if (index < 0) { |
| @@ -248,10 +272,16 @@ int pdsc_adminq_post(struct pdsc *pdsc, · 12 unmodified lines | |||
| 248 | break; | 272 | break; |
| 249 | 273 | ||
| 250 | if (!pdsc_is_fw_running(pdsc)) { | 274 | if (!pdsc_is_fw_running(pdsc)) { |
| 251 | u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | 275 | if (pdsc->info_regs) { |
| 252 | 276 | u8 fw_status = | |
| 253 | dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", | 277 | ioread8(&pdsc->info_regs->fw_status); |
| 254 | __func__, fw_status); | 278 | |
| 279 | dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", | ||
| 280 | __func__, fw_status); | ||
| 281 | } else { | ||
| 282 | dev_dbg(pdsc->dev, "%s: post wait failed - BARs not setup\n", | ||
| 283 | __func__); | ||
| 284 | } | ||
| 255 | err = -ENXIO; | 285 | err = -ENXIO; |
| 256 | break; | 286 | break; |
| 257 | } | 287 | } |
| @@ -285,6 +315,8 @@ err_out: · 27 unmodified lines | |||
| 285 | queue_work(pdsc->wq, &pdsc->health_work); | 315 | queue_work(pdsc->wq, &pdsc->health_work); |
| 286 | } | 316 | } |
| 287 | 317 | ||
| 318 | refcount_dec(&pdsc->adminq_refcnt); | ||
| 319 | |||
| 288 | return err; | 320 | return err; |
| 289 | } | 321 | } |
| 290 | EXPORT_SYMBOL_GPL(pdsc_adminq_post); | 322 | EXPORT_SYMBOL_GPL(pdsc_adminq_post); |
| @@ -125,7 +125,7 @@ static int pdsc_qcq_intr_alloc(struct pdsc *pdsc, struct pdsc_qcq *qcq) · 124 unmodified lines | |||
| 125 | 125 | ||
| 126 | snprintf(name, sizeof(name), "%s-%d-%s", | 126 | snprintf(name, sizeof(name), "%s-%d-%s", |
| 127 | PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name); | 127 | PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name); |
| 128 | index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, qcq); | 128 | index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, pdsc); |
| 129 | if (index < 0) | 129 | if (index < 0) |
| 130 | return index; | 130 | return index; |
| 131 | qcq->intx = index; | 131 | qcq->intx = index; |
| @@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) · 272 unmodified lines | |||
| 404 | int numdescs; | 404 | int numdescs; |
| 405 | int err; | 405 | int err; |
| 406 | 406 | ||
| 407 | if (init) | 407 | err = pdsc_dev_init(pdsc); |
| 408 | err = pdsc_dev_init(pdsc); | ||
| 409 | else | ||
| 410 | err = pdsc_dev_reinit(pdsc); | ||
| 411 | if (err) | 408 | if (err) |
| 412 | return err; | 409 | return err; |
| 413 | 410 | ||
| @@ -450,6 +447,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) · 36 unmodified lines | |||
| 450 | pdsc_debugfs_add_viftype(pdsc); | 447 | pdsc_debugfs_add_viftype(pdsc); |
| 451 | } | 448 | } |
| 452 | 449 | ||
| 450 | refcount_set(&pdsc->adminq_refcnt, 1); | ||
| 453 | clear_bit(PDSC_S_FW_DEAD, &pdsc->state); | 451 | clear_bit(PDSC_S_FW_DEAD, &pdsc->state); |
| 454 | return 0; | 452 | return 0; |
| 455 | 453 | ||
| @@ -464,6 +462,8 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 8 unmodified lines | |||
| 464 | 462 | ||
| 465 | if (!pdsc->pdev->is_virtfn) | 463 | if (!pdsc->pdev->is_virtfn) |
| 466 | pdsc_devcmd_reset(pdsc); | 464 | pdsc_devcmd_reset(pdsc); |
| 465 | if (pdsc->adminqcq.work.func) | ||
| 466 | cancel_work_sync(&pdsc->adminqcq.work); | ||
| 467 | pdsc_qcq_free(pdsc, &pdsc->notifyqcq); | 467 | pdsc_qcq_free(pdsc, &pdsc->notifyqcq); |
| 468 | pdsc_qcq_free(pdsc, &pdsc->adminqcq); | 468 | pdsc_qcq_free(pdsc, &pdsc->adminqcq); |
| 469 | 469 | ||
| @@ -476,10 +476,9 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 6 unmodified lines | |||
| 476 | for (i = 0; i < pdsc->nintrs; i++) | 476 | for (i = 0; i < pdsc->nintrs; i++) |
| 477 | pdsc_intr_free(pdsc, i); | 477 | pdsc_intr_free(pdsc, i); |
| 478 | 478 | ||
| 479 | if (removing) { | 479 | kfree(pdsc->intr_info); |
| 480 | kfree(pdsc->intr_info); | 480 | pdsc->intr_info = NULL; |
| 481 | pdsc->intr_info = NULL; | 481 | pdsc->nintrs = 0; |
| 482 | } | ||
| 483 | } | 482 | } |
| 484 | 483 | ||
| 485 | if (pdsc->kern_dbpage) { | 484 | if (pdsc->kern_dbpage) { |
| @@ -487,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 1 unmodified line | |||
| 487 | pdsc->kern_dbpage = NULL; | 486 | pdsc->kern_dbpage = NULL; |
| 488 | } | 487 | } |
| 489 | 488 | ||
| 489 | pci_free_irq_vectors(pdsc->pdev); | ||
| 490 | set_bit(PDSC_S_FW_DEAD, &pdsc->state); | 490 | set_bit(PDSC_S_FW_DEAD, &pdsc->state); |
| 491 | } | 491 | } |
| 492 | 492 | ||
| @@ -512,6 +512,24 @@ void pdsc_stop(struct pdsc *pdsc) · 19 unmodified lines | |||
| 512 | PDS_CORE_INTR_MASK_SET); | 512 | PDS_CORE_INTR_MASK_SET); |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | static void pdsc_adminq_wait_and_dec_once_unused(struct pdsc *pdsc) | ||
| 516 | { | ||
| 517 | /* The driver initializes the adminq_refcnt to 1 when the adminq is | ||
| 518 | * allocated and ready for use. Other users/requesters will increment | ||
| 519 | * the refcnt while in use. If the refcnt is down to 1 then the adminq | ||
| 520 | * is not in use and the refcnt can be cleared and adminq freed. Before | ||
| 521 | * calling this function the driver will set PDSC_S_FW_DEAD, which | ||
| 522 | * prevent subsequent attempts to use the adminq and increment the | ||
| 523 | * refcnt to fail. This guarantees that this function will eventually | ||
| 524 | * exit. | ||
| 525 | */ | ||
| 526 | while (!refcount_dec_if_one(&pdsc->adminq_refcnt)) { | ||
| 527 | dev_dbg_ratelimited(pdsc->dev, "%s: adminq in use\n", | ||
| 528 | __func__); | ||
| 529 | cpu_relax(); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 515 | void pdsc_fw_down(struct pdsc *pdsc) | 533 | void pdsc_fw_down(struct pdsc *pdsc) |
| 516 | { | 534 | { |
| 517 | union pds_core_notifyq_comp reset_event = { | 535 | union pds_core_notifyq_comp reset_event = { |
| @@ -527,6 +545,8 @@ void pdsc_fw_down(struct pdsc *pdsc) · 9 unmodified lines | |||
| 527 | if (pdsc->pdev->is_virtfn) | 545 | if (pdsc->pdev->is_virtfn) |
| 528 | return; | 546 | return; |
| 529 | 547 | ||
| 548 | pdsc_adminq_wait_and_dec_once_unused(pdsc); | ||
| 549 | |||
| 530 | /* Notify clients of fw_down */ | 550 | /* Notify clients of fw_down */ |
| 531 | if (pdsc->fw_reporter) | 551 | if (pdsc->fw_reporter) |
| 532 | devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); | 552 | devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); |
| @@ -577,7 +597,13 @@ err_out: · 44 unmodified lines | |||
| 577 | 597 | ||
| 578 | static void pdsc_check_pci_health(struct pdsc *pdsc) | 598 | static void pdsc_check_pci_health(struct pdsc *pdsc) |
| 579 | { | 599 | { |
| 580 | u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | 600 | u8 fw_status; |
| 601 | |||
| 602 | /* some sort of teardown already in progress */ | ||
| 603 | if (!pdsc->info_regs) | ||
| 604 | return; | ||
| 605 | |||
| 606 | fw_status = ioread8(&pdsc->info_regs->fw_status); | ||
| 581 | 607 | ||
| 582 | /* is PCI broken? */ | 608 | /* is PCI broken? */ |
| 583 | if (fw_status != PDS_RC_BAD_PCI) | 609 | if (fw_status != PDS_RC_BAD_PCI) |
| @@ -184,6 +184,7 @@ struct pdsc { · 183 unmodified lines | |||
| 184 | struct mutex devcmd_lock; /* lock for dev_cmd operations */ | 184 | struct mutex devcmd_lock; /* lock for dev_cmd operations */ |
| 185 | struct mutex config_lock; /* lock for configuration operations */ | 185 | struct mutex config_lock; /* lock for configuration operations */ |
| 186 | spinlock_t adminq_lock; /* lock for adminq operations */ | 186 | spinlock_t adminq_lock; /* lock for adminq operations */ |
| 187 | refcount_t adminq_refcnt; | ||
| 187 | struct pds_core_dev_info_regs __iomem *info_regs; | 188 | struct pds_core_dev_info_regs __iomem *info_regs; |
| 188 | struct pds_core_dev_cmd_regs __iomem *cmd_regs; | 189 | struct pds_core_dev_cmd_regs __iomem *cmd_regs; |
| 189 | struct pds_core_intr __iomem *intr_ctrl; | 190 | struct pds_core_intr __iomem *intr_ctrl; |
| @@ -280,7 +281,6 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, · 90 unmodified lines | |||
| 280 | union pds_core_dev_comp *comp, int max_seconds); | 281 | union pds_core_dev_comp *comp, int max_seconds); |
| 281 | int pdsc_devcmd_init(struct pdsc *pdsc); | 282 | int pdsc_devcmd_init(struct pdsc *pdsc); |
| 282 | int pdsc_devcmd_reset(struct pdsc *pdsc); | 283 | int pdsc_devcmd_reset(struct pdsc *pdsc); |
| 283 | int pdsc_dev_reinit(struct pdsc *pdsc); | ||
| 284 | int pdsc_dev_init(struct pdsc *pdsc); | 284 | int pdsc_dev_init(struct pdsc *pdsc); |
| 285 | 285 | ||
| 286 | void pdsc_reset_prepare(struct pci_dev *pdev); | 286 | void pdsc_reset_prepare(struct pci_dev *pdev); |
| @@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity); · 63 unmodified lines | |||
| 64 | 64 | ||
| 65 | void pdsc_debugfs_add_ident(struct pdsc *pdsc) | 65 | void pdsc_debugfs_add_ident(struct pdsc *pdsc) |
| 66 | { | 66 | { |
| 67 | /* This file will already exist in the reset flow */ | ||
| 68 | if (debugfs_lookup("identity", pdsc->dentry)) | ||
| 69 | return; | ||
| 70 | |||
| 67 | debugfs_create_file("identity", 0400, pdsc->dentry, | 71 | debugfs_create_file("identity", 0400, pdsc->dentry, |
| 68 | pdsc, &identity_fops); | 72 | pdsc, &identity_fops); |
| 69 | } | 73 | } |
| @@ -57,6 +57,9 @@ int pdsc_err_to_errno(enum pds_core_status_code code) · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | bool pdsc_is_fw_running(struct pdsc *pdsc) | 58 | bool pdsc_is_fw_running(struct pdsc *pdsc) |
| 59 | { | 59 | { |
| 60 | if (!pdsc->info_regs) | ||
| 61 | return false; | ||
| 62 | |||
| 60 | pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); | 63 | pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); |
| 61 | pdsc->last_fw_time = jiffies; | 64 | pdsc->last_fw_time = jiffies; |
| 62 | pdsc->last_hb = ioread32(&pdsc->info_regs->fw_heartbeat); | 65 | pdsc->last_hb = ioread32(&pdsc->info_regs->fw_heartbeat); |
| @@ -182,13 +185,17 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, · 119 unmodified lines | |||
| 182 | { | 185 | { |
| 183 | int err; | 186 | int err; |
| 184 | 187 | ||
| 188 | if (!pdsc->cmd_regs) | ||
| 189 | return -ENXIO; | ||
| 190 | |||
| 185 | memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); | 191 | memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); |
| 186 | pdsc_devcmd_dbell(pdsc); | 192 | pdsc_devcmd_dbell(pdsc); |
| 187 | err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); | 193 | err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); |
| 188 | memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); | ||
| 189 | 194 | ||
| 190 | if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) | 195 | if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) |
| 191 | queue_work(pdsc->wq, &pdsc->health_work); | 196 | queue_work(pdsc->wq, &pdsc->health_work); |
| 197 | else | ||
| 198 | memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); | ||
| 192 | 199 | ||
| 193 | return err; | 200 | return err; |
| 194 | } | 201 | } |
| @@ -309,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc) · 114 unmodified lines | |||
| 309 | return 0; | 316 | return 0; |
| 310 | } | 317 | } |
| 311 | 318 | ||
| 312 | int pdsc_dev_reinit(struct pdsc *pdsc) | ||
| 313 | { | ||
| 314 | pdsc_init_devinfo(pdsc); | ||
| 315 | |||
| 316 | return pdsc_identify(pdsc); | ||
| 317 | } | ||
| 318 | |||
| 319 | int pdsc_dev_init(struct pdsc *pdsc) | 319 | int pdsc_dev_init(struct pdsc *pdsc) |
| 320 | { | 320 | { |
| 321 | unsigned int nintrs; | 321 | unsigned int nintrs; |
| @@ -111,7 +111,8 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | mutex_lock(&pdsc->devcmd_lock); | 112 | mutex_lock(&pdsc->devcmd_lock); |
| 113 | err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2); | 113 | err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2); |
| 114 | memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); | 114 | if (!err) |
| 115 | memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); | ||
| 115 | mutex_unlock(&pdsc->devcmd_lock); | 116 | mutex_unlock(&pdsc->devcmd_lock); |
| 116 | if (err && err != -EIO) | 117 | if (err && err != -EIO) |
| 117 | return err; | 118 | return err; |
| @@ -107,6 +107,9 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw, · 106 unmodified lines | |||
| 107 | 107 | ||
| 108 | dev_info(pdsc->dev, "Installing firmware\n"); | 108 | dev_info(pdsc->dev, "Installing firmware\n"); |
| 109 | 109 | ||
| 110 | if (!pdsc->cmd_regs) | ||
| 111 | return -ENXIO; | ||
| 112 | |||
| 110 | dl = priv_to_devlink(pdsc); | 113 | dl = priv_to_devlink(pdsc); |
| 111 | devlink_flash_update_status_notify(dl, "Preparing to flash", | 114 | devlink_flash_update_status_notify(dl, "Preparing to flash", |
| 112 | NULL, 0, 0); | 115 | NULL, 0, 0); |
| @@ -37,6 +37,11 @@ static void pdsc_unmap_bars(struct pdsc *pdsc) · 36 unmodified lines | |||
| 37 | struct pdsc_dev_bar *bars = pdsc->bars; | 37 | struct pdsc_dev_bar *bars = pdsc->bars; |
| 38 | unsigned int i; | 38 | unsigned int i; |
| 39 | 39 | ||
| 40 | pdsc->info_regs = NULL; | ||
| 41 | pdsc->cmd_regs = NULL; | ||
| 42 | pdsc->intr_status = NULL; | ||
| 43 | pdsc->intr_ctrl = NULL; | ||
| 44 | |||
| 40 | for (i = 0; i < PDS_CORE_BARS_MAX; i++) { | 45 | for (i = 0; i < PDS_CORE_BARS_MAX; i++) { |
| 41 | if (bars[i].vaddr) | 46 | if (bars[i].vaddr) |
| 42 | pci_iounmap(pdsc->pdev, bars[i].vaddr); | 47 | pci_iounmap(pdsc->pdev, bars[i].vaddr); |
| @@ -293,7 +298,7 @@ err_out_stop: · 250 unmodified lines | |||
| 293 | err_out_teardown: | 298 | err_out_teardown: |
| 294 | pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); | 299 | pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); |
| 295 | err_out_unmap_bars: | 300 | err_out_unmap_bars: |
| 296 | del_timer_sync(&pdsc->wdtimer); | 301 | timer_shutdown_sync(&pdsc->wdtimer); |
| 297 | if (pdsc->wq) | 302 | if (pdsc->wq) |
| 298 | destroy_workqueue(pdsc->wq); | 303 | destroy_workqueue(pdsc->wq); |
| 299 | mutex_destroy(&pdsc->config_lock); | 304 | mutex_destroy(&pdsc->config_lock); |
| @@ -420,7 +425,7 @@ static void pdsc_remove(struct pci_dev *pdev) · 120 unmodified lines | |||
| 420 | */ | 425 | */ |
| 421 | pdsc_sriov_configure(pdev, 0); | 426 | pdsc_sriov_configure(pdev, 0); |
| 422 | 427 | ||
| 423 | del_timer_sync(&pdsc->wdtimer); | 428 | timer_shutdown_sync(&pdsc->wdtimer); |
| 424 | if (pdsc->wq) | 429 | if (pdsc->wq) |
| 425 | destroy_workqueue(pdsc->wq); | 430 | destroy_workqueue(pdsc->wq); |
| 426 | 431 | ||
| @@ -433,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev) · 6 unmodified lines | |||
| 433 | mutex_destroy(&pdsc->config_lock); | 438 | mutex_destroy(&pdsc->config_lock); |
| 434 | mutex_destroy(&pdsc->devcmd_lock); | 439 | mutex_destroy(&pdsc->devcmd_lock); |
| 435 | 440 | ||
| 436 | pci_free_irq_vectors(pdev); | ||
| 437 | pdsc_unmap_bars(pdsc); | 441 | pdsc_unmap_bars(pdsc); |
| 438 | pci_release_regions(pdev); | 442 | pci_release_regions(pdev); |
| 439 | } | 443 | } |
| @@ -445,13 +449,26 @@ static void pdsc_remove(struct pci_dev *pdev) · 5 unmodified lines | |||
| 445 | devlink_free(dl); | 449 | devlink_free(dl); |
| 446 | } | 450 | } |
| 447 | 451 | ||
| 452 | static void pdsc_stop_health_thread(struct pdsc *pdsc) | ||
| 453 | { | ||
| 454 | timer_shutdown_sync(&pdsc->wdtimer); | ||
| 455 | if (pdsc->health_work.func) | ||
| 456 | cancel_work_sync(&pdsc->health_work); | ||
| 457 | } | ||
| 458 | |||
| 459 | static void pdsc_restart_health_thread(struct pdsc *pdsc) | ||
| 460 | { | ||
| 461 | timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0); | ||
| 462 | mod_timer(&pdsc->wdtimer, jiffies + 1); | ||
| 463 | } | ||
| 464 | |||
| 448 | void pdsc_reset_prepare(struct pci_dev *pdev) | 465 | void pdsc_reset_prepare(struct pci_dev *pdev) |
| 449 | { | 466 | { |
| 450 | struct pdsc *pdsc = pci_get_drvdata(pdev); | 467 | struct pdsc *pdsc = pci_get_drvdata(pdev); |
| 451 | 468 | ||
| 469 | pdsc_stop_health_thread(pdsc); | ||
| 452 | pdsc_fw_down(pdsc); | 470 | pdsc_fw_down(pdsc); |
| 453 | 471 | ||
| 454 | pci_free_irq_vectors(pdev); | ||
| 455 | pdsc_unmap_bars(pdsc); | 472 | pdsc_unmap_bars(pdsc); |
| 456 | pci_release_regions(pdev); | 473 | pci_release_regions(pdev); |
| 457 | pci_disable_device(pdev); | 474 | pci_disable_device(pdev); |
| @@ -486,6 +503,7 @@ void pdsc_reset_done(struct pci_dev *pdev) · 28 unmodified lines | |||
| 486 | } | 503 | } |
| 487 | 504 | ||
| 488 | pdsc_fw_up(pdsc); | 505 | pdsc_fw_up(pdsc); |
| 506 | pdsc_restart_health_thread(pdsc); | ||
| 489 | } | 507 | } |
| 490 | 508 | ||
| 491 | static const struct pci_error_handlers pdsc_err_handler = { | 509 | static const struct pci_error_handlers pdsc_err_handler = { |
| @@ -993,7 +993,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic) · 992 unmodified lines | |||
| 993 | return 0; | 993 | return 0; |
| 994 | 994 | ||
| 995 | err_exit_hwts_rx: | 995 | err_exit_hwts_rx: |
| 996 | aq_ring_free(&aq_ptp->hwts_rx); | 996 | aq_ring_hwts_rx_free(&aq_ptp->hwts_rx); |
| 997 | err_exit_ptp_rx: | 997 | err_exit_ptp_rx: |
| 998 | aq_ring_free(&aq_ptp->ptp_rx); | 998 | aq_ring_free(&aq_ptp->ptp_rx); |
| 999 | err_exit_ptp_tx: | 999 | err_exit_ptp_tx: |
| @@ -1011,7 +1011,7 @@ void aq_ptp_ring_free(struct aq_nic_s *aq_nic) · 11 unmodified lines | |||
| 1011 | 1011 | ||
| 1012 | aq_ring_free(&aq_ptp->ptp_tx); | 1012 | aq_ring_free(&aq_ptp->ptp_tx); |
| 1013 | aq_ring_free(&aq_ptp->ptp_rx); | 1013 | aq_ring_free(&aq_ptp->ptp_rx); |
| 1014 | aq_ring_free(&aq_ptp->hwts_rx); | 1014 | aq_ring_hwts_rx_free(&aq_ptp->hwts_rx); |
| 1015 | 1015 | ||
| 1016 | aq_ptp_skb_ring_release(&aq_ptp->skb_ring); | 1016 | aq_ptp_skb_ring_release(&aq_ptp->skb_ring); |
| 1017 | } | 1017 | } |
| @@ -919,6 +919,19 @@ void aq_ring_free(struct aq_ring_s *self) · 918 unmodified lines | |||
| 919 | } | 919 | } |
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | void aq_ring_hwts_rx_free(struct aq_ring_s *self) | ||
| 923 | { | ||
| 924 | if (!self) | ||
| 925 | return; | ||
| 926 | |||
| 927 | if (self->dx_ring) { | ||
| 928 | dma_free_coherent(aq_nic_get_dev(self->aq_nic), | ||
| 929 | self->size * self->dx_size + AQ_CFG_RXDS_DEF, | ||
| 930 | self->dx_ring, self->dx_ring_pa); | ||
| 931 | self->dx_ring = NULL; | ||
| 932 | } | ||
| 933 | } | ||
| 934 | |||
| 922 | unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) | 935 | unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) |
| 923 | { | 936 | { |
| 924 | unsigned int count; | 937 | unsigned int count; |
| @@ -210,6 +210,7 @@ int aq_ring_rx_fill(struct aq_ring_s *self); · 209 unmodified lines | |||
| 210 | int aq_ring_hwts_rx_alloc(struct aq_ring_s *self, | 210 | int aq_ring_hwts_rx_alloc(struct aq_ring_s *self, |
| 211 | struct aq_nic_s *aq_nic, unsigned int idx, | 211 | struct aq_nic_s *aq_nic, unsigned int idx, |
| 212 | unsigned int size, unsigned int dx_size); | 212 | unsigned int size, unsigned int dx_size); |
| 213 | void aq_ring_hwts_rx_free(struct aq_ring_s *self); | ||
| 213 | void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic); | 214 | void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic); |
| 214 | 215 | ||
| 215 | unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data); | 216 | unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data); |
| @@ -793,5 +793,6 @@ static struct platform_driver bcm4908_enet_driver = { · 792 unmodified lines | |||
| 793 | }; | 793 | }; |
| 794 | module_platform_driver(bcm4908_enet_driver); | 794 | module_platform_driver(bcm4908_enet_driver); |
| 795 | 795 | ||
| 796 | MODULE_DESCRIPTION("Broadcom BCM4908 Gigabit Ethernet driver"); | ||
| 796 | MODULE_LICENSE("GPL v2"); | 797 | MODULE_LICENSE("GPL v2"); |
| 797 | MODULE_DEVICE_TABLE(of, bcm4908_enet_of_match); | 798 | MODULE_DEVICE_TABLE(of, bcm4908_enet_of_match); |
| @@ -260,4 +260,5 @@ void bcma_mdio_mii_unregister(struct mii_bus *mii_bus) · 259 unmodified lines | |||
| 260 | EXPORT_SYMBOL_GPL(bcma_mdio_mii_unregister); | 260 | EXPORT_SYMBOL_GPL(bcma_mdio_mii_unregister); |
| 261 | 261 | ||
| 262 | MODULE_AUTHOR("Rafał Miłecki"); | 262 | MODULE_AUTHOR("Rafał Miłecki"); |
| 263 | MODULE_DESCRIPTION("Broadcom iProc GBit BCMA MDIO helpers"); | ||
| 263 | MODULE_LICENSE("GPL"); | 264 | MODULE_LICENSE("GPL"); |
| @@ -362,4 +362,5 @@ module_init(bgmac_init) · 361 unmodified lines | |||
| 362 | module_exit(bgmac_exit) | 362 | module_exit(bgmac_exit) |
| 363 | 363 | ||
| 364 | MODULE_AUTHOR("Rafał Miłecki"); | 364 | MODULE_AUTHOR("Rafał Miłecki"); |
| 365 | MODULE_DESCRIPTION("Broadcom iProc GBit BCMA interface driver"); | ||
| 365 | MODULE_LICENSE("GPL"); | 366 | MODULE_LICENSE("GPL"); |
| @@ -298,4 +298,5 @@ static struct platform_driver bgmac_enet_driver = { · 297 unmodified lines | |||
| 298 | }; | 298 | }; |
| 299 | 299 | ||
| 300 | module_platform_driver(bgmac_enet_driver); | 300 | module_platform_driver(bgmac_enet_driver); |
| 301 | MODULE_DESCRIPTION("Broadcom iProc GBit platform interface driver"); | ||
| 301 | MODULE_LICENSE("GPL"); | 302 | MODULE_LICENSE("GPL"); |
| @@ -1626,4 +1626,5 @@ int bgmac_enet_resume(struct bgmac *bgmac) · 1625 unmodified lines | |||
| 1626 | EXPORT_SYMBOL_GPL(bgmac_enet_resume); | 1626 | EXPORT_SYMBOL_GPL(bgmac_enet_resume); |
| 1627 | 1627 | ||
| 1628 | MODULE_AUTHOR("Rafał Miłecki"); | 1628 | MODULE_AUTHOR("Rafał Miłecki"); |
| 1629 | MODULE_DESCRIPTION("Broadcom iProc GBit driver"); | ||
| 1629 | MODULE_LICENSE("GPL"); | 1630 | MODULE_LICENSE("GPL"); |
| @@ -3817,7 +3817,7 @@ static int bnxt_alloc_cp_rings(struct bnxt *bp) · 3816 unmodified lines | |||
| 3817 | { | 3817 | { |
| 3818 | bool sh = !!(bp->flags & BNXT_FLAG_SHARED_RINGS); | 3818 | bool sh = !!(bp->flags & BNXT_FLAG_SHARED_RINGS); |
| 3819 | int i, j, rc, ulp_base_vec, ulp_msix; | 3819 | int i, j, rc, ulp_base_vec, ulp_msix; |
| 3820 | int tcs = netdev_get_num_tc(bp->dev); | 3820 | int tcs = bp->num_tc; |
| 3821 | 3821 | ||
| 3822 | if (!tcs) | 3822 | if (!tcs) |
| 3823 | tcs = 1; | 3823 | tcs = 1; |
| @@ -5935,8 +5935,12 @@ static u16 bnxt_get_max_rss_ring(struct bnxt *bp) · 2111 unmodified lines | |||
| 5935 | 5935 | ||
| 5936 | int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings) | 5936 | int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings) |
| 5937 | { | 5937 | { |
| 5938 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) | 5938 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { |
| 5939 | return DIV_ROUND_UP(rx_rings, BNXT_RSS_TABLE_ENTRIES_P5); | 5939 | if (!rx_rings) |
| 5940 | return 0; | ||
| 5941 | return bnxt_calc_nr_ring_pages(rx_rings - 1, | ||
| 5942 | BNXT_RSS_TABLE_ENTRIES_P5); | ||
| 5943 | } | ||
| 5940 | if (BNXT_CHIP_TYPE_NITRO_A0(bp)) | 5944 | if (BNXT_CHIP_TYPE_NITRO_A0(bp)) |
| 5941 | return 2; | 5945 | return 2; |
| 5942 | return 1; | 5946 | return 1; |
| @@ -6926,7 +6930,7 @@ static int bnxt_hwrm_get_rings(struct bnxt *bp) · 983 unmodified lines | |||
| 6926 | if (cp < (rx + tx)) { | 6930 | if (cp < (rx + tx)) { |
| 6927 | rc = __bnxt_trim_rings(bp, &rx, &tx, cp, false); | 6931 | rc = __bnxt_trim_rings(bp, &rx, &tx, cp, false); |
| 6928 | if (rc) | 6932 | if (rc) |
| 6929 | return rc; | 6933 | goto get_rings_exit; |
| 6930 | if (bp->flags & BNXT_FLAG_AGG_RINGS) | 6934 | if (bp->flags & BNXT_FLAG_AGG_RINGS) |
| 6931 | rx <<= 1; | 6935 | rx <<= 1; |
| 6932 | hw_resc->resv_rx_rings = rx; | 6936 | hw_resc->resv_rx_rings = rx; |
| @@ -6938,8 +6942,9 @@ static int bnxt_hwrm_get_rings(struct bnxt *bp) · 5 unmodified lines | |||
| 6938 | hw_resc->resv_cp_rings = cp; | 6942 | hw_resc->resv_cp_rings = cp; |
| 6939 | hw_resc->resv_stat_ctxs = stats; | 6943 | hw_resc->resv_stat_ctxs = stats; |
| 6940 | } | 6944 | } |
| 6945 | get_rings_exit: | ||
| 6941 | hwrm_req_drop(bp, req); | 6946 | hwrm_req_drop(bp, req); |
| 6942 | return 0; | 6947 | return rc; |
| 6943 | } | 6948 | } |
| 6944 | 6949 | ||
| 6945 | int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings) | 6950 | int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings) |
| @@ -7000,10 +7005,11 @@ __bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, · 54 unmodified lines | |||
| 7000 | 7005 | ||
| 7001 | req->num_rx_rings = cpu_to_le16(rx_rings); | 7006 | req->num_rx_rings = cpu_to_le16(rx_rings); |
| 7002 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { | 7007 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { |
| 7008 | u16 rss_ctx = bnxt_get_nr_rss_ctxs(bp, ring_grps); | ||
| 7009 | |||
| 7003 | req->num_cmpl_rings = cpu_to_le16(tx_rings + ring_grps); | 7010 | req->num_cmpl_rings = cpu_to_le16(tx_rings + ring_grps); |
| 7004 | req->num_msix = cpu_to_le16(cp_rings); | 7011 | req->num_msix = cpu_to_le16(cp_rings); |
| 7005 | req->num_rsscos_ctxs = | 7012 | req->num_rsscos_ctxs = cpu_to_le16(rss_ctx); |
| 7006 | cpu_to_le16(DIV_ROUND_UP(ring_grps, 64)); | ||
| 7007 | } else { | 7013 | } else { |
| 7008 | req->num_cmpl_rings = cpu_to_le16(cp_rings); | 7014 | req->num_cmpl_rings = cpu_to_le16(cp_rings); |
| 7009 | req->num_hw_ring_grps = cpu_to_le16(ring_grps); | 7015 | req->num_hw_ring_grps = cpu_to_le16(ring_grps); |
| @@ -7050,8 +7056,10 @@ __bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings, · 40 unmodified lines | |||
| 7050 | req->num_tx_rings = cpu_to_le16(tx_rings); | 7056 | req->num_tx_rings = cpu_to_le16(tx_rings); |
| 7051 | req->num_rx_rings = cpu_to_le16(rx_rings); | 7057 | req->num_rx_rings = cpu_to_le16(rx_rings); |
| 7052 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { | 7058 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { |
| 7059 | u16 rss_ctx = bnxt_get_nr_rss_ctxs(bp, ring_grps); | ||
| 7060 | |||
| 7053 | req->num_cmpl_rings = cpu_to_le16(tx_rings + ring_grps); | 7061 | req->num_cmpl_rings = cpu_to_le16(tx_rings + ring_grps); |
| 7054 | req->num_rsscos_ctxs = cpu_to_le16(DIV_ROUND_UP(ring_grps, 64)); | 7062 | req->num_rsscos_ctxs = cpu_to_le16(rss_ctx); |
| 7055 | } else { | 7063 | } else { |
| 7056 | req->num_cmpl_rings = cpu_to_le16(cp_rings); | 7064 | req->num_cmpl_rings = cpu_to_le16(cp_rings); |
| 7057 | req->num_hw_ring_grps = cpu_to_le16(ring_grps); | 7065 | req->num_hw_ring_grps = cpu_to_le16(ring_grps); |
| @@ -9938,7 +9946,7 @@ static int __bnxt_num_tx_to_cp(struct bnxt *bp, int tx, int tx_sets, int tx_xdp) · 2880 unmodified lines | |||
| 9938 | 9946 | ||
| 9939 | int bnxt_num_tx_to_cp(struct bnxt *bp, int tx) | 9947 | int bnxt_num_tx_to_cp(struct bnxt *bp, int tx) |
| 9940 | { | 9948 | { |
| 9941 | int tcs = netdev_get_num_tc(bp->dev); | 9949 | int tcs = bp->num_tc; |
| 9942 | 9950 | ||
| 9943 | if (!tcs) | 9951 | if (!tcs) |
| 9944 | tcs = 1; | 9952 | tcs = 1; |
| @@ -9947,7 +9955,7 @@ int bnxt_num_tx_to_cp(struct bnxt *bp, int tx) · 2 unmodified lines | |||
| 9947 | 9955 | ||
| 9948 | static int bnxt_num_cp_to_tx(struct bnxt *bp, int tx_cp) | 9956 | static int bnxt_num_cp_to_tx(struct bnxt *bp, int tx_cp) |
| 9949 | { | 9957 | { |
| 9950 | int tcs = netdev_get_num_tc(bp->dev); | 9958 | int tcs = bp->num_tc; |
| 9951 | 9959 | ||
| 9952 | return (tx_cp - bp->tx_nr_rings_xdp) * tcs + | 9960 | return (tx_cp - bp->tx_nr_rings_xdp) * tcs + |
| 9953 | bp->tx_nr_rings_xdp; | 9961 | bp->tx_nr_rings_xdp; |
| @@ -9977,7 +9985,7 @@ static void bnxt_setup_msix(struct bnxt *bp) · 23 unmodified lines | |||
| 9977 | struct net_device *dev = bp->dev; | 9985 | struct net_device *dev = bp->dev; |
| 9978 | int tcs, i; | 9986 | int tcs, i; |
| 9979 | 9987 | ||
| 9980 | tcs = netdev_get_num_tc(dev); | 9988 | tcs = bp->num_tc; |
| 9981 | if (tcs) { | 9989 | if (tcs) { |
| 9982 | int i, off, count; | 9990 | int i, off, count; |
| 9983 | 9991 | ||
| @@ -10009,8 +10017,10 @@ static void bnxt_setup_inta(struct bnxt *bp) · 25 unmodified lines | |||
| 10009 | { | 10017 | { |
| 10010 | const int len = sizeof(bp->irq_tbl[0].name); | 10018 | const int len = sizeof(bp->irq_tbl[0].name); |
| 10011 | 10019 | ||
| 10012 | if (netdev_get_num_tc(bp->dev)) | 10020 | if (bp->num_tc) { |
| 10013 | netdev_reset_tc(bp->dev); | 10021 | netdev_reset_tc(bp->dev); |
| 10022 | bp->num_tc = 0; | ||
| 10023 | } | ||
| 10014 | 10024 | ||
| 10015 | snprintf(bp->irq_tbl[0].name, len, "%s-%s-%d", bp->dev->name, "TxRx", | 10025 | snprintf(bp->irq_tbl[0].name, len, "%s-%s-%d", bp->dev->name, "TxRx", |
| 10016 | 0); | 10026 | 0); |
| @@ -10236,8 +10246,8 @@ static void bnxt_clear_int_mode(struct bnxt *bp) · 219 unmodified lines | |||
| 10236 | 10246 | ||
| 10237 | int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init) | 10247 | int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init) |
| 10238 | { | 10248 | { |
| 10239 | int tcs = netdev_get_num_tc(bp->dev); | ||
| 10240 | bool irq_cleared = false; | 10249 | bool irq_cleared = false; |
| 10250 | int tcs = bp->num_tc; | ||
| 10241 | int rc; | 10251 | int rc; |
| 10242 | 10252 | ||
| 10243 | if (!bnxt_need_reserve_rings(bp)) | 10253 | if (!bnxt_need_reserve_rings(bp)) |
| @@ -10263,6 +10273,7 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init) · 19 unmodified lines | |||
| 10263 | bp->tx_nr_rings - bp->tx_nr_rings_xdp)) { | 10273 | bp->tx_nr_rings - bp->tx_nr_rings_xdp)) { |
| 10264 | netdev_err(bp->dev, "tx ring reservation failure\n"); | 10274 | netdev_err(bp->dev, "tx ring reservation failure\n"); |
| 10265 | netdev_reset_tc(bp->dev); | 10275 | netdev_reset_tc(bp->dev); |
| 10276 | bp->num_tc = 0; | ||
| 10266 | if (bp->tx_nr_rings_xdp) | 10277 | if (bp->tx_nr_rings_xdp) |
| 10267 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings_xdp; | 10278 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings_xdp; |
| 10268 | else | 10279 | else |
| @@ -11564,10 +11575,12 @@ int bnxt_half_open_nic(struct bnxt *bp) · 1295 unmodified lines | |||
| 11564 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); | 11575 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); |
| 11565 | goto half_open_err; | 11576 | goto half_open_err; |
| 11566 | } | 11577 | } |
| 11578 | bnxt_init_napi(bp); | ||
| 11567 | set_bit(BNXT_STATE_HALF_OPEN, &bp->state); | 11579 | set_bit(BNXT_STATE_HALF_OPEN, &bp->state); |
| 11568 | rc = bnxt_init_nic(bp, true); | 11580 | rc = bnxt_init_nic(bp, true); |
| 11569 | if (rc) { | 11581 | if (rc) { |
| 11570 | clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); | 11582 | clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); |
| 11583 | bnxt_del_napi(bp); | ||
| 11571 | netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); | 11584 | netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); |
| 11572 | goto half_open_err; | 11585 | goto half_open_err; |
| 11573 | } | 11586 | } |
| @@ -11586,6 +11599,7 @@ half_open_err: · 12 unmodified lines | |||
| 11586 | void bnxt_half_close_nic(struct bnxt *bp) | 11599 | void bnxt_half_close_nic(struct bnxt *bp) |
| 11587 | { | 11600 | { |
| 11588 | bnxt_hwrm_resource_free(bp, false, true); | 11601 | bnxt_hwrm_resource_free(bp, false, true); |
| 11602 | bnxt_del_napi(bp); | ||
| 11589 | bnxt_free_skbs(bp); | 11603 | bnxt_free_skbs(bp); |
| 11590 | bnxt_free_mem(bp, true); | 11604 | bnxt_free_mem(bp, true); |
| 11591 | clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); | 11605 | clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); |
| @@ -13232,6 +13246,11 @@ static int bnxt_fw_init_one_p1(struct bnxt *bp) · 1640 unmodified lines | |||
| 13232 | 13246 | ||
| 13233 | bp->fw_cap = 0; | 13247 | bp->fw_cap = 0; |
| 13234 | rc = bnxt_hwrm_ver_get(bp); | 13248 | rc = bnxt_hwrm_ver_get(bp); |
| 13249 | /* FW may be unresponsive after FLR. FLR must complete within 100 msec | ||
| 13250 | * so wait before continuing with recovery. | ||
| 13251 | */ | ||
| 13252 | if (rc) | ||
| 13253 | msleep(100); | ||
| 13235 | bnxt_try_map_fw_health_reg(bp); | 13254 | bnxt_try_map_fw_health_reg(bp); |
| 13236 | if (rc) { | 13255 | if (rc) { |
| 13237 | rc = bnxt_try_recover_fw(bp); | 13256 | rc = bnxt_try_recover_fw(bp); |
| @@ -13784,7 +13803,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc) · 546 unmodified lines | |||
| 13784 | return -EINVAL; | 13803 | return -EINVAL; |
| 13785 | } | 13804 | } |
| 13786 | 13805 | ||
| 13787 | if (netdev_get_num_tc(dev) == tc) | 13806 | if (bp->num_tc == tc) |
| 13788 | return 0; | 13807 | return 0; |
| 13789 | 13808 | ||
| 13790 | if (bp->flags & BNXT_FLAG_SHARED_RINGS) | 13809 | if (bp->flags & BNXT_FLAG_SHARED_RINGS) |
| @@ -13802,9 +13821,11 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc) · 11 unmodified lines | |||
| 13802 | if (tc) { | 13821 | if (tc) { |
| 13803 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc; | 13822 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc; |
| 13804 | netdev_set_num_tc(dev, tc); | 13823 | netdev_set_num_tc(dev, tc); |
| 13824 | bp->num_tc = tc; | ||
| 13805 | } else { | 13825 | } else { |
| 13806 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc; | 13826 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc; |
| 13807 | netdev_reset_tc(dev); | 13827 | netdev_reset_tc(dev); |
| 13828 | bp->num_tc = 0; | ||
| 13808 | } | 13829 | } |
| 13809 | bp->tx_nr_rings += bp->tx_nr_rings_xdp; | 13830 | bp->tx_nr_rings += bp->tx_nr_rings_xdp; |
| 13810 | tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings); | 13831 | tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings); |
| @@ -2225,6 +2225,7 @@ struct bnxt { · 2224 unmodified lines | |||
| 2225 | u8 tc_to_qidx[BNXT_MAX_QUEUE]; | 2225 | u8 tc_to_qidx[BNXT_MAX_QUEUE]; |
| 2226 | u8 q_ids[BNXT_MAX_QUEUE]; | 2226 | u8 q_ids[BNXT_MAX_QUEUE]; |
| 2227 | u8 max_q; | 2227 | u8 max_q; |
| 2228 | u8 num_tc; | ||
| 2228 | 2229 | ||
| 2229 | unsigned int current_interval; | 2230 | unsigned int current_interval; |
| 2230 | #define BNXT_TIMER_INTERVAL HZ | 2231 | #define BNXT_TIMER_INTERVAL HZ |
| @@ -228,7 +228,7 @@ static int bnxt_queue_remap(struct bnxt *bp, unsigned int lltc_mask) · 227 unmodified lines | |||
| 228 | } | 228 | } |
| 229 | } | 229 | } |
| 230 | if (bp->ieee_ets) { | 230 | if (bp->ieee_ets) { |
| 231 | int tc = netdev_get_num_tc(bp->dev); | 231 | int tc = bp->num_tc; |
| 232 | 232 | ||
| 233 | if (!tc) | 233 | if (!tc) |
| 234 | tc = 1; | 234 | tc = 1; |
| @@ -884,7 +884,7 @@ static void bnxt_get_channels(struct net_device *dev, · 883 unmodified lines | |||
| 884 | if (max_tx_sch_inputs) | 884 | if (max_tx_sch_inputs) |
| 885 | max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs); | 885 | max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs); |
| 886 | 886 | ||
| 887 | tcs = netdev_get_num_tc(dev); | 887 | tcs = bp->num_tc; |
| 888 | tx_grps = max(tcs, 1); | 888 | tx_grps = max(tcs, 1); |
| 889 | if (bp->tx_nr_rings_xdp) | 889 | if (bp->tx_nr_rings_xdp) |
| 890 | tx_grps++; | 890 | tx_grps++; |
| @@ -944,7 +944,7 @@ static int bnxt_set_channels(struct net_device *dev, · 53 unmodified lines | |||
| 944 | if (channel->combined_count) | 944 | if (channel->combined_count) |
| 945 | sh = true; | 945 | sh = true; |
| 946 | 946 | ||
| 947 | tcs = netdev_get_num_tc(dev); | 947 | tcs = bp->num_tc; |
| 948 | 948 | ||
| 949 | req_tx_rings = sh ? channel->combined_count : channel->tx_count; | 949 | req_tx_rings = sh ? channel->combined_count : channel->tx_count; |
| 950 | req_rx_rings = sh ? channel->combined_count : channel->rx_count; | 950 | req_rx_rings = sh ? channel->combined_count : channel->rx_count; |
| @@ -1574,7 +1574,8 @@ u32 bnxt_get_rxfh_indir_size(struct net_device *dev) · 623 unmodified lines | |||
| 1574 | struct bnxt *bp = netdev_priv(dev); | 1574 | struct bnxt *bp = netdev_priv(dev); |
| 1575 | 1575 | ||
| 1576 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) | 1576 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) |
| 1577 | return ALIGN(bp->rx_nr_rings, BNXT_RSS_TABLE_ENTRIES_P5); | 1577 | return bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) * |
| 1578 | BNXT_RSS_TABLE_ENTRIES_P5; | ||
| 1578 | return HW_HASH_INDEX_SIZE; | 1579 | return HW_HASH_INDEX_SIZE; |
| 1579 | } | 1580 | } |
| 1580 | 1581 | ||
| @@ -684,7 +684,7 @@ static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb) · 683 unmodified lines | |||
| 684 | timestamp.hwtstamp = ns_to_ktime(ns); | 684 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 685 | skb_tstamp_tx(ptp->tx_skb, ×tamp); | 685 | skb_tstamp_tx(ptp->tx_skb, ×tamp); |
| 686 | } else { | 686 | } else { |
| 687 | netdev_WARN_ONCE(bp->dev, | 687 | netdev_warn_once(bp->dev, |
| 688 | "TS query for TX timer failed rc = %x\n", rc); | 688 | "TS query for TX timer failed rc = %x\n", rc); |
| 689 | } | 689 | } |
| 690 | 690 | ||
| @@ -407,7 +407,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog) · 406 unmodified lines | |||
| 407 | if (prog) | 407 | if (prog) |
| 408 | tx_xdp = bp->rx_nr_rings; | 408 | tx_xdp = bp->rx_nr_rings; |
| 409 | 409 | ||
| 410 | tc = netdev_get_num_tc(dev); | 410 | tc = bp->num_tc; |
| 411 | if (!tc) | 411 | if (!tc) |
| 412 | tc = 1; | 412 | tc = 1; |
| 413 | rc = bnxt_check_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings, | 413 | rc = bnxt_check_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings, |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include "octeon_network.h" | 27 | #include "octeon_network.h" |
| 28 | 28 | ||
| 29 | MODULE_AUTHOR("Cavium Networks, <support@cavium.com>"); | 29 | MODULE_AUTHOR("Cavium Networks, <support@cavium.com>"); |
| 30 | MODULE_DESCRIPTION("Cavium LiquidIO Intelligent Server Adapter Core"); | ||
| 30 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
| 31 | 32 | ||
| 32 | /* OOM task polling interval */ | 33 | /* OOM task polling interval */ |
| @@ -868,5 +868,6 @@ static struct platform_driver ep93xx_eth_driver = { · 867 unmodified lines | |||
| 868 | 868 | ||
| 869 | module_platform_driver(ep93xx_eth_driver); | 869 | module_platform_driver(ep93xx_eth_driver); |
| 870 | 870 | ||
| 871 | MODULE_DESCRIPTION("Cirrus EP93xx Ethernet driver"); | ||
| 871 | MODULE_LICENSE("GPL"); | 872 | MODULE_LICENSE("GPL"); |
| 872 | MODULE_ALIAS("platform:ep93xx-eth"); | 873 | MODULE_ALIAS("platform:ep93xx-eth"); |
| @@ -719,17 +719,25 @@ static void tsnep_xdp_xmit_flush(struct tsnep_tx *tx) · 718 unmodified lines | |||
| 719 | 719 | ||
| 720 | static bool tsnep_xdp_xmit_back(struct tsnep_adapter *adapter, | 720 | static bool tsnep_xdp_xmit_back(struct tsnep_adapter *adapter, |
| 721 | struct xdp_buff *xdp, | 721 | struct xdp_buff *xdp, |
| 722 | struct netdev_queue *tx_nq, struct tsnep_tx *tx) | 722 | struct netdev_queue *tx_nq, struct tsnep_tx *tx, |
| 723 | bool zc) | ||
| 723 | { | 724 | { |
| 724 | struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp); | 725 | struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp); |
| 725 | bool xmit; | 726 | bool xmit; |
| 727 | u32 type; | ||
| 726 | 728 | ||
| 727 | if (unlikely(!xdpf)) | 729 | if (unlikely(!xdpf)) |
| 728 | return false; | 730 | return false; |
| 729 | 731 | ||
| 732 | /* no page pool for zero copy */ | ||
| 733 | if (zc) | ||
| 734 | type = TSNEP_TX_TYPE_XDP_NDO; | ||
| 735 | else | ||
| 736 | type = TSNEP_TX_TYPE_XDP_TX; | ||
| 737 | |||
| 730 | __netif_tx_lock(tx_nq, smp_processor_id()); | 738 | __netif_tx_lock(tx_nq, smp_processor_id()); |
| 731 | 739 | ||
| 732 | xmit = tsnep_xdp_xmit_frame_ring(xdpf, tx, TSNEP_TX_TYPE_XDP_TX); | 740 | xmit = tsnep_xdp_xmit_frame_ring(xdpf, tx, type); |
| 733 | 741 | ||
| 734 | /* Avoid transmit queue timeout since we share it with the slow path */ | 742 | /* Avoid transmit queue timeout since we share it with the slow path */ |
| 735 | if (xmit) | 743 | if (xmit) |
| @@ -1273,7 +1281,7 @@ static bool tsnep_xdp_run_prog(struct tsnep_rx *rx, struct bpf_prog *prog, · 537 unmodified lines | |||
| 1273 | case XDP_PASS: | 1281 | case XDP_PASS: |
| 1274 | return false; | 1282 | return false; |
| 1275 | case XDP_TX: | 1283 | case XDP_TX: |
| 1276 | if (!tsnep_xdp_xmit_back(rx->adapter, xdp, tx_nq, tx)) | 1284 | if (!tsnep_xdp_xmit_back(rx->adapter, xdp, tx_nq, tx, false)) |
| 1277 | goto out_failure; | 1285 | goto out_failure; |
| 1278 | *status |= TSNEP_XDP_TX; | 1286 | *status |= TSNEP_XDP_TX; |
| 1279 | return true; | 1287 | return true; |
| @@ -1323,7 +1331,7 @@ static bool tsnep_xdp_run_prog_zc(struct tsnep_rx *rx, struct bpf_prog *prog, · 43 unmodified lines | |||
| 1323 | case XDP_PASS: | 1331 | case XDP_PASS: |
| 1324 | return false; | 1332 | return false; |
| 1325 | case XDP_TX: | 1333 | case XDP_TX: |
| 1326 | if (!tsnep_xdp_xmit_back(rx->adapter, xdp, tx_nq, tx)) | 1334 | if (!tsnep_xdp_xmit_back(rx->adapter, xdp, tx_nq, tx, true)) |
| 1327 | goto out_failure; | 1335 | goto out_failure; |
| 1328 | *status |= TSNEP_XDP_TX; | 1336 | *status |= TSNEP_XDP_TX; |
| 1329 | return true; | 1337 | return true; |
| @@ -1485,7 +1493,7 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi, · 155 unmodified lines | |||
| 1485 | 1493 | ||
| 1486 | xdp_prepare_buff(&xdp, page_address(entry->page), | 1494 | xdp_prepare_buff(&xdp, page_address(entry->page), |
| 1487 | XDP_PACKET_HEADROOM + TSNEP_RX_INLINE_METADATA_SIZE, | 1495 | XDP_PACKET_HEADROOM + TSNEP_RX_INLINE_METADATA_SIZE, |
| 1488 | length, false); | 1496 | length - ETH_FCS_LEN, false); |
| 1489 | 1497 | ||
| 1490 | consume = tsnep_xdp_run_prog(rx, prog, &xdp, | 1498 | consume = tsnep_xdp_run_prog(rx, prog, &xdp, |
| 1491 | &xdp_status, tx_nq, tx); | 1499 | &xdp_status, tx_nq, tx); |
| @@ -1568,7 +1576,7 @@ static int tsnep_rx_poll_zc(struct tsnep_rx *rx, struct napi_struct *napi, · 76 unmodified lines | |||
| 1568 | prefetch(entry->xdp->data); | 1576 | prefetch(entry->xdp->data); |
| 1569 | length = __le32_to_cpu(entry->desc_wb->properties) & | 1577 | length = __le32_to_cpu(entry->desc_wb->properties) & |
| 1570 | TSNEP_DESC_LENGTH_MASK; | 1578 | TSNEP_DESC_LENGTH_MASK; |
| 1571 | xsk_buff_set_size(entry->xdp, length); | 1579 | xsk_buff_set_size(entry->xdp, length - ETH_FCS_LEN); |
| 1572 | xsk_buff_dma_sync_for_cpu(entry->xdp, rx->xsk_pool); | 1580 | xsk_buff_dma_sync_for_cpu(entry->xdp, rx->xsk_pool); |
| 1573 | 1581 | ||
| 1574 | /* RX metadata with timestamps is in front of actual data, | 1582 | /* RX metadata with timestamps is in front of actual data, |
| @@ -1762,6 +1770,19 @@ static void tsnep_rx_reopen_xsk(struct tsnep_rx *rx) · 187 unmodified lines | |||
| 1762 | allocated--; | 1770 | allocated--; |
| 1763 | } | 1771 | } |
| 1764 | } | 1772 | } |
| 1773 | |||
| 1774 | /* set need wakeup flag immediately if ring is not filled completely, | ||
| 1775 | * first polling would be too late as need wakeup signalisation would | ||
| 1776 | * be delayed for an indefinite time | ||
| 1777 | */ | ||
| 1778 | if (xsk_uses_need_wakeup(rx->xsk_pool)) { | ||
| 1779 | int desc_available = tsnep_rx_desc_available(rx); | ||
| 1780 | |||
| 1781 | if (desc_available) | ||
| 1782 | xsk_set_rx_need_wakeup(rx->xsk_pool); | ||
| 1783 | else | ||
| 1784 | xsk_clear_rx_need_wakeup(rx->xsk_pool); | ||
| 1785 | } | ||
| 1765 | } | 1786 | } |
| 1766 | 1787 | ||
| 1767 | static bool tsnep_pending(struct tsnep_queue *queue) | 1788 | static bool tsnep_pending(struct tsnep_queue *queue) |
| @@ -661,4 +661,5 @@ static struct platform_driver nps_enet_driver = { · 660 unmodified lines | |||
| 661 | module_platform_driver(nps_enet_driver); | 661 | module_platform_driver(nps_enet_driver); |
| 662 | 662 | ||
| 663 | MODULE_AUTHOR("EZchip Semiconductor"); | 663 | MODULE_AUTHOR("EZchip Semiconductor"); |
| 664 | MODULE_DESCRIPTION("EZchip NPS Ethernet driver"); | ||
| 664 | MODULE_LICENSE("GPL v2"); | 665 | MODULE_LICENSE("GPL v2"); |
| @@ -3216,4 +3216,5 @@ void enetc_pci_remove(struct pci_dev *pdev) · 3215 unmodified lines | |||
| 3216 | } | 3216 | } |
| 3217 | EXPORT_SYMBOL_GPL(enetc_pci_remove); | 3217 | EXPORT_SYMBOL_GPL(enetc_pci_remove); |
| 3218 | 3218 | ||
| 3219 | MODULE_DESCRIPTION("NXP ENETC Ethernet driver"); | ||
| 3219 | MODULE_LICENSE("Dual BSD/GPL"); | 3220 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -2036,6 +2036,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) · 2035 unmodified lines | |||
| 2036 | 2036 | ||
| 2037 | /* if any of the above changed restart the FEC */ | 2037 | /* if any of the above changed restart the FEC */ |
| 2038 | if (status_change) { | 2038 | if (status_change) { |
| 2039 | netif_stop_queue(ndev); | ||
| 2039 | napi_disable(&fep->napi); | 2040 | napi_disable(&fep->napi); |
| 2040 | netif_tx_lock_bh(ndev); | 2041 | netif_tx_lock_bh(ndev); |
| 2041 | fec_restart(ndev); | 2042 | fec_restart(ndev); |
| @@ -2045,6 +2046,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) · 3 unmodified lines | |||
| 2045 | } | 2046 | } |
| 2046 | } else { | 2047 | } else { |
| 2047 | if (fep->link) { | 2048 | if (fep->link) { |
| 2049 | netif_stop_queue(ndev); | ||
| 2048 | napi_disable(&fep->napi); | 2050 | napi_disable(&fep->napi); |
| 2049 | netif_tx_lock_bh(ndev); | 2051 | netif_tx_lock_bh(ndev); |
| 2050 | fec_stop(ndev); | 2052 | fec_stop(ndev); |
| @@ -4769,4 +4771,5 @@ static struct platform_driver fec_driver = { · 2718 unmodified lines | |||
| 4769 | 4771 | ||
| 4770 | module_platform_driver(fec_driver); | 4772 | module_platform_driver(fec_driver); |
| 4771 | 4773 | ||
| 4774 | MODULE_DESCRIPTION("NXP Fast Ethernet Controller (FEC) driver"); | ||
| 4772 | MODULE_LICENSE("GPL"); | 4775 | MODULE_LICENSE("GPL"); |
| @@ -531,4 +531,5 @@ static struct platform_driver fsl_pq_mdio_driver = { · 530 unmodified lines | |||
| 531 | 531 | ||
| 532 | module_platform_driver(fsl_pq_mdio_driver); | 532 | module_platform_driver(fsl_pq_mdio_driver); |
| 533 | 533 | ||
| 534 | MODULE_DESCRIPTION("Freescale PQ MDIO helpers"); | ||
| 534 | MODULE_LICENSE("GPL"); | 535 | MODULE_LICENSE("GPL"); |
| @@ -356,7 +356,7 @@ static enum pkt_hash_types gve_rss_type(__be16 pkt_flags) · 355 unmodified lines | |||
| 356 | 356 | ||
| 357 | static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, | 357 | static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, |
| 358 | struct gve_rx_slot_page_info *page_info, | 358 | struct gve_rx_slot_page_info *page_info, |
| 359 | u16 packet_buffer_size, u16 len, | 359 | unsigned int truesize, u16 len, |
| 360 | struct gve_rx_ctx *ctx) | 360 | struct gve_rx_ctx *ctx) |
| 361 | { | 361 | { |
| 362 | u32 offset = page_info->page_offset + page_info->pad; | 362 | u32 offset = page_info->page_offset + page_info->pad; |
| @@ -389,10 +389,10 @@ static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, · 26 unmodified lines | |||
| 389 | if (skb != ctx->skb_head) { | 389 | if (skb != ctx->skb_head) { |
| 390 | ctx->skb_head->len += len; | 390 | ctx->skb_head->len += len; |
| 391 | ctx->skb_head->data_len += len; | 391 | ctx->skb_head->data_len += len; |
| 392 | ctx->skb_head->truesize += packet_buffer_size; | 392 | ctx->skb_head->truesize += truesize; |
| 393 | } | 393 | } |
| 394 | skb_add_rx_frag(skb, num_frags, page_info->page, | 394 | skb_add_rx_frag(skb, num_frags, page_info->page, |
| 395 | offset, len, packet_buffer_size); | 395 | offset, len, truesize); |
| 396 | 396 | ||
| 397 | return ctx->skb_head; | 397 | return ctx->skb_head; |
| 398 | } | 398 | } |
| @@ -486,7 +486,7 @@ static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx, · 87 unmodified lines | |||
| 486 | 486 | ||
| 487 | memcpy(alloc_page_info.page_address, src, page_info->pad + len); | 487 | memcpy(alloc_page_info.page_address, src, page_info->pad + len); |
| 488 | skb = gve_rx_add_frags(napi, &alloc_page_info, | 488 | skb = gve_rx_add_frags(napi, &alloc_page_info, |
| 489 | rx->packet_buffer_size, | 489 | PAGE_SIZE, |
| 490 | len, ctx); | 490 | len, ctx); |
| 491 | 491 | ||
| 492 | u64_stats_update_begin(&rx->statss); | 492 | u64_stats_update_begin(&rx->statss); |
| @@ -360,23 +360,43 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca); · 359 unmodified lines | |||
| 360 | * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of | 360 | * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of |
| 361 | * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) | 361 | * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) |
| 362 | * bits to count nanoseconds leaving the rest for fractional nonseconds. | 362 | * bits to count nanoseconds leaving the rest for fractional nonseconds. |
| 363 | * | ||
| 364 | * Any given INCVALUE also has an associated maximum adjustment value. This | ||
| 365 | * maximum adjustment value is the largest increase (or decrease) which can be | ||
| 366 | * safely applied without overflowing the INCVALUE. Since INCVALUE has | ||
| 367 | * a maximum range of 24 bits, its largest value is 0xFFFFFF. | ||
| 368 | * | ||
| 369 | * To understand where the maximum value comes from, consider the following | ||
| 370 | * equation: | ||
| 371 | * | ||
| 372 | * new_incval = base_incval + (base_incval * adjustment) / 1billion | ||
| 373 | * | ||
| 374 | * To avoid overflow that means: | ||
| 375 | * max_incval = base_incval + (base_incval * max_adj) / billion | ||
| 376 | * | ||
| 377 | * Re-arranging: | ||
| 378 | * max_adj = floor(((max_incval - base_incval) * 1billion) / 1billion) | ||
| 363 | */ | 379 | */ |
| 364 | #define INCVALUE_96MHZ 125 | 380 | #define INCVALUE_96MHZ 125 |
| 365 | #define INCVALUE_SHIFT_96MHZ 17 | 381 | #define INCVALUE_SHIFT_96MHZ 17 |
| 366 | #define INCPERIOD_SHIFT_96MHZ 2 | 382 | #define INCPERIOD_SHIFT_96MHZ 2 |
| 367 | #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) | 383 | #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) |
| 384 | #define MAX_PPB_96MHZ 23999900 /* 23,999,900 ppb */ | ||
| 368 | 385 | ||
| 369 | #define INCVALUE_25MHZ 40 | 386 | #define INCVALUE_25MHZ 40 |
| 370 | #define INCVALUE_SHIFT_25MHZ 18 | 387 | #define INCVALUE_SHIFT_25MHZ 18 |
| 371 | #define INCPERIOD_25MHZ 1 | 388 | #define INCPERIOD_25MHZ 1 |
| 389 | #define MAX_PPB_25MHZ 599999900 /* 599,999,900 ppb */ | ||
| 372 | 390 | ||
| 373 | #define INCVALUE_24MHZ 125 | 391 | #define INCVALUE_24MHZ 125 |
| 374 | #define INCVALUE_SHIFT_24MHZ 14 | 392 | #define INCVALUE_SHIFT_24MHZ 14 |
| 375 | #define INCPERIOD_24MHZ 3 | 393 | #define INCPERIOD_24MHZ 3 |
| 394 | #define MAX_PPB_24MHZ 999999999 /* 999,999,999 ppb */ | ||
| 376 | 395 | ||
| 377 | #define INCVALUE_38400KHZ 26 | 396 | #define INCVALUE_38400KHZ 26 |
| 378 | #define INCVALUE_SHIFT_38400KHZ 19 | 397 | #define INCVALUE_SHIFT_38400KHZ 19 |
| 379 | #define INCPERIOD_38400KHZ 1 | 398 | #define INCPERIOD_38400KHZ 1 |
| 399 | #define MAX_PPB_38400KHZ 230769100 /* 230,769,100 ppb */ | ||
| 380 | 400 | ||
| 381 | /* Another drawback of scaling the incvalue by a large factor is the | 401 | /* Another drawback of scaling the incvalue by a large factor is the |
| 382 | * 64-bit SYSTIM register overflows more quickly. This is dealt with | 402 | * 64-bit SYSTIM register overflows more quickly. This is dealt with |
| @@ -280,8 +280,17 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) · 279 unmodified lines | |||
| 280 | 280 | ||
| 281 | switch (hw->mac.type) { | 281 | switch (hw->mac.type) { |
| 282 | case e1000_pch2lan: | 282 | case e1000_pch2lan: |
| 283 | adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; | ||
| 284 | break; | ||
| 283 | case e1000_pch_lpt: | 285 | case e1000_pch_lpt: |
| 286 | if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) | ||
| 287 | adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; | ||
| 288 | else | ||
| 289 | adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; | ||
| 290 | break; | ||
| 284 | case e1000_pch_spt: | 291 | case e1000_pch_spt: |
| 292 | adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; | ||
| 293 | break; | ||
| 285 | case e1000_pch_cnp: | 294 | case e1000_pch_cnp: |
| 286 | case e1000_pch_tgp: | 295 | case e1000_pch_tgp: |
| 287 | case e1000_pch_adp: | 296 | case e1000_pch_adp: |
| @@ -289,15 +298,14 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) · 1 unmodified line | |||
| 289 | case e1000_pch_lnp: | 298 | case e1000_pch_lnp: |
| 290 | case e1000_pch_ptp: | 299 | case e1000_pch_ptp: |
| 291 | case e1000_pch_nvp: | 300 | case e1000_pch_nvp: |
| 292 | if ((hw->mac.type < e1000_pch_lpt) || | 301 | if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) |
| 293 | (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) { | 302 | adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; |
| 294 | adapter->ptp_clock_info.max_adj = 24000000 - 1; | 303 | else |
| 295 | break; | 304 | adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; |
| 296 | } | 305 | break; |
| 297 | fallthrough; | ||
| 298 | case e1000_82574: | 306 | case e1000_82574: |
| 299 | case e1000_82583: | 307 | case e1000_82583: |
| 300 | adapter->ptp_clock_info.max_adj = 600000000 - 1; | 308 | adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; |
| 301 | break; | 309 | break; |
| 302 | default: | 310 | default: |
| 303 | break; | 311 | break; |
| @@ -43,7 +43,7 @@ · 42 unmodified lines | |||
| 43 | #define I40E_LLDP_TLV_SUBTYPE_SHIFT 0 | 43 | #define I40E_LLDP_TLV_SUBTYPE_SHIFT 0 |
| 44 | #define I40E_LLDP_TLV_SUBTYPE_MASK (0xFF << I40E_LLDP_TLV_SUBTYPE_SHIFT) | 44 | #define I40E_LLDP_TLV_SUBTYPE_MASK (0xFF << I40E_LLDP_TLV_SUBTYPE_SHIFT) |
| 45 | #define I40E_LLDP_TLV_OUI_SHIFT 8 | 45 | #define I40E_LLDP_TLV_OUI_SHIFT 8 |
| 46 | #define I40E_LLDP_TLV_OUI_MASK (0xFFFFFF << I40E_LLDP_TLV_OUI_SHIFT) | 46 | #define I40E_LLDP_TLV_OUI_MASK (0xFFFFFFU << I40E_LLDP_TLV_OUI_SHIFT) |
| 47 | 47 | ||
| 48 | /* Defines for IEEE ETS TLV */ | 48 | /* Defines for IEEE ETS TLV */ |
| 49 | #define I40E_IEEE_ETS_MAXTC_SHIFT 0 | 49 | #define I40E_IEEE_ETS_MAXTC_SHIFT 0 |
| @@ -3588,40 +3588,55 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) · 3587 unmodified lines | |||
| 3588 | struct i40e_hmc_obj_rxq rx_ctx; | 3588 | struct i40e_hmc_obj_rxq rx_ctx; |
| 3589 | int err = 0; | 3589 | int err = 0; |
| 3590 | bool ok; | 3590 | bool ok; |
| 3591 | int ret; | ||
| 3592 | 3591 | ||
| 3593 | bitmap_zero(ring->state, __I40E_RING_STATE_NBITS); | 3592 | bitmap_zero(ring->state, __I40E_RING_STATE_NBITS); |
| 3594 | 3593 | ||
| 3595 | /* clear the context structure first */ | 3594 | /* clear the context structure first */ |
| 3596 | memset(&rx_ctx, 0, sizeof(rx_ctx)); | 3595 | memset(&rx_ctx, 0, sizeof(rx_ctx)); |
| 3597 | 3596 | ||
| 3598 | if (ring->vsi->type == I40E_VSI_MAIN) | 3597 | ring->rx_buf_len = vsi->rx_buf_len; |
| 3599 | xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); | 3598 | |
| 3599 | /* XDP RX-queue info only needed for RX rings exposed to XDP */ | ||
| 3600 | if (ring->vsi->type != I40E_VSI_MAIN) | ||
| 3601 | goto skip; | ||
| 3602 | |||
| 3603 | if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { | ||
| 3604 | err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, | ||
| 3605 | ring->queue_index, | ||
| 3606 | ring->q_vector->napi.napi_id, | ||
| 3607 | ring->rx_buf_len); | ||
| 3608 | if (err) | ||
| 3609 | return err; | ||
| 3610 | } | ||
| 3600 | 3611 | ||
| 3601 | ring->xsk_pool = i40e_xsk_pool(ring); | 3612 | ring->xsk_pool = i40e_xsk_pool(ring); |
| 3602 | if (ring->xsk_pool) { | 3613 | if (ring->xsk_pool) { |
| 3603 | ring->rx_buf_len = | 3614 | xdp_rxq_info_unreg(&ring->xdp_rxq); |
| 3604 | xsk_pool_get_rx_frame_size(ring->xsk_pool); | 3615 | ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); |
| 3605 | ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, | 3616 | err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, |
| 3617 | ring->queue_index, | ||
| 3618 | ring->q_vector->napi.napi_id, | ||
| 3619 | ring->rx_buf_len); | ||
| 3620 | if (err) | ||
| 3621 | return err; | ||
| 3622 | err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, | ||
| 3606 | MEM_TYPE_XSK_BUFF_POOL, | 3623 | MEM_TYPE_XSK_BUFF_POOL, |
| 3607 | NULL); | 3624 | NULL); |
| 3608 | if (ret) | 3625 | if (err) |
| 3609 | return ret; | 3626 | return err; |
| 3610 | dev_info(&vsi->back->pdev->dev, | 3627 | dev_info(&vsi->back->pdev->dev, |
| 3611 | "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", | 3628 | "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", |
| 3612 | ring->queue_index); | 3629 | ring->queue_index); |
| 3613 | 3630 | ||
| 3614 | } else { | 3631 | } else { |
| 3615 | ring->rx_buf_len = vsi->rx_buf_len; | 3632 | err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, |
| 3616 | if (ring->vsi->type == I40E_VSI_MAIN) { | 3633 | MEM_TYPE_PAGE_SHARED, |
| 3617 | ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, | 3634 | NULL); |
| 3618 | MEM_TYPE_PAGE_SHARED, | 3635 | if (err) |
| 3619 | NULL); | 3636 | return err; |
| 3620 | if (ret) | ||
| 3621 | return ret; | ||
| 3622 | } | ||
| 3623 | } | 3637 | } |
| 3624 | 3638 | ||
| 3639 | skip: | ||
| 3625 | xdp_init_buff(&ring->xdp, i40e_rx_pg_size(ring) / 2, &ring->xdp_rxq); | 3640 | xdp_init_buff(&ring->xdp, i40e_rx_pg_size(ring) / 2, &ring->xdp_rxq); |
| 3626 | 3641 | ||
| 3627 | rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len, | 3642 | rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len, |
| @@ -1548,7 +1548,6 @@ void i40e_free_rx_resources(struct i40e_ring *rx_ring) · 1547 unmodified lines | |||
| 1548 | int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) | 1548 | int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) |
| 1549 | { | 1549 | { |
| 1550 | struct device *dev = rx_ring->dev; | 1550 | struct device *dev = rx_ring->dev; |
| 1551 | int err; | ||
| 1552 | 1551 | ||
| 1553 | u64_stats_init(&rx_ring->syncp); | 1552 | u64_stats_init(&rx_ring->syncp); |
| 1554 | 1553 | ||
| @@ -1569,14 +1568,6 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) · 14 unmodified lines | |||
| 1569 | rx_ring->next_to_process = 0; | 1568 | rx_ring->next_to_process = 0; |
| 1570 | rx_ring->next_to_use = 0; | 1569 | rx_ring->next_to_use = 0; |
| 1571 | 1570 | ||
| 1572 | /* XDP RX-queue info only needed for RX rings exposed to XDP */ | ||
| 1573 | if (rx_ring->vsi->type == I40E_VSI_MAIN) { | ||
| 1574 | err = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, | ||
| 1575 | rx_ring->queue_index, rx_ring->q_vector->napi.napi_id); | ||
| 1576 | if (err < 0) | ||
| 1577 | return err; | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; | 1571 | rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; |
| 1581 | 1572 | ||
| 1582 | rx_ring->rx_bi = | 1573 | rx_ring->rx_bi = |
| @@ -2087,7 +2078,8 @@ static void i40e_put_rx_buffer(struct i40e_ring *rx_ring, · 504 unmodified lines | |||
| 2087 | static void i40e_process_rx_buffs(struct i40e_ring *rx_ring, int xdp_res, | 2078 | static void i40e_process_rx_buffs(struct i40e_ring *rx_ring, int xdp_res, |
| 2088 | struct xdp_buff *xdp) | 2079 | struct xdp_buff *xdp) |
| 2089 | { | 2080 | { |
| 2090 | u32 next = rx_ring->next_to_clean; | 2081 | u32 nr_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags; |
| 2082 | u32 next = rx_ring->next_to_clean, i = 0; | ||
| 2091 | struct i40e_rx_buffer *rx_buffer; | 2083 | struct i40e_rx_buffer *rx_buffer; |
| 2092 | 2084 | ||
| 2093 | xdp->flags = 0; | 2085 | xdp->flags = 0; |
| @@ -2100,10 +2092,10 @@ static void i40e_process_rx_buffs(struct i40e_ring *rx_ring, int xdp_res, · 6 unmodified lines | |||
| 2100 | if (!rx_buffer->page) | 2092 | if (!rx_buffer->page) |
| 2101 | continue; | 2093 | continue; |
| 2102 | 2094 | ||
| 2103 | if (xdp_res == I40E_XDP_CONSUMED) | 2095 | if (xdp_res != I40E_XDP_CONSUMED) |
| 2104 | rx_buffer->pagecnt_bias++; | ||
| 2105 | else | ||
| 2106 | i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz); | 2096 | i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz); |
| 2097 | else if (i++ <= nr_frags) | ||
| 2098 | rx_buffer->pagecnt_bias++; | ||
| 2107 | 2099 | ||
| 2108 | /* EOP buffer will be put in i40e_clean_rx_irq() */ | 2100 | /* EOP buffer will be put in i40e_clean_rx_irq() */ |
| 2109 | if (next == rx_ring->next_to_process) | 2101 | if (next == rx_ring->next_to_process) |
| @@ -2117,20 +2109,20 @@ static void i40e_process_rx_buffs(struct i40e_ring *rx_ring, int xdp_res, · 7 unmodified lines | |||
| 2117 | * i40e_construct_skb - Allocate skb and populate it | 2109 | * i40e_construct_skb - Allocate skb and populate it |
| 2118 | * @rx_ring: rx descriptor ring to transact packets on | 2110 | * @rx_ring: rx descriptor ring to transact packets on |
| 2119 | * @xdp: xdp_buff pointing to the data | 2111 | * @xdp: xdp_buff pointing to the data |
| 2120 | * @nr_frags: number of buffers for the packet | ||
| 2121 | * | 2112 | * |
| 2122 | * This function allocates an skb. It then populates it with the page | 2113 | * This function allocates an skb. It then populates it with the page |
| 2123 | * data from the current receive descriptor, taking care to set up the | 2114 | * data from the current receive descriptor, taking care to set up the |
| 2124 | * skb correctly. | 2115 | * skb correctly. |
| 2125 | */ | 2116 | */ |
| 2126 | static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, | 2117 | static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, |
| 2127 | struct xdp_buff *xdp, | 2118 | struct xdp_buff *xdp) |
| 2128 | u32 nr_frags) | ||
| 2129 | { | 2119 | { |
| 2130 | unsigned int size = xdp->data_end - xdp->data; | 2120 | unsigned int size = xdp->data_end - xdp->data; |
| 2131 | struct i40e_rx_buffer *rx_buffer; | 2121 | struct i40e_rx_buffer *rx_buffer; |
| 2122 | struct skb_shared_info *sinfo; | ||
| 2132 | unsigned int headlen; | 2123 | unsigned int headlen; |
| 2133 | struct sk_buff *skb; | 2124 | struct sk_buff *skb; |
| 2125 | u32 nr_frags = 0; | ||
| 2134 | 2126 | ||
| 2135 | /* prefetch first cache line of first page */ | 2127 | /* prefetch first cache line of first page */ |
| 2136 | net_prefetch(xdp->data); | 2128 | net_prefetch(xdp->data); |
| @@ -2168,6 +2160,10 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, · 31 unmodified lines | |||
| 2168 | memcpy(__skb_put(skb, headlen), xdp->data, | 2160 | memcpy(__skb_put(skb, headlen), xdp->data, |
| 2169 | ALIGN(headlen, sizeof(long))); | 2161 | ALIGN(headlen, sizeof(long))); |
| 2170 | 2162 | ||
| 2163 | if (unlikely(xdp_buff_has_frags(xdp))) { | ||
| 2164 | sinfo = xdp_get_shared_info_from_buff(xdp); | ||
| 2165 | nr_frags = sinfo->nr_frags; | ||
| 2166 | } | ||
| 2171 | rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); | 2167 | rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); |
| 2172 | /* update all of the pointers */ | 2168 | /* update all of the pointers */ |
| 2173 | size -= headlen; | 2169 | size -= headlen; |
| @@ -2187,9 +2183,8 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, · 13 unmodified lines | |||
| 2187 | } | 2183 | } |
| 2188 | 2184 | ||
| 2189 | if (unlikely(xdp_buff_has_frags(xdp))) { | 2185 | if (unlikely(xdp_buff_has_frags(xdp))) { |
| 2190 | struct skb_shared_info *sinfo, *skinfo = skb_shinfo(skb); | 2186 | struct skb_shared_info *skinfo = skb_shinfo(skb); |
| 2191 | 2187 | ||
| 2192 | sinfo = xdp_get_shared_info_from_buff(xdp); | ||
| 2193 | memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0], | 2188 | memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0], |
| 2194 | sizeof(skb_frag_t) * nr_frags); | 2189 | sizeof(skb_frag_t) * nr_frags); |
| 2195 | 2190 | ||
| @@ -2212,17 +2207,17 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, · 16 unmodified lines | |||
| 2212 | * i40e_build_skb - Build skb around an existing buffer | 2207 | * i40e_build_skb - Build skb around an existing buffer |
| 2213 | * @rx_ring: Rx descriptor ring to transact packets on | 2208 | * @rx_ring: Rx descriptor ring to transact packets on |
| 2214 | * @xdp: xdp_buff pointing to the data | 2209 | * @xdp: xdp_buff pointing to the data |
| 2215 | * @nr_frags: number of buffers for the packet | ||
| 2216 | * | 2210 | * |
| 2217 | * This function builds an skb around an existing Rx buffer, taking care | 2211 | * This function builds an skb around an existing Rx buffer, taking care |
| 2218 | * to set up the skb correctly and avoid any memcpy overhead. | 2212 | * to set up the skb correctly and avoid any memcpy overhead. |
| 2219 | */ | 2213 | */ |
| 2220 | static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, | 2214 | static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, |
| 2221 | struct xdp_buff *xdp, | 2215 | struct xdp_buff *xdp) |
| 2222 | u32 nr_frags) | ||
| 2223 | { | 2216 | { |
| 2224 | unsigned int metasize = xdp->data - xdp->data_meta; | 2217 | unsigned int metasize = xdp->data - xdp->data_meta; |
| 2218 | struct skb_shared_info *sinfo; | ||
| 2225 | struct sk_buff *skb; | 2219 | struct sk_buff *skb; |
| 2220 | u32 nr_frags; | ||
| 2226 | 2221 | ||
| 2227 | /* Prefetch first cache line of first page. If xdp->data_meta | 2222 | /* Prefetch first cache line of first page. If xdp->data_meta |
| 2228 | * is unused, this points exactly as xdp->data, otherwise we | 2223 | * is unused, this points exactly as xdp->data, otherwise we |
| @@ -2231,6 +2226,11 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, · 2 unmodified lines | |||
| 2231 | */ | 2226 | */ |
| 2232 | net_prefetch(xdp->data_meta); | 2227 | net_prefetch(xdp->data_meta); |
| 2233 | 2228 | ||
| 2229 | if (unlikely(xdp_buff_has_frags(xdp))) { | ||
| 2230 | sinfo = xdp_get_shared_info_from_buff(xdp); | ||
| 2231 | nr_frags = sinfo->nr_frags; | ||
| 2232 | } | ||
| 2233 | |||
| 2234 | /* build an skb around the page buffer */ | 2234 | /* build an skb around the page buffer */ |
| 2235 | skb = napi_build_skb(xdp->data_hard_start, xdp->frame_sz); | 2235 | skb = napi_build_skb(xdp->data_hard_start, xdp->frame_sz); |
| 2236 | if (unlikely(!skb)) | 2236 | if (unlikely(!skb)) |
| @@ -2243,9 +2243,6 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, · 6 unmodified lines | |||
| 2243 | skb_metadata_set(skb, metasize); | 2243 | skb_metadata_set(skb, metasize); |
| 2244 | 2244 | ||
| 2245 | if (unlikely(xdp_buff_has_frags(xdp))) { | 2245 | if (unlikely(xdp_buff_has_frags(xdp))) { |
| 2246 | struct skb_shared_info *sinfo; | ||
| 2247 | |||
| 2248 | sinfo = xdp_get_shared_info_from_buff(xdp); | ||
| 2249 | xdp_update_skb_shared_info(skb, nr_frags, | 2246 | xdp_update_skb_shared_info(skb, nr_frags, |
| 2250 | sinfo->xdp_frags_size, | 2247 | sinfo->xdp_frags_size, |
| 2251 | nr_frags * xdp->frame_sz, | 2248 | nr_frags * xdp->frame_sz, |
| @@ -2589,9 +2586,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget, · 337 unmodified lines | |||
| 2589 | total_rx_bytes += size; | 2586 | total_rx_bytes += size; |
| 2590 | } else { | 2587 | } else { |
| 2591 | if (ring_uses_build_skb(rx_ring)) | 2588 | if (ring_uses_build_skb(rx_ring)) |
| 2592 | skb = i40e_build_skb(rx_ring, xdp, nfrags); | 2589 | skb = i40e_build_skb(rx_ring, xdp); |
| 2593 | else | 2590 | else |
| 2594 | skb = i40e_construct_skb(rx_ring, xdp, nfrags); | 2591 | skb = i40e_construct_skb(rx_ring, xdp); |
| 2595 | 2592 | ||
| 2596 | /* drop if we failed to retrieve a buffer */ | 2593 | /* drop if we failed to retrieve a buffer */ |
| 2597 | if (!skb) { | 2594 | if (!skb) { |
| @@ -414,7 +414,8 @@ i40e_add_xsk_frag(struct i40e_ring *rx_ring, struct xdp_buff *first, · 413 unmodified lines | |||
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, | 416 | __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, |
| 417 | virt_to_page(xdp->data_hard_start), 0, size); | 417 | virt_to_page(xdp->data_hard_start), |
| 418 | XDP_PACKET_HEADROOM, size); | ||
| 418 | sinfo->xdp_frags_size += size; | 419 | sinfo->xdp_frags_size += size; |
| 419 | xsk_buff_add_frag(xdp); | 420 | xsk_buff_add_frag(xdp); |
| 420 | 421 | ||
| @@ -498,7 +499,6 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget) · 77 unmodified lines | |||
| 498 | xdp_res = i40e_run_xdp_zc(rx_ring, first, xdp_prog); | 499 | xdp_res = i40e_run_xdp_zc(rx_ring, first, xdp_prog); |
| 499 | i40e_handle_xdp_result_zc(rx_ring, first, rx_desc, &rx_packets, | 500 | i40e_handle_xdp_result_zc(rx_ring, first, rx_desc, &rx_packets, |
| 500 | &rx_bytes, xdp_res, &failure); | 501 | &rx_bytes, xdp_res, &failure); |
| 501 | first->flags = 0; | ||
| 502 | next_to_clean = next_to_process; | 502 | next_to_clean = next_to_process; |
| 503 | if (failure) | 503 | if (failure) |
| 504 | break; | 504 | break; |
| @@ -547,19 +547,27 @@ int ice_vsi_cfg_rxq(struct ice_rx_ring *ring) · 546 unmodified lines | |||
| 547 | ring->rx_buf_len = ring->vsi->rx_buf_len; | 547 | ring->rx_buf_len = ring->vsi->rx_buf_len; |
| 548 | 548 | ||
| 549 | if (ring->vsi->type == ICE_VSI_PF) { | 549 | if (ring->vsi->type == ICE_VSI_PF) { |
| 550 | if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) | 550 | if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { |
| 551 | /* coverity[check_return] */ | 551 | err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, |
| 552 | __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, | 552 | ring->q_index, |
| 553 | ring->q_index, | 553 | ring->q_vector->napi.napi_id, |
| 554 | ring->q_vector->napi.napi_id, | 554 | ring->rx_buf_len); |
| 555 | ring->vsi->rx_buf_len); | 555 | if (err) |
| 556 | return err; | ||
| 557 | } | ||
| 556 | 558 | ||
| 557 | ring->xsk_pool = ice_xsk_pool(ring); | 559 | ring->xsk_pool = ice_xsk_pool(ring); |
| 558 | if (ring->xsk_pool) { | 560 | if (ring->xsk_pool) { |
| 559 | xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); | 561 | xdp_rxq_info_unreg(&ring->xdp_rxq); |
| 560 | 562 | ||
| 561 | ring->rx_buf_len = | 563 | ring->rx_buf_len = |
| 562 | xsk_pool_get_rx_frame_size(ring->xsk_pool); | 564 | xsk_pool_get_rx_frame_size(ring->xsk_pool); |
| 565 | err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, | ||
| 566 | ring->q_index, | ||
| 567 | ring->q_vector->napi.napi_id, | ||
| 568 | ring->rx_buf_len); | ||
| 569 | if (err) | ||
| 570 | return err; | ||
| 563 | err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, | 571 | err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, |
| 564 | MEM_TYPE_XSK_BUFF_POOL, | 572 | MEM_TYPE_XSK_BUFF_POOL, |
| 565 | NULL); | 573 | NULL); |
| @@ -571,13 +579,14 @@ int ice_vsi_cfg_rxq(struct ice_rx_ring *ring) · 5 unmodified lines | |||
| 571 | dev_info(dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", | 579 | dev_info(dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", |
| 572 | ring->q_index); | 580 | ring->q_index); |
| 573 | } else { | 581 | } else { |
| 574 | if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) | 582 | if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { |
| 575 | /* coverity[check_return] */ | 583 | err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, |
| 576 | __xdp_rxq_info_reg(&ring->xdp_rxq, | 584 | ring->q_index, |
| 577 | ring->netdev, | 585 | ring->q_vector->napi.napi_id, |
| 578 | ring->q_index, | 586 | ring->rx_buf_len); |
| 579 | ring->q_vector->napi.napi_id, | 587 | if (err) |
| 580 | ring->vsi->rx_buf_len); | 588 | return err; |
| 589 | } | ||
| 581 | 590 | ||
| 582 | err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, | 591 | err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, |
| 583 | MEM_TYPE_PAGE_SHARED, | 592 | MEM_TYPE_PAGE_SHARED, |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | |||
| 24 | #define rd64(a, reg) readq((a)->hw_addr + (reg)) | 24 | #define rd64(a, reg) readq((a)->hw_addr + (reg)) |
| 25 | 25 | ||
| 26 | #define ice_flush(a) rd32((a), GLGEN_STAT) | 26 | #define ice_flush(a) rd32((a), GLGEN_STAT) |
| 27 | #define ICE_M(m, s) ((m) << (s)) | 27 | #define ICE_M(m, s) ((m ## U) << (s)) |
| 28 | 28 | ||
| 29 | struct ice_dma_mem { | 29 | struct ice_dma_mem { |
| 30 | void *va; | 30 | void *va; |
| @@ -513,11 +513,6 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring) · 512 unmodified lines | |||
| 513 | if (ice_is_xdp_ena_vsi(rx_ring->vsi)) | 513 | if (ice_is_xdp_ena_vsi(rx_ring->vsi)) |
| 514 | WRITE_ONCE(rx_ring->xdp_prog, rx_ring->vsi->xdp_prog); | 514 | WRITE_ONCE(rx_ring->xdp_prog, rx_ring->vsi->xdp_prog); |
| 515 | 515 | ||
| 516 | if (rx_ring->vsi->type == ICE_VSI_PF && | ||
| 517 | !xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) | ||
| 518 | if (xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, | ||
| 519 | rx_ring->q_index, rx_ring->q_vector->napi.napi_id)) | ||
| 520 | goto err; | ||
| 521 | return 0; | 516 | return 0; |
| 522 | 517 | ||
| 523 | err: | 518 | err: |
| @@ -603,9 +598,7 @@ out_failure: · 79 unmodified lines | |||
| 603 | ret = ICE_XDP_CONSUMED; | 598 | ret = ICE_XDP_CONSUMED; |
| 604 | } | 599 | } |
| 605 | exit: | 600 | exit: |
| 606 | rx_buf->act = ret; | 601 | ice_set_rx_bufs_act(xdp, rx_ring, ret); |
| 607 | if (unlikely(xdp_buff_has_frags(xdp))) | ||
| 608 | ice_set_rx_bufs_act(xdp, rx_ring, ret); | ||
| 609 | } | 602 | } |
| 610 | 603 | ||
| 611 | /** | 604 | /** |
| @@ -893,14 +886,17 @@ ice_add_xdp_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, · 281 unmodified lines | |||
| 893 | } | 886 | } |
| 894 | 887 | ||
| 895 | if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) { | 888 | if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) { |
| 896 | if (unlikely(xdp_buff_has_frags(xdp))) | 889 | ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED); |
| 897 | ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED); | ||
| 898 | return -ENOMEM; | 890 | return -ENOMEM; |
| 899 | } | 891 | } |
| 900 | 892 | ||
| 901 | __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page, | 893 | __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page, |
| 902 | rx_buf->page_offset, size); | 894 | rx_buf->page_offset, size); |
| 903 | sinfo->xdp_frags_size += size; | 895 | sinfo->xdp_frags_size += size; |
| 896 | /* remember frag count before XDP prog execution; bpf_xdp_adjust_tail() | ||
| 897 | * can pop off frags but driver has to handle it on its own | ||
| 898 | */ | ||
| 899 | rx_ring->nr_frags = sinfo->nr_frags; | ||
| 904 | 900 | ||
| 905 | if (page_is_pfmemalloc(rx_buf->page)) | 901 | if (page_is_pfmemalloc(rx_buf->page)) |
| 906 | xdp_buff_set_frag_pfmemalloc(xdp); | 902 | xdp_buff_set_frag_pfmemalloc(xdp); |
| @@ -1251,6 +1247,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) · 344 unmodified lines | |||
| 1251 | 1247 | ||
| 1252 | xdp->data = NULL; | 1248 | xdp->data = NULL; |
| 1253 | rx_ring->first_desc = ntc; | 1249 | rx_ring->first_desc = ntc; |
| 1250 | rx_ring->nr_frags = 0; | ||
| 1254 | continue; | 1251 | continue; |
| 1255 | construct_skb: | 1252 | construct_skb: |
| 1256 | if (likely(ice_ring_uses_build_skb(rx_ring))) | 1253 | if (likely(ice_ring_uses_build_skb(rx_ring))) |
| @@ -1266,10 +1263,12 @@ construct_skb: · 9 unmodified lines | |||
| 1266 | ICE_XDP_CONSUMED); | 1263 | ICE_XDP_CONSUMED); |
| 1267 | xdp->data = NULL; | 1264 | xdp->data = NULL; |
| 1268 | rx_ring->first_desc = ntc; | 1265 | rx_ring->first_desc = ntc; |
| 1266 | rx_ring->nr_frags = 0; | ||
| 1269 | break; | 1267 | break; |
| 1270 | } | 1268 | } |
| 1271 | xdp->data = NULL; | 1269 | xdp->data = NULL; |
| 1272 | rx_ring->first_desc = ntc; | 1270 | rx_ring->first_desc = ntc; |
| 1271 | rx_ring->nr_frags = 0; | ||
| 1273 | 1272 | ||
| 1274 | stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_RXE_S); | 1273 | stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_RXE_S); |
| 1275 | if (unlikely(ice_test_staterr(rx_desc->wb.status_error0, | 1274 | if (unlikely(ice_test_staterr(rx_desc->wb.status_error0, |
| @@ -358,6 +358,7 @@ struct ice_rx_ring { · 357 unmodified lines | |||
| 358 | struct ice_tx_ring *xdp_ring; | 358 | struct ice_tx_ring *xdp_ring; |
| 359 | struct ice_rx_ring *next; /* pointer to next ring in q_vector */ | 359 | struct ice_rx_ring *next; /* pointer to next ring in q_vector */ |
| 360 | struct xsk_buff_pool *xsk_pool; | 360 | struct xsk_buff_pool *xsk_pool; |
| 361 | u32 nr_frags; | ||
| 361 | dma_addr_t dma; /* physical address of ring */ | 362 | dma_addr_t dma; /* physical address of ring */ |
| 362 | u16 rx_buf_len; | 363 | u16 rx_buf_len; |
| 363 | u8 dcb_tc; /* Traffic class of ring */ | 364 | u8 dcb_tc; /* Traffic class of ring */ |
| @@ -12,26 +12,39 @@ · 11 unmodified lines | |||
| 12 | * act: action to store onto Rx buffers related to XDP buffer parts | 12 | * act: action to store onto Rx buffers related to XDP buffer parts |
| 13 | * | 13 | * |
| 14 | * Set action that should be taken before putting Rx buffer from first frag | 14 | * Set action that should be taken before putting Rx buffer from first frag |
| 15 | * to one before last. Last one is handled by caller of this function as it | 15 | * to the last. |
| 16 | * is the EOP frag that is currently being processed. This function is | ||
| 17 | * supposed to be called only when XDP buffer contains frags. | ||
| 18 | */ | 16 | */ |
| 19 | static inline void | 17 | static inline void |
| 20 | ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring, | 18 | ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring, |
| 21 | const unsigned int act) | 19 | const unsigned int act) |
| 22 | { | 20 | { |
| 23 | const struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); | 21 | u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags; |
| 24 | u32 first = rx_ring->first_desc; | 22 | u32 nr_frags = rx_ring->nr_frags + 1; |
| 25 | u32 nr_frags = sinfo->nr_frags; | 23 | u32 idx = rx_ring->first_desc; |
| 26 | u32 cnt = rx_ring->count; | 24 | u32 cnt = rx_ring->count; |
| 27 | struct ice_rx_buf *buf; | 25 | struct ice_rx_buf *buf; |
| 28 | 26 | ||
| 29 | for (int i = 0; i < nr_frags; i++) { | 27 | for (int i = 0; i < nr_frags; i++) { |
| 30 | buf = &rx_ring->rx_buf[first]; | 28 | buf = &rx_ring->rx_buf[idx]; |
| 31 | buf->act = act; | 29 | buf->act = act; |
| 32 | 30 | ||
| 33 | if (++first == cnt) | 31 | if (++idx == cnt) |
| 34 | first = 0; | 32 | idx = 0; |
| 33 | } | ||
| 34 | |||
| 35 | /* adjust pagecnt_bias on frags freed by XDP prog */ | ||
| 36 | if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) { | ||
| 37 | u32 delta = rx_ring->nr_frags - sinfo_frags; | ||
| 38 | |||
| 39 | while (delta) { | ||
| 40 | if (idx == 0) | ||
| 41 | idx = cnt - 1; | ||
| 42 | else | ||
| 43 | idx--; | ||
| 44 | buf = &rx_ring->rx_buf[idx]; | ||
| 45 | buf->pagecnt_bias--; | ||
| 46 | delta--; | ||
| 47 | } | ||
| 35 | } | 48 | } |
| 36 | } | 49 | } |
| 37 | 50 | ||
| @@ -1072,7 +1072,7 @@ struct ice_aq_get_set_rss_lut_params { · 1071 unmodified lines | |||
| 1072 | #define ICE_OROM_VER_BUILD_SHIFT 8 | 1072 | #define ICE_OROM_VER_BUILD_SHIFT 8 |
| 1073 | #define ICE_OROM_VER_BUILD_MASK (0xffff << ICE_OROM_VER_BUILD_SHIFT) | 1073 | #define ICE_OROM_VER_BUILD_MASK (0xffff << ICE_OROM_VER_BUILD_SHIFT) |
| 1074 | #define ICE_OROM_VER_SHIFT 24 | 1074 | #define ICE_OROM_VER_SHIFT 24 |
| 1075 | #define ICE_OROM_VER_MASK (0xff << ICE_OROM_VER_SHIFT) | 1075 | #define ICE_OROM_VER_MASK (0xffU << ICE_OROM_VER_SHIFT) |
| 1076 | #define ICE_SR_PFA_PTR 0x40 | 1076 | #define ICE_SR_PFA_PTR 0x40 |
| 1077 | #define ICE_SR_1ST_NVM_BANK_PTR 0x42 | 1077 | #define ICE_SR_1ST_NVM_BANK_PTR 0x42 |
| 1078 | #define ICE_SR_NVM_BANK_SIZE 0x43 | 1078 | #define ICE_SR_NVM_BANK_SIZE 0x43 |
| @@ -825,7 +825,8 @@ ice_add_xsk_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *first, · 824 unmodified lines | |||
| 825 | } | 825 | } |
| 826 | 826 | ||
| 827 | __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, | 827 | __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, |
| 828 | virt_to_page(xdp->data_hard_start), 0, size); | 828 | virt_to_page(xdp->data_hard_start), |
| 829 | XDP_PACKET_HEADROOM, size); | ||
| 829 | sinfo->xdp_frags_size += size; | 830 | sinfo->xdp_frags_size += size; |
| 830 | xsk_buff_add_frag(xdp); | 831 | xsk_buff_add_frag(xdp); |
| 831 | 832 | ||
| @@ -895,7 +896,6 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget) · 63 unmodified lines | |||
| 895 | 896 | ||
| 896 | if (!first) { | 897 | if (!first) { |
| 897 | first = xdp; | 898 | first = xdp; |
| 898 | xdp_buff_clear_frags_flag(first); | ||
| 899 | } else if (ice_add_xsk_frag(rx_ring, first, xdp, size)) { | 899 | } else if (ice_add_xsk_frag(rx_ring, first, xdp, size)) { |
| 900 | break; | 900 | break; |
| 901 | } | 901 | } |
| @@ -783,6 +783,8 @@ static int idpf_cfg_netdev(struct idpf_vport *vport) · 782 unmodified lines | |||
| 783 | /* setup watchdog timeout value to be 5 second */ | 783 | /* setup watchdog timeout value to be 5 second */ |
| 784 | netdev->watchdog_timeo = 5 * HZ; | 784 | netdev->watchdog_timeo = 5 * HZ; |
| 785 | 785 | ||
| 786 | netdev->dev_port = idx; | ||
| 787 | |||
| 786 | /* configure default MTU size */ | 788 | /* configure default MTU size */ |
| 787 | netdev->min_mtu = ETH_MIN_MTU; | 789 | netdev->min_mtu = ETH_MIN_MTU; |
| 788 | netdev->max_mtu = vport->max_mtu; | 790 | netdev->max_mtu = vport->max_mtu; |
| @@ -978,7 +978,7 @@ struct virtchnl2_ptype { · 977 unmodified lines | |||
| 978 | u8 proto_id_count; | 978 | u8 proto_id_count; |
| 979 | __le16 pad; | 979 | __le16 pad; |
| 980 | __le16 proto_id[]; | 980 | __le16 proto_id[]; |
| 981 | }; | 981 | } __packed __aligned(2); |
| 982 | VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype); | 982 | VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype); |
| 983 | 983 | ||
| 984 | /** | 984 | /** |
| @@ -716,7 +716,8 @@ static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, · 715 unmodified lines | |||
| 716 | if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { | 716 | if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { |
| 717 | error = FIELD_GET(IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK, command); | 717 | error = FIELD_GET(IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK, command); |
| 718 | hw_dbg(hw, "Failed to read, error %x\n", error); | 718 | hw_dbg(hw, "Failed to read, error %x\n", error); |
| 719 | return -EIO; | 719 | ret = -EIO; |
| 720 | goto out; | ||
| 720 | } | 721 | } |
| 721 | 722 | ||
| 722 | if (!ret) | 723 | if (!ret) |
| @@ -318,4 +318,5 @@ static struct platform_driver liteeth_driver = { · 317 unmodified lines | |||
| 318 | module_platform_driver(liteeth_driver); | 318 | module_platform_driver(liteeth_driver); |
| 319 | 319 | ||
| 320 | MODULE_AUTHOR("Joel Stanley <joel@jms.id.au>"); | 320 | MODULE_AUTHOR("Joel Stanley <joel@jms.id.au>"); |
| 321 | MODULE_DESCRIPTION("LiteX Liteeth Ethernet driver"); | ||
| 321 | MODULE_LICENSE("GPL"); | 322 | MODULE_LICENSE("GPL"); |
| @@ -614,12 +614,38 @@ static void mvpp23_bm_set_8pool_mode(struct mvpp2 *priv) · 613 unmodified lines | |||
| 614 | mvpp2_write(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG, val); | 614 | mvpp2_write(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG, val); |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | /* Cleanup pool before actual initialization in the OS */ | ||
| 618 | static void mvpp2_bm_pool_cleanup(struct mvpp2 *priv, int pool_id) | ||
| 619 | { | ||
| 620 | unsigned int thread = mvpp2_cpu_to_thread(priv, get_cpu()); | ||
| 621 | u32 val; | ||
| 622 | int i; | ||
| 623 | |||
| 624 | /* Drain the BM from all possible residues left by firmware */ | ||
| 625 | for (i = 0; i < MVPP2_BM_POOL_SIZE_MAX; i++) | ||
| 626 | mvpp2_thread_read(priv, thread, MVPP2_BM_PHY_ALLOC_REG(pool_id)); | ||
| 627 | |||
| 628 | put_cpu(); | ||
| 629 | |||
| 630 | /* Stop the BM pool */ | ||
| 631 | val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(pool_id)); | ||
| 632 | val |= MVPP2_BM_STOP_MASK; | ||
| 633 | mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(pool_id), val); | ||
| 634 | } | ||
| 635 | |||
| 617 | static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) | 636 | static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) |
| 618 | { | 637 | { |
| 619 | enum dma_data_direction dma_dir = DMA_FROM_DEVICE; | 638 | enum dma_data_direction dma_dir = DMA_FROM_DEVICE; |
| 620 | int i, err, poolnum = MVPP2_BM_POOLS_NUM; | 639 | int i, err, poolnum = MVPP2_BM_POOLS_NUM; |
| 621 | struct mvpp2_port *port; | 640 | struct mvpp2_port *port; |
| 622 | 641 | ||
| 642 | if (priv->percpu_pools) | ||
| 643 | poolnum = mvpp2_get_nrxqs(priv) * 2; | ||
| 644 | |||
| 645 | /* Clean up the pool state in case it contains stale state */ | ||
| 646 | for (i = 0; i < poolnum; i++) | ||
| 647 | mvpp2_bm_pool_cleanup(priv, i); | ||
| 648 | |||
| 623 | if (priv->percpu_pools) { | 649 | if (priv->percpu_pools) { |
| 624 | for (i = 0; i < priv->port_count; i++) { | 650 | for (i = 0; i < priv->port_count; i++) { |
| 625 | port = priv->port_list[i]; | 651 | port = priv->port_list[i]; |
| @@ -629,7 +655,6 @@ static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) · 3 unmodified lines | |||
| 629 | } | 655 | } |
| 630 | } | 656 | } |
| 631 | 657 | ||
| 632 | poolnum = mvpp2_get_nrxqs(priv) * 2; | ||
| 633 | for (i = 0; i < poolnum; i++) { | 658 | for (i = 0; i < poolnum; i++) { |
| 634 | /* the pool in use */ | 659 | /* the pool in use */ |
| 635 | int pn = i / (poolnum / 2); | 660 | int pn = i / (poolnum / 2); |
| @@ -413,4 +413,5 @@ const char *otx2_mbox_id2name(u16 id) · 412 unmodified lines | |||
| 413 | EXPORT_SYMBOL(otx2_mbox_id2name); | 413 | EXPORT_SYMBOL(otx2_mbox_id2name); |
| 414 | 414 | ||
| 415 | MODULE_AUTHOR("Marvell."); | 415 | MODULE_AUTHOR("Marvell."); |
| 416 | MODULE_DESCRIPTION("Marvell RVU NIC Mbox helpers"); | ||
| 416 | MODULE_LICENSE("GPL v2"); | 417 | MODULE_LICENSE("GPL v2"); |
| @@ -1850,8 +1850,8 @@ void npc_mcam_rsrcs_deinit(struct rvu *rvu) · 1849 unmodified lines | |||
| 1850 | { | 1850 | { |
| 1851 | struct npc_mcam *mcam = &rvu->hw->mcam; | 1851 | struct npc_mcam *mcam = &rvu->hw->mcam; |
| 1852 | 1852 | ||
| 1853 | kfree(mcam->bmap); | 1853 | bitmap_free(mcam->bmap); |
| 1854 | kfree(mcam->bmap_reverse); | 1854 | bitmap_free(mcam->bmap_reverse); |
| 1855 | kfree(mcam->entry2pfvf_map); | 1855 | kfree(mcam->entry2pfvf_map); |
| 1856 | kfree(mcam->cntr2pfvf_map); | 1856 | kfree(mcam->cntr2pfvf_map); |
| 1857 | kfree(mcam->entry2cntr_map); | 1857 | kfree(mcam->entry2cntr_map); |
| @@ -1904,21 +1904,20 @@ int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr) · 46 unmodified lines | |||
| 1904 | mcam->pf_offset = mcam->nixlf_offset + nixlf_count; | 1904 | mcam->pf_offset = mcam->nixlf_offset + nixlf_count; |
| 1905 | 1905 | ||
| 1906 | /* Allocate bitmaps for managing MCAM entries */ | 1906 | /* Allocate bitmaps for managing MCAM entries */ |
| 1907 | mcam->bmap = kmalloc_array(BITS_TO_LONGS(mcam->bmap_entries), | 1907 | mcam->bmap = bitmap_zalloc(mcam->bmap_entries, GFP_KERNEL); |
| 1908 | sizeof(long), GFP_KERNEL); | ||
| 1909 | if (!mcam->bmap) | 1908 | if (!mcam->bmap) |
| 1910 | return -ENOMEM; | 1909 | return -ENOMEM; |
| 1911 | 1910 | ||
| 1912 | mcam->bmap_reverse = kmalloc_array(BITS_TO_LONGS(mcam->bmap_entries), | 1911 | mcam->bmap_reverse = bitmap_zalloc(mcam->bmap_entries, GFP_KERNEL); |
| 1913 | sizeof(long), GFP_KERNEL); | ||
| 1914 | if (!mcam->bmap_reverse) | 1912 | if (!mcam->bmap_reverse) |
| 1915 | goto free_bmap; | 1913 | goto free_bmap; |
| 1916 | 1914 | ||
| 1917 | mcam->bmap_fcnt = mcam->bmap_entries; | 1915 | mcam->bmap_fcnt = mcam->bmap_entries; |
| 1918 | 1916 | ||
| 1919 | /* Alloc memory for saving entry to RVU PFFUNC allocation mapping */ | 1917 | /* Alloc memory for saving entry to RVU PFFUNC allocation mapping */ |
| 1920 | mcam->entry2pfvf_map = kmalloc_array(mcam->bmap_entries, | 1918 | mcam->entry2pfvf_map = kcalloc(mcam->bmap_entries, sizeof(u16), |
| 1921 | sizeof(u16), GFP_KERNEL); | 1919 | GFP_KERNEL); |
| 1920 | |||
| 1922 | if (!mcam->entry2pfvf_map) | 1921 | if (!mcam->entry2pfvf_map) |
| 1923 | goto free_bmap_reverse; | 1922 | goto free_bmap_reverse; |
| 1924 | 1923 | ||
| @@ -1941,21 +1940,21 @@ int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr) · 16 unmodified lines | |||
| 1941 | if (err) | 1940 | if (err) |
| 1942 | goto free_entry_map; | 1941 | goto free_entry_map; |
| 1943 | 1942 | ||
| 1944 | mcam->cntr2pfvf_map = kmalloc_array(mcam->counters.max, | 1943 | mcam->cntr2pfvf_map = kcalloc(mcam->counters.max, sizeof(u16), |
| 1945 | sizeof(u16), GFP_KERNEL); | 1944 | GFP_KERNEL); |
| 1946 | if (!mcam->cntr2pfvf_map) | 1945 | if (!mcam->cntr2pfvf_map) |
| 1947 | goto free_cntr_bmap; | 1946 | goto free_cntr_bmap; |
| 1948 | 1947 | ||
| 1949 | /* Alloc memory for MCAM entry to counter mapping and for tracking | 1948 | /* Alloc memory for MCAM entry to counter mapping and for tracking |
| 1950 | * counter's reference count. | 1949 | * counter's reference count. |
| 1951 | */ | 1950 | */ |
| 1952 | mcam->entry2cntr_map = kmalloc_array(mcam->bmap_entries, | 1951 | mcam->entry2cntr_map = kcalloc(mcam->bmap_entries, sizeof(u16), |
| 1953 | sizeof(u16), GFP_KERNEL); | 1952 | GFP_KERNEL); |
| 1954 | if (!mcam->entry2cntr_map) | 1953 | if (!mcam->entry2cntr_map) |
| 1955 | goto free_cntr_map; | 1954 | goto free_cntr_map; |
| 1956 | 1955 | ||
| 1957 | mcam->cntr_refcnt = kmalloc_array(mcam->counters.max, | 1956 | mcam->cntr_refcnt = kcalloc(mcam->counters.max, sizeof(u16), |
| 1958 | sizeof(u16), GFP_KERNEL); | 1957 | GFP_KERNEL); |
| 1959 | if (!mcam->cntr_refcnt) | 1958 | if (!mcam->cntr_refcnt) |
| 1960 | goto free_entry_cntr_map; | 1959 | goto free_entry_cntr_map; |
| 1961 | 1960 | ||
| @@ -1988,9 +1987,9 @@ free_cntr_bmap: · 26 unmodified lines | |||
| 1988 | free_entry_map: | 1987 | free_entry_map: |
| 1989 | kfree(mcam->entry2pfvf_map); | 1988 | kfree(mcam->entry2pfvf_map); |
| 1990 | free_bmap_reverse: | 1989 | free_bmap_reverse: |
| 1991 | kfree(mcam->bmap_reverse); | 1990 | bitmap_free(mcam->bmap_reverse); |
| 1992 | free_bmap: | 1991 | free_bmap: |
| 1993 | kfree(mcam->bmap); | 1992 | bitmap_free(mcam->bmap); |
| 1994 | 1993 | ||
| 1995 | return -ENOMEM; | 1994 | return -ENOMEM; |
| 1996 | } | 1995 | } |
| @@ -951,8 +951,11 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) · 950 unmodified lines | |||
| 951 | if (pfvf->ptp && qidx < pfvf->hw.tx_queues) { | 951 | if (pfvf->ptp && qidx < pfvf->hw.tx_queues) { |
| 952 | err = qmem_alloc(pfvf->dev, &sq->timestamps, qset->sqe_cnt, | 952 | err = qmem_alloc(pfvf->dev, &sq->timestamps, qset->sqe_cnt, |
| 953 | sizeof(*sq->timestamps)); | 953 | sizeof(*sq->timestamps)); |
| 954 | if (err) | 954 | if (err) { |
| 955 | kfree(sq->sg); | ||
| 956 | sq->sg = NULL; | ||
| 955 | return err; | 957 | return err; |
| 958 | } | ||
| 956 | } | 959 | } |
| 957 | 960 | ||
| 958 | sq->head = 0; | 961 | sq->head = 0; |
| @@ -968,7 +971,14 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) · 9 unmodified lines | |||
| 968 | sq->stats.bytes = 0; | 971 | sq->stats.bytes = 0; |
| 969 | sq->stats.pkts = 0; | 972 | sq->stats.pkts = 0; |
| 970 | 973 | ||
| 971 | return pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura); | 974 | err = pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura); |
| 975 | if (err) { | ||
| 976 | kfree(sq->sg); | ||
| 977 | sq->sg = NULL; | ||
| 978 | return err; | ||
| 979 | } | ||
| 980 | |||
| 981 | return 0; | ||
| 972 | 982 | ||
| 973 | } | 983 | } |
| 974 | 984 | ||
| @@ -314,7 +314,6 @@ static int otx2_set_channels(struct net_device *dev, · 313 unmodified lines | |||
| 314 | pfvf->hw.tx_queues = channel->tx_count; | 314 | pfvf->hw.tx_queues = channel->tx_count; |
| 315 | if (pfvf->xdp_prog) | 315 | if (pfvf->xdp_prog) |
| 316 | pfvf->hw.xdp_queues = channel->rx_count; | 316 | pfvf->hw.xdp_queues = channel->rx_count; |
| 317 | pfvf->hw.non_qos_queues = pfvf->hw.tx_queues + pfvf->hw.xdp_queues; | ||
| 318 | 317 | ||
| 319 | if (if_up) | 318 | if (if_up) |
| 320 | err = dev->netdev_ops->ndo_open(dev); | 319 | err = dev->netdev_ops->ndo_open(dev); |
| @@ -1744,6 +1744,7 @@ int otx2_open(struct net_device *netdev) · 1743 unmodified lines | |||
| 1744 | /* RQ and SQs are mapped to different CQs, | 1744 | /* RQ and SQs are mapped to different CQs, |
| 1745 | * so find out max CQ IRQs (i.e CINTs) needed. | 1745 | * so find out max CQ IRQs (i.e CINTs) needed. |
| 1746 | */ | 1746 | */ |
| 1747 | pf->hw.non_qos_queues = pf->hw.tx_queues + pf->hw.xdp_queues; | ||
| 1747 | pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, | 1748 | pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, |
| 1748 | pf->hw.tc_tx_queues); | 1749 | pf->hw.tc_tx_queues); |
| 1749 | 1750 | ||
| @@ -2643,8 +2644,6 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog) · 893 unmodified lines | |||
| 2643 | xdp_features_clear_redirect_target(dev); | 2644 | xdp_features_clear_redirect_target(dev); |
| 2644 | } | 2645 | } |
| 2645 | 2646 | ||
| 2646 | pf->hw.non_qos_queues += pf->hw.xdp_queues; | ||
| 2647 | |||
| 2648 | if (if_up) | 2647 | if (if_up) |
| 2649 | otx2_open(pf->netdev); | 2648 | otx2_open(pf->netdev); |
| 2650 | 2649 | ||
| @@ -1403,7 +1403,7 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, · 1402 unmodified lines | |||
| 1403 | struct otx2_cq_queue *cq, | 1403 | struct otx2_cq_queue *cq, |
| 1404 | bool *need_xdp_flush) | 1404 | bool *need_xdp_flush) |
| 1405 | { | 1405 | { |
| 1406 | unsigned char *hard_start, *data; | 1406 | unsigned char *hard_start; |
| 1407 | int qidx = cq->cq_idx; | 1407 | int qidx = cq->cq_idx; |
| 1408 | struct xdp_buff xdp; | 1408 | struct xdp_buff xdp; |
| 1409 | struct page *page; | 1409 | struct page *page; |
| @@ -1417,9 +1417,8 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, · 7 unmodified lines | |||
| 1417 | 1417 | ||
| 1418 | xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); | 1418 | xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); |
| 1419 | 1419 | ||
| 1420 | data = (unsigned char *)phys_to_virt(pa); | 1420 | hard_start = (unsigned char *)phys_to_virt(pa); |
| 1421 | hard_start = page_address(page); | 1421 | xdp_prepare_buff(&xdp, hard_start, OTX2_HEAD_ROOM, |
| 1422 | xdp_prepare_buff(&xdp, hard_start, data - hard_start, | ||
| 1423 | cqe->sg.seg_size, false); | 1422 | cqe->sg.seg_size, false); |
| 1424 | 1423 | ||
| 1425 | act = bpf_prog_run_xdp(prog, &xdp); | 1424 | act = bpf_prog_run_xdp(prog, &xdp); |
| @@ -4761,7 +4761,10 @@ static int mtk_probe(struct platform_device *pdev) · 4760 unmodified lines | |||
| 4761 | } | 4761 | } |
| 4762 | 4762 | ||
| 4763 | if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { | 4763 | if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { |
| 4764 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); | 4764 | err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); |
| 4765 | if (!err) | ||
| 4766 | err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); | ||
| 4767 | |||
| 4765 | if (err) { | 4768 | if (err) { |
| 4766 | dev_err(&pdev->dev, "Wrong DMA config\n"); | 4769 | dev_err(&pdev->dev, "Wrong DMA config\n"); |
| 4767 | return -EINVAL; | 4770 | return -EINVAL; |
| @@ -1923,6 +1923,7 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status, · 1922 unmodified lines | |||
| 1923 | { | 1923 | { |
| 1924 | const char *namep = mlx5_command_str(opcode); | 1924 | const char *namep = mlx5_command_str(opcode); |
| 1925 | struct mlx5_cmd_stats *stats; | 1925 | struct mlx5_cmd_stats *stats; |
| 1926 | unsigned long flags; | ||
| 1926 | 1927 | ||
| 1927 | if (!err || !(strcmp(namep, "unknown command opcode"))) | 1928 | if (!err || !(strcmp(namep, "unknown command opcode"))) |
| 1928 | return; | 1929 | return; |
| @@ -1930,7 +1931,7 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status, · 1 unmodified line | |||
| 1930 | stats = xa_load(&dev->cmd.stats, opcode); | 1931 | stats = xa_load(&dev->cmd.stats, opcode); |
| 1931 | if (!stats) | 1932 | if (!stats) |
| 1932 | return; | 1933 | return; |
| 1933 | spin_lock_irq(&stats->lock); | 1934 | spin_lock_irqsave(&stats->lock, flags); |
| 1934 | stats->failed++; | 1935 | stats->failed++; |
| 1935 | if (err < 0) | 1936 | if (err < 0) |
| 1936 | stats->last_failed_errno = -err; | 1937 | stats->last_failed_errno = -err; |
| @@ -1939,7 +1940,7 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status, · 2 unmodified lines | |||
| 1939 | stats->last_failed_mbox_status = status; | 1940 | stats->last_failed_mbox_status = status; |
| 1940 | stats->last_failed_syndrome = syndrome; | 1941 | stats->last_failed_syndrome = syndrome; |
| 1941 | } | 1942 | } |
| 1942 | spin_unlock_irq(&stats->lock); | 1943 | spin_unlock_irqrestore(&stats->lock, flags); |
| 1943 | } | 1944 | } |
| 1944 | 1945 | ||
| 1945 | /* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */ | 1946 | /* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */ |
| @@ -1124,7 +1124,7 @@ static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev) · 1123 unmodified lines | |||
| 1124 | extern const struct ethtool_ops mlx5e_ethtool_ops; | 1124 | extern const struct ethtool_ops mlx5e_ethtool_ops; |
| 1125 | 1125 | ||
| 1126 | int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, u32 *mkey); | 1126 | int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, u32 *mkey); |
| 1127 | int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev); | 1127 | int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises); |
| 1128 | void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev); | 1128 | void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev); |
| 1129 | int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb, | 1129 | int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb, |
| 1130 | bool enable_mc_lb); | 1130 | bool enable_mc_lb); |
| @@ -436,6 +436,7 @@ static int fs_any_create_groups(struct mlx5e_flow_table *ft) · 435 unmodified lines | |||
| 436 | in = kvzalloc(inlen, GFP_KERNEL); | 436 | in = kvzalloc(inlen, GFP_KERNEL); |
| 437 | if (!in || !ft->g) { | 437 | if (!in || !ft->g) { |
| 438 | kfree(ft->g); | 438 | kfree(ft->g); |
| 439 | ft->g = NULL; | ||
| 439 | kvfree(in); | 440 | kvfree(in); |
| 440 | return -ENOMEM; | 441 | return -ENOMEM; |
| 441 | } | 442 | } |
| @@ -1064,8 +1064,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev, · 1063 unmodified lines | |||
| 1064 | void *wq = MLX5_ADDR_OF(sqc, sqc, wq); | 1064 | void *wq = MLX5_ADDR_OF(sqc, sqc, wq); |
| 1065 | bool allow_swp; | 1065 | bool allow_swp; |
| 1066 | 1066 | ||
| 1067 | allow_swp = | 1067 | allow_swp = mlx5_geneve_tx_allowed(mdev) || |
| 1068 | mlx5_geneve_tx_allowed(mdev) || !!mlx5_ipsec_device_caps(mdev); | 1068 | (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO); |
| 1069 | mlx5e_build_sq_param_common(mdev, param); | 1069 | mlx5e_build_sq_param_common(mdev, param); |
| 1070 | MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size); | 1070 | MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size); |
| 1071 | MLX5_SET(sqc, sqc, allow_swp, allow_swp); | 1071 | MLX5_SET(sqc, sqc, allow_swp, allow_swp); |
| @@ -213,7 +213,7 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, · 212 unmodified lines | |||
| 213 | mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp); | 213 | mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp); |
| 214 | out: | 214 | out: |
| 215 | napi_consume_skb(skb, budget); | 215 | napi_consume_skb(skb, budget); |
| 216 | md_buff[*md_buff_sz++] = metadata_id; | 216 | md_buff[(*md_buff_sz)++] = metadata_id; |
| 217 | if (unlikely(mlx5e_ptp_metadata_map_unhealthy(&ptpsq->metadata_map)) && | 217 | if (unlikely(mlx5e_ptp_metadata_map_unhealthy(&ptpsq->metadata_map)) && |
| 218 | !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) | 218 | !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) |
| 219 | queue_work(ptpsq->txqsq.priv->wq, &ptpsq->report_unhealthy_work); | 219 | queue_work(ptpsq->txqsq.priv->wq, &ptpsq->report_unhealthy_work); |
| @@ -336,12 +336,17 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, · 335 unmodified lines | |||
| 336 | /* iv len */ | 336 | /* iv len */ |
| 337 | aes_gcm->icv_len = x->aead->alg_icv_len; | 337 | aes_gcm->icv_len = x->aead->alg_icv_len; |
| 338 | 338 | ||
| 339 | attrs->dir = x->xso.dir; | ||
| 340 | |||
| 339 | /* esn */ | 341 | /* esn */ |
| 340 | if (x->props.flags & XFRM_STATE_ESN) { | 342 | if (x->props.flags & XFRM_STATE_ESN) { |
| 341 | attrs->replay_esn.trigger = true; | 343 | attrs->replay_esn.trigger = true; |
| 342 | attrs->replay_esn.esn = sa_entry->esn_state.esn; | 344 | attrs->replay_esn.esn = sa_entry->esn_state.esn; |
| 343 | attrs->replay_esn.esn_msb = sa_entry->esn_state.esn_msb; | 345 | attrs->replay_esn.esn_msb = sa_entry->esn_state.esn_msb; |
| 344 | attrs->replay_esn.overlap = sa_entry->esn_state.overlap; | 346 | attrs->replay_esn.overlap = sa_entry->esn_state.overlap; |
| 347 | if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) | ||
| 348 | goto skip_replay_window; | ||
| 349 | |||
| 345 | switch (x->replay_esn->replay_window) { | 350 | switch (x->replay_esn->replay_window) { |
| 346 | case 32: | 351 | case 32: |
| 347 | attrs->replay_esn.replay_window = | 352 | attrs->replay_esn.replay_window = |
| @@ -365,7 +370,7 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, · 17 unmodified lines | |||
| 365 | } | 370 | } |
| 366 | } | 371 | } |
| 367 | 372 | ||
| 368 | attrs->dir = x->xso.dir; | 373 | skip_replay_window: |
| 369 | /* spi */ | 374 | /* spi */ |
| 370 | attrs->spi = be32_to_cpu(x->id.spi); | 375 | attrs->spi = be32_to_cpu(x->id.spi); |
| 371 | 376 | ||
| @@ -501,7 +506,8 @@ static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev, · 129 unmodified lines | |||
| 501 | return -EINVAL; | 506 | return -EINVAL; |
| 502 | } | 507 | } |
| 503 | 508 | ||
| 504 | if (x->replay_esn && x->replay_esn->replay_window != 32 && | 509 | if (x->replay_esn && x->xso.dir == XFRM_DEV_OFFLOAD_IN && |
| 510 | x->replay_esn->replay_window != 32 && | ||
| 505 | x->replay_esn->replay_window != 64 && | 511 | x->replay_esn->replay_window != 64 && |
| 506 | x->replay_esn->replay_window != 128 && | 512 | x->replay_esn->replay_window != 128 && |
| 507 | x->replay_esn->replay_window != 256) { | 513 | x->replay_esn->replay_window != 256) { |
| @@ -254,11 +254,13 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, · 253 unmodified lines | |||
| 254 | 254 | ||
| 255 | ft->g = kcalloc(MLX5E_ARFS_NUM_GROUPS, | 255 | ft->g = kcalloc(MLX5E_ARFS_NUM_GROUPS, |
| 256 | sizeof(*ft->g), GFP_KERNEL); | 256 | sizeof(*ft->g), GFP_KERNEL); |
| 257 | in = kvzalloc(inlen, GFP_KERNEL); | 257 | if (!ft->g) |
| 258 | if (!in || !ft->g) { | ||
| 259 | kfree(ft->g); | ||
| 260 | kvfree(in); | ||
| 261 | return -ENOMEM; | 258 | return -ENOMEM; |
| 259 | |||
| 260 | in = kvzalloc(inlen, GFP_KERNEL); | ||
| 261 | if (!in) { | ||
| 262 | err = -ENOMEM; | ||
| 263 | goto err_free_g; | ||
| 262 | } | 264 | } |
| 263 | 265 | ||
| 264 | mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); | 266 | mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); |
| @@ -278,7 +280,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, · 13 unmodified lines | |||
| 278 | break; | 280 | break; |
| 279 | default: | 281 | default: |
| 280 | err = -EINVAL; | 282 | err = -EINVAL; |
| 281 | goto out; | 283 | goto err_free_in; |
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | switch (type) { | 286 | switch (type) { |
| @@ -300,7 +302,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, · 15 unmodified lines | |||
| 300 | break; | 302 | break; |
| 301 | default: | 303 | default: |
| 302 | err = -EINVAL; | 304 | err = -EINVAL; |
| 303 | goto out; | 305 | goto err_free_in; |
| 304 | } | 306 | } |
| 305 | 307 | ||
| 306 | MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); | 308 | MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); |
| @@ -309,7 +311,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, · 2 unmodified lines | |||
| 309 | MLX5_SET_CFG(in, end_flow_index, ix - 1); | 311 | MLX5_SET_CFG(in, end_flow_index, ix - 1); |
| 310 | ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); | 312 | ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); |
| 311 | if (IS_ERR(ft->g[ft->num_groups])) | 313 | if (IS_ERR(ft->g[ft->num_groups])) |
| 312 | goto err; | 314 | goto err_clean_group; |
| 313 | ft->num_groups++; | 315 | ft->num_groups++; |
| 314 | 316 | ||
| 315 | memset(in, 0, inlen); | 317 | memset(in, 0, inlen); |
| @@ -318,18 +320,20 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, · 2 unmodified lines | |||
| 318 | MLX5_SET_CFG(in, end_flow_index, ix - 1); | 320 | MLX5_SET_CFG(in, end_flow_index, ix - 1); |
| 319 | ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); | 321 | ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); |
| 320 | if (IS_ERR(ft->g[ft->num_groups])) | 322 | if (IS_ERR(ft->g[ft->num_groups])) |
| 321 | goto err; | 323 | goto err_clean_group; |
| 322 | ft->num_groups++; | 324 | ft->num_groups++; |
| 323 | 325 | ||
| 324 | kvfree(in); | 326 | kvfree(in); |
| 325 | return 0; | 327 | return 0; |
| 326 | 328 | ||
| 327 | err: | 329 | err_clean_group: |
| 328 | err = PTR_ERR(ft->g[ft->num_groups]); | 330 | err = PTR_ERR(ft->g[ft->num_groups]); |
| 329 | ft->g[ft->num_groups] = NULL; | 331 | ft->g[ft->num_groups] = NULL; |
| 330 | out: | 332 | err_free_in: |
| 331 | kvfree(in); | 333 | kvfree(in); |
| 332 | 334 | err_free_g: | |
| 335 | kfree(ft->g); | ||
| 336 | ft->g = NULL; | ||
| 333 | return err; | 337 | return err; |
| 334 | } | 338 | } |
| 335 | 339 | ||
| @@ -95,7 +95,7 @@ static void mlx5e_destroy_tises(struct mlx5_core_dev *mdev, u32 tisn[MLX5_MAX_PO · 94 unmodified lines | |||
| 95 | { | 95 | { |
| 96 | int tc, i; | 96 | int tc, i; |
| 97 | 97 | ||
| 98 | for (i = 0; i < MLX5_MAX_PORTS; i++) | 98 | for (i = 0; i < mlx5e_get_num_lag_ports(mdev); i++) |
| 99 | for (tc = 0; tc < MLX5_MAX_NUM_TC; tc++) | 99 | for (tc = 0; tc < MLX5_MAX_NUM_TC; tc++) |
| 100 | mlx5e_destroy_tis(mdev, tisn[i][tc]); | 100 | mlx5e_destroy_tis(mdev, tisn[i][tc]); |
| 101 | } | 101 | } |
| @@ -110,7 +110,7 @@ static int mlx5e_create_tises(struct mlx5_core_dev *mdev, u32 tisn[MLX5_MAX_PORT · 8 unmodified lines | |||
| 110 | int tc, i; | 110 | int tc, i; |
| 111 | int err; | 111 | int err; |
| 112 | 112 | ||
| 113 | for (i = 0; i < MLX5_MAX_PORTS; i++) { | 113 | for (i = 0; i < mlx5e_get_num_lag_ports(mdev); i++) { |
| 114 | for (tc = 0; tc < MLX5_MAX_NUM_TC; tc++) { | 114 | for (tc = 0; tc < MLX5_MAX_NUM_TC; tc++) { |
| 115 | u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {}; | 115 | u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {}; |
| 116 | void *tisc; | 116 | void *tisc; |
| @@ -140,7 +140,7 @@ err_close_tises: · 23 unmodified lines | |||
| 140 | return err; | 140 | return err; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev) | 143 | int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises) |
| 144 | { | 144 | { |
| 145 | struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs; | 145 | struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs; |
| 146 | int err; | 146 | int err; |
| @@ -169,11 +169,15 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev) · 22 unmodified lines | |||
| 169 | goto err_destroy_mkey; | 169 | goto err_destroy_mkey; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | err = mlx5e_create_tises(mdev, res->tisn); | 172 | if (create_tises) { |
| 173 | if (err) { | 173 | err = mlx5e_create_tises(mdev, res->tisn); |
| 174 | mlx5_core_err(mdev, "alloc tises failed, %d\n", err); | 174 | if (err) { |
| 175 | goto err_destroy_bfreg; | 175 | mlx5_core_err(mdev, "alloc tises failed, %d\n", err); |
| 176 | goto err_destroy_bfreg; | ||
| 177 | } | ||
| 178 | res->tisn_valid = true; | ||
| 176 | } | 179 | } |
| 180 | |||
| 177 | INIT_LIST_HEAD(&res->td.tirs_list); | 181 | INIT_LIST_HEAD(&res->td.tirs_list); |
| 178 | mutex_init(&res->td.list_lock); | 182 | mutex_init(&res->td.list_lock); |
| 179 | 183 | ||
| @@ -203,7 +207,8 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev) · 23 unmodified lines | |||
| 203 | 207 | ||
| 204 | mlx5_crypto_dek_cleanup(mdev->mlx5e_res.dek_priv); | 208 | mlx5_crypto_dek_cleanup(mdev->mlx5e_res.dek_priv); |
| 205 | mdev->mlx5e_res.dek_priv = NULL; | 209 | mdev->mlx5e_res.dek_priv = NULL; |
| 206 | mlx5e_destroy_tises(mdev, res->tisn); | 210 | if (res->tisn_valid) |
| 211 | mlx5e_destroy_tises(mdev, res->tisn); | ||
| 207 | mlx5_free_bfreg(mdev, &res->bfreg); | 212 | mlx5_free_bfreg(mdev, &res->bfreg); |
| 208 | mlx5_core_destroy_mkey(mdev, res->mkey); | 213 | mlx5_core_destroy_mkey(mdev, res->mkey); |
| 209 | mlx5_core_dealloc_transport_domain(mdev, res->td.tdn); | 214 | mlx5_core_dealloc_transport_domain(mdev, res->td.tdn); |
| @@ -5992,7 +5992,7 @@ static int mlx5e_resume(struct auxiliary_device *adev) · 5991 unmodified lines | |||
| 5992 | if (netif_device_present(netdev)) | 5992 | if (netif_device_present(netdev)) |
| 5993 | return 0; | 5993 | return 0; |
| 5994 | 5994 | ||
| 5995 | err = mlx5e_create_mdev_resources(mdev); | 5995 | err = mlx5e_create_mdev_resources(mdev, true); |
| 5996 | if (err) | 5996 | if (err) |
| 5997 | return err; | 5997 | return err; |
| 5998 | 5998 | ||
| @@ -761,7 +761,7 @@ static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp) · 760 unmodified lines | |||
| 761 | 761 | ||
| 762 | err = mlx5e_rss_params_indir_init(&indir, mdev, | 762 | err = mlx5e_rss_params_indir_init(&indir, mdev, |
| 763 | mlx5e_rqt_size(mdev, hp->num_channels), | 763 | mlx5e_rqt_size(mdev, hp->num_channels), |
| 764 | mlx5e_rqt_size(mdev, priv->max_nch)); | 764 | mlx5e_rqt_size(mdev, hp->num_channels)); |
| 765 | if (err) | 765 | if (err) |
| 766 | return err; | 766 | return err; |
| 767 | 767 | ||
| @@ -2014,9 +2014,10 @@ static void mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *flow, · 1246 unmodified lines | |||
| 2014 | list_for_each_entry_safe(peer_flow, tmp, &flow->peer_flows, peer_flows) { | 2014 | list_for_each_entry_safe(peer_flow, tmp, &flow->peer_flows, peer_flows) { |
| 2015 | if (peer_index != mlx5_get_dev_index(peer_flow->priv->mdev)) | 2015 | if (peer_index != mlx5_get_dev_index(peer_flow->priv->mdev)) |
| 2016 | continue; | 2016 | continue; |
| 2017 | |||
| 2018 | list_del(&peer_flow->peer_flows); | ||
| 2017 | if (refcount_dec_and_test(&peer_flow->refcnt)) { | 2019 | if (refcount_dec_and_test(&peer_flow->refcnt)) { |
| 2018 | mlx5e_tc_del_fdb_flow(peer_flow->priv, peer_flow); | 2020 | mlx5e_tc_del_fdb_flow(peer_flow->priv, peer_flow); |
| 2019 | list_del(&peer_flow->peer_flows); | ||
| 2020 | kfree(peer_flow); | 2021 | kfree(peer_flow); |
| 2021 | } | 2022 | } |
| 2022 | } | 2023 | } |
| @@ -83,6 +83,7 @@ mlx5_esw_bridge_mdb_flow_create(u16 esw_owner_vhca_id, struct mlx5_esw_bridge_md · 82 unmodified lines | |||
| 83 | i++; | 83 | i++; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | rule_spec->flow_context.flags |= FLOW_CONTEXT_UPLINK_HAIRPIN_EN; | ||
| 86 | rule_spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; | 87 | rule_spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; |
| 87 | dmac_v = MLX5_ADDR_OF(fte_match_param, rule_spec->match_value, outer_headers.dmac_47_16); | 88 | dmac_v = MLX5_ADDR_OF(fte_match_param, rule_spec->match_value, outer_headers.dmac_47_16); |
| 88 | ether_addr_copy(dmac_v, entry->key.addr); | 89 | ether_addr_copy(dmac_v, entry->key.addr); |
| @@ -587,6 +588,7 @@ mlx5_esw_bridge_mcast_vlan_flow_create(u16 vlan_proto, struct mlx5_esw_bridge_po · 498 unmodified lines | |||
| 587 | if (!rule_spec) | 588 | if (!rule_spec) |
| 588 | return ERR_PTR(-ENOMEM); | 589 | return ERR_PTR(-ENOMEM); |
| 589 | 590 | ||
| 591 | rule_spec->flow_context.flags |= FLOW_CONTEXT_UPLINK_HAIRPIN_EN; | ||
| 590 | rule_spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; | 592 | rule_spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; |
| 591 | 593 | ||
| 592 | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; | 594 | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; |
| @@ -662,6 +664,7 @@ mlx5_esw_bridge_mcast_fwd_flow_create(struct mlx5_esw_bridge_port *port) · 69 unmodified lines | |||
| 662 | dest.vport.flags = MLX5_FLOW_DEST_VPORT_VHCA_ID; | 664 | dest.vport.flags = MLX5_FLOW_DEST_VPORT_VHCA_ID; |
| 663 | dest.vport.vhca_id = port->esw_owner_vhca_id; | 665 | dest.vport.vhca_id = port->esw_owner_vhca_id; |
| 664 | } | 666 | } |
| 667 | rule_spec->flow_context.flags |= FLOW_CONTEXT_UPLINK_HAIRPIN_EN; | ||
| 665 | handle = mlx5_add_flow_rules(port->mcast.ft, rule_spec, &flow_act, &dest, 1); | 668 | handle = mlx5_add_flow_rules(port->mcast.ft, rule_spec, &flow_act, &dest, 1); |
| 666 | 669 | ||
| 667 | kvfree(rule_spec); | 670 | kvfree(rule_spec); |
| @@ -566,6 +566,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, · 565 unmodified lines | |||
| 566 | fte->flow_context.flow_tag); | 566 | fte->flow_context.flow_tag); |
| 567 | MLX5_SET(flow_context, in_flow_context, flow_source, | 567 | MLX5_SET(flow_context, in_flow_context, flow_source, |
| 568 | fte->flow_context.flow_source); | 568 | fte->flow_context.flow_source); |
| 569 | MLX5_SET(flow_context, in_flow_context, uplink_hairpin_en, | ||
| 570 | !!(fte->flow_context.flags & FLOW_CONTEXT_UPLINK_HAIRPIN_EN)); | ||
| 569 | 571 | ||
| 570 | MLX5_SET(flow_context, in_flow_context, extended_destination, | 572 | MLX5_SET(flow_context, in_flow_context, extended_destination, |
| 571 | extended_dest); | 573 | extended_dest); |
| @@ -783,7 +783,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num, · 782 unmodified lines | |||
| 783 | } | 783 | } |
| 784 | 784 | ||
| 785 | /* This should only be called once per mdev */ | 785 | /* This should only be called once per mdev */ |
| 786 | err = mlx5e_create_mdev_resources(mdev); | 786 | err = mlx5e_create_mdev_resources(mdev, false); |
| 787 | if (err) | 787 | if (err) |
| 788 | goto destroy_ht; | 788 | goto destroy_ht; |
| 789 | } | 789 | } |
| @@ -98,7 +98,7 @@ static int create_aso_cq(struct mlx5_aso_cq *cq, void *cqc_data) · 97 unmodified lines | |||
| 98 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, | 98 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, |
| 99 | (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); | 99 | (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); |
| 100 | 100 | ||
| 101 | MLX5_SET(cqc, cqc, cq_period_mode, DIM_CQ_PERIOD_MODE_START_FROM_EQE); | 101 | MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); |
| 102 | MLX5_SET(cqc, cqc, c_eqn_or_apu_element, eqn); | 102 | MLX5_SET(cqc, cqc, c_eqn_or_apu_element, eqn); |
| 103 | MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); | 103 | MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); |
| 104 | MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift - | 104 | MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift - |
| @@ -788,6 +788,7 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher, · 787 unmodified lines | |||
| 788 | switch (action_type) { | 788 | switch (action_type) { |
| 789 | case DR_ACTION_TYP_DROP: | 789 | case DR_ACTION_TYP_DROP: |
| 790 | attr.final_icm_addr = nic_dmn->drop_icm_addr; | 790 | attr.final_icm_addr = nic_dmn->drop_icm_addr; |
| 791 | attr.hit_gvmi = nic_dmn->drop_icm_addr >> 48; | ||
| 791 | break; | 792 | break; |
| 792 | case DR_ACTION_TYP_FT: | 793 | case DR_ACTION_TYP_FT: |
| 793 | dest_action = action; | 794 | dest_action = action; |
| @@ -873,11 +874,17 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher, · 79 unmodified lines | |||
| 873 | action->sampler->tx_icm_addr; | 874 | action->sampler->tx_icm_addr; |
| 874 | break; | 875 | break; |
| 875 | case DR_ACTION_TYP_VPORT: | 876 | case DR_ACTION_TYP_VPORT: |
| 876 | attr.hit_gvmi = action->vport->caps->vhca_gvmi; | 877 | if (unlikely(rx_rule && action->vport->caps->num == MLX5_VPORT_UPLINK)) { |
| 877 | dest_action = action; | 878 | /* can't go to uplink on RX rule - dropping instead */ |
| 878 | attr.final_icm_addr = rx_rule ? | 879 | attr.final_icm_addr = nic_dmn->drop_icm_addr; |
| 879 | action->vport->caps->icm_address_rx : | 880 | attr.hit_gvmi = nic_dmn->drop_icm_addr >> 48; |
| 880 | action->vport->caps->icm_address_tx; | 881 | } else { |
| 882 | attr.hit_gvmi = action->vport->caps->vhca_gvmi; | ||
| 883 | dest_action = action; | ||
| 884 | attr.final_icm_addr = rx_rule ? | ||
| 885 | action->vport->caps->icm_address_rx : | ||
| 886 | action->vport->caps->icm_address_tx; | ||
| 887 | } | ||
| 881 | break; | 888 | break; |
| 882 | case DR_ACTION_TYP_POP_VLAN: | 889 | case DR_ACTION_TYP_POP_VLAN: |
| 883 | if (!rx_rule && !(dmn->ste_ctx->actions_caps & | 890 | if (!rx_rule && !(dmn->ste_ctx->actions_caps & |
| @@ -440,6 +440,27 @@ out: · 439 unmodified lines | |||
| 440 | } | 440 | } |
| 441 | EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid); | 441 | EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid); |
| 442 | 442 | ||
| 443 | int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group) | ||
| 444 | { | ||
| 445 | int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); | ||
| 446 | u32 *out; | ||
| 447 | int err; | ||
| 448 | |||
| 449 | out = kvzalloc(outlen, GFP_KERNEL); | ||
| 450 | if (!out) | ||
| 451 | return -ENOMEM; | ||
| 452 | |||
| 453 | err = mlx5_query_nic_vport_context(mdev, 0, out); | ||
| 454 | if (err) | ||
| 455 | goto out; | ||
| 456 | |||
| 457 | *sd_group = MLX5_GET(query_nic_vport_context_out, out, | ||
| 458 | nic_vport_context.sd_group); | ||
| 459 | out: | ||
| 460 | kvfree(out); | ||
| 461 | return err; | ||
| 462 | } | ||
| 463 | |||
| 443 | int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid) | 464 | int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid) |
| 444 | { | 465 | { |
| 445 | u32 *out; | 466 | u32 *out; |
| @@ -168,9 +168,10 @@ static void lan966x_port_link_up(struct lan966x_port *port) · 167 unmodified lines | |||
| 168 | lan966x_taprio_speed_set(port, config->speed); | 168 | lan966x_taprio_speed_set(port, config->speed); |
| 169 | 169 | ||
| 170 | /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the | 170 | /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the |
| 171 | * port speed for QSGMII ports. | 171 | * port speed for QSGMII or SGMII ports. |
| 172 | */ | 172 | */ |
| 173 | if (phy_interface_num_ports(config->portmode) == 4) | 173 | if (phy_interface_num_ports(config->portmode) == 4 || |
| 174 | config->portmode == PHY_INTERFACE_MODE_SGMII) | ||
| 174 | mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); | 175 | mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); |
| 175 | 176 | ||
| 176 | lan_wr(config->duplex | mode, | 177 | lan_wr(config->duplex | mode, |
| @@ -1424,10 +1424,30 @@ static void nfp_nft_ct_translate_mangle_action(struct flow_action_entry *mangle_ · 1423 unmodified lines | |||
| 1424 | mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask); | 1424 | mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask); |
| 1425 | return; | 1425 | return; |
| 1426 | 1426 | ||
| 1427 | /* Both struct tcphdr and struct udphdr start with | ||
| 1428 | * __be16 source; | ||
| 1429 | * __be16 dest; | ||
| 1430 | * so we can use the same code for both. | ||
| 1431 | */ | ||
| 1427 | case FLOW_ACT_MANGLE_HDR_TYPE_TCP: | 1432 | case FLOW_ACT_MANGLE_HDR_TYPE_TCP: |
| 1428 | case FLOW_ACT_MANGLE_HDR_TYPE_UDP: | 1433 | case FLOW_ACT_MANGLE_HDR_TYPE_UDP: |
| 1429 | mangle_action->mangle.val = (__force u16)cpu_to_be16(mangle_action->mangle.val); | 1434 | if (mangle_action->mangle.offset == offsetof(struct tcphdr, source)) { |
| 1430 | mangle_action->mangle.mask = (__force u16)cpu_to_be16(mangle_action->mangle.mask); | 1435 | mangle_action->mangle.val = |
| 1436 | (__force u32)cpu_to_be32(mangle_action->mangle.val << 16); | ||
| 1437 | /* The mask of mangle action is inverse mask, | ||
| 1438 | * so clear the dest tp port with 0xFFFF to | ||
| 1439 | * instead of rotate-left operation. | ||
| 1440 | */ | ||
| 1441 | mangle_action->mangle.mask = | ||
| 1442 | (__force u32)cpu_to_be32(mangle_action->mangle.mask << 16 | 0xFFFF); | ||
| 1443 | } | ||
| 1444 | if (mangle_action->mangle.offset == offsetof(struct tcphdr, dest)) { | ||
| 1445 | mangle_action->mangle.offset = 0; | ||
| 1446 | mangle_action->mangle.val = | ||
| 1447 | (__force u32)cpu_to_be32(mangle_action->mangle.val); | ||
| 1448 | mangle_action->mangle.mask = | ||
| 1449 | (__force u32)cpu_to_be32(mangle_action->mangle.mask); | ||
| 1450 | } | ||
| 1431 | return; | 1451 | return; |
| 1432 | 1452 | ||
| 1433 | default: | 1453 | default: |
| @@ -1864,10 +1884,30 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv, · 430 unmodified lines | |||
| 1864 | { | 1884 | { |
| 1865 | struct flow_rule *rule = flow_cls_offload_flow_rule(flow); | 1885 | struct flow_rule *rule = flow_cls_offload_flow_rule(flow); |
| 1866 | struct nfp_fl_ct_flow_entry *ct_entry; | 1886 | struct nfp_fl_ct_flow_entry *ct_entry; |
| 1887 | struct flow_action_entry *ct_goto; | ||
| 1867 | struct nfp_fl_ct_zone_entry *zt; | 1888 | struct nfp_fl_ct_zone_entry *zt; |
| 1889 | struct flow_action_entry *act; | ||
| 1868 | bool wildcarded = false; | 1890 | bool wildcarded = false; |
| 1869 | struct flow_match_ct ct; | 1891 | struct flow_match_ct ct; |
| 1870 | struct flow_action_entry *ct_goto; | 1892 | int i; |
| 1893 | |||
| 1894 | flow_action_for_each(i, act, &rule->action) { | ||
| 1895 | switch (act->id) { | ||
| 1896 | case FLOW_ACTION_REDIRECT: | ||
| 1897 | case FLOW_ACTION_REDIRECT_INGRESS: | ||
| 1898 | case FLOW_ACTION_MIRRED: | ||
| 1899 | case FLOW_ACTION_MIRRED_INGRESS: | ||
| 1900 | if (act->dev->rtnl_link_ops && | ||
| 1901 | !strcmp(act->dev->rtnl_link_ops->kind, "openvswitch")) { | ||
| 1902 | NL_SET_ERR_MSG_MOD(extack, | ||
| 1903 | "unsupported offload: out port is openvswitch internal port"); | ||
| 1904 | return -EOPNOTSUPP; | ||
| 1905 | } | ||
| 1906 | break; | ||
| 1907 | default: | ||
| 1908 | break; | ||
| 1909 | } | ||
| 1910 | } | ||
| 1871 | 1911 | ||
| 1872 | flow_rule_match_ct(rule, &ct); | 1912 | flow_rule_match_ct(rule, &ct); |
| 1873 | if (!ct.mask->ct_zone) { | 1913 | if (!ct.mask->ct_zone) { |
| @@ -1084,7 +1084,7 @@ nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev, · 1083 unmodified lines | |||
| 1084 | u16 nfp_mac_idx = 0; | 1084 | u16 nfp_mac_idx = 0; |
| 1085 | 1085 | ||
| 1086 | entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); | 1086 | entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); |
| 1087 | if (entry && nfp_tunnel_is_mac_idx_global(entry->index)) { | 1087 | if (entry && (nfp_tunnel_is_mac_idx_global(entry->index) || netif_is_lag_port(netdev))) { |
| 1088 | if (entry->bridge_count || | 1088 | if (entry->bridge_count || |
| 1089 | !nfp_flower_is_supported_bridge(netdev)) { | 1089 | !nfp_flower_is_supported_bridge(netdev)) { |
| 1090 | nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, | 1090 | nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, |
| @@ -2776,6 +2776,7 @@ static void nfp_net_netdev_init(struct nfp_net *nn) · 2775 unmodified lines | |||
| 2776 | case NFP_NFD_VER_NFD3: | 2776 | case NFP_NFD_VER_NFD3: |
| 2777 | netdev->netdev_ops = &nfp_nfd3_netdev_ops; | 2777 | netdev->netdev_ops = &nfp_nfd3_netdev_ops; |
| 2778 | netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY; | 2778 | netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY; |
| 2779 | netdev->xdp_features |= NETDEV_XDP_ACT_REDIRECT; | ||
| 2779 | break; | 2780 | break; |
| 2780 | case NFP_NFD_VER_NFDK: | 2781 | case NFP_NFD_VER_NFDK: |
| 2781 | netdev->netdev_ops = &nfp_nfdk_netdev_ops; | 2782 | netdev->netdev_ops = &nfp_nfdk_netdev_ops; |
| @@ -537,11 +537,13 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) · 536 unmodified lines | |||
| 537 | const u32 barcfg_msix_general = | 537 | const u32 barcfg_msix_general = |
| 538 | NFP_PCIE_BAR_PCIE2CPP_MapType( | 538 | NFP_PCIE_BAR_PCIE2CPP_MapType( |
| 539 | NFP_PCIE_BAR_PCIE2CPP_MapType_GENERAL) | | 539 | NFP_PCIE_BAR_PCIE2CPP_MapType_GENERAL) | |
| 540 | NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT; | 540 | NFP_PCIE_BAR_PCIE2CPP_LengthSelect( |
| 541 | NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT); | ||
| 541 | const u32 barcfg_msix_xpb = | 542 | const u32 barcfg_msix_xpb = |
| 542 | NFP_PCIE_BAR_PCIE2CPP_MapType( | 543 | NFP_PCIE_BAR_PCIE2CPP_MapType( |
| 543 | NFP_PCIE_BAR_PCIE2CPP_MapType_BULK) | | 544 | NFP_PCIE_BAR_PCIE2CPP_MapType_BULK) | |
| 544 | NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT | | 545 | NFP_PCIE_BAR_PCIE2CPP_LengthSelect( |
| 546 | NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT) | | ||
| 545 | NFP_PCIE_BAR_PCIE2CPP_Target_BaseAddress( | 547 | NFP_PCIE_BAR_PCIE2CPP_Target_BaseAddress( |
| 546 | NFP_CPP_TARGET_ISLAND_XPB); | 548 | NFP_CPP_TARGET_ISLAND_XPB); |
| 547 | const u32 barcfg_explicit[4] = { | 549 | const u32 barcfg_explicit[4] = { |
| @@ -59,28 +59,51 @@ · 58 unmodified lines | |||
| 59 | #undef FRAME_FILTER_DEBUG | 59 | #undef FRAME_FILTER_DEBUG |
| 60 | /* #define FRAME_FILTER_DEBUG */ | 60 | /* #define FRAME_FILTER_DEBUG */ |
| 61 | 61 | ||
| 62 | struct stmmac_q_tx_stats { | ||
| 63 | u64_stats_t tx_bytes; | ||
| 64 | u64_stats_t tx_set_ic_bit; | ||
| 65 | u64_stats_t tx_tso_frames; | ||
| 66 | u64_stats_t tx_tso_nfrags; | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct stmmac_napi_tx_stats { | ||
| 70 | u64_stats_t tx_packets; | ||
| 71 | u64_stats_t tx_pkt_n; | ||
| 72 | u64_stats_t poll; | ||
| 73 | u64_stats_t tx_clean; | ||
| 74 | u64_stats_t tx_set_ic_bit; | ||
| 75 | }; | ||
| 76 | |||
| 62 | struct stmmac_txq_stats { | 77 | struct stmmac_txq_stats { |
| 63 | u64 tx_bytes; | 78 | /* Updates protected by tx queue lock. */ |
| 64 | u64 tx_packets; | 79 | struct u64_stats_sync q_syncp; |
| 65 | u64 tx_pkt_n; | 80 | struct stmmac_q_tx_stats q; |
| 66 | u64 tx_normal_irq_n; | 81 | |
| 67 | u64 napi_poll; | 82 | /* Updates protected by NAPI poll logic. */ |
| 68 | u64 tx_clean; | 83 | struct u64_stats_sync napi_syncp; |
| 69 | u64 tx_set_ic_bit; | 84 | struct stmmac_napi_tx_stats napi; |
| 70 | u64 tx_tso_frames; | ||
| 71 | u64 tx_tso_nfrags; | ||
| 72 | struct u64_stats_sync syncp; | ||
| 73 | } ____cacheline_aligned_in_smp; | 85 | } ____cacheline_aligned_in_smp; |
| 74 | 86 | ||
| 87 | struct stmmac_napi_rx_stats { | ||
| 88 | u64_stats_t rx_bytes; | ||
| 89 | u64_stats_t rx_packets; | ||
| 90 | u64_stats_t rx_pkt_n; | ||
| 91 | u64_stats_t poll; | ||
| 92 | }; | ||
| 93 | |||
| 75 | struct stmmac_rxq_stats { | 94 | struct stmmac_rxq_stats { |
| 76 | u64 rx_bytes; | 95 | /* Updates protected by NAPI poll logic. */ |
| 77 | u64 rx_packets; | 96 | struct u64_stats_sync napi_syncp; |
| 78 | u64 rx_pkt_n; | 97 | struct stmmac_napi_rx_stats napi; |
| 79 | u64 rx_normal_irq_n; | ||
| 80 | u64 napi_poll; | ||
| 81 | struct u64_stats_sync syncp; | ||
| 82 | } ____cacheline_aligned_in_smp; | 98 | } ____cacheline_aligned_in_smp; |
| 83 | 99 | ||
| 100 | /* Updates on each CPU protected by not allowing nested irqs. */ | ||
| 101 | struct stmmac_pcpu_stats { | ||
| 102 | struct u64_stats_sync syncp; | ||
| 103 | u64_stats_t rx_normal_irq_n[MTL_MAX_TX_QUEUES]; | ||
| 104 | u64_stats_t tx_normal_irq_n[MTL_MAX_RX_QUEUES]; | ||
| 105 | }; | ||
| 106 | |||
| 84 | /* Extra statistic and debug information exposed by ethtool */ | 107 | /* Extra statistic and debug information exposed by ethtool */ |
| 85 | struct stmmac_extra_stats { | 108 | struct stmmac_extra_stats { |
| 86 | /* Transmit errors */ | 109 | /* Transmit errors */ |
| @@ -205,6 +228,7 @@ struct stmmac_extra_stats { · 118 unmodified lines | |||
| 205 | /* per queue statistics */ | 228 | /* per queue statistics */ |
| 206 | struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES]; | 229 | struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES]; |
| 207 | struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES]; | 230 | struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES]; |
| 231 | struct stmmac_pcpu_stats __percpu *pcpu_stats; | ||
| 208 | unsigned long rx_dropped; | 232 | unsigned long rx_dropped; |
| 209 | unsigned long rx_errors; | 233 | unsigned long rx_errors; |
| 210 | unsigned long tx_dropped; | 234 | unsigned long tx_dropped; |
| @@ -216,6 +240,7 @@ struct stmmac_safety_stats { · 5 unmodified lines | |||
| 216 | unsigned long mac_errors[32]; | 240 | unsigned long mac_errors[32]; |
| 217 | unsigned long mtl_errors[32]; | 241 | unsigned long mtl_errors[32]; |
| 218 | unsigned long dma_errors[32]; | 242 | unsigned long dma_errors[32]; |
| 243 | unsigned long dma_dpp_errors[32]; | ||
| 219 | }; | 244 | }; |
| 220 | 245 | ||
| 221 | /* Number of fields in Safety Stats */ | 246 | /* Number of fields in Safety Stats */ |
| @@ -353,6 +353,10 @@ static int imx_dwmac_probe(struct platform_device *pdev) · 352 unmodified lines | |||
| 353 | if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) | 353 | if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) |
| 354 | plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; | 354 | plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; |
| 355 | 355 | ||
| 356 | /* Default TX Q0 to use TSO and rest TXQ for TBS */ | ||
| 357 | for (int i = 1; i < plat_dat->tx_queues_to_use; i++) | ||
| 358 | plat_dat->tx_queues_cfg[i].tbs_en = 1; | ||
| 359 | |||
| 356 | plat_dat->host_dma_width = dwmac->ops->addr_width; | 360 | plat_dat->host_dma_width = dwmac->ops->addr_width; |
| 357 | plat_dat->init = imx_dwmac_init; | 361 | plat_dat->init = imx_dwmac_init; |
| 358 | plat_dat->exit = imx_dwmac_exit; | 362 | plat_dat->exit = imx_dwmac_exit; |
| @@ -441,8 +441,7 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, · 440 unmodified lines | |||
| 441 | struct stmmac_extra_stats *x, u32 chan, | 441 | struct stmmac_extra_stats *x, u32 chan, |
| 442 | u32 dir) | 442 | u32 dir) |
| 443 | { | 443 | { |
| 444 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; | 444 | struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); |
| 445 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; | ||
| 446 | int ret = 0; | 445 | int ret = 0; |
| 447 | u32 v; | 446 | u32 v; |
| 448 | 447 | ||
| @@ -455,9 +454,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, · 6 unmodified lines | |||
| 455 | 454 | ||
| 456 | if (v & EMAC_TX_INT) { | 455 | if (v & EMAC_TX_INT) { |
| 457 | ret |= handle_tx; | 456 | ret |= handle_tx; |
| 458 | u64_stats_update_begin(&txq_stats->syncp); | 457 | u64_stats_update_begin(&stats->syncp); |
| 459 | txq_stats->tx_normal_irq_n++; | 458 | u64_stats_inc(&stats->tx_normal_irq_n[chan]); |
| 460 | u64_stats_update_end(&txq_stats->syncp); | 459 | u64_stats_update_end(&stats->syncp); |
| 461 | } | 460 | } |
| 462 | 461 | ||
| 463 | if (v & EMAC_TX_DMA_STOP_INT) | 462 | if (v & EMAC_TX_DMA_STOP_INT) |
| @@ -479,9 +478,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, · 15 unmodified lines | |||
| 479 | 478 | ||
| 480 | if (v & EMAC_RX_INT) { | 479 | if (v & EMAC_RX_INT) { |
| 481 | ret |= handle_rx; | 480 | ret |= handle_rx; |
| 482 | u64_stats_update_begin(&rxq_stats->syncp); | 481 | u64_stats_update_begin(&stats->syncp); |
| 483 | rxq_stats->rx_normal_irq_n++; | 482 | u64_stats_inc(&stats->rx_normal_irq_n[chan]); |
| 484 | u64_stats_update_end(&rxq_stats->syncp); | 483 | u64_stats_update_end(&stats->syncp); |
| 485 | } | 484 | } |
| 486 | 485 | ||
| 487 | if (v & EMAC_RX_BUF_UA_INT) | 486 | if (v & EMAC_RX_BUF_UA_INT) |
| @@ -171,8 +171,7 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, · 170 unmodified lines | |||
| 171 | const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; | 171 | const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; |
| 172 | u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan)); | 172 | u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan)); |
| 173 | u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); | 173 | u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); |
| 174 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; | 174 | struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); |
| 175 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; | ||
| 176 | int ret = 0; | 175 | int ret = 0; |
| 177 | 176 | ||
| 178 | if (dir == DMA_DIR_RX) | 177 | if (dir == DMA_DIR_RX) |
| @@ -201,15 +200,15 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, · 22 unmodified lines | |||
| 201 | } | 200 | } |
| 202 | /* TX/RX NORMAL interrupts */ | 201 | /* TX/RX NORMAL interrupts */ |
| 203 | if (likely(intr_status & DMA_CHAN_STATUS_RI)) { | 202 | if (likely(intr_status & DMA_CHAN_STATUS_RI)) { |
| 204 | u64_stats_update_begin(&rxq_stats->syncp); | 203 | u64_stats_update_begin(&stats->syncp); |
| 205 | rxq_stats->rx_normal_irq_n++; | 204 | u64_stats_inc(&stats->rx_normal_irq_n[chan]); |
| 206 | u64_stats_update_end(&rxq_stats->syncp); | 205 | u64_stats_update_end(&stats->syncp); |
| 207 | ret |= handle_rx; | 206 | ret |= handle_rx; |
| 208 | } | 207 | } |
| 209 | if (likely(intr_status & DMA_CHAN_STATUS_TI)) { | 208 | if (likely(intr_status & DMA_CHAN_STATUS_TI)) { |
| 210 | u64_stats_update_begin(&txq_stats->syncp); | 209 | u64_stats_update_begin(&stats->syncp); |
| 211 | txq_stats->tx_normal_irq_n++; | 210 | u64_stats_inc(&stats->tx_normal_irq_n[chan]); |
| 212 | u64_stats_update_end(&txq_stats->syncp); | 211 | u64_stats_update_end(&stats->syncp); |
| 213 | ret |= handle_tx; | 212 | ret |= handle_tx; |
| 214 | } | 213 | } |
| 215 | 214 | ||
| @@ -162,8 +162,7 @@ static void show_rx_process_state(unsigned int status) · 161 unmodified lines | |||
| 162 | int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, | 162 | int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, |
| 163 | struct stmmac_extra_stats *x, u32 chan, u32 dir) | 163 | struct stmmac_extra_stats *x, u32 chan, u32 dir) |
| 164 | { | 164 | { |
| 165 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; | 165 | struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); |
| 166 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; | ||
| 167 | int ret = 0; | 166 | int ret = 0; |
| 168 | /* read the status register (CSR5) */ | 167 | /* read the status register (CSR5) */ |
| 169 | u32 intr_status = readl(ioaddr + DMA_STATUS); | 168 | u32 intr_status = readl(ioaddr + DMA_STATUS); |
| @@ -215,16 +214,16 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, · 45 unmodified lines | |||
| 215 | u32 value = readl(ioaddr + DMA_INTR_ENA); | 214 | u32 value = readl(ioaddr + DMA_INTR_ENA); |
| 216 | /* to schedule NAPI on real RIE event. */ | 215 | /* to schedule NAPI on real RIE event. */ |
| 217 | if (likely(value & DMA_INTR_ENA_RIE)) { | 216 | if (likely(value & DMA_INTR_ENA_RIE)) { |
| 218 | u64_stats_update_begin(&rxq_stats->syncp); | 217 | u64_stats_update_begin(&stats->syncp); |
| 219 | rxq_stats->rx_normal_irq_n++; | 218 | u64_stats_inc(&stats->rx_normal_irq_n[chan]); |
| 220 | u64_stats_update_end(&rxq_stats->syncp); | 219 | u64_stats_update_end(&stats->syncp); |
| 221 | ret |= handle_rx; | 220 | ret |= handle_rx; |
| 222 | } | 221 | } |
| 223 | } | 222 | } |
| 224 | if (likely(intr_status & DMA_STATUS_TI)) { | 223 | if (likely(intr_status & DMA_STATUS_TI)) { |
| 225 | u64_stats_update_begin(&txq_stats->syncp); | 224 | u64_stats_update_begin(&stats->syncp); |
| 226 | txq_stats->tx_normal_irq_n++; | 225 | u64_stats_inc(&stats->tx_normal_irq_n[chan]); |
| 227 | u64_stats_update_end(&txq_stats->syncp); | 226 | u64_stats_update_end(&stats->syncp); |
| 228 | ret |= handle_tx; | 227 | ret |= handle_tx; |
| 229 | } | 228 | } |
| 230 | if (unlikely(intr_status & DMA_STATUS_ERI)) | 229 | if (unlikely(intr_status & DMA_STATUS_ERI)) |
| @@ -303,6 +303,8 @@ · 302 unmodified lines | |||
| 303 | #define XGMAC_RXCEIE BIT(4) | 303 | #define XGMAC_RXCEIE BIT(4) |
| 304 | #define XGMAC_TXCEIE BIT(0) | 304 | #define XGMAC_TXCEIE BIT(0) |
| 305 | #define XGMAC_MTL_ECC_INT_STATUS 0x000010cc | 305 | #define XGMAC_MTL_ECC_INT_STATUS 0x000010cc |
| 306 | #define XGMAC_MTL_DPP_CONTROL 0x000010e0 | ||
| 307 | #define XGMAC_DPP_DISABLE BIT(0) | ||
| 306 | #define XGMAC_MTL_TXQ_OPMODE(x) (0x00001100 + (0x80 * (x))) | 308 | #define XGMAC_MTL_TXQ_OPMODE(x) (0x00001100 + (0x80 * (x))) |
| 307 | #define XGMAC_TQS GENMASK(25, 16) | 309 | #define XGMAC_TQS GENMASK(25, 16) |
| 308 | #define XGMAC_TQS_SHIFT 16 | 310 | #define XGMAC_TQS_SHIFT 16 |
| @@ -385,6 +387,7 @@ · 76 unmodified lines | |||
| 385 | #define XGMAC_DCEIE BIT(1) | 387 | #define XGMAC_DCEIE BIT(1) |
| 386 | #define XGMAC_TCEIE BIT(0) | 388 | #define XGMAC_TCEIE BIT(0) |
| 387 | #define XGMAC_DMA_ECC_INT_STATUS 0x0000306c | 389 | #define XGMAC_DMA_ECC_INT_STATUS 0x0000306c |
| 390 | #define XGMAC_DMA_DPP_INT_STATUS 0x00003074 | ||
| 388 | #define XGMAC_DMA_CH_CONTROL(x) (0x00003100 + (0x80 * (x))) | 391 | #define XGMAC_DMA_CH_CONTROL(x) (0x00003100 + (0x80 * (x))) |
| 389 | #define XGMAC_SPH BIT(24) | 392 | #define XGMAC_SPH BIT(24) |
| 390 | #define XGMAC_PBLx8 BIT(16) | 393 | #define XGMAC_PBLx8 BIT(16) |
| @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= { · 829 unmodified lines | |||
| 830 | { false, "UNKNOWN", "Unknown Error" }, /* 31 */ | 830 | { false, "UNKNOWN", "Unknown Error" }, /* 31 */ |
| 831 | }; | 831 | }; |
| 832 | 832 | ||
| 833 | static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error"; | ||
| 834 | static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error"; | ||
| 835 | static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = { | ||
| 836 | { true, "TDPES0", dpp_tx_err }, | ||
| 837 | { true, "TDPES1", dpp_tx_err }, | ||
| 838 | { true, "TDPES2", dpp_tx_err }, | ||
| 839 | { true, "TDPES3", dpp_tx_err }, | ||
| 840 | { true, "TDPES4", dpp_tx_err }, | ||
| 841 | { true, "TDPES5", dpp_tx_err }, | ||
| 842 | { true, "TDPES6", dpp_tx_err }, | ||
| 843 | { true, "TDPES7", dpp_tx_err }, | ||
| 844 | { true, "TDPES8", dpp_tx_err }, | ||
| 845 | { true, "TDPES9", dpp_tx_err }, | ||
| 846 | { true, "TDPES10", dpp_tx_err }, | ||
| 847 | { true, "TDPES11", dpp_tx_err }, | ||
| 848 | { true, "TDPES12", dpp_tx_err }, | ||
| 849 | { true, "TDPES13", dpp_tx_err }, | ||
| 850 | { true, "TDPES14", dpp_tx_err }, | ||
| 851 | { true, "TDPES15", dpp_tx_err }, | ||
| 852 | { true, "RDPES0", dpp_rx_err }, | ||
| 853 | { true, "RDPES1", dpp_rx_err }, | ||
| 854 | { true, "RDPES2", dpp_rx_err }, | ||
| 855 | { true, "RDPES3", dpp_rx_err }, | ||
| 856 | { true, "RDPES4", dpp_rx_err }, | ||
| 857 | { true, "RDPES5", dpp_rx_err }, | ||
| 858 | { true, "RDPES6", dpp_rx_err }, | ||
| 859 | { true, "RDPES7", dpp_rx_err }, | ||
| 860 | { true, "RDPES8", dpp_rx_err }, | ||
| 861 | { true, "RDPES9", dpp_rx_err }, | ||
| 862 | { true, "RDPES10", dpp_rx_err }, | ||
| 863 | { true, "RDPES11", dpp_rx_err }, | ||
| 864 | { true, "RDPES12", dpp_rx_err }, | ||
| 865 | { true, "RDPES13", dpp_rx_err }, | ||
| 866 | { true, "RDPES14", dpp_rx_err }, | ||
| 867 | { true, "RDPES15", dpp_rx_err }, | ||
| 868 | }; | ||
| 869 | |||
| 833 | static void dwxgmac3_handle_dma_err(struct net_device *ndev, | 870 | static void dwxgmac3_handle_dma_err(struct net_device *ndev, |
| 834 | void __iomem *ioaddr, bool correctable, | 871 | void __iomem *ioaddr, bool correctable, |
| 835 | struct stmmac_safety_stats *stats) | 872 | struct stmmac_safety_stats *stats) |
| @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev, · 5 unmodified lines | |||
| 841 | 878 | ||
| 842 | dwxgmac3_log_error(ndev, value, correctable, "DMA", | 879 | dwxgmac3_log_error(ndev, value, correctable, "DMA", |
| 843 | dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats); | 880 | dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats); |
| 881 | |||
| 882 | value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS); | ||
| 883 | writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS); | ||
| 884 | |||
| 885 | dwxgmac3_log_error(ndev, value, false, "DMA_DPP", | ||
| 886 | dwxgmac3_dma_dpp_errors, | ||
| 887 | STAT_OFF(dma_dpp_errors), stats); | ||
| 844 | } | 888 | } |
| 845 | 889 | ||
| 846 | static int | 890 | static int |
| @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp, · 34 unmodified lines | |||
| 881 | value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */ | 925 | value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */ |
| 882 | writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL); | 926 | writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL); |
| 883 | 927 | ||
| 928 | /* 5. Enable Data Path Parity Protection */ | ||
| 929 | value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL); | ||
| 930 | /* already enabled by default, explicit enable it again */ | ||
| 931 | value &= ~XGMAC_DPP_DISABLE; | ||
| 932 | writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL); | ||
| 933 | |||
| 884 | return 0; | 934 | return 0; |
| 885 | } | 935 | } |
| 886 | 936 | ||
| @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev, · 27 unmodified lines | |||
| 914 | ret |= !corr; | 964 | ret |= !corr; |
| 915 | } | 965 | } |
| 916 | 966 | ||
| 917 | err = dma & (XGMAC_DEUIS | XGMAC_DECIS); | 967 | /* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in |
| 968 | * DMA_Safety_Interrupt_Status, so we handle DMA Data Path | ||
| 969 | * Parity Errors here | ||
| 970 | */ | ||
| 971 | err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS); | ||
| 918 | corr = dma & XGMAC_DECIS; | 972 | corr = dma & XGMAC_DECIS; |
| 919 | if (err) { | 973 | if (err) { |
| 920 | dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats); | 974 | dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats); |
| @@ -930,6 +984,7 @@ static const struct dwxgmac3_error { · 9 unmodified lines | |||
| 930 | { dwxgmac3_mac_errors }, | 984 | { dwxgmac3_mac_errors }, |
| 931 | { dwxgmac3_mtl_errors }, | 985 | { dwxgmac3_mtl_errors }, |
| 932 | { dwxgmac3_dma_errors }, | 986 | { dwxgmac3_dma_errors }, |
| 987 | { dwxgmac3_dma_dpp_errors }, | ||
| 933 | }; | 988 | }; |
| 934 | 989 | ||
| 935 | static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats, | 990 | static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats, |
| @@ -337,8 +337,7 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, · 336 unmodified lines | |||
| 337 | struct stmmac_extra_stats *x, u32 chan, | 337 | struct stmmac_extra_stats *x, u32 chan, |
| 338 | u32 dir) | 338 | u32 dir) |
| 339 | { | 339 | { |
| 340 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; | 340 | struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats); |
| 341 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; | ||
| 342 | u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); | 341 | u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); |
| 343 | u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); | 342 | u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); |
| 344 | int ret = 0; | 343 | int ret = 0; |
| @@ -367,15 +366,15 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, · 22 unmodified lines | |||
| 367 | /* TX/RX NORMAL interrupts */ | 366 | /* TX/RX NORMAL interrupts */ |
| 368 | if (likely(intr_status & XGMAC_NIS)) { | 367 | if (likely(intr_status & XGMAC_NIS)) { |
| 369 | if (likely(intr_status & XGMAC_RI)) { | 368 | if (likely(intr_status & XGMAC_RI)) { |
| 370 | u64_stats_update_begin(&rxq_stats->syncp); | 369 | u64_stats_update_begin(&stats->syncp); |
| 371 | rxq_stats->rx_normal_irq_n++; | 370 | u64_stats_inc(&stats->rx_normal_irq_n[chan]); |
| 372 | u64_stats_update_end(&rxq_stats->syncp); | 371 | u64_stats_update_end(&stats->syncp); |
| 373 | ret |= handle_rx; | 372 | ret |= handle_rx; |
| 374 | } | 373 | } |
| 375 | if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { | 374 | if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { |
| 376 | u64_stats_update_begin(&txq_stats->syncp); | 375 | u64_stats_update_begin(&stats->syncp); |
| 377 | txq_stats->tx_normal_irq_n++; | 376 | u64_stats_inc(&stats->tx_normal_irq_n[chan]); |
| 378 | u64_stats_update_end(&txq_stats->syncp); | 377 | u64_stats_update_end(&stats->syncp); |
| 379 | ret |= handle_tx; | 378 | ret |= handle_tx; |
| 380 | } | 379 | } |
| 381 | } | 380 | } |
| @@ -549,44 +549,79 @@ stmmac_set_pauseparam(struct net_device *netdev, · 548 unmodified lines | |||
| 549 | } | 549 | } |
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | static u64 stmmac_get_rx_normal_irq_n(struct stmmac_priv *priv, int q) | ||
| 553 | { | ||
| 554 | u64 total; | ||
| 555 | int cpu; | ||
| 556 | |||
| 557 | total = 0; | ||
| 558 | for_each_possible_cpu(cpu) { | ||
| 559 | struct stmmac_pcpu_stats *pcpu; | ||
| 560 | unsigned int start; | ||
| 561 | u64 irq_n; | ||
| 562 | |||
| 563 | pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu); | ||
| 564 | do { | ||
| 565 | start = u64_stats_fetch_begin(&pcpu->syncp); | ||
| 566 | irq_n = u64_stats_read(&pcpu->rx_normal_irq_n[q]); | ||
| 567 | } while (u64_stats_fetch_retry(&pcpu->syncp, start)); | ||
| 568 | total += irq_n; | ||
| 569 | } | ||
| 570 | return total; | ||
| 571 | } | ||
| 572 | |||
| 573 | static u64 stmmac_get_tx_normal_irq_n(struct stmmac_priv *priv, int q) | ||
| 574 | { | ||
| 575 | u64 total; | ||
| 576 | int cpu; | ||
| 577 | |||
| 578 | total = 0; | ||
| 579 | for_each_possible_cpu(cpu) { | ||
| 580 | struct stmmac_pcpu_stats *pcpu; | ||
| 581 | unsigned int start; | ||
| 582 | u64 irq_n; | ||
| 583 | |||
| 584 | pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu); | ||
| 585 | do { | ||
| 586 | start = u64_stats_fetch_begin(&pcpu->syncp); | ||
| 587 | irq_n = u64_stats_read(&pcpu->tx_normal_irq_n[q]); | ||
| 588 | } while (u64_stats_fetch_retry(&pcpu->syncp, start)); | ||
| 589 | total += irq_n; | ||
| 590 | } | ||
| 591 | return total; | ||
| 592 | } | ||
| 593 | |||
| 552 | static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) | 594 | static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) |
| 553 | { | 595 | { |
| 554 | u32 tx_cnt = priv->plat->tx_queues_to_use; | 596 | u32 tx_cnt = priv->plat->tx_queues_to_use; |
| 555 | u32 rx_cnt = priv->plat->rx_queues_to_use; | 597 | u32 rx_cnt = priv->plat->rx_queues_to_use; |
| 556 | unsigned int start; | 598 | unsigned int start; |
| 557 | int q, stat; | 599 | int q; |
| 558 | char *p; | ||
| 559 | 600 | ||
| 560 | for (q = 0; q < tx_cnt; q++) { | 601 | for (q = 0; q < tx_cnt; q++) { |
| 561 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q]; | 602 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q]; |
| 562 | struct stmmac_txq_stats snapshot; | 603 | u64 pkt_n; |
| 563 | 604 | ||
| 564 | do { | 605 | do { |
| 565 | start = u64_stats_fetch_begin(&txq_stats->syncp); | 606 | start = u64_stats_fetch_begin(&txq_stats->napi_syncp); |
| 566 | snapshot = *txq_stats; | 607 | pkt_n = u64_stats_read(&txq_stats->napi.tx_pkt_n); |
| 567 | } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); | 608 | } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start)); |
| 568 | 609 | ||
| 569 | p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n); | 610 | *data++ = pkt_n; |
| 570 | for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { | 611 | *data++ = stmmac_get_tx_normal_irq_n(priv, q); |
| 571 | *data++ = (*(u64 *)p); | ||
| 572 | p += sizeof(u64); | ||
| 573 | } | ||
| 574 | } | 612 | } |
| 575 | 613 | ||
| 576 | for (q = 0; q < rx_cnt; q++) { | 614 | for (q = 0; q < rx_cnt; q++) { |
| 577 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q]; | 615 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q]; |
| 578 | struct stmmac_rxq_stats snapshot; | 616 | u64 pkt_n; |
| 579 | 617 | ||
| 580 | do { | 618 | do { |
| 581 | start = u64_stats_fetch_begin(&rxq_stats->syncp); | 619 | start = u64_stats_fetch_begin(&rxq_stats->napi_syncp); |
| 582 | snapshot = *rxq_stats; | 620 | pkt_n = u64_stats_read(&rxq_stats->napi.rx_pkt_n); |
| 583 | } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); | 621 | } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start)); |
| 584 | 622 | ||
| 585 | p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n); | 623 | *data++ = pkt_n; |
| 586 | for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { | 624 | *data++ = stmmac_get_rx_normal_irq_n(priv, q); |
| 587 | *data++ = (*(u64 *)p); | ||
| 588 | p += sizeof(u64); | ||
| 589 | } | ||
| 590 | } | 625 | } |
| 591 | } | 626 | } |
| 592 | 627 | ||
| @@ -645,39 +680,49 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, · 52 unmodified lines | |||
| 645 | pos = j; | 680 | pos = j; |
| 646 | for (i = 0; i < rx_queues_count; i++) { | 681 | for (i = 0; i < rx_queues_count; i++) { |
| 647 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i]; | 682 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i]; |
| 648 | struct stmmac_rxq_stats snapshot; | 683 | struct stmmac_napi_rx_stats snapshot; |
| 684 | u64 n_irq; | ||
| 649 | 685 | ||
| 650 | j = pos; | 686 | j = pos; |
| 651 | do { | 687 | do { |
| 652 | start = u64_stats_fetch_begin(&rxq_stats->syncp); | 688 | start = u64_stats_fetch_begin(&rxq_stats->napi_syncp); |
| 653 | snapshot = *rxq_stats; | 689 | snapshot = rxq_stats->napi; |
| 654 | } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); | 690 | } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start)); |
| 655 | 691 | ||
| 656 | data[j++] += snapshot.rx_pkt_n; | 692 | data[j++] += u64_stats_read(&snapshot.rx_pkt_n); |
| 657 | data[j++] += snapshot.rx_normal_irq_n; | 693 | n_irq = stmmac_get_rx_normal_irq_n(priv, i); |
| 658 | normal_irq_n += snapshot.rx_normal_irq_n; | 694 | data[j++] += n_irq; |
| 659 | napi_poll += snapshot.napi_poll; | 695 | normal_irq_n += n_irq; |
| 696 | napi_poll += u64_stats_read(&snapshot.poll); | ||
| 660 | } | 697 | } |
| 661 | 698 | ||
| 662 | pos = j; | 699 | pos = j; |
| 663 | for (i = 0; i < tx_queues_count; i++) { | 700 | for (i = 0; i < tx_queues_count; i++) { |
| 664 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i]; | 701 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i]; |
| 665 | struct stmmac_txq_stats snapshot; | 702 | struct stmmac_napi_tx_stats napi_snapshot; |
| 703 | struct stmmac_q_tx_stats q_snapshot; | ||
| 704 | u64 n_irq; | ||
| 666 | 705 | ||
| 667 | j = pos; | 706 | j = pos; |
| 668 | do { | 707 | do { |
| 669 | start = u64_stats_fetch_begin(&txq_stats->syncp); | 708 | start = u64_stats_fetch_begin(&txq_stats->q_syncp); |
| 670 | snapshot = *txq_stats; | 709 | q_snapshot = txq_stats->q; |
| 671 | } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); | 710 | } while (u64_stats_fetch_retry(&txq_stats->q_syncp, start)); |
| 672 | 711 | do { | |
| 673 | data[j++] += snapshot.tx_pkt_n; | 712 | start = u64_stats_fetch_begin(&txq_stats->napi_syncp); |
| 674 | data[j++] += snapshot.tx_normal_irq_n; | 713 | napi_snapshot = txq_stats->napi; |
| 675 | normal_irq_n += snapshot.tx_normal_irq_n; | 714 | } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start)); |
| 676 | data[j++] += snapshot.tx_clean; | 715 | |
| 677 | data[j++] += snapshot.tx_set_ic_bit; | 716 | data[j++] += u64_stats_read(&napi_snapshot.tx_pkt_n); |
| 678 | data[j++] += snapshot.tx_tso_frames; | 717 | n_irq = stmmac_get_tx_normal_irq_n(priv, i); |
| 679 | data[j++] += snapshot.tx_tso_nfrags; | 718 | data[j++] += n_irq; |
| 680 | napi_poll += snapshot.napi_poll; | 719 | normal_irq_n += n_irq; |
| 720 | data[j++] += u64_stats_read(&napi_snapshot.tx_clean); | ||
| 721 | data[j++] += u64_stats_read(&q_snapshot.tx_set_ic_bit) + | ||
| 722 | u64_stats_read(&napi_snapshot.tx_set_ic_bit); | ||
| 723 | data[j++] += u64_stats_read(&q_snapshot.tx_tso_frames); | ||
| 724 | data[j++] += u64_stats_read(&q_snapshot.tx_tso_nfrags); | ||
| 725 | napi_poll += u64_stats_read(&napi_snapshot.poll); | ||
| 681 | } | 726 | } |
| 682 | normal_irq_n += priv->xstats.rx_early_irq; | 727 | normal_irq_n += priv->xstats.rx_early_irq; |
| 683 | data[j++] = normal_irq_n; | 728 | data[j++] = normal_irq_n; |
| @@ -2482,7 +2482,6 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) · 2481 unmodified lines | |||
| 2482 | struct xdp_desc xdp_desc; | 2482 | struct xdp_desc xdp_desc; |
| 2483 | bool work_done = true; | 2483 | bool work_done = true; |
| 2484 | u32 tx_set_ic_bit = 0; | 2484 | u32 tx_set_ic_bit = 0; |
| 2485 | unsigned long flags; | ||
| 2486 | 2485 | ||
| 2487 | /* Avoids TX time-out as we are sharing with slow path */ | 2486 | /* Avoids TX time-out as we are sharing with slow path */ |
| 2488 | txq_trans_cond_update(nq); | 2487 | txq_trans_cond_update(nq); |
| @@ -2566,9 +2565,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) · 77 unmodified lines | |||
| 2566 | tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); | 2565 | tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); |
| 2567 | entry = tx_q->cur_tx; | 2566 | entry = tx_q->cur_tx; |
| 2568 | } | 2567 | } |
| 2569 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 2568 | u64_stats_update_begin(&txq_stats->napi_syncp); |
| 2570 | txq_stats->tx_set_ic_bit += tx_set_ic_bit; | 2569 | u64_stats_add(&txq_stats->napi.tx_set_ic_bit, tx_set_ic_bit); |
| 2571 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 2570 | u64_stats_update_end(&txq_stats->napi_syncp); |
| 2572 | 2571 | ||
| 2573 | if (tx_desc) { | 2572 | if (tx_desc) { |
| 2574 | stmmac_flush_tx_descriptors(priv, queue); | 2573 | stmmac_flush_tx_descriptors(priv, queue); |
| @@ -2616,7 +2615,6 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue, · 41 unmodified lines | |||
| 2616 | unsigned int bytes_compl = 0, pkts_compl = 0; | 2615 | unsigned int bytes_compl = 0, pkts_compl = 0; |
| 2617 | unsigned int entry, xmits = 0, count = 0; | 2616 | unsigned int entry, xmits = 0, count = 0; |
| 2618 | u32 tx_packets = 0, tx_errors = 0; | 2617 | u32 tx_packets = 0, tx_errors = 0; |
| 2619 | unsigned long flags; | ||
| 2620 | 2618 | ||
| 2621 | __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue)); | 2619 | __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue)); |
| 2622 | 2620 | ||
| @@ -2782,11 +2780,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue, · 159 unmodified lines | |||
| 2782 | if (tx_q->dirty_tx != tx_q->cur_tx) | 2780 | if (tx_q->dirty_tx != tx_q->cur_tx) |
| 2783 | *pending_packets = true; | 2781 | *pending_packets = true; |
| 2784 | 2782 | ||
| 2785 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 2783 | u64_stats_update_begin(&txq_stats->napi_syncp); |
| 2786 | txq_stats->tx_packets += tx_packets; | 2784 | u64_stats_add(&txq_stats->napi.tx_packets, tx_packets); |
| 2787 | txq_stats->tx_pkt_n += tx_packets; | 2785 | u64_stats_add(&txq_stats->napi.tx_pkt_n, tx_packets); |
| 2788 | txq_stats->tx_clean++; | 2786 | u64_stats_inc(&txq_stats->napi.tx_clean); |
| 2789 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 2787 | u64_stats_update_end(&txq_stats->napi_syncp); |
| 2790 | 2788 | ||
| 2791 | priv->xstats.tx_errors += tx_errors; | 2789 | priv->xstats.tx_errors += tx_errors; |
| 2792 | 2790 | ||
| @@ -3932,6 +3930,9 @@ static int __stmmac_open(struct net_device *dev, · 1139 unmodified lines | |||
| 3932 | priv->rx_copybreak = STMMAC_RX_COPYBREAK; | 3930 | priv->rx_copybreak = STMMAC_RX_COPYBREAK; |
| 3933 | 3931 | ||
| 3934 | buf_sz = dma_conf->dma_buf_sz; | 3932 | buf_sz = dma_conf->dma_buf_sz; |
| 3933 | for (int i = 0; i < MTL_MAX_TX_QUEUES; i++) | ||
| 3934 | if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN) | ||
| 3935 | dma_conf->tx_queue[i].tbs = priv->dma_conf.tx_queue[i].tbs; | ||
| 3935 | memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); | 3936 | memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); |
| 3936 | 3937 | ||
| 3937 | stmmac_reset_queues_param(priv); | 3938 | stmmac_reset_queues_param(priv); |
| @@ -4210,7 +4211,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 272 unmodified lines | |||
| 4210 | struct stmmac_tx_queue *tx_q; | 4211 | struct stmmac_tx_queue *tx_q; |
| 4211 | bool has_vlan, set_ic; | 4212 | bool has_vlan, set_ic; |
| 4212 | u8 proto_hdr_len, hdr; | 4213 | u8 proto_hdr_len, hdr; |
| 4213 | unsigned long flags; | ||
| 4214 | u32 pay_len, mss; | 4214 | u32 pay_len, mss; |
| 4215 | dma_addr_t des; | 4215 | dma_addr_t des; |
| 4216 | int i; | 4216 | int i; |
| @@ -4375,13 +4375,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 158 unmodified lines | |||
| 4375 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); | 4375 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); |
| 4376 | } | 4376 | } |
| 4377 | 4377 | ||
| 4378 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 4378 | u64_stats_update_begin(&txq_stats->q_syncp); |
| 4379 | txq_stats->tx_bytes += skb->len; | 4379 | u64_stats_add(&txq_stats->q.tx_bytes, skb->len); |
| 4380 | txq_stats->tx_tso_frames++; | 4380 | u64_stats_inc(&txq_stats->q.tx_tso_frames); |
| 4381 | txq_stats->tx_tso_nfrags += nfrags; | 4381 | u64_stats_add(&txq_stats->q.tx_tso_nfrags, nfrags); |
| 4382 | if (set_ic) | 4382 | if (set_ic) |
| 4383 | txq_stats->tx_set_ic_bit++; | 4383 | u64_stats_inc(&txq_stats->q.tx_set_ic_bit); |
| 4384 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 4384 | u64_stats_update_end(&txq_stats->q_syncp); |
| 4385 | 4385 | ||
| 4386 | if (priv->sarc_type) | 4386 | if (priv->sarc_type) |
| 4387 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); | 4387 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); |
| @@ -4480,7 +4480,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 92 unmodified lines | |||
| 4480 | struct stmmac_tx_queue *tx_q; | 4480 | struct stmmac_tx_queue *tx_q; |
| 4481 | bool has_vlan, set_ic; | 4481 | bool has_vlan, set_ic; |
| 4482 | int entry, first_tx; | 4482 | int entry, first_tx; |
| 4483 | unsigned long flags; | ||
| 4484 | dma_addr_t des; | 4483 | dma_addr_t des; |
| 4485 | 4484 | ||
| 4486 | tx_q = &priv->dma_conf.tx_queue[queue]; | 4485 | tx_q = &priv->dma_conf.tx_queue[queue]; |
| @@ -4650,11 +4649,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 163 unmodified lines | |||
| 4650 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); | 4649 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); |
| 4651 | } | 4650 | } |
| 4652 | 4651 | ||
| 4653 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 4652 | u64_stats_update_begin(&txq_stats->q_syncp); |
| 4654 | txq_stats->tx_bytes += skb->len; | 4653 | u64_stats_add(&txq_stats->q.tx_bytes, skb->len); |
| 4655 | if (set_ic) | 4654 | if (set_ic) |
| 4656 | txq_stats->tx_set_ic_bit++; | 4655 | u64_stats_inc(&txq_stats->q.tx_set_ic_bit); |
| 4657 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 4656 | u64_stats_update_end(&txq_stats->q_syncp); |
| 4658 | 4657 | ||
| 4659 | if (priv->sarc_type) | 4658 | if (priv->sarc_type) |
| 4660 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); | 4659 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); |
| @@ -4918,12 +4917,11 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, · 257 unmodified lines | |||
| 4918 | set_ic = false; | 4917 | set_ic = false; |
| 4919 | 4918 | ||
| 4920 | if (set_ic) { | 4919 | if (set_ic) { |
| 4921 | unsigned long flags; | ||
| 4922 | tx_q->tx_count_frames = 0; | 4920 | tx_q->tx_count_frames = 0; |
| 4923 | stmmac_set_tx_ic(priv, tx_desc); | 4921 | stmmac_set_tx_ic(priv, tx_desc); |
| 4924 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 4922 | u64_stats_update_begin(&txq_stats->q_syncp); |
| 4925 | txq_stats->tx_set_ic_bit++; | 4923 | u64_stats_inc(&txq_stats->q.tx_set_ic_bit); |
| 4926 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 4924 | u64_stats_update_end(&txq_stats->q_syncp); |
| 4927 | } | 4925 | } |
| 4928 | 4926 | ||
| 4929 | stmmac_enable_dma_transmission(priv, priv->ioaddr); | 4927 | stmmac_enable_dma_transmission(priv, priv->ioaddr); |
| @@ -5073,7 +5071,6 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue, · 143 unmodified lines | |||
| 5073 | unsigned int len = xdp->data_end - xdp->data; | 5071 | unsigned int len = xdp->data_end - xdp->data; |
| 5074 | enum pkt_hash_types hash_type; | 5072 | enum pkt_hash_types hash_type; |
| 5075 | int coe = priv->hw->rx_csum; | 5073 | int coe = priv->hw->rx_csum; |
| 5076 | unsigned long flags; | ||
| 5077 | struct sk_buff *skb; | 5074 | struct sk_buff *skb; |
| 5078 | u32 hash; | 5075 | u32 hash; |
| 5079 | 5076 | ||
| @@ -5103,10 +5100,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue, · 23 unmodified lines | |||
| 5103 | skb_record_rx_queue(skb, queue); | 5100 | skb_record_rx_queue(skb, queue); |
| 5104 | napi_gro_receive(&ch->rxtx_napi, skb); | 5101 | napi_gro_receive(&ch->rxtx_napi, skb); |
| 5105 | 5102 | ||
| 5106 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); | 5103 | u64_stats_update_begin(&rxq_stats->napi_syncp); |
| 5107 | rxq_stats->rx_pkt_n++; | 5104 | u64_stats_inc(&rxq_stats->napi.rx_pkt_n); |
| 5108 | rxq_stats->rx_bytes += len; | 5105 | u64_stats_add(&rxq_stats->napi.rx_bytes, len); |
| 5109 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); | 5106 | u64_stats_update_end(&rxq_stats->napi_syncp); |
| 5110 | } | 5107 | } |
| 5111 | 5108 | ||
| 5112 | static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) | 5109 | static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) |
| @@ -5188,7 +5185,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) · 75 unmodified lines | |||
| 5188 | unsigned int desc_size; | 5185 | unsigned int desc_size; |
| 5189 | struct bpf_prog *prog; | 5186 | struct bpf_prog *prog; |
| 5190 | bool failure = false; | 5187 | bool failure = false; |
| 5191 | unsigned long flags; | ||
| 5192 | int xdp_status = 0; | 5188 | int xdp_status = 0; |
| 5193 | int status = 0; | 5189 | int status = 0; |
| 5194 | 5190 | ||
| @@ -5343,9 +5339,9 @@ read_again: · 148 unmodified lines | |||
| 5343 | 5339 | ||
| 5344 | stmmac_finalize_xdp_rx(priv, xdp_status); | 5340 | stmmac_finalize_xdp_rx(priv, xdp_status); |
| 5345 | 5341 | ||
| 5346 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); | 5342 | u64_stats_update_begin(&rxq_stats->napi_syncp); |
| 5347 | rxq_stats->rx_pkt_n += count; | 5343 | u64_stats_add(&rxq_stats->napi.rx_pkt_n, count); |
| 5348 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); | 5344 | u64_stats_update_end(&rxq_stats->napi_syncp); |
| 5349 | 5345 | ||
| 5350 | priv->xstats.rx_dropped += rx_dropped; | 5346 | priv->xstats.rx_dropped += rx_dropped; |
| 5351 | priv->xstats.rx_errors += rx_errors; | 5347 | priv->xstats.rx_errors += rx_errors; |
| @@ -5383,7 +5379,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) · 31 unmodified lines | |||
| 5383 | unsigned int desc_size; | 5379 | unsigned int desc_size; |
| 5384 | struct sk_buff *skb = NULL; | 5380 | struct sk_buff *skb = NULL; |
| 5385 | struct stmmac_xdp_buff ctx; | 5381 | struct stmmac_xdp_buff ctx; |
| 5386 | unsigned long flags; | ||
| 5387 | int xdp_status = 0; | 5382 | int xdp_status = 0; |
| 5388 | int buf_sz; | 5383 | int buf_sz; |
| 5389 | 5384 | ||
| @@ -5643,11 +5638,11 @@ drain_data: · 253 unmodified lines | |||
| 5643 | 5638 | ||
| 5644 | stmmac_rx_refill(priv, queue); | 5639 | stmmac_rx_refill(priv, queue); |
| 5645 | 5640 | ||
| 5646 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); | 5641 | u64_stats_update_begin(&rxq_stats->napi_syncp); |
| 5647 | rxq_stats->rx_packets += rx_packets; | 5642 | u64_stats_add(&rxq_stats->napi.rx_packets, rx_packets); |
| 5648 | rxq_stats->rx_bytes += rx_bytes; | 5643 | u64_stats_add(&rxq_stats->napi.rx_bytes, rx_bytes); |
| 5649 | rxq_stats->rx_pkt_n += count; | 5644 | u64_stats_add(&rxq_stats->napi.rx_pkt_n, count); |
| 5650 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); | 5645 | u64_stats_update_end(&rxq_stats->napi_syncp); |
| 5651 | 5646 | ||
| 5652 | priv->xstats.rx_dropped += rx_dropped; | 5647 | priv->xstats.rx_dropped += rx_dropped; |
| 5653 | priv->xstats.rx_errors += rx_errors; | 5648 | priv->xstats.rx_errors += rx_errors; |
| @@ -5662,13 +5657,12 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget) · 8 unmodified lines | |||
| 5662 | struct stmmac_priv *priv = ch->priv_data; | 5657 | struct stmmac_priv *priv = ch->priv_data; |
| 5663 | struct stmmac_rxq_stats *rxq_stats; | 5658 | struct stmmac_rxq_stats *rxq_stats; |
| 5664 | u32 chan = ch->index; | 5659 | u32 chan = ch->index; |
| 5665 | unsigned long flags; | ||
| 5666 | int work_done; | 5660 | int work_done; |
| 5667 | 5661 | ||
| 5668 | rxq_stats = &priv->xstats.rxq_stats[chan]; | 5662 | rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 5669 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); | 5663 | u64_stats_update_begin(&rxq_stats->napi_syncp); |
| 5670 | rxq_stats->napi_poll++; | 5664 | u64_stats_inc(&rxq_stats->napi.poll); |
| 5671 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); | 5665 | u64_stats_update_end(&rxq_stats->napi_syncp); |
| 5672 | 5666 | ||
| 5673 | work_done = stmmac_rx(priv, budget, chan); | 5667 | work_done = stmmac_rx(priv, budget, chan); |
| 5674 | if (work_done < budget && napi_complete_done(napi, work_done)) { | 5668 | if (work_done < budget && napi_complete_done(napi, work_done)) { |
| @@ -5690,13 +5684,12 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget) · 15 unmodified lines | |||
| 5690 | struct stmmac_txq_stats *txq_stats; | 5684 | struct stmmac_txq_stats *txq_stats; |
| 5691 | bool pending_packets = false; | 5685 | bool pending_packets = false; |
| 5692 | u32 chan = ch->index; | 5686 | u32 chan = ch->index; |
| 5693 | unsigned long flags; | ||
| 5694 | int work_done; | 5687 | int work_done; |
| 5695 | 5688 | ||
| 5696 | txq_stats = &priv->xstats.txq_stats[chan]; | 5689 | txq_stats = &priv->xstats.txq_stats[chan]; |
| 5697 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 5690 | u64_stats_update_begin(&txq_stats->napi_syncp); |
| 5698 | txq_stats->napi_poll++; | 5691 | u64_stats_inc(&txq_stats->napi.poll); |
| 5699 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 5692 | u64_stats_update_end(&txq_stats->napi_syncp); |
| 5700 | 5693 | ||
| 5701 | work_done = stmmac_tx_clean(priv, budget, chan, &pending_packets); | 5694 | work_done = stmmac_tx_clean(priv, budget, chan, &pending_packets); |
| 5702 | work_done = min(work_done, budget); | 5695 | work_done = min(work_done, budget); |
| @@ -5726,17 +5719,16 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget) · 23 unmodified lines | |||
| 5726 | struct stmmac_rxq_stats *rxq_stats; | 5719 | struct stmmac_rxq_stats *rxq_stats; |
| 5727 | struct stmmac_txq_stats *txq_stats; | 5720 | struct stmmac_txq_stats *txq_stats; |
| 5728 | u32 chan = ch->index; | 5721 | u32 chan = ch->index; |
| 5729 | unsigned long flags; | ||
| 5730 | 5722 | ||
| 5731 | rxq_stats = &priv->xstats.rxq_stats[chan]; | 5723 | rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 5732 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); | 5724 | u64_stats_update_begin(&rxq_stats->napi_syncp); |
| 5733 | rxq_stats->napi_poll++; | 5725 | u64_stats_inc(&rxq_stats->napi.poll); |
| 5734 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); | 5726 | u64_stats_update_end(&rxq_stats->napi_syncp); |
| 5735 | 5727 | ||
| 5736 | txq_stats = &priv->xstats.txq_stats[chan]; | 5728 | txq_stats = &priv->xstats.txq_stats[chan]; |
| 5737 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); | 5729 | u64_stats_update_begin(&txq_stats->napi_syncp); |
| 5738 | txq_stats->napi_poll++; | 5730 | u64_stats_inc(&txq_stats->napi.poll); |
| 5739 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); | 5731 | u64_stats_update_end(&txq_stats->napi_syncp); |
| 5740 | 5732 | ||
| 5741 | tx_done = stmmac_tx_clean(priv, budget, chan, &tx_pending_packets); | 5733 | tx_done = stmmac_tx_clean(priv, budget, chan, &tx_pending_packets); |
| 5742 | tx_done = min(tx_done, budget); | 5734 | tx_done = min(tx_done, budget); |
| @@ -7062,10 +7054,13 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64 · 1319 unmodified lines | |||
| 7062 | u64 tx_bytes; | 7054 | u64 tx_bytes; |
| 7063 | 7055 | ||
| 7064 | do { | 7056 | do { |
| 7065 | start = u64_stats_fetch_begin(&txq_stats->syncp); | 7057 | start = u64_stats_fetch_begin(&txq_stats->q_syncp); |
| 7066 | tx_packets = txq_stats->tx_packets; | 7058 | tx_bytes = u64_stats_read(&txq_stats->q.tx_bytes); |
| 7067 | tx_bytes = txq_stats->tx_bytes; | 7059 | } while (u64_stats_fetch_retry(&txq_stats->q_syncp, start)); |
| 7068 | } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); | 7060 | do { |
| 7061 | start = u64_stats_fetch_begin(&txq_stats->napi_syncp); | ||
| 7062 | tx_packets = u64_stats_read(&txq_stats->napi.tx_packets); | ||
| 7063 | } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start)); | ||
| 7069 | 7064 | ||
| 7070 | stats->tx_packets += tx_packets; | 7065 | stats->tx_packets += tx_packets; |
| 7071 | stats->tx_bytes += tx_bytes; | 7066 | stats->tx_bytes += tx_bytes; |
| @@ -7077,10 +7072,10 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64 · 5 unmodified lines | |||
| 7077 | u64 rx_bytes; | 7072 | u64 rx_bytes; |
| 7078 | 7073 | ||
| 7079 | do { | 7074 | do { |
| 7080 | start = u64_stats_fetch_begin(&rxq_stats->syncp); | 7075 | start = u64_stats_fetch_begin(&rxq_stats->napi_syncp); |
| 7081 | rx_packets = rxq_stats->rx_packets; | 7076 | rx_packets = u64_stats_read(&rxq_stats->napi.rx_packets); |
| 7082 | rx_bytes = rxq_stats->rx_bytes; | 7077 | rx_bytes = u64_stats_read(&rxq_stats->napi.rx_bytes); |
| 7083 | } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); | 7078 | } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start)); |
| 7084 | 7079 | ||
| 7085 | stats->rx_packets += rx_packets; | 7080 | stats->rx_packets += rx_packets; |
| 7086 | stats->rx_bytes += rx_bytes; | 7081 | stats->rx_bytes += rx_bytes; |
| @@ -7474,9 +7469,16 @@ int stmmac_dvr_probe(struct device *device, · 387 unmodified lines | |||
| 7474 | priv->dev = ndev; | 7469 | priv->dev = ndev; |
| 7475 | 7470 | ||
| 7476 | for (i = 0; i < MTL_MAX_RX_QUEUES; i++) | 7471 | for (i = 0; i < MTL_MAX_RX_QUEUES; i++) |
| 7477 | u64_stats_init(&priv->xstats.rxq_stats[i].syncp); | 7472 | u64_stats_init(&priv->xstats.rxq_stats[i].napi_syncp); |
| 7478 | for (i = 0; i < MTL_MAX_TX_QUEUES; i++) | 7473 | for (i = 0; i < MTL_MAX_TX_QUEUES; i++) { |
| 7479 | u64_stats_init(&priv->xstats.txq_stats[i].syncp); | 7474 | u64_stats_init(&priv->xstats.txq_stats[i].q_syncp); |
| 7475 | u64_stats_init(&priv->xstats.txq_stats[i].napi_syncp); | ||
| 7476 | } | ||
| 7477 | |||
| 7478 | priv->xstats.pcpu_stats = | ||
| 7479 | devm_netdev_alloc_pcpu_stats(device, struct stmmac_pcpu_stats); | ||
| 7480 | if (!priv->xstats.pcpu_stats) | ||
| 7481 | return -ENOMEM; | ||
| 7480 | 7482 | ||
| 7481 | stmmac_set_ethtool_ops(ndev); | 7483 | stmmac_set_ethtool_ops(ndev); |
| 7482 | priv->pause = pause; | 7484 | priv->pause = pause; |
| @@ -7542,6 +7544,9 @@ int stmmac_dvr_probe(struct device *device, · 59 unmodified lines | |||
| 7542 | dev_err(priv->device, "unable to bring out of ahb reset: %pe\n", | 7544 | dev_err(priv->device, "unable to bring out of ahb reset: %pe\n", |
| 7543 | ERR_PTR(ret)); | 7545 | ERR_PTR(ret)); |
| 7544 | 7546 | ||
| 7547 | /* Wait a bit for the reset to take effect */ | ||
| 7548 | udelay(10); | ||
| 7549 | |||
| 7545 | /* Init MAC and get the capabilities */ | 7550 | /* Init MAC and get the capabilities */ |
| 7546 | ret = stmmac_hw_init(priv); | 7551 | ret = stmmac_hw_init(priv); |
| 7547 | if (ret) | 7552 | if (ret) |
| @@ -631,6 +631,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) · 630 unmodified lines | |||
| 631 | } | 631 | } |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | phy->mac_managed_pm = true; | ||
| 635 | |||
| 634 | slave->phy = phy; | 636 | slave->phy = phy; |
| 635 | 637 | ||
| 636 | phy_attached_info(slave->phy); | 638 | phy_attached_info(slave->phy); |
| @@ -773,6 +773,9 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) · 772 unmodified lines | |||
| 773 | slave->slave_num); | 773 | slave->slave_num); |
| 774 | return; | 774 | return; |
| 775 | } | 775 | } |
| 776 | |||
| 777 | phy->mac_managed_pm = true; | ||
| 778 | |||
| 776 | slave->phy = phy; | 779 | slave->phy = phy; |
| 777 | 780 | ||
| 778 | phy_attached_info(slave->phy); | 781 | phy_attached_info(slave->phy); |
| @@ -221,21 +221,25 @@ static int fjes_hw_setup(struct fjes_hw *hw) · 220 unmodified lines | |||
| 221 | 221 | ||
| 222 | mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid); | 222 | mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid); |
| 223 | hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL); | 223 | hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL); |
| 224 | if (!(hw->hw_info.req_buf)) | 224 | if (!(hw->hw_info.req_buf)) { |
| 225 | return -ENOMEM; | 225 | result = -ENOMEM; |
| 226 | goto free_ep_info; | ||
| 227 | } | ||
| 226 | 228 | ||
| 227 | hw->hw_info.req_buf_size = mem_size; | 229 | hw->hw_info.req_buf_size = mem_size; |
| 228 | 230 | ||
| 229 | mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid); | 231 | mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid); |
| 230 | hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL); | 232 | hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL); |
| 231 | if (!(hw->hw_info.res_buf)) | 233 | if (!(hw->hw_info.res_buf)) { |
| 232 | return -ENOMEM; | 234 | result = -ENOMEM; |
| 235 | goto free_req_buf; | ||
| 236 | } | ||
| 233 | 237 | ||
| 234 | hw->hw_info.res_buf_size = mem_size; | 238 | hw->hw_info.res_buf_size = mem_size; |
| 235 | 239 | ||
| 236 | result = fjes_hw_alloc_shared_status_region(hw); | 240 | result = fjes_hw_alloc_shared_status_region(hw); |
| 237 | if (result) | 241 | if (result) |
| 238 | return result; | 242 | goto free_res_buf; |
| 239 | 243 | ||
| 240 | hw->hw_info.buffer_share_bit = 0; | 244 | hw->hw_info.buffer_share_bit = 0; |
| 241 | hw->hw_info.buffer_unshare_reserve_bit = 0; | 245 | hw->hw_info.buffer_unshare_reserve_bit = 0; |
| @@ -246,11 +250,11 @@ static int fjes_hw_setup(struct fjes_hw *hw) · 4 unmodified lines | |||
| 246 | 250 | ||
| 247 | result = fjes_hw_alloc_epbuf(&buf_pair->tx); | 251 | result = fjes_hw_alloc_epbuf(&buf_pair->tx); |
| 248 | if (result) | 252 | if (result) |
| 249 | return result; | 253 | goto free_epbuf; |
| 250 | 254 | ||
| 251 | result = fjes_hw_alloc_epbuf(&buf_pair->rx); | 255 | result = fjes_hw_alloc_epbuf(&buf_pair->rx); |
| 252 | if (result) | 256 | if (result) |
| 253 | return result; | 257 | goto free_epbuf; |
| 254 | 258 | ||
| 255 | spin_lock_irqsave(&hw->rx_status_lock, flags); | 259 | spin_lock_irqsave(&hw->rx_status_lock, flags); |
| 256 | fjes_hw_setup_epbuf(&buf_pair->tx, mac, | 260 | fjes_hw_setup_epbuf(&buf_pair->tx, mac, |
| @@ -273,6 +277,25 @@ static int fjes_hw_setup(struct fjes_hw *hw) · 16 unmodified lines | |||
| 273 | fjes_hw_init_command_registers(hw, ¶m); | 277 | fjes_hw_init_command_registers(hw, ¶m); |
| 274 | 278 | ||
| 275 | return 0; | 279 | return 0; |
| 280 | |||
| 281 | free_epbuf: | ||
| 282 | for (epidx = 0; epidx < hw->max_epid ; epidx++) { | ||
| 283 | if (epidx == hw->my_epid) | ||
| 284 | continue; | ||
| 285 | fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx); | ||
| 286 | fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx); | ||
| 287 | } | ||
| 288 | fjes_hw_free_shared_status_region(hw); | ||
| 289 | free_res_buf: | ||
| 290 | kfree(hw->hw_info.res_buf); | ||
| 291 | hw->hw_info.res_buf = NULL; | ||
| 292 | free_req_buf: | ||
| 293 | kfree(hw->hw_info.req_buf); | ||
| 294 | hw->hw_info.req_buf = NULL; | ||
| 295 | free_ep_info: | ||
| 296 | kfree(hw->ep_shm_info); | ||
| 297 | hw->ep_shm_info = NULL; | ||
| 298 | return result; | ||
| 276 | } | 299 | } |
| 277 | 300 | ||
| 278 | static void fjes_hw_cleanup(struct fjes_hw *hw) | 301 | static void fjes_hw_cleanup(struct fjes_hw *hw) |
| @@ -708,7 +708,10 @@ void netvsc_device_remove(struct hv_device *device) · 707 unmodified lines | |||
| 708 | /* Disable NAPI and disassociate its context from the device. */ | 708 | /* Disable NAPI and disassociate its context from the device. */ |
| 709 | for (i = 0; i < net_device->num_chn; i++) { | 709 | for (i = 0; i < net_device->num_chn; i++) { |
| 710 | /* See also vmbus_reset_channel_cb(). */ | 710 | /* See also vmbus_reset_channel_cb(). */ |
| 711 | napi_disable(&net_device->chan_table[i].napi); | 711 | /* only disable enabled NAPI channel */ |
| 712 | if (i < ndev->real_num_rx_queues) | ||
| 713 | napi_disable(&net_device->chan_table[i].napi); | ||
| 714 | |||
| 712 | netif_napi_del(&net_device->chan_table[i].napi); | 715 | netif_napi_del(&net_device->chan_table[i].napi); |
| 713 | } | 716 | } |
| 714 | 717 | ||
| @@ -42,9 +42,13 @@ · 41 unmodified lines | |||
| 42 | #define LINKCHANGE_INT (2 * HZ) | 42 | #define LINKCHANGE_INT (2 * HZ) |
| 43 | #define VF_TAKEOVER_INT (HZ / 10) | 43 | #define VF_TAKEOVER_INT (HZ / 10) |
| 44 | 44 | ||
| 45 | /* Macros to define the context of vf registration */ | ||
| 46 | #define VF_REG_IN_PROBE 1 | ||
| 47 | #define VF_REG_IN_NOTIFIER 2 | ||
| 48 | |||
| 45 | static unsigned int ring_size __ro_after_init = 128; | 49 | static unsigned int ring_size __ro_after_init = 128; |
| 46 | module_param(ring_size, uint, 0444); | 50 | module_param(ring_size, uint, 0444); |
| 47 | MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); | 51 | MODULE_PARM_DESC(ring_size, "Ring buffer size (# of 4K pages)"); |
| 48 | unsigned int netvsc_ring_bytes __ro_after_init; | 52 | unsigned int netvsc_ring_bytes __ro_after_init; |
| 49 | 53 | ||
| 50 | static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | | 54 | static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | |
| @@ -2185,7 +2189,7 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb) · 2134 unmodified lines | |||
| 2185 | } | 2189 | } |
| 2186 | 2190 | ||
| 2187 | static int netvsc_vf_join(struct net_device *vf_netdev, | 2191 | static int netvsc_vf_join(struct net_device *vf_netdev, |
| 2188 | struct net_device *ndev) | 2192 | struct net_device *ndev, int context) |
| 2189 | { | 2193 | { |
| 2190 | struct net_device_context *ndev_ctx = netdev_priv(ndev); | 2194 | struct net_device_context *ndev_ctx = netdev_priv(ndev); |
| 2191 | int ret; | 2195 | int ret; |
| @@ -2208,7 +2212,11 @@ static int netvsc_vf_join(struct net_device *vf_netdev, · 16 unmodified lines | |||
| 2208 | goto upper_link_failed; | 2212 | goto upper_link_failed; |
| 2209 | } | 2213 | } |
| 2210 | 2214 | ||
| 2211 | schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); | 2215 | /* If this registration is called from probe context vf_takeover |
| 2216 | * is taken care of later in probe itself. | ||
| 2217 | */ | ||
| 2218 | if (context == VF_REG_IN_NOTIFIER) | ||
| 2219 | schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); | ||
| 2212 | 2220 | ||
| 2213 | call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); | 2221 | call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); |
| 2214 | 2222 | ||
| @@ -2346,7 +2354,7 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev) · 131 unmodified lines | |||
| 2346 | return NOTIFY_DONE; | 2354 | return NOTIFY_DONE; |
| 2347 | } | 2355 | } |
| 2348 | 2356 | ||
| 2349 | static int netvsc_register_vf(struct net_device *vf_netdev) | 2357 | static int netvsc_register_vf(struct net_device *vf_netdev, int context) |
| 2350 | { | 2358 | { |
| 2351 | struct net_device_context *net_device_ctx; | 2359 | struct net_device_context *net_device_ctx; |
| 2352 | struct netvsc_device *netvsc_dev; | 2360 | struct netvsc_device *netvsc_dev; |
| @@ -2386,7 +2394,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev) · 33 unmodified lines | |||
| 2386 | 2394 | ||
| 2387 | netdev_info(ndev, "VF registering: %s\n", vf_netdev->name); | 2395 | netdev_info(ndev, "VF registering: %s\n", vf_netdev->name); |
| 2388 | 2396 | ||
| 2389 | if (netvsc_vf_join(vf_netdev, ndev) != 0) | 2397 | if (netvsc_vf_join(vf_netdev, ndev, context) != 0) |
| 2390 | return NOTIFY_DONE; | 2398 | return NOTIFY_DONE; |
| 2391 | 2399 | ||
| 2392 | dev_hold(vf_netdev); | 2400 | dev_hold(vf_netdev); |
| @@ -2484,10 +2492,31 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) · 91 unmodified lines | |||
| 2484 | return NOTIFY_OK; | 2492 | return NOTIFY_OK; |
| 2485 | } | 2493 | } |
| 2486 | 2494 | ||
| 2495 | static int check_dev_is_matching_vf(struct net_device *event_ndev) | ||
| 2496 | { | ||
| 2497 | /* Skip NetVSC interfaces */ | ||
| 2498 | if (event_ndev->netdev_ops == &device_ops) | ||
| 2499 | return -ENODEV; | ||
| 2500 | |||
| 2501 | /* Avoid non-Ethernet type devices */ | ||
| 2502 | if (event_ndev->type != ARPHRD_ETHER) | ||
| 2503 | return -ENODEV; | ||
| 2504 | |||
| 2505 | /* Avoid Vlan dev with same MAC registering as VF */ | ||
| 2506 | if (is_vlan_dev(event_ndev)) | ||
| 2507 | return -ENODEV; | ||
| 2508 | |||
| 2509 | /* Avoid Bonding master dev with same MAC registering as VF */ | ||
| 2510 | if (netif_is_bond_master(event_ndev)) | ||
| 2511 | return -ENODEV; | ||
| 2512 | |||
| 2513 | return 0; | ||
| 2514 | } | ||
| 2515 | |||
| 2487 | static int netvsc_probe(struct hv_device *dev, | 2516 | static int netvsc_probe(struct hv_device *dev, |
| 2488 | const struct hv_vmbus_device_id *dev_id) | 2517 | const struct hv_vmbus_device_id *dev_id) |
| 2489 | { | 2518 | { |
| 2490 | struct net_device *net = NULL; | 2519 | struct net_device *net = NULL, *vf_netdev; |
| 2491 | struct net_device_context *net_device_ctx; | 2520 | struct net_device_context *net_device_ctx; |
| 2492 | struct netvsc_device_info *device_info = NULL; | 2521 | struct netvsc_device_info *device_info = NULL; |
| 2493 | struct netvsc_device *nvdev; | 2522 | struct netvsc_device *nvdev; |
| @@ -2599,6 +2628,30 @@ static int netvsc_probe(struct hv_device *dev, · 105 unmodified lines | |||
| 2599 | } | 2628 | } |
| 2600 | 2629 | ||
| 2601 | list_add(&net_device_ctx->list, &netvsc_dev_list); | 2630 | list_add(&net_device_ctx->list, &netvsc_dev_list); |
| 2631 | |||
| 2632 | /* When the hv_netvsc driver is unloaded and reloaded, the | ||
| 2633 | * NET_DEVICE_REGISTER for the vf device is replayed before probe | ||
| 2634 | * is complete. This is because register_netdevice_notifier() gets | ||
| 2635 | * registered before vmbus_driver_register() so that callback func | ||
| 2636 | * is set before probe and we don't miss events like NETDEV_POST_INIT | ||
| 2637 | * So, in this section we try to register the matching vf device that | ||
| 2638 | * is present as a netdevice, knowing that its register call is not | ||
| 2639 | * processed in the netvsc_netdev_notifier(as probing is progress and | ||
| 2640 | * get_netvsc_byslot fails). | ||
| 2641 | */ | ||
| 2642 | for_each_netdev(dev_net(net), vf_netdev) { | ||
| 2643 | ret = check_dev_is_matching_vf(vf_netdev); | ||
| 2644 | if (ret != 0) | ||
| 2645 | continue; | ||
| 2646 | |||
| 2647 | if (net != get_netvsc_byslot(vf_netdev)) | ||
| 2648 | continue; | ||
| 2649 | |||
| 2650 | netvsc_prepare_bonding(vf_netdev); | ||
| 2651 | netvsc_register_vf(vf_netdev, VF_REG_IN_PROBE); | ||
| 2652 | __netvsc_vf_setup(net, vf_netdev); | ||
| 2653 | break; | ||
| 2654 | } | ||
| 2602 | rtnl_unlock(); | 2655 | rtnl_unlock(); |
| 2603 | 2656 | ||
| 2604 | netvsc_devinfo_put(device_info); | 2657 | netvsc_devinfo_put(device_info); |
| @@ -2754,28 +2807,17 @@ static int netvsc_netdev_event(struct notifier_block *this, · 149 unmodified lines | |||
| 2754 | unsigned long event, void *ptr) | 2807 | unsigned long event, void *ptr) |
| 2755 | { | 2808 | { |
| 2756 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); | 2809 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); |
| 2810 | int ret = 0; | ||
| 2757 | 2811 | ||
| 2758 | /* Skip our own events */ | 2812 | ret = check_dev_is_matching_vf(event_dev); |
| 2759 | if (event_dev->netdev_ops == &device_ops) | 2813 | if (ret != 0) |
| 2760 | return NOTIFY_DONE; | ||
| 2761 | |||
| 2762 | /* Avoid non-Ethernet type devices */ | ||
| 2763 | if (event_dev->type != ARPHRD_ETHER) | ||
| 2764 | return NOTIFY_DONE; | ||
| 2765 | |||
| 2766 | /* Avoid Vlan dev with same MAC registering as VF */ | ||
| 2767 | if (is_vlan_dev(event_dev)) | ||
| 2768 | return NOTIFY_DONE; | ||
| 2769 | |||
| 2770 | /* Avoid Bonding master dev with same MAC registering as VF */ | ||
| 2771 | if (netif_is_bond_master(event_dev)) | ||
| 2772 | return NOTIFY_DONE; | 2814 | return NOTIFY_DONE; |
| 2773 | 2815 | ||
| 2774 | switch (event) { | 2816 | switch (event) { |
| 2775 | case NETDEV_POST_INIT: | 2817 | case NETDEV_POST_INIT: |
| 2776 | return netvsc_prepare_bonding(event_dev); | 2818 | return netvsc_prepare_bonding(event_dev); |
| 2777 | case NETDEV_REGISTER: | 2819 | case NETDEV_REGISTER: |
| 2778 | return netvsc_register_vf(event_dev); | 2820 | return netvsc_register_vf(event_dev, VF_REG_IN_NOTIFIER); |
| 2779 | case NETDEV_UNREGISTER: | 2821 | case NETDEV_UNREGISTER: |
| 2780 | return netvsc_unregister_vf(event_dev); | 2822 | return netvsc_unregister_vf(event_dev); |
| 2781 | case NETDEV_UP: | 2823 | case NETDEV_UP: |
| @@ -2807,7 +2849,7 @@ static int __init netvsc_drv_init(void) · 25 unmodified lines | |||
| 2807 | pr_info("Increased ring_size to %u (min allowed)\n", | 2849 | pr_info("Increased ring_size to %u (min allowed)\n", |
| 2808 | ring_size); | 2850 | ring_size); |
| 2809 | } | 2851 | } |
| 2810 | netvsc_ring_bytes = ring_size * PAGE_SIZE; | 2852 | netvsc_ring_bytes = VMBUS_RING_SIZE(ring_size * 4096); |
| 2811 | 2853 | ||
| 2812 | register_netdevice_notifier(&netvsc_netdev_notifier); | 2854 | register_netdevice_notifier(&netvsc_netdev_notifier); |
| 2813 | 2855 | ||
| @@ -607,11 +607,26 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, · 606 unmodified lines | |||
| 607 | return ERR_PTR(-EINVAL); | 607 | return ERR_PTR(-EINVAL); |
| 608 | } | 608 | } |
| 609 | 609 | ||
| 610 | ret = skb_ensure_writable_head_tail(skb, dev); | 610 | if (unlikely(skb_headroom(skb) < MACSEC_NEEDED_HEADROOM || |
| 611 | if (unlikely(ret < 0)) { | 611 | skb_tailroom(skb) < MACSEC_NEEDED_TAILROOM)) { |
| 612 | macsec_txsa_put(tx_sa); | 612 | struct sk_buff *nskb = skb_copy_expand(skb, |
| 613 | kfree_skb(skb); | 613 | MACSEC_NEEDED_HEADROOM, |
| 614 | return ERR_PTR(ret); | 614 | MACSEC_NEEDED_TAILROOM, |
| 615 | GFP_ATOMIC); | ||
| 616 | if (likely(nskb)) { | ||
| 617 | consume_skb(skb); | ||
| 618 | skb = nskb; | ||
| 619 | } else { | ||
| 620 | macsec_txsa_put(tx_sa); | ||
| 621 | kfree_skb(skb); | ||
| 622 | return ERR_PTR(-ENOMEM); | ||
| 623 | } | ||
| 624 | } else { | ||
| 625 | skb = skb_unshare(skb, GFP_ATOMIC); | ||
| 626 | if (!skb) { | ||
| 627 | macsec_txsa_put(tx_sa); | ||
| 628 | return ERR_PTR(-ENOMEM); | ||
| 629 | } | ||
| 615 | } | 630 | } |
| 616 | 631 | ||
| 617 | unprotected_len = skb->len; | 632 | unprotected_len = skb->len; |
| @@ -835,14 +835,14 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 834 unmodified lines | |||
| 835 | trap_report_dw.work); | 835 | trap_report_dw.work); |
| 836 | nsim_dev = nsim_trap_data->nsim_dev; | 836 | nsim_dev = nsim_trap_data->nsim_dev; |
| 837 | 837 | ||
| 838 | /* For each running port and enabled packet trap, generate a UDP | ||
| 839 | * packet with a random 5-tuple and report it. | ||
| 840 | */ | ||
| 841 | if (!devl_trylock(priv_to_devlink(nsim_dev))) { | 838 | if (!devl_trylock(priv_to_devlink(nsim_dev))) { |
| 842 | schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 0); | 839 | schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 1); |
| 843 | return; | 840 | return; |
| 844 | } | 841 | } |
| 845 | 842 | ||
| 843 | /* For each running port and enabled packet trap, generate a UDP | ||
| 844 | * packet with a random 5-tuple and report it. | ||
| 845 | */ | ||
| 846 | list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) { | 846 | list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) { |
| 847 | if (!netif_running(nsim_dev_port->ns->netdev)) | 847 | if (!netif_running(nsim_dev_port->ns->netdev)) |
| 848 | continue; | 848 | continue; |
| @@ -489,7 +489,7 @@ static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val, · 488 unmodified lines | |||
| 489 | u16 reg, val; | 489 | u16 reg, val; |
| 490 | 490 | ||
| 491 | if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) | 491 | if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) |
| 492 | bias = -2; | 492 | bias = -1; |
| 493 | 493 | ||
| 494 | val = clamp_val(bias + tx_r50_cal_val, 0, 63); | 494 | val = clamp_val(bias + tx_r50_cal_val, 0, 63); |
| 495 | 495 | ||
| @@ -705,6 +705,11 @@ restore: · 209 unmodified lines | |||
| 705 | static void mt798x_phy_common_finetune(struct phy_device *phydev) | 705 | static void mt798x_phy_common_finetune(struct phy_device *phydev) |
| 706 | { | 706 | { |
| 707 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | 707 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); |
| 708 | /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ | ||
| 709 | __phy_write(phydev, 0x11, 0xc71); | ||
| 710 | __phy_write(phydev, 0x12, 0xc); | ||
| 711 | __phy_write(phydev, 0x10, 0x8fae); | ||
| 712 | |||
| 708 | /* EnabRandUpdTrig = 1 */ | 713 | /* EnabRandUpdTrig = 1 */ |
| 709 | __phy_write(phydev, 0x11, 0x2f00); | 714 | __phy_write(phydev, 0x11, 0x2f00); |
| 710 | __phy_write(phydev, 0x12, 0xe); | 715 | __phy_write(phydev, 0x12, 0xe); |
| @@ -715,15 +720,56 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 4 unmodified lines | |||
| 715 | __phy_write(phydev, 0x12, 0x0); | 720 | __phy_write(phydev, 0x12, 0x0); |
| 716 | __phy_write(phydev, 0x10, 0x83aa); | 721 | __phy_write(phydev, 0x10, 0x83aa); |
| 717 | 722 | ||
| 718 | /* TrFreeze = 0 */ | 723 | /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ |
| 724 | __phy_write(phydev, 0x11, 0x240); | ||
| 725 | __phy_write(phydev, 0x12, 0x0); | ||
| 726 | __phy_write(phydev, 0x10, 0x9680); | ||
| 727 | |||
| 728 | /* TrFreeze = 0 (mt7988 default) */ | ||
| 719 | __phy_write(phydev, 0x11, 0x0); | 729 | __phy_write(phydev, 0x11, 0x0); |
| 720 | __phy_write(phydev, 0x12, 0x0); | 730 | __phy_write(phydev, 0x12, 0x0); |
| 721 | __phy_write(phydev, 0x10, 0x9686); | 731 | __phy_write(phydev, 0x10, 0x9686); |
| 722 | 732 | ||
| 733 | /* SSTrKp100 = 5 */ | ||
| 734 | /* SSTrKf100 = 6 */ | ||
| 735 | /* SSTrKp1000Mas = 5 */ | ||
| 736 | /* SSTrKf1000Mas = 6 */ | ||
| 723 | /* SSTrKp1000Slv = 5 */ | 737 | /* SSTrKp1000Slv = 5 */ |
| 738 | /* SSTrKf1000Slv = 6 */ | ||
| 724 | __phy_write(phydev, 0x11, 0xbaef); | 739 | __phy_write(phydev, 0x11, 0xbaef); |
| 725 | __phy_write(phydev, 0x12, 0x2e); | 740 | __phy_write(phydev, 0x12, 0x2e); |
| 726 | __phy_write(phydev, 0x10, 0x968c); | 741 | __phy_write(phydev, 0x10, 0x968c); |
| 742 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | ||
| 743 | } | ||
| 744 | |||
| 745 | static void mt7981_phy_finetune(struct phy_device *phydev) | ||
| 746 | { | ||
| 747 | u16 val[8] = { 0x01ce, 0x01c1, | ||
| 748 | 0x020f, 0x0202, | ||
| 749 | 0x03d0, 0x03c0, | ||
| 750 | 0x0013, 0x0005 }; | ||
| 751 | int i, k; | ||
| 752 | |||
| 753 | /* 100M eye finetune: | ||
| 754 | * Keep middle level of TX MLT3 shapper as default. | ||
| 755 | * Only change TX MLT3 overshoot level here. | ||
| 756 | */ | ||
| 757 | for (k = 0, i = 1; i < 12; i++) { | ||
| 758 | if (i % 3 == 0) | ||
| 759 | continue; | ||
| 760 | phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); | ||
| 761 | } | ||
| 762 | |||
| 763 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | ||
| 764 | /* ResetSyncOffset = 6 */ | ||
| 765 | __phy_write(phydev, 0x11, 0x600); | ||
| 766 | __phy_write(phydev, 0x12, 0x0); | ||
| 767 | __phy_write(phydev, 0x10, 0x8fc0); | ||
| 768 | |||
| 769 | /* VgaDecRate = 1 */ | ||
| 770 | __phy_write(phydev, 0x11, 0x4c2a); | ||
| 771 | __phy_write(phydev, 0x12, 0x3e); | ||
| 772 | __phy_write(phydev, 0x10, 0x8fa4); | ||
| 727 | 773 | ||
| 728 | /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, | 774 | /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, |
| 729 | * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 | 775 | * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 |
| @@ -738,7 +784,7 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 8 unmodified lines | |||
| 738 | __phy_write(phydev, 0x10, 0x8ec0); | 784 | __phy_write(phydev, 0x10, 0x8ec0); |
| 739 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | 785 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); |
| 740 | 786 | ||
| 741 | /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/ | 787 | /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ |
| 742 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, | 788 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, |
| 743 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, | 789 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, |
| 744 | BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); | 790 | BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); |
| @@ -771,48 +817,6 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 26 unmodified lines | |||
| 771 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); | 817 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); |
| 772 | } | 818 | } |
| 773 | 819 | ||
| 774 | static void mt7981_phy_finetune(struct phy_device *phydev) | ||
| 775 | { | ||
| 776 | u16 val[8] = { 0x01ce, 0x01c1, | ||
| 777 | 0x020f, 0x0202, | ||
| 778 | 0x03d0, 0x03c0, | ||
| 779 | 0x0013, 0x0005 }; | ||
| 780 | int i, k; | ||
| 781 | |||
| 782 | /* 100M eye finetune: | ||
| 783 | * Keep middle level of TX MLT3 shapper as default. | ||
| 784 | * Only change TX MLT3 overshoot level here. | ||
| 785 | */ | ||
| 786 | for (k = 0, i = 1; i < 12; i++) { | ||
| 787 | if (i % 3 == 0) | ||
| 788 | continue; | ||
| 789 | phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); | ||
| 790 | } | ||
| 791 | |||
| 792 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | ||
| 793 | /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ | ||
| 794 | __phy_write(phydev, 0x11, 0xc71); | ||
| 795 | __phy_write(phydev, 0x12, 0xc); | ||
| 796 | __phy_write(phydev, 0x10, 0x8fae); | ||
| 797 | |||
| 798 | /* ResetSyncOffset = 6 */ | ||
| 799 | __phy_write(phydev, 0x11, 0x600); | ||
| 800 | __phy_write(phydev, 0x12, 0x0); | ||
| 801 | __phy_write(phydev, 0x10, 0x8fc0); | ||
| 802 | |||
| 803 | /* VgaDecRate = 1 */ | ||
| 804 | __phy_write(phydev, 0x11, 0x4c2a); | ||
| 805 | __phy_write(phydev, 0x12, 0x3e); | ||
| 806 | __phy_write(phydev, 0x10, 0x8fa4); | ||
| 807 | |||
| 808 | /* FfeUpdGainForce = 4 */ | ||
| 809 | __phy_write(phydev, 0x11, 0x240); | ||
| 810 | __phy_write(phydev, 0x12, 0x0); | ||
| 811 | __phy_write(phydev, 0x10, 0x9680); | ||
| 812 | |||
| 813 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | ||
| 814 | } | ||
| 815 | |||
| 816 | static void mt7988_phy_finetune(struct phy_device *phydev) | 820 | static void mt7988_phy_finetune(struct phy_device *phydev) |
| 817 | { | 821 | { |
| 818 | u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, | 822 | u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, |
| @@ -827,17 +831,7 @@ static void mt7988_phy_finetune(struct phy_device *phydev) · 8 unmodified lines | |||
| 827 | /* TCT finetune */ | 831 | /* TCT finetune */ |
| 828 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); | 832 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); |
| 829 | 833 | ||
| 830 | /* Disable TX power saving */ | ||
| 831 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, | ||
| 832 | MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); | ||
| 833 | |||
| 834 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | 834 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); |
| 835 | |||
| 836 | /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */ | ||
| 837 | __phy_write(phydev, 0x11, 0x671); | ||
| 838 | __phy_write(phydev, 0x12, 0xc); | ||
| 839 | __phy_write(phydev, 0x10, 0x8fae); | ||
| 840 | |||
| 841 | /* ResetSyncOffset = 5 */ | 835 | /* ResetSyncOffset = 5 */ |
| 842 | __phy_write(phydev, 0x11, 0x500); | 836 | __phy_write(phydev, 0x11, 0x500); |
| 843 | __phy_write(phydev, 0x12, 0x0); | 837 | __phy_write(phydev, 0x12, 0x0); |
| @@ -845,13 +839,27 @@ static void mt7988_phy_finetune(struct phy_device *phydev) · 1 unmodified line | |||
| 845 | 839 | ||
| 846 | /* VgaDecRate is 1 at default on mt7988 */ | 840 | /* VgaDecRate is 1 at default on mt7988 */ |
| 847 | 841 | ||
| 848 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | 842 | /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, |
| 843 | * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 | ||
| 844 | */ | ||
| 845 | __phy_write(phydev, 0x11, 0xb90a); | ||
| 846 | __phy_write(phydev, 0x12, 0x6f); | ||
| 847 | __phy_write(phydev, 0x10, 0x8f82); | ||
| 848 | |||
| 849 | /* RemAckCntLimitCtrl = 1 */ | ||
| 850 | __phy_write(phydev, 0x11, 0xfbba); | ||
| 851 | __phy_write(phydev, 0x12, 0xc3); | ||
| 852 | __phy_write(phydev, 0x10, 0x87f8); | ||
| 849 | 853 | ||
| 850 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30); | ||
| 851 | /* TxClkOffset = 2 */ | ||
| 852 | __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK, | ||
| 853 | FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2)); | ||
| 854 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | 854 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); |
| 855 | |||
| 856 | /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ | ||
| 857 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, | ||
| 858 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, | ||
| 859 | BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); | ||
| 860 | |||
| 861 | /* rg_tr_lpf_cnt_val = 1023 */ | ||
| 862 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); | ||
| 855 | } | 863 | } |
| 856 | 864 | ||
| 857 | static void mt798x_phy_eee(struct phy_device *phydev) | 865 | static void mt798x_phy_eee(struct phy_device *phydev) |
| @@ -884,11 +892,11 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 26 unmodified lines | |||
| 884 | MTK_PHY_LPI_SLV_SEND_TX_EN, | 892 | MTK_PHY_LPI_SLV_SEND_TX_EN, |
| 885 | FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); | 893 | FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); |
| 886 | 894 | ||
| 887 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, | 895 | /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ |
| 888 | MTK_PHY_LPI_SEND_LOC_TIMER_MASK | | 896 | phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, |
| 889 | MTK_PHY_LPI_TXPCS_LOC_RCV, | 897 | MTK_PHY_LPI_TXPCS_LOC_RCV); |
| 890 | FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); | ||
| 891 | 898 | ||
| 899 | /* This also fixes some IoT issues, such as CH340 */ | ||
| 892 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, | 900 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, |
| 893 | MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, | 901 | MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, |
| 894 | FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | | 902 | FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | |
| @@ -922,7 +930,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 27 unmodified lines | |||
| 922 | __phy_write(phydev, 0x12, 0x0); | 930 | __phy_write(phydev, 0x12, 0x0); |
| 923 | __phy_write(phydev, 0x10, 0x9690); | 931 | __phy_write(phydev, 0x10, 0x9690); |
| 924 | 932 | ||
| 925 | /* REG_EEE_st2TrKf1000 = 3 */ | 933 | /* REG_EEE_st2TrKf1000 = 2 */ |
| 926 | __phy_write(phydev, 0x11, 0x114f); | 934 | __phy_write(phydev, 0x11, 0x114f); |
| 927 | __phy_write(phydev, 0x12, 0x2); | 935 | __phy_write(phydev, 0x12, 0x2); |
| 928 | __phy_write(phydev, 0x10, 0x969a); | 936 | __phy_write(phydev, 0x10, 0x969a); |
| @@ -947,7 +955,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 18 unmodified lines | |||
| 947 | __phy_write(phydev, 0x12, 0x0); | 955 | __phy_write(phydev, 0x12, 0x0); |
| 948 | __phy_write(phydev, 0x10, 0x96b8); | 956 | __phy_write(phydev, 0x10, 0x96b8); |
| 949 | 957 | ||
| 950 | /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */ | 958 | /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ |
| 951 | __phy_write(phydev, 0x11, 0x1463); | 959 | __phy_write(phydev, 0x11, 0x1463); |
| 952 | __phy_write(phydev, 0x12, 0x0); | 960 | __phy_write(phydev, 0x12, 0x0); |
| 953 | __phy_write(phydev, 0x10, 0x96ca); | 961 | __phy_write(phydev, 0x10, 0x96ca); |
| @@ -1459,6 +1467,13 @@ static int mt7988_phy_probe(struct phy_device *phydev) · 505 unmodified lines | |||
| 1459 | if (err) | 1467 | if (err) |
| 1460 | return err; | 1468 | return err; |
| 1461 | 1469 | ||
| 1470 | /* Disable TX power saving at probing to: | ||
| 1471 | * 1. Meet common mode compliance test criteria | ||
| 1472 | * 2. Make sure that TX-VCM calibration works fine | ||
| 1473 | */ | ||
| 1474 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, | ||
| 1475 | MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); | ||
| 1476 | |||
| 1462 | return mt798x_phy_calibration(phydev); | 1477 | return mt798x_phy_calibration(phydev); |
| 1463 | } | 1478 | } |
| 1464 | 1479 | ||
| @@ -120,6 +120,11 @@ · 119 unmodified lines | |||
| 120 | */ | 120 | */ |
| 121 | #define LAN8814_1PPM_FORMAT 17179 | 121 | #define LAN8814_1PPM_FORMAT 17179 |
| 122 | 122 | ||
| 123 | #define PTP_RX_VERSION 0x0248 | ||
| 124 | #define PTP_TX_VERSION 0x0288 | ||
| 125 | #define PTP_MAX_VERSION(x) (((x) & GENMASK(7, 0)) << 8) | ||
| 126 | #define PTP_MIN_VERSION(x) ((x) & GENMASK(7, 0)) | ||
| 127 | |||
| 123 | #define PTP_RX_MOD 0x024F | 128 | #define PTP_RX_MOD 0x024F |
| 124 | #define PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_ BIT(3) | 129 | #define PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_ BIT(3) |
| 125 | #define PTP_RX_TIMESTAMP_EN 0x024D | 130 | #define PTP_RX_TIMESTAMP_EN 0x024D |
| @@ -3150,6 +3155,12 @@ static void lan8814_ptp_init(struct phy_device *phydev) · 3024 unmodified lines | |||
| 3150 | lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_IP_ADDR_EN, 0); | 3155 | lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_IP_ADDR_EN, 0); |
| 3151 | lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_IP_ADDR_EN, 0); | 3156 | lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_IP_ADDR_EN, 0); |
| 3152 | 3157 | ||
| 3158 | /* Disable checking for minorVersionPTP field */ | ||
| 3159 | lanphy_write_page_reg(phydev, 5, PTP_RX_VERSION, | ||
| 3160 | PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0)); | ||
| 3161 | lanphy_write_page_reg(phydev, 5, PTP_TX_VERSION, | ||
| 3162 | PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0)); | ||
| 3163 | |||
| 3153 | skb_queue_head_init(&ptp_priv->tx_queue); | 3164 | skb_queue_head_init(&ptp_priv->tx_queue); |
| 3154 | skb_queue_head_init(&ptp_priv->rx_queue); | 3165 | skb_queue_head_init(&ptp_priv->rx_queue); |
| 3155 | INIT_LIST_HEAD(&ptp_priv->rx_ts_list); | 3166 | INIT_LIST_HEAD(&ptp_priv->rx_ts_list); |
| @@ -460,6 +460,10 @@ ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) · 459 unmodified lines | |||
| 460 | case PPPIOCSMRU: | 460 | case PPPIOCSMRU: |
| 461 | if (get_user(val, p)) | 461 | if (get_user(val, p)) |
| 462 | break; | 462 | break; |
| 463 | if (val > U16_MAX) { | ||
| 464 | err = -EINVAL; | ||
| 465 | break; | ||
| 466 | } | ||
| 463 | if (val < PPP_MRU) | 467 | if (val < PPP_MRU) |
| 464 | val = PPP_MRU; | 468 | val = PPP_MRU; |
| 465 | ap->mru = val; | 469 | ap->mru = val; |
| @@ -1630,13 +1630,19 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog, · 1629 unmodified lines | |||
| 1630 | switch (act) { | 1630 | switch (act) { |
| 1631 | case XDP_REDIRECT: | 1631 | case XDP_REDIRECT: |
| 1632 | err = xdp_do_redirect(tun->dev, xdp, xdp_prog); | 1632 | err = xdp_do_redirect(tun->dev, xdp, xdp_prog); |
| 1633 | if (err) | 1633 | if (err) { |
| 1634 | dev_core_stats_rx_dropped_inc(tun->dev); | ||
| 1634 | return err; | 1635 | return err; |
| 1636 | } | ||
| 1637 | dev_sw_netstats_rx_add(tun->dev, xdp->data_end - xdp->data); | ||
| 1635 | break; | 1638 | break; |
| 1636 | case XDP_TX: | 1639 | case XDP_TX: |
| 1637 | err = tun_xdp_tx(tun->dev, xdp); | 1640 | err = tun_xdp_tx(tun->dev, xdp); |
| 1638 | if (err < 0) | 1641 | if (err < 0) { |
| 1642 | dev_core_stats_rx_dropped_inc(tun->dev); | ||
| 1639 | return err; | 1643 | return err; |
| 1644 | } | ||
| 1645 | dev_sw_netstats_rx_add(tun->dev, xdp->data_end - xdp->data); | ||
| 1640 | break; | 1646 | break; |
| 1641 | case XDP_PASS: | 1647 | case XDP_PASS: |
| 1642 | break; | 1648 | break; |
| @@ -1803,5 +1803,6 @@ static struct usb_driver ar5523_driver = { · 1802 unmodified lines | |||
| 1803 | 1803 | ||
| 1804 | module_usb_driver(ar5523_driver); | 1804 | module_usb_driver(ar5523_driver); |
| 1805 | 1805 | ||
| 1806 | MODULE_DESCRIPTION("Atheros AR5523 wireless driver"); | ||
| 1806 | MODULE_LICENSE("Dual BSD/GPL"); | 1807 | MODULE_LICENSE("Dual BSD/GPL"); |
| 1807 | MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); | 1808 | MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); |
| @@ -368,10 +368,6 @@ struct ath11k_vif { · 367 unmodified lines | |||
| 368 | struct ieee80211_chanctx_conf chanctx; | 368 | struct ieee80211_chanctx_conf chanctx; |
| 369 | struct ath11k_arp_ns_offload arp_ns_offload; | 369 | struct ath11k_arp_ns_offload arp_ns_offload; |
| 370 | struct ath11k_rekey_data rekey_data; | 370 | struct ath11k_rekey_data rekey_data; |
| 371 | |||
| 372 | #ifdef CONFIG_ATH11K_DEBUGFS | ||
| 373 | struct dentry *debugfs_twt; | ||
| 374 | #endif /* CONFIG_ATH11K_DEBUGFS */ | ||
| 375 | }; | 371 | }; |
| 376 | 372 | ||
| 377 | struct ath11k_vif_iter { | 373 | struct ath11k_vif_iter { |
| @@ -1894,35 +1894,30 @@ static const struct file_operations ath11k_fops_twt_resume_dialog = { · 1893 unmodified lines | |||
| 1894 | .open = simple_open | 1894 | .open = simple_open |
| 1895 | }; | 1895 | }; |
| 1896 | 1896 | ||
| 1897 | void ath11k_debugfs_add_interface(struct ath11k_vif *arvif) | 1897 | void ath11k_debugfs_op_vif_add(struct ieee80211_hw *hw, |
| 1898 | struct ieee80211_vif *vif) | ||
| 1898 | { | 1899 | { |
| 1900 | struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); | ||
| 1899 | struct ath11k_base *ab = arvif->ar->ab; | 1901 | struct ath11k_base *ab = arvif->ar->ab; |
| 1902 | struct dentry *debugfs_twt; | ||
| 1900 | 1903 | ||
| 1901 | if (arvif->vif->type != NL80211_IFTYPE_AP && | 1904 | if (arvif->vif->type != NL80211_IFTYPE_AP && |
| 1902 | !(arvif->vif->type == NL80211_IFTYPE_STATION && | 1905 | !(arvif->vif->type == NL80211_IFTYPE_STATION && |
| 1903 | test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map))) | 1906 | test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map))) |
| 1904 | return; | 1907 | return; |
| 1905 | 1908 | ||
| 1906 | arvif->debugfs_twt = debugfs_create_dir("twt", | 1909 | debugfs_twt = debugfs_create_dir("twt", |
| 1907 | arvif->vif->debugfs_dir); | 1910 | arvif->vif->debugfs_dir); |
| 1908 | debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt, | 1911 | debugfs_create_file("add_dialog", 0200, debugfs_twt, |
| 1909 | arvif, &ath11k_fops_twt_add_dialog); | 1912 | arvif, &ath11k_fops_twt_add_dialog); |
| 1910 | 1913 | ||
| 1911 | debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt, | 1914 | debugfs_create_file("del_dialog", 0200, debugfs_twt, |
| 1912 | arvif, &ath11k_fops_twt_del_dialog); | 1915 | arvif, &ath11k_fops_twt_del_dialog); |
| 1913 | 1916 | ||
| 1914 | debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt, | 1917 | debugfs_create_file("pause_dialog", 0200, debugfs_twt, |
| 1915 | arvif, &ath11k_fops_twt_pause_dialog); | 1918 | arvif, &ath11k_fops_twt_pause_dialog); |
| 1916 | 1919 | ||
| 1917 | debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt, | 1920 | debugfs_create_file("resume_dialog", 0200, debugfs_twt, |
| 1918 | arvif, &ath11k_fops_twt_resume_dialog); | 1921 | arvif, &ath11k_fops_twt_resume_dialog); |
| 1919 | } | 1922 | } |
| 1920 | 1923 | ||
| 1921 | void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif) | ||
| 1922 | { | ||
| 1923 | if (!arvif->debugfs_twt) | ||
| 1924 | return; | ||
| 1925 | |||
| 1926 | debugfs_remove_recursive(arvif->debugfs_twt); | ||
| 1927 | arvif->debugfs_twt = NULL; | ||
| 1928 | } | ||
| @@ -307,8 +307,8 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar) · 306 unmodified lines | |||
| 307 | return ar->debug.rx_filter; | 307 | return ar->debug.rx_filter; |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | void ath11k_debugfs_add_interface(struct ath11k_vif *arvif); | 310 | void ath11k_debugfs_op_vif_add(struct ieee80211_hw *hw, |
| 311 | void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif); | 311 | struct ieee80211_vif *vif); |
| 312 | void ath11k_debugfs_add_dbring_entry(struct ath11k *ar, | 312 | void ath11k_debugfs_add_dbring_entry(struct ath11k *ar, |
| 313 | enum wmi_direct_buffer_module id, | 313 | enum wmi_direct_buffer_module id, |
| 314 | enum ath11k_dbg_dbr_event event, | 314 | enum ath11k_dbg_dbr_event event, |
| @@ -387,14 +387,6 @@ static inline int ath11k_debugfs_get_fw_stats(struct ath11k *ar, · 72 unmodified lines | |||
| 387 | return 0; | 387 | return 0; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | static inline void ath11k_debugfs_add_interface(struct ath11k_vif *arvif) | ||
| 391 | { | ||
| 392 | } | ||
| 393 | |||
| 394 | static inline void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif) | ||
| 395 | { | ||
| 396 | } | ||
| 397 | |||
| 398 | static inline void | 390 | static inline void |
| 399 | ath11k_debugfs_add_dbring_entry(struct ath11k *ar, | 391 | ath11k_debugfs_add_dbring_entry(struct ath11k *ar, |
| 400 | enum wmi_direct_buffer_module id, | 392 | enum wmi_direct_buffer_module id, |
| @@ -6756,13 +6756,6 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, · 6755 unmodified lines | |||
| 6756 | goto err; | 6756 | goto err; |
| 6757 | } | 6757 | } |
| 6758 | 6758 | ||
| 6759 | /* In the case of hardware recovery, debugfs files are | ||
| 6760 | * not deleted since ieee80211_ops.remove_interface() is | ||
| 6761 | * not invoked. In such cases, try to delete the files. | ||
| 6762 | * These will be re-created later. | ||
| 6763 | */ | ||
| 6764 | ath11k_debugfs_remove_interface(arvif); | ||
| 6765 | |||
| 6766 | memset(arvif, 0, sizeof(*arvif)); | 6759 | memset(arvif, 0, sizeof(*arvif)); |
| 6767 | 6760 | ||
| 6768 | arvif->ar = ar; | 6761 | arvif->ar = ar; |
| @@ -6939,8 +6932,6 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, · 170 unmodified lines | |||
| 6939 | 6932 | ||
| 6940 | ath11k_dp_vdev_tx_attach(ar, arvif); | 6933 | ath11k_dp_vdev_tx_attach(ar, arvif); |
| 6941 | 6934 | ||
| 6942 | ath11k_debugfs_add_interface(arvif); | ||
| 6943 | |||
| 6944 | if (vif->type != NL80211_IFTYPE_MONITOR && | 6935 | if (vif->type != NL80211_IFTYPE_MONITOR && |
| 6945 | test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) { | 6936 | test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) { |
| 6946 | ret = ath11k_mac_monitor_vdev_create(ar); | 6937 | ret = ath11k_mac_monitor_vdev_create(ar); |
| @@ -7056,8 +7047,6 @@ err_vdev_del: · 109 unmodified lines | |||
| 7056 | /* Recalc txpower for remaining vdev */ | 7047 | /* Recalc txpower for remaining vdev */ |
| 7057 | ath11k_mac_txpower_recalc(ar); | 7048 | ath11k_mac_txpower_recalc(ar); |
| 7058 | 7049 | ||
| 7059 | ath11k_debugfs_remove_interface(arvif); | ||
| 7060 | |||
| 7061 | /* TODO: recal traffic pause state based on the available vdevs */ | 7050 | /* TODO: recal traffic pause state based on the available vdevs */ |
| 7062 | 7051 | ||
| 7063 | mutex_unlock(&ar->conf_mutex); | 7052 | mutex_unlock(&ar->conf_mutex); |
| @@ -9153,6 +9142,7 @@ static const struct ieee80211_ops ath11k_ops = { · 2089 unmodified lines | |||
| 9153 | #endif | 9142 | #endif |
| 9154 | 9143 | ||
| 9155 | #ifdef CONFIG_ATH11K_DEBUGFS | 9144 | #ifdef CONFIG_ATH11K_DEBUGFS |
| 9145 | .vif_add_debugfs = ath11k_debugfs_op_vif_add, | ||
| 9156 | .sta_add_debugfs = ath11k_debugfs_sta_op_add, | 9146 | .sta_add_debugfs = ath11k_debugfs_sta_op_add, |
| 9157 | #endif | 9147 | #endif |
| 9158 | 9148 | ||
| @@ -1685,6 +1685,7 @@ static struct platform_driver wcn36xx_driver = { · 1684 unmodified lines | |||
| 1685 | 1685 | ||
| 1686 | module_platform_driver(wcn36xx_driver); | 1686 | module_platform_driver(wcn36xx_driver); |
| 1687 | 1687 | ||
| 1688 | MODULE_DESCRIPTION("Qualcomm Atheros WCN3660/3680 wireless driver"); | ||
| 1688 | MODULE_LICENSE("Dual BSD/GPL"); | 1689 | MODULE_LICENSE("Dual BSD/GPL"); |
| 1689 | MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com"); | 1690 | MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com"); |
| 1690 | MODULE_FIRMWARE(WLAN_NV_FILE); | 1691 | MODULE_FIRMWARE(WLAN_NV_FILE); |
| @@ -20,6 +20,7 @@ static void __exit brcmf_bca_exit(void) · 19 unmodified lines | |||
| 20 | brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_BCA, THIS_MODULE); | 20 | brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_BCA, THIS_MODULE); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom AP chipsets"); | ||
| 23 | MODULE_LICENSE("Dual BSD/GPL"); | 24 | MODULE_LICENSE("Dual BSD/GPL"); |
| 24 | MODULE_IMPORT_NS(BRCMFMAC); | 25 | MODULE_IMPORT_NS(BRCMFMAC); |
| 25 | 26 | ||
| @@ -3779,8 +3779,10 @@ static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req, · 3778 unmodified lines | |||
| 3779 | if (req->channels[i] == chan) | 3779 | if (req->channels[i] == chan) |
| 3780 | break; | 3780 | break; |
| 3781 | } | 3781 | } |
| 3782 | if (i == req->n_channels) | 3782 | if (i == req->n_channels) { |
| 3783 | req->channels[req->n_channels++] = chan; | 3783 | req->n_channels++; |
| 3784 | req->channels[i] = chan; | ||
| 3785 | } | ||
| 3784 | 3786 | ||
| 3785 | for (i = 0; i < req->n_ssids; i++) { | 3787 | for (i = 0; i < req->n_ssids; i++) { |
| 3786 | if (req->ssids[i].ssid_len == ssid_len && | 3788 | if (req->ssids[i].ssid_len == ssid_len && |
| @@ -20,6 +20,7 @@ static void __exit brcmf_cyw_exit(void) · 19 unmodified lines | |||
| 20 | brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_CYW, THIS_MODULE); | 20 | brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_CYW, THIS_MODULE); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Cypress/Infineon chipsets"); | ||
| 23 | MODULE_LICENSE("Dual BSD/GPL"); | 24 | MODULE_LICENSE("Dual BSD/GPL"); |
| 24 | MODULE_IMPORT_NS(BRCMFMAC); | 25 | MODULE_IMPORT_NS(BRCMFMAC); |
| 25 | 26 | ||
| @@ -20,6 +20,7 @@ static void __exit brcmf_wcc_exit(void) · 19 unmodified lines | |||
| 20 | brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_WCC, THIS_MODULE); | 20 | brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_WCC, THIS_MODULE); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom mobility chipsets"); | ||
| 23 | MODULE_LICENSE("Dual BSD/GPL"); | 24 | MODULE_LICENSE("Dual BSD/GPL"); |
| 24 | MODULE_IMPORT_NS(BRCMFMAC); | 25 | MODULE_IMPORT_NS(BRCMFMAC); |
| 25 | 26 | ||
| @@ -537,7 +537,7 @@ enum iwl_fw_dbg_config_cmd_type { · 536 unmodified lines | |||
| 537 | }; /* LDBG_CFG_CMD_TYPE_API_E_VER_1 */ | 537 | }; /* LDBG_CFG_CMD_TYPE_API_E_VER_1 */ |
| 538 | 538 | ||
| 539 | /* this token disables debug asserts in the firmware */ | 539 | /* this token disables debug asserts in the firmware */ |
| 540 | #define IWL_FW_DBG_CONFIG_TOKEN 0x00011301 | 540 | #define IWL_FW_DBG_CONFIG_TOKEN 0x00010001 |
| 541 | 541 | ||
| 542 | /** | 542 | /** |
| 543 | * struct iwl_fw_dbg_config_cmd - configure FW debug | 543 | * struct iwl_fw_dbg_config_cmd - configure FW debug |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause | 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2005-2014, 2018-2023 Intel Corporation | 3 | * Copyright (C) 2005-2014, 2018-2024 Intel Corporation |
| 4 | * Copyright (C) 2013-2015 Intel Mobile Communications GmbH | 4 | * Copyright (C) 2013-2015 Intel Mobile Communications GmbH |
| 5 | * Copyright (C) 2015-2017 Intel Deutschland GmbH | 5 | * Copyright (C) 2015-2017 Intel Deutschland GmbH |
| 6 | */ | 6 | */ |
| @@ -19,7 +19,6 @@ · 12 unmodified lines | |||
| 19 | * @fwrt_ptr: pointer to the buffer coming from fwrt | 19 | * @fwrt_ptr: pointer to the buffer coming from fwrt |
| 20 | * @trans_ptr: pointer to struct %iwl_trans_dump_data which contains the | 20 | * @trans_ptr: pointer to struct %iwl_trans_dump_data which contains the |
| 21 | * transport's data. | 21 | * transport's data. |
| 22 | * @trans_len: length of the valid data in trans_ptr | ||
| 23 | * @fwrt_len: length of the valid data in fwrt_ptr | 22 | * @fwrt_len: length of the valid data in fwrt_ptr |
| 24 | */ | 23 | */ |
| 25 | struct iwl_fw_dump_ptrs { | 24 | struct iwl_fw_dump_ptrs { |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause | 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2018-2023 Intel Corporation | 3 | * Copyright (C) 2018-2024 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | #include <linux/firmware.h> | 5 | #include <linux/firmware.h> |
| 6 | #include "iwl-drv.h" | 6 | #include "iwl-drv.h" |
| @@ -1096,7 +1096,7 @@ static int iwl_dbg_tlv_override_trig_node(struct iwl_fw_runtime *fwrt, · 1089 unmodified lines | |||
| 1096 | node_trig = (void *)node_tlv->data; | 1096 | node_trig = (void *)node_tlv->data; |
| 1097 | } | 1097 | } |
| 1098 | 1098 | ||
| 1099 | memcpy(node_trig->data + offset, trig->data, trig_data_len); | 1099 | memcpy((u8 *)node_trig->data + offset, trig->data, trig_data_len); |
| 1100 | node_tlv->length = cpu_to_le32(size); | 1100 | node_tlv->length = cpu_to_le32(size); |
| 1101 | 1101 | ||
| 1102 | if (policy & IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG) { | 1102 | if (policy & IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG) { |
| @@ -128,6 +128,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv) · 127 unmodified lines | |||
| 128 | kfree(drv->fw.ucode_capa.cmd_versions); | 128 | kfree(drv->fw.ucode_capa.cmd_versions); |
| 129 | kfree(drv->fw.phy_integration_ver); | 129 | kfree(drv->fw.phy_integration_ver); |
| 130 | kfree(drv->trans->dbg.pc_data); | 130 | kfree(drv->trans->dbg.pc_data); |
| 131 | drv->trans->dbg.pc_data = NULL; | ||
| 131 | 132 | ||
| 132 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) | 133 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) |
| 133 | iwl_free_fw_img(drv, drv->fw.img + i); | 134 | iwl_free_fw_img(drv, drv->fw.img + i); |
| @@ -668,7 +668,6 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = { · 667 unmodified lines | |||
| 668 | .has_eht = true, | 668 | .has_eht = true, |
| 669 | .eht_cap_elem = { | 669 | .eht_cap_elem = { |
| 670 | .mac_cap_info[0] = | 670 | .mac_cap_info[0] = |
| 671 | IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS | | ||
| 672 | IEEE80211_EHT_MAC_CAP0_OM_CONTROL | | 671 | IEEE80211_EHT_MAC_CAP0_OM_CONTROL | |
| 673 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | | 672 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | |
| 674 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 | | 673 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 | |
| @@ -793,7 +792,6 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = { · 118 unmodified lines | |||
| 793 | .has_eht = true, | 792 | .has_eht = true, |
| 794 | .eht_cap_elem = { | 793 | .eht_cap_elem = { |
| 795 | .mac_cap_info[0] = | 794 | .mac_cap_info[0] = |
| 796 | IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS | | ||
| 797 | IEEE80211_EHT_MAC_CAP0_OM_CONTROL | | 795 | IEEE80211_EHT_MAC_CAP0_OM_CONTROL | |
| 798 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | | 796 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | |
| 799 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2, | 797 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2, |
| @@ -1020,8 +1018,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, · 220 unmodified lines | |||
| 1020 | if (CSR_HW_REV_TYPE(trans->hw_rev) == IWL_CFG_MAC_TYPE_GL && | 1018 | if (CSR_HW_REV_TYPE(trans->hw_rev) == IWL_CFG_MAC_TYPE_GL && |
| 1021 | iftype_data->eht_cap.has_eht) { | 1019 | iftype_data->eht_cap.has_eht) { |
| 1022 | iftype_data->eht_cap.eht_cap_elem.mac_cap_info[0] &= | 1020 | iftype_data->eht_cap.eht_cap_elem.mac_cap_info[0] &= |
| 1023 | ~(IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS | | 1021 | ~(IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | |
| 1024 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 | | ||
| 1025 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2); | 1022 | IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2); |
| 1026 | iftype_data->eht_cap.eht_cap_elem.phy_cap_info[3] &= | 1023 | iftype_data->eht_cap.eht_cap_elem.phy_cap_info[3] &= |
| 1027 | ~(IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO | | 1024 | ~(IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO | |
| @@ -1600,7 +1600,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, · 1599 unmodified lines | |||
| 1600 | */ | 1600 | */ |
| 1601 | if (vif->type == NL80211_IFTYPE_AP || | 1601 | if (vif->type == NL80211_IFTYPE_AP || |
| 1602 | vif->type == NL80211_IFTYPE_ADHOC) { | 1602 | vif->type == NL80211_IFTYPE_ADHOC) { |
| 1603 | iwl_mvm_vif_dbgfs_add_link(mvm, vif); | 1603 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) |
| 1604 | iwl_mvm_vif_dbgfs_add_link(mvm, vif); | ||
| 1604 | ret = 0; | 1605 | ret = 0; |
| 1605 | goto out; | 1606 | goto out; |
| 1606 | } | 1607 | } |
| @@ -1640,7 +1641,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, · 33 unmodified lines | |||
| 1640 | iwl_mvm_chandef_get_primary_80(&vif->bss_conf.chandef); | 1641 | iwl_mvm_chandef_get_primary_80(&vif->bss_conf.chandef); |
| 1641 | } | 1642 | } |
| 1642 | 1643 | ||
| 1643 | iwl_mvm_vif_dbgfs_add_link(mvm, vif); | 1644 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) |
| 1645 | iwl_mvm_vif_dbgfs_add_link(mvm, vif); | ||
| 1644 | 1646 | ||
| 1645 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && | 1647 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && |
| 1646 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && | 1648 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && |
| @@ -81,7 +81,8 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, · 80 unmodified lines | |||
| 81 | ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS); | 81 | ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | iwl_mvm_vif_dbgfs_add_link(mvm, vif); | 84 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) |
| 85 | iwl_mvm_vif_dbgfs_add_link(mvm, vif); | ||
| 85 | 86 | ||
| 86 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && | 87 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && |
| 87 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && | 88 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && |
| @@ -437,6 +438,9 @@ __iwl_mvm_mld_unassign_vif_chanctx(struct iwl_mvm *mvm, · 349 unmodified lines | |||
| 437 | mvmvif->ap_ibss_active = false; | 438 | mvmvif->ap_ibss_active = false; |
| 438 | } | 439 | } |
| 439 | 440 | ||
| 441 | iwl_mvm_link_changed(mvm, vif, link_conf, | ||
| 442 | LINK_CONTEXT_MODIFY_ACTIVE, false); | ||
| 443 | |||
| 440 | if (iwl_mvm_is_esr_supported(mvm->fwrt.trans) && n_active > 1) { | 444 | if (iwl_mvm_is_esr_supported(mvm->fwrt.trans) && n_active > 1) { |
| 441 | int ret = iwl_mvm_esr_mode_inactive(mvm, vif); | 445 | int ret = iwl_mvm_esr_mode_inactive(mvm, vif); |
| 442 | 446 | ||
| @@ -448,9 +452,6 @@ __iwl_mvm_mld_unassign_vif_chanctx(struct iwl_mvm *mvm, · 5 unmodified lines | |||
| 448 | if (vif->type == NL80211_IFTYPE_MONITOR) | 452 | if (vif->type == NL80211_IFTYPE_MONITOR) |
| 449 | iwl_mvm_mld_rm_snif_sta(mvm, vif); | 453 | iwl_mvm_mld_rm_snif_sta(mvm, vif); |
| 450 | 454 | ||
| 451 | iwl_mvm_link_changed(mvm, vif, link_conf, | ||
| 452 | LINK_CONTEXT_MODIFY_ACTIVE, false); | ||
| 453 | |||
| 454 | if (switching_chanctx) | 455 | if (switching_chanctx) |
| 455 | return; | 456 | return; |
| 456 | mvmvif->link[link_id]->phy_ctxt = NULL; | 457 | mvmvif->link[link_id]->phy_ctxt = NULL; |
| @@ -125,7 +125,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) · 124 unmodified lines | |||
| 125 | "FW rev %s - Softmac protocol %x.%x\n", | 125 | "FW rev %s - Softmac protocol %x.%x\n", |
| 126 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); | 126 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); |
| 127 | snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version), | 127 | snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version), |
| 128 | "%s - %x.%x", fw_version, | 128 | "%.19s - %x.%x", fw_version, |
| 129 | priv->fw_var >> 8, priv->fw_var & 0xff); | 129 | priv->fw_var >> 8, priv->fw_var & 0xff); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| @@ -700,6 +700,7 @@ static struct spi_driver p54spi_driver = { · 699 unmodified lines | |||
| 700 | 700 | ||
| 701 | module_spi_driver(p54spi_driver); | 701 | module_spi_driver(p54spi_driver); |
| 702 | 702 | ||
| 703 | MODULE_DESCRIPTION("Prism54 SPI wireless driver"); | ||
| 703 | MODULE_LICENSE("GPL"); | 704 | MODULE_LICENSE("GPL"); |
| 704 | MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); | 705 | MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); |
| 705 | MODULE_ALIAS("spi:cx3110x"); | 706 | MODULE_ALIAS("spi:cx3110x"); |
| @@ -728,6 +728,7 @@ const struct ieee80211_ops mt7603_ops = { · 727 unmodified lines | |||
| 728 | .set_sar_specs = mt7603_set_sar_specs, | 728 | .set_sar_specs = mt7603_set_sar_specs, |
| 729 | }; | 729 | }; |
| 730 | 730 | ||
| 731 | MODULE_DESCRIPTION("MediaTek MT7603E and MT76x8 wireless driver"); | ||
| 731 | MODULE_LICENSE("Dual BSD/GPL"); | 732 | MODULE_LICENSE("Dual BSD/GPL"); |
| 732 | 733 | ||
| 733 | static int __init mt7603_init(void) | 734 | static int __init mt7603_init(void) |
| @@ -1375,4 +1375,5 @@ const struct ieee80211_ops mt7615_ops = { · 1374 unmodified lines | |||
| 1375 | }; | 1375 | }; |
| 1376 | EXPORT_SYMBOL_GPL(mt7615_ops); | 1376 | EXPORT_SYMBOL_GPL(mt7615_ops); |
| 1377 | 1377 | ||
| 1378 | MODULE_DESCRIPTION("MediaTek MT7615E and MT7663E wireless driver"); | ||
| 1378 | MODULE_LICENSE("Dual BSD/GPL"); | 1379 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -270,4 +270,5 @@ static void __exit mt7615_exit(void) · 269 unmodified lines | |||
| 270 | 270 | ||
| 271 | module_init(mt7615_init); | 271 | module_init(mt7615_init); |
| 272 | module_exit(mt7615_exit); | 272 | module_exit(mt7615_exit); |
| 273 | MODULE_DESCRIPTION("MediaTek MT7615E MMIO helpers"); | ||
| 273 | MODULE_LICENSE("Dual BSD/GPL"); | 274 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -253,4 +253,5 @@ module_sdio_driver(mt7663s_driver); · 252 unmodified lines | |||
| 253 | 253 | ||
| 254 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 254 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| 255 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 255 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 256 | MODULE_DESCRIPTION("MediaTek MT7663S (SDIO) wireless driver"); | ||
| 256 | MODULE_LICENSE("Dual BSD/GPL"); | 257 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -281,4 +281,5 @@ module_usb_driver(mt7663u_driver); · 280 unmodified lines | |||
| 281 | 281 | ||
| 282 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 282 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| 283 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 283 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 284 | MODULE_DESCRIPTION("MediaTek MT7663U (USB) wireless driver"); | ||
| 284 | MODULE_LICENSE("Dual BSD/GPL"); | 285 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -349,4 +349,5 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_register_device); · 348 unmodified lines | |||
| 349 | 349 | ||
| 350 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 350 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 351 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 351 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| 352 | MODULE_DESCRIPTION("MediaTek MT7663 SDIO/USB helpers"); | ||
| 352 | MODULE_LICENSE("Dual BSD/GPL"); | 353 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -3160,4 +3160,5 @@ exit: · 3159 unmodified lines | |||
| 3160 | EXPORT_SYMBOL_GPL(mt76_connac2_mcu_fill_message); | 3160 | EXPORT_SYMBOL_GPL(mt76_connac2_mcu_fill_message); |
| 3161 | 3161 | ||
| 3162 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 3162 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 3163 | MODULE_DESCRIPTION("MediaTek MT76x connac layer helpers"); | ||
| 3163 | MODULE_LICENSE("Dual BSD/GPL"); | 3164 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -342,4 +342,5 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev) · 341 unmodified lines | |||
| 342 | return 0; | 342 | return 0; |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | MODULE_DESCRIPTION("MediaTek MT76x EEPROM helpers"); | ||
| 345 | MODULE_LICENSE("Dual BSD/GPL"); | 346 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -302,6 +302,7 @@ static const struct pci_device_id mt76x0e_device_table[] = { · 301 unmodified lines | |||
| 302 | MODULE_DEVICE_TABLE(pci, mt76x0e_device_table); | 302 | MODULE_DEVICE_TABLE(pci, mt76x0e_device_table); |
| 303 | MODULE_FIRMWARE(MT7610E_FIRMWARE); | 303 | MODULE_FIRMWARE(MT7610E_FIRMWARE); |
| 304 | MODULE_FIRMWARE(MT7650E_FIRMWARE); | 304 | MODULE_FIRMWARE(MT7650E_FIRMWARE); |
| 305 | MODULE_DESCRIPTION("MediaTek MT76x0E (PCIe) wireless driver"); | ||
| 305 | MODULE_LICENSE("Dual BSD/GPL"); | 306 | MODULE_LICENSE("Dual BSD/GPL"); |
| 306 | 307 | ||
| 307 | static struct pci_driver mt76x0e_driver = { | 308 | static struct pci_driver mt76x0e_driver = { |
| @@ -336,6 +336,7 @@ err: · 335 unmodified lines | |||
| 336 | MODULE_DEVICE_TABLE(usb, mt76x0_device_table); | 336 | MODULE_DEVICE_TABLE(usb, mt76x0_device_table); |
| 337 | MODULE_FIRMWARE(MT7610E_FIRMWARE); | 337 | MODULE_FIRMWARE(MT7610E_FIRMWARE); |
| 338 | MODULE_FIRMWARE(MT7610U_FIRMWARE); | 338 | MODULE_FIRMWARE(MT7610U_FIRMWARE); |
| 339 | MODULE_DESCRIPTION("MediaTek MT76x0U (USB) wireless driver"); | ||
| 339 | MODULE_LICENSE("GPL"); | 340 | MODULE_LICENSE("GPL"); |
| 340 | 341 | ||
| 341 | static struct usb_driver mt76x0_driver = { | 342 | static struct usb_driver mt76x0_driver = { |
| @@ -293,4 +293,5 @@ void mt76x02u_init_mcu(struct mt76_dev *dev) · 292 unmodified lines | |||
| 293 | EXPORT_SYMBOL_GPL(mt76x02u_init_mcu); | 293 | EXPORT_SYMBOL_GPL(mt76x02u_init_mcu); |
| 294 | 294 | ||
| 295 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); | 295 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); |
| 296 | MODULE_DESCRIPTION("MediaTek MT76x02 MCU helpers"); | ||
| 296 | MODULE_LICENSE("Dual BSD/GPL"); | 297 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -696,4 +696,5 @@ void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev) · 695 unmodified lines | |||
| 696 | } | 696 | } |
| 697 | EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list); | 697 | EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list); |
| 698 | 698 | ||
| 699 | MODULE_DESCRIPTION("MediaTek MT76x02 helpers"); | ||
| 699 | MODULE_LICENSE("Dual BSD/GPL"); | 700 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -506,4 +506,5 @@ int mt76x2_eeprom_init(struct mt76x02_dev *dev) · 505 unmodified lines | |||
| 506 | } | 506 | } |
| 507 | EXPORT_SYMBOL_GPL(mt76x2_eeprom_init); | 507 | EXPORT_SYMBOL_GPL(mt76x2_eeprom_init); |
| 508 | 508 | ||
| 509 | MODULE_DESCRIPTION("MediaTek MT76x2 EEPROM helpers"); | ||
| 509 | MODULE_LICENSE("Dual BSD/GPL"); | 510 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -165,6 +165,7 @@ mt76x2e_resume(struct pci_dev *pdev) · 164 unmodified lines | |||
| 165 | MODULE_DEVICE_TABLE(pci, mt76x2e_device_table); | 165 | MODULE_DEVICE_TABLE(pci, mt76x2e_device_table); |
| 166 | MODULE_FIRMWARE(MT7662_FIRMWARE); | 166 | MODULE_FIRMWARE(MT7662_FIRMWARE); |
| 167 | MODULE_FIRMWARE(MT7662_ROM_PATCH); | 167 | MODULE_FIRMWARE(MT7662_ROM_PATCH); |
| 168 | MODULE_DESCRIPTION("MediaTek MT76x2E (PCIe) wireless driver"); | ||
| 168 | MODULE_LICENSE("Dual BSD/GPL"); | 169 | MODULE_LICENSE("Dual BSD/GPL"); |
| 169 | 170 | ||
| 170 | static struct pci_driver mt76pci_driver = { | 171 | static struct pci_driver mt76pci_driver = { |
| @@ -147,4 +147,5 @@ static struct usb_driver mt76x2u_driver = { · 146 unmodified lines | |||
| 147 | module_usb_driver(mt76x2u_driver); | 147 | module_usb_driver(mt76x2u_driver); |
| 148 | 148 | ||
| 149 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); | 149 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); |
| 150 | MODULE_DESCRIPTION("MediaTek MT76x2U (USB) wireless driver"); | ||
| 150 | MODULE_LICENSE("Dual BSD/GPL"); | 151 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -958,4 +958,5 @@ static void __exit mt7915_exit(void) · 957 unmodified lines | |||
| 958 | 958 | ||
| 959 | module_init(mt7915_init); | 959 | module_init(mt7915_init); |
| 960 | module_exit(mt7915_exit); | 960 | module_exit(mt7915_exit); |
| 961 | MODULE_DESCRIPTION("MediaTek MT7915E MMIO helpers"); | ||
| 961 | MODULE_LICENSE("Dual BSD/GPL"); | 962 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -1418,5 +1418,6 @@ const struct ieee80211_ops mt7921_ops = { · 1417 unmodified lines | |||
| 1418 | }; | 1418 | }; |
| 1419 | EXPORT_SYMBOL_GPL(mt7921_ops); | 1419 | EXPORT_SYMBOL_GPL(mt7921_ops); |
| 1420 | 1420 | ||
| 1421 | MODULE_DESCRIPTION("MediaTek MT7921 core driver"); | ||
| 1421 | MODULE_LICENSE("Dual BSD/GPL"); | 1422 | MODULE_LICENSE("Dual BSD/GPL"); |
| 1422 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 1423 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| @@ -544,4 +544,5 @@ MODULE_FIRMWARE(MT7922_FIRMWARE_WM); · 543 unmodified lines | |||
| 544 | MODULE_FIRMWARE(MT7922_ROM_PATCH); | 544 | MODULE_FIRMWARE(MT7922_ROM_PATCH); |
| 545 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 545 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| 546 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 546 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 547 | MODULE_DESCRIPTION("MediaTek MT7921E (PCIe) wireless driver"); | ||
| 547 | MODULE_LICENSE("Dual BSD/GPL"); | 548 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -323,5 +323,6 @@ static struct sdio_driver mt7921s_driver = { · 322 unmodified lines | |||
| 323 | .drv.pm = pm_sleep_ptr(&mt7921s_pm_ops), | 323 | .drv.pm = pm_sleep_ptr(&mt7921s_pm_ops), |
| 324 | }; | 324 | }; |
| 325 | module_sdio_driver(mt7921s_driver); | 325 | module_sdio_driver(mt7921s_driver); |
| 326 | MODULE_DESCRIPTION("MediaTek MT7921S (SDIO) wireless driver"); | ||
| 326 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 327 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| 327 | MODULE_LICENSE("Dual BSD/GPL"); | 328 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -336,5 +336,6 @@ static struct usb_driver mt7921u_driver = { · 335 unmodified lines | |||
| 336 | }; | 336 | }; |
| 337 | module_usb_driver(mt7921u_driver); | 337 | module_usb_driver(mt7921u_driver); |
| 338 | 338 | ||
| 339 | MODULE_DESCRIPTION("MediaTek MT7921U (USB) wireless driver"); | ||
| 339 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 340 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 340 | MODULE_LICENSE("Dual BSD/GPL"); | 341 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -1450,4 +1450,5 @@ const struct ieee80211_ops mt7925_ops = { · 1449 unmodified lines | |||
| 1450 | EXPORT_SYMBOL_GPL(mt7925_ops); | 1450 | EXPORT_SYMBOL_GPL(mt7925_ops); |
| 1451 | 1451 | ||
| 1452 | MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>"); | 1452 | MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>"); |
| 1453 | MODULE_DESCRIPTION("MediaTek MT7925 core driver"); | ||
| 1453 | MODULE_LICENSE("Dual BSD/GPL"); | 1454 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -583,4 +583,5 @@ MODULE_FIRMWARE(MT7925_FIRMWARE_WM); · 582 unmodified lines | |||
| 583 | MODULE_FIRMWARE(MT7925_ROM_PATCH); | 583 | MODULE_FIRMWARE(MT7925_ROM_PATCH); |
| 584 | MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>"); | 584 | MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>"); |
| 585 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 585 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 586 | MODULE_DESCRIPTION("MediaTek MT7925E (PCIe) wireless driver"); | ||
| 586 | MODULE_LICENSE("Dual BSD/GPL"); | 587 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -329,4 +329,5 @@ static struct usb_driver mt7925u_driver = { · 328 unmodified lines | |||
| 329 | module_usb_driver(mt7925u_driver); | 329 | module_usb_driver(mt7925u_driver); |
| 330 | 330 | ||
| 331 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 331 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 332 | MODULE_DESCRIPTION("MediaTek MT7925U (USB) wireless driver"); | ||
| 332 | MODULE_LICENSE("Dual BSD/GPL"); | 333 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -862,5 +862,6 @@ int mt792x_load_firmware(struct mt792x_dev *dev) · 861 unmodified lines | |||
| 862 | } | 862 | } |
| 863 | EXPORT_SYMBOL_GPL(mt792x_load_firmware); | 863 | EXPORT_SYMBOL_GPL(mt792x_load_firmware); |
| 864 | 864 | ||
| 865 | MODULE_DESCRIPTION("MediaTek MT792x core driver"); | ||
| 865 | MODULE_LICENSE("Dual BSD/GPL"); | 866 | MODULE_LICENSE("Dual BSD/GPL"); |
| 866 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 867 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| @@ -314,5 +314,6 @@ void mt792xu_disconnect(struct usb_interface *usb_intf) · 313 unmodified lines | |||
| 314 | } | 314 | } |
| 315 | EXPORT_SYMBOL_GPL(mt792xu_disconnect); | 315 | EXPORT_SYMBOL_GPL(mt792xu_disconnect); |
| 316 | 316 | ||
| 317 | MODULE_DESCRIPTION("MediaTek MT792x USB helpers"); | ||
| 317 | MODULE_LICENSE("Dual BSD/GPL"); | 318 | MODULE_LICENSE("Dual BSD/GPL"); |
| 318 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 319 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| @@ -4477,7 +4477,8 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy) · 4476 unmodified lines | |||
| 4477 | 4477 | ||
| 4478 | skb_put_data(skb, &req, sizeof(req)); | 4478 | skb_put_data(skb, &req, sizeof(req)); |
| 4479 | /* cck and ofdm */ | 4479 | /* cck and ofdm */ |
| 4480 | skb_put_data(skb, &la.cck, sizeof(la.cck) + sizeof(la.ofdm)); | 4480 | skb_put_data(skb, &la.cck, sizeof(la.cck)); |
| 4481 | skb_put_data(skb, &la.ofdm, sizeof(la.ofdm)); | ||
| 4481 | /* ht20 */ | 4482 | /* ht20 */ |
| 4482 | skb_put_data(skb, &la.mcs[0], 8); | 4483 | skb_put_data(skb, &la.mcs[0], 8); |
| 4483 | /* ht40 */ | 4484 | /* ht40 */ |
| @@ -650,4 +650,5 @@ static void __exit mt7996_exit(void) · 649 unmodified lines | |||
| 650 | 650 | ||
| 651 | module_init(mt7996_init); | 651 | module_init(mt7996_init); |
| 652 | module_exit(mt7996_exit); | 652 | module_exit(mt7996_exit); |
| 653 | MODULE_DESCRIPTION("MediaTek MT7996 MMIO helpers"); | ||
| 653 | MODULE_LICENSE("Dual BSD/GPL"); | 654 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -672,4 +672,5 @@ EXPORT_SYMBOL_GPL(mt76s_init); · 671 unmodified lines | |||
| 672 | 672 | ||
| 673 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | 673 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); |
| 674 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); | 674 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); |
| 675 | MODULE_DESCRIPTION("MediaTek MT76x SDIO helpers"); | ||
| 675 | MODULE_LICENSE("Dual BSD/GPL"); | 676 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -1128,4 +1128,5 @@ int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf) · 1127 unmodified lines | |||
| 1128 | EXPORT_SYMBOL_GPL(mt76u_init); | 1128 | EXPORT_SYMBOL_GPL(mt76u_init); |
| 1129 | 1129 | ||
| 1130 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); | 1130 | MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); |
| 1131 | MODULE_DESCRIPTION("MediaTek MT76x USB helpers"); | ||
| 1131 | MODULE_LICENSE("Dual BSD/GPL"); | 1132 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -138,4 +138,5 @@ int __mt76_worker_fn(void *ptr) · 137 unmodified lines | |||
| 138 | } | 138 | } |
| 139 | EXPORT_SYMBOL_GPL(__mt76_worker_fn); | 139 | EXPORT_SYMBOL_GPL(__mt76_worker_fn); |
| 140 | 140 | ||
| 141 | MODULE_DESCRIPTION("MediaTek MT76x helpers"); | ||
| 141 | MODULE_LICENSE("Dual BSD/GPL"); | 142 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -1018,5 +1018,6 @@ unregister_netdev: · 1017 unmodified lines | |||
| 1018 | return ERR_PTR(ret); | 1018 | return ERR_PTR(ret); |
| 1019 | } | 1019 | } |
| 1020 | 1020 | ||
| 1021 | MODULE_DESCRIPTION("Atmel WILC1000 core wireless driver"); | ||
| 1021 | MODULE_LICENSE("GPL"); | 1022 | MODULE_LICENSE("GPL"); |
| 1022 | MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER)); | 1023 | MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER)); |
| @@ -984,4 +984,5 @@ static struct sdio_driver wilc_sdio_driver = { · 983 unmodified lines | |||
| 984 | module_driver(wilc_sdio_driver, | 984 | module_driver(wilc_sdio_driver, |
| 985 | sdio_register_driver, | 985 | sdio_register_driver, |
| 986 | sdio_unregister_driver); | 986 | sdio_unregister_driver); |
| 987 | MODULE_DESCRIPTION("Atmel WILC1000 SDIO wireless driver"); | ||
| 987 | MODULE_LICENSE("GPL"); | 988 | MODULE_LICENSE("GPL"); |
| @@ -273,6 +273,7 @@ static struct spi_driver wilc_spi_driver = { · 272 unmodified lines | |||
| 273 | .remove = wilc_bus_remove, | 273 | .remove = wilc_bus_remove, |
| 274 | }; | 274 | }; |
| 275 | module_spi_driver(wilc_spi_driver); | 275 | module_spi_driver(wilc_spi_driver); |
| 276 | MODULE_DESCRIPTION("Atmel WILC1000 SPI wireless driver"); | ||
| 276 | MODULE_LICENSE("GPL"); | 277 | MODULE_LICENSE("GPL"); |
| 277 | 278 | ||
| 278 | static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) | 279 | static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) |
| @@ -343,5 +343,6 @@ static void __exit wl1251_sdio_exit(void) · 342 unmodified lines | |||
| 343 | module_init(wl1251_sdio_init); | 343 | module_init(wl1251_sdio_init); |
| 344 | module_exit(wl1251_sdio_exit); | 344 | module_exit(wl1251_sdio_exit); |
| 345 | 345 | ||
| 346 | MODULE_DESCRIPTION("TI WL1251 SDIO helpers"); | ||
| 346 | MODULE_LICENSE("GPL"); | 347 | MODULE_LICENSE("GPL"); |
| 347 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); | 348 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); |
| @@ -342,6 +342,7 @@ static struct spi_driver wl1251_spi_driver = { · 341 unmodified lines | |||
| 342 | 342 | ||
| 343 | module_spi_driver(wl1251_spi_driver); | 343 | module_spi_driver(wl1251_spi_driver); |
| 344 | 344 | ||
| 345 | MODULE_DESCRIPTION("TI WL1251 SPI helpers"); | ||
| 345 | MODULE_LICENSE("GPL"); | 346 | MODULE_LICENSE("GPL"); |
| 346 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); | 347 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); |
| 347 | MODULE_ALIAS("spi:wl1251"); | 348 | MODULE_ALIAS("spi:wl1251"); |
| @@ -1955,6 +1955,7 @@ module_param_named(tcxo, tcxo_param, charp, 0); · 1954 unmodified lines | |||
| 1955 | MODULE_PARM_DESC(tcxo, | 1955 | MODULE_PARM_DESC(tcxo, |
| 1956 | "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6"); | 1956 | "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6"); |
| 1957 | 1957 | ||
| 1958 | MODULE_DESCRIPTION("TI WL12xx wireless driver"); | ||
| 1958 | MODULE_LICENSE("GPL v2"); | 1959 | MODULE_LICENSE("GPL v2"); |
| 1959 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 1960 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
| 1960 | MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); | 1961 | MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); |
| @@ -2086,6 +2086,7 @@ module_param_named(num_rx_desc, num_rx_desc_param, int, 0400); · 2085 unmodified lines | |||
| 2086 | MODULE_PARM_DESC(num_rx_desc_param, | 2086 | MODULE_PARM_DESC(num_rx_desc_param, |
| 2087 | "Number of Rx descriptors: u8 (default is 32)"); | 2087 | "Number of Rx descriptors: u8 (default is 32)"); |
| 2088 | 2088 | ||
| 2089 | MODULE_DESCRIPTION("TI WiLink 8 wireless driver"); | ||
| 2089 | MODULE_LICENSE("GPL v2"); | 2090 | MODULE_LICENSE("GPL v2"); |
| 2090 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 2091 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
| 2091 | MODULE_FIRMWARE(WL18XX_FW_NAME); | 2092 | MODULE_FIRMWARE(WL18XX_FW_NAME); |
| @@ -6793,6 +6793,7 @@ MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); · 6792 unmodified lines | |||
| 6793 | module_param(no_recovery, int, 0600); | 6793 | module_param(no_recovery, int, 0600); |
| 6794 | MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); | 6794 | MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); |
| 6795 | 6795 | ||
| 6796 | MODULE_DESCRIPTION("TI WLAN core driver"); | ||
| 6796 | MODULE_LICENSE("GPL"); | 6797 | MODULE_LICENSE("GPL"); |
| 6797 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 6798 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
| 6798 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 6799 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
| @@ -447,6 +447,7 @@ module_sdio_driver(wl1271_sdio_driver); · 446 unmodified lines | |||
| 447 | module_param(dump, bool, 0600); | 447 | module_param(dump, bool, 0600); |
| 448 | MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); | 448 | MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); |
| 449 | 449 | ||
| 450 | MODULE_DESCRIPTION("TI WLAN SDIO helpers"); | ||
| 450 | MODULE_LICENSE("GPL"); | 451 | MODULE_LICENSE("GPL"); |
| 451 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 452 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
| 452 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 453 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
| @@ -562,6 +562,7 @@ static struct spi_driver wl1271_spi_driver = { · 561 unmodified lines | |||
| 562 | }; | 562 | }; |
| 563 | 563 | ||
| 564 | module_spi_driver(wl1271_spi_driver); | 564 | module_spi_driver(wl1271_spi_driver); |
| 565 | MODULE_DESCRIPTION("TI WLAN SPI helpers"); | ||
| 565 | MODULE_LICENSE("GPL"); | 566 | MODULE_LICENSE("GPL"); |
| 566 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 567 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
| 567 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 568 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
| @@ -104,13 +104,12 @@ bool provides_xdp_headroom = true; · 103 unmodified lines | |||
| 104 | module_param(provides_xdp_headroom, bool, 0644); | 104 | module_param(provides_xdp_headroom, bool, 0644); |
| 105 | 105 | ||
| 106 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | 106 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, |
| 107 | u8 status); | 107 | s8 status); |
| 108 | 108 | ||
| 109 | static void make_tx_response(struct xenvif_queue *queue, | 109 | static void make_tx_response(struct xenvif_queue *queue, |
| 110 | struct xen_netif_tx_request *txp, | 110 | const struct xen_netif_tx_request *txp, |
| 111 | unsigned int extra_count, | 111 | unsigned int extra_count, |
| 112 | s8 st); | 112 | s8 status); |
| 113 | static void push_tx_responses(struct xenvif_queue *queue); | ||
| 114 | 113 | ||
| 115 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); | 114 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); |
| 116 | 115 | ||
| @@ -208,13 +207,9 @@ static void xenvif_tx_err(struct xenvif_queue *queue, · 91 unmodified lines | |||
| 208 | unsigned int extra_count, RING_IDX end) | 207 | unsigned int extra_count, RING_IDX end) |
| 209 | { | 208 | { |
| 210 | RING_IDX cons = queue->tx.req_cons; | 209 | RING_IDX cons = queue->tx.req_cons; |
| 211 | unsigned long flags; | ||
| 212 | 210 | ||
| 213 | do { | 211 | do { |
| 214 | spin_lock_irqsave(&queue->response_lock, flags); | ||
| 215 | make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); | 212 | make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); |
| 216 | push_tx_responses(queue); | ||
| 217 | spin_unlock_irqrestore(&queue->response_lock, flags); | ||
| 218 | if (cons == end) | 213 | if (cons == end) |
| 219 | break; | 214 | break; |
| 220 | RING_COPY_REQUEST(&queue->tx, cons++, txp); | 215 | RING_COPY_REQUEST(&queue->tx, cons++, txp); |
| @@ -463,12 +458,20 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 242 unmodified lines | |||
| 463 | } | 458 | } |
| 464 | 459 | ||
| 465 | for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; | 460 | for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; |
| 466 | shinfo->nr_frags++, gop++, nr_slots--) { | 461 | nr_slots--) { |
| 462 | if (unlikely(!txp->size)) { | ||
| 463 | make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); | ||
| 464 | ++txp; | ||
| 465 | continue; | ||
| 466 | } | ||
| 467 | |||
| 467 | index = pending_index(queue->pending_cons++); | 468 | index = pending_index(queue->pending_cons++); |
| 468 | pending_idx = queue->pending_ring[index]; | 469 | pending_idx = queue->pending_ring[index]; |
| 469 | xenvif_tx_create_map_op(queue, pending_idx, txp, | 470 | xenvif_tx_create_map_op(queue, pending_idx, txp, |
| 470 | txp == first ? extra_count : 0, gop); | 471 | txp == first ? extra_count : 0, gop); |
| 471 | frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); | 472 | frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); |
| 473 | ++shinfo->nr_frags; | ||
| 474 | ++gop; | ||
| 472 | 475 | ||
| 473 | if (txp == first) | 476 | if (txp == first) |
| 474 | txp = txfrags; | 477 | txp = txfrags; |
| @@ -481,20 +484,33 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 6 unmodified lines | |||
| 481 | shinfo = skb_shinfo(nskb); | 484 | shinfo = skb_shinfo(nskb); |
| 482 | frags = shinfo->frags; | 485 | frags = shinfo->frags; |
| 483 | 486 | ||
| 484 | for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; | 487 | for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { |
| 485 | shinfo->nr_frags++, txp++, gop++) { | 488 | if (unlikely(!txp->size)) { |
| 489 | make_tx_response(queue, txp, 0, | ||
| 490 | XEN_NETIF_RSP_OKAY); | ||
| 491 | continue; | ||
| 492 | } | ||
| 493 | |||
| 486 | index = pending_index(queue->pending_cons++); | 494 | index = pending_index(queue->pending_cons++); |
| 487 | pending_idx = queue->pending_ring[index]; | 495 | pending_idx = queue->pending_ring[index]; |
| 488 | xenvif_tx_create_map_op(queue, pending_idx, txp, 0, | 496 | xenvif_tx_create_map_op(queue, pending_idx, txp, 0, |
| 489 | gop); | 497 | gop); |
| 490 | frag_set_pending_idx(&frags[shinfo->nr_frags], | 498 | frag_set_pending_idx(&frags[shinfo->nr_frags], |
| 491 | pending_idx); | 499 | pending_idx); |
| 500 | ++shinfo->nr_frags; | ||
| 501 | ++gop; | ||
| 502 | } | ||
| 503 | |||
| 504 | if (shinfo->nr_frags) { | ||
| 505 | skb_shinfo(skb)->frag_list = nskb; | ||
| 506 | nskb = NULL; | ||
| 492 | } | 507 | } |
| 508 | } | ||
| 493 | 509 | ||
| 494 | skb_shinfo(skb)->frag_list = nskb; | 510 | if (nskb) { |
| 495 | } else if (nskb) { | ||
| 496 | /* A frag_list skb was allocated but it is no longer needed | 511 | /* A frag_list skb was allocated but it is no longer needed |
| 497 | * because enough slots were converted to copy ops above. | 512 | * because enough slots were converted to copy ops above or some |
| 513 | * were empty. | ||
| 498 | */ | 514 | */ |
| 499 | kfree_skb(nskb); | 515 | kfree_skb(nskb); |
| 500 | } | 516 | } |
| @@ -963,7 +979,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 462 unmodified lines | |||
| 963 | (ret == 0) ? | 979 | (ret == 0) ? |
| 964 | XEN_NETIF_RSP_OKAY : | 980 | XEN_NETIF_RSP_OKAY : |
| 965 | XEN_NETIF_RSP_ERROR); | 981 | XEN_NETIF_RSP_ERROR); |
| 966 | push_tx_responses(queue); | ||
| 967 | continue; | 982 | continue; |
| 968 | } | 983 | } |
| 969 | 984 | ||
| @@ -975,7 +990,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 5 unmodified lines | |||
| 975 | 990 | ||
| 976 | make_tx_response(queue, &txreq, extra_count, | 991 | make_tx_response(queue, &txreq, extra_count, |
| 977 | XEN_NETIF_RSP_OKAY); | 992 | XEN_NETIF_RSP_OKAY); |
| 978 | push_tx_responses(queue); | ||
| 979 | continue; | 993 | continue; |
| 980 | } | 994 | } |
| 981 | 995 | ||
| @@ -1401,8 +1415,35 @@ int xenvif_tx_action(struct xenvif_queue *queue, int budget) · 419 unmodified lines | |||
| 1401 | return work_done; | 1415 | return work_done; |
| 1402 | } | 1416 | } |
| 1403 | 1417 | ||
| 1418 | static void _make_tx_response(struct xenvif_queue *queue, | ||
| 1419 | const struct xen_netif_tx_request *txp, | ||
| 1420 | unsigned int extra_count, | ||
| 1421 | s8 status) | ||
| 1422 | { | ||
| 1423 | RING_IDX i = queue->tx.rsp_prod_pvt; | ||
| 1424 | struct xen_netif_tx_response *resp; | ||
| 1425 | |||
| 1426 | resp = RING_GET_RESPONSE(&queue->tx, i); | ||
| 1427 | resp->id = txp->id; | ||
| 1428 | resp->status = status; | ||
| 1429 | |||
| 1430 | while (extra_count-- != 0) | ||
| 1431 | RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; | ||
| 1432 | |||
| 1433 | queue->tx.rsp_prod_pvt = ++i; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | static void push_tx_responses(struct xenvif_queue *queue) | ||
| 1437 | { | ||
| 1438 | int notify; | ||
| 1439 | |||
| 1440 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | ||
| 1441 | if (notify) | ||
| 1442 | notify_remote_via_irq(queue->tx_irq); | ||
| 1443 | } | ||
| 1444 | |||
| 1404 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | 1445 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, |
| 1405 | u8 status) | 1446 | s8 status) |
| 1406 | { | 1447 | { |
| 1407 | struct pending_tx_info *pending_tx_info; | 1448 | struct pending_tx_info *pending_tx_info; |
| 1408 | pending_ring_idx_t index; | 1449 | pending_ring_idx_t index; |
| @@ -1412,8 +1453,8 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 3 unmodified lines | |||
| 1412 | 1453 | ||
| 1413 | spin_lock_irqsave(&queue->response_lock, flags); | 1454 | spin_lock_irqsave(&queue->response_lock, flags); |
| 1414 | 1455 | ||
| 1415 | make_tx_response(queue, &pending_tx_info->req, | 1456 | _make_tx_response(queue, &pending_tx_info->req, |
| 1416 | pending_tx_info->extra_count, status); | 1457 | pending_tx_info->extra_count, status); |
| 1417 | 1458 | ||
| 1418 | /* Release the pending index before pusing the Tx response so | 1459 | /* Release the pending index before pusing the Tx response so |
| 1419 | * its available before a new Tx request is pushed by the | 1460 | * its available before a new Tx request is pushed by the |
| @@ -1427,32 +1468,19 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 7 unmodified lines | |||
| 1427 | spin_unlock_irqrestore(&queue->response_lock, flags); | 1468 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 1428 | } | 1469 | } |
| 1429 | 1470 | ||
| 1430 | |||
| 1431 | static void make_tx_response(struct xenvif_queue *queue, | 1471 | static void make_tx_response(struct xenvif_queue *queue, |
| 1432 | struct xen_netif_tx_request *txp, | 1472 | const struct xen_netif_tx_request *txp, |
| 1433 | unsigned int extra_count, | 1473 | unsigned int extra_count, |
| 1434 | s8 st) | 1474 | s8 status) |
| 1435 | { | 1475 | { |
| 1436 | RING_IDX i = queue->tx.rsp_prod_pvt; | 1476 | unsigned long flags; |
| 1437 | struct xen_netif_tx_response *resp; | ||
| 1438 | |||
| 1439 | resp = RING_GET_RESPONSE(&queue->tx, i); | ||
| 1440 | resp->id = txp->id; | ||
| 1441 | resp->status = st; | ||
| 1442 | |||
| 1443 | while (extra_count-- != 0) | ||
| 1444 | RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; | ||
| 1445 | 1477 | ||
| 1446 | queue->tx.rsp_prod_pvt = ++i; | 1478 | spin_lock_irqsave(&queue->response_lock, flags); |
| 1447 | } | ||
| 1448 | 1479 | ||
| 1449 | static void push_tx_responses(struct xenvif_queue *queue) | 1480 | _make_tx_response(queue, txp, extra_count, status); |
| 1450 | { | 1481 | push_tx_responses(queue); |
| 1451 | int notify; | ||
| 1452 | 1482 | ||
| 1453 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | 1483 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 1454 | if (notify) | ||
| 1455 | notify_remote_via_irq(queue->tx_irq); | ||
| 1456 | } | 1484 | } |
| 1457 | 1485 | ||
| 1458 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) | 1486 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) |
| @@ -471,4 +471,5 @@ int nvme_auth_generate_key(u8 *secret, struct nvme_dhchap_key **ret_key) · 470 unmodified lines | |||
| 471 | } | 471 | } |
| 472 | EXPORT_SYMBOL_GPL(nvme_auth_generate_key); | 472 | EXPORT_SYMBOL_GPL(nvme_auth_generate_key); |
| 473 | 473 | ||
| 474 | MODULE_DESCRIPTION("NVMe Authentication framework"); | ||
| 474 | MODULE_LICENSE("GPL v2"); | 475 | MODULE_LICENSE("GPL v2"); |
| @@ -181,5 +181,6 @@ static void __exit nvme_keyring_exit(void) · 180 unmodified lines | |||
| 181 | 181 | ||
| 182 | MODULE_LICENSE("GPL v2"); | 182 | MODULE_LICENSE("GPL v2"); |
| 183 | MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>"); | 183 | MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>"); |
| 184 | MODULE_DESCRIPTION("NVMe Keyring implementation"); | ||
| 184 | module_init(nvme_keyring_init); | 185 | module_init(nvme_keyring_init); |
| 185 | module_exit(nvme_keyring_exit); | 186 | module_exit(nvme_keyring_exit); |
| @@ -797,6 +797,7 @@ static int apple_nvme_init_request(struct blk_mq_tag_set *set, · 796 unmodified lines | |||
| 797 | 797 | ||
| 798 | static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown) | 798 | static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown) |
| 799 | { | 799 | { |
| 800 | enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl); | ||
| 800 | u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS); | 801 | u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS); |
| 801 | bool dead = false, freeze = false; | 802 | bool dead = false, freeze = false; |
| 802 | unsigned long flags; | 803 | unsigned long flags; |
| @@ -808,8 +809,8 @@ static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown) · 5 unmodified lines | |||
| 808 | if (csts & NVME_CSTS_CFS) | 809 | if (csts & NVME_CSTS_CFS) |
| 809 | dead = true; | 810 | dead = true; |
| 810 | 811 | ||
| 811 | if (anv->ctrl.state == NVME_CTRL_LIVE || | 812 | if (state == NVME_CTRL_LIVE || |
| 812 | anv->ctrl.state == NVME_CTRL_RESETTING) { | 813 | state == NVME_CTRL_RESETTING) { |
| 813 | freeze = true; | 814 | freeze = true; |
| 814 | nvme_start_freeze(&anv->ctrl); | 815 | nvme_start_freeze(&anv->ctrl); |
| 815 | } | 816 | } |
| @@ -881,7 +882,7 @@ static enum blk_eh_timer_return apple_nvme_timeout(struct request *req) · 65 unmodified lines | |||
| 881 | unsigned long flags; | 882 | unsigned long flags; |
| 882 | u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS); | 883 | u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS); |
| 883 | 884 | ||
| 884 | if (anv->ctrl.state != NVME_CTRL_LIVE) { | 885 | if (nvme_ctrl_state(&anv->ctrl) != NVME_CTRL_LIVE) { |
| 885 | /* | 886 | /* |
| 886 | * From rdma.c: | 887 | * From rdma.c: |
| 887 | * If we are resetting, connecting or deleting we should | 888 | * If we are resetting, connecting or deleting we should |
| @@ -985,10 +986,10 @@ static void apple_nvme_reset_work(struct work_struct *work) · 97 unmodified lines | |||
| 985 | u32 boot_status, aqa; | 986 | u32 boot_status, aqa; |
| 986 | struct apple_nvme *anv = | 987 | struct apple_nvme *anv = |
| 987 | container_of(work, struct apple_nvme, ctrl.reset_work); | 988 | container_of(work, struct apple_nvme, ctrl.reset_work); |
| 989 | enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl); | ||
| 988 | 990 | ||
| 989 | if (anv->ctrl.state != NVME_CTRL_RESETTING) { | 991 | if (state != NVME_CTRL_RESETTING) { |
| 990 | dev_warn(anv->dev, "ctrl state %d is not RESETTING\n", | 992 | dev_warn(anv->dev, "ctrl state %d is not RESETTING\n", state); |
| 991 | anv->ctrl.state); | ||
| 992 | ret = -ENODEV; | 993 | ret = -ENODEV; |
| 993 | goto out; | 994 | goto out; |
| 994 | } | 995 | } |
| @@ -48,11 +48,6 @@ struct nvme_dhchap_queue_context { · 47 unmodified lines | |||
| 48 | 48 | ||
| 49 | static struct workqueue_struct *nvme_auth_wq; | 49 | static struct workqueue_struct *nvme_auth_wq; |
| 50 | 50 | ||
| 51 | #define nvme_auth_flags_from_qid(qid) \ | ||
| 52 | (qid == 0) ? 0 : BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED | ||
| 53 | #define nvme_auth_queue_from_qid(ctrl, qid) \ | ||
| 54 | (qid == 0) ? (ctrl)->fabrics_q : (ctrl)->connect_q | ||
| 55 | |||
| 56 | static inline int ctrl_max_dhchaps(struct nvme_ctrl *ctrl) | 51 | static inline int ctrl_max_dhchaps(struct nvme_ctrl *ctrl) |
| 57 | { | 52 | { |
| 58 | return ctrl->opts->nr_io_queues + ctrl->opts->nr_write_queues + | 53 | return ctrl->opts->nr_io_queues + ctrl->opts->nr_write_queues + |
| @@ -63,10 +58,15 @@ static int nvme_auth_submit(struct nvme_ctrl *ctrl, int qid, · 4 unmodified lines | |||
| 63 | void *data, size_t data_len, bool auth_send) | 58 | void *data, size_t data_len, bool auth_send) |
| 64 | { | 59 | { |
| 65 | struct nvme_command cmd = {}; | 60 | struct nvme_command cmd = {}; |
| 66 | blk_mq_req_flags_t flags = nvme_auth_flags_from_qid(qid); | 61 | nvme_submit_flags_t flags = NVME_SUBMIT_RETRY; |
| 67 | struct request_queue *q = nvme_auth_queue_from_qid(ctrl, qid); | 62 | struct request_queue *q = ctrl->fabrics_q; |
| 68 | int ret; | 63 | int ret; |
| 69 | 64 | ||
| 65 | if (qid != 0) { | ||
| 66 | flags |= NVME_SUBMIT_NOWAIT | NVME_SUBMIT_RESERVED; | ||
| 67 | q = ctrl->connect_q; | ||
| 68 | } | ||
| 69 | |||
| 70 | cmd.auth_common.opcode = nvme_fabrics_command; | 70 | cmd.auth_common.opcode = nvme_fabrics_command; |
| 71 | cmd.auth_common.secp = NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER; | 71 | cmd.auth_common.secp = NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER; |
| 72 | cmd.auth_common.spsp0 = 0x01; | 72 | cmd.auth_common.spsp0 = 0x01; |
| @@ -80,8 +80,7 @@ static int nvme_auth_submit(struct nvme_ctrl *ctrl, int qid, · 7 unmodified lines | |||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | ret = __nvme_submit_sync_cmd(q, &cmd, NULL, data, data_len, | 82 | ret = __nvme_submit_sync_cmd(q, &cmd, NULL, data, data_len, |
| 83 | qid == 0 ? NVME_QID_ANY : qid, | 83 | qid == 0 ? NVME_QID_ANY : qid, flags); |
| 84 | 0, flags); | ||
| 85 | if (ret > 0) | 84 | if (ret > 0) |
| 86 | dev_warn(ctrl->device, | 85 | dev_warn(ctrl->device, |
| 87 | "qid %d auth_send failed with status %d\n", qid, ret); | 86 | "qid %d auth_send failed with status %d\n", qid, ret); |
| @@ -897,7 +896,7 @@ static void nvme_ctrl_auth_work(struct work_struct *work) · 809 unmodified lines | |||
| 897 | * If the ctrl is no connected, bail as reconnect will handle | 896 | * If the ctrl is no connected, bail as reconnect will handle |
| 898 | * authentication. | 897 | * authentication. |
| 899 | */ | 898 | */ |
| 900 | if (ctrl->state != NVME_CTRL_LIVE) | 899 | if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE) |
| 901 | return; | 900 | return; |
| 902 | 901 | ||
| 903 | /* Authenticate admin queue first */ | 902 | /* Authenticate admin queue first */ |
| @@ -171,15 +171,15 @@ static const char * const nvme_statuses[] = { · 170 unmodified lines | |||
| 171 | [NVME_SC_HOST_ABORTED_CMD] = "Host Aborted Command", | 171 | [NVME_SC_HOST_ABORTED_CMD] = "Host Aborted Command", |
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | const unsigned char *nvme_get_error_status_str(u16 status) | 174 | const char *nvme_get_error_status_str(u16 status) |
| 175 | { | 175 | { |
| 176 | status &= 0x7ff; | 176 | status &= 0x7ff; |
| 177 | if (status < ARRAY_SIZE(nvme_statuses) && nvme_statuses[status]) | 177 | if (status < ARRAY_SIZE(nvme_statuses) && nvme_statuses[status]) |
| 178 | return nvme_statuses[status & 0x7ff]; | 178 | return nvme_statuses[status]; |
| 179 | return "Unknown"; | 179 | return "Unknown"; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | const unsigned char *nvme_get_opcode_str(u8 opcode) | 182 | const char *nvme_get_opcode_str(u8 opcode) |
| 183 | { | 183 | { |
| 184 | if (opcode < ARRAY_SIZE(nvme_ops) && nvme_ops[opcode]) | 184 | if (opcode < ARRAY_SIZE(nvme_ops) && nvme_ops[opcode]) |
| 185 | return nvme_ops[opcode]; | 185 | return nvme_ops[opcode]; |
| @@ -187,7 +187,7 @@ const unsigned char *nvme_get_opcode_str(u8 opcode) · 1 unmodified line | |||
| 187 | } | 187 | } |
| 188 | EXPORT_SYMBOL_GPL(nvme_get_opcode_str); | 188 | EXPORT_SYMBOL_GPL(nvme_get_opcode_str); |
| 189 | 189 | ||
| 190 | const unsigned char *nvme_get_admin_opcode_str(u8 opcode) | 190 | const char *nvme_get_admin_opcode_str(u8 opcode) |
| 191 | { | 191 | { |
| 192 | if (opcode < ARRAY_SIZE(nvme_admin_ops) && nvme_admin_ops[opcode]) | 192 | if (opcode < ARRAY_SIZE(nvme_admin_ops) && nvme_admin_ops[opcode]) |
| 193 | return nvme_admin_ops[opcode]; | 193 | return nvme_admin_ops[opcode]; |
| @@ -195,7 +195,7 @@ const unsigned char *nvme_get_admin_opcode_str(u8 opcode) · 1 unmodified line | |||
| 195 | } | 195 | } |
| 196 | EXPORT_SYMBOL_GPL(nvme_get_admin_opcode_str); | 196 | EXPORT_SYMBOL_GPL(nvme_get_admin_opcode_str); |
| 197 | 197 | ||
| 198 | const unsigned char *nvme_get_fabrics_opcode_str(u8 opcode) { | 198 | const char *nvme_get_fabrics_opcode_str(u8 opcode) { |
| 199 | if (opcode < ARRAY_SIZE(nvme_fabrics_ops) && nvme_fabrics_ops[opcode]) | 199 | if (opcode < ARRAY_SIZE(nvme_fabrics_ops) && nvme_fabrics_ops[opcode]) |
| 200 | return nvme_fabrics_ops[opcode]; | 200 | return nvme_fabrics_ops[opcode]; |
| 201 | return "Unknown"; | 201 | return "Unknown"; |
| @@ -338,6 +338,30 @@ static void nvme_log_error(struct request *req) · 337 unmodified lines | |||
| 338 | nr->status & NVME_SC_DNR ? "DNR " : ""); | 338 | nr->status & NVME_SC_DNR ? "DNR " : ""); |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | static void nvme_log_err_passthru(struct request *req) | ||
| 342 | { | ||
| 343 | struct nvme_ns *ns = req->q->queuedata; | ||
| 344 | struct nvme_request *nr = nvme_req(req); | ||
| 345 | |||
| 346 | pr_err_ratelimited("%s: %s(0x%x), %s (sct 0x%x / sc 0x%x) %s%s" | ||
| 347 | "cdw10=0x%x cdw11=0x%x cdw12=0x%x cdw13=0x%x cdw14=0x%x cdw15=0x%x\n", | ||
| 348 | ns ? ns->disk->disk_name : dev_name(nr->ctrl->device), | ||
| 349 | ns ? nvme_get_opcode_str(nr->cmd->common.opcode) : | ||
| 350 | nvme_get_admin_opcode_str(nr->cmd->common.opcode), | ||
| 351 | nr->cmd->common.opcode, | ||
| 352 | nvme_get_error_status_str(nr->status), | ||
| 353 | nr->status >> 8 & 7, /* Status Code Type */ | ||
| 354 | nr->status & 0xff, /* Status Code */ | ||
| 355 | nr->status & NVME_SC_MORE ? "MORE " : "", | ||
| 356 | nr->status & NVME_SC_DNR ? "DNR " : "", | ||
| 357 | nr->cmd->common.cdw10, | ||
| 358 | nr->cmd->common.cdw11, | ||
| 359 | nr->cmd->common.cdw12, | ||
| 360 | nr->cmd->common.cdw13, | ||
| 361 | nr->cmd->common.cdw14, | ||
| 362 | nr->cmd->common.cdw14); | ||
| 363 | } | ||
| 364 | |||
| 341 | enum nvme_disposition { | 365 | enum nvme_disposition { |
| 342 | COMPLETE, | 366 | COMPLETE, |
| 343 | RETRY, | 367 | RETRY, |
| @@ -385,8 +409,12 @@ static inline void nvme_end_req(struct request *req) · 41 unmodified lines | |||
| 385 | { | 409 | { |
| 386 | blk_status_t status = nvme_error_status(nvme_req(req)->status); | 410 | blk_status_t status = nvme_error_status(nvme_req(req)->status); |
| 387 | 411 | ||
| 388 | if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET))) | 412 | if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET))) { |
| 389 | nvme_log_error(req); | 413 | if (blk_rq_is_passthrough(req)) |
| 414 | nvme_log_err_passthru(req); | ||
| 415 | else | ||
| 416 | nvme_log_error(req); | ||
| 417 | } | ||
| 390 | nvme_end_req_zoned(req); | 418 | nvme_end_req_zoned(req); |
| 391 | nvme_trace_bio_complete(req); | 419 | nvme_trace_bio_complete(req); |
| 392 | if (req->cmd_flags & REQ_NVME_MPATH) | 420 | if (req->cmd_flags & REQ_NVME_MPATH) |
| @@ -679,10 +707,21 @@ static inline void nvme_clear_nvme_request(struct request *req) · 286 unmodified lines | |||
| 679 | /* initialize a passthrough request */ | 707 | /* initialize a passthrough request */ |
| 680 | void nvme_init_request(struct request *req, struct nvme_command *cmd) | 708 | void nvme_init_request(struct request *req, struct nvme_command *cmd) |
| 681 | { | 709 | { |
| 682 | if (req->q->queuedata) | 710 | struct nvme_request *nr = nvme_req(req); |
| 711 | bool logging_enabled; | ||
| 712 | |||
| 713 | if (req->q->queuedata) { | ||
| 714 | struct nvme_ns *ns = req->q->disk->private_data; | ||
| 715 | |||
| 716 | logging_enabled = ns->head->passthru_err_log_enabled; | ||
| 683 | req->timeout = NVME_IO_TIMEOUT; | 717 | req->timeout = NVME_IO_TIMEOUT; |
| 684 | else /* no queuedata implies admin queue */ | 718 | } else { /* no queuedata implies admin queue */ |
| 719 | logging_enabled = nr->ctrl->passthru_err_log_enabled; | ||
| 685 | req->timeout = NVME_ADMIN_TIMEOUT; | 720 | req->timeout = NVME_ADMIN_TIMEOUT; |
| 721 | } | ||
| 722 | |||
| 723 | if (!logging_enabled) | ||
| 724 | req->rq_flags |= RQF_QUIET; | ||
| 686 | 725 | ||
| 687 | /* passthru commands should let the driver set the SGL flags */ | 726 | /* passthru commands should let the driver set the SGL flags */ |
| 688 | cmd->common.flags &= ~NVME_CMD_SGL_ALL; | 727 | cmd->common.flags &= ~NVME_CMD_SGL_ALL; |
| @@ -691,8 +730,7 @@ void nvme_init_request(struct request *req, struct nvme_command *cmd) · 2 unmodified lines | |||
| 691 | if (req->mq_hctx->type == HCTX_TYPE_POLL) | 730 | if (req->mq_hctx->type == HCTX_TYPE_POLL) |
| 692 | req->cmd_flags |= REQ_POLLED; | 731 | req->cmd_flags |= REQ_POLLED; |
| 693 | nvme_clear_nvme_request(req); | 732 | nvme_clear_nvme_request(req); |
| 694 | req->rq_flags |= RQF_QUIET; | 733 | memcpy(nr->cmd, cmd, sizeof(*cmd)); |
| 695 | memcpy(nvme_req(req)->cmd, cmd, sizeof(*cmd)); | ||
| 696 | } | 734 | } |
| 697 | EXPORT_SYMBOL_GPL(nvme_init_request); | 735 | EXPORT_SYMBOL_GPL(nvme_init_request); |
| 698 | 736 | ||
| @@ -721,7 +759,7 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl, · 22 unmodified lines | |||
| 721 | EXPORT_SYMBOL_GPL(nvme_fail_nonready_command); | 759 | EXPORT_SYMBOL_GPL(nvme_fail_nonready_command); |
| 722 | 760 | ||
| 723 | bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, | 761 | bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, |
| 724 | bool queue_live) | 762 | bool queue_live, enum nvme_ctrl_state state) |
| 725 | { | 763 | { |
| 726 | struct nvme_request *req = nvme_req(rq); | 764 | struct nvme_request *req = nvme_req(rq); |
| 727 | 765 | ||
| @@ -742,7 +780,7 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, · 14 unmodified lines | |||
| 742 | * command, which is require to set the queue live in the | 780 | * command, which is require to set the queue live in the |
| 743 | * appropinquate states. | 781 | * appropinquate states. |
| 744 | */ | 782 | */ |
| 745 | switch (nvme_ctrl_state(ctrl)) { | 783 | switch (state) { |
| 746 | case NVME_CTRL_CONNECTING: | 784 | case NVME_CTRL_CONNECTING: |
| 747 | if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) && | 785 | if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) && |
| 748 | (req->cmd->fabrics.fctype == nvme_fabrics_type_connect || | 786 | (req->cmd->fabrics.fctype == nvme_fabrics_type_connect || |
| @@ -1051,20 +1089,27 @@ EXPORT_SYMBOL_NS_GPL(nvme_execute_rq, NVME_TARGET_PASSTHRU); · 302 unmodified lines | |||
| 1051 | */ | 1089 | */ |
| 1052 | int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | 1090 | int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, |
| 1053 | union nvme_result *result, void *buffer, unsigned bufflen, | 1091 | union nvme_result *result, void *buffer, unsigned bufflen, |
| 1054 | int qid, int at_head, blk_mq_req_flags_t flags) | 1092 | int qid, nvme_submit_flags_t flags) |
| 1055 | { | 1093 | { |
| 1056 | struct request *req; | 1094 | struct request *req; |
| 1057 | int ret; | 1095 | int ret; |
| 1096 | blk_mq_req_flags_t blk_flags = 0; | ||
| 1058 | 1097 | ||
| 1098 | if (flags & NVME_SUBMIT_NOWAIT) | ||
| 1099 | blk_flags |= BLK_MQ_REQ_NOWAIT; | ||
| 1100 | if (flags & NVME_SUBMIT_RESERVED) | ||
| 1101 | blk_flags |= BLK_MQ_REQ_RESERVED; | ||
| 1059 | if (qid == NVME_QID_ANY) | 1102 | if (qid == NVME_QID_ANY) |
| 1060 | req = blk_mq_alloc_request(q, nvme_req_op(cmd), flags); | 1103 | req = blk_mq_alloc_request(q, nvme_req_op(cmd), blk_flags); |
| 1061 | else | 1104 | else |
| 1062 | req = blk_mq_alloc_request_hctx(q, nvme_req_op(cmd), flags, | 1105 | req = blk_mq_alloc_request_hctx(q, nvme_req_op(cmd), blk_flags, |
| 1063 | qid - 1); | 1106 | qid - 1); |
| 1064 | 1107 | ||
| 1065 | if (IS_ERR(req)) | 1108 | if (IS_ERR(req)) |
| 1066 | return PTR_ERR(req); | 1109 | return PTR_ERR(req); |
| 1067 | nvme_init_request(req, cmd); | 1110 | nvme_init_request(req, cmd); |
| 1111 | if (flags & NVME_SUBMIT_RETRY) | ||
| 1112 | req->cmd_flags &= ~REQ_FAILFAST_DRIVER; | ||
| 1068 | 1113 | ||
| 1069 | if (buffer && bufflen) { | 1114 | if (buffer && bufflen) { |
| 1070 | ret = blk_rq_map_kern(q, req, buffer, bufflen, GFP_KERNEL); | 1115 | ret = blk_rq_map_kern(q, req, buffer, bufflen, GFP_KERNEL); |
| @@ -1072,7 +1117,7 @@ int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, · 1 unmodified line | |||
| 1072 | goto out; | 1117 | goto out; |
| 1073 | } | 1118 | } |
| 1074 | 1119 | ||
| 1075 | ret = nvme_execute_rq(req, at_head); | 1120 | ret = nvme_execute_rq(req, flags & NVME_SUBMIT_AT_HEAD); |
| 1076 | if (result && ret >= 0) | 1121 | if (result && ret >= 0) |
| 1077 | *result = nvme_req(req)->result; | 1122 | *result = nvme_req(req)->result; |
| 1078 | out: | 1123 | out: |
| @@ -1085,7 +1130,7 @@ int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, · 6 unmodified lines | |||
| 1085 | void *buffer, unsigned bufflen) | 1130 | void *buffer, unsigned bufflen) |
| 1086 | { | 1131 | { |
| 1087 | return __nvme_submit_sync_cmd(q, cmd, NULL, buffer, bufflen, | 1132 | return __nvme_submit_sync_cmd(q, cmd, NULL, buffer, bufflen, |
| 1088 | NVME_QID_ANY, 0, 0); | 1133 | NVME_QID_ANY, 0); |
| 1089 | } | 1134 | } |
| 1090 | EXPORT_SYMBOL_GPL(nvme_submit_sync_cmd); | 1135 | EXPORT_SYMBOL_GPL(nvme_submit_sync_cmd); |
| 1091 | 1136 | ||
| @@ -1560,7 +1605,7 @@ static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid, · 468 unmodified lines | |||
| 1560 | c.features.dword11 = cpu_to_le32(dword11); | 1605 | c.features.dword11 = cpu_to_le32(dword11); |
| 1561 | 1606 | ||
| 1562 | ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &res, | 1607 | ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &res, |
| 1563 | buffer, buflen, NVME_QID_ANY, 0, 0); | 1608 | buffer, buflen, NVME_QID_ANY, 0); |
| 1564 | if (ret >= 0 && result) | 1609 | if (ret >= 0 && result) |
| 1565 | *result = le32_to_cpu(res.u32); | 1610 | *result = le32_to_cpu(res.u32); |
| 1566 | return ret; | 1611 | return ret; |
| @@ -2172,7 +2217,7 @@ static int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t l · 605 unmodified lines | |||
| 2172 | cmd.common.cdw11 = cpu_to_le32(len); | 2217 | cmd.common.cdw11 = cpu_to_le32(len); |
| 2173 | 2218 | ||
| 2174 | return __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len, | 2219 | return __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len, |
| 2175 | NVME_QID_ANY, 1, 0); | 2220 | NVME_QID_ANY, NVME_SUBMIT_AT_HEAD); |
| 2176 | } | 2221 | } |
| 2177 | 2222 | ||
| 2178 | static void nvme_configure_opal(struct nvme_ctrl *ctrl, bool was_suspended) | 2223 | static void nvme_configure_opal(struct nvme_ctrl *ctrl, bool was_suspended) |
| @@ -3714,6 +3759,13 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info) · 1535 unmodified lines | |||
| 3714 | nvme_mpath_add_disk(ns, info->anagrpid); | 3759 | nvme_mpath_add_disk(ns, info->anagrpid); |
| 3715 | nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name); | 3760 | nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name); |
| 3716 | 3761 | ||
| 3762 | /* | ||
| 3763 | * Set ns->disk->device->driver_data to ns so we can access | ||
| 3764 | * ns->head->passthru_err_log_enabled in | ||
| 3765 | * nvme_io_passthru_err_log_enabled_[store | show](). | ||
| 3766 | */ | ||
| 3767 | dev_set_drvdata(disk_to_dev(ns->disk), ns); | ||
| 3768 | |||
| 3717 | return; | 3769 | return; |
| 3718 | 3770 | ||
| 3719 | out_cleanup_ns_from_list: | 3771 | out_cleanup_ns_from_list: |
| @@ -4138,6 +4190,7 @@ static bool nvme_ctrl_pp_status(struct nvme_ctrl *ctrl) · 418 unmodified lines | |||
| 4138 | static void nvme_get_fw_slot_info(struct nvme_ctrl *ctrl) | 4190 | static void nvme_get_fw_slot_info(struct nvme_ctrl *ctrl) |
| 4139 | { | 4191 | { |
| 4140 | struct nvme_fw_slot_info_log *log; | 4192 | struct nvme_fw_slot_info_log *log; |
| 4193 | u8 next_fw_slot, cur_fw_slot; | ||
| 4141 | 4194 | ||
| 4142 | log = kmalloc(sizeof(*log), GFP_KERNEL); | 4195 | log = kmalloc(sizeof(*log), GFP_KERNEL); |
| 4143 | if (!log) | 4196 | if (!log) |
| @@ -4149,13 +4202,15 @@ static void nvme_get_fw_slot_info(struct nvme_ctrl *ctrl) · 5 unmodified lines | |||
| 4149 | goto out_free_log; | 4202 | goto out_free_log; |
| 4150 | } | 4203 | } |
| 4151 | 4204 | ||
| 4152 | if (log->afi & 0x70 || !(log->afi & 0x7)) { | 4205 | cur_fw_slot = log->afi & 0x7; |
| 4206 | next_fw_slot = (log->afi & 0x70) >> 4; | ||
| 4207 | if (!cur_fw_slot || (next_fw_slot && (cur_fw_slot != next_fw_slot))) { | ||
| 4153 | dev_info(ctrl->device, | 4208 | dev_info(ctrl->device, |
| 4154 | "Firmware is activated after next Controller Level Reset\n"); | 4209 | "Firmware is activated after next Controller Level Reset\n"); |
| 4155 | goto out_free_log; | 4210 | goto out_free_log; |
| 4156 | } | 4211 | } |
| 4157 | 4212 | ||
| 4158 | memcpy(ctrl->subsys->firmware_rev, &log->frs[(log->afi & 0x7) - 1], | 4213 | memcpy(ctrl->subsys->firmware_rev, &log->frs[cur_fw_slot - 1], |
| 4159 | sizeof(ctrl->subsys->firmware_rev)); | 4214 | sizeof(ctrl->subsys->firmware_rev)); |
| 4160 | 4215 | ||
| 4161 | out_free_log: | 4216 | out_free_log: |
| @@ -4514,6 +4569,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, · 352 unmodified lines | |||
| 4514 | int ret; | 4569 | int ret; |
| 4515 | 4570 | ||
| 4516 | WRITE_ONCE(ctrl->state, NVME_CTRL_NEW); | 4571 | WRITE_ONCE(ctrl->state, NVME_CTRL_NEW); |
| 4572 | ctrl->passthru_err_log_enabled = false; | ||
| 4517 | clear_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags); | 4573 | clear_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags); |
| 4518 | spin_lock_init(&ctrl->lock); | 4574 | spin_lock_init(&ctrl->lock); |
| 4519 | mutex_init(&ctrl->scan_lock); | 4575 | mutex_init(&ctrl->scan_lock); |
| @@ -4851,5 +4907,6 @@ static void __exit nvme_core_exit(void) · 331 unmodified lines | |||
| 4851 | 4907 | ||
| 4852 | MODULE_LICENSE("GPL"); | 4908 | MODULE_LICENSE("GPL"); |
| 4853 | MODULE_VERSION("1.0"); | 4909 | MODULE_VERSION("1.0"); |
| 4910 | MODULE_DESCRIPTION("NVMe host core framework"); | ||
| 4854 | module_init(nvme_core_init); | 4911 | module_init(nvme_core_init); |
| 4855 | module_exit(nvme_core_exit); | 4912 | module_exit(nvme_core_exit); |
| @@ -180,7 +180,7 @@ int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val) · 179 unmodified lines | |||
| 180 | cmd.prop_get.offset = cpu_to_le32(off); | 180 | cmd.prop_get.offset = cpu_to_le32(off); |
| 181 | 181 | ||
| 182 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, | 182 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, |
| 183 | NVME_QID_ANY, 0, 0); | 183 | NVME_QID_ANY, 0); |
| 184 | 184 | ||
| 185 | if (ret >= 0) | 185 | if (ret >= 0) |
| 186 | *val = le64_to_cpu(res.u64); | 186 | *val = le64_to_cpu(res.u64); |
| @@ -226,7 +226,7 @@ int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val) · 39 unmodified lines | |||
| 226 | cmd.prop_get.offset = cpu_to_le32(off); | 226 | cmd.prop_get.offset = cpu_to_le32(off); |
| 227 | 227 | ||
| 228 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, | 228 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, |
| 229 | NVME_QID_ANY, 0, 0); | 229 | NVME_QID_ANY, 0); |
| 230 | 230 | ||
| 231 | if (ret >= 0) | 231 | if (ret >= 0) |
| 232 | *val = le64_to_cpu(res.u64); | 232 | *val = le64_to_cpu(res.u64); |
| @@ -271,7 +271,7 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val) · 38 unmodified lines | |||
| 271 | cmd.prop_set.value = cpu_to_le64(val); | 271 | cmd.prop_set.value = cpu_to_le64(val); |
| 272 | 272 | ||
| 273 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0, | 273 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0, |
| 274 | NVME_QID_ANY, 0, 0); | 274 | NVME_QID_ANY, 0); |
| 275 | if (unlikely(ret)) | 275 | if (unlikely(ret)) |
| 276 | dev_err(ctrl->device, | 276 | dev_err(ctrl->device, |
| 277 | "Property Set error: %d, offset %#x\n", | 277 | "Property Set error: %d, offset %#x\n", |
| @@ -450,8 +450,10 @@ int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl) · 172 unmodified lines | |||
| 450 | return -ENOMEM; | 450 | return -ENOMEM; |
| 451 | 451 | ||
| 452 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, | 452 | ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, |
| 453 | data, sizeof(*data), NVME_QID_ANY, 1, | 453 | data, sizeof(*data), NVME_QID_ANY, |
| 454 | BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT); | 454 | NVME_SUBMIT_AT_HEAD | |
| 455 | NVME_SUBMIT_NOWAIT | | ||
| 456 | NVME_SUBMIT_RESERVED); | ||
| 455 | if (ret) { | 457 | if (ret) { |
| 456 | nvmf_log_connect_error(ctrl, ret, le32_to_cpu(res.u32), | 458 | nvmf_log_connect_error(ctrl, ret, le32_to_cpu(res.u32), |
| 457 | &cmd, data); | 459 | &cmd, data); |
| @@ -525,8 +527,10 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid) · 67 unmodified lines | |||
| 525 | return -ENOMEM; | 527 | return -ENOMEM; |
| 526 | 528 | ||
| 527 | ret = __nvme_submit_sync_cmd(ctrl->connect_q, &cmd, &res, | 529 | ret = __nvme_submit_sync_cmd(ctrl->connect_q, &cmd, &res, |
| 528 | data, sizeof(*data), qid, 1, | 530 | data, sizeof(*data), qid, |
| 529 | BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT); | 531 | NVME_SUBMIT_AT_HEAD | |
| 532 | NVME_SUBMIT_RESERVED | | ||
| 533 | NVME_SUBMIT_NOWAIT); | ||
| 530 | if (ret) { | 534 | if (ret) { |
| 531 | nvmf_log_connect_error(ctrl, ret, le32_to_cpu(res.u32), | 535 | nvmf_log_connect_error(ctrl, ret, le32_to_cpu(res.u32), |
| 532 | &cmd, data); | 536 | &cmd, data); |
| @@ -1488,6 +1492,7 @@ static void __exit nvmf_exit(void) · 955 unmodified lines | |||
| 1488 | } | 1492 | } |
| 1489 | 1493 | ||
| 1490 | MODULE_LICENSE("GPL v2"); | 1494 | MODULE_LICENSE("GPL v2"); |
| 1495 | MODULE_DESCRIPTION("NVMe host fabrics library"); | ||
| 1491 | 1496 | ||
| 1492 | module_init(nvmf_init); | 1497 | module_init(nvmf_init); |
| 1493 | module_exit(nvmf_exit); | 1498 | module_exit(nvmf_exit); |
| @@ -185,9 +185,11 @@ static inline bool · 184 unmodified lines | |||
| 185 | nvmf_ctlr_matches_baseopts(struct nvme_ctrl *ctrl, | 185 | nvmf_ctlr_matches_baseopts(struct nvme_ctrl *ctrl, |
| 186 | struct nvmf_ctrl_options *opts) | 186 | struct nvmf_ctrl_options *opts) |
| 187 | { | 187 | { |
| 188 | if (ctrl->state == NVME_CTRL_DELETING || | 188 | enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); |
| 189 | ctrl->state == NVME_CTRL_DELETING_NOIO || | 189 | |
| 190 | ctrl->state == NVME_CTRL_DEAD || | 190 | if (state == NVME_CTRL_DELETING || |
| 191 | state == NVME_CTRL_DELETING_NOIO || | ||
| 192 | state == NVME_CTRL_DEAD || | ||
| 191 | strcmp(opts->subsysnqn, ctrl->opts->subsysnqn) || | 193 | strcmp(opts->subsysnqn, ctrl->opts->subsysnqn) || |
| 192 | strcmp(opts->host->nqn, ctrl->opts->host->nqn) || | 194 | strcmp(opts->host->nqn, ctrl->opts->host->nqn) || |
| 193 | !uuid_equal(&opts->host->id, &ctrl->opts->host->id)) | 195 | !uuid_equal(&opts->host->id, &ctrl->opts->host->id)) |
| @@ -221,11 +221,6 @@ static LIST_HEAD(nvme_fc_lport_list); · 220 unmodified lines | |||
| 221 | static DEFINE_IDA(nvme_fc_local_port_cnt); | 221 | static DEFINE_IDA(nvme_fc_local_port_cnt); |
| 222 | static DEFINE_IDA(nvme_fc_ctrl_cnt); | 222 | static DEFINE_IDA(nvme_fc_ctrl_cnt); |
| 223 | 223 | ||
| 224 | static struct workqueue_struct *nvme_fc_wq; | ||
| 225 | |||
| 226 | static bool nvme_fc_waiting_to_unload; | ||
| 227 | static DECLARE_COMPLETION(nvme_fc_unload_proceed); | ||
| 228 | |||
| 229 | /* | 224 | /* |
| 230 | * These items are short-term. They will eventually be moved into | 225 | * These items are short-term. They will eventually be moved into |
| 231 | * a generic FC class. See comments in module init. | 226 | * a generic FC class. See comments in module init. |
| @@ -255,8 +250,6 @@ nvme_fc_free_lport(struct kref *ref) · 23 unmodified lines | |||
| 255 | /* remove from transport list */ | 250 | /* remove from transport list */ |
| 256 | spin_lock_irqsave(&nvme_fc_lock, flags); | 251 | spin_lock_irqsave(&nvme_fc_lock, flags); |
| 257 | list_del(&lport->port_list); | 252 | list_del(&lport->port_list); |
| 258 | if (nvme_fc_waiting_to_unload && list_empty(&nvme_fc_lport_list)) | ||
| 259 | complete(&nvme_fc_unload_proceed); | ||
| 260 | spin_unlock_irqrestore(&nvme_fc_lock, flags); | 253 | spin_unlock_irqrestore(&nvme_fc_lock, flags); |
| 261 | 254 | ||
| 262 | ida_free(&nvme_fc_local_port_cnt, lport->localport.port_num); | 255 | ida_free(&nvme_fc_local_port_cnt, lport->localport.port_num); |
| @@ -2574,6 +2567,7 @@ static enum blk_eh_timer_return nvme_fc_timeout(struct request *rq) · 2311 unmodified lines | |||
| 2574 | { | 2567 | { |
| 2575 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq); | 2568 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq); |
| 2576 | struct nvme_fc_ctrl *ctrl = op->ctrl; | 2569 | struct nvme_fc_ctrl *ctrl = op->ctrl; |
| 2570 | u16 qnum = op->queue->qnum; | ||
| 2577 | struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu; | 2571 | struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu; |
| 2578 | struct nvme_command *sqe = &cmdiu->sqe; | 2572 | struct nvme_command *sqe = &cmdiu->sqe; |
| 2579 | 2573 | ||
| @@ -2582,10 +2576,11 @@ static enum blk_eh_timer_return nvme_fc_timeout(struct request *rq) · 2 unmodified lines | |||
| 2582 | * will detect the aborted io and will fail the connection. | 2576 | * will detect the aborted io and will fail the connection. |
| 2583 | */ | 2577 | */ |
| 2584 | dev_info(ctrl->ctrl.device, | 2578 | dev_info(ctrl->ctrl.device, |
| 2585 | "NVME-FC{%d.%d}: io timeout: opcode %d fctype %d w10/11: " | 2579 | "NVME-FC{%d.%d}: io timeout: opcode %d fctype %d (%s) w10/11: " |
| 2586 | "x%08x/x%08x\n", | 2580 | "x%08x/x%08x\n", |
| 2587 | ctrl->cnum, op->queue->qnum, sqe->common.opcode, | 2581 | ctrl->cnum, qnum, sqe->common.opcode, sqe->fabrics.fctype, |
| 2588 | sqe->connect.fctype, sqe->common.cdw10, sqe->common.cdw11); | 2582 | nvme_fabrics_opcode_str(qnum, sqe), |
| 2583 | sqe->common.cdw10, sqe->common.cdw11); | ||
| 2589 | if (__nvme_fc_abort_op(ctrl, op)) | 2584 | if (__nvme_fc_abort_op(ctrl, op)) |
| 2590 | nvme_fc_error_recovery(ctrl, "io timeout abort failed"); | 2585 | nvme_fc_error_recovery(ctrl, "io timeout abort failed"); |
| 2591 | 2586 | ||
| @@ -3575,8 +3570,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · 983 unmodified lines | |||
| 3575 | flush_delayed_work(&ctrl->connect_work); | 3570 | flush_delayed_work(&ctrl->connect_work); |
| 3576 | 3571 | ||
| 3577 | dev_info(ctrl->ctrl.device, | 3572 | dev_info(ctrl->ctrl.device, |
| 3578 | "NVME-FC{%d}: new ctrl: NQN \"%s\"\n", | 3573 | "NVME-FC{%d}: new ctrl: NQN \"%s\", hostnqn: %s\n", |
| 3579 | ctrl->cnum, nvmf_ctrl_subsysnqn(&ctrl->ctrl)); | 3574 | ctrl->cnum, nvmf_ctrl_subsysnqn(&ctrl->ctrl), opts->host->nqn); |
| 3580 | 3575 | ||
| 3581 | return &ctrl->ctrl; | 3576 | return &ctrl->ctrl; |
| 3582 | 3577 | ||
| @@ -3894,10 +3889,6 @@ static int __init nvme_fc_init_module(void) · 311 unmodified lines | |||
| 3894 | { | 3889 | { |
| 3895 | int ret; | 3890 | int ret; |
| 3896 | 3891 | ||
| 3897 | nvme_fc_wq = alloc_workqueue("nvme_fc_wq", WQ_MEM_RECLAIM, 0); | ||
| 3898 | if (!nvme_fc_wq) | ||
| 3899 | return -ENOMEM; | ||
| 3900 | |||
| 3901 | /* | 3892 | /* |
| 3902 | * NOTE: | 3893 | * NOTE: |
| 3903 | * It is expected that in the future the kernel will combine | 3894 | * It is expected that in the future the kernel will combine |
| @@ -3915,7 +3906,7 @@ static int __init nvme_fc_init_module(void) · 11 unmodified lines | |||
| 3915 | ret = class_register(&fc_class); | 3906 | ret = class_register(&fc_class); |
| 3916 | if (ret) { | 3907 | if (ret) { |
| 3917 | pr_err("couldn't register class fc\n"); | 3908 | pr_err("couldn't register class fc\n"); |
| 3918 | goto out_destroy_wq; | 3909 | return ret; |
| 3919 | } | 3910 | } |
| 3920 | 3911 | ||
| 3921 | /* | 3912 | /* |
| @@ -3939,8 +3930,6 @@ out_destroy_device: · 17 unmodified lines | |||
| 3939 | device_destroy(&fc_class, MKDEV(0, 0)); | 3930 | device_destroy(&fc_class, MKDEV(0, 0)); |
| 3940 | out_destroy_class: | 3931 | out_destroy_class: |
| 3941 | class_unregister(&fc_class); | 3932 | class_unregister(&fc_class); |
| 3942 | out_destroy_wq: | ||
| 3943 | destroy_workqueue(nvme_fc_wq); | ||
| 3944 | 3933 | ||
| 3945 | return ret; | 3934 | return ret; |
| 3946 | } | 3935 | } |
| @@ -3960,48 +3949,27 @@ nvme_fc_delete_controllers(struct nvme_fc_rport *rport) · 13 unmodified lines | |||
| 3960 | spin_unlock(&rport->lock); | 3949 | spin_unlock(&rport->lock); |
| 3961 | } | 3950 | } |
| 3962 | 3951 | ||
| 3963 | static void | 3952 | static void __exit nvme_fc_exit_module(void) |
| 3964 | nvme_fc_cleanup_for_unload(void) | ||
| 3965 | { | 3953 | { |
| 3966 | struct nvme_fc_lport *lport; | 3954 | struct nvme_fc_lport *lport; |
| 3967 | struct nvme_fc_rport *rport; | 3955 | struct nvme_fc_rport *rport; |
| 3968 | |||
| 3969 | list_for_each_entry(lport, &nvme_fc_lport_list, port_list) { | ||
| 3970 | list_for_each_entry(rport, &lport->endp_list, endp_list) { | ||
| 3971 | nvme_fc_delete_controllers(rport); | ||
| 3972 | } | ||
| 3973 | } | ||
| 3974 | } | ||
| 3975 | |||
| 3976 | static void __exit nvme_fc_exit_module(void) | ||
| 3977 | { | ||
| 3978 | unsigned long flags; | 3956 | unsigned long flags; |
| 3979 | bool need_cleanup = false; | ||
| 3980 | 3957 | ||
| 3981 | spin_lock_irqsave(&nvme_fc_lock, flags); | 3958 | spin_lock_irqsave(&nvme_fc_lock, flags); |
| 3982 | nvme_fc_waiting_to_unload = true; | 3959 | list_for_each_entry(lport, &nvme_fc_lport_list, port_list) |
| 3983 | if (!list_empty(&nvme_fc_lport_list)) { | 3960 | list_for_each_entry(rport, &lport->endp_list, endp_list) |
| 3984 | need_cleanup = true; | 3961 | nvme_fc_delete_controllers(rport); |
| 3985 | nvme_fc_cleanup_for_unload(); | ||
| 3986 | } | ||
| 3987 | spin_unlock_irqrestore(&nvme_fc_lock, flags); | 3962 | spin_unlock_irqrestore(&nvme_fc_lock, flags); |
| 3988 | if (need_cleanup) { | 3963 | flush_workqueue(nvme_delete_wq); |
| 3989 | pr_info("%s: waiting for ctlr deletes\n", __func__); | ||
| 3990 | wait_for_completion(&nvme_fc_unload_proceed); | ||
| 3991 | pr_info("%s: ctrl deletes complete\n", __func__); | ||
| 3992 | } | ||
| 3993 | 3964 | ||
| 3994 | nvmf_unregister_transport(&nvme_fc_transport); | 3965 | nvmf_unregister_transport(&nvme_fc_transport); |
| 3995 | 3966 | ||
| 3996 | ida_destroy(&nvme_fc_local_port_cnt); | ||
| 3997 | ida_destroy(&nvme_fc_ctrl_cnt); | ||
| 3998 | |||
| 3999 | device_destroy(&fc_class, MKDEV(0, 0)); | 3967 | device_destroy(&fc_class, MKDEV(0, 0)); |
| 4000 | class_unregister(&fc_class); | 3968 | class_unregister(&fc_class); |
| 4001 | destroy_workqueue(nvme_fc_wq); | ||
| 4002 | } | 3969 | } |
| 4003 | 3970 | ||
| 4004 | module_init(nvme_fc_init_module); | 3971 | module_init(nvme_fc_init_module); |
| 4005 | module_exit(nvme_fc_exit_module); | 3972 | module_exit(nvme_fc_exit_module); |
| 4006 | 3973 | ||
| 3974 | MODULE_DESCRIPTION("NVMe host FC transport driver"); | ||
| 4007 | MODULE_LICENSE("GPL v2"); | 3975 | MODULE_LICENSE("GPL v2"); |
| @@ -228,7 +228,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) · 227 unmodified lines | |||
| 228 | length = (io.nblocks + 1) << ns->head->lba_shift; | 228 | length = (io.nblocks + 1) << ns->head->lba_shift; |
| 229 | 229 | ||
| 230 | if ((io.control & NVME_RW_PRINFO_PRACT) && | 230 | if ((io.control & NVME_RW_PRINFO_PRACT) && |
| 231 | ns->head->ms == sizeof(struct t10_pi_tuple)) { | 231 | (ns->head->ms == ns->head->pi_size)) { |
| 232 | /* | 232 | /* |
| 233 | * Protection information is stripped/inserted by the | 233 | * Protection information is stripped/inserted by the |
| 234 | * controller. | 234 | * controller. |
| @@ -156,7 +156,7 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl) · 155 unmodified lines | |||
| 156 | if (!ns->head->disk) | 156 | if (!ns->head->disk) |
| 157 | continue; | 157 | continue; |
| 158 | kblockd_schedule_work(&ns->head->requeue_work); | 158 | kblockd_schedule_work(&ns->head->requeue_work); |
| 159 | if (ctrl->state == NVME_CTRL_LIVE) | 159 | if (nvme_ctrl_state(ns->ctrl) == NVME_CTRL_LIVE) |
| 160 | disk_uevent(ns->head->disk, KOBJ_CHANGE); | 160 | disk_uevent(ns->head->disk, KOBJ_CHANGE); |
| 161 | } | 161 | } |
| 162 | up_read(&ctrl->namespaces_rwsem); | 162 | up_read(&ctrl->namespaces_rwsem); |
| @@ -223,13 +223,14 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns) · 60 unmodified lines | |||
| 223 | 223 | ||
| 224 | static bool nvme_path_is_disabled(struct nvme_ns *ns) | 224 | static bool nvme_path_is_disabled(struct nvme_ns *ns) |
| 225 | { | 225 | { |
| 226 | enum nvme_ctrl_state state = nvme_ctrl_state(ns->ctrl); | ||
| 227 | |||
| 226 | /* | 228 | /* |
| 227 | * We don't treat NVME_CTRL_DELETING as a disabled path as I/O should | 229 | * We don't treat NVME_CTRL_DELETING as a disabled path as I/O should |
| 228 | * still be able to complete assuming that the controller is connected. | 230 | * still be able to complete assuming that the controller is connected. |
| 229 | * Otherwise it will fail immediately and return to the requeue list. | 231 | * Otherwise it will fail immediately and return to the requeue list. |
| 230 | */ | 232 | */ |
| 231 | if (ns->ctrl->state != NVME_CTRL_LIVE && | 233 | if (state != NVME_CTRL_LIVE && state != NVME_CTRL_DELETING) |
| 232 | ns->ctrl->state != NVME_CTRL_DELETING) | ||
| 233 | return true; | 234 | return true; |
| 234 | if (test_bit(NVME_NS_ANA_PENDING, &ns->flags) || | 235 | if (test_bit(NVME_NS_ANA_PENDING, &ns->flags) || |
| 235 | !test_bit(NVME_NS_READY, &ns->flags)) | 236 | !test_bit(NVME_NS_READY, &ns->flags)) |
| @@ -331,7 +332,7 @@ out: · 95 unmodified lines | |||
| 331 | 332 | ||
| 332 | static inline bool nvme_path_is_optimized(struct nvme_ns *ns) | 333 | static inline bool nvme_path_is_optimized(struct nvme_ns *ns) |
| 333 | { | 334 | { |
| 334 | return ns->ctrl->state == NVME_CTRL_LIVE && | 335 | return nvme_ctrl_state(ns->ctrl) == NVME_CTRL_LIVE && |
| 335 | ns->ana_state == NVME_ANA_OPTIMIZED; | 336 | ns->ana_state == NVME_ANA_OPTIMIZED; |
| 336 | } | 337 | } |
| 337 | 338 | ||
| @@ -358,7 +359,7 @@ static bool nvme_available_path(struct nvme_ns_head *head) · 20 unmodified lines | |||
| 358 | list_for_each_entry_rcu(ns, &head->list, siblings) { | 359 | list_for_each_entry_rcu(ns, &head->list, siblings) { |
| 359 | if (test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ns->ctrl->flags)) | 360 | if (test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ns->ctrl->flags)) |
| 360 | continue; | 361 | continue; |
| 361 | switch (ns->ctrl->state) { | 362 | switch (nvme_ctrl_state(ns->ctrl)) { |
| 362 | case NVME_CTRL_LIVE: | 363 | case NVME_CTRL_LIVE: |
| 363 | case NVME_CTRL_RESETTING: | 364 | case NVME_CTRL_RESETTING: |
| 364 | case NVME_CTRL_CONNECTING: | 365 | case NVME_CTRL_CONNECTING: |
| @@ -667,7 +668,7 @@ static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc, · 302 unmodified lines | |||
| 667 | * controller is ready. | 668 | * controller is ready. |
| 668 | */ | 669 | */ |
| 669 | if (nvme_state_is_live(ns->ana_state) && | 670 | if (nvme_state_is_live(ns->ana_state) && |
| 670 | ns->ctrl->state == NVME_CTRL_LIVE) | 671 | nvme_ctrl_state(ns->ctrl) == NVME_CTRL_LIVE) |
| 671 | nvme_mpath_set_live(ns); | 672 | nvme_mpath_set_live(ns); |
| 672 | } | 673 | } |
| 673 | 674 | ||
| @@ -748,7 +749,7 @@ static void nvme_ana_work(struct work_struct *work) · 74 unmodified lines | |||
| 748 | { | 749 | { |
| 749 | struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, ana_work); | 750 | struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, ana_work); |
| 750 | 751 | ||
| 751 | if (ctrl->state != NVME_CTRL_LIVE) | 752 | if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE) |
| 752 | return; | 753 | return; |
| 753 | 754 | ||
| 754 | nvme_read_ana_log(ctrl); | 755 | nvme_read_ana_log(ctrl); |
| @@ -263,6 +263,7 @@ enum nvme_ctrl_flags { · 262 unmodified lines | |||
| 263 | struct nvme_ctrl { | 263 | struct nvme_ctrl { |
| 264 | bool comp_seen; | 264 | bool comp_seen; |
| 265 | bool identified; | 265 | bool identified; |
| 266 | bool passthru_err_log_enabled; | ||
| 266 | enum nvme_ctrl_state state; | 267 | enum nvme_ctrl_state state; |
| 267 | spinlock_t lock; | 268 | spinlock_t lock; |
| 268 | struct mutex scan_lock; | 269 | struct mutex scan_lock; |
| @@ -454,6 +455,7 @@ struct nvme_ns_head { · 185 unmodified lines | |||
| 454 | struct list_head entry; | 455 | struct list_head entry; |
| 455 | struct kref ref; | 456 | struct kref ref; |
| 456 | bool shared; | 457 | bool shared; |
| 458 | bool passthru_err_log_enabled; | ||
| 457 | int instance; | 459 | int instance; |
| 458 | struct nvme_effects_log *effects; | 460 | struct nvme_effects_log *effects; |
| 459 | u64 nuse; | 461 | u64 nuse; |
| @@ -522,7 +524,6 @@ struct nvme_ns { · 62 unmodified lines | |||
| 522 | struct device cdev_device; | 524 | struct device cdev_device; |
| 523 | 525 | ||
| 524 | struct nvme_fault_inject fault_inject; | 526 | struct nvme_fault_inject fault_inject; |
| 525 | |||
| 526 | }; | 527 | }; |
| 527 | 528 | ||
| 528 | /* NVMe ns supports metadata actions by the controller (generate/strip) */ | 529 | /* NVMe ns supports metadata actions by the controller (generate/strip) */ |
| @@ -805,17 +806,18 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req); · 276 unmodified lines | |||
| 805 | blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl, | 806 | blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl, |
| 806 | struct request *req); | 807 | struct request *req); |
| 807 | bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, | 808 | bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, |
| 808 | bool queue_live); | 809 | bool queue_live, enum nvme_ctrl_state state); |
| 809 | 810 | ||
| 810 | static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, | 811 | static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, |
| 811 | bool queue_live) | 812 | bool queue_live) |
| 812 | { | 813 | { |
| 813 | if (likely(ctrl->state == NVME_CTRL_LIVE)) | 814 | enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); |
| 815 | |||
| 816 | if (likely(state == NVME_CTRL_LIVE)) | ||
| 814 | return true; | 817 | return true; |
| 815 | if (ctrl->ops->flags & NVME_F_FABRICS && | 818 | if (ctrl->ops->flags & NVME_F_FABRICS && state == NVME_CTRL_DELETING) |
| 816 | ctrl->state == NVME_CTRL_DELETING) | ||
| 817 | return queue_live; | 819 | return queue_live; |
| 818 | return __nvme_check_ready(ctrl, rq, queue_live); | 820 | return __nvme_check_ready(ctrl, rq, queue_live, state); |
| 819 | } | 821 | } |
| 820 | 822 | ||
| 821 | /* | 823 | /* |
| @@ -836,12 +838,27 @@ static inline bool nvme_is_unique_nsid(struct nvme_ctrl *ctrl, · 14 unmodified lines | |||
| 836 | (ctrl->ctratt & NVME_CTRL_CTRATT_NVM_SETS); | 838 | (ctrl->ctratt & NVME_CTRL_CTRATT_NVM_SETS); |
| 837 | } | 839 | } |
| 838 | 840 | ||
| 841 | /* | ||
| 842 | * Flags for __nvme_submit_sync_cmd() | ||
| 843 | */ | ||
| 844 | typedef __u32 __bitwise nvme_submit_flags_t; | ||
| 845 | |||
| 846 | enum { | ||
| 847 | /* Insert request at the head of the queue */ | ||
| 848 | NVME_SUBMIT_AT_HEAD = (__force nvme_submit_flags_t)(1 << 0), | ||
| 849 | /* Set BLK_MQ_REQ_NOWAIT when allocating request */ | ||
| 850 | NVME_SUBMIT_NOWAIT = (__force nvme_submit_flags_t)(1 << 1), | ||
| 851 | /* Set BLK_MQ_REQ_RESERVED when allocating request */ | ||
| 852 | NVME_SUBMIT_RESERVED = (__force nvme_submit_flags_t)(1 << 2), | ||
| 853 | /* Retry command when NVME_SC_DNR is not set in the result */ | ||
| 854 | NVME_SUBMIT_RETRY = (__force nvme_submit_flags_t)(1 << 3), | ||
| 855 | }; | ||
| 856 | |||
| 839 | int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | 857 | int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, |
| 840 | void *buf, unsigned bufflen); | 858 | void *buf, unsigned bufflen); |
| 841 | int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | 859 | int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, |
| 842 | union nvme_result *result, void *buffer, unsigned bufflen, | 860 | union nvme_result *result, void *buffer, unsigned bufflen, |
| 843 | int qid, int at_head, | 861 | int qid, nvme_submit_flags_t flags); |
| 844 | blk_mq_req_flags_t flags); | ||
| 845 | int nvme_set_features(struct nvme_ctrl *dev, unsigned int fid, | 862 | int nvme_set_features(struct nvme_ctrl *dev, unsigned int fid, |
| 846 | unsigned int dword11, void *buffer, size_t buflen, | 863 | unsigned int dword11, void *buffer, size_t buflen, |
| 847 | u32 *result); | 864 | u32 *result); |
| @@ -1124,35 +1141,42 @@ static inline bool nvme_multi_css(struct nvme_ctrl *ctrl) · 276 unmodified lines | |||
| 1124 | } | 1141 | } |
| 1125 | 1142 | ||
| 1126 | #ifdef CONFIG_NVME_VERBOSE_ERRORS | 1143 | #ifdef CONFIG_NVME_VERBOSE_ERRORS |
| 1127 | const unsigned char *nvme_get_error_status_str(u16 status); | 1144 | const char *nvme_get_error_status_str(u16 status); |
| 1128 | const unsigned char *nvme_get_opcode_str(u8 opcode); | 1145 | const char *nvme_get_opcode_str(u8 opcode); |
| 1129 | const unsigned char *nvme_get_admin_opcode_str(u8 opcode); | 1146 | const char *nvme_get_admin_opcode_str(u8 opcode); |
| 1130 | const unsigned char *nvme_get_fabrics_opcode_str(u8 opcode); | 1147 | const char *nvme_get_fabrics_opcode_str(u8 opcode); |
| 1131 | #else /* CONFIG_NVME_VERBOSE_ERRORS */ | 1148 | #else /* CONFIG_NVME_VERBOSE_ERRORS */ |
| 1132 | static inline const unsigned char *nvme_get_error_status_str(u16 status) | 1149 | static inline const char *nvme_get_error_status_str(u16 status) |
| 1133 | { | 1150 | { |
| 1134 | return "I/O Error"; | 1151 | return "I/O Error"; |
| 1135 | } | 1152 | } |
| 1136 | static inline const unsigned char *nvme_get_opcode_str(u8 opcode) | 1153 | static inline const char *nvme_get_opcode_str(u8 opcode) |
| 1137 | { | 1154 | { |
| 1138 | return "I/O Cmd"; | 1155 | return "I/O Cmd"; |
| 1139 | } | 1156 | } |
| 1140 | static inline const unsigned char *nvme_get_admin_opcode_str(u8 opcode) | 1157 | static inline const char *nvme_get_admin_opcode_str(u8 opcode) |
| 1141 | { | 1158 | { |
| 1142 | return "Admin Cmd"; | 1159 | return "Admin Cmd"; |
| 1143 | } | 1160 | } |
| 1144 | 1161 | ||
| 1145 | static inline const unsigned char *nvme_get_fabrics_opcode_str(u8 opcode) | 1162 | static inline const char *nvme_get_fabrics_opcode_str(u8 opcode) |
| 1146 | { | 1163 | { |
| 1147 | return "Fabrics Cmd"; | 1164 | return "Fabrics Cmd"; |
| 1148 | } | 1165 | } |
| 1149 | #endif /* CONFIG_NVME_VERBOSE_ERRORS */ | 1166 | #endif /* CONFIG_NVME_VERBOSE_ERRORS */ |
| 1150 | 1167 | ||
| 1151 | static inline const unsigned char *nvme_opcode_str(int qid, u8 opcode, u8 fctype) | 1168 | static inline const char *nvme_opcode_str(int qid, u8 opcode) |
| 1152 | { | 1169 | { |
| 1153 | if (opcode == nvme_fabrics_command) | ||
| 1154 | return nvme_get_fabrics_opcode_str(fctype); | ||
| 1155 | return qid ? nvme_get_opcode_str(opcode) : | 1170 | return qid ? nvme_get_opcode_str(opcode) : |
| 1156 | nvme_get_admin_opcode_str(opcode); | 1171 | nvme_get_admin_opcode_str(opcode); |
| 1157 | } | 1172 | } |
| 1173 | |||
| 1174 | static inline const char *nvme_fabrics_opcode_str( | ||
| 1175 | int qid, const struct nvme_command *cmd) | ||
| 1176 | { | ||
| 1177 | if (nvme_is_fabrics(cmd)) | ||
| 1178 | return nvme_get_fabrics_opcode_str(cmd->fabrics.fctype); | ||
| 1179 | |||
| 1180 | return nvme_opcode_str(qid, cmd->common.opcode); | ||
| 1181 | } | ||
| 1158 | #endif /* _NVME_H */ | 1182 | #endif /* _NVME_H */ |
| @@ -1349,7 +1349,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req) · 1348 unmodified lines | |||
| 1349 | dev_warn(dev->ctrl.device, | 1349 | dev_warn(dev->ctrl.device, |
| 1350 | "I/O tag %d (%04x) opcode %#x (%s) QID %d timeout, reset controller\n", | 1350 | "I/O tag %d (%04x) opcode %#x (%s) QID %d timeout, reset controller\n", |
| 1351 | req->tag, nvme_cid(req), opcode, | 1351 | req->tag, nvme_cid(req), opcode, |
| 1352 | nvme_opcode_str(nvmeq->qid, opcode, 0), nvmeq->qid); | 1352 | nvme_opcode_str(nvmeq->qid, opcode), nvmeq->qid); |
| 1353 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; | 1353 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; |
| 1354 | goto disable; | 1354 | goto disable; |
| 1355 | } | 1355 | } |
| @@ -3543,5 +3543,6 @@ static void __exit nvme_exit(void) · 2187 unmodified lines | |||
| 3543 | MODULE_AUTHOR("Matthew Wilcox <willy@linux.intel.com>"); | 3543 | MODULE_AUTHOR("Matthew Wilcox <willy@linux.intel.com>"); |
| 3544 | MODULE_LICENSE("GPL"); | 3544 | MODULE_LICENSE("GPL"); |
| 3545 | MODULE_VERSION("1.0"); | 3545 | MODULE_VERSION("1.0"); |
| 3546 | MODULE_DESCRIPTION("NVMe host PCIe transport driver"); | ||
| 3546 | module_init(nvme_init); | 3547 | module_init(nvme_init); |
| 3547 | module_exit(nvme_exit); | 3548 | module_exit(nvme_exit); |
| @@ -1410,6 +1410,8 @@ static int nvme_rdma_map_sg_pi(struct nvme_rdma_queue *queue, · 1409 unmodified lines | |||
| 1410 | struct nvme_ns *ns = rq->q->queuedata; | 1410 | struct nvme_ns *ns = rq->q->queuedata; |
| 1411 | struct bio *bio = rq->bio; | 1411 | struct bio *bio = rq->bio; |
| 1412 | struct nvme_keyed_sgl_desc *sg = &c->common.dptr.ksgl; | 1412 | struct nvme_keyed_sgl_desc *sg = &c->common.dptr.ksgl; |
| 1413 | struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); | ||
| 1414 | u32 xfer_len; | ||
| 1413 | int nr; | 1415 | int nr; |
| 1414 | 1416 | ||
| 1415 | req->mr = ib_mr_pool_get(queue->qp, &queue->qp->sig_mrs); | 1417 | req->mr = ib_mr_pool_get(queue->qp, &queue->qp->sig_mrs); |
| @@ -1422,8 +1424,7 @@ static int nvme_rdma_map_sg_pi(struct nvme_rdma_queue *queue, · 6 unmodified lines | |||
| 1422 | if (unlikely(nr)) | 1424 | if (unlikely(nr)) |
| 1423 | goto mr_put; | 1425 | goto mr_put; |
| 1424 | 1426 | ||
| 1425 | nvme_rdma_set_sig_attrs(blk_get_integrity(bio->bi_bdev->bd_disk), c, | 1427 | nvme_rdma_set_sig_attrs(bi, c, req->mr->sig_attrs, ns->head->pi_type); |
| 1426 | req->mr->sig_attrs, ns->head->pi_type); | ||
| 1427 | nvme_rdma_set_prot_checks(c, &req->mr->sig_attrs->check_mask); | 1428 | nvme_rdma_set_prot_checks(c, &req->mr->sig_attrs->check_mask); |
| 1428 | 1429 | ||
| 1429 | ib_update_fast_reg_key(req->mr, ib_inc_rkey(req->mr->rkey)); | 1430 | ib_update_fast_reg_key(req->mr, ib_inc_rkey(req->mr->rkey)); |
| @@ -1441,7 +1442,11 @@ static int nvme_rdma_map_sg_pi(struct nvme_rdma_queue *queue, · 11 unmodified lines | |||
| 1441 | IB_ACCESS_REMOTE_WRITE; | 1442 | IB_ACCESS_REMOTE_WRITE; |
| 1442 | 1443 | ||
| 1443 | sg->addr = cpu_to_le64(req->mr->iova); | 1444 | sg->addr = cpu_to_le64(req->mr->iova); |
| 1444 | put_unaligned_le24(req->mr->length, sg->length); | 1445 | xfer_len = req->mr->length; |
| 1446 | /* Check if PI is added by the HW */ | ||
| 1447 | if (!pi_count) | ||
| 1448 | xfer_len += (xfer_len >> bi->interval_exp) * ns->head->pi_size; | ||
| 1449 | put_unaligned_le24(xfer_len, sg->length); | ||
| 1445 | put_unaligned_le32(req->mr->rkey, sg->key); | 1450 | put_unaligned_le32(req->mr->rkey, sg->key); |
| 1446 | sg->type = NVME_KEY_SGL_FMT_DATA_DESC << 4; | 1451 | sg->type = NVME_KEY_SGL_FMT_DATA_DESC << 4; |
| 1447 | 1452 | ||
| @@ -1946,14 +1951,13 @@ static enum blk_eh_timer_return nvme_rdma_timeout(struct request *rq) · 498 unmodified lines | |||
| 1946 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); | 1951 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); |
| 1947 | struct nvme_rdma_queue *queue = req->queue; | 1952 | struct nvme_rdma_queue *queue = req->queue; |
| 1948 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; | 1953 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; |
| 1949 | u8 opcode = req->req.cmd->common.opcode; | 1954 | struct nvme_command *cmd = req->req.cmd; |
| 1950 | u8 fctype = req->req.cmd->fabrics.fctype; | ||
| 1951 | int qid = nvme_rdma_queue_idx(queue); | 1955 | int qid = nvme_rdma_queue_idx(queue); |
| 1952 | 1956 | ||
| 1953 | dev_warn(ctrl->ctrl.device, | 1957 | dev_warn(ctrl->ctrl.device, |
| 1954 | "I/O tag %d (%04x) opcode %#x (%s) QID %d timeout\n", | 1958 | "I/O tag %d (%04x) opcode %#x (%s) QID %d timeout\n", |
| 1955 | rq->tag, nvme_cid(rq), opcode, | 1959 | rq->tag, nvme_cid(rq), cmd->common.opcode, |
| 1956 | nvme_opcode_str(qid, opcode, fctype), qid); | 1960 | nvme_fabrics_opcode_str(qid, cmd), qid); |
| 1957 | 1961 | ||
| 1958 | if (nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_LIVE) { | 1962 | if (nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_LIVE) { |
| 1959 | /* | 1963 | /* |
| @@ -2296,8 +2300,8 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, · 336 unmodified lines | |||
| 2296 | if (ret) | 2300 | if (ret) |
| 2297 | goto out_uninit_ctrl; | 2301 | goto out_uninit_ctrl; |
| 2298 | 2302 | ||
| 2299 | dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISpcs\n", | 2303 | dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISpcs, hostnqn: %s\n", |
| 2300 | nvmf_ctrl_subsysnqn(&ctrl->ctrl), &ctrl->addr); | 2304 | nvmf_ctrl_subsysnqn(&ctrl->ctrl), &ctrl->addr, opts->host->nqn); |
| 2301 | 2305 | ||
| 2302 | mutex_lock(&nvme_rdma_ctrl_mutex); | 2306 | mutex_lock(&nvme_rdma_ctrl_mutex); |
| 2303 | list_add_tail(&ctrl->list, &nvme_rdma_ctrl_list); | 2307 | list_add_tail(&ctrl->list, &nvme_rdma_ctrl_list); |
| @@ -2400,4 +2404,5 @@ static void __exit nvme_rdma_cleanup_module(void) · 96 unmodified lines | |||
| 2400 | module_init(nvme_rdma_init_module); | 2404 | module_init(nvme_rdma_init_module); |
| 2401 | module_exit(nvme_rdma_cleanup_module); | 2405 | module_exit(nvme_rdma_cleanup_module); |
| 2402 | 2406 | ||
| 2407 | MODULE_DESCRIPTION("NVMe host RDMA transport driver"); | ||
| 2403 | MODULE_LICENSE("GPL v2"); | 2408 | MODULE_LICENSE("GPL v2"); |
| @@ -35,6 +35,31 @@ static ssize_t nvme_sysfs_rescan(struct device *dev, · 34 unmodified lines | |||
| 35 | } | 35 | } |
| 36 | static DEVICE_ATTR(rescan_controller, S_IWUSR, NULL, nvme_sysfs_rescan); | 36 | static DEVICE_ATTR(rescan_controller, S_IWUSR, NULL, nvme_sysfs_rescan); |
| 37 | 37 | ||
| 38 | static ssize_t nvme_adm_passthru_err_log_enabled_show(struct device *dev, | ||
| 39 | struct device_attribute *attr, char *buf) | ||
| 40 | { | ||
| 41 | struct nvme_ctrl *ctrl = dev_get_drvdata(dev); | ||
| 42 | |||
| 43 | return sysfs_emit(buf, | ||
| 44 | ctrl->passthru_err_log_enabled ? "on\n" : "off\n"); | ||
| 45 | } | ||
| 46 | |||
| 47 | static ssize_t nvme_adm_passthru_err_log_enabled_store(struct device *dev, | ||
| 48 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 49 | { | ||
| 50 | struct nvme_ctrl *ctrl = dev_get_drvdata(dev); | ||
| 51 | bool passthru_err_log_enabled; | ||
| 52 | int err; | ||
| 53 | |||
| 54 | err = kstrtobool(buf, &passthru_err_log_enabled); | ||
| 55 | if (err) | ||
| 56 | return -EINVAL; | ||
| 57 | |||
| 58 | ctrl->passthru_err_log_enabled = passthru_err_log_enabled; | ||
| 59 | |||
| 60 | return count; | ||
| 61 | } | ||
| 62 | |||
| 38 | static inline struct nvme_ns_head *dev_to_ns_head(struct device *dev) | 63 | static inline struct nvme_ns_head *dev_to_ns_head(struct device *dev) |
| 39 | { | 64 | { |
| 40 | struct gendisk *disk = dev_to_disk(dev); | 65 | struct gendisk *disk = dev_to_disk(dev); |
| @@ -44,6 +69,37 @@ static inline struct nvme_ns_head *dev_to_ns_head(struct device *dev) · 3 unmodified lines | |||
| 44 | return nvme_get_ns_from_dev(dev)->head; | 69 | return nvme_get_ns_from_dev(dev)->head; |
| 45 | } | 70 | } |
| 46 | 71 | ||
| 72 | static ssize_t nvme_io_passthru_err_log_enabled_show(struct device *dev, | ||
| 73 | struct device_attribute *attr, char *buf) | ||
| 74 | { | ||
| 75 | struct nvme_ns_head *head = dev_to_ns_head(dev); | ||
| 76 | |||
| 77 | return sysfs_emit(buf, head->passthru_err_log_enabled ? "on\n" : "off\n"); | ||
| 78 | } | ||
| 79 | |||
| 80 | static ssize_t nvme_io_passthru_err_log_enabled_store(struct device *dev, | ||
| 81 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 82 | { | ||
| 83 | struct nvme_ns_head *head = dev_to_ns_head(dev); | ||
| 84 | bool passthru_err_log_enabled; | ||
| 85 | int err; | ||
| 86 | |||
| 87 | err = kstrtobool(buf, &passthru_err_log_enabled); | ||
| 88 | if (err) | ||
| 89 | return -EINVAL; | ||
| 90 | head->passthru_err_log_enabled = passthru_err_log_enabled; | ||
| 91 | |||
| 92 | return count; | ||
| 93 | } | ||
| 94 | |||
| 95 | static struct device_attribute dev_attr_adm_passthru_err_log_enabled = \ | ||
| 96 | __ATTR(passthru_err_log_enabled, S_IRUGO | S_IWUSR, \ | ||
| 97 | nvme_adm_passthru_err_log_enabled_show, nvme_adm_passthru_err_log_enabled_store); | ||
| 98 | |||
| 99 | static struct device_attribute dev_attr_io_passthru_err_log_enabled = \ | ||
| 100 | __ATTR(passthru_err_log_enabled, S_IRUGO | S_IWUSR, \ | ||
| 101 | nvme_io_passthru_err_log_enabled_show, nvme_io_passthru_err_log_enabled_store); | ||
| 102 | |||
| 47 | static ssize_t wwid_show(struct device *dev, struct device_attribute *attr, | 103 | static ssize_t wwid_show(struct device *dev, struct device_attribute *attr, |
| 48 | char *buf) | 104 | char *buf) |
| 49 | { | 105 | { |
| @@ -208,6 +264,7 @@ static struct attribute *nvme_ns_attrs[] = { · 158 unmodified lines | |||
| 208 | &dev_attr_ana_grpid.attr, | 264 | &dev_attr_ana_grpid.attr, |
| 209 | &dev_attr_ana_state.attr, | 265 | &dev_attr_ana_state.attr, |
| 210 | #endif | 266 | #endif |
| 267 | &dev_attr_io_passthru_err_log_enabled.attr, | ||
| 211 | NULL, | 268 | NULL, |
| 212 | }; | 269 | }; |
| 213 | 270 | ||
| @@ -311,6 +368,7 @@ static ssize_t nvme_sysfs_show_state(struct device *dev, · 97 unmodified lines | |||
| 311 | char *buf) | 368 | char *buf) |
| 312 | { | 369 | { |
| 313 | struct nvme_ctrl *ctrl = dev_get_drvdata(dev); | 370 | struct nvme_ctrl *ctrl = dev_get_drvdata(dev); |
| 371 | unsigned state = (unsigned)nvme_ctrl_state(ctrl); | ||
| 314 | static const char *const state_name[] = { | 372 | static const char *const state_name[] = { |
| 315 | [NVME_CTRL_NEW] = "new", | 373 | [NVME_CTRL_NEW] = "new", |
| 316 | [NVME_CTRL_LIVE] = "live", | 374 | [NVME_CTRL_LIVE] = "live", |
| @@ -321,9 +379,8 @@ static ssize_t nvme_sysfs_show_state(struct device *dev, · 4 unmodified lines | |||
| 321 | [NVME_CTRL_DEAD] = "dead", | 379 | [NVME_CTRL_DEAD] = "dead", |
| 322 | }; | 380 | }; |
| 323 | 381 | ||
| 324 | if ((unsigned)ctrl->state < ARRAY_SIZE(state_name) && | 382 | if (state < ARRAY_SIZE(state_name) && state_name[state]) |
| 325 | state_name[ctrl->state]) | 383 | return sysfs_emit(buf, "%s\n", state_name[state]); |
| 326 | return sysfs_emit(buf, "%s\n", state_name[ctrl->state]); | ||
| 327 | 384 | ||
| 328 | return sysfs_emit(buf, "unknown state\n"); | 385 | return sysfs_emit(buf, "unknown state\n"); |
| 329 | } | 386 | } |
| @@ -655,6 +712,7 @@ static struct attribute *nvme_dev_attrs[] = { · 325 unmodified lines | |||
| 655 | #ifdef CONFIG_NVME_TCP_TLS | 712 | #ifdef CONFIG_NVME_TCP_TLS |
| 656 | &dev_attr_tls_key.attr, | 713 | &dev_attr_tls_key.attr, |
| 657 | #endif | 714 | #endif |
| 715 | &dev_attr_adm_passthru_err_log_enabled.attr, | ||
| 658 | NULL | 716 | NULL |
| 659 | }; | 717 | }; |
| 660 | 718 | ||
| @@ -2428,13 +2428,13 @@ static enum blk_eh_timer_return nvme_tcp_timeout(struct request *rq) · 2427 unmodified lines | |||
| 2428 | struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq); | 2428 | struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq); |
| 2429 | struct nvme_ctrl *ctrl = &req->queue->ctrl->ctrl; | 2429 | struct nvme_ctrl *ctrl = &req->queue->ctrl->ctrl; |
| 2430 | struct nvme_tcp_cmd_pdu *pdu = nvme_tcp_req_cmd_pdu(req); | 2430 | struct nvme_tcp_cmd_pdu *pdu = nvme_tcp_req_cmd_pdu(req); |
| 2431 | u8 opc = pdu->cmd.common.opcode, fctype = pdu->cmd.fabrics.fctype; | 2431 | struct nvme_command *cmd = &pdu->cmd; |
| 2432 | int qid = nvme_tcp_queue_id(req->queue); | 2432 | int qid = nvme_tcp_queue_id(req->queue); |
| 2433 | 2433 | ||
| 2434 | dev_warn(ctrl->device, | 2434 | dev_warn(ctrl->device, |
| 2435 | "I/O tag %d (%04x) type %d opcode %#x (%s) QID %d timeout\n", | 2435 | "I/O tag %d (%04x) type %d opcode %#x (%s) QID %d timeout\n", |
| 2436 | rq->tag, nvme_cid(rq), pdu->hdr.type, opc, | 2436 | rq->tag, nvme_cid(rq), pdu->hdr.type, cmd->common.opcode, |
| 2437 | nvme_opcode_str(qid, opc, fctype), qid); | 2437 | nvme_fabrics_opcode_str(qid, cmd), qid); |
| 2438 | 2438 | ||
| 2439 | if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE) { | 2439 | if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE) { |
| 2440 | /* | 2440 | /* |
| @@ -2753,8 +2753,8 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev, · 312 unmodified lines | |||
| 2753 | if (ret) | 2753 | if (ret) |
| 2754 | goto out_uninit_ctrl; | 2754 | goto out_uninit_ctrl; |
| 2755 | 2755 | ||
| 2756 | dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISp\n", | 2756 | dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISp, hostnqn: %s\n", |
| 2757 | nvmf_ctrl_subsysnqn(&ctrl->ctrl), &ctrl->addr); | 2757 | nvmf_ctrl_subsysnqn(&ctrl->ctrl), &ctrl->addr, opts->host->nqn); |
| 2758 | 2758 | ||
| 2759 | mutex_lock(&nvme_tcp_ctrl_mutex); | 2759 | mutex_lock(&nvme_tcp_ctrl_mutex); |
| 2760 | list_add_tail(&ctrl->list, &nvme_tcp_ctrl_list); | 2760 | list_add_tail(&ctrl->list, &nvme_tcp_ctrl_list); |
| @@ -2826,4 +2826,5 @@ static void __exit nvme_tcp_cleanup_module(void) · 65 unmodified lines | |||
| 2826 | module_init(nvme_tcp_init_module); | 2826 | module_init(nvme_tcp_init_module); |
| 2827 | module_exit(nvme_tcp_cleanup_module); | 2827 | module_exit(nvme_tcp_cleanup_module); |
| 2828 | 2828 | ||
| 2829 | MODULE_DESCRIPTION("NVMe host TCP transport driver"); | ||
| 2829 | MODULE_LICENSE("GPL v2"); | 2830 | MODULE_LICENSE("GPL v2"); |
| @@ -248,7 +248,7 @@ void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid) · 247 unmodified lines | |||
| 248 | nvmet_add_to_changed_ns_log(ctrl, cpu_to_le32(nsid)); | 248 | nvmet_add_to_changed_ns_log(ctrl, cpu_to_le32(nsid)); |
| 249 | if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_NS_ATTR)) | 249 | if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_NS_ATTR)) |
| 250 | continue; | 250 | continue; |
| 251 | nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, | 251 | nvmet_add_async_event(ctrl, NVME_AER_NOTICE, |
| 252 | NVME_AER_NOTICE_NS_CHANGED, | 252 | NVME_AER_NOTICE_NS_CHANGED, |
| 253 | NVME_LOG_CHANGED_NS); | 253 | NVME_LOG_CHANGED_NS); |
| 254 | } | 254 | } |
| @@ -265,7 +265,7 @@ void nvmet_send_ana_event(struct nvmet_subsys *subsys, · 10 unmodified lines | |||
| 265 | continue; | 265 | continue; |
| 266 | if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_ANA_CHANGE)) | 266 | if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_ANA_CHANGE)) |
| 267 | continue; | 267 | continue; |
| 268 | nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, | 268 | nvmet_add_async_event(ctrl, NVME_AER_NOTICE, |
| 269 | NVME_AER_NOTICE_ANA, NVME_LOG_ANA); | 269 | NVME_AER_NOTICE_ANA, NVME_LOG_ANA); |
| 270 | } | 270 | } |
| 271 | mutex_unlock(&subsys->lock); | 271 | mutex_unlock(&subsys->lock); |
| @@ -1705,4 +1705,5 @@ static void __exit nvmet_exit(void) · 1433 unmodified lines | |||
| 1705 | module_init(nvmet_init); | 1705 | module_init(nvmet_init); |
| 1706 | module_exit(nvmet_exit); | 1706 | module_exit(nvmet_exit); |
| 1707 | 1707 | ||
| 1708 | MODULE_DESCRIPTION("NVMe target core framework"); | ||
| 1708 | MODULE_LICENSE("GPL v2"); | 1709 | MODULE_LICENSE("GPL v2"); |
| @@ -21,7 +21,7 @@ static void __nvmet_disc_changed(struct nvmet_port *port, · 20 unmodified lines | |||
| 21 | if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_DISC_CHANGE)) | 21 | if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_DISC_CHANGE)) |
| 22 | return; | 22 | return; |
| 23 | 23 | ||
| 24 | nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, | 24 | nvmet_add_async_event(ctrl, NVME_AER_NOTICE, |
| 25 | NVME_AER_NOTICE_DISC_CHANGED, NVME_LOG_DISC); | 25 | NVME_AER_NOTICE_DISC_CHANGED, NVME_LOG_DISC); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| @@ -111,6 +111,8 @@ struct nvmet_fc_tgtport { · 110 unmodified lines | |||
| 111 | struct nvmet_fc_port_entry *pe; | 111 | struct nvmet_fc_port_entry *pe; |
| 112 | struct kref ref; | 112 | struct kref ref; |
| 113 | u32 max_sg_cnt; | 113 | u32 max_sg_cnt; |
| 114 | |||
| 115 | struct work_struct put_work; | ||
| 114 | }; | 116 | }; |
| 115 | 117 | ||
| 116 | struct nvmet_fc_port_entry { | 118 | struct nvmet_fc_port_entry { |
| @@ -145,7 +147,6 @@ struct nvmet_fc_tgt_queue { · 28 unmodified lines | |||
| 145 | struct list_head avail_defer_list; | 147 | struct list_head avail_defer_list; |
| 146 | struct workqueue_struct *work_q; | 148 | struct workqueue_struct *work_q; |
| 147 | struct kref ref; | 149 | struct kref ref; |
| 148 | struct rcu_head rcu; | ||
| 149 | /* array of fcp_iods */ | 150 | /* array of fcp_iods */ |
| 150 | struct nvmet_fc_fcp_iod fod[] __counted_by(sqsize); | 151 | struct nvmet_fc_fcp_iod fod[] __counted_by(sqsize); |
| 151 | } __aligned(sizeof(unsigned long long)); | 152 | } __aligned(sizeof(unsigned long long)); |
| @@ -166,10 +167,9 @@ struct nvmet_fc_tgt_assoc { · 14 unmodified lines | |||
| 166 | struct nvmet_fc_hostport *hostport; | 167 | struct nvmet_fc_hostport *hostport; |
| 167 | struct nvmet_fc_ls_iod *rcv_disconn; | 168 | struct nvmet_fc_ls_iod *rcv_disconn; |
| 168 | struct list_head a_list; | 169 | struct list_head a_list; |
| 169 | struct nvmet_fc_tgt_queue __rcu *queues[NVMET_NR_QUEUES + 1]; | 170 | struct nvmet_fc_tgt_queue *queues[NVMET_NR_QUEUES + 1]; |
| 170 | struct kref ref; | 171 | struct kref ref; |
| 171 | struct work_struct del_work; | 172 | struct work_struct del_work; |
| 172 | struct rcu_head rcu; | ||
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | 175 | ||
| @@ -249,6 +249,13 @@ static int nvmet_fc_tgt_a_get(struct nvmet_fc_tgt_assoc *assoc); · 73 unmodified lines | |||
| 249 | static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue); | 249 | static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue); |
| 250 | static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue); | 250 | static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue); |
| 251 | static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport); | 251 | static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport); |
| 252 | static void nvmet_fc_put_tgtport_work(struct work_struct *work) | ||
| 253 | { | ||
| 254 | struct nvmet_fc_tgtport *tgtport = | ||
| 255 | container_of(work, struct nvmet_fc_tgtport, put_work); | ||
| 256 | |||
| 257 | nvmet_fc_tgtport_put(tgtport); | ||
| 258 | } | ||
| 252 | static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport); | 259 | static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport); |
| 253 | static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, | 260 | static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, |
| 254 | struct nvmet_fc_fcp_iod *fod); | 261 | struct nvmet_fc_fcp_iod *fod); |
| @@ -360,7 +367,7 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) · 105 unmodified lines | |||
| 360 | 367 | ||
| 361 | if (!lsop->req_queued) { | 368 | if (!lsop->req_queued) { |
| 362 | spin_unlock_irqrestore(&tgtport->lock, flags); | 369 | spin_unlock_irqrestore(&tgtport->lock, flags); |
| 363 | return; | 370 | goto out_putwork; |
| 364 | } | 371 | } |
| 365 | 372 | ||
| 366 | list_del(&lsop->lsreq_list); | 373 | list_del(&lsop->lsreq_list); |
| @@ -373,7 +380,8 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) · 6 unmodified lines | |||
| 373 | (lsreq->rqstlen + lsreq->rsplen), | 380 | (lsreq->rqstlen + lsreq->rsplen), |
| 374 | DMA_BIDIRECTIONAL); | 381 | DMA_BIDIRECTIONAL); |
| 375 | 382 | ||
| 376 | nvmet_fc_tgtport_put(tgtport); | 383 | out_putwork: |
| 384 | queue_work(nvmet_wq, &tgtport->put_work); | ||
| 377 | } | 385 | } |
| 378 | 386 | ||
| 379 | static int | 387 | static int |
| @@ -489,8 +497,7 @@ nvmet_fc_xmt_disconnect_assoc(struct nvmet_fc_tgt_assoc *assoc) · 109 unmodified lines | |||
| 489 | * message is normal. Otherwise, send unless the hostport has | 497 | * message is normal. Otherwise, send unless the hostport has |
| 490 | * already been invalidated by the lldd. | 498 | * already been invalidated by the lldd. |
| 491 | */ | 499 | */ |
| 492 | if (!tgtport->ops->ls_req || !assoc->hostport || | 500 | if (!tgtport->ops->ls_req || assoc->hostport->invalid) |
| 493 | assoc->hostport->invalid) | ||
| 494 | return; | 501 | return; |
| 495 | 502 | ||
| 496 | lsop = kzalloc((sizeof(*lsop) + | 503 | lsop = kzalloc((sizeof(*lsop) + |
| @@ -802,14 +809,11 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, · 305 unmodified lines | |||
| 802 | if (!queue) | 809 | if (!queue) |
| 803 | return NULL; | 810 | return NULL; |
| 804 | 811 | ||
| 805 | if (!nvmet_fc_tgt_a_get(assoc)) | ||
| 806 | goto out_free_queue; | ||
| 807 | |||
| 808 | queue->work_q = alloc_workqueue("ntfc%d.%d.%d", 0, 0, | 812 | queue->work_q = alloc_workqueue("ntfc%d.%d.%d", 0, 0, |
| 809 | assoc->tgtport->fc_target_port.port_num, | 813 | assoc->tgtport->fc_target_port.port_num, |
| 810 | assoc->a_id, qid); | 814 | assoc->a_id, qid); |
| 811 | if (!queue->work_q) | 815 | if (!queue->work_q) |
| 812 | goto out_a_put; | 816 | goto out_free_queue; |
| 813 | 817 | ||
| 814 | queue->qid = qid; | 818 | queue->qid = qid; |
| 815 | queue->sqsize = sqsize; | 819 | queue->sqsize = sqsize; |
| @@ -831,15 +835,13 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, · 15 unmodified lines | |||
| 831 | goto out_fail_iodlist; | 835 | goto out_fail_iodlist; |
| 832 | 836 | ||
| 833 | WARN_ON(assoc->queues[qid]); | 837 | WARN_ON(assoc->queues[qid]); |
| 834 | rcu_assign_pointer(assoc->queues[qid], queue); | 838 | assoc->queues[qid] = queue; |
| 835 | 839 | ||
| 836 | return queue; | 840 | return queue; |
| 837 | 841 | ||
| 838 | out_fail_iodlist: | 842 | out_fail_iodlist: |
| 839 | nvmet_fc_destroy_fcp_iodlist(assoc->tgtport, queue); | 843 | nvmet_fc_destroy_fcp_iodlist(assoc->tgtport, queue); |
| 840 | destroy_workqueue(queue->work_q); | 844 | destroy_workqueue(queue->work_q); |
| 841 | out_a_put: | ||
| 842 | nvmet_fc_tgt_a_put(assoc); | ||
| 843 | out_free_queue: | 845 | out_free_queue: |
| 844 | kfree(queue); | 846 | kfree(queue); |
| 845 | return NULL; | 847 | return NULL; |
| @@ -852,15 +854,11 @@ nvmet_fc_tgt_queue_free(struct kref *ref) · 6 unmodified lines | |||
| 852 | struct nvmet_fc_tgt_queue *queue = | 854 | struct nvmet_fc_tgt_queue *queue = |
| 853 | container_of(ref, struct nvmet_fc_tgt_queue, ref); | 855 | container_of(ref, struct nvmet_fc_tgt_queue, ref); |
| 854 | 856 | ||
| 855 | rcu_assign_pointer(queue->assoc->queues[queue->qid], NULL); | ||
| 856 | |||
| 857 | nvmet_fc_destroy_fcp_iodlist(queue->assoc->tgtport, queue); | 857 | nvmet_fc_destroy_fcp_iodlist(queue->assoc->tgtport, queue); |
| 858 | 858 | ||
| 859 | nvmet_fc_tgt_a_put(queue->assoc); | ||
| 860 | |||
| 861 | destroy_workqueue(queue->work_q); | 859 | destroy_workqueue(queue->work_q); |
| 862 | 860 | ||
| 863 | kfree_rcu(queue, rcu); | 861 | kfree(queue); |
| 864 | } | 862 | } |
| 865 | 863 | ||
| 866 | static void | 864 | static void |
| @@ -969,7 +967,7 @@ nvmet_fc_find_target_queue(struct nvmet_fc_tgtport *tgtport, · 102 unmodified lines | |||
| 969 | rcu_read_lock(); | 967 | rcu_read_lock(); |
| 970 | list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { | 968 | list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { |
| 971 | if (association_id == assoc->association_id) { | 969 | if (association_id == assoc->association_id) { |
| 972 | queue = rcu_dereference(assoc->queues[qid]); | 970 | queue = assoc->queues[qid]; |
| 973 | if (queue && | 971 | if (queue && |
| 974 | (!atomic_read(&queue->connected) || | 972 | (!atomic_read(&queue->connected) || |
| 975 | !nvmet_fc_tgt_q_get(queue))) | 973 | !nvmet_fc_tgt_q_get(queue))) |
| @@ -1078,8 +1076,6 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) · 102 unmodified lines | |||
| 1078 | /* new allocation not needed */ | 1076 | /* new allocation not needed */ |
| 1079 | kfree(newhost); | 1077 | kfree(newhost); |
| 1080 | newhost = match; | 1078 | newhost = match; |
| 1081 | /* no new allocation - release reference */ | ||
| 1082 | nvmet_fc_tgtport_put(tgtport); | ||
| 1083 | } else { | 1079 | } else { |
| 1084 | newhost->tgtport = tgtport; | 1080 | newhost->tgtport = tgtport; |
| 1085 | newhost->hosthandle = hosthandle; | 1081 | newhost->hosthandle = hosthandle; |
| @@ -1094,23 +1090,54 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) · 8 unmodified lines | |||
| 1094 | } | 1090 | } |
| 1095 | 1091 | ||
| 1096 | static void | 1092 | static void |
| 1097 | nvmet_fc_delete_assoc(struct work_struct *work) | 1093 | nvmet_fc_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) |
| 1094 | { | ||
| 1095 | nvmet_fc_delete_target_assoc(assoc); | ||
| 1096 | nvmet_fc_tgt_a_put(assoc); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | static void | ||
| 1100 | nvmet_fc_delete_assoc_work(struct work_struct *work) | ||
| 1098 | { | 1101 | { |
| 1099 | struct nvmet_fc_tgt_assoc *assoc = | 1102 | struct nvmet_fc_tgt_assoc *assoc = |
| 1100 | container_of(work, struct nvmet_fc_tgt_assoc, del_work); | 1103 | container_of(work, struct nvmet_fc_tgt_assoc, del_work); |
| 1104 | struct nvmet_fc_tgtport *tgtport = assoc->tgtport; | ||
| 1101 | 1105 | ||
| 1102 | nvmet_fc_delete_target_assoc(assoc); | 1106 | nvmet_fc_delete_assoc(assoc); |
| 1103 | nvmet_fc_tgt_a_put(assoc); | 1107 | nvmet_fc_tgtport_put(tgtport); |
| 1108 | } | ||
| 1109 | |||
| 1110 | static void | ||
| 1111 | nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) | ||
| 1112 | { | ||
| 1113 | nvmet_fc_tgtport_get(assoc->tgtport); | ||
| 1114 | queue_work(nvmet_wq, &assoc->del_work); | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | static bool | ||
| 1118 | nvmet_fc_assoc_exits(struct nvmet_fc_tgtport *tgtport, u64 association_id) | ||
| 1119 | { | ||
| 1120 | struct nvmet_fc_tgt_assoc *a; | ||
| 1121 | |||
| 1122 | list_for_each_entry_rcu(a, &tgtport->assoc_list, a_list) { | ||
| 1123 | if (association_id == a->association_id) | ||
| 1124 | return true; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | return false; | ||
| 1104 | } | 1128 | } |
| 1105 | 1129 | ||
| 1106 | static struct nvmet_fc_tgt_assoc * | 1130 | static struct nvmet_fc_tgt_assoc * |
| 1107 | nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) | 1131 | nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) |
| 1108 | { | 1132 | { |
| 1109 | struct nvmet_fc_tgt_assoc *assoc, *tmpassoc; | 1133 | struct nvmet_fc_tgt_assoc *assoc; |
| 1110 | unsigned long flags; | 1134 | unsigned long flags; |
| 1135 | bool done; | ||
| 1111 | u64 ran; | 1136 | u64 ran; |
| 1112 | int idx; | 1137 | int idx; |
| 1113 | bool needrandom = true; | 1138 | |
| 1139 | if (!tgtport->pe) | ||
| 1140 | return NULL; | ||
| 1114 | 1141 | ||
| 1115 | assoc = kzalloc(sizeof(*assoc), GFP_KERNEL); | 1142 | assoc = kzalloc(sizeof(*assoc), GFP_KERNEL); |
| 1116 | if (!assoc) | 1143 | if (!assoc) |
| @@ -1120,43 +1147,35 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) · 3 unmodified lines | |||
| 1120 | if (idx < 0) | 1147 | if (idx < 0) |
| 1121 | goto out_free_assoc; | 1148 | goto out_free_assoc; |
| 1122 | 1149 | ||
| 1123 | if (!nvmet_fc_tgtport_get(tgtport)) | ||
| 1124 | goto out_ida; | ||
| 1125 | |||
| 1126 | assoc->hostport = nvmet_fc_alloc_hostport(tgtport, hosthandle); | 1150 | assoc->hostport = nvmet_fc_alloc_hostport(tgtport, hosthandle); |
| 1127 | if (IS_ERR(assoc->hostport)) | 1151 | if (IS_ERR(assoc->hostport)) |
| 1128 | goto out_put; | 1152 | goto out_ida; |
| 1129 | 1153 | ||
| 1130 | assoc->tgtport = tgtport; | 1154 | assoc->tgtport = tgtport; |
| 1131 | assoc->a_id = idx; | 1155 | assoc->a_id = idx; |
| 1132 | INIT_LIST_HEAD(&assoc->a_list); | 1156 | INIT_LIST_HEAD(&assoc->a_list); |
| 1133 | kref_init(&assoc->ref); | 1157 | kref_init(&assoc->ref); |
| 1134 | INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc); | 1158 | INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc_work); |
| 1135 | atomic_set(&assoc->terminating, 0); | 1159 | atomic_set(&assoc->terminating, 0); |
| 1136 | 1160 | ||
| 1137 | while (needrandom) { | 1161 | done = false; |
| 1162 | do { | ||
| 1138 | get_random_bytes(&ran, sizeof(ran) - BYTES_FOR_QID); | 1163 | get_random_bytes(&ran, sizeof(ran) - BYTES_FOR_QID); |
| 1139 | ran = ran << BYTES_FOR_QID_SHIFT; | 1164 | ran = ran << BYTES_FOR_QID_SHIFT; |
| 1140 | 1165 | ||
| 1141 | spin_lock_irqsave(&tgtport->lock, flags); | 1166 | spin_lock_irqsave(&tgtport->lock, flags); |
| 1142 | needrandom = false; | 1167 | rcu_read_lock(); |
| 1143 | list_for_each_entry(tmpassoc, &tgtport->assoc_list, a_list) { | 1168 | if (!nvmet_fc_assoc_exits(tgtport, ran)) { |
| 1144 | if (ran == tmpassoc->association_id) { | ||
| 1145 | needrandom = true; | ||
| 1146 | break; | ||
| 1147 | } | ||
| 1148 | } | ||
| 1149 | if (!needrandom) { | ||
| 1150 | assoc->association_id = ran; | 1169 | assoc->association_id = ran; |
| 1151 | list_add_tail_rcu(&assoc->a_list, &tgtport->assoc_list); | 1170 | list_add_tail_rcu(&assoc->a_list, &tgtport->assoc_list); |
| 1171 | done = true; | ||
| 1152 | } | 1172 | } |
| 1173 | rcu_read_unlock(); | ||
| 1153 | spin_unlock_irqrestore(&tgtport->lock, flags); | 1174 | spin_unlock_irqrestore(&tgtport->lock, flags); |
| 1154 | } | 1175 | } while (!done); |
| 1155 | 1176 | ||
| 1156 | return assoc; | 1177 | return assoc; |
| 1157 | 1178 | ||
| 1158 | out_put: | ||
| 1159 | nvmet_fc_tgtport_put(tgtport); | ||
| 1160 | out_ida: | 1179 | out_ida: |
| 1161 | ida_free(&tgtport->assoc_cnt, idx); | 1180 | ida_free(&tgtport->assoc_cnt, idx); |
| 1162 | out_free_assoc: | 1181 | out_free_assoc: |
| @@ -1172,13 +1191,18 @@ nvmet_fc_target_assoc_free(struct kref *ref) · 9 unmodified lines | |||
| 1172 | struct nvmet_fc_tgtport *tgtport = assoc->tgtport; | 1191 | struct nvmet_fc_tgtport *tgtport = assoc->tgtport; |
| 1173 | struct nvmet_fc_ls_iod *oldls; | 1192 | struct nvmet_fc_ls_iod *oldls; |
| 1174 | unsigned long flags; | 1193 | unsigned long flags; |
| 1194 | int i; | ||
| 1195 | |||
| 1196 | for (i = NVMET_NR_QUEUES; i >= 0; i--) { | ||
| 1197 | if (assoc->queues[i]) | ||
| 1198 | nvmet_fc_delete_target_queue(assoc->queues[i]); | ||
| 1199 | } | ||
| 1175 | 1200 | ||
| 1176 | /* Send Disconnect now that all i/o has completed */ | 1201 | /* Send Disconnect now that all i/o has completed */ |
| 1177 | nvmet_fc_xmt_disconnect_assoc(assoc); | 1202 | nvmet_fc_xmt_disconnect_assoc(assoc); |
| 1178 | 1203 | ||
| 1179 | nvmet_fc_free_hostport(assoc->hostport); | 1204 | nvmet_fc_free_hostport(assoc->hostport); |
| 1180 | spin_lock_irqsave(&tgtport->lock, flags); | 1205 | spin_lock_irqsave(&tgtport->lock, flags); |
| 1181 | list_del_rcu(&assoc->a_list); | ||
| 1182 | oldls = assoc->rcv_disconn; | 1206 | oldls = assoc->rcv_disconn; |
| 1183 | spin_unlock_irqrestore(&tgtport->lock, flags); | 1207 | spin_unlock_irqrestore(&tgtport->lock, flags); |
| 1184 | /* if pending Rcv Disconnect Association LS, send rsp now */ | 1208 | /* if pending Rcv Disconnect Association LS, send rsp now */ |
| @@ -1188,8 +1212,7 @@ nvmet_fc_target_assoc_free(struct kref *ref) · 3 unmodified lines | |||
| 1188 | dev_info(tgtport->dev, | 1212 | dev_info(tgtport->dev, |
| 1189 | "{%d:%d} Association freed\n", | 1213 | "{%d:%d} Association freed\n", |
| 1190 | tgtport->fc_target_port.port_num, assoc->a_id); | 1214 | tgtport->fc_target_port.port_num, assoc->a_id); |
| 1191 | kfree_rcu(assoc, rcu); | 1215 | kfree(assoc); |
| 1192 | nvmet_fc_tgtport_put(tgtport); | ||
| 1193 | } | 1216 | } |
| 1194 | 1217 | ||
| 1195 | static void | 1218 | static void |
| @@ -1208,7 +1231,7 @@ static void · 12 unmodified lines | |||
| 1208 | nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) | 1231 | nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) |
| 1209 | { | 1232 | { |
| 1210 | struct nvmet_fc_tgtport *tgtport = assoc->tgtport; | 1233 | struct nvmet_fc_tgtport *tgtport = assoc->tgtport; |
| 1211 | struct nvmet_fc_tgt_queue *queue; | 1234 | unsigned long flags; |
| 1212 | int i, terminating; | 1235 | int i, terminating; |
| 1213 | 1236 | ||
| 1214 | terminating = atomic_xchg(&assoc->terminating, 1); | 1237 | terminating = atomic_xchg(&assoc->terminating, 1); |
| @@ -1217,29 +1240,21 @@ nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) · 2 unmodified lines | |||
| 1217 | if (terminating) | 1240 | if (terminating) |
| 1218 | return; | 1241 | return; |
| 1219 | 1242 | ||
| 1243 | spin_lock_irqsave(&tgtport->lock, flags); | ||
| 1244 | list_del_rcu(&assoc->a_list); | ||
| 1245 | spin_unlock_irqrestore(&tgtport->lock, flags); | ||
| 1220 | 1246 | ||
| 1221 | for (i = NVMET_NR_QUEUES; i >= 0; i--) { | 1247 | synchronize_rcu(); |
| 1222 | rcu_read_lock(); | ||
| 1223 | queue = rcu_dereference(assoc->queues[i]); | ||
| 1224 | if (!queue) { | ||
| 1225 | rcu_read_unlock(); | ||
| 1226 | continue; | ||
| 1227 | } | ||
| 1228 | 1248 | ||
| 1229 | if (!nvmet_fc_tgt_q_get(queue)) { | 1249 | /* ensure all in-flight I/Os have been processed */ |
| 1230 | rcu_read_unlock(); | 1250 | for (i = NVMET_NR_QUEUES; i >= 0; i--) { |
| 1231 | continue; | 1251 | if (assoc->queues[i]) |
| 1232 | } | 1252 | flush_workqueue(assoc->queues[i]->work_q); |
| 1233 | rcu_read_unlock(); | ||
| 1234 | nvmet_fc_delete_target_queue(queue); | ||
| 1235 | nvmet_fc_tgt_q_put(queue); | ||
| 1236 | } | 1253 | } |
| 1237 | 1254 | ||
| 1238 | dev_info(tgtport->dev, | 1255 | dev_info(tgtport->dev, |
| 1239 | "{%d:%d} Association deleted\n", | 1256 | "{%d:%d} Association deleted\n", |
| 1240 | tgtport->fc_target_port.port_num, assoc->a_id); | 1257 | tgtport->fc_target_port.port_num, assoc->a_id); |
| 1241 | |||
| 1242 | nvmet_fc_tgt_a_put(assoc); | ||
| 1243 | } | 1258 | } |
| 1244 | 1259 | ||
| 1245 | static struct nvmet_fc_tgt_assoc * | 1260 | static struct nvmet_fc_tgt_assoc * |
| @@ -1415,6 +1430,7 @@ nvmet_fc_register_targetport(struct nvmet_fc_port_info *pinfo, · 169 unmodified lines | |||
| 1415 | kref_init(&newrec->ref); | 1430 | kref_init(&newrec->ref); |
| 1416 | ida_init(&newrec->assoc_cnt); | 1431 | ida_init(&newrec->assoc_cnt); |
| 1417 | newrec->max_sg_cnt = template->max_sgl_segments; | 1432 | newrec->max_sg_cnt = template->max_sgl_segments; |
| 1433 | INIT_WORK(&newrec->put_work, nvmet_fc_put_tgtport_work); | ||
| 1418 | 1434 | ||
| 1419 | ret = nvmet_fc_alloc_ls_iodlist(newrec); | 1435 | ret = nvmet_fc_alloc_ls_iodlist(newrec); |
| 1420 | if (ret) { | 1436 | if (ret) { |
| @@ -1492,9 +1508,8 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport) · 71 unmodified lines | |||
| 1492 | list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { | 1508 | list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { |
| 1493 | if (!nvmet_fc_tgt_a_get(assoc)) | 1509 | if (!nvmet_fc_tgt_a_get(assoc)) |
| 1494 | continue; | 1510 | continue; |
| 1495 | if (!queue_work(nvmet_wq, &assoc->del_work)) | 1511 | nvmet_fc_schedule_delete_assoc(assoc); |
| 1496 | /* already deleting - release local reference */ | 1512 | nvmet_fc_tgt_a_put(assoc); |
| 1497 | nvmet_fc_tgt_a_put(assoc); | ||
| 1498 | } | 1513 | } |
| 1499 | rcu_read_unlock(); | 1514 | rcu_read_unlock(); |
| 1500 | } | 1515 | } |
| @@ -1540,16 +1555,14 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port, · 39 unmodified lines | |||
| 1540 | spin_lock_irqsave(&tgtport->lock, flags); | 1555 | spin_lock_irqsave(&tgtport->lock, flags); |
| 1541 | list_for_each_entry_safe(assoc, next, | 1556 | list_for_each_entry_safe(assoc, next, |
| 1542 | &tgtport->assoc_list, a_list) { | 1557 | &tgtport->assoc_list, a_list) { |
| 1543 | if (!assoc->hostport || | 1558 | if (assoc->hostport->hosthandle != hosthandle) |
| 1544 | assoc->hostport->hosthandle != hosthandle) | ||
| 1545 | continue; | 1559 | continue; |
| 1546 | if (!nvmet_fc_tgt_a_get(assoc)) | 1560 | if (!nvmet_fc_tgt_a_get(assoc)) |
| 1547 | continue; | 1561 | continue; |
| 1548 | assoc->hostport->invalid = 1; | 1562 | assoc->hostport->invalid = 1; |
| 1549 | noassoc = false; | 1563 | noassoc = false; |
| 1550 | if (!queue_work(nvmet_wq, &assoc->del_work)) | 1564 | nvmet_fc_schedule_delete_assoc(assoc); |
| 1551 | /* already deleting - release local reference */ | 1565 | nvmet_fc_tgt_a_put(assoc); |
| 1552 | nvmet_fc_tgt_a_put(assoc); | ||
| 1553 | } | 1566 | } |
| 1554 | spin_unlock_irqrestore(&tgtport->lock, flags); | 1567 | spin_unlock_irqrestore(&tgtport->lock, flags); |
| 1555 | 1568 | ||
| @@ -1581,7 +1594,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) · 25 unmodified lines | |||
| 1581 | 1594 | ||
| 1582 | rcu_read_lock(); | 1595 | rcu_read_lock(); |
| 1583 | list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { | 1596 | list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { |
| 1584 | queue = rcu_dereference(assoc->queues[0]); | 1597 | queue = assoc->queues[0]; |
| 1585 | if (queue && queue->nvme_sq.ctrl == ctrl) { | 1598 | if (queue && queue->nvme_sq.ctrl == ctrl) { |
| 1586 | if (nvmet_fc_tgt_a_get(assoc)) | 1599 | if (nvmet_fc_tgt_a_get(assoc)) |
| 1587 | found_ctrl = true; | 1600 | found_ctrl = true; |
| @@ -1593,9 +1606,8 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) · 5 unmodified lines | |||
| 1593 | nvmet_fc_tgtport_put(tgtport); | 1606 | nvmet_fc_tgtport_put(tgtport); |
| 1594 | 1607 | ||
| 1595 | if (found_ctrl) { | 1608 | if (found_ctrl) { |
| 1596 | if (!queue_work(nvmet_wq, &assoc->del_work)) | 1609 | nvmet_fc_schedule_delete_assoc(assoc); |
| 1597 | /* already deleting - release local reference */ | 1610 | nvmet_fc_tgt_a_put(assoc); |
| 1598 | nvmet_fc_tgt_a_put(assoc); | ||
| 1599 | return; | 1611 | return; |
| 1600 | } | 1612 | } |
| 1601 | 1613 | ||
| @@ -1625,6 +1637,8 @@ nvmet_fc_unregister_targetport(struct nvmet_fc_target_port *target_port) · 23 unmodified lines | |||
| 1625 | /* terminate any outstanding associations */ | 1637 | /* terminate any outstanding associations */ |
| 1626 | __nvmet_fc_free_assocs(tgtport); | 1638 | __nvmet_fc_free_assocs(tgtport); |
| 1627 | 1639 | ||
| 1640 | flush_workqueue(nvmet_wq); | ||
| 1641 | |||
| 1628 | /* | 1642 | /* |
| 1629 | * should terminate LS's as well. However, LS's will be generated | 1643 | * should terminate LS's as well. However, LS's will be generated |
| 1630 | * at the tail end of association termination, so they likely don't | 1644 | * at the tail end of association termination, so they likely don't |
| @@ -1870,9 +1884,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, · 239 unmodified lines | |||
| 1870 | sizeof(struct fcnvme_ls_disconnect_assoc_acc)), | 1884 | sizeof(struct fcnvme_ls_disconnect_assoc_acc)), |
| 1871 | FCNVME_LS_DISCONNECT_ASSOC); | 1885 | FCNVME_LS_DISCONNECT_ASSOC); |
| 1872 | 1886 | ||
| 1873 | /* release get taken in nvmet_fc_find_target_assoc */ | ||
| 1874 | nvmet_fc_tgt_a_put(assoc); | ||
| 1875 | |||
| 1876 | /* | 1887 | /* |
| 1877 | * The rules for LS response says the response cannot | 1888 | * The rules for LS response says the response cannot |
| 1878 | * go back until ABTS's have been sent for all outstanding | 1889 | * go back until ABTS's have been sent for all outstanding |
| @@ -1887,8 +1898,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, · 8 unmodified lines | |||
| 1887 | assoc->rcv_disconn = iod; | 1898 | assoc->rcv_disconn = iod; |
| 1888 | spin_unlock_irqrestore(&tgtport->lock, flags); | 1899 | spin_unlock_irqrestore(&tgtport->lock, flags); |
| 1889 | 1900 | ||
| 1890 | nvmet_fc_delete_target_assoc(assoc); | ||
| 1891 | |||
| 1892 | if (oldls) { | 1901 | if (oldls) { |
| 1893 | dev_info(tgtport->dev, | 1902 | dev_info(tgtport->dev, |
| 1894 | "{%d:%d} Multiple Disconnect Association LS's " | 1903 | "{%d:%d} Multiple Disconnect Association LS's " |
| @@ -1904,6 +1913,9 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, · 9 unmodified lines | |||
| 1904 | nvmet_fc_xmt_ls_rsp(tgtport, oldls); | 1913 | nvmet_fc_xmt_ls_rsp(tgtport, oldls); |
| 1905 | } | 1914 | } |
| 1906 | 1915 | ||
| 1916 | nvmet_fc_schedule_delete_assoc(assoc); | ||
| 1917 | nvmet_fc_tgt_a_put(assoc); | ||
| 1918 | |||
| 1907 | return false; | 1919 | return false; |
| 1908 | } | 1920 | } |
| 1909 | 1921 | ||
| @@ -2540,8 +2552,9 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, · 630 unmodified lines | |||
| 2540 | 2552 | ||
| 2541 | fod->req.cmd = &fod->cmdiubuf.sqe; | 2553 | fod->req.cmd = &fod->cmdiubuf.sqe; |
| 2542 | fod->req.cqe = &fod->rspiubuf.cqe; | 2554 | fod->req.cqe = &fod->rspiubuf.cqe; |
| 2543 | if (tgtport->pe) | 2555 | if (!tgtport->pe) |
| 2544 | fod->req.port = tgtport->pe->port; | 2556 | goto transport_error; |
| 2557 | fod->req.port = tgtport->pe->port; | ||
| 2545 | 2558 | ||
| 2546 | /* clear any response payload */ | 2559 | /* clear any response payload */ |
| 2547 | memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf)); | 2560 | memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf)); |
| @@ -2902,6 +2915,9 @@ nvmet_fc_remove_port(struct nvmet_port *port) · 354 unmodified lines | |||
| 2902 | 2915 | ||
| 2903 | nvmet_fc_portentry_unbind(pe); | 2916 | nvmet_fc_portentry_unbind(pe); |
| 2904 | 2917 | ||
| 2918 | /* terminate any outstanding associations */ | ||
| 2919 | __nvmet_fc_free_assocs(pe->tgtport); | ||
| 2920 | |||
| 2905 | kfree(pe); | 2921 | kfree(pe); |
| 2906 | } | 2922 | } |
| 2907 | 2923 | ||
| @@ -2933,6 +2949,9 @@ static int __init nvmet_fc_init_module(void) · 25 unmodified lines | |||
| 2933 | 2949 | ||
| 2934 | static void __exit nvmet_fc_exit_module(void) | 2950 | static void __exit nvmet_fc_exit_module(void) |
| 2935 | { | 2951 | { |
| 2952 | /* ensure any shutdown operation, e.g. delete ctrls have finished */ | ||
| 2953 | flush_workqueue(nvmet_wq); | ||
| 2954 | |||
| 2936 | /* sanity check - all lports should be removed */ | 2955 | /* sanity check - all lports should be removed */ |
| 2937 | if (!list_empty(&nvmet_fc_target_list)) | 2956 | if (!list_empty(&nvmet_fc_target_list)) |
| 2938 | pr_warn("%s: targetport list not empty\n", __func__); | 2957 | pr_warn("%s: targetport list not empty\n", __func__); |
| @@ -2945,4 +2964,5 @@ static void __exit nvmet_fc_exit_module(void) · 6 unmodified lines | |||
| 2945 | module_init(nvmet_fc_init_module); | 2964 | module_init(nvmet_fc_init_module); |
| 2946 | module_exit(nvmet_fc_exit_module); | 2965 | module_exit(nvmet_fc_exit_module); |
| 2947 | 2966 | ||
| 2967 | MODULE_DESCRIPTION("NVMe target FC transport driver"); | ||
| 2948 | MODULE_LICENSE("GPL v2"); | 2968 | MODULE_LICENSE("GPL v2"); |
| @@ -358,7 +358,7 @@ fcloop_h2t_ls_req(struct nvme_fc_local_port *localport, · 357 unmodified lines | |||
| 358 | if (!rport->targetport) { | 358 | if (!rport->targetport) { |
| 359 | tls_req->status = -ECONNREFUSED; | 359 | tls_req->status = -ECONNREFUSED; |
| 360 | spin_lock(&rport->lock); | 360 | spin_lock(&rport->lock); |
| 361 | list_add_tail(&rport->ls_list, &tls_req->ls_list); | 361 | list_add_tail(&tls_req->ls_list, &rport->ls_list); |
| 362 | spin_unlock(&rport->lock); | 362 | spin_unlock(&rport->lock); |
| 363 | queue_work(nvmet_wq, &rport->ls_work); | 363 | queue_work(nvmet_wq, &rport->ls_work); |
| 364 | return ret; | 364 | return ret; |
| @@ -391,7 +391,7 @@ fcloop_h2t_xmt_ls_rsp(struct nvmet_fc_target_port *targetport, · 26 unmodified lines | |||
| 391 | if (remoteport) { | 391 | if (remoteport) { |
| 392 | rport = remoteport->private; | 392 | rport = remoteport->private; |
| 393 | spin_lock(&rport->lock); | 393 | spin_lock(&rport->lock); |
| 394 | list_add_tail(&rport->ls_list, &tls_req->ls_list); | 394 | list_add_tail(&tls_req->ls_list, &rport->ls_list); |
| 395 | spin_unlock(&rport->lock); | 395 | spin_unlock(&rport->lock); |
| 396 | queue_work(nvmet_wq, &rport->ls_work); | 396 | queue_work(nvmet_wq, &rport->ls_work); |
| 397 | } | 397 | } |
| @@ -446,7 +446,7 @@ fcloop_t2h_ls_req(struct nvmet_fc_target_port *targetport, void *hosthandle, · 48 unmodified lines | |||
| 446 | if (!tport->remoteport) { | 446 | if (!tport->remoteport) { |
| 447 | tls_req->status = -ECONNREFUSED; | 447 | tls_req->status = -ECONNREFUSED; |
| 448 | spin_lock(&tport->lock); | 448 | spin_lock(&tport->lock); |
| 449 | list_add_tail(&tport->ls_list, &tls_req->ls_list); | 449 | list_add_tail(&tls_req->ls_list, &tport->ls_list); |
| 450 | spin_unlock(&tport->lock); | 450 | spin_unlock(&tport->lock); |
| 451 | queue_work(nvmet_wq, &tport->ls_work); | 451 | queue_work(nvmet_wq, &tport->ls_work); |
| 452 | return ret; | 452 | return ret; |
| @@ -1650,4 +1650,5 @@ static void __exit fcloop_exit(void) · 1197 unmodified lines | |||
| 1650 | module_init(fcloop_init); | 1650 | module_init(fcloop_init); |
| 1651 | module_exit(fcloop_exit); | 1651 | module_exit(fcloop_exit); |
| 1652 | 1652 | ||
| 1653 | MODULE_DESCRIPTION("NVMe target FC loop transport driver"); | ||
| 1653 | MODULE_LICENSE("GPL v2"); | 1654 | MODULE_LICENSE("GPL v2"); |
| @@ -400,7 +400,7 @@ static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl) · 399 unmodified lines | |||
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | nvme_quiesce_admin_queue(&ctrl->ctrl); | 402 | nvme_quiesce_admin_queue(&ctrl->ctrl); |
| 403 | if (ctrl->ctrl.state == NVME_CTRL_LIVE) | 403 | if (nvme_ctrl_state(&ctrl->ctrl) == NVME_CTRL_LIVE) |
| 404 | nvme_disable_ctrl(&ctrl->ctrl, true); | 404 | nvme_disable_ctrl(&ctrl->ctrl, true); |
| 405 | 405 | ||
| 406 | nvme_cancel_admin_tagset(&ctrl->ctrl); | 406 | nvme_cancel_admin_tagset(&ctrl->ctrl); |
| @@ -434,8 +434,10 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work) · 27 unmodified lines | |||
| 434 | nvme_loop_shutdown_ctrl(ctrl); | 434 | nvme_loop_shutdown_ctrl(ctrl); |
| 435 | 435 | ||
| 436 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { | 436 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { |
| 437 | if (ctrl->ctrl.state != NVME_CTRL_DELETING && | 437 | enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl); |
| 438 | ctrl->ctrl.state != NVME_CTRL_DELETING_NOIO) | 438 | |
| 439 | if (state != NVME_CTRL_DELETING && | ||
| 440 | state != NVME_CTRL_DELETING_NOIO) | ||
| 439 | /* state change failure for non-deleted ctrl? */ | 441 | /* state change failure for non-deleted ctrl? */ |
| 440 | WARN_ON_ONCE(1); | 442 | WARN_ON_ONCE(1); |
| 441 | return; | 443 | return; |
| @@ -688,5 +690,6 @@ static void __exit nvme_loop_cleanup_module(void) · 246 unmodified lines | |||
| 688 | module_init(nvme_loop_init_module); | 690 | module_init(nvme_loop_init_module); |
| 689 | module_exit(nvme_loop_cleanup_module); | 691 | module_exit(nvme_loop_cleanup_module); |
| 690 | 692 | ||
| 693 | MODULE_DESCRIPTION("NVMe target loop transport driver"); | ||
| 691 | MODULE_LICENSE("GPL v2"); | 694 | MODULE_LICENSE("GPL v2"); |
| 692 | MODULE_ALIAS("nvmet-transport-254"); /* 254 == NVMF_TRTYPE_LOOP */ | 695 | MODULE_ALIAS("nvmet-transport-254"); /* 254 == NVMF_TRTYPE_LOOP */ |
| @@ -2104,5 +2104,6 @@ static void __exit nvmet_rdma_exit(void) · 2103 unmodified lines | |||
| 2104 | module_init(nvmet_rdma_init); | 2104 | module_init(nvmet_rdma_init); |
| 2105 | module_exit(nvmet_rdma_exit); | 2105 | module_exit(nvmet_rdma_exit); |
| 2106 | 2106 | ||
| 2107 | MODULE_DESCRIPTION("NVMe target RDMA transport driver"); | ||
| 2107 | MODULE_LICENSE("GPL v2"); | 2108 | MODULE_LICENSE("GPL v2"); |
| 2108 | MODULE_ALIAS("nvmet-transport-1"); /* 1 == NVMF_TRTYPE_RDMA */ | 2109 | MODULE_ALIAS("nvmet-transport-1"); /* 1 == NVMF_TRTYPE_RDMA */ |
| @@ -2216,10 +2216,12 @@ static void __exit nvmet_tcp_exit(void) · 2215 unmodified lines | |||
| 2216 | flush_workqueue(nvmet_wq); | 2216 | flush_workqueue(nvmet_wq); |
| 2217 | 2217 | ||
| 2218 | destroy_workqueue(nvmet_tcp_wq); | 2218 | destroy_workqueue(nvmet_tcp_wq); |
| 2219 | ida_destroy(&nvmet_tcp_queue_ida); | ||
| 2219 | } | 2220 | } |
| 2220 | 2221 | ||
| 2221 | module_init(nvmet_tcp_init); | 2222 | module_init(nvmet_tcp_init); |
| 2222 | module_exit(nvmet_tcp_exit); | 2223 | module_exit(nvmet_tcp_exit); |
| 2223 | 2224 | ||
| 2225 | MODULE_DESCRIPTION("NVMe target TCP transport driver"); | ||
| 2224 | MODULE_LICENSE("GPL v2"); | 2226 | MODULE_LICENSE("GPL v2"); |
| 2225 | MODULE_ALIAS("nvmet-transport-3"); /* 3 == NVMF_TRTYPE_TCP */ | 2227 | MODULE_ALIAS("nvmet-transport-3"); /* 3 == NVMF_TRTYPE_TCP */ |
| @@ -386,21 +386,8 @@ void pci_bus_add_devices(const struct pci_bus *bus) · 385 unmodified lines | |||
| 386 | } | 386 | } |
| 387 | EXPORT_SYMBOL(pci_bus_add_devices); | 387 | EXPORT_SYMBOL(pci_bus_add_devices); |
| 388 | 388 | ||
| 389 | /** pci_walk_bus - walk devices on/under bus, calling callback. | 389 | static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), |
| 390 | * @top bus whose devices should be walked | 390 | void *userdata, bool locked) |
| 391 | * @cb callback to be called for each device found | ||
| 392 | * @userdata arbitrary pointer to be passed to callback. | ||
| 393 | * | ||
| 394 | * Walk the given bus, including any bridged devices | ||
| 395 | * on buses under this bus. Call the provided callback | ||
| 396 | * on each device found. | ||
| 397 | * | ||
| 398 | * We check the return of @cb each time. If it returns anything | ||
| 399 | * other than 0, we break out. | ||
| 400 | * | ||
| 401 | */ | ||
| 402 | void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | ||
| 403 | void *userdata) | ||
| 404 | { | 391 | { |
| 405 | struct pci_dev *dev; | 392 | struct pci_dev *dev; |
| 406 | struct pci_bus *bus; | 393 | struct pci_bus *bus; |
| @@ -408,7 +395,8 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), · 1 unmodified line | |||
| 408 | int retval; | 395 | int retval; |
| 409 | 396 | ||
| 410 | bus = top; | 397 | bus = top; |
| 411 | down_read(&pci_bus_sem); | 398 | if (!locked) |
| 399 | down_read(&pci_bus_sem); | ||
| 412 | next = top->devices.next; | 400 | next = top->devices.next; |
| 413 | for (;;) { | 401 | for (;;) { |
| 414 | if (next == &bus->devices) { | 402 | if (next == &bus->devices) { |
| @@ -431,10 +419,37 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), · 16 unmodified lines | |||
| 431 | if (retval) | 419 | if (retval) |
| 432 | break; | 420 | break; |
| 433 | } | 421 | } |
| 434 | up_read(&pci_bus_sem); | 422 | if (!locked) |
| 423 | up_read(&pci_bus_sem); | ||
| 424 | } | ||
| 425 | |||
| 426 | /** | ||
| 427 | * pci_walk_bus - walk devices on/under bus, calling callback. | ||
| 428 | * @top: bus whose devices should be walked | ||
| 429 | * @cb: callback to be called for each device found | ||
| 430 | * @userdata: arbitrary pointer to be passed to callback | ||
| 431 | * | ||
| 432 | * Walk the given bus, including any bridged devices | ||
| 433 | * on buses under this bus. Call the provided callback | ||
| 434 | * on each device found. | ||
| 435 | * | ||
| 436 | * We check the return of @cb each time. If it returns anything | ||
| 437 | * other than 0, we break out. | ||
| 438 | */ | ||
| 439 | void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), void *userdata) | ||
| 440 | { | ||
| 441 | __pci_walk_bus(top, cb, userdata, false); | ||
| 435 | } | 442 | } |
| 436 | EXPORT_SYMBOL_GPL(pci_walk_bus); | 443 | EXPORT_SYMBOL_GPL(pci_walk_bus); |
| 437 | 444 | ||
| 445 | void pci_walk_bus_locked(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), void *userdata) | ||
| 446 | { | ||
| 447 | lockdep_assert_held(&pci_bus_sem); | ||
| 448 | |||
| 449 | __pci_walk_bus(top, cb, userdata, true); | ||
| 450 | } | ||
| 451 | EXPORT_SYMBOL_GPL(pci_walk_bus_locked); | ||
| 452 | |||
| 438 | struct pci_bus *pci_bus_get(struct pci_bus *bus) | 453 | struct pci_bus *pci_bus_get(struct pci_bus *bus) |
| 439 | { | 454 | { |
| 440 | if (bus) | 455 | if (bus) |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | 6 | * Author: Kishon Vijay Abraham I <kishon@ti.com> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/align.h> | ||
| 9 | #include <linux/bitfield.h> | 10 | #include <linux/bitfield.h> |
| 10 | #include <linux/of.h> | 11 | #include <linux/of.h> |
| 11 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| @@ -482,9 +483,10 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, · 470 unmodified lines | |||
| 482 | reg = ep_func->msi_cap + PCI_MSI_DATA_32; | 483 | reg = ep_func->msi_cap + PCI_MSI_DATA_32; |
| 483 | msg_data = dw_pcie_ep_readw_dbi(ep, func_no, reg); | 484 | msg_data = dw_pcie_ep_readw_dbi(ep, func_no, reg); |
| 484 | } | 485 | } |
| 485 | aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1); | 486 | msg_addr = ((u64)msg_addr_upper) << 32 | msg_addr_lower; |
| 486 | msg_addr = ((u64)msg_addr_upper) << 32 | | 487 | |
| 487 | (msg_addr_lower & ~aligned_offset); | 488 | aligned_offset = msg_addr & (epc->mem->window.page_size - 1); |
| 489 | msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); | ||
| 488 | ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, | 490 | ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, |
| 489 | epc->mem->window.page_size); | 491 | epc->mem->window.page_size); |
| 490 | if (ret) | 492 | if (ret) |
| @@ -551,7 +553,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, · 60 unmodified lines | |||
| 551 | } | 553 | } |
| 552 | 554 | ||
| 553 | aligned_offset = msg_addr & (epc->mem->window.page_size - 1); | 555 | aligned_offset = msg_addr & (epc->mem->window.page_size - 1); |
| 554 | msg_addr &= ~aligned_offset; | 556 | msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); |
| 555 | ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, | 557 | ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, |
| 556 | epc->mem->window.page_size); | 558 | epc->mem->window.page_size); |
| 557 | if (ret) | 559 | if (ret) |
| @@ -972,7 +972,7 @@ static int qcom_pcie_enable_aspm(struct pci_dev *pdev, void *userdata) · 971 unmodified lines | |||
| 972 | * Downstream devices need to be in D0 state before enabling PCI PM | 972 | * Downstream devices need to be in D0 state before enabling PCI PM |
| 973 | * substates. | 973 | * substates. |
| 974 | */ | 974 | */ |
| 975 | pci_set_power_state(pdev, PCI_D0); | 975 | pci_set_power_state_locked(pdev, PCI_D0); |
| 976 | pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL); | 976 | pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL); |
| 977 | 977 | ||
| 978 | return 0; | 978 | return 0; |
| @@ -1354,6 +1354,7 @@ end: · 1353 unmodified lines | |||
| 1354 | /** | 1354 | /** |
| 1355 | * pci_set_full_power_state - Put a PCI device into D0 and update its state | 1355 | * pci_set_full_power_state - Put a PCI device into D0 and update its state |
| 1356 | * @dev: PCI device to power up | 1356 | * @dev: PCI device to power up |
| 1357 | * @locked: whether pci_bus_sem is held | ||
| 1357 | * | 1358 | * |
| 1358 | * Call pci_power_up() to put @dev into D0, read from its PCI_PM_CTRL register | 1359 | * Call pci_power_up() to put @dev into D0, read from its PCI_PM_CTRL register |
| 1359 | * to confirm the state change, restore its BARs if they might be lost and | 1360 | * to confirm the state change, restore its BARs if they might be lost and |
| @@ -1363,7 +1364,7 @@ end: · 3 unmodified lines | |||
| 1363 | * to D0, it is more efficient to use pci_power_up() directly instead of this | 1364 | * to D0, it is more efficient to use pci_power_up() directly instead of this |
| 1364 | * function. | 1365 | * function. |
| 1365 | */ | 1366 | */ |
| 1366 | static int pci_set_full_power_state(struct pci_dev *dev) | 1367 | static int pci_set_full_power_state(struct pci_dev *dev, bool locked) |
| 1367 | { | 1368 | { |
| 1368 | u16 pmcsr; | 1369 | u16 pmcsr; |
| 1369 | int ret; | 1370 | int ret; |
| @@ -1399,7 +1400,7 @@ static int pci_set_full_power_state(struct pci_dev *dev) · 29 unmodified lines | |||
| 1399 | } | 1400 | } |
| 1400 | 1401 | ||
| 1401 | if (dev->bus->self) | 1402 | if (dev->bus->self) |
| 1402 | pcie_aspm_pm_state_change(dev->bus->self); | 1403 | pcie_aspm_pm_state_change(dev->bus->self, locked); |
| 1403 | 1404 | ||
| 1404 | return 0; | 1405 | return 0; |
| 1405 | } | 1406 | } |
| @@ -1428,10 +1429,22 @@ void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) · 22 unmodified lines | |||
| 1428 | pci_walk_bus(bus, __pci_dev_set_current_state, &state); | 1429 | pci_walk_bus(bus, __pci_dev_set_current_state, &state); |
| 1429 | } | 1430 | } |
| 1430 | 1431 | ||
| 1432 | static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state, bool locked) | ||
| 1433 | { | ||
| 1434 | if (!bus) | ||
| 1435 | return; | ||
| 1436 | |||
| 1437 | if (locked) | ||
| 1438 | pci_walk_bus_locked(bus, __pci_dev_set_current_state, &state); | ||
| 1439 | else | ||
| 1440 | pci_walk_bus(bus, __pci_dev_set_current_state, &state); | ||
| 1441 | } | ||
| 1442 | |||
| 1431 | /** | 1443 | /** |
| 1432 | * pci_set_low_power_state - Put a PCI device into a low-power state. | 1444 | * pci_set_low_power_state - Put a PCI device into a low-power state. |
| 1433 | * @dev: PCI device to handle. | 1445 | * @dev: PCI device to handle. |
| 1434 | * @state: PCI power state (D1, D2, D3hot) to put the device into. | 1446 | * @state: PCI power state (D1, D2, D3hot) to put the device into. |
| 1447 | * @locked: whether pci_bus_sem is held | ||
| 1435 | * | 1448 | * |
| 1436 | * Use the device's PCI_PM_CTRL register to put it into a low-power state. | 1449 | * Use the device's PCI_PM_CTRL register to put it into a low-power state. |
| 1437 | * | 1450 | * |
| @@ -1442,7 +1455,7 @@ void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) · 4 unmodified lines | |||
| 1442 | * 0 if device already is in the requested state. | 1455 | * 0 if device already is in the requested state. |
| 1443 | * 0 if device's power state has been successfully changed. | 1456 | * 0 if device's power state has been successfully changed. |
| 1444 | */ | 1457 | */ |
| 1445 | static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state) | 1458 | static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state, bool locked) |
| 1446 | { | 1459 | { |
| 1447 | u16 pmcsr; | 1460 | u16 pmcsr; |
| 1448 | 1461 | ||
| @@ -1496,29 +1509,12 @@ static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state) · 47 unmodified lines | |||
| 1496 | pci_power_name(state)); | 1509 | pci_power_name(state)); |
| 1497 | 1510 | ||
| 1498 | if (dev->bus->self) | 1511 | if (dev->bus->self) |
| 1499 | pcie_aspm_pm_state_change(dev->bus->self); | 1512 | pcie_aspm_pm_state_change(dev->bus->self, locked); |
| 1500 | 1513 | ||
| 1501 | return 0; | 1514 | return 0; |
| 1502 | } | 1515 | } |
| 1503 | 1516 | ||
| 1504 | /** | 1517 | static int __pci_set_power_state(struct pci_dev *dev, pci_power_t state, bool locked) |
| 1505 | * pci_set_power_state - Set the power state of a PCI device | ||
| 1506 | * @dev: PCI device to handle. | ||
| 1507 | * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. | ||
| 1508 | * | ||
| 1509 | * Transition a device to a new power state, using the platform firmware and/or | ||
| 1510 | * the device's PCI PM registers. | ||
| 1511 | * | ||
| 1512 | * RETURN VALUE: | ||
| 1513 | * -EINVAL if the requested state is invalid. | ||
| 1514 | * -EIO if device does not support PCI PM or its PM capabilities register has a | ||
| 1515 | * wrong version, or device doesn't support the requested state. | ||
| 1516 | * 0 if the transition is to D1 or D2 but D1 and D2 are not supported. | ||
| 1517 | * 0 if device already is in the requested state. | ||
| 1518 | * 0 if the transition is to D3 but D3 is not supported. | ||
| 1519 | * 0 if device's power state has been successfully changed. | ||
| 1520 | */ | ||
| 1521 | int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | ||
| 1522 | { | 1518 | { |
| 1523 | int error; | 1519 | int error; |
| 1524 | 1520 | ||
| @@ -1542,7 +1538,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) · 17 unmodified lines | |||
| 1542 | return 0; | 1538 | return 0; |
| 1543 | 1539 | ||
| 1544 | if (state == PCI_D0) | 1540 | if (state == PCI_D0) |
| 1545 | return pci_set_full_power_state(dev); | 1541 | return pci_set_full_power_state(dev, locked); |
| 1546 | 1542 | ||
| 1547 | /* | 1543 | /* |
| 1548 | * This device is quirked not to be put into D3, so don't put it in | 1544 | * This device is quirked not to be put into D3, so don't put it in |
| @@ -1556,16 +1552,16 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) · 7 unmodified lines | |||
| 1556 | * To put the device in D3cold, put it into D3hot in the native | 1552 | * To put the device in D3cold, put it into D3hot in the native |
| 1557 | * way, then put it into D3cold using platform ops. | 1553 | * way, then put it into D3cold using platform ops. |
| 1558 | */ | 1554 | */ |
| 1559 | error = pci_set_low_power_state(dev, PCI_D3hot); | 1555 | error = pci_set_low_power_state(dev, PCI_D3hot, locked); |
| 1560 | 1556 | ||
| 1561 | if (pci_platform_power_transition(dev, PCI_D3cold)) | 1557 | if (pci_platform_power_transition(dev, PCI_D3cold)) |
| 1562 | return error; | 1558 | return error; |
| 1563 | 1559 | ||
| 1564 | /* Powering off a bridge may power off the whole hierarchy */ | 1560 | /* Powering off a bridge may power off the whole hierarchy */ |
| 1565 | if (dev->current_state == PCI_D3cold) | 1561 | if (dev->current_state == PCI_D3cold) |
| 1566 | pci_bus_set_current_state(dev->subordinate, PCI_D3cold); | 1562 | __pci_bus_set_current_state(dev->subordinate, PCI_D3cold, locked); |
| 1567 | } else { | 1563 | } else { |
| 1568 | error = pci_set_low_power_state(dev, state); | 1564 | error = pci_set_low_power_state(dev, state, locked); |
| 1569 | 1565 | ||
| 1570 | if (pci_platform_power_transition(dev, state)) | 1566 | if (pci_platform_power_transition(dev, state)) |
| 1571 | return error; | 1567 | return error; |
| @@ -1573,8 +1569,38 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) · 1 unmodified line | |||
| 1573 | 1569 | ||
| 1574 | return 0; | 1570 | return 0; |
| 1575 | } | 1571 | } |
| 1572 | |||
| 1573 | /** | ||
| 1574 | * pci_set_power_state - Set the power state of a PCI device | ||
| 1575 | * @dev: PCI device to handle. | ||
| 1576 | * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. | ||
| 1577 | * | ||
| 1578 | * Transition a device to a new power state, using the platform firmware and/or | ||
| 1579 | * the device's PCI PM registers. | ||
| 1580 | * | ||
| 1581 | * RETURN VALUE: | ||
| 1582 | * -EINVAL if the requested state is invalid. | ||
| 1583 | * -EIO if device does not support PCI PM or its PM capabilities register has a | ||
| 1584 | * wrong version, or device doesn't support the requested state. | ||
| 1585 | * 0 if the transition is to D1 or D2 but D1 and D2 are not supported. | ||
| 1586 | * 0 if device already is in the requested state. | ||
| 1587 | * 0 if the transition is to D3 but D3 is not supported. | ||
| 1588 | * 0 if device's power state has been successfully changed. | ||
| 1589 | */ | ||
| 1590 | int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | ||
| 1591 | { | ||
| 1592 | return __pci_set_power_state(dev, state, false); | ||
| 1593 | } | ||
| 1576 | EXPORT_SYMBOL(pci_set_power_state); | 1594 | EXPORT_SYMBOL(pci_set_power_state); |
| 1577 | 1595 | ||
11 more lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 248 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 276 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 409 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 239 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 466 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 314 lines aren’t shown here.
This diff is large: its 747 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 897 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 233 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 587 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 198 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 326 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 456 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 460 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 1178 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
File mode changed from 100755 to 100644.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
File mode changed from 100755 to 100644.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.